diff options
Diffstat (limited to 'drivers/usb/otg/twl4030-usb.c')
-rw-r--r-- | drivers/usb/otg/twl4030-usb.c | 86 |
1 files changed, 36 insertions, 50 deletions
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 9e3e7a5c258b..223cdf46ccb7 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -33,10 +33,11 @@ | |||
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/usb/otg.h> | 35 | #include <linux/usb/otg.h> |
36 | #include <linux/i2c/twl4030.h> | 36 | #include <linux/i2c/twl.h> |
37 | #include <linux/regulator/consumer.h> | 37 | #include <linux/regulator/consumer.h> |
38 | #include <linux/err.h> | 38 | #include <linux/err.h> |
39 | 39 | #include <linux/notifier.h> | |
40 | #include <linux/slab.h> | ||
40 | 41 | ||
41 | /* Register defines */ | 42 | /* Register defines */ |
42 | 43 | ||
@@ -236,15 +237,6 @@ | |||
236 | #define PMBR1 0x0D | 237 | #define PMBR1 0x0D |
237 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) | 238 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) |
238 | 239 | ||
239 | |||
240 | |||
241 | enum linkstat { | ||
242 | USB_LINK_UNKNOWN = 0, | ||
243 | USB_LINK_NONE, | ||
244 | USB_LINK_VBUS, | ||
245 | USB_LINK_ID, | ||
246 | }; | ||
247 | |||
248 | struct twl4030_usb { | 240 | struct twl4030_usb { |
249 | struct otg_transceiver otg; | 241 | struct otg_transceiver otg; |
250 | struct device *dev; | 242 | struct device *dev; |
@@ -276,16 +268,16 @@ static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, | |||
276 | { | 268 | { |
277 | u8 check; | 269 | u8 check; |
278 | 270 | ||
279 | if ((twl4030_i2c_write_u8(module, data, address) >= 0) && | 271 | if ((twl_i2c_write_u8(module, data, address) >= 0) && |
280 | (twl4030_i2c_read_u8(module, &check, address) >= 0) && | 272 | (twl_i2c_read_u8(module, &check, address) >= 0) && |
281 | (check == data)) | 273 | (check == data)) |
282 | return 0; | 274 | return 0; |
283 | dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", | 275 | dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", |
284 | 1, module, address, check, data); | 276 | 1, module, address, check, data); |
285 | 277 | ||
286 | /* Failed once: Try again */ | 278 | /* Failed once: Try again */ |
287 | if ((twl4030_i2c_write_u8(module, data, address) >= 0) && | 279 | if ((twl_i2c_write_u8(module, data, address) >= 0) && |
288 | (twl4030_i2c_read_u8(module, &check, address) >= 0) && | 280 | (twl_i2c_read_u8(module, &check, address) >= 0) && |
289 | (check == data)) | 281 | (check == data)) |
290 | return 0; | 282 | return 0; |
291 | dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", | 283 | dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", |
@@ -303,7 +295,7 @@ static inline int twl4030_usb_write(struct twl4030_usb *twl, | |||
303 | { | 295 | { |
304 | int ret = 0; | 296 | int ret = 0; |
305 | 297 | ||
306 | ret = twl4030_i2c_write_u8(TWL4030_MODULE_USB, data, address); | 298 | ret = twl_i2c_write_u8(TWL4030_MODULE_USB, data, address); |
307 | if (ret < 0) | 299 | if (ret < 0) |
308 | dev_dbg(twl->dev, | 300 | dev_dbg(twl->dev, |
309 | "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); | 301 | "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); |
@@ -315,7 +307,7 @@ static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) | |||
315 | u8 data; | 307 | u8 data; |
316 | int ret = 0; | 308 | int ret = 0; |
317 | 309 | ||
318 | ret = twl4030_i2c_read_u8(module, &data, address); | 310 | ret = twl_i2c_read_u8(module, &data, address); |
319 | if (ret >= 0) | 311 | if (ret >= 0) |
320 | ret = data; | 312 | ret = data; |
321 | else | 313 | else |
@@ -347,10 +339,10 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) | |||
347 | 339 | ||
348 | /*-------------------------------------------------------------------------*/ | 340 | /*-------------------------------------------------------------------------*/ |
349 | 341 | ||
350 | static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | 342 | static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) |
351 | { | 343 | { |
352 | int status; | 344 | int status; |
353 | int linkstat = USB_LINK_UNKNOWN; | 345 | int linkstat = USB_EVENT_NONE; |
354 | 346 | ||
355 | /* | 347 | /* |
356 | * For ID/VBUS sensing, see manual section 15.4.8 ... | 348 | * For ID/VBUS sensing, see manual section 15.4.8 ... |
@@ -368,11 +360,11 @@ static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
368 | dev_err(twl->dev, "USB link status err %d\n", status); | 360 | dev_err(twl->dev, "USB link status err %d\n", status); |
369 | else if (status & (BIT(7) | BIT(2))) { | 361 | else if (status & (BIT(7) | BIT(2))) { |
370 | if (status & BIT(2)) | 362 | if (status & BIT(2)) |
371 | linkstat = USB_LINK_ID; | 363 | linkstat = USB_EVENT_ID; |
372 | else | 364 | else |
373 | linkstat = USB_LINK_VBUS; | 365 | linkstat = USB_EVENT_VBUS; |
374 | } else | 366 | } else |
375 | linkstat = USB_LINK_NONE; | 367 | linkstat = USB_EVENT_NONE; |
376 | 368 | ||
377 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", | 369 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", |
378 | status, status, linkstat); | 370 | status, status, linkstat); |
@@ -383,7 +375,7 @@ static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
383 | 375 | ||
384 | spin_lock_irq(&twl->lock); | 376 | spin_lock_irq(&twl->lock); |
385 | twl->linkstat = linkstat; | 377 | twl->linkstat = linkstat; |
386 | if (linkstat == USB_LINK_ID) { | 378 | if (linkstat == USB_EVENT_ID) { |
387 | twl->otg.default_a = true; | 379 | twl->otg.default_a = true; |
388 | twl->otg.state = OTG_STATE_A_IDLE; | 380 | twl->otg.state = OTG_STATE_A_IDLE; |
389 | } else { | 381 | } else { |
@@ -462,7 +454,7 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) | |||
462 | * SLEEP. We work around this by clearing the bit after usv3v1 | 454 | * SLEEP. We work around this by clearing the bit after usv3v1 |
463 | * is re-activated. This ensures that VUSB3V1 is really active. | 455 | * is re-activated. This ensures that VUSB3V1 is really active. |
464 | */ | 456 | */ |
465 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, | 457 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, |
466 | VUSB_DEDICATED2); | 458 | VUSB_DEDICATED2); |
467 | regulator_enable(twl->usb1v5); | 459 | regulator_enable(twl->usb1v5); |
468 | pwr &= ~PHY_PWR_PHYPWD; | 460 | pwr &= ~PHY_PWR_PHYPWD; |
@@ -505,44 +497,44 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) | |||
505 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) | 497 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) |
506 | { | 498 | { |
507 | /* Enable writing to power configuration registers */ | 499 | /* Enable writing to power configuration registers */ |
508 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); | 500 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); |
509 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY); | 501 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY); |
510 | 502 | ||
511 | /* put VUSB3V1 LDO in active state */ | 503 | /* put VUSB3V1 LDO in active state */ |
512 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); | 504 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); |
513 | 505 | ||
514 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ | 506 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ |
515 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); | 507 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); |
516 | 508 | ||
517 | /* Initialize 3.1V regulator */ | 509 | /* Initialize 3.1V regulator */ |
518 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); | 510 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); |
519 | 511 | ||
520 | twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); | 512 | twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); |
521 | if (IS_ERR(twl->usb3v1)) | 513 | if (IS_ERR(twl->usb3v1)) |
522 | return -ENODEV; | 514 | return -ENODEV; |
523 | 515 | ||
524 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); | 516 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); |
525 | 517 | ||
526 | /* Initialize 1.5V regulator */ | 518 | /* Initialize 1.5V regulator */ |
527 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); | 519 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); |
528 | 520 | ||
529 | twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); | 521 | twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); |
530 | if (IS_ERR(twl->usb1v5)) | 522 | if (IS_ERR(twl->usb1v5)) |
531 | goto fail1; | 523 | goto fail1; |
532 | 524 | ||
533 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); | 525 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); |
534 | 526 | ||
535 | /* Initialize 1.8V regulator */ | 527 | /* Initialize 1.8V regulator */ |
536 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); | 528 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); |
537 | 529 | ||
538 | twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); | 530 | twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); |
539 | if (IS_ERR(twl->usb1v8)) | 531 | if (IS_ERR(twl->usb1v8)) |
540 | goto fail2; | 532 | goto fail2; |
541 | 533 | ||
542 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); | 534 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); |
543 | 535 | ||
544 | /* disable access to power configuration registers */ | 536 | /* disable access to power configuration registers */ |
545 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); | 537 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); |
546 | 538 | ||
547 | return 0; | 539 | return 0; |
548 | 540 | ||
@@ -564,7 +556,7 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev, | |||
564 | 556 | ||
565 | spin_lock_irqsave(&twl->lock, flags); | 557 | spin_lock_irqsave(&twl->lock, flags); |
566 | ret = sprintf(buf, "%s\n", | 558 | ret = sprintf(buf, "%s\n", |
567 | (twl->linkstat == USB_LINK_VBUS) ? "on" : "off"); | 559 | (twl->linkstat == USB_EVENT_VBUS) ? "on" : "off"); |
568 | spin_unlock_irqrestore(&twl->lock, flags); | 560 | spin_unlock_irqrestore(&twl->lock, flags); |
569 | 561 | ||
570 | return ret; | 562 | return ret; |
@@ -576,17 +568,8 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
576 | struct twl4030_usb *twl = _twl; | 568 | struct twl4030_usb *twl = _twl; |
577 | int status; | 569 | int status; |
578 | 570 | ||
579 | #ifdef CONFIG_LOCKDEP | ||
580 | /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which | ||
581 | * we don't want and can't tolerate. Although it might be | ||
582 | * friendlier not to borrow this thread context... | ||
583 | */ | ||
584 | local_irq_enable(); | ||
585 | #endif | ||
586 | |||
587 | status = twl4030_usb_linkstat(twl); | 571 | status = twl4030_usb_linkstat(twl); |
588 | if (status != USB_LINK_UNKNOWN) { | 572 | if (status >= 0) { |
589 | |||
590 | /* FIXME add a set_power() method so that B-devices can | 573 | /* FIXME add a set_power() method so that B-devices can |
591 | * configure the charger appropriately. It's not always | 574 | * configure the charger appropriately. It's not always |
592 | * correct to consume VBUS power, and how much current to | 575 | * correct to consume VBUS power, and how much current to |
@@ -598,12 +581,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
598 | * USB_LINK_VBUS state. musb_hdrc won't care until it | 581 | * USB_LINK_VBUS state. musb_hdrc won't care until it |
599 | * starts to handle softconnect right. | 582 | * starts to handle softconnect right. |
600 | */ | 583 | */ |
601 | twl4030charger_usb_en(status == USB_LINK_VBUS); | 584 | if (status == USB_EVENT_NONE) |
602 | |||
603 | if (status == USB_LINK_NONE) | ||
604 | twl4030_phy_suspend(twl, 0); | 585 | twl4030_phy_suspend(twl, 0); |
605 | else | 586 | else |
606 | twl4030_phy_resume(twl); | 587 | twl4030_phy_resume(twl); |
588 | |||
589 | blocking_notifier_call_chain(&twl->otg.notifier, status, | ||
590 | twl->otg.gadget); | ||
607 | } | 591 | } |
608 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 592 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
609 | 593 | ||
@@ -693,6 +677,8 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
693 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 677 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
694 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | 678 | dev_warn(&pdev->dev, "could not create sysfs file\n"); |
695 | 679 | ||
680 | BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); | ||
681 | |||
696 | /* Our job is to use irqs and status from the power module | 682 | /* Our job is to use irqs and status from the power module |
697 | * to keep the transceiver disabled when nothing's connected. | 683 | * to keep the transceiver disabled when nothing's connected. |
698 | * | 684 | * |
@@ -702,7 +688,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
702 | * need both handles, otherwise just one suffices. | 688 | * need both handles, otherwise just one suffices. |
703 | */ | 689 | */ |
704 | twl->irq_enabled = true; | 690 | twl->irq_enabled = true; |
705 | status = request_irq(twl->irq, twl4030_usb_irq, | 691 | status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, |
706 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 692 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, |
707 | "twl4030_usb", twl); | 693 | "twl4030_usb", twl); |
708 | if (status < 0) { | 694 | if (status < 0) { |