1 /*
2  * hid.c -- HID Composite driver
3  *
4  * Based on multi.c
5  *
6  * Copyright (C) 2010 Fabien Chouteau <fabien.chouteau@barco.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13 
14 
15 #include <linux/kernel.h>
16 #include <linux/platform_device.h>
17 #include <linux/list.h>
18 
19 #define DRIVER_DESC		"HID Gadget"
20 #define DRIVER_VERSION		"2010/03/16"
21 
22 /*-------------------------------------------------------------------------*/
23 
24 #define HIDG_VENDOR_NUM		0x0525	/* XXX NetChip */
25 #define HIDG_PRODUCT_NUM	0xa4ac	/* Linux-USB HID gadget */
26 
27 /*-------------------------------------------------------------------------*/
28 
29 /*
30  * kbuild is not very cooperative with respect to linking separately
31  * compiled library objects into one module.  So for now we won't use
32  * separate compilation ... ensuring init/exit sections work to shrink
33  * the runtime footprint, and giving us at least some parts of what
34  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
35  */
36 
37 #include "composite.c"
38 #include "usbstring.c"
39 #include "config.c"
40 #include "epautoconf.c"
41 
42 #include "f_hid.c"
43 
44 
45 struct hidg_func_node {
46 	struct list_head node;
47 	struct hidg_func_descriptor *func;
48 };
49 
50 static LIST_HEAD(hidg_func_list);
51 
52 /*-------------------------------------------------------------------------*/
53 
54 static struct usb_device_descriptor device_desc = {
55 	.bLength =		sizeof device_desc,
56 	.bDescriptorType =	USB_DT_DEVICE,
57 
58 	.bcdUSB =		cpu_to_le16(0x0200),
59 
60 	/* .bDeviceClass =		USB_CLASS_COMM, */
61 	/* .bDeviceSubClass =	0, */
62 	/* .bDeviceProtocol =	0, */
63 	.bDeviceClass =		0xEF,
64 	.bDeviceSubClass =	2,
65 	.bDeviceProtocol =	1,
66 	/* .bMaxPacketSize0 = f(hardware) */
67 
68 	/* Vendor and product id can be overridden by module parameters.  */
69 	.idVendor =		cpu_to_le16(HIDG_VENDOR_NUM),
70 	.idProduct =		cpu_to_le16(HIDG_PRODUCT_NUM),
71 	/* .bcdDevice = f(hardware) */
72 	/* .iManufacturer = DYNAMIC */
73 	/* .iProduct = DYNAMIC */
74 	/* NO SERIAL NUMBER */
75 	.bNumConfigurations =	1,
76 };
77 
78 static struct usb_otg_descriptor otg_descriptor = {
79 	.bLength =		sizeof otg_descriptor,
80 	.bDescriptorType =	USB_DT_OTG,
81 
82 	/* REVISIT SRP-only hardware is possible, although
83 	 * it would not be called "OTG" ...
84 	 */
85 	.bmAttributes =		USB_OTG_SRP | USB_OTG_HNP,
86 };
87 
88 static const struct usb_descriptor_header *otg_desc[] = {
89 	(struct usb_descriptor_header *) &otg_descriptor,
90 	NULL,
91 };
92 
93 
94 /* string IDs are assigned dynamically */
95 
96 #define STRING_MANUFACTURER_IDX		0
97 #define STRING_PRODUCT_IDX		1
98 
99 static char manufacturer[50];
100 
101 static struct usb_string strings_dev[] = {
102 	[STRING_MANUFACTURER_IDX].s = manufacturer,
103 	[STRING_PRODUCT_IDX].s = DRIVER_DESC,
104 	{  } /* end of list */
105 };
106 
107 static struct usb_gadget_strings stringtab_dev = {
108 	.language	= 0x0409,	/* en-us */
109 	.strings	= strings_dev,
110 };
111 
112 static struct usb_gadget_strings *dev_strings[] = {
113 	&stringtab_dev,
114 	NULL,
115 };
116 
117 
118 
119 /****************************** Configurations ******************************/
120 
do_config(struct usb_configuration * c)121 static int __init do_config(struct usb_configuration *c)
122 {
123 	struct hidg_func_node *e;
124 	int func = 0, status = 0;
125 
126 	if (gadget_is_otg(c->cdev->gadget)) {
127 		c->descriptors = otg_desc;
128 		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
129 	}
130 
131 	list_for_each_entry(e, &hidg_func_list, node) {
132 		status = hidg_bind_config(c, e->func, func++);
133 		if (status)
134 			break;
135 	}
136 
137 	return status;
138 }
139 
140 static struct usb_configuration config_driver = {
141 	.label			= "HID Gadget",
142 	.bConfigurationValue	= 1,
143 	/* .iConfiguration = DYNAMIC */
144 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
145 };
146 
147 /****************************** Gadget Bind ******************************/
148 
hid_bind(struct usb_composite_dev * cdev)149 static int __init hid_bind(struct usb_composite_dev *cdev)
150 {
151 	struct usb_gadget *gadget = cdev->gadget;
152 	struct list_head *tmp;
153 	int status, gcnum, funcs = 0;
154 
155 	list_for_each(tmp, &hidg_func_list)
156 		funcs++;
157 
158 	if (!funcs)
159 		return -ENODEV;
160 
161 	/* set up HID */
162 	status = ghid_setup(cdev->gadget, funcs);
163 	if (status < 0)
164 		return status;
165 
166 	gcnum = usb_gadget_controller_number(gadget);
167 	if (gcnum >= 0)
168 		device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
169 	else
170 		device_desc.bcdDevice = cpu_to_le16(0x0300 | 0x0099);
171 
172 
173 	/* Allocate string descriptor numbers ... note that string
174 	 * contents can be overridden by the composite_dev glue.
175 	 */
176 
177 	/* device descriptor strings: manufacturer, product */
178 	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
179 		init_utsname()->sysname, init_utsname()->release,
180 		gadget->name);
181 	status = usb_string_id(cdev);
182 	if (status < 0)
183 		return status;
184 	strings_dev[STRING_MANUFACTURER_IDX].id = status;
185 	device_desc.iManufacturer = status;
186 
187 	status = usb_string_id(cdev);
188 	if (status < 0)
189 		return status;
190 	strings_dev[STRING_PRODUCT_IDX].id = status;
191 	device_desc.iProduct = status;
192 
193 	/* register our configuration */
194 	status = usb_add_config(cdev, &config_driver, do_config);
195 	if (status < 0)
196 		return status;
197 
198 	dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
199 
200 	return 0;
201 }
202 
hid_unbind(struct usb_composite_dev * cdev)203 static int __exit hid_unbind(struct usb_composite_dev *cdev)
204 {
205 	ghid_cleanup();
206 	return 0;
207 }
208 
hidg_plat_driver_probe(struct platform_device * pdev)209 static int __init hidg_plat_driver_probe(struct platform_device *pdev)
210 {
211 	struct hidg_func_descriptor *func = pdev->dev.platform_data;
212 	struct hidg_func_node *entry;
213 
214 	if (!func) {
215 		dev_err(&pdev->dev, "Platform data missing\n");
216 		return -ENODEV;
217 	}
218 
219 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
220 	if (!entry)
221 		return -ENOMEM;
222 
223 	entry->func = func;
224 	list_add_tail(&entry->node, &hidg_func_list);
225 
226 	return 0;
227 }
228 
hidg_plat_driver_remove(struct platform_device * pdev)229 static int __devexit hidg_plat_driver_remove(struct platform_device *pdev)
230 {
231 	struct hidg_func_node *e, *n;
232 
233 	list_for_each_entry_safe(e, n, &hidg_func_list, node) {
234 		list_del(&e->node);
235 		kfree(e);
236 	}
237 
238 	return 0;
239 }
240 
241 
242 /****************************** Some noise ******************************/
243 
244 
245 static struct usb_composite_driver hidg_driver = {
246 	.name		= "g_hid",
247 	.dev		= &device_desc,
248 	.strings	= dev_strings,
249 	.max_speed	= USB_SPEED_HIGH,
250 	.unbind		= __exit_p(hid_unbind),
251 };
252 
253 static struct platform_driver hidg_plat_driver = {
254 	.remove		= __devexit_p(hidg_plat_driver_remove),
255 	.driver		= {
256 		.owner	= THIS_MODULE,
257 		.name	= "hidg",
258 	},
259 };
260 
261 
262 MODULE_DESCRIPTION(DRIVER_DESC);
263 MODULE_AUTHOR("Fabien Chouteau, Peter Korsgaard");
264 MODULE_LICENSE("GPL");
265 
hidg_init(void)266 static int __init hidg_init(void)
267 {
268 	int status;
269 
270 	status = platform_driver_probe(&hidg_plat_driver,
271 				hidg_plat_driver_probe);
272 	if (status < 0)
273 		return status;
274 
275 	status = usb_composite_probe(&hidg_driver, hid_bind);
276 	if (status < 0)
277 		platform_driver_unregister(&hidg_plat_driver);
278 
279 	return status;
280 }
281 module_init(hidg_init);
282 
hidg_cleanup(void)283 static void __exit hidg_cleanup(void)
284 {
285 	platform_driver_unregister(&hidg_plat_driver);
286 	usb_composite_unregister(&hidg_driver);
287 }
288 module_exit(hidg_cleanup);
289