0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/delay.h>
0013 #include <linux/mfd/core.h>
0014 #include <linux/slab.h>
0015 #include <linux/list.h>
0016
0017 #include <linux/mfd/wm831x/core.h>
0018 #include <linux/mfd/wm831x/pdata.h>
0019 #include <linux/mfd/wm831x/irq.h>
0020 #include <linux/mfd/wm831x/auxadc.h>
0021 #include <linux/mfd/wm831x/otp.h>
0022 #include <linux/mfd/wm831x/regulator.h>
0023
0024 struct wm831x_auxadc_req {
0025 struct list_head list;
0026 enum wm831x_auxadc input;
0027 int val;
0028 struct completion done;
0029 };
0030
0031 static int wm831x_auxadc_read_irq(struct wm831x *wm831x,
0032 enum wm831x_auxadc input)
0033 {
0034 struct wm831x_auxadc_req *req;
0035 int ret;
0036 bool ena = false;
0037
0038 req = kzalloc(sizeof(*req), GFP_KERNEL);
0039 if (!req)
0040 return -ENOMEM;
0041
0042 init_completion(&req->done);
0043 req->input = input;
0044 req->val = -ETIMEDOUT;
0045
0046 mutex_lock(&wm831x->auxadc_lock);
0047
0048
0049 list_add(&req->list, &wm831x->auxadc_pending);
0050
0051 ena = !wm831x->auxadc_active;
0052
0053 if (ena) {
0054 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
0055 WM831X_AUX_ENA, WM831X_AUX_ENA);
0056 if (ret != 0) {
0057 dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n",
0058 ret);
0059 goto out;
0060 }
0061 }
0062
0063
0064 if (!(wm831x->auxadc_active & (1 << input))) {
0065 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE,
0066 1 << input, 1 << input);
0067 if (ret != 0) {
0068 dev_err(wm831x->dev,
0069 "Failed to set AUXADC source: %d\n", ret);
0070 goto out;
0071 }
0072
0073 wm831x->auxadc_active |= 1 << input;
0074 }
0075
0076
0077 if (ena) {
0078 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
0079 WM831X_AUX_CVT_ENA |
0080 WM831X_AUX_RATE_MASK,
0081 WM831X_AUX_CVT_ENA |
0082 WM831X_AUX_RATE_MASK);
0083 if (ret != 0) {
0084 dev_err(wm831x->dev, "Failed to start AUXADC: %d\n",
0085 ret);
0086 goto out;
0087 }
0088 }
0089
0090 mutex_unlock(&wm831x->auxadc_lock);
0091
0092
0093 wait_for_completion_timeout(&req->done, msecs_to_jiffies(500));
0094
0095 mutex_lock(&wm831x->auxadc_lock);
0096 ret = req->val;
0097
0098 out:
0099 list_del(&req->list);
0100 mutex_unlock(&wm831x->auxadc_lock);
0101
0102 kfree(req);
0103
0104 return ret;
0105 }
0106
0107 static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
0108 {
0109 struct wm831x *wm831x = irq_data;
0110 struct wm831x_auxadc_req *req;
0111 int ret, input, val;
0112
0113 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
0114 if (ret < 0) {
0115 dev_err(wm831x->dev,
0116 "Failed to read AUXADC data: %d\n", ret);
0117 return IRQ_NONE;
0118 }
0119
0120 input = ((ret & WM831X_AUX_DATA_SRC_MASK)
0121 >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
0122
0123 if (input == 14)
0124 input = WM831X_AUX_CAL;
0125
0126 val = ret & WM831X_AUX_DATA_MASK;
0127
0128 mutex_lock(&wm831x->auxadc_lock);
0129
0130
0131 wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE,
0132 1 << input, 0);
0133 wm831x->auxadc_active &= ~(1 << input);
0134
0135
0136 if (!wm831x->auxadc_active)
0137 wm831x_reg_write(wm831x, WM831X_AUXADC_CONTROL, 0);
0138
0139
0140 list_for_each_entry(req, &wm831x->auxadc_pending, list) {
0141 if (req->input == input) {
0142 req->val = val;
0143 complete(&req->done);
0144 }
0145 }
0146
0147 mutex_unlock(&wm831x->auxadc_lock);
0148
0149 return IRQ_HANDLED;
0150 }
0151
0152 static int wm831x_auxadc_read_polled(struct wm831x *wm831x,
0153 enum wm831x_auxadc input)
0154 {
0155 int ret, src, timeout;
0156
0157 mutex_lock(&wm831x->auxadc_lock);
0158
0159 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
0160 WM831X_AUX_ENA, WM831X_AUX_ENA);
0161 if (ret < 0) {
0162 dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret);
0163 goto out;
0164 }
0165
0166
0167 src = input;
0168 ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE,
0169 1 << src);
0170 if (ret < 0) {
0171 dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret);
0172 goto out;
0173 }
0174
0175 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
0176 WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA);
0177 if (ret < 0) {
0178 dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret);
0179 goto disable;
0180 }
0181
0182
0183
0184 timeout = 5;
0185 while (timeout) {
0186 msleep(1);
0187
0188 ret = wm831x_reg_read(wm831x,
0189 WM831X_INTERRUPT_STATUS_1);
0190 if (ret < 0) {
0191 dev_err(wm831x->dev,
0192 "ISR 1 read failed: %d\n", ret);
0193 goto disable;
0194 }
0195
0196
0197 if (ret & WM831X_AUXADC_DATA_EINT) {
0198 wm831x_reg_write(wm831x,
0199 WM831X_INTERRUPT_STATUS_1,
0200 WM831X_AUXADC_DATA_EINT);
0201 break;
0202 } else {
0203 dev_err(wm831x->dev,
0204 "AUXADC conversion timeout\n");
0205 ret = -EBUSY;
0206 goto disable;
0207 }
0208 }
0209
0210 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
0211 if (ret < 0) {
0212 dev_err(wm831x->dev,
0213 "Failed to read AUXADC data: %d\n", ret);
0214 goto disable;
0215 }
0216
0217 src = ((ret & WM831X_AUX_DATA_SRC_MASK)
0218 >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
0219
0220 if (src == 14)
0221 src = WM831X_AUX_CAL;
0222
0223 if (src != input) {
0224 dev_err(wm831x->dev, "Data from source %d not %d\n",
0225 src, input);
0226 ret = -EINVAL;
0227 } else {
0228 ret &= WM831X_AUX_DATA_MASK;
0229 }
0230
0231 disable:
0232 wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0);
0233 out:
0234 mutex_unlock(&wm831x->auxadc_lock);
0235 return ret;
0236 }
0237
0238
0239
0240
0241
0242
0243
0244 int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
0245 {
0246 return wm831x->auxadc_read(wm831x, input);
0247 }
0248 EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
0249
0250
0251
0252
0253
0254
0255
0256 int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input)
0257 {
0258 int ret;
0259
0260 ret = wm831x_auxadc_read(wm831x, input);
0261 if (ret < 0)
0262 return ret;
0263
0264 ret *= 1465;
0265
0266 return ret;
0267 }
0268 EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv);
0269
0270 void wm831x_auxadc_init(struct wm831x *wm831x)
0271 {
0272 int ret;
0273
0274 mutex_init(&wm831x->auxadc_lock);
0275 INIT_LIST_HEAD(&wm831x->auxadc_pending);
0276
0277 if (wm831x->irq) {
0278 wm831x->auxadc_read = wm831x_auxadc_read_irq;
0279
0280 ret = request_threaded_irq(wm831x_irq(wm831x,
0281 WM831X_IRQ_AUXADC_DATA),
0282 NULL, wm831x_auxadc_irq,
0283 IRQF_ONESHOT,
0284 "auxadc", wm831x);
0285 if (ret < 0) {
0286 dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
0287 ret);
0288 wm831x->auxadc_read = NULL;
0289 }
0290 }
0291
0292 if (!wm831x->auxadc_read)
0293 wm831x->auxadc_read = wm831x_auxadc_read_polled;
0294 }