diff options
-rw-r--r-- | drivers/mfd/wm8350-core.c | 35 | ||||
-rw-r--r-- | include/linux/mfd/wm8350/core.h | 2 |
2 files changed, 31 insertions, 6 deletions
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 9a970bd68775..bd75807d5302 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -339,7 +339,6 @@ EXPORT_SYMBOL_GPL(wm8350_reg_unlock); | |||
339 | int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) | 339 | int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) |
340 | { | 340 | { |
341 | u16 reg, result = 0; | 341 | u16 reg, result = 0; |
342 | int tries = 5; | ||
343 | 342 | ||
344 | if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP) | 343 | if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP) |
345 | return -EINVAL; | 344 | return -EINVAL; |
@@ -363,12 +362,13 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) | |||
363 | reg |= 1 << channel | WM8350_AUXADC_POLL; | 362 | reg |= 1 << channel | WM8350_AUXADC_POLL; |
364 | wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); | 363 | wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); |
365 | 364 | ||
366 | do { | 365 | /* We ignore the result of the completion and just check for a |
367 | schedule_timeout_interruptible(1); | 366 | * conversion result, allowing us to soldier on if the IRQ |
368 | reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); | 367 | * infrastructure is not set up for the chip. */ |
369 | } while ((reg & WM8350_AUXADC_POLL) && --tries); | 368 | wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5)); |
370 | 369 | ||
371 | if (!tries) | 370 | reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); |
371 | if (reg & WM8350_AUXADC_POLL) | ||
372 | dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); | 372 | dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); |
373 | else | 373 | else |
374 | result = wm8350_reg_read(wm8350, | 374 | result = wm8350_reg_read(wm8350, |
@@ -385,6 +385,15 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) | |||
385 | } | 385 | } |
386 | EXPORT_SYMBOL_GPL(wm8350_read_auxadc); | 386 | EXPORT_SYMBOL_GPL(wm8350_read_auxadc); |
387 | 387 | ||
388 | static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data) | ||
389 | { | ||
390 | struct wm8350 *wm8350 = irq_data; | ||
391 | |||
392 | complete(&wm8350->auxadc_done); | ||
393 | |||
394 | return IRQ_HANDLED; | ||
395 | } | ||
396 | |||
388 | /* | 397 | /* |
389 | * Cache is always host endian. | 398 | * Cache is always host endian. |
390 | */ | 399 | */ |
@@ -682,11 +691,22 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, | |||
682 | } | 691 | } |
683 | 692 | ||
684 | mutex_init(&wm8350->auxadc_mutex); | 693 | mutex_init(&wm8350->auxadc_mutex); |
694 | init_completion(&wm8350->auxadc_done); | ||
685 | 695 | ||
686 | ret = wm8350_irq_init(wm8350, irq, pdata); | 696 | ret = wm8350_irq_init(wm8350, irq, pdata); |
687 | if (ret < 0) | 697 | if (ret < 0) |
688 | goto err; | 698 | goto err; |
689 | 699 | ||
700 | if (wm8350->irq_base) { | ||
701 | ret = request_threaded_irq(wm8350->irq_base + | ||
702 | WM8350_IRQ_AUXADC_DATARDY, | ||
703 | NULL, wm8350_auxadc_irq, 0, | ||
704 | "auxadc", wm8350); | ||
705 | if (ret < 0) | ||
706 | dev_warn(wm8350->dev, | ||
707 | "Failed to request AUXADC IRQ: %d\n", ret); | ||
708 | } | ||
709 | |||
690 | if (pdata && pdata->init) { | 710 | if (pdata && pdata->init) { |
691 | ret = pdata->init(wm8350); | 711 | ret = pdata->init(wm8350); |
692 | if (ret != 0) { | 712 | if (ret != 0) { |
@@ -736,6 +756,9 @@ void wm8350_device_exit(struct wm8350 *wm8350) | |||
736 | platform_device_unregister(wm8350->gpio.pdev); | 756 | platform_device_unregister(wm8350->gpio.pdev); |
737 | platform_device_unregister(wm8350->codec.pdev); | 757 | platform_device_unregister(wm8350->codec.pdev); |
738 | 758 | ||
759 | if (wm8350->irq_base) | ||
760 | free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350); | ||
761 | |||
739 | wm8350_irq_exit(wm8350); | 762 | wm8350_irq_exit(wm8350); |
740 | 763 | ||
741 | kfree(wm8350->reg_cache); | 764 | kfree(wm8350->reg_cache); |
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index fae08aa65413..98fcc977e82b 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/completion.h> | ||
19 | 20 | ||
20 | #include <linux/mfd/wm8350/audio.h> | 21 | #include <linux/mfd/wm8350/audio.h> |
21 | #include <linux/mfd/wm8350/gpio.h> | 22 | #include <linux/mfd/wm8350/gpio.h> |
@@ -621,6 +622,7 @@ struct wm8350 { | |||
621 | u16 *reg_cache; | 622 | u16 *reg_cache; |
622 | 623 | ||
623 | struct mutex auxadc_mutex; | 624 | struct mutex auxadc_mutex; |
625 | struct completion auxadc_done; | ||
624 | 626 | ||
625 | /* Interrupt handling */ | 627 | /* Interrupt handling */ |
626 | struct mutex irq_lock; | 628 | struct mutex irq_lock; |