Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b69be6d5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: gadget: support for dynamic read of usb composition"

parents cdaae388 de9008b9
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -2,21 +2,32 @@ Qualcomm Technologies, Inc's USB Gadget

Required properties:
- compatible: Should be "qcom,usb-gadget".
- qcom,vid: VendorId to be used by composite device.

Required subnode properties:
- qcom,pid: ProductId to be used by composite device.
- qcom,composition: List of configurations where each is separated by '|'.
	And each configuration has comma separated list of functions
	specified as: <f1_name>.<f1_instance_name>,<f2_name>....
- qcom,vid: VendorId to be used by composite device.
- qcom,pid: ProductId to be used by composite device.

Optional properties:
- qcom,default-pid: ProductId to be used by composite device.
- qcom,class: Class of composite device.
- qcom,subclass: SubClass of composite device.
- qcom,protocol: Protocol of composite device.

Examples:
Example:
	usb_gadget {
		compatible = "qcom,usb-gadget";
		qcom,composition = "rndis.rndis|ecm.ecm";
		qcom,vid = <0x05c6>;
		qcom,pid = <0x9057>;

		composition1 {
			qcom,pid = <0x9103>;
			qcom,composition = "diag.diag,ipc.ipc,gsi.rmnet,gsi.rmnet.v2x,ecm.ecm,gsi.dpl";
		};

		composition2 {
			qcom,pid = <0x9105>;
			qcom,composition = "diag.diag,gsi.dpl";
		};
	};
+45 −21
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
#include <linux/property.h>
#include <linux/usb/composite.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/kernel.h>

struct qti_usb_function {
	struct usb_function_instance *fi;
@@ -59,6 +61,10 @@ module_param_string(serialno, serialno_string,
		    sizeof(serialno_string), 0644);
MODULE_PARM_DESC(quirks, "String representing name of manufacturer");

static char usb_pid_string[256];
module_param_string(usb_pid, usb_pid_string, sizeof(usb_pid_string), 0644);
MODULE_PARM_DESC(quirks, "String representing product id");

/* String Table */
static struct usb_string strings_dev[] = {
	[USB_GADGET_MANUFACTURER_IDX].s = manufacturer_string,
@@ -468,20 +474,8 @@ static void qti_gadget_unregister(struct qti_usb_gadget *qg)
static int qti_gadget_get_properties(struct qti_usb_gadget *gadget)
{
	struct device *dev = gadget->dev;
	int ret, val;

	ret = device_property_read_string(dev, "qcom,composition",
				    &gadget->composition_funcs);
	if (ret) {
		dev_err(dev, "USB gadget composition not specified\n");
		return ret;
	}

	/* bail out if ffs is specified and let userspace handle it */
	if (strstr(gadget->composition_funcs, "ffs.")) {
		dev_err(dev, "user should enable ffs\n");
		return -EINVAL;
	}
	struct device_node *child = NULL;
	int ret = 0, val = 0, pid = 0;

	ret = device_property_read_u32(dev, "qcom,vid", &val);
	if (ret) {
@@ -490,13 +484,6 @@ static int qti_gadget_get_properties(struct qti_usb_gadget *gadget)
	}
	gadget->cdev.desc.idVendor = (u16)val;

	ret = device_property_read_u32(dev, "qcom,pid", &val);
	if (ret) {
		dev_err(dev, "USB gadget idProduct not specified\n");
		return ret;
	}
	gadget->cdev.desc.idProduct = (u16)val;

	ret = device_property_read_u32(dev, "qcom,class", &val);
	if (!ret)
		gadget->cdev.desc.bDeviceClass = (u8)val;
@@ -509,6 +496,43 @@ static int qti_gadget_get_properties(struct qti_usb_gadget *gadget)
	if (!ret)
		gadget->cdev.desc.bDeviceProtocol = (u8)val;

	/* Check if pid passed via cmdline which takes precedence */
	if (usb_pid_string != NULL) {
		ret = kstrtoint(usb_pid_string, 16, &val);
		if (ret)
			return ret;
	} else {
		ret = device_property_read_u32(dev, "qcom,default-pid", &val);
		if (ret) {
			dev_dbg(dev, "USB gadget default-pid not specified\n");
			return ret;
		}
	}

	pid = val;

	/* Go through all the child nodes and find matching pid */
	while ((child = of_get_next_child(dev->of_node, child)) != NULL) {
		of_property_read_u32(child, "qcom,pid", &val);
		if (val == pid) {
			of_property_read_string(child, "qcom,composition",
					&gadget->composition_funcs);
			break;
		}
	}

	/* Check if couldn't find a matching composition */
	if (gadget->composition_funcs == NULL)
		return -EINVAL;

	/* bail out if ffs is specified and let userspace handle it */
	if (strstr(gadget->composition_funcs, "ffs.")) {
		dev_err(dev, "user should enable ffs\n");
		return -EINVAL;
	}

	gadget->cdev.desc.idProduct = (u16)pid;

	return 0;
}