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

Commit bd7dd235 authored by Mark Kuo's avatar Mark Kuo Committed by Badhri Jagan Sridharan
Browse files

CHROMIUM: usb: gadget: f_mtp: Add SuperSpeed support



Add SuperSpeed endpoint and companion descriptors.

BUG=chrome-os-partner:43682
TEST=Smaug enumerates as a SuperSpeed device.

Change-Id: I2bf3125d180fcb07222a5740fa67f3526cf3e95c
Signed-off-by: default avatarHui Fu <hfu@nvidia.com>
Signed-off-by: default avatarHenry Lin <henryl@nvidia.com>
Signed-off-by: default avatarMark Kuo <mkuo@nvidia.com>
Signed-off-by: default avatarAndrew Bresticker <abrestic@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/294950
parent c7b86229
Loading
Loading
Loading
Loading
+76 −2
Original line number Diff line number Diff line
@@ -135,6 +135,34 @@ static struct usb_interface_descriptor ptp_interface_desc = {
	.bInterfaceProtocol     = 1,
};

static struct usb_endpoint_descriptor mtp_ss_in_desc = {
	.bLength                = USB_DT_ENDPOINT_SIZE,
	.bDescriptorType        = USB_DT_ENDPOINT,
	.bEndpointAddress       = USB_DIR_IN,
	.bmAttributes           = USB_ENDPOINT_XFER_BULK,
	.wMaxPacketSize         = __constant_cpu_to_le16(1024),
};

static struct usb_ss_ep_comp_descriptor mtp_ss_in_comp_desc = {
	.bLength                = sizeof(mtp_ss_in_comp_desc),
	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
	/* .bMaxBurst           = DYNAMIC, */
};

static struct usb_endpoint_descriptor mtp_ss_out_desc = {
	.bLength                = USB_DT_ENDPOINT_SIZE,
	.bDescriptorType        = USB_DT_ENDPOINT,
	.bEndpointAddress       = USB_DIR_OUT,
	.bmAttributes           = USB_ENDPOINT_XFER_BULK,
	.wMaxPacketSize         = __constant_cpu_to_le16(1024),
};

static struct usb_ss_ep_comp_descriptor mtp_ss_out_comp_desc = {
	.bLength                = sizeof(mtp_ss_out_comp_desc),
	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
	/* .bMaxBurst           = DYNAMIC, */
};

static struct usb_endpoint_descriptor mtp_highspeed_in_desc = {
	.bLength                = USB_DT_ENDPOINT_SIZE,
	.bDescriptorType        = USB_DT_ENDPOINT,
@@ -174,6 +202,12 @@ static struct usb_endpoint_descriptor mtp_intr_desc = {
	.bInterval              = 6,
};

static struct usb_ss_ep_comp_descriptor mtp_intr_ss_comp_desc = {
	.bLength                = sizeof(mtp_intr_ss_comp_desc),
	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
	.wBytesPerInterval      = cpu_to_le16(2),
};

static struct usb_descriptor_header *fs_mtp_descs[] = {
	(struct usb_descriptor_header *) &mtp_interface_desc,
	(struct usb_descriptor_header *) &mtp_fullspeed_in_desc,
@@ -190,6 +224,17 @@ static struct usb_descriptor_header *hs_mtp_descs[] = {
	NULL,
};

static struct usb_descriptor_header *ss_mtp_descs[] = {
	(struct usb_descriptor_header *) &mtp_interface_desc,
	(struct usb_descriptor_header *) &mtp_ss_in_desc,
	(struct usb_descriptor_header *) &mtp_ss_in_comp_desc,
	(struct usb_descriptor_header *) &mtp_ss_out_desc,
	(struct usb_descriptor_header *) &mtp_ss_out_comp_desc,
	(struct usb_descriptor_header *) &mtp_intr_desc,
	(struct usb_descriptor_header *) &mtp_intr_ss_comp_desc,
	NULL,
};

static struct usb_descriptor_header *fs_ptp_descs[] = {
	(struct usb_descriptor_header *) &ptp_interface_desc,
	(struct usb_descriptor_header *) &mtp_fullspeed_in_desc,
@@ -206,6 +251,17 @@ static struct usb_descriptor_header *hs_ptp_descs[] = {
	NULL,
};

static struct usb_descriptor_header *ss_ptp_descs[] = {
	(struct usb_descriptor_header *) &ptp_interface_desc,
	(struct usb_descriptor_header *) &mtp_ss_in_desc,
	(struct usb_descriptor_header *) &mtp_ss_in_comp_desc,
	(struct usb_descriptor_header *) &mtp_ss_out_desc,
	(struct usb_descriptor_header *) &mtp_ss_out_comp_desc,
	(struct usb_descriptor_header *) &mtp_intr_desc,
	(struct usb_descriptor_header *) &mtp_intr_ss_comp_desc,
	NULL,
};

static struct usb_string mtp_string_defs[] = {
	/* Naming interface "MTP" so libmtp will recognize us */
	[INTERFACE_STRING_INDEX].s	= "MTP",
@@ -1131,9 +1187,23 @@ mtp_function_bind(struct usb_configuration *c, struct usb_function *f)
		mtp_highspeed_out_desc.bEndpointAddress =
			mtp_fullspeed_out_desc.bEndpointAddress;
	}
	/* support super speed hardware */
	if (gadget_is_superspeed(c->cdev->gadget)) {
		unsigned max_burst;

		/* Calculate bMaxBurst, we know packet size is 1024 */
		max_burst = min_t(unsigned, MTP_BULK_BUFFER_SIZE / 1024, 15);
		mtp_ss_in_desc.bEndpointAddress =
			mtp_fullspeed_in_desc.bEndpointAddress;
		mtp_ss_in_comp_desc.bMaxBurst = max_burst;
		mtp_ss_out_desc.bEndpointAddress =
			mtp_fullspeed_out_desc.bEndpointAddress;
		mtp_ss_out_comp_desc.bMaxBurst = max_burst;
	}

	DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
		gadget_is_superspeed(c->cdev->gadget) ? "super" :
		(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full"),
		f->name, dev->ep_in->name, dev->ep_out->name);
	return 0;
}
@@ -1238,9 +1308,11 @@ static int mtp_bind_config(struct usb_configuration *c, bool ptp_config)
	if (ptp_config) {
		dev->function.fs_descriptors = fs_ptp_descs;
		dev->function.hs_descriptors = hs_ptp_descs;
		dev->function.ss_descriptors = ss_ptp_descs;
	} else {
		dev->function.fs_descriptors = fs_mtp_descs;
		dev->function.hs_descriptors = hs_mtp_descs;
		dev->function.ss_descriptors = ss_mtp_descs;
	}
	dev->function.bind = mtp_function_bind;
	dev->function.unbind = mtp_function_unbind;
@@ -1449,9 +1521,11 @@ struct usb_function *function_alloc_mtp_ptp(struct usb_function_instance *fi,
	if (mtp_config) {
		dev->function.fs_descriptors = fs_mtp_descs;
		dev->function.hs_descriptors = hs_mtp_descs;
		dev->function.ss_descriptors = ss_mtp_descs;
	} else {
		dev->function.fs_descriptors = fs_ptp_descs;
		dev->function.hs_descriptors = hs_ptp_descs;
		dev->function.ss_descriptors = ss_ptp_descs;
	}
	dev->function.bind = mtp_function_bind;
	dev->function.unbind = mtp_function_unbind;