2 * softupd.c -- Nokia Software Update Gadget
4 * Copyright (C) 2009 Nokia Corporation
5 * Contact: Felipe Balbi <felipe.balbi@nokia.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/kernel.h>
23 #include <linux/utsname.h>
24 #include <linux/device.h>
25 #include <linux/usb/ch9.h>
26 #include <linux/usb/gadget.h>
27 #include "gadget_chips.h"
31 #define NOKIA_VERSION_NUM 0x0100
33 /*-------------------------------------------------------------------------*/
36 * Kbuild is not very cooperative with respect to linking separately
37 * compiled library objects into one module. So for now we won't use
38 * separate compilation ... ensuring init/exit sections work to shrink
39 * the runtime footprint, and giving us at least some parts of what
40 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
42 #include "composite.c"
43 #include "usbstring.c"
45 #include "epautoconf.c"
52 /*-------------------------------------------------------------------------*/
54 #define NOKIA_VENDOR_ID 0x0421 /* Nokia */
55 #define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Update Gadget */
57 /* string IDs are assigned dynamically */
59 #define STRING_MANUFACTURER_IDX 0
60 #define STRING_PRODUCT_IDX 1
61 #define STRING_DESCRIPTION_IDX 2
62 #define STRING_SERIAL_IDX 3
64 static char manufacturer_nokia[] = "Nokia";
65 static const char product_nokia[] = "N900 (PC-Suite Mode)";
66 static const char description_nokia[] = "Firmware Upgrade Configuration";
68 static struct usb_string strings_dev[] = {
69 [STRING_MANUFACTURER_IDX].s = manufacturer_nokia,
70 [STRING_PRODUCT_IDX].s = product_nokia,
71 [STRING_DESCRIPTION_IDX].s = description_nokia,
72 [STRING_SERIAL_IDX].s = "",
76 static struct usb_gadget_strings stringtab_dev = {
77 .language = 0x0409, /* en-us */
78 .strings = strings_dev,
81 static struct usb_gadget_strings *dev_strings[] = {
86 static struct usb_device_descriptor device_desc = {
87 .bLength = USB_DT_DEVICE_SIZE,
88 .bDescriptorType = USB_DT_DEVICE,
90 .bcdUSB = __constant_cpu_to_le16(0x0200),
92 .bDeviceClass = USB_CLASS_COMM,
93 .idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID),
94 .idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID),
96 /* .iManufacturer = DYNAMIC */
97 /* .iProduct = DYNAMIC */
98 /* .iSerialNumber = DYNAMIC */
100 .bNumConfigurations = 1,
103 /*-------------------------------------------------------------------------*/
106 MODULE_DESCRIPTION("Nokia Firmware Upgrade Gadget Driver");
107 MODULE_AUTHOR("Felipe Balbi");
108 MODULE_LICENSE("GPL");
110 /*-------------------------------------------------------------------------*/
112 static int __init softupd_bind_config(struct usb_configuration *c)
116 status = phonet_bind_config(c);
118 struct usb_composite_dev *cdev = c->cdev;
120 dev_err(&cdev->gadget->dev, "could not bind phonet config\n");
123 status = raw_bind_config(c);
125 dev_err(&c->cdev->gadget->dev, "could not bind raw config\n");
130 static struct usb_configuration softupd_config_driver = {
132 .bind = softupd_bind_config,
134 .bmAttributes = USB_CONFIG_ATT_ONE,
137 /* .iConfiguration = DYNAMIC */
138 .bConfigurationValue = 1,
141 static int __init softupd_bind(struct usb_composite_dev *cdev)
143 struct usb_gadget *gadget = cdev->gadget;
147 status = gphonet_setup(cdev->gadget);
151 status = graw_setup(cdev->gadget);
155 status = usb_string_id(cdev);
158 strings_dev[STRING_MANUFACTURER_IDX].id = status;
160 device_desc.iManufacturer = status;
162 status = usb_string_id(cdev);
165 strings_dev[STRING_PRODUCT_IDX].id = status;
167 device_desc.iProduct = status;
169 status = usb_string_id(cdev);
172 strings_dev[STRING_SERIAL_IDX].id = status;
174 device_desc.iSerialNumber = status;
176 /* config description */
177 status = usb_string_id(cdev);
180 strings_dev[STRING_DESCRIPTION_IDX].id = status;
182 softupd_config_driver.iConfiguration = status;
184 /* set up other descriptors */
185 gcnum = usb_gadget_controller_number(gadget);
187 device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM);
189 /* this should only work with hw that supports altsettings
190 * and several endpoints, anything else, panic.
192 pr_err("%s: controller '%s' not recognized\n",
193 __func__, gadget->name);
197 /* finaly register the configuration */
198 status = usb_add_config(cdev, &softupd_config_driver);
202 INFO(cdev, "%s\n", product_nokia);
216 static int softupd_unbind(struct usb_composite_dev *cdev)
224 static struct usb_composite_driver softupd_driver = {
227 .strings = dev_strings,
228 .bind = softupd_bind,
229 .unbind = softupd_unbind,
232 static int __init softupd_init(void)
234 return usb_composite_register(&softupd_driver);
236 module_init(softupd_init);
238 static void __exit softupd_cleanup(void)
240 usb_composite_unregister(&softupd_driver);
242 module_exit(softupd_cleanup);