1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * wm831x-auxadc.c -- AUXADC for Wolfson WM831x PMICs 4 * 5 * Copyright 2009-2011 Wolfson Microelectronics PLC. 6 * 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/delay.h> 13 #include <linux/mfd/core.h> 14 #include <linux/slab.h> 15 #include <linux/list.h> 16 17 #include <linux/mfd/wm831x/core.h> 18 #include <linux/mfd/wm831x/pdata.h> 19 #include <linux/mfd/wm831x/irq.h> 20 #include <linux/mfd/wm831x/auxadc.h> 21 #include <linux/mfd/wm831x/otp.h> 22 #include <linux/mfd/wm831x/regulator.h> 23 24 struct wm831x_auxadc_req { 25 struct list_head list; 26 enum wm831x_auxadc input; 27 int val; 28 struct completion done; 29 }; 30 31 static int wm831x_auxadc_read_irq(struct wm831x *wm831x, 32 enum wm831x_auxadc input) 33 { 34 struct wm831x_auxadc_req *req; 35 int ret; 36 bool ena = false; 37 38 req = kzalloc(sizeof(*req), GFP_KERNEL); 39 if (!req) 40 return -ENOMEM; 41 42 init_completion(&req->done); 43 req->input = input; 44 req->val = -ETIMEDOUT; 45 46 mutex_lock(&wm831x->auxadc_lock); 47 48 /* Enqueue the request */ 49 list_add(&req->list, &wm831x->auxadc_pending); 50 51 ena = !wm831x->auxadc_active; 52 53 if (ena) { 54 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, 55 WM831X_AUX_ENA, WM831X_AUX_ENA); 56 if (ret != 0) { 57 dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", 58 ret); 59 goto out; 60 } 61 } 62 63 /* Enable the conversion if not already running */ 64 if (!(wm831x->auxadc_active & (1 << input))) { 65 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE, 66 1 << input, 1 << input); 67 if (ret != 0) { 68 dev_err(wm831x->dev, 69 "Failed to set AUXADC source: %d\n", ret); 70 goto out; 71 } 72 73 wm831x->auxadc_active |= 1 << input; 74 } 75 76 /* We convert at the fastest rate possible */ 77 if (ena) { 78 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, 79 WM831X_AUX_CVT_ENA | 80 WM831X_AUX_RATE_MASK, 81 WM831X_AUX_CVT_ENA | 82 WM831X_AUX_RATE_MASK); 83 if (ret != 0) { 84 dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", 85 ret); 86 goto out; 87 } 88 } 89 90 mutex_unlock(&wm831x->auxadc_lock); 91 92 /* Wait for an interrupt */ 93 wait_for_completion_timeout(&req->done, msecs_to_jiffies(500)); 94 95 mutex_lock(&wm831x->auxadc_lock); 96 97 list_del(&req->list); 98 ret = req->val; 99 100 out: 101 mutex_unlock(&wm831x->auxadc_lock); 102 103 kfree(req); 104 105 return ret; 106 } 107 108 static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data) 109 { 110 struct wm831x *wm831x = irq_data; 111 struct wm831x_auxadc_req *req; 112 int ret, input, val; 113 114 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA); 115 if (ret < 0) { 116 dev_err(wm831x->dev, 117 "Failed to read AUXADC data: %d\n", ret); 118 return IRQ_NONE; 119 } 120 121 input = ((ret & WM831X_AUX_DATA_SRC_MASK) 122 >> WM831X_AUX_DATA_SRC_SHIFT) - 1; 123 124 if (input == 14) 125 input = WM831X_AUX_CAL; 126 127 val = ret & WM831X_AUX_DATA_MASK; 128 129 mutex_lock(&wm831x->auxadc_lock); 130 131 /* Disable this conversion, we're about to complete all users */ 132 wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE, 133 1 << input, 0); 134 wm831x->auxadc_active &= ~(1 << input); 135 136 /* Turn off the entire convertor if idle */ 137 if (!wm831x->auxadc_active) 138 wm831x_reg_write(wm831x, WM831X_AUXADC_CONTROL, 0); 139 140 /* Wake up any threads waiting for this request */ 141 list_for_each_entry(req, &wm831x->auxadc_pending, list) { 142 if (req->input == input) { 143 req->val = val; 144 complete(&req->done); 145 } 146 } 147 148 mutex_unlock(&wm831x->auxadc_lock); 149 150 return IRQ_HANDLED; 151 } 152 153 static int wm831x_auxadc_read_polled(struct wm831x *wm831x, 154 enum wm831x_auxadc input) 155 { 156 int ret, src, timeout; 157 158 mutex_lock(&wm831x->auxadc_lock); 159 160 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, 161 WM831X_AUX_ENA, WM831X_AUX_ENA); 162 if (ret < 0) { 163 dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret); 164 goto out; 165 } 166 167 /* We force a single source at present */ 168 src = input; 169 ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE, 170 1 << src); 171 if (ret < 0) { 172 dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret); 173 goto out; 174 } 175 176 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, 177 WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA); 178 if (ret < 0) { 179 dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret); 180 goto disable; 181 } 182 183 /* If we're not using interrupts then poll the 184 * interrupt status register */ 185 timeout = 5; 186 while (timeout) { 187 msleep(1); 188 189 ret = wm831x_reg_read(wm831x, 190 WM831X_INTERRUPT_STATUS_1); 191 if (ret < 0) { 192 dev_err(wm831x->dev, 193 "ISR 1 read failed: %d\n", ret); 194 goto disable; 195 } 196 197 /* Did it complete? */ 198 if (ret & WM831X_AUXADC_DATA_EINT) { 199 wm831x_reg_write(wm831x, 200 WM831X_INTERRUPT_STATUS_1, 201 WM831X_AUXADC_DATA_EINT); 202 break; 203 } else { 204 dev_err(wm831x->dev, 205 "AUXADC conversion timeout\n"); 206 ret = -EBUSY; 207 goto disable; 208 } 209 } 210 211 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA); 212 if (ret < 0) { 213 dev_err(wm831x->dev, 214 "Failed to read AUXADC data: %d\n", ret); 215 goto disable; 216 } 217 218 src = ((ret & WM831X_AUX_DATA_SRC_MASK) 219 >> WM831X_AUX_DATA_SRC_SHIFT) - 1; 220 221 if (src == 14) 222 src = WM831X_AUX_CAL; 223 224 if (src != input) { 225 dev_err(wm831x->dev, "Data from source %d not %d\n", 226 src, input); 227 ret = -EINVAL; 228 } else { 229 ret &= WM831X_AUX_DATA_MASK; 230 } 231 232 disable: 233 wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0); 234 out: 235 mutex_unlock(&wm831x->auxadc_lock); 236 return ret; 237 } 238 239 /** 240 * wm831x_auxadc_read: Read a value from the WM831x AUXADC 241 * 242 * @wm831x: Device to read from. 243 * @input: AUXADC input to read. 244 */ 245 int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) 246 { 247 return wm831x->auxadc_read(wm831x, input); 248 } 249 EXPORT_SYMBOL_GPL(wm831x_auxadc_read); 250 251 /** 252 * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC 253 * 254 * @wm831x: Device to read from. 255 * @input: AUXADC input to read. 256 */ 257 int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input) 258 { 259 int ret; 260 261 ret = wm831x_auxadc_read(wm831x, input); 262 if (ret < 0) 263 return ret; 264 265 ret *= 1465; 266 267 return ret; 268 } 269 EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv); 270 271 void wm831x_auxadc_init(struct wm831x *wm831x) 272 { 273 int ret; 274 275 mutex_init(&wm831x->auxadc_lock); 276 INIT_LIST_HEAD(&wm831x->auxadc_pending); 277 278 if (wm831x->irq) { 279 wm831x->auxadc_read = wm831x_auxadc_read_irq; 280 281 ret = request_threaded_irq(wm831x_irq(wm831x, 282 WM831X_IRQ_AUXADC_DATA), 283 NULL, wm831x_auxadc_irq, 284 IRQF_ONESHOT, 285 "auxadc", wm831x); 286 if (ret < 0) { 287 dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n", 288 ret); 289 wm831x->auxadc_read = NULL; 290 } 291 } 292 293 if (!wm831x->auxadc_read) 294 wm831x->auxadc_read = wm831x_auxadc_read_polled; 295 } 296