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

drivers/misc: add support the FSA9480 USB Switch

The FSA9480 is a USB port accessory detector and switch. This patch adds
support the FSA9480 USB Switch.

[akpm@linux-foundation.org: make a couple of things static]
Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Donggeun Kim and committed by
Linus Torvalds
a1bb73d7 703f03c8

+615
+21
Documentation/ABI/testing/sysfs-bus-i2c-devices-fsa9480
··· 1 + What: /sys/bus/i2c/devices/.../device 2 + Date: February 2011 3 + Contact: Minkyu Kang <mk7.kang@samsung.com> 4 + Description: 5 + show what device is attached 6 + NONE - no device 7 + USB - USB device is attached 8 + UART - UART is attached 9 + CHARGER - Charger is attaced 10 + JIG - JIG is attached 11 + 12 + What: /sys/bus/i2c/devices/.../switch 13 + Date: February 2011 14 + Contact: Minkyu Kang <mk7.kang@samsung.com> 15 + Description: 16 + show or set the state of manual switch 17 + VAUDIO - switch to VAUDIO path 18 + UART - switch to UART path 19 + AUDIO - switch to AUDIO path 20 + DHOST - switch to DHOST path 21 + AUTO - switch automatically by device
+9
drivers/misc/Kconfig
··· 489 489 To compile this driver as a module, choose M here: the module will 490 490 be called pch_phub. 491 491 492 + config USB_SWITCH_FSA9480 493 + tristate "FSA9480 USB Switch" 494 + depends on I2C 495 + help 496 + The FSA9480 is a USB port accessory detector and switch. 497 + The FSA9480 is fully controlled using I2C and enables USB data, 498 + stereo and mono audio, video, microphone and UART data to use 499 + a common connector port. 500 + 492 501 source "drivers/misc/c2port/Kconfig" 493 502 source "drivers/misc/eeprom/Kconfig" 494 503 source "drivers/misc/cb710/Kconfig"
+1
drivers/misc/Makefile
··· 46 46 obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o 47 47 obj-y += lis3lv02d/ 48 48 obj-y += carma/ 49 + obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
+557
drivers/misc/fsa9480.c
··· 1 + /* 2 + * fsa9480.c - FSA9480 micro USB switch device driver 3 + * 4 + * Copyright (C) 2010 Samsung Electronics 5 + * Minkyu Kang <mk7.kang@samsung.com> 6 + * Wonguk Jeong <wonguk.jeong@samsung.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 version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/err.h> 16 + #include <linux/i2c.h> 17 + #include <linux/platform_data/fsa9480.h> 18 + #include <linux/irq.h> 19 + #include <linux/interrupt.h> 20 + #include <linux/workqueue.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/slab.h> 23 + #include <linux/pm_runtime.h> 24 + 25 + /* FSA9480 I2C registers */ 26 + #define FSA9480_REG_DEVID 0x01 27 + #define FSA9480_REG_CTRL 0x02 28 + #define FSA9480_REG_INT1 0x03 29 + #define FSA9480_REG_INT2 0x04 30 + #define FSA9480_REG_INT1_MASK 0x05 31 + #define FSA9480_REG_INT2_MASK 0x06 32 + #define FSA9480_REG_ADC 0x07 33 + #define FSA9480_REG_TIMING1 0x08 34 + #define FSA9480_REG_TIMING2 0x09 35 + #define FSA9480_REG_DEV_T1 0x0a 36 + #define FSA9480_REG_DEV_T2 0x0b 37 + #define FSA9480_REG_BTN1 0x0c 38 + #define FSA9480_REG_BTN2 0x0d 39 + #define FSA9480_REG_CK 0x0e 40 + #define FSA9480_REG_CK_INT1 0x0f 41 + #define FSA9480_REG_CK_INT2 0x10 42 + #define FSA9480_REG_CK_INTMASK1 0x11 43 + #define FSA9480_REG_CK_INTMASK2 0x12 44 + #define FSA9480_REG_MANSW1 0x13 45 + #define FSA9480_REG_MANSW2 0x14 46 + 47 + /* Control */ 48 + #define CON_SWITCH_OPEN (1 << 4) 49 + #define CON_RAW_DATA (1 << 3) 50 + #define CON_MANUAL_SW (1 << 2) 51 + #define CON_WAIT (1 << 1) 52 + #define CON_INT_MASK (1 << 0) 53 + #define CON_MASK (CON_SWITCH_OPEN | CON_RAW_DATA | \ 54 + CON_MANUAL_SW | CON_WAIT) 55 + 56 + /* Device Type 1 */ 57 + #define DEV_USB_OTG (1 << 7) 58 + #define DEV_DEDICATED_CHG (1 << 6) 59 + #define DEV_USB_CHG (1 << 5) 60 + #define DEV_CAR_KIT (1 << 4) 61 + #define DEV_UART (1 << 3) 62 + #define DEV_USB (1 << 2) 63 + #define DEV_AUDIO_2 (1 << 1) 64 + #define DEV_AUDIO_1 (1 << 0) 65 + 66 + #define DEV_T1_USB_MASK (DEV_USB_OTG | DEV_USB) 67 + #define DEV_T1_UART_MASK (DEV_UART) 68 + #define DEV_T1_CHARGER_MASK (DEV_DEDICATED_CHG | DEV_USB_CHG) 69 + 70 + /* Device Type 2 */ 71 + #define DEV_AV (1 << 6) 72 + #define DEV_TTY (1 << 5) 73 + #define DEV_PPD (1 << 4) 74 + #define DEV_JIG_UART_OFF (1 << 3) 75 + #define DEV_JIG_UART_ON (1 << 2) 76 + #define DEV_JIG_USB_OFF (1 << 1) 77 + #define DEV_JIG_USB_ON (1 << 0) 78 + 79 + #define DEV_T2_USB_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON) 80 + #define DEV_T2_UART_MASK (DEV_JIG_UART_OFF | DEV_JIG_UART_ON) 81 + #define DEV_T2_JIG_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON | \ 82 + DEV_JIG_UART_OFF | DEV_JIG_UART_ON) 83 + 84 + /* 85 + * Manual Switch 86 + * D- [7:5] / D+ [4:2] 87 + * 000: Open all / 001: USB / 010: AUDIO / 011: UART / 100: V_AUDIO 88 + */ 89 + #define SW_VAUDIO ((4 << 5) | (4 << 2)) 90 + #define SW_UART ((3 << 5) | (3 << 2)) 91 + #define SW_AUDIO ((2 << 5) | (2 << 2)) 92 + #define SW_DHOST ((1 << 5) | (1 << 2)) 93 + #define SW_AUTO ((0 << 5) | (0 << 2)) 94 + 95 + /* Interrupt 1 */ 96 + #define INT_DETACH (1 << 1) 97 + #define INT_ATTACH (1 << 0) 98 + 99 + struct fsa9480_usbsw { 100 + struct i2c_client *client; 101 + struct fsa9480_platform_data *pdata; 102 + int dev1; 103 + int dev2; 104 + int mansw; 105 + }; 106 + 107 + static struct fsa9480_usbsw *chip; 108 + 109 + static int fsa9480_write_reg(struct i2c_client *client, 110 + int reg, int value) 111 + { 112 + int ret; 113 + 114 + ret = i2c_smbus_write_byte_data(client, reg, value); 115 + 116 + if (ret < 0) 117 + dev_err(&client->dev, "%s: err %d\n", __func__, ret); 118 + 119 + return ret; 120 + } 121 + 122 + static int fsa9480_read_reg(struct i2c_client *client, int reg) 123 + { 124 + int ret; 125 + 126 + ret = i2c_smbus_read_byte_data(client, reg); 127 + 128 + if (ret < 0) 129 + dev_err(&client->dev, "%s: err %d\n", __func__, ret); 130 + 131 + return ret; 132 + } 133 + 134 + static int fsa9480_read_irq(struct i2c_client *client, int *value) 135 + { 136 + int ret; 137 + 138 + ret = i2c_smbus_read_i2c_block_data(client, 139 + FSA9480_REG_INT1, 2, (u8 *)value); 140 + *value &= 0xffff; 141 + 142 + if (ret < 0) 143 + dev_err(&client->dev, "%s: err %d\n", __func__, ret); 144 + 145 + return ret; 146 + } 147 + 148 + static void fsa9480_set_switch(const char *buf) 149 + { 150 + struct fsa9480_usbsw *usbsw = chip; 151 + struct i2c_client *client = usbsw->client; 152 + unsigned int value; 153 + unsigned int path = 0; 154 + 155 + value = fsa9480_read_reg(client, FSA9480_REG_CTRL); 156 + 157 + if (!strncmp(buf, "VAUDIO", 6)) { 158 + path = SW_VAUDIO; 159 + value &= ~CON_MANUAL_SW; 160 + } else if (!strncmp(buf, "UART", 4)) { 161 + path = SW_UART; 162 + value &= ~CON_MANUAL_SW; 163 + } else if (!strncmp(buf, "AUDIO", 5)) { 164 + path = SW_AUDIO; 165 + value &= ~CON_MANUAL_SW; 166 + } else if (!strncmp(buf, "DHOST", 5)) { 167 + path = SW_DHOST; 168 + value &= ~CON_MANUAL_SW; 169 + } else if (!strncmp(buf, "AUTO", 4)) { 170 + path = SW_AUTO; 171 + value |= CON_MANUAL_SW; 172 + } else { 173 + printk(KERN_ERR "Wrong command\n"); 174 + return; 175 + } 176 + 177 + usbsw->mansw = path; 178 + fsa9480_write_reg(client, FSA9480_REG_MANSW1, path); 179 + fsa9480_write_reg(client, FSA9480_REG_CTRL, value); 180 + } 181 + 182 + static ssize_t fsa9480_get_switch(char *buf) 183 + { 184 + struct fsa9480_usbsw *usbsw = chip; 185 + struct i2c_client *client = usbsw->client; 186 + unsigned int value; 187 + 188 + value = fsa9480_read_reg(client, FSA9480_REG_MANSW1); 189 + 190 + if (value == SW_VAUDIO) 191 + return sprintf(buf, "VAUDIO\n"); 192 + else if (value == SW_UART) 193 + return sprintf(buf, "UART\n"); 194 + else if (value == SW_AUDIO) 195 + return sprintf(buf, "AUDIO\n"); 196 + else if (value == SW_DHOST) 197 + return sprintf(buf, "DHOST\n"); 198 + else if (value == SW_AUTO) 199 + return sprintf(buf, "AUTO\n"); 200 + else 201 + return sprintf(buf, "%x", value); 202 + } 203 + 204 + static ssize_t fsa9480_show_device(struct device *dev, 205 + struct device_attribute *attr, 206 + char *buf) 207 + { 208 + struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev); 209 + struct i2c_client *client = usbsw->client; 210 + int dev1, dev2; 211 + 212 + dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1); 213 + dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2); 214 + 215 + if (!dev1 && !dev2) 216 + return sprintf(buf, "NONE\n"); 217 + 218 + /* USB */ 219 + if (dev1 & DEV_T1_USB_MASK || dev2 & DEV_T2_USB_MASK) 220 + return sprintf(buf, "USB\n"); 221 + 222 + /* UART */ 223 + if (dev1 & DEV_T1_UART_MASK || dev2 & DEV_T2_UART_MASK) 224 + return sprintf(buf, "UART\n"); 225 + 226 + /* CHARGER */ 227 + if (dev1 & DEV_T1_CHARGER_MASK) 228 + return sprintf(buf, "CHARGER\n"); 229 + 230 + /* JIG */ 231 + if (dev2 & DEV_T2_JIG_MASK) 232 + return sprintf(buf, "JIG\n"); 233 + 234 + return sprintf(buf, "UNKNOWN\n"); 235 + } 236 + 237 + static ssize_t fsa9480_show_manualsw(struct device *dev, 238 + struct device_attribute *attr, char *buf) 239 + { 240 + return fsa9480_get_switch(buf); 241 + 242 + } 243 + 244 + static ssize_t fsa9480_set_manualsw(struct device *dev, 245 + struct device_attribute *attr, 246 + const char *buf, size_t count) 247 + { 248 + fsa9480_set_switch(buf); 249 + 250 + return count; 251 + } 252 + 253 + static DEVICE_ATTR(device, S_IRUGO, fsa9480_show_device, NULL); 254 + static DEVICE_ATTR(switch, S_IRUGO | S_IWUSR, 255 + fsa9480_show_manualsw, fsa9480_set_manualsw); 256 + 257 + static struct attribute *fsa9480_attributes[] = { 258 + &dev_attr_device.attr, 259 + &dev_attr_switch.attr, 260 + NULL 261 + }; 262 + 263 + static const struct attribute_group fsa9480_group = { 264 + .attrs = fsa9480_attributes, 265 + }; 266 + 267 + static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw, int intr) 268 + { 269 + int val1, val2, ctrl; 270 + struct fsa9480_platform_data *pdata = usbsw->pdata; 271 + struct i2c_client *client = usbsw->client; 272 + 273 + val1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1); 274 + val2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2); 275 + ctrl = fsa9480_read_reg(client, FSA9480_REG_CTRL); 276 + 277 + dev_info(&client->dev, "intr: 0x%x, dev1: 0x%x, dev2: 0x%x\n", 278 + intr, val1, val2); 279 + 280 + if (!intr) 281 + goto out; 282 + 283 + if (intr & INT_ATTACH) { /* Attached */ 284 + /* USB */ 285 + if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) { 286 + if (pdata->usb_cb) 287 + pdata->usb_cb(FSA9480_ATTACHED); 288 + 289 + if (usbsw->mansw) { 290 + fsa9480_write_reg(client, 291 + FSA9480_REG_MANSW1, usbsw->mansw); 292 + } 293 + } 294 + 295 + /* UART */ 296 + if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) { 297 + if (pdata->uart_cb) 298 + pdata->uart_cb(FSA9480_ATTACHED); 299 + 300 + if (!(ctrl & CON_MANUAL_SW)) { 301 + fsa9480_write_reg(client, 302 + FSA9480_REG_MANSW1, SW_UART); 303 + } 304 + } 305 + 306 + /* CHARGER */ 307 + if (val1 & DEV_T1_CHARGER_MASK) { 308 + if (pdata->charger_cb) 309 + pdata->charger_cb(FSA9480_ATTACHED); 310 + } 311 + 312 + /* JIG */ 313 + if (val2 & DEV_T2_JIG_MASK) { 314 + if (pdata->jig_cb) 315 + pdata->jig_cb(FSA9480_ATTACHED); 316 + } 317 + } else if (intr & INT_DETACH) { /* Detached */ 318 + /* USB */ 319 + if (usbsw->dev1 & DEV_T1_USB_MASK || 320 + usbsw->dev2 & DEV_T2_USB_MASK) { 321 + if (pdata->usb_cb) 322 + pdata->usb_cb(FSA9480_DETACHED); 323 + } 324 + 325 + /* UART */ 326 + if (usbsw->dev1 & DEV_T1_UART_MASK || 327 + usbsw->dev2 & DEV_T2_UART_MASK) { 328 + if (pdata->uart_cb) 329 + pdata->uart_cb(FSA9480_DETACHED); 330 + } 331 + 332 + /* CHARGER */ 333 + if (usbsw->dev1 & DEV_T1_CHARGER_MASK) { 334 + if (pdata->charger_cb) 335 + pdata->charger_cb(FSA9480_DETACHED); 336 + } 337 + 338 + /* JIG */ 339 + if (usbsw->dev2 & DEV_T2_JIG_MASK) { 340 + if (pdata->jig_cb) 341 + pdata->jig_cb(FSA9480_DETACHED); 342 + } 343 + } 344 + 345 + usbsw->dev1 = val1; 346 + usbsw->dev2 = val2; 347 + 348 + out: 349 + ctrl &= ~CON_INT_MASK; 350 + fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); 351 + } 352 + 353 + static irqreturn_t fsa9480_irq_handler(int irq, void *data) 354 + { 355 + struct fsa9480_usbsw *usbsw = data; 356 + struct i2c_client *client = usbsw->client; 357 + int intr; 358 + 359 + /* clear interrupt */ 360 + fsa9480_read_irq(client, &intr); 361 + 362 + /* device detection */ 363 + fsa9480_detect_dev(usbsw, intr); 364 + 365 + return IRQ_HANDLED; 366 + } 367 + 368 + static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) 369 + { 370 + struct fsa9480_platform_data *pdata = usbsw->pdata; 371 + struct i2c_client *client = usbsw->client; 372 + int ret; 373 + int intr; 374 + unsigned int ctrl = CON_MASK; 375 + 376 + /* clear interrupt */ 377 + fsa9480_read_irq(client, &intr); 378 + 379 + /* unmask interrupt (attach/detach only) */ 380 + fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0xfc); 381 + fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x1f); 382 + 383 + usbsw->mansw = fsa9480_read_reg(client, FSA9480_REG_MANSW1); 384 + 385 + if (usbsw->mansw) 386 + ctrl &= ~CON_MANUAL_SW; /* Manual Switching Mode */ 387 + 388 + fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); 389 + 390 + if (pdata && pdata->cfg_gpio) 391 + pdata->cfg_gpio(); 392 + 393 + if (client->irq) { 394 + ret = request_threaded_irq(client->irq, NULL, 395 + fsa9480_irq_handler, 396 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 397 + "fsa9480 micro USB", usbsw); 398 + if (ret) { 399 + dev_err(&client->dev, "failed to reqeust IRQ\n"); 400 + return ret; 401 + } 402 + 403 + device_init_wakeup(&client->dev, pdata->wakeup); 404 + } 405 + 406 + return 0; 407 + } 408 + 409 + static int __devinit fsa9480_probe(struct i2c_client *client, 410 + const struct i2c_device_id *id) 411 + { 412 + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 413 + struct fsa9480_usbsw *usbsw; 414 + int ret = 0; 415 + 416 + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 417 + return -EIO; 418 + 419 + usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL); 420 + if (!usbsw) { 421 + dev_err(&client->dev, "failed to allocate driver data\n"); 422 + return -ENOMEM; 423 + } 424 + 425 + usbsw->client = client; 426 + usbsw->pdata = client->dev.platform_data; 427 + 428 + chip = usbsw; 429 + 430 + i2c_set_clientdata(client, usbsw); 431 + 432 + ret = fsa9480_irq_init(usbsw); 433 + if (ret) 434 + goto fail1; 435 + 436 + ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group); 437 + if (ret) { 438 + dev_err(&client->dev, 439 + "failed to create fsa9480 attribute group\n"); 440 + goto fail2; 441 + } 442 + 443 + /* ADC Detect Time: 500ms */ 444 + fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x6); 445 + 446 + if (chip->pdata->reset_cb) 447 + chip->pdata->reset_cb(); 448 + 449 + /* device detection */ 450 + fsa9480_detect_dev(usbsw, INT_ATTACH); 451 + 452 + pm_runtime_set_active(&client->dev); 453 + 454 + return 0; 455 + 456 + fail2: 457 + if (client->irq) 458 + free_irq(client->irq, NULL); 459 + fail1: 460 + i2c_set_clientdata(client, NULL); 461 + kfree(usbsw); 462 + return ret; 463 + } 464 + 465 + static int __devexit fsa9480_remove(struct i2c_client *client) 466 + { 467 + struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); 468 + if (client->irq) 469 + free_irq(client->irq, NULL); 470 + i2c_set_clientdata(client, NULL); 471 + 472 + sysfs_remove_group(&client->dev.kobj, &fsa9480_group); 473 + device_init_wakeup(&client->dev, 0); 474 + kfree(usbsw); 475 + return 0; 476 + } 477 + 478 + #ifdef CONFIG_PM 479 + 480 + static int fsa9480_suspend(struct i2c_client *client, pm_message_t state) 481 + { 482 + struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); 483 + struct fsa9480_platform_data *pdata = usbsw->pdata; 484 + 485 + if (device_may_wakeup(&client->dev) && client->irq) 486 + enable_irq_wake(client->irq); 487 + 488 + if (pdata->usb_power) 489 + pdata->usb_power(0); 490 + 491 + return 0; 492 + } 493 + 494 + static int fsa9480_resume(struct i2c_client *client) 495 + { 496 + struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); 497 + int dev1, dev2; 498 + 499 + if (device_may_wakeup(&client->dev) && client->irq) 500 + disable_irq_wake(client->irq); 501 + 502 + /* 503 + * Clear Pending interrupt. Note that detect_dev does what 504 + * the interrupt handler does. So, we don't miss pending and 505 + * we reenable interrupt if there is one. 506 + */ 507 + fsa9480_read_reg(client, FSA9480_REG_INT1); 508 + fsa9480_read_reg(client, FSA9480_REG_INT2); 509 + 510 + dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1); 511 + dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2); 512 + 513 + /* device detection */ 514 + fsa9480_detect_dev(usbsw, (dev1 || dev2) ? INT_ATTACH : INT_DETACH); 515 + 516 + return 0; 517 + } 518 + 519 + #else 520 + 521 + #define fsa9480_suspend NULL 522 + #define fsa9480_resume NULL 523 + 524 + #endif /* CONFIG_PM */ 525 + 526 + static const struct i2c_device_id fsa9480_id[] = { 527 + {"fsa9480", 0}, 528 + {} 529 + }; 530 + MODULE_DEVICE_TABLE(i2c, fsa9480_id); 531 + 532 + static struct i2c_driver fsa9480_i2c_driver = { 533 + .driver = { 534 + .name = "fsa9480", 535 + }, 536 + .probe = fsa9480_probe, 537 + .remove = __devexit_p(fsa9480_remove), 538 + .resume = fsa9480_resume, 539 + .suspend = fsa9480_suspend, 540 + .id_table = fsa9480_id, 541 + }; 542 + 543 + static int __init fsa9480_init(void) 544 + { 545 + return i2c_add_driver(&fsa9480_i2c_driver); 546 + } 547 + module_init(fsa9480_init); 548 + 549 + static void __exit fsa9480_exit(void) 550 + { 551 + i2c_del_driver(&fsa9480_i2c_driver); 552 + } 553 + module_exit(fsa9480_exit); 554 + 555 + MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>"); 556 + MODULE_DESCRIPTION("FSA9480 USB Switch driver"); 557 + MODULE_LICENSE("GPL");
+27
include/linux/platform_data/fsa9480.h
··· 1 + /* 2 + * Copyright (C) 2010 Samsung Electronics 3 + * Minkyu Kang <mk7.kang@samsung.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #ifndef _FSA9480_H_ 11 + #define _FSA9480_H_ 12 + 13 + #define FSA9480_ATTACHED 1 14 + #define FSA9480_DETACHED 0 15 + 16 + struct fsa9480_platform_data { 17 + void (*cfg_gpio) (void); 18 + void (*usb_cb) (u8 attached); 19 + void (*uart_cb) (u8 attached); 20 + void (*charger_cb) (u8 attached); 21 + void (*jig_cb) (u8 attached); 22 + void (*reset_cb) (void); 23 + void (*usb_power) (u8 on); 24 + int wakeup; 25 + }; 26 + 27 + #endif /* _FSA9480_H_ */