|
@@ -306,161 +306,6 @@ out:
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(wm831x_set_bits);
|
|
EXPORT_SYMBOL_GPL(wm831x_set_bits);
|
|
|
|
|
|
-/**
|
|
|
|
- * wm831x_auxadc_read: Read a value from the WM831x AUXADC
|
|
|
|
- *
|
|
|
|
- * @wm831x: Device to read from.
|
|
|
|
- * @input: AUXADC input to read.
|
|
|
|
- */
|
|
|
|
-int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
|
|
|
|
-{
|
|
|
|
- int ret, src, irq_masked, timeout;
|
|
|
|
-
|
|
|
|
- /* Are we using the interrupt? */
|
|
|
|
- irq_masked = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_1_MASK);
|
|
|
|
- irq_masked &= WM831X_AUXADC_DATA_EINT;
|
|
|
|
-
|
|
|
|
- mutex_lock(&wm831x->auxadc_lock);
|
|
|
|
-
|
|
|
|
- ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
|
|
|
|
- WM831X_AUX_ENA, WM831X_AUX_ENA);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret);
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* We force a single source at present */
|
|
|
|
- src = input;
|
|
|
|
- ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE,
|
|
|
|
- 1 << src);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret);
|
|
|
|
- goto out;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Clear any notification from a very late arriving interrupt */
|
|
|
|
- try_wait_for_completion(&wm831x->auxadc_done);
|
|
|
|
-
|
|
|
|
- ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
|
|
|
|
- WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret);
|
|
|
|
- goto disable;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (irq_masked) {
|
|
|
|
- /* If we're not using interrupts then poll the
|
|
|
|
- * interrupt status register */
|
|
|
|
- timeout = 5;
|
|
|
|
- while (timeout) {
|
|
|
|
- msleep(1);
|
|
|
|
-
|
|
|
|
- ret = wm831x_reg_read(wm831x,
|
|
|
|
- WM831X_INTERRUPT_STATUS_1);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(wm831x->dev,
|
|
|
|
- "ISR 1 read failed: %d\n", ret);
|
|
|
|
- goto disable;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Did it complete? */
|
|
|
|
- if (ret & WM831X_AUXADC_DATA_EINT) {
|
|
|
|
- wm831x_reg_write(wm831x,
|
|
|
|
- WM831X_INTERRUPT_STATUS_1,
|
|
|
|
- WM831X_AUXADC_DATA_EINT);
|
|
|
|
- break;
|
|
|
|
- } else {
|
|
|
|
- dev_err(wm831x->dev,
|
|
|
|
- "AUXADC conversion timeout\n");
|
|
|
|
- ret = -EBUSY;
|
|
|
|
- goto disable;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(wm831x->dev,
|
|
|
|
- "Failed to read AUXADC data: %d\n", ret);
|
|
|
|
- goto disable;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- wm831x->auxadc_data = ret;
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
- /* If we are using interrupts then wait for the
|
|
|
|
- * interrupt to complete. Use an extremely long
|
|
|
|
- * timeout to handle situations with heavy load where
|
|
|
|
- * the notification of the interrupt may be delayed by
|
|
|
|
- * threaded IRQ handling. */
|
|
|
|
- if (!wait_for_completion_timeout(&wm831x->auxadc_done,
|
|
|
|
- msecs_to_jiffies(500))) {
|
|
|
|
- dev_err(wm831x->dev, "Timed out waiting for AUXADC\n");
|
|
|
|
- ret = -EBUSY;
|
|
|
|
- goto disable;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- src = ((wm831x->auxadc_data & WM831X_AUX_DATA_SRC_MASK)
|
|
|
|
- >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
|
|
|
|
-
|
|
|
|
- if (src == 14)
|
|
|
|
- src = WM831X_AUX_CAL;
|
|
|
|
-
|
|
|
|
- if (src != input) {
|
|
|
|
- dev_err(wm831x->dev, "Data from source %d not %d\n",
|
|
|
|
- src, input);
|
|
|
|
- ret = -EINVAL;
|
|
|
|
- } else {
|
|
|
|
- ret = wm831x->auxadc_data & WM831X_AUX_DATA_MASK;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-disable:
|
|
|
|
- wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0);
|
|
|
|
-out:
|
|
|
|
- mutex_unlock(&wm831x->auxadc_lock);
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
|
|
|
|
-
|
|
|
|
-static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
|
|
|
|
-{
|
|
|
|
- struct wm831x *wm831x = irq_data;
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- dev_err(wm831x->dev,
|
|
|
|
- "Failed to read AUXADC data: %d\n", ret);
|
|
|
|
- wm831x->auxadc_data = 0xffff;
|
|
|
|
- } else {
|
|
|
|
- wm831x->auxadc_data = ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- complete(&wm831x->auxadc_done);
|
|
|
|
-
|
|
|
|
- return IRQ_HANDLED;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
|
|
|
|
- *
|
|
|
|
- * @wm831x: Device to read from.
|
|
|
|
- * @input: AUXADC input to read.
|
|
|
|
- */
|
|
|
|
-int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input)
|
|
|
|
-{
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- ret = wm831x_auxadc_read(wm831x, input);
|
|
|
|
- if (ret < 0)
|
|
|
|
- return ret;
|
|
|
|
-
|
|
|
|
- ret *= 1465;
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv);
|
|
|
|
-
|
|
|
|
static struct resource wm831x_dcdc1_resources[] = {
|
|
static struct resource wm831x_dcdc1_resources[] = {
|
|
{
|
|
{
|
|
.start = WM831X_DC1_CONTROL_1,
|
|
.start = WM831X_DC1_CONTROL_1,
|
|
@@ -1447,8 +1292,6 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
|
|
|
|
|
|
mutex_init(&wm831x->io_lock);
|
|
mutex_init(&wm831x->io_lock);
|
|
mutex_init(&wm831x->key_lock);
|
|
mutex_init(&wm831x->key_lock);
|
|
- mutex_init(&wm831x->auxadc_lock);
|
|
|
|
- init_completion(&wm831x->auxadc_done);
|
|
|
|
dev_set_drvdata(wm831x->dev, wm831x);
|
|
dev_set_drvdata(wm831x->dev, wm831x);
|
|
|
|
|
|
ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
|
|
ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
|
|
@@ -1603,15 +1446,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
|
|
if (ret != 0)
|
|
if (ret != 0)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
- if (wm831x->irq_base) {
|
|
|
|
- ret = request_threaded_irq(wm831x->irq_base +
|
|
|
|
- WM831X_IRQ_AUXADC_DATA,
|
|
|
|
- NULL, wm831x_auxadc_irq, 0,
|
|
|
|
- "auxadc", wm831x);
|
|
|
|
- if (ret < 0)
|
|
|
|
- dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
|
|
|
|
- ret);
|
|
|
|
- }
|
|
|
|
|
|
+ wm831x_auxadc_init(wm831x);
|
|
|
|
|
|
/* The core device is up, instantiate the subdevices. */
|
|
/* The core device is up, instantiate the subdevices. */
|
|
switch (parent) {
|
|
switch (parent) {
|