From 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 16 May 2024 03:11:33 +0000 Subject: [PATCH] AX88772C_eeprom and ax8872c build together --- kernel/drivers/usb/gadget/function/f_accessory.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 140 insertions(+), 15 deletions(-) diff --git a/kernel/drivers/usb/gadget/function/f_accessory.c b/kernel/drivers/usb/gadget/function/f_accessory.c index c6bb836..7d35d6c 100644 --- a/kernel/drivers/usb/gadget/function/f_accessory.c +++ b/kernel/drivers/usb/gadget/function/f_accessory.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Gadget Function Driver for Android USB accessories * @@ -119,6 +120,12 @@ /* delayed work for handling ACCESSORY_START */ struct delayed_work start_work; + /* work for handling ACCESSORY GET PROTOCOL */ + struct work_struct getprotocol_work; + + /* work for handling ACCESSORY SEND STRING */ + struct work_struct sendstring_work; + /* worker for registering and unregistering hid devices */ struct work_struct hid_work; @@ -142,12 +149,62 @@ .bInterfaceProtocol = 0, }; +static struct usb_endpoint_descriptor acc_superspeedplus_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_endpoint_descriptor acc_superspeedplus_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor acc_superspeedplus_comp_desc = { + .bLength = sizeof(acc_superspeedplus_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + +static struct usb_endpoint_descriptor acc_superspeed_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_endpoint_descriptor acc_superspeed_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor acc_superspeed_comp_desc = { + .bLength = sizeof(acc_superspeed_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + /* the following 2 values can be tweaked if necessary */ + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + static struct usb_endpoint_descriptor acc_highspeed_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(512), + .wMaxPacketSize = cpu_to_le16(512), }; static struct usb_endpoint_descriptor acc_highspeed_out_desc = { @@ -155,7 +212,7 @@ .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), + .wMaxPacketSize = cpu_to_le16(512), }; static struct usb_endpoint_descriptor acc_fullspeed_in_desc = { @@ -183,6 +240,24 @@ (struct usb_descriptor_header *) &acc_interface_desc, (struct usb_descriptor_header *) &acc_highspeed_in_desc, (struct usb_descriptor_header *) &acc_highspeed_out_desc, + NULL, +}; + +static struct usb_descriptor_header *ss_acc_descs[] = { + (struct usb_descriptor_header *) &acc_interface_desc, + (struct usb_descriptor_header *) &acc_superspeed_in_desc, + (struct usb_descriptor_header *) &acc_superspeed_comp_desc, + (struct usb_descriptor_header *) &acc_superspeed_out_desc, + (struct usb_descriptor_header *) &acc_superspeed_comp_desc, + NULL, +}; + +static struct usb_descriptor_header *ssp_acc_descs[] = { + (struct usb_descriptor_header *) &acc_interface_desc, + (struct usb_descriptor_header *) &acc_superspeedplus_in_desc, + (struct usb_descriptor_header *) &acc_superspeedplus_comp_desc, + (struct usb_descriptor_header *) &acc_superspeedplus_out_desc, + (struct usb_descriptor_header *) &acc_superspeedplus_comp_desc, NULL, }; @@ -229,6 +304,8 @@ /* Cancel any async work */ cancel_delayed_work_sync(&dev->start_work); + cancel_work_sync(&dev->getprotocol_work); + cancel_work_sync(&dev->sendstring_work); cancel_work_sync(&dev->hid_work); ref->acc_dev = NULL; @@ -721,16 +798,16 @@ } while (count > 0) { - if (!dev->online) { + /* get an idle tx request to use */ + req = 0; + ret = wait_event_interruptible(dev->write_wq, + ((req = req_get(dev, &dev->tx_idle)) || !dev->online)); + if (!dev->online || dev->disconnected) { pr_debug("acc_write dev->error\n"); r = -EIO; break; } - /* get an idle tx request to use */ - req = 0; - ret = wait_event_interruptible(dev->write_wq, - ((req = req_get(dev, &dev->tx_idle)) || !dev->online)); if (!req) { r = ret; break; @@ -854,9 +931,7 @@ .read = acc_read, .write = acc_write, .unlocked_ioctl = acc_ioctl, -#ifdef CONFIG_COMPAT .compat_ioctl = acc_ioctl, -#endif .open = acc_open, .release = acc_release, }; @@ -926,6 +1001,7 @@ value = 0; cdev->req->complete = acc_complete_setup_noop; } else if (b_request == ACCESSORY_SEND_STRING) { + schedule_work(&dev->sendstring_work); dev->string_index = w_index; cdev->gadget->ep0->driver_data = dev; cdev->req->complete = acc_complete_set_string; @@ -972,6 +1048,7 @@ } } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) { if (b_request == ACCESSORY_GET_PROTOCOL) { + schedule_work(&dev->getprotocol_work); *((u16 *)cdev->req->buf) = PROTOCOL_VERSION; value = sizeof(u16); cdev->req->complete = acc_complete_setup_noop; @@ -1007,6 +1084,26 @@ return value; } EXPORT_SYMBOL_GPL(acc_ctrlrequest); + +int acc_ctrlrequest_composite(struct usb_composite_dev *cdev, + const struct usb_ctrlrequest *ctrl) +{ + u16 w_length = le16_to_cpu(ctrl->wLength); + + if (w_length > USB_COMP_EP0_BUFSIZ) { + if (ctrl->bRequestType & USB_DIR_IN) { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ); + w_length = USB_COMP_EP0_BUFSIZ; + } else { + return -EINVAL; + } + } + return acc_ctrlrequest(cdev, ctrl); +} +EXPORT_SYMBOL_GPL(acc_ctrlrequest_composite); static int __acc_function_bind(struct usb_configuration *c, @@ -1048,12 +1145,22 @@ return ret; /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - acc_highspeed_in_desc.bEndpointAddress = - acc_fullspeed_in_desc.bEndpointAddress; - acc_highspeed_out_desc.bEndpointAddress = - acc_fullspeed_out_desc.bEndpointAddress; - } + acc_highspeed_in_desc.bEndpointAddress = + acc_fullspeed_in_desc.bEndpointAddress; + acc_highspeed_out_desc.bEndpointAddress = + acc_fullspeed_out_desc.bEndpointAddress; + + /* support super speed hardware */ + acc_superspeed_in_desc.bEndpointAddress = + acc_fullspeed_in_desc.bEndpointAddress; + acc_superspeed_out_desc.bEndpointAddress = + acc_fullspeed_out_desc.bEndpointAddress; + + /* support super speed plus hardware */ + acc_superspeedplus_in_desc.bEndpointAddress = + acc_fullspeed_in_desc.bEndpointAddress; + acc_superspeedplus_out_desc.bEndpointAddress = + acc_fullspeed_out_desc.bEndpointAddress; DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", @@ -1116,6 +1223,20 @@ } acc_hid_unbind(dev); +} + +static void acc_getprotocol_work(struct work_struct *data) +{ + char *envp[2] = { "ACCESSORY=GETPROTOCOL", NULL }; + + kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp); +} + +static void acc_sendstring_work(struct work_struct *data) +{ + char *envp[2] = { "ACCESSORY=SENDSTRING", NULL }; + + kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp); } static void acc_start_work(struct work_struct *data) @@ -1293,6 +1414,8 @@ INIT_LIST_HEAD(&dev->dead_hid_list); INIT_DELAYED_WORK(&dev->start_work, acc_start_work); INIT_WORK(&dev->hid_work, acc_hid_work); + INIT_WORK(&dev->getprotocol_work, acc_getprotocol_work); + INIT_WORK(&dev->sendstring_work, acc_sendstring_work); dev->ref = ref; if (cmpxchg_relaxed(&ref->acc_dev, NULL, dev)) { @@ -1436,6 +1559,8 @@ dev->function.strings = acc_strings, dev->function.fs_descriptors = fs_acc_descs; dev->function.hs_descriptors = hs_acc_descs; + dev->function.ss_descriptors = ss_acc_descs; + dev->function.ssp_descriptors = ssp_acc_descs; dev->function.bind = acc_function_bind_configfs; dev->function.unbind = acc_function_unbind; dev->function.set_alt = acc_function_set_alt; -- Gitblit v1.6.2