/* Enqueue the request */
list_add(&req->list, &wm831x->auxadc_pending);
ena = !wm831x->auxadc_active;
if (ena) {
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;
}
}
/* Enable the conversion if not already running */ if (!(wm831x->auxadc_active & (1 << input))) {
ret = wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE,
1 << input, 1 << input); if (ret != 0) {
dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret); goto out;
}
wm831x->auxadc_active |= 1 << input;
}
/* We convert at the fastest rate possible */ if (ena) {
ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
WM831X_AUX_CVT_ENA |
WM831X_AUX_RATE_MASK,
WM831X_AUX_CVT_ENA |
WM831X_AUX_RATE_MASK); if (ret != 0) {
dev_err(wm831x->dev, "Failed to start AUXADC: %d\n",
ret); goto out;
}
}
mutex_unlock(&wm831x->auxadc_lock);
/* Wait for an interrupt */
wait_for_completion_timeout(&req->done, msecs_to_jiffies(500));
/* Disable this conversion, we're about to complete all users */
wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE,
1 << input, 0);
wm831x->auxadc_active &= ~(1 << input);
/* Turn off the entire convertor if idle */ if (!wm831x->auxadc_active)
wm831x_reg_write(wm831x, WM831X_AUXADC_CONTROL, 0);
/* Wake up any threads waiting for this request */
list_for_each_entry(req, &wm831x->auxadc_pending, list) { if (req->input == input) {
req->val = val;
complete(&req->done);
}
}
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;
}
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 we're not using interrupts then read the interrupt status register */
msleep(20);
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);
} 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_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)
{ return wm831x->auxadc_read(wm831x, input);
}
EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
/** * 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;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.