Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.1-rc2 557 lines 13 kB view raw
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 99struct fsa9480_usbsw { 100 struct i2c_client *client; 101 struct fsa9480_platform_data *pdata; 102 int dev1; 103 int dev2; 104 int mansw; 105}; 106 107static struct fsa9480_usbsw *chip; 108 109static 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 122static 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 134static 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 148static 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 182static 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 204static 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 237static 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 244static 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 253static DEVICE_ATTR(device, S_IRUGO, fsa9480_show_device, NULL); 254static DEVICE_ATTR(switch, S_IRUGO | S_IWUSR, 255 fsa9480_show_manualsw, fsa9480_set_manualsw); 256 257static struct attribute *fsa9480_attributes[] = { 258 &dev_attr_device.attr, 259 &dev_attr_switch.attr, 260 NULL 261}; 262 263static const struct attribute_group fsa9480_group = { 264 .attrs = fsa9480_attributes, 265}; 266 267static 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 348out: 349 ctrl &= ~CON_INT_MASK; 350 fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl); 351} 352 353static 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 368static 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 409static 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 456fail2: 457 if (client->irq) 458 free_irq(client->irq, NULL); 459fail1: 460 i2c_set_clientdata(client, NULL); 461 kfree(usbsw); 462 return ret; 463} 464 465static 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 480static 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 494static 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 526static const struct i2c_device_id fsa9480_id[] = { 527 {"fsa9480", 0}, 528 {} 529}; 530MODULE_DEVICE_TABLE(i2c, fsa9480_id); 531 532static 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 543static int __init fsa9480_init(void) 544{ 545 return i2c_add_driver(&fsa9480_i2c_driver); 546} 547module_init(fsa9480_init); 548 549static void __exit fsa9480_exit(void) 550{ 551 i2c_del_driver(&fsa9480_i2c_driver); 552} 553module_exit(fsa9480_exit); 554 555MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>"); 556MODULE_DESCRIPTION("FSA9480 USB Switch driver"); 557MODULE_LICENSE("GPL");