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/utsname.h> 20#include <linux/device.h> 21 22#include "u_serial.h" 23#include "u_ether.h" 24#include "u_phonet.h" 25#include "gadget_chips.h" 26 27/* Defines */ 28 29#define NOKIA_VERSION_NUM 0x0211 30#define NOKIA_LONG_NAME "N900 (PC-Suite Mode)" 31 32/*-------------------------------------------------------------------------*/ 33 34/* 35 * Kbuild is not very cooperative with respect to linking separately 36 * compiled library objects into one module. So for now we won't use 37 * separate compilation ... ensuring init/exit sections work to shrink 38 * the runtime footprint, and giving us at least some parts of what 39 * a "gcc --combine ... part1.c part2.c part3.c ... " build would. 40 */ 41#include "composite.c" 42#include "usbstring.c" 43#include "config.c" 44#include "epautoconf.c" 45 46#include "u_serial.c" 47#include "f_acm.c" 48#include "f_ecm.c" 49#include "f_obex.c" 50#include "f_serial.c" 51#include "f_phonet.c" 52#include "u_ether.c" 53 54/*-------------------------------------------------------------------------*/ 55 56#define NOKIA_VENDOR_ID 0x0421 /* Nokia */ 57#define NOKIA_PRODUCT_ID 0x01c8 /* Nokia Gadget */ 58 59/* string IDs are assigned dynamically */ 60 61#define STRING_MANUFACTURER_IDX 0 62#define STRING_PRODUCT_IDX 1 63#define STRING_DESCRIPTION_IDX 2 64 65static char manufacturer_nokia[] = "Nokia"; 66static const char product_nokia[] = NOKIA_LONG_NAME; 67static const char description_nokia[] = "PC-Suite Configuration"; 68 69static struct usb_string strings_dev[] = { 70 [STRING_MANUFACTURER_IDX].s = manufacturer_nokia, 71 [STRING_PRODUCT_IDX].s = NOKIA_LONG_NAME, 72 [STRING_DESCRIPTION_IDX].s = description_nokia, 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 struct usb_device_descriptor device_desc = { 87 .bLength = USB_DT_DEVICE_SIZE, 88 .bDescriptorType = USB_DT_DEVICE, 89 .bcdUSB = __constant_cpu_to_le16(0x0200), 90 .bDeviceClass = USB_CLASS_COMM, 91 .idVendor = __constant_cpu_to_le16(NOKIA_VENDOR_ID), 92 .idProduct = __constant_cpu_to_le16(NOKIA_PRODUCT_ID), 93 /* .iManufacturer = DYNAMIC */ 94 /* .iProduct = DYNAMIC */ 95 .bNumConfigurations = 1, 96}; 97 98/*-------------------------------------------------------------------------*/ 99 100/* Module */ 101MODULE_DESCRIPTION("Nokia composite gadget driver for N900"); 102MODULE_AUTHOR("Felipe Balbi"); 103MODULE_LICENSE("GPL"); 104 105/*-------------------------------------------------------------------------*/ 106 107static u8 hostaddr[ETH_ALEN]; 108 109static int __init nokia_bind_config(struct usb_configuration *c) 110{ 111 int status = 0; 112 113 status = phonet_bind_config(c); 114 if (status) 115 printk(KERN_DEBUG "could not bind phonet config\n"); 116 117 status = obex_bind_config(c, 0); 118 if (status) 119 printk(KERN_DEBUG "could not bind obex config %d\n", 0); 120 121 status = obex_bind_config(c, 1); 122 if (status) 123 printk(KERN_DEBUG "could not bind obex config %d\n", 0); 124 125 status = acm_bind_config(c, 2); 126 if (status) 127 printk(KERN_DEBUG "could not bind acm config\n"); 128 129 status = ecm_bind_config(c, hostaddr); 130 if (status) 131 printk(KERN_DEBUG "could not bind ecm config\n"); 132 133 return status; 134} 135 136static struct usb_configuration nokia_config_500ma_driver = { 137 .label = "Bus Powered", 138 .bConfigurationValue = 1, 139 /* .iConfiguration = DYNAMIC */ 140 .bmAttributes = USB_CONFIG_ATT_ONE, 141 .bMaxPower = 250, /* 500mA */ 142}; 143 144static struct usb_configuration nokia_config_100ma_driver = { 145 .label = "Self Powered", 146 .bConfigurationValue = 2, 147 /* .iConfiguration = DYNAMIC */ 148 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, 149 .bMaxPower = 50, /* 100 mA */ 150}; 151 152static int __init nokia_bind(struct usb_composite_dev *cdev) 153{ 154 int gcnum; 155 struct usb_gadget *gadget = cdev->gadget; 156 int status; 157 158 status = gphonet_setup(cdev->gadget); 159 if (status < 0) 160 goto err_phonet; 161 162 status = gserial_setup(cdev->gadget, 3); 163 if (status < 0) 164 goto err_serial; 165 166 status = gether_setup(cdev->gadget, hostaddr); 167 if (status < 0) 168 goto err_ether; 169 170 status = usb_string_id(cdev); 171 if (status < 0) 172 goto err_usb; 173 strings_dev[STRING_MANUFACTURER_IDX].id = status; 174 175 device_desc.iManufacturer = status; 176 177 status = usb_string_id(cdev); 178 if (status < 0) 179 goto err_usb; 180 strings_dev[STRING_PRODUCT_IDX].id = status; 181 182 device_desc.iProduct = status; 183 184 /* config description */ 185 status = usb_string_id(cdev); 186 if (status < 0) 187 goto err_usb; 188 strings_dev[STRING_DESCRIPTION_IDX].id = status; 189 190 nokia_config_500ma_driver.iConfiguration = status; 191 nokia_config_100ma_driver.iConfiguration = status; 192 193 /* set up other descriptors */ 194 gcnum = usb_gadget_controller_number(gadget); 195 if (gcnum >= 0) 196 device_desc.bcdDevice = cpu_to_le16(NOKIA_VERSION_NUM); 197 else { 198 /* this should only work with hw that supports altsettings 199 * and several endpoints, anything else, panic. 200 */ 201 pr_err("nokia_bind: controller '%s' not recognized\n", 202 gadget->name); 203 goto err_usb; 204 } 205 206 /* finally register the configuration */ 207 status = usb_add_config(cdev, &nokia_config_500ma_driver, 208 nokia_bind_config); 209 if (status < 0) 210 goto err_usb; 211 212 status = usb_add_config(cdev, &nokia_config_100ma_driver, 213 nokia_bind_config); 214 if (status < 0) 215 goto err_usb; 216 217 dev_info(&gadget->dev, "%s\n", NOKIA_LONG_NAME); 218 219 return 0; 220 221err_usb: 222 gether_cleanup(); 223err_ether: 224 gserial_cleanup(); 225err_serial: 226 gphonet_cleanup(); 227err_phonet: 228 return status; 229} 230 231static int __exit nokia_unbind(struct usb_composite_dev *cdev) 232{ 233 gphonet_cleanup(); 234 gserial_cleanup(); 235 gether_cleanup(); 236 237 return 0; 238} 239 240static struct usb_composite_driver nokia_driver = { 241 .name = "g_nokia", 242 .dev = &device_desc, 243 .strings = dev_strings, 244 .max_speed = USB_SPEED_HIGH, 245 .unbind = __exit_p(nokia_unbind), 246}; 247 248static int __init nokia_init(void) 249{ 250 return usb_composite_probe(&nokia_driver, nokia_bind); 251} 252module_init(nokia_init); 253 254static void __exit nokia_cleanup(void) 255{ 256 usb_composite_unregister(&nokia_driver); 257} 258module_exit(nokia_cleanup); 259 260