forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/drivers/usb/gadget/function/f_accessory.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Gadget Function Driver for Android USB accessories
34 *
....@@ -119,6 +120,12 @@
119120 /* delayed work for handling ACCESSORY_START */
120121 struct delayed_work start_work;
121122
123
+ /* work for handling ACCESSORY GET PROTOCOL */
124
+ struct work_struct getprotocol_work;
125
+
126
+ /* work for handling ACCESSORY SEND STRING */
127
+ struct work_struct sendstring_work;
128
+
122129 /* worker for registering and unregistering hid devices */
123130 struct work_struct hid_work;
124131
....@@ -142,12 +149,62 @@
142149 .bInterfaceProtocol = 0,
143150 };
144151
152
+static struct usb_endpoint_descriptor acc_superspeedplus_in_desc = {
153
+ .bLength = USB_DT_ENDPOINT_SIZE,
154
+ .bDescriptorType = USB_DT_ENDPOINT,
155
+ .bEndpointAddress = USB_DIR_IN,
156
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
157
+ .wMaxPacketSize = cpu_to_le16(1024),
158
+};
159
+
160
+static struct usb_endpoint_descriptor acc_superspeedplus_out_desc = {
161
+ .bLength = USB_DT_ENDPOINT_SIZE,
162
+ .bDescriptorType = USB_DT_ENDPOINT,
163
+ .bEndpointAddress = USB_DIR_OUT,
164
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
165
+ .wMaxPacketSize = cpu_to_le16(1024),
166
+};
167
+
168
+static struct usb_ss_ep_comp_descriptor acc_superspeedplus_comp_desc = {
169
+ .bLength = sizeof(acc_superspeedplus_comp_desc),
170
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
171
+
172
+ /* the following 2 values can be tweaked if necessary */
173
+ /* .bMaxBurst = 0, */
174
+ /* .bmAttributes = 0, */
175
+};
176
+
177
+static struct usb_endpoint_descriptor acc_superspeed_in_desc = {
178
+ .bLength = USB_DT_ENDPOINT_SIZE,
179
+ .bDescriptorType = USB_DT_ENDPOINT,
180
+ .bEndpointAddress = USB_DIR_IN,
181
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
182
+ .wMaxPacketSize = cpu_to_le16(1024),
183
+};
184
+
185
+static struct usb_endpoint_descriptor acc_superspeed_out_desc = {
186
+ .bLength = USB_DT_ENDPOINT_SIZE,
187
+ .bDescriptorType = USB_DT_ENDPOINT,
188
+ .bEndpointAddress = USB_DIR_OUT,
189
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
190
+ .wMaxPacketSize = cpu_to_le16(1024),
191
+};
192
+
193
+static struct usb_ss_ep_comp_descriptor acc_superspeed_comp_desc = {
194
+ .bLength = sizeof(acc_superspeed_comp_desc),
195
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
196
+
197
+ /* the following 2 values can be tweaked if necessary */
198
+ /* .bMaxBurst = 0, */
199
+ /* .bmAttributes = 0, */
200
+};
201
+
145202 static struct usb_endpoint_descriptor acc_highspeed_in_desc = {
146203 .bLength = USB_DT_ENDPOINT_SIZE,
147204 .bDescriptorType = USB_DT_ENDPOINT,
148205 .bEndpointAddress = USB_DIR_IN,
149206 .bmAttributes = USB_ENDPOINT_XFER_BULK,
150
- .wMaxPacketSize = __constant_cpu_to_le16(512),
207
+ .wMaxPacketSize = cpu_to_le16(512),
151208 };
152209
153210 static struct usb_endpoint_descriptor acc_highspeed_out_desc = {
....@@ -155,7 +212,7 @@
155212 .bDescriptorType = USB_DT_ENDPOINT,
156213 .bEndpointAddress = USB_DIR_OUT,
157214 .bmAttributes = USB_ENDPOINT_XFER_BULK,
158
- .wMaxPacketSize = __constant_cpu_to_le16(512),
215
+ .wMaxPacketSize = cpu_to_le16(512),
159216 };
160217
161218 static struct usb_endpoint_descriptor acc_fullspeed_in_desc = {
....@@ -183,6 +240,24 @@
183240 (struct usb_descriptor_header *) &acc_interface_desc,
184241 (struct usb_descriptor_header *) &acc_highspeed_in_desc,
185242 (struct usb_descriptor_header *) &acc_highspeed_out_desc,
243
+ NULL,
244
+};
245
+
246
+static struct usb_descriptor_header *ss_acc_descs[] = {
247
+ (struct usb_descriptor_header *) &acc_interface_desc,
248
+ (struct usb_descriptor_header *) &acc_superspeed_in_desc,
249
+ (struct usb_descriptor_header *) &acc_superspeed_comp_desc,
250
+ (struct usb_descriptor_header *) &acc_superspeed_out_desc,
251
+ (struct usb_descriptor_header *) &acc_superspeed_comp_desc,
252
+ NULL,
253
+};
254
+
255
+static struct usb_descriptor_header *ssp_acc_descs[] = {
256
+ (struct usb_descriptor_header *) &acc_interface_desc,
257
+ (struct usb_descriptor_header *) &acc_superspeedplus_in_desc,
258
+ (struct usb_descriptor_header *) &acc_superspeedplus_comp_desc,
259
+ (struct usb_descriptor_header *) &acc_superspeedplus_out_desc,
260
+ (struct usb_descriptor_header *) &acc_superspeedplus_comp_desc,
186261 NULL,
187262 };
188263
....@@ -229,6 +304,8 @@
229304
230305 /* Cancel any async work */
231306 cancel_delayed_work_sync(&dev->start_work);
307
+ cancel_work_sync(&dev->getprotocol_work);
308
+ cancel_work_sync(&dev->sendstring_work);
232309 cancel_work_sync(&dev->hid_work);
233310
234311 ref->acc_dev = NULL;
....@@ -721,16 +798,16 @@
721798 }
722799
723800 while (count > 0) {
724
- if (!dev->online) {
801
+ /* get an idle tx request to use */
802
+ req = 0;
803
+ ret = wait_event_interruptible(dev->write_wq,
804
+ ((req = req_get(dev, &dev->tx_idle)) || !dev->online));
805
+ if (!dev->online || dev->disconnected) {
725806 pr_debug("acc_write dev->error\n");
726807 r = -EIO;
727808 break;
728809 }
729810
730
- /* get an idle tx request to use */
731
- req = 0;
732
- ret = wait_event_interruptible(dev->write_wq,
733
- ((req = req_get(dev, &dev->tx_idle)) || !dev->online));
734811 if (!req) {
735812 r = ret;
736813 break;
....@@ -854,9 +931,7 @@
854931 .read = acc_read,
855932 .write = acc_write,
856933 .unlocked_ioctl = acc_ioctl,
857
-#ifdef CONFIG_COMPAT
858934 .compat_ioctl = acc_ioctl,
859
-#endif
860935 .open = acc_open,
861936 .release = acc_release,
862937 };
....@@ -926,6 +1001,7 @@
9261001 value = 0;
9271002 cdev->req->complete = acc_complete_setup_noop;
9281003 } else if (b_request == ACCESSORY_SEND_STRING) {
1004
+ schedule_work(&dev->sendstring_work);
9291005 dev->string_index = w_index;
9301006 cdev->gadget->ep0->driver_data = dev;
9311007 cdev->req->complete = acc_complete_set_string;
....@@ -972,6 +1048,7 @@
9721048 }
9731049 } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) {
9741050 if (b_request == ACCESSORY_GET_PROTOCOL) {
1051
+ schedule_work(&dev->getprotocol_work);
9751052 *((u16 *)cdev->req->buf) = PROTOCOL_VERSION;
9761053 value = sizeof(u16);
9771054 cdev->req->complete = acc_complete_setup_noop;
....@@ -1007,6 +1084,26 @@
10071084 return value;
10081085 }
10091086 EXPORT_SYMBOL_GPL(acc_ctrlrequest);
1087
+
1088
+int acc_ctrlrequest_composite(struct usb_composite_dev *cdev,
1089
+ const struct usb_ctrlrequest *ctrl)
1090
+{
1091
+ u16 w_length = le16_to_cpu(ctrl->wLength);
1092
+
1093
+ if (w_length > USB_COMP_EP0_BUFSIZ) {
1094
+ if (ctrl->bRequestType & USB_DIR_IN) {
1095
+ /* Cast away the const, we are going to overwrite on purpose. */
1096
+ __le16 *temp = (__le16 *)&ctrl->wLength;
1097
+
1098
+ *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ);
1099
+ w_length = USB_COMP_EP0_BUFSIZ;
1100
+ } else {
1101
+ return -EINVAL;
1102
+ }
1103
+ }
1104
+ return acc_ctrlrequest(cdev, ctrl);
1105
+}
1106
+EXPORT_SYMBOL_GPL(acc_ctrlrequest_composite);
10101107
10111108 static int
10121109 __acc_function_bind(struct usb_configuration *c,
....@@ -1048,12 +1145,22 @@
10481145 return ret;
10491146
10501147 /* support high speed hardware */
1051
- if (gadget_is_dualspeed(c->cdev->gadget)) {
1052
- acc_highspeed_in_desc.bEndpointAddress =
1053
- acc_fullspeed_in_desc.bEndpointAddress;
1054
- acc_highspeed_out_desc.bEndpointAddress =
1055
- acc_fullspeed_out_desc.bEndpointAddress;
1056
- }
1148
+ acc_highspeed_in_desc.bEndpointAddress =
1149
+ acc_fullspeed_in_desc.bEndpointAddress;
1150
+ acc_highspeed_out_desc.bEndpointAddress =
1151
+ acc_fullspeed_out_desc.bEndpointAddress;
1152
+
1153
+ /* support super speed hardware */
1154
+ acc_superspeed_in_desc.bEndpointAddress =
1155
+ acc_fullspeed_in_desc.bEndpointAddress;
1156
+ acc_superspeed_out_desc.bEndpointAddress =
1157
+ acc_fullspeed_out_desc.bEndpointAddress;
1158
+
1159
+ /* support super speed plus hardware */
1160
+ acc_superspeedplus_in_desc.bEndpointAddress =
1161
+ acc_fullspeed_in_desc.bEndpointAddress;
1162
+ acc_superspeedplus_out_desc.bEndpointAddress =
1163
+ acc_fullspeed_out_desc.bEndpointAddress;
10571164
10581165 DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
10591166 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
....@@ -1116,6 +1223,20 @@
11161223 }
11171224
11181225 acc_hid_unbind(dev);
1226
+}
1227
+
1228
+static void acc_getprotocol_work(struct work_struct *data)
1229
+{
1230
+ char *envp[2] = { "ACCESSORY=GETPROTOCOL", NULL };
1231
+
1232
+ kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp);
1233
+}
1234
+
1235
+static void acc_sendstring_work(struct work_struct *data)
1236
+{
1237
+ char *envp[2] = { "ACCESSORY=SENDSTRING", NULL };
1238
+
1239
+ kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp);
11191240 }
11201241
11211242 static void acc_start_work(struct work_struct *data)
....@@ -1293,6 +1414,8 @@
12931414 INIT_LIST_HEAD(&dev->dead_hid_list);
12941415 INIT_DELAYED_WORK(&dev->start_work, acc_start_work);
12951416 INIT_WORK(&dev->hid_work, acc_hid_work);
1417
+ INIT_WORK(&dev->getprotocol_work, acc_getprotocol_work);
1418
+ INIT_WORK(&dev->sendstring_work, acc_sendstring_work);
12961419
12971420 dev->ref = ref;
12981421 if (cmpxchg_relaxed(&ref->acc_dev, NULL, dev)) {
....@@ -1436,6 +1559,8 @@
14361559 dev->function.strings = acc_strings,
14371560 dev->function.fs_descriptors = fs_acc_descs;
14381561 dev->function.hs_descriptors = hs_acc_descs;
1562
+ dev->function.ss_descriptors = ss_acc_descs;
1563
+ dev->function.ssp_descriptors = ssp_acc_descs;
14391564 dev->function.bind = acc_function_bind_configfs;
14401565 dev->function.unbind = acc_function_unbind;
14411566 dev->function.set_alt = acc_function_set_alt;