diff options
author | George Cherian <george.cherian@ti.com> | 2013-10-10 14:48:39 -0400 |
---|---|---|
committer | Chanwoo Choi <cw00.choi@samsung.com> | 2014-01-06 21:54:27 -0500 |
commit | b7d2d5be3c910fddd19cafa0861016712c665168 (patch) | |
tree | fa1d11ccb1e00760732306e191d56ca5dbc5f885 | |
parent | 5fbc77d6ebd0ab801273085bbf98fdaa66054ad8 (diff) |
extcon: palmas: Handle ID interrupt properly using USB_ID_INT_SRC
Always cross check with the ID state and the source of interrupt.
Also add a case in which ID Source is ID_GND but LATCH state is set
wrongly. This uses the previous Link stat to determine the new state.
Signed-off-by: George Cherian <george.cherian@ti.com>
Acked-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
-rw-r--r-- | drivers/extcon/extcon-palmas.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c index 6e83e9a43d12..2aea4bcdd7f3 100644 --- a/drivers/extcon/extcon-palmas.c +++ b/drivers/extcon/extcon-palmas.c | |||
@@ -78,20 +78,24 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) | |||
78 | 78 | ||
79 | static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) | 79 | static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) |
80 | { | 80 | { |
81 | unsigned int set; | 81 | unsigned int set, id_src; |
82 | struct palmas_usb *palmas_usb = _palmas_usb; | 82 | struct palmas_usb *palmas_usb = _palmas_usb; |
83 | 83 | ||
84 | palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | 84 | palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE, |
85 | PALMAS_USB_ID_INT_LATCH_SET, &set); | 85 | PALMAS_USB_ID_INT_LATCH_SET, &set); |
86 | palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | ||
87 | PALMAS_USB_ID_INT_SRC, &id_src); | ||
86 | 88 | ||
87 | if (set & PALMAS_USB_ID_INT_SRC_ID_GND) { | 89 | if ((set & PALMAS_USB_ID_INT_SRC_ID_GND) && |
90 | (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { | ||
88 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | 91 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, |
89 | PALMAS_USB_ID_INT_LATCH_CLR, | 92 | PALMAS_USB_ID_INT_LATCH_CLR, |
90 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); | 93 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); |
91 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; | 94 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; |
92 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); | 95 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); |
93 | dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); | 96 | dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); |
94 | } else if (set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) { | 97 | } else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) && |
98 | (id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) { | ||
95 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | 99 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, |
96 | PALMAS_USB_ID_INT_LATCH_CLR, | 100 | PALMAS_USB_ID_INT_LATCH_CLR, |
97 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); | 101 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); |
@@ -103,6 +107,11 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) | |||
103 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; | 107 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; |
104 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); | 108 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); |
105 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); | 109 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); |
110 | } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) && | ||
111 | (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { | ||
112 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; | ||
113 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); | ||
114 | dev_info(palmas_usb->dev, " USB-HOST cable is attached\n"); | ||
106 | } | 115 | } |
107 | 116 | ||
108 | return IRQ_HANDLED; | 117 | return IRQ_HANDLED; |