aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/wm831x-core.c36
-rw-r--r--include/linux/mfd/wm831x/core.h2
2 files changed, 31 insertions, 7 deletions
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index c428d9f918fc..07101e9e1cba 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -321,7 +321,6 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits);
321 */ 321 */
322int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) 322int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
323{ 323{
324 int tries = 10;
325 int ret, src; 324 int ret, src;
326 325
327 mutex_lock(&wm831x->auxadc_lock); 326 mutex_lock(&wm831x->auxadc_lock);
@@ -349,13 +348,14 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
349 goto disable; 348 goto disable;
350 } 349 }
351 350
352 do { 351 /* Ignore the result to allow us to soldier on without IRQ hookup */
353 msleep(1); 352 wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5));
354 353
355 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL); 354 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
356 if (ret < 0) 355 if (ret < 0) {
357 ret = WM831X_AUX_CVT_ENA; 356 dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret);
358 } while ((ret & WM831X_AUX_CVT_ENA) && --tries); 357 goto disable;
358 }
359 359
360 if (ret & WM831X_AUX_CVT_ENA) { 360 if (ret & WM831X_AUX_CVT_ENA) {
361 dev_err(wm831x->dev, "Timed out reading AUXADC\n"); 361 dev_err(wm831x->dev, "Timed out reading AUXADC\n");
@@ -390,6 +390,15 @@ out:
390} 390}
391EXPORT_SYMBOL_GPL(wm831x_auxadc_read); 391EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
392 392
393static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
394{
395 struct wm831x *wm831x = irq_data;
396
397 complete(&wm831x->auxadc_done);
398
399 return IRQ_HANDLED;
400}
401
393/** 402/**
394 * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC 403 * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
395 * 404 *
@@ -1411,6 +1420,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1411 mutex_init(&wm831x->io_lock); 1420 mutex_init(&wm831x->io_lock);
1412 mutex_init(&wm831x->key_lock); 1421 mutex_init(&wm831x->key_lock);
1413 mutex_init(&wm831x->auxadc_lock); 1422 mutex_init(&wm831x->auxadc_lock);
1423 init_completion(&wm831x->auxadc_done);
1414 dev_set_drvdata(wm831x->dev, wm831x); 1424 dev_set_drvdata(wm831x->dev, wm831x);
1415 1425
1416 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); 1426 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
@@ -1523,6 +1533,16 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1523 if (ret != 0) 1533 if (ret != 0)
1524 goto err; 1534 goto err;
1525 1535
1536 if (wm831x->irq_base) {
1537 ret = request_threaded_irq(wm831x->irq_base +
1538 WM831X_IRQ_AUXADC_DATA,
1539 NULL, wm831x_auxadc_irq, 0,
1540 "auxadc", wm831x);
1541 if (ret < 0)
1542 dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
1543 ret);
1544 }
1545
1526 /* The core device is up, instantiate the subdevices. */ 1546 /* The core device is up, instantiate the subdevices. */
1527 switch (parent) { 1547 switch (parent) {
1528 case WM8310: 1548 case WM8310:
@@ -1593,6 +1613,8 @@ static void wm831x_device_exit(struct wm831x *wm831x)
1593{ 1613{
1594 wm831x_otp_exit(wm831x); 1614 wm831x_otp_exit(wm831x);
1595 mfd_remove_devices(wm831x->dev); 1615 mfd_remove_devices(wm831x->dev);
1616 if (wm831x->irq_base)
1617 free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
1596 wm831x_irq_exit(wm831x); 1618 wm831x_irq_exit(wm831x);
1597 kfree(wm831x); 1619 kfree(wm831x);
1598} 1620}
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 53580b592bc9..5915f6e3d9ab 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -15,6 +15,7 @@
15#ifndef __MFD_WM831X_CORE_H__ 15#ifndef __MFD_WM831X_CORE_H__
16#define __MFD_WM831X_CORE_H__ 16#define __MFD_WM831X_CORE_H__
17 17
18#include <linux/completion.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19 20
20/* 21/*
@@ -261,6 +262,7 @@ struct wm831x {
261 int num_gpio; 262 int num_gpio;
262 263
263 struct mutex auxadc_lock; 264 struct mutex auxadc_lock;
265 struct completion auxadc_done;
264 266
265 /* The WM831x has a security key blocking access to certain 267 /* The WM831x has a security key blocking access to certain
266 * registers. The mutex is taken by the accessors for locking 268 * registers. The mutex is taken by the accessors for locking