aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2015-12-29 19:55:45 -0500
committerChanwoo Choi <cw00.choi@samsung.com>2016-02-05 00:15:31 -0500
commitb7aad8e2685b0aa58295bc4250c8476c9c7193eb (patch)
treeb55b0b167b9ef6fd47da7140ec04ba6fe0cfd2e8
parentc4924e92442d7218bd725e47fa3988c73aae84c9 (diff)
extcon: palmas: Add the support for VBUS detection by using GPIO
This patch support for VBUS detection by using GPIO pin. Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/extcon/extcon-palmas.c50
-rw-r--r--include/linux/mfd/palmas.h3
2 files changed, 53 insertions, 0 deletions
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c
index 93c30a885740..885ee95a6a7b 100644
--- a/drivers/extcon/extcon-palmas.c
+++ b/drivers/extcon/extcon-palmas.c
@@ -216,11 +216,23 @@ static int palmas_usb_probe(struct platform_device *pdev)
216 return PTR_ERR(palmas_usb->id_gpiod); 216 return PTR_ERR(palmas_usb->id_gpiod);
217 } 217 }
218 218
219 palmas_usb->vbus_gpiod = devm_gpiod_get_optional(&pdev->dev, "vbus",
220 GPIOD_IN);
221 if (IS_ERR(palmas_usb->vbus_gpiod)) {
222 dev_err(&pdev->dev, "failed to get vbus gpio\n");
223 return PTR_ERR(palmas_usb->vbus_gpiod);
224 }
225
219 if (palmas_usb->enable_id_detection && palmas_usb->id_gpiod) { 226 if (palmas_usb->enable_id_detection && palmas_usb->id_gpiod) {
220 palmas_usb->enable_id_detection = false; 227 palmas_usb->enable_id_detection = false;
221 palmas_usb->enable_gpio_id_detection = true; 228 palmas_usb->enable_gpio_id_detection = true;
222 } 229 }
223 230
231 if (palmas_usb->enable_vbus_detection && palmas_usb->vbus_gpiod) {
232 palmas_usb->enable_vbus_detection = false;
233 palmas_usb->enable_gpio_vbus_detection = true;
234 }
235
224 if (palmas_usb->enable_gpio_id_detection) { 236 if (palmas_usb->enable_gpio_id_detection) {
225 u32 debounce; 237 u32 debounce;
226 238
@@ -311,6 +323,40 @@ static int palmas_usb_probe(struct platform_device *pdev)
311 palmas_usb->vbus_irq, status); 323 palmas_usb->vbus_irq, status);
312 return status; 324 return status;
313 } 325 }
326 } else if (palmas_usb->enable_gpio_vbus_detection) {
327 /* remux GPIO_1 as VBUSDET */
328 status = palmas_update_bits(palmas,
329 PALMAS_PU_PD_OD_BASE,
330 PALMAS_PRIMARY_SECONDARY_PAD1,
331 PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK,
332 (1 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT));
333 if (status < 0) {
334 dev_err(&pdev->dev, "can't remux GPIO1\n");
335 return status;
336 }
337
338 palmas_usb->vbus_otg_irq = regmap_irq_get_virq(palmas->irq_data,
339 PALMAS_VBUS_OTG_IRQ);
340 palmas_usb->gpio_vbus_irq = gpiod_to_irq(palmas_usb->vbus_gpiod);
341 if (palmas_usb->gpio_vbus_irq < 0) {
342 dev_err(&pdev->dev, "failed to get vbus irq\n");
343 return palmas_usb->gpio_vbus_irq;
344 }
345 status = devm_request_threaded_irq(&pdev->dev,
346 palmas_usb->gpio_vbus_irq,
347 NULL,
348 palmas_vbus_irq_handler,
349 IRQF_TRIGGER_FALLING |
350 IRQF_TRIGGER_RISING |
351 IRQF_ONESHOT |
352 IRQF_EARLY_RESUME,
353 "palmas_usb_vbus",
354 palmas_usb);
355 if (status < 0) {
356 dev_err(&pdev->dev,
357 "failed to request handler for vbus irq\n");
358 return status;
359 }
314 } 360 }
315 361
316 palmas_enable_irq(palmas_usb); 362 palmas_enable_irq(palmas_usb);
@@ -337,6 +383,8 @@ static int palmas_usb_suspend(struct device *dev)
337 if (device_may_wakeup(dev)) { 383 if (device_may_wakeup(dev)) {
338 if (palmas_usb->enable_vbus_detection) 384 if (palmas_usb->enable_vbus_detection)
339 enable_irq_wake(palmas_usb->vbus_irq); 385 enable_irq_wake(palmas_usb->vbus_irq);
386 if (palmas_usb->enable_gpio_vbus_detection)
387 enable_irq_wake(palmas_usb->gpio_vbus_irq);
340 if (palmas_usb->enable_id_detection) 388 if (palmas_usb->enable_id_detection)
341 enable_irq_wake(palmas_usb->id_irq); 389 enable_irq_wake(palmas_usb->id_irq);
342 if (palmas_usb->enable_gpio_id_detection) 390 if (palmas_usb->enable_gpio_id_detection)
@@ -352,6 +400,8 @@ static int palmas_usb_resume(struct device *dev)
352 if (device_may_wakeup(dev)) { 400 if (device_may_wakeup(dev)) {
353 if (palmas_usb->enable_vbus_detection) 401 if (palmas_usb->enable_vbus_detection)
354 disable_irq_wake(palmas_usb->vbus_irq); 402 disable_irq_wake(palmas_usb->vbus_irq);
403 if (palmas_usb->enable_gpio_vbus_detection)
404 disable_irq_wake(palmas_usb->gpio_vbus_irq);
355 if (palmas_usb->enable_id_detection) 405 if (palmas_usb->enable_id_detection)
356 disable_irq_wake(palmas_usb->id_irq); 406 disable_irq_wake(palmas_usb->id_irq);
357 if (palmas_usb->enable_gpio_id_detection) 407 if (palmas_usb->enable_gpio_id_detection)
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index c800dbc42079..5c9a1d44c125 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -580,7 +580,9 @@ struct palmas_usb {
580 int vbus_irq; 580 int vbus_irq;
581 581
582 int gpio_id_irq; 582 int gpio_id_irq;
583 int gpio_vbus_irq;
583 struct gpio_desc *id_gpiod; 584 struct gpio_desc *id_gpiod;
585 struct gpio_desc *vbus_gpiod;
584 unsigned long sw_debounce_jiffies; 586 unsigned long sw_debounce_jiffies;
585 struct delayed_work wq_detectid; 587 struct delayed_work wq_detectid;
586 588
@@ -589,6 +591,7 @@ struct palmas_usb {
589 bool enable_vbus_detection; 591 bool enable_vbus_detection;
590 bool enable_id_detection; 592 bool enable_id_detection;
591 bool enable_gpio_id_detection; 593 bool enable_gpio_id_detection;
594 bool enable_gpio_vbus_detection;
592}; 595};
593 596
594#define comparator_to_palmas(x) container_of((x), struct palmas_usb, comparator) 597#define comparator_to_palmas(x) container_of((x), struct palmas_usb, comparator)