mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-04-01 11:54:10 +00:00
mfd: Use completion interrupt for WM835x AUXADC
Use the completion interrupt generated by the device rather than polling for conversions to complete. As a backup we still check the state of the AUXADC if we don't get a completion, mostly for systems that don't have the WM8350 interrupt infrastructure hooked up. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
11a441ce82
commit
d19663ac61
2 changed files with 31 additions and 6 deletions
|
@ -339,7 +339,6 @@ EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
|
||||||
int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
|
int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
|
||||||
{
|
{
|
||||||
u16 reg, result = 0;
|
u16 reg, result = 0;
|
||||||
int tries = 5;
|
|
||||||
|
|
||||||
if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
|
if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -363,12 +362,13 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
|
||||||
reg |= 1 << channel | WM8350_AUXADC_POLL;
|
reg |= 1 << channel | WM8350_AUXADC_POLL;
|
||||||
wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
|
wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
|
||||||
|
|
||||||
do {
|
/* We ignore the result of the completion and just check for a
|
||||||
schedule_timeout_interruptible(1);
|
* conversion result, allowing us to soldier on if the IRQ
|
||||||
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
|
* infrastructure is not set up for the chip. */
|
||||||
} while ((reg & WM8350_AUXADC_POLL) && --tries);
|
wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5));
|
||||||
|
|
||||||
if (!tries)
|
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
|
||||||
|
if (reg & WM8350_AUXADC_POLL)
|
||||||
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
|
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
|
||||||
else
|
else
|
||||||
result = wm8350_reg_read(wm8350,
|
result = wm8350_reg_read(wm8350,
|
||||||
|
@ -385,6 +385,15 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
|
EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
|
||||||
|
|
||||||
|
static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data)
|
||||||
|
{
|
||||||
|
struct wm8350 *wm8350 = irq_data;
|
||||||
|
|
||||||
|
complete(&wm8350->auxadc_done);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cache is always host endian.
|
* Cache is always host endian.
|
||||||
*/
|
*/
|
||||||
|
@ -682,11 +691,22 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&wm8350->auxadc_mutex);
|
mutex_init(&wm8350->auxadc_mutex);
|
||||||
|
init_completion(&wm8350->auxadc_done);
|
||||||
|
|
||||||
ret = wm8350_irq_init(wm8350, irq, pdata);
|
ret = wm8350_irq_init(wm8350, irq, pdata);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (wm8350->irq_base) {
|
||||||
|
ret = request_threaded_irq(wm8350->irq_base +
|
||||||
|
WM8350_IRQ_AUXADC_DATARDY,
|
||||||
|
NULL, wm8350_auxadc_irq, 0,
|
||||||
|
"auxadc", wm8350);
|
||||||
|
if (ret < 0)
|
||||||
|
dev_warn(wm8350->dev,
|
||||||
|
"Failed to request AUXADC IRQ: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
if (pdata && pdata->init) {
|
if (pdata && pdata->init) {
|
||||||
ret = pdata->init(wm8350);
|
ret = pdata->init(wm8350);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
@ -736,6 +756,9 @@ void wm8350_device_exit(struct wm8350 *wm8350)
|
||||||
platform_device_unregister(wm8350->gpio.pdev);
|
platform_device_unregister(wm8350->gpio.pdev);
|
||||||
platform_device_unregister(wm8350->codec.pdev);
|
platform_device_unregister(wm8350->codec.pdev);
|
||||||
|
|
||||||
|
if (wm8350->irq_base)
|
||||||
|
free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350);
|
||||||
|
|
||||||
wm8350_irq_exit(wm8350);
|
wm8350_irq_exit(wm8350);
|
||||||
|
|
||||||
kfree(wm8350->reg_cache);
|
kfree(wm8350->reg_cache);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
|
|
||||||
#include <linux/mfd/wm8350/audio.h>
|
#include <linux/mfd/wm8350/audio.h>
|
||||||
#include <linux/mfd/wm8350/gpio.h>
|
#include <linux/mfd/wm8350/gpio.h>
|
||||||
|
@ -621,6 +622,7 @@ struct wm8350 {
|
||||||
u16 *reg_cache;
|
u16 *reg_cache;
|
||||||
|
|
||||||
struct mutex auxadc_mutex;
|
struct mutex auxadc_mutex;
|
||||||
|
struct completion auxadc_done;
|
||||||
|
|
||||||
/* Interrupt handling */
|
/* Interrupt handling */
|
||||||
struct mutex irq_lock;
|
struct mutex irq_lock;
|
||||||
|
|
Loading…
Add table
Reference in a new issue