blob: 77b458a8cba6d3098fb7b97d2cb48d02bcbef2b1 [file] [log] [blame]
Manu Gautam9c365d42019-12-12 14:59:57 +05301/*
2 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/module.h>
15#include <linux/property.h>
16#include <linux/usb/composite.h>
17#include <linux/platform_device.h>
Aniket Randivede9008b2020-02-13 15:08:45 +053018#include <linux/of.h>
19#include <linux/kernel.h>
Manu Gautam9c365d42019-12-12 14:59:57 +053020
21struct qti_usb_function {
22 struct usb_function_instance *fi;
23 struct usb_function *f;
24
25 struct list_head list;
26};
27
28#define MAX_FUNC_NAME_LEN 48
29#define MAX_CFG_NAME_LEN 128
30
31struct qti_usb_config {
32 struct usb_configuration c;
33
34 /* List of functions bound to this config */
35 struct list_head func_list;
36 /* List of qti_usb_functions bound to this config */
37 struct list_head qti_funcs;
38};
39
40struct qti_usb_gadget {
41 struct usb_composite_dev cdev;
42 struct usb_composite_driver composite;
43
44 const char *composition_funcs;
Manu Gautamb68e7382019-12-27 13:20:26 +053045 bool enabled;
Manu Gautam9c365d42019-12-12 14:59:57 +053046 struct device *dev;
47};
48
49static char manufacturer_string[256] = "Qualcomm Technologies, Inc";
50module_param_string(manufacturer, manufacturer_string,
51 sizeof(manufacturer_string), 0644);
52MODULE_PARM_DESC(quirks, "String representing name of manufacturer");
53
54static char product_string[256] = "USB_device_SN:12345";
55module_param_string(product, product_string,
56 sizeof(product_string), 0644);
57MODULE_PARM_DESC(quirks, "String representing product name");
58
59static char serialno_string[256] = "12345";
60module_param_string(serialno, serialno_string,
61 sizeof(serialno_string), 0644);
62MODULE_PARM_DESC(quirks, "String representing name of manufacturer");
63
Aniket Randivede9008b2020-02-13 15:08:45 +053064static char usb_pid_string[256];
65module_param_string(usb_pid, usb_pid_string, sizeof(usb_pid_string), 0644);
66MODULE_PARM_DESC(quirks, "String representing product id");
67
Manu Gautam9c365d42019-12-12 14:59:57 +053068/* String Table */
69static struct usb_string strings_dev[] = {
70 [USB_GADGET_MANUFACTURER_IDX].s = manufacturer_string,
71 [USB_GADGET_PRODUCT_IDX].s = product_string,
72 [USB_GADGET_SERIAL_IDX].s = serialno_string,
73 { } /* end of list */
74};
75
76static struct usb_gadget_strings stringtab_dev = {
77 .language = 0x0409, /* en-us */
78 .strings = strings_dev,
79};
80
81static struct usb_gadget_strings *dev_strings[] = {
82 &stringtab_dev,
83 NULL,
84};
85
86static void qti_configs_remove_funcs(struct qti_usb_gadget *qg)
87{
88 struct usb_configuration *c;
89
90 list_for_each_entry(c, &qg->cdev.configs, list) {
91 struct qti_usb_config *cfg;
92 struct usb_function *f, *tmp;
93
94 cfg = container_of(c, struct qti_usb_config, c);
95
96 list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) {
97
98 list_move(&f->list, &cfg->func_list);
99 if (f->unbind) {
100 dev_dbg(&qg->cdev.gadget->dev,
101 "unbind function '%s'/%pK\n",
102 f->name, f);
103 f->unbind(c, f);
104 }
105 }
106 c->fullspeed = 0;
107 c->highspeed = 0;
108 c->superspeed = 0;
109 c->superspeed_plus = 0;
110 c->next_interface_id = 0;
111 memset(c->interface, 0, sizeof(c->interface));
112 }
113}
114
115static int qti_composite_bind(struct usb_gadget *gadget,
116 struct usb_gadget_driver *gdriver)
117{
118 struct usb_composite_driver *composite = to_cdriver(gdriver);
119 struct qti_usb_gadget *qg = container_of(composite,
120 struct qti_usb_gadget, composite);
121 struct usb_composite_dev *cdev = &qg->cdev;
122 struct usb_configuration *c;
123 struct usb_string *s;
124 int ret = -EINVAL;
125
126 cdev->gadget = gadget;
127 set_gadget_data(gadget, cdev);
128 spin_lock_init(&qg->cdev.lock);
129
130 ret = composite_dev_prepare(composite, cdev);
131 if (ret)
132 return ret;
133
134 if (list_empty(&cdev->configs)) {
135 pr_err("No configurations found in %s.\n", composite->name);
136 ret = -EINVAL;
137 goto composite_cleanup;
138 }
139
140 list_for_each_entry(c, &cdev->configs, list) {
141 struct qti_usb_config *qcfg;
142
143 qcfg = container_of(c, struct qti_usb_config, c);
144 if (list_empty(&qcfg->func_list)) {
145 pr_err("Config %s/%d of %s doesn't have a function.\n",
146 c->label, c->bConfigurationValue,
147 qg->composite.name);
148 goto composite_cleanup;
149 }
150 }
151
152 s = usb_gstrings_attach(cdev, dev_strings, USB_GADGET_FIRST_AVAIL_IDX);
153 if (IS_ERR(s)) {
154 ret = PTR_ERR(s);
155 goto composite_cleanup;
156 }
157
158 cdev->desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
159 cdev->desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
160 cdev->desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id;
161
162 /* Go through all configs, attach all functions */
163 list_for_each_entry(c, &qg->cdev.configs, list) {
164 struct qti_usb_config *qcfg;
165 struct usb_function *f, *tmp;
166
167 qcfg = container_of(c, struct qti_usb_config, c);
168
169 list_for_each_entry_safe(f, tmp, &qcfg->func_list, list) {
170 list_del(&f->list);
171 ret = usb_add_function(c, f);
172 if (ret) {
173 list_add(&f->list, &qcfg->func_list);
174 goto remove_funcs;
175 }
176 }
177 usb_ep_autoconfig_reset(cdev->gadget);
178 }
179
180 usb_ep_autoconfig_reset(cdev->gadget);
181
182 return 0;
183
184remove_funcs:
185 qti_configs_remove_funcs(qg);
186composite_cleanup:
187 composite_dev_cleanup(cdev);
188 return ret;
189}
190
191static void qti_composite_unbind(struct usb_gadget *gadget)
192{
193 struct usb_composite_dev *cdev;
194 struct qti_usb_gadget *qg;
195
196 cdev = get_gadget_data(gadget);
197 qg = container_of(cdev, struct qti_usb_gadget, cdev);
198
199 qti_configs_remove_funcs(qg);
200 composite_dev_cleanup(cdev);
201 usb_ep_autoconfig_reset(cdev->gadget);
202 cdev->gadget = NULL;
203 set_gadget_data(gadget, NULL);
204}
205
206static const struct usb_gadget_driver qti_gadget_driver = {
207 .bind = qti_composite_bind,
208 .unbind = qti_composite_unbind,
209 .setup = composite_setup,
210 .reset = composite_disconnect,
211 .disconnect = composite_disconnect,
212 .suspend = composite_suspend,
213 .resume = composite_resume,
214
215 .max_speed = USB_SPEED_SUPER_PLUS,
216 .driver = {
217 .owner = THIS_MODULE,
218 .name = "qti-gadget",
219 },
220};
221
222static void qti_usb_funcs_free(struct qti_usb_config *qcfg)
223{
224 struct usb_function *f, *tmp;
225 struct qti_usb_function *qf, *qf_tmp;
226
227 list_for_each_entry_safe(f, tmp, &qcfg->func_list, list) {
228 list_del(&f->list);
229 usb_put_function(f);
230
231 /* find corresponding function_instance and free it */
232 list_for_each_entry_safe(qf, qf_tmp, &qcfg->qti_funcs, list) {
233 if (qf->f == f) {
234 list_del(&qf->list);
235 usb_put_function_instance(qf->fi);
236 kfree(qf);
237 break;
238 }
239 }
240 }
241}
242
243static void qti_cleanup_configs_funcs(struct qti_usb_gadget *qg)
244{
245 struct usb_configuration *c, *c_tmp;
246
247 list_for_each_entry_safe(c, c_tmp, &qg->cdev.configs, list) {
248 struct qti_usb_config *qcfg;
249
250 qcfg = container_of(c, struct qti_usb_config, c);
251 WARN_ON(!list_empty(&qcfg->c.functions));
252
253 qti_usb_funcs_free(qcfg);
254
255 list_del(&qcfg->c.list);
256 kfree(qcfg->c.label);
257 kfree(qcfg);
258 }
259}
260
261static int qti_usb_func_alloc(struct qti_usb_config *qcfg,
262 const char *name)
263{
264 struct qti_usb_function *qf;
265 struct usb_function_instance *fi;
266 struct usb_function *f;
267 char buf[MAX_FUNC_NAME_LEN];
268 char *func_name;
269 char *instance_name;
270 int ret;
271
272 ret = snprintf(buf, MAX_FUNC_NAME_LEN, "%s", name);
273 if (ret >= MAX_FUNC_NAME_LEN)
274 return -ENAMETOOLONG;
275
276 func_name = buf;
277 instance_name = strnchr(func_name, MAX_FUNC_NAME_LEN, '.');
278 if (!instance_name) {
279 pr_err("Can't find . in <func>.<instance>:%s\n", buf);
280 return -EINVAL;
281 }
282 *instance_name = '\0';
283 instance_name++;
284
285 qf = kzalloc(sizeof(*qf), GFP_KERNEL);
286 if (!qf)
287 return -ENOMEM;
288
289 fi = usb_get_function_instance(func_name);
290 if (IS_ERR(fi)) {
291 kfree(qf);
292 return PTR_ERR(fi);
293 }
294 qf->fi = fi;
295
296 if (fi->set_inst_name) {
297 ret = fi->set_inst_name(fi, instance_name);
298 if (ret) {
299 kfree(qf);
300 usb_put_function_instance(fi);
301 return ret;
302 }
303 }
304
305 f = usb_get_function(fi);
306 if (IS_ERR(f)) {
307 kfree(qf);
308 usb_put_function_instance(fi);
309 return PTR_ERR(f);
310 }
311 qf->f = f;
312 list_add_tail(&qf->list, &qcfg->qti_funcs);
313
314 /* stash the function until we bind it to the gadget */
315 list_add_tail(&f->list, &qcfg->func_list);
316
317 return 0;
318}
319
320static int qti_usb_funcs_alloc(struct qti_usb_config *qcfg,
321 const char *funcs)
322{
323 char buf[MAX_CFG_NAME_LEN];
324 char *fn_name, *next_fn;
325 int ret = 0;
326
327 ret = snprintf(buf, MAX_CFG_NAME_LEN, "%s", funcs);
328 if (ret >= MAX_CFG_NAME_LEN)
329 return -ENAMETOOLONG;
330
331 fn_name = buf;
332 while (fn_name) {
333 next_fn = strnchr(fn_name, MAX_CFG_NAME_LEN, ',');
334 if (next_fn)
335 *next_fn++ = '\0';
336
337 ret = qti_usb_func_alloc(qcfg, fn_name);
338 if (ret) {
339 qti_usb_funcs_free(qcfg);
340 break;
341 }
342
343 fn_name = next_fn;
344 };
345
346 return ret;
347}
348
349static int qti_usb_config_add(struct qti_usb_gadget *gadget,
350 const char *name, u8 num)
351{
352 struct qti_usb_config *qcfg;
353 int ret = 0;
354
355 qcfg = kzalloc(sizeof(*qcfg), GFP_KERNEL);
356 if (!qcfg)
357 return -ENOMEM;
358
359 qcfg->c.label = kstrdup(name, GFP_KERNEL);
360 if (!qcfg->c.label) {
361 ret = -ENOMEM;
362 goto free_cfg;
363 }
364 qcfg->c.bConfigurationValue = num;
365 qcfg->c.bmAttributes = USB_CONFIG_ATT_ONE;
366 qcfg->c.MaxPower = CONFIG_USB_GADGET_VBUS_DRAW;
367 INIT_LIST_HEAD(&qcfg->func_list);
368 INIT_LIST_HEAD(&qcfg->qti_funcs);
369
370 ret = usb_add_config_only(&gadget->cdev, &qcfg->c);
371 if (ret)
372 goto free_label;
373
374 ret = qti_usb_funcs_alloc(qcfg, name);
375 if (ret)
376 goto cfg_del;
377
378 return ret;
379
380cfg_del:
381 list_del(&qcfg->c.list);
382free_label:
383 kfree(qcfg->c.label);
384free_cfg:
385 kfree(qcfg);
386 return ret;
387
388}
389
390static int qti_usb_configs_make(struct qti_usb_gadget *gadget,
391 const char *cfgs)
392{
393 char buf[MAX_CFG_NAME_LEN];
394 char *cfg_name, *next_cfg;
395 int ret = 0;
396 u8 num = 1;
397
398 ret = snprintf(buf, MAX_CFG_NAME_LEN, "%s", cfgs);
399 if (ret >= MAX_CFG_NAME_LEN)
400 return -ENAMETOOLONG;
401
402 cfg_name = buf;
403 while (cfg_name) {
404 next_cfg = strnchr(cfg_name, MAX_CFG_NAME_LEN, '|');
405 if (next_cfg)
406 *next_cfg++ = '\0';
407
408 ret = qti_usb_config_add(gadget, cfg_name, num);
409 if (ret)
410 break;
411
412 cfg_name = next_cfg;
413 num++;
414 };
415
416 return ret;
417}
418
419static int qti_gadget_register(struct qti_usb_gadget *qg)
420{
421 int ret;
422
Manu Gautamb68e7382019-12-27 13:20:26 +0530423 if (qg->enabled)
424 return -EINVAL;
425
Manu Gautam9c365d42019-12-12 14:59:57 +0530426 ret = qti_usb_configs_make(qg, qg->composition_funcs);
427 if (ret)
428 return ret;
429
430 qg->cdev.desc.bLength = USB_DT_DEVICE_SIZE;
431 qg->cdev.desc.bDescriptorType = USB_DT_DEVICE;
432 qg->cdev.desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
433
434 qg->composite.gadget_driver = qti_gadget_driver;
435 qg->composite.max_speed = qti_gadget_driver.max_speed;
436
437 qg->composite.gadget_driver.function = kstrdup("qti-gadget",
438 GFP_KERNEL);
439 qg->composite.name = qg->composite.gadget_driver.function;
440
441 if (!qg->composite.gadget_driver.function) {
442 ret = -ENOMEM;
443 goto free_configs;
444 }
445
446 ret = usb_gadget_probe_driver(&qg->composite.gadget_driver);
447 if (ret)
448 goto free_name;
449
Manu Gautamb68e7382019-12-27 13:20:26 +0530450 qg->enabled = true;
451
Manu Gautam9c365d42019-12-12 14:59:57 +0530452 return 0;
453
454free_name:
455 kfree(qg->composite.gadget_driver.function);
456free_configs:
457 qti_cleanup_configs_funcs(qg);
458
459 return ret;
460}
461
462static void qti_gadget_unregister(struct qti_usb_gadget *qg)
463{
Manu Gautamb68e7382019-12-27 13:20:26 +0530464 if (!qg->enabled)
465 return;
466
Manu Gautam9c365d42019-12-12 14:59:57 +0530467 usb_gadget_unregister_driver(&qg->composite.gadget_driver);
468 kfree(qg->composite.gadget_driver.function);
469 qti_cleanup_configs_funcs(qg);
Manu Gautamb68e7382019-12-27 13:20:26 +0530470
471 qg->enabled = false;
Manu Gautam9c365d42019-12-12 14:59:57 +0530472}
473
474static int qti_gadget_get_properties(struct qti_usb_gadget *gadget)
475{
476 struct device *dev = gadget->dev;
Aniket Randivede9008b2020-02-13 15:08:45 +0530477 struct device_node *child = NULL;
478 int ret = 0, val = 0, pid = 0;
Manu Gautam9c365d42019-12-12 14:59:57 +0530479
480 ret = device_property_read_u32(dev, "qcom,vid", &val);
481 if (ret) {
482 dev_err(dev, "USB gadget idVendor not specified\n");
483 return ret;
484 }
485 gadget->cdev.desc.idVendor = (u16)val;
486
Manu Gautam9c365d42019-12-12 14:59:57 +0530487 ret = device_property_read_u32(dev, "qcom,class", &val);
488 if (!ret)
489 gadget->cdev.desc.bDeviceClass = (u8)val;
490
491 ret = device_property_read_u32(dev, "qcom,subclass", &val);
492 if (!ret)
493 gadget->cdev.desc.bDeviceSubClass = (u8)val;
494
495 ret = device_property_read_u32(dev, "qcom,protocol", &val);
496 if (!ret)
497 gadget->cdev.desc.bDeviceProtocol = (u8)val;
498
Aniket Randivede9008b2020-02-13 15:08:45 +0530499 /* Check if pid passed via cmdline which takes precedence */
500 if (usb_pid_string != NULL) {
501 ret = kstrtoint(usb_pid_string, 16, &val);
502 if (ret)
503 return ret;
504 } else {
505 ret = device_property_read_u32(dev, "qcom,default-pid", &val);
506 if (ret) {
507 dev_dbg(dev, "USB gadget default-pid not specified\n");
508 return ret;
509 }
510 }
511
512 pid = val;
513
514 /* Go through all the child nodes and find matching pid */
515 while ((child = of_get_next_child(dev->of_node, child)) != NULL) {
516 of_property_read_u32(child, "qcom,pid", &val);
517 if (val == pid) {
518 of_property_read_string(child, "qcom,composition",
519 &gadget->composition_funcs);
520 break;
521 }
522 }
523
524 /* Check if couldn't find a matching composition */
525 if (gadget->composition_funcs == NULL)
526 return -EINVAL;
527
528 /* bail out if ffs is specified and let userspace handle it */
529 if (strstr(gadget->composition_funcs, "ffs.")) {
530 dev_err(dev, "user should enable ffs\n");
531 return -EINVAL;
532 }
533
534 gadget->cdev.desc.idProduct = (u16)pid;
535
Manu Gautam9c365d42019-12-12 14:59:57 +0530536 return 0;
537}
538
Manu Gautamb68e7382019-12-27 13:20:26 +0530539static ssize_t enabled_show(struct device *dev,
540 struct device_attribute *attr, char *buf)
541{
542 struct qti_usb_gadget *qg = dev_get_drvdata(dev);
543
544 return snprintf(buf, PAGE_SIZE, "%c\n",
545 qg->enabled ? 'Y' : 'N');
546}
547
548static ssize_t enabled_store(struct device *dev,
549 struct device_attribute *attr, const char *buf, size_t count)
550{
551 struct qti_usb_gadget *qg = dev_get_drvdata(dev);
552 bool enable;
553 int ret;
554
555 ret = strtobool(buf, &enable);
556 if (ret)
557 return ret;
558
559 if (enable)
560 qti_gadget_register(qg);
561 else
562 qti_gadget_unregister(qg);
563
564 return count;
565}
566static DEVICE_ATTR_RW(enabled);
567
Manu Gautam9c365d42019-12-12 14:59:57 +0530568static int qti_gadget_probe(struct platform_device *pdev)
569{
570 int ret;
571 struct device *dev = &pdev->dev;
572 struct qti_usb_gadget *gadget;
573
574 gadget = devm_kzalloc(dev, sizeof(*gadget), GFP_KERNEL);
575 if (!gadget)
576 return -ENOMEM;
577
578 platform_set_drvdata(pdev, gadget);
579 gadget->dev = dev;
580 INIT_LIST_HEAD(&gadget->cdev.configs);
581 INIT_LIST_HEAD(&gadget->cdev.gstrings);
582
583 ret = qti_gadget_get_properties(gadget);
584 if (ret)
585 return ret;
586
587 ret = qti_gadget_register(gadget);
588 if (ret)
589 return ret;
590
Manu Gautamb68e7382019-12-27 13:20:26 +0530591 device_create_file(&pdev->dev, &dev_attr_enabled);
592
Manu Gautam9c365d42019-12-12 14:59:57 +0530593 return 0;
594}
595
596static int qti_gadget_remove(struct platform_device *pdev)
597{
598 struct qti_usb_gadget *qg = platform_get_drvdata(pdev);
599
Manu Gautamb68e7382019-12-27 13:20:26 +0530600 device_remove_file(&pdev->dev, &dev_attr_enabled);
Manu Gautam9c365d42019-12-12 14:59:57 +0530601 qti_gadget_unregister(qg);
602
603 return 0;
604}
605
606static const struct of_device_id qti_gadget_dt_match[] = {
607 {
608 .compatible = "qcom,usb-gadget",
609 },
610 { },
611};
612MODULE_DEVICE_TABLE(of, qti_gadget_dt_match);
613
614static struct platform_driver qti_gadget_platform_driver = {
615 .driver = {
616 .name = "qti_usb_gadget",
617 .of_match_table = qti_gadget_dt_match,
618 },
619 .probe = qti_gadget_probe,
620 .remove = qti_gadget_remove,
621};
622
623static int __init gadget_qti_init(void)
624{
625 int ret;
626
627 ret = platform_driver_register(&qti_gadget_platform_driver);
628 if (ret) {
629 pr_err("%s: Failed to register qti gadget platform driver\n",
630 __func__);
631 }
632
633 return ret;
634}
635module_init(gadget_qti_init);
636
637static void __exit gadget_qti_exit(void)
638{
639 platform_driver_unregister(&qti_gadget_platform_driver);
640}
641module_exit(gadget_qti_exit);