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