Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.9-rc1 250 lines 6.4 kB view raw
1/* 2 * nokia.c -- Nokia Composite Gadget Driver 3 * 4 * Copyright (C) 2008-2010 Nokia Corporation 5 * Contact: Felipe Balbi <felipe.balbi@nokia.com> 6 * 7 * This gadget driver borrows from serial.c which is: 8 * 9 * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) 10 * Copyright (C) 2008 by David Brownell 11 * Copyright (C) 2008 by Nokia Corporation 12 * 13 * This software is distributed under the terms of the GNU General 14 * Public License ("GPL") as published by the Free Software Foundation, 15 * version 2 of that License. 16 */ 17 18#include <linux/kernel.h> 19#include <linux/device.h> 20 21#include "u_serial.h" 22#include "u_ether.h" 23#include "u_phonet.h" 24#include "gadget_chips.h" 25 26/* Defines */ 27 28#define NOKIA_VERSION_NUM 0x0211 29#define NOKIA_LONG_NAME "N900 (PC-Suite Mode)" 30 31/*-------------------------------------------------------------------------*/ 32 33/* 34 * Kbuild is not very cooperative with respect to linking separately 35 * compiled library objects into one module. So for now we won't use 36 * separate compilation ... ensuring init/exit sections work to shrink 37 * the runtime footprint, and giving us at least some parts of what 38 * a "gcc --combine ... part1.c part2.c part3.c ... " build would. 39 */ 40#define USB_FACM_INCLUDED 41#include "f_acm.c" 42#include "f_ecm.c" 43#include "f_obex.c" 44#include "f_serial.c" 45#include "f_phonet.c" 46#include "u_ether.c" 47 48/*-------------------------------------------------------------------------*/ 49USB_GADGET_COMPOSITE_OPTIONS(); 50 51#define NOKIA_VENDOR_ID 0x0421 /* Nokia */ 52#define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */ 53 54/* string IDs are assigned dynamically */ 55 56#define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX 57 58static char manufacturer_nokia[] = "Nokia"; 59static const char product_nokia[] = NOKIA_LONG_NAME; 60static const char description_nokia[] = "PC-Suite Configuration"; 61 62static struct usb_string strings_dev[] = { 63 [USB_GADGET_MANUFACTURER_IDX].s = manufacturer_nokia, 64 [USB_GADGET_PRODUCT_IDX].s = NOKIA_LONG_NAME, 65 [USB_GADGET_SERIAL_IDX].s = "", 66 [STRING_DESCRIPTION_IDX].s = description_nokia, 67 { } /* end of list */ 68}; 69 70static struct usb_gadget_strings stringtab_dev = { 71 .language = 0x0409, /* en-us */ 72 .strings = strings_dev, 73}; 74 75static struct usb_gadget_strings *dev_strings[] = { 76 &stringtab_dev, 77 NULL, 78}; 79 80static struct usb_device_descriptor device_desc = { 81 .bLength = USB_DT_DEVICE_SIZE, 82 .bDescriptorType = USB_DT_DEVICE, 83 .bcdUSB = __constant_cpu_to_le16(0x0200), 84 .bDeviceClass = USB_CLASS_COMM, 85 .idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID), 86 .idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID), 87 .bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM), 88 /* .iManufacturer = DYNAMIC */ 89 /* .iProduct = DYNAMIC */ 90 .bNumConfigurations = 1, 91}; 92 93/*-------------------------------------------------------------------------*/ 94 95/* Module */ 96MODULE_DESCRIPTION("Nokia composite gadget driver for N900"); 97MODULE_AUTHOR("Felipe Balbi"); 98MODULE_LICENSE("GPL"); 99 100/*-------------------------------------------------------------------------*/ 101 102static u8 hostaddr[ETH_ALEN]; 103 104enum { 105 TTY_PORT_OBEX0, 106 TTY_PORT_OBEX1, 107 TTY_PORT_ACM, 108 TTY_PORTS_MAX, 109}; 110 111static unsigned char tty_lines[TTY_PORTS_MAX]; 112 113static int __init nokia_bind_config(struct usb_configuration *c) 114{ 115 int status = 0; 116 117 status = phonet_bind_config(c); 118 if (status) 119 printk(KERN_DEBUG "could not bind phonet config\n"); 120 121 status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX0]); 122 if (status) 123 printk(KERN_DEBUG "could not bind obex config %d\n", 0); 124 125 status = obex_bind_config(c, tty_lines[TTY_PORT_OBEX1]); 126 if (status) 127 printk(KERN_DEBUG "could not bind obex config %d\n", 0); 128 129 status = acm_bind_config(c, tty_lines[TTY_PORT_ACM]); 130 if (status) 131 printk(KERN_DEBUG "could not bind acm config\n"); 132 133 status = ecm_bind_config(c, hostaddr); 134 if (status) 135 printk(KERN_DEBUG "could not bind ecm config\n"); 136 137 return status; 138} 139 140static struct usb_configuration nokia_config_500ma_driver = { 141 .label = "Bus Powered", 142 .bConfigurationValue = 1, 143 /* .iConfiguration = DYNAMIC */ 144 .bmAttributes = USB_CONFIG_ATT_ONE, 145 .MaxPower = 500, 146}; 147 148static struct usb_configuration nokia_config_100ma_driver = { 149 .label = "Self Powered", 150 .bConfigurationValue = 2, 151 /* .iConfiguration = DYNAMIC */ 152 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, 153 .MaxPower = 100, 154}; 155 156static int __init nokia_bind(struct usb_composite_dev *cdev) 157{ 158 struct usb_gadget *gadget = cdev->gadget; 159 int status; 160 int cur_line; 161 162 status = gphonet_setup(cdev->gadget); 163 if (status < 0) 164 goto err_phonet; 165 166 for (cur_line = 0; cur_line < TTY_PORTS_MAX; cur_line++) { 167 status = gserial_alloc_line(&tty_lines[cur_line]); 168 if (status) 169 goto err_ether; 170 } 171 172 status = gether_setup(cdev->gadget, hostaddr); 173 if (status < 0) 174 goto err_ether; 175 176 status = usb_string_ids_tab(cdev, strings_dev); 177 if (status < 0) 178 goto err_usb; 179 device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; 180 device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; 181 status = strings_dev[STRING_DESCRIPTION_IDX].id; 182 nokia_config_500ma_driver.iConfiguration = status; 183 nokia_config_100ma_driver.iConfiguration = status; 184 185 if (!gadget_supports_altsettings(gadget)) 186 goto err_usb; 187 188 /* finally register the configuration */ 189 status = usb_add_config(cdev, &nokia_config_500ma_driver, 190 nokia_bind_config); 191 if (status < 0) 192 goto err_usb; 193 194 status = usb_add_config(cdev, &nokia_config_100ma_driver, 195 nokia_bind_config); 196 if (status < 0) 197 goto err_usb; 198 199 usb_composite_overwrite_options(cdev, &coverwrite); 200 dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME); 201 202 return 0; 203 204err_usb: 205 gether_cleanup(); 206err_ether: 207 cur_line--; 208 while (cur_line >= 0) 209 gserial_free_line(tty_lines[cur_line--]); 210 211 gphonet_cleanup(); 212err_phonet: 213 return status; 214} 215 216static int __exit nokia_unbind(struct usb_composite_dev *cdev) 217{ 218 int i; 219 220 gphonet_cleanup(); 221 222 for (i = 0; i < TTY_PORTS_MAX; i++) 223 gserial_free_line(tty_lines[i]); 224 225 gether_cleanup(); 226 227 return 0; 228} 229 230static __refdata struct usb_composite_driver nokia_driver = { 231 .name = "g_nokia", 232 .dev = &device_desc, 233 .strings = dev_strings, 234 .max_speed = USB_SPEED_HIGH, 235 .bind = nokia_bind, 236 .unbind = __exit_p(nokia_unbind), 237}; 238 239static int __init nokia_init(void) 240{ 241 return usb_composite_probe(&nokia_driver); 242} 243module_init(nokia_init); 244 245static void __exit nokia_cleanup(void) 246{ 247 usb_composite_unregister(&nokia_driver); 248} 249module_exit(nokia_cleanup); 250