aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/wm8350-core.c35
-rw-r--r--include/linux/mfd/wm8350/core.h2
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);
339int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) 339int 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}
386EXPORT_SYMBOL_GPL(wm8350_read_auxadc); 386EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
387 387
388static 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;