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