diff options
author | Felipe Balbi <felipe.balbi@nokia.com> | 2009-12-17 06:01:37 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-02 17:53:21 -0500 |
commit | d1b5b5c0a8a8204f0c51d5eb99736ecfb2fd5b4e (patch) | |
tree | bc6f229bdcdd716d25efc4603d933eacbdd3d1c8 /drivers/usb/otg/twl4030-usb.c | |
parent | e9a20171dfa0aa134d2211126d1310f2daea52cf (diff) |
USB: otg: twl4030: add support for notifier
it's expected that the transceiver driver will
initialize and call the notifier chain when
necessary. Implement that for twl4030-usb driver.
Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/otg/twl4030-usb.c')
-rw-r--r-- | drivers/usb/otg/twl4030-usb.c | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 2be9f2fa41f9..34452d95b386 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/i2c/twl.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 | 40 | ||
41 | /* Register defines */ | 41 | /* Register defines */ |
42 | 42 | ||
@@ -236,15 +236,6 @@ | |||
236 | #define PMBR1 0x0D | 236 | #define PMBR1 0x0D |
237 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) | 237 | #define GPIO_USB_4PIN_ULPI_2430C (3 << 0) |
238 | 238 | ||
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 { | 239 | struct twl4030_usb { |
249 | struct otg_transceiver otg; | 240 | struct otg_transceiver otg; |
250 | struct device *dev; | 241 | struct device *dev; |
@@ -347,10 +338,10 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) | |||
347 | 338 | ||
348 | /*-------------------------------------------------------------------------*/ | 339 | /*-------------------------------------------------------------------------*/ |
349 | 340 | ||
350 | static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | 341 | static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) |
351 | { | 342 | { |
352 | int status; | 343 | int status; |
353 | int linkstat = USB_LINK_UNKNOWN; | 344 | int linkstat = USB_EVENT_NONE; |
354 | 345 | ||
355 | /* | 346 | /* |
356 | * For ID/VBUS sensing, see manual section 15.4.8 ... | 347 | * For ID/VBUS sensing, see manual section 15.4.8 ... |
@@ -368,11 +359,11 @@ static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
368 | dev_err(twl->dev, "USB link status err %d\n", status); | 359 | dev_err(twl->dev, "USB link status err %d\n", status); |
369 | else if (status & (BIT(7) | BIT(2))) { | 360 | else if (status & (BIT(7) | BIT(2))) { |
370 | if (status & BIT(2)) | 361 | if (status & BIT(2)) |
371 | linkstat = USB_LINK_ID; | 362 | linkstat = USB_EVENT_ID; |
372 | else | 363 | else |
373 | linkstat = USB_LINK_VBUS; | 364 | linkstat = USB_EVENT_VBUS; |
374 | } else | 365 | } else |
375 | linkstat = USB_LINK_NONE; | 366 | linkstat = USB_EVENT_NONE; |
376 | 367 | ||
377 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", | 368 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", |
378 | status, status, linkstat); | 369 | status, status, linkstat); |
@@ -383,7 +374,7 @@ static enum linkstat twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
383 | 374 | ||
384 | spin_lock_irq(&twl->lock); | 375 | spin_lock_irq(&twl->lock); |
385 | twl->linkstat = linkstat; | 376 | twl->linkstat = linkstat; |
386 | if (linkstat == USB_LINK_ID) { | 377 | if (linkstat == USB_EVENT_ID) { |
387 | twl->otg.default_a = true; | 378 | twl->otg.default_a = true; |
388 | twl->otg.state = OTG_STATE_A_IDLE; | 379 | twl->otg.state = OTG_STATE_A_IDLE; |
389 | } else { | 380 | } else { |
@@ -564,7 +555,7 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev, | |||
564 | 555 | ||
565 | spin_lock_irqsave(&twl->lock, flags); | 556 | spin_lock_irqsave(&twl->lock, flags); |
566 | ret = sprintf(buf, "%s\n", | 557 | ret = sprintf(buf, "%s\n", |
567 | (twl->linkstat == USB_LINK_VBUS) ? "on" : "off"); | 558 | (twl->linkstat == USB_EVENT_VBUS) ? "on" : "off"); |
568 | spin_unlock_irqrestore(&twl->lock, flags); | 559 | spin_unlock_irqrestore(&twl->lock, flags); |
569 | 560 | ||
570 | return ret; | 561 | return ret; |
@@ -585,8 +576,7 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
585 | #endif | 576 | #endif |
586 | 577 | ||
587 | status = twl4030_usb_linkstat(twl); | 578 | status = twl4030_usb_linkstat(twl); |
588 | if (status != USB_LINK_UNKNOWN) { | 579 | if (status >= 0) { |
589 | |||
590 | /* FIXME add a set_power() method so that B-devices can | 580 | /* FIXME add a set_power() method so that B-devices can |
591 | * configure the charger appropriately. It's not always | 581 | * configure the charger appropriately. It's not always |
592 | * correct to consume VBUS power, and how much current to | 582 | * correct to consume VBUS power, and how much current to |
@@ -598,12 +588,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
598 | * USB_LINK_VBUS state. musb_hdrc won't care until it | 588 | * USB_LINK_VBUS state. musb_hdrc won't care until it |
599 | * starts to handle softconnect right. | 589 | * starts to handle softconnect right. |
600 | */ | 590 | */ |
601 | if (status == USB_LINK_NONE) | 591 | if (status == USB_EVENT_NONE) |
602 | twl4030_phy_suspend(twl, 0); | 592 | twl4030_phy_suspend(twl, 0); |
603 | else | 593 | else |
604 | twl4030_phy_resume(twl); | 594 | twl4030_phy_resume(twl); |
605 | 595 | ||
606 | twl4030charger_usb_en(status == USB_LINK_VBUS); | 596 | blocking_notifier_call_chain(&twl->otg.notifier, status, |
597 | twl->otg.gadget); | ||
607 | } | 598 | } |
608 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 599 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
609 | 600 | ||
@@ -693,6 +684,8 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
693 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 684 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
694 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | 685 | dev_warn(&pdev->dev, "could not create sysfs file\n"); |
695 | 686 | ||
687 | BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); | ||
688 | |||
696 | /* Our job is to use irqs and status from the power module | 689 | /* Our job is to use irqs and status from the power module |
697 | * to keep the transceiver disabled when nothing's connected. | 690 | * to keep the transceiver disabled when nothing's connected. |
698 | * | 691 | * |