1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * |
4 | * TWL4030 MADC module driver-This driver monitors the real time |
5 | * conversion of analog signals like battery temperature, |
6 | * battery type, battery level etc. |
7 | * |
8 | * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ |
9 | * J Keerthy <j-keerthy@ti.com> |
10 | * |
11 | * Based on twl4030-madc.c |
12 | * Copyright (C) 2008 Nokia Corporation |
13 | * Mikko Ylinen <mikko.k.ylinen@nokia.com> |
14 | * |
15 | * Amit Kucheria <amit.kucheria@canonical.com> |
16 | */ |
17 | |
18 | #include <linux/device.h> |
19 | #include <linux/interrupt.h> |
20 | #include <linux/kernel.h> |
21 | #include <linux/delay.h> |
22 | #include <linux/platform_device.h> |
23 | #include <linux/slab.h> |
24 | #include <linux/mfd/twl.h> |
25 | #include <linux/module.h> |
26 | #include <linux/stddef.h> |
27 | #include <linux/mutex.h> |
28 | #include <linux/bitops.h> |
29 | #include <linux/jiffies.h> |
30 | #include <linux/types.h> |
31 | #include <linux/gfp.h> |
32 | #include <linux/err.h> |
33 | #include <linux/of.h> |
34 | #include <linux/regulator/consumer.h> |
35 | |
36 | #include <linux/iio/iio.h> |
37 | |
38 | #define TWL4030_MADC_MAX_CHANNELS 16 |
39 | |
40 | #define TWL4030_MADC_CTRL1 0x00 |
41 | #define TWL4030_MADC_CTRL2 0x01 |
42 | |
43 | #define TWL4030_MADC_RTSELECT_LSB 0x02 |
44 | #define TWL4030_MADC_SW1SELECT_LSB 0x06 |
45 | #define TWL4030_MADC_SW2SELECT_LSB 0x0A |
46 | |
47 | #define TWL4030_MADC_RTAVERAGE_LSB 0x04 |
48 | #define TWL4030_MADC_SW1AVERAGE_LSB 0x08 |
49 | #define TWL4030_MADC_SW2AVERAGE_LSB 0x0C |
50 | |
51 | #define TWL4030_MADC_CTRL_SW1 0x12 |
52 | #define TWL4030_MADC_CTRL_SW2 0x13 |
53 | |
54 | #define TWL4030_MADC_RTCH0_LSB 0x17 |
55 | #define TWL4030_MADC_GPCH0_LSB 0x37 |
56 | |
57 | #define TWL4030_MADC_MADCON (1 << 0) /* MADC power on */ |
58 | #define TWL4030_MADC_BUSY (1 << 0) /* MADC busy */ |
59 | /* MADC conversion completion */ |
60 | #define TWL4030_MADC_EOC_SW (1 << 1) |
61 | /* MADC SWx start conversion */ |
62 | #define TWL4030_MADC_SW_START (1 << 5) |
63 | #define TWL4030_MADC_ADCIN0 (1 << 0) |
64 | #define TWL4030_MADC_ADCIN1 (1 << 1) |
65 | #define TWL4030_MADC_ADCIN2 (1 << 2) |
66 | #define TWL4030_MADC_ADCIN3 (1 << 3) |
67 | #define TWL4030_MADC_ADCIN4 (1 << 4) |
68 | #define TWL4030_MADC_ADCIN5 (1 << 5) |
69 | #define TWL4030_MADC_ADCIN6 (1 << 6) |
70 | #define TWL4030_MADC_ADCIN7 (1 << 7) |
71 | #define TWL4030_MADC_ADCIN8 (1 << 8) |
72 | #define TWL4030_MADC_ADCIN9 (1 << 9) |
73 | #define TWL4030_MADC_ADCIN10 (1 << 10) |
74 | #define TWL4030_MADC_ADCIN11 (1 << 11) |
75 | #define TWL4030_MADC_ADCIN12 (1 << 12) |
76 | #define TWL4030_MADC_ADCIN13 (1 << 13) |
77 | #define TWL4030_MADC_ADCIN14 (1 << 14) |
78 | #define TWL4030_MADC_ADCIN15 (1 << 15) |
79 | |
80 | /* Fixed channels */ |
81 | #define TWL4030_MADC_BTEMP TWL4030_MADC_ADCIN1 |
82 | #define TWL4030_MADC_VBUS TWL4030_MADC_ADCIN8 |
83 | #define TWL4030_MADC_VBKB TWL4030_MADC_ADCIN9 |
84 | #define TWL4030_MADC_ICHG TWL4030_MADC_ADCIN10 |
85 | #define TWL4030_MADC_VCHG TWL4030_MADC_ADCIN11 |
86 | #define TWL4030_MADC_VBAT TWL4030_MADC_ADCIN12 |
87 | |
88 | /* Step size and prescaler ratio */ |
89 | #define TEMP_STEP_SIZE 147 |
90 | #define TEMP_PSR_R 100 |
91 | #define CURR_STEP_SIZE 147 |
92 | #define CURR_PSR_R1 44 |
93 | #define CURR_PSR_R2 88 |
94 | |
95 | #define TWL4030_BCI_BCICTL1 0x23 |
96 | #define TWL4030_BCI_CGAIN 0x020 |
97 | #define TWL4030_BCI_MESBAT (1 << 1) |
98 | #define TWL4030_BCI_TYPEN (1 << 4) |
99 | #define TWL4030_BCI_ITHEN (1 << 3) |
100 | |
101 | #define REG_BCICTL2 0x024 |
102 | #define TWL4030_BCI_ITHSENS 0x007 |
103 | |
104 | /* Register and bits for GPBR1 register */ |
105 | #define TWL4030_REG_GPBR1 0x0c |
106 | #define TWL4030_GPBR1_MADC_HFCLK_EN (1 << 7) |
107 | |
108 | #define TWL4030_USB_SEL_MADC_MCPC (1<<3) |
109 | #define TWL4030_USB_CARKIT_ANA_CTRL 0xBB |
110 | |
111 | struct twl4030_madc_conversion_method { |
112 | u8 sel; |
113 | u8 avg; |
114 | u8 rbase; |
115 | u8 ctrl; |
116 | }; |
117 | |
118 | /** |
119 | * struct twl4030_madc_request - madc request packet for channel conversion |
120 | * @channels: 16 bit bitmap for individual channels |
121 | * @do_avg: sample the input channel for 4 consecutive cycles |
122 | * @method: RT, SW1, SW2 |
123 | * @type: Polling or interrupt based method |
124 | * @active: Flag if request is active |
125 | * @result_pending: Flag from irq handler, that result is ready |
126 | * @raw: Return raw value, do not convert it |
127 | * @rbuf: Result buffer |
128 | */ |
129 | struct twl4030_madc_request { |
130 | unsigned long channels; |
131 | bool do_avg; |
132 | u16 method; |
133 | u16 type; |
134 | bool active; |
135 | bool result_pending; |
136 | bool raw; |
137 | int rbuf[TWL4030_MADC_MAX_CHANNELS]; |
138 | }; |
139 | |
140 | enum conversion_methods { |
141 | TWL4030_MADC_RT, |
142 | TWL4030_MADC_SW1, |
143 | TWL4030_MADC_SW2, |
144 | TWL4030_MADC_NUM_METHODS |
145 | }; |
146 | |
147 | enum sample_type { |
148 | TWL4030_MADC_WAIT, |
149 | TWL4030_MADC_IRQ_ONESHOT, |
150 | TWL4030_MADC_IRQ_REARM |
151 | }; |
152 | |
153 | /** |
154 | * struct twl4030_madc_data - a container for madc info |
155 | * @dev: Pointer to device structure for madc |
156 | * @lock: Mutex protecting this data structure |
157 | * @usb3v1: Pointer to bias regulator for madc |
158 | * @requests: Array of request struct corresponding to SW1, SW2 and RT |
159 | * @use_second_irq: IRQ selection (main or co-processor) |
160 | * @imr: Interrupt mask register of MADC |
161 | * @isr: Interrupt status register of MADC |
162 | */ |
163 | struct twl4030_madc_data { |
164 | struct device *dev; |
165 | struct mutex lock; |
166 | struct regulator *usb3v1; |
167 | struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS]; |
168 | bool use_second_irq; |
169 | u8 imr; |
170 | u8 isr; |
171 | }; |
172 | |
173 | static int twl4030_madc_conversion(struct twl4030_madc_request *req); |
174 | |
175 | static int twl4030_madc_read(struct iio_dev *iio_dev, |
176 | const struct iio_chan_spec *chan, |
177 | int *val, int *val2, long mask) |
178 | { |
179 | struct twl4030_madc_data *madc = iio_priv(indio_dev: iio_dev); |
180 | struct twl4030_madc_request req; |
181 | int ret; |
182 | |
183 | req.method = madc->use_second_irq ? TWL4030_MADC_SW2 : TWL4030_MADC_SW1; |
184 | |
185 | req.channels = BIT(chan->channel); |
186 | req.active = false; |
187 | req.type = TWL4030_MADC_WAIT; |
188 | req.raw = !(mask == IIO_CHAN_INFO_PROCESSED); |
189 | req.do_avg = (mask == IIO_CHAN_INFO_AVERAGE_RAW); |
190 | |
191 | ret = twl4030_madc_conversion(req: &req); |
192 | if (ret < 0) |
193 | return ret; |
194 | |
195 | *val = req.rbuf[chan->channel]; |
196 | |
197 | return IIO_VAL_INT; |
198 | } |
199 | |
200 | static const struct iio_info twl4030_madc_iio_info = { |
201 | .read_raw = &twl4030_madc_read, |
202 | }; |
203 | |
204 | #define TWL4030_ADC_CHANNEL(_channel, _type, _name) { \ |
205 | .type = _type, \ |
206 | .channel = _channel, \ |
207 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
208 | BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \ |
209 | BIT(IIO_CHAN_INFO_PROCESSED), \ |
210 | .datasheet_name = _name, \ |
211 | .indexed = 1, \ |
212 | } |
213 | |
214 | static const struct iio_chan_spec twl4030_madc_iio_channels[] = { |
215 | TWL4030_ADC_CHANNEL(0, IIO_VOLTAGE, "ADCIN0" ), |
216 | TWL4030_ADC_CHANNEL(1, IIO_TEMP, "ADCIN1" ), |
217 | TWL4030_ADC_CHANNEL(2, IIO_VOLTAGE, "ADCIN2" ), |
218 | TWL4030_ADC_CHANNEL(3, IIO_VOLTAGE, "ADCIN3" ), |
219 | TWL4030_ADC_CHANNEL(4, IIO_VOLTAGE, "ADCIN4" ), |
220 | TWL4030_ADC_CHANNEL(5, IIO_VOLTAGE, "ADCIN5" ), |
221 | TWL4030_ADC_CHANNEL(6, IIO_VOLTAGE, "ADCIN6" ), |
222 | TWL4030_ADC_CHANNEL(7, IIO_VOLTAGE, "ADCIN7" ), |
223 | TWL4030_ADC_CHANNEL(8, IIO_VOLTAGE, "ADCIN8" ), |
224 | TWL4030_ADC_CHANNEL(9, IIO_VOLTAGE, "ADCIN9" ), |
225 | TWL4030_ADC_CHANNEL(10, IIO_CURRENT, "ADCIN10" ), |
226 | TWL4030_ADC_CHANNEL(11, IIO_VOLTAGE, "ADCIN11" ), |
227 | TWL4030_ADC_CHANNEL(12, IIO_VOLTAGE, "ADCIN12" ), |
228 | TWL4030_ADC_CHANNEL(13, IIO_VOLTAGE, "ADCIN13" ), |
229 | TWL4030_ADC_CHANNEL(14, IIO_VOLTAGE, "ADCIN14" ), |
230 | TWL4030_ADC_CHANNEL(15, IIO_VOLTAGE, "ADCIN15" ), |
231 | }; |
232 | |
233 | static struct twl4030_madc_data *twl4030_madc; |
234 | |
235 | static const struct s16_fract twl4030_divider_ratios[16] = { |
236 | {1, 1}, /* CHANNEL 0 No Prescaler */ |
237 | {1, 1}, /* CHANNEL 1 No Prescaler */ |
238 | {6, 10}, /* CHANNEL 2 */ |
239 | {6, 10}, /* CHANNEL 3 */ |
240 | {6, 10}, /* CHANNEL 4 */ |
241 | {6, 10}, /* CHANNEL 5 */ |
242 | {6, 10}, /* CHANNEL 6 */ |
243 | {6, 10}, /* CHANNEL 7 */ |
244 | {3, 14}, /* CHANNEL 8 */ |
245 | {1, 3}, /* CHANNEL 9 */ |
246 | {1, 1}, /* CHANNEL 10 No Prescaler */ |
247 | {15, 100}, /* CHANNEL 11 */ |
248 | {1, 4}, /* CHANNEL 12 */ |
249 | {1, 1}, /* CHANNEL 13 Reserved channels */ |
250 | {1, 1}, /* CHANNEL 14 Reseved channels */ |
251 | {5, 11}, /* CHANNEL 15 */ |
252 | }; |
253 | |
254 | /* Conversion table from -3 to 55 degrees Celcius */ |
255 | static int twl4030_therm_tbl[] = { |
256 | 30800, 29500, 28300, 27100, |
257 | 26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, |
258 | 17900, 17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, |
259 | 12600, 12100, 11600, 11200, 10800, 10400, 10000, 9630, 9280, |
260 | 8950, 8620, 8310, 8020, 7730, 7460, 7200, 6950, 6710, |
261 | 6470, 6250, 6040, 5830, 5640, 5450, 5260, 5090, 4920, |
262 | 4760, 4600, 4450, 4310, 4170, 4040, 3910, 3790, 3670, |
263 | 3550 |
264 | }; |
265 | |
266 | /* |
267 | * Structure containing the registers |
268 | * of different conversion methods supported by MADC. |
269 | * Hardware or RT real time conversion request initiated by external host |
270 | * processor for RT Signal conversions. |
271 | * External host processors can also request for non RT conversions |
272 | * SW1 and SW2 software conversions also called asynchronous or GPC request. |
273 | */ |
274 | static |
275 | const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = { |
276 | [TWL4030_MADC_RT] = { |
277 | .sel = TWL4030_MADC_RTSELECT_LSB, |
278 | .avg = TWL4030_MADC_RTAVERAGE_LSB, |
279 | .rbase = TWL4030_MADC_RTCH0_LSB, |
280 | }, |
281 | [TWL4030_MADC_SW1] = { |
282 | .sel = TWL4030_MADC_SW1SELECT_LSB, |
283 | .avg = TWL4030_MADC_SW1AVERAGE_LSB, |
284 | .rbase = TWL4030_MADC_GPCH0_LSB, |
285 | .ctrl = TWL4030_MADC_CTRL_SW1, |
286 | }, |
287 | [TWL4030_MADC_SW2] = { |
288 | .sel = TWL4030_MADC_SW2SELECT_LSB, |
289 | .avg = TWL4030_MADC_SW2AVERAGE_LSB, |
290 | .rbase = TWL4030_MADC_GPCH0_LSB, |
291 | .ctrl = TWL4030_MADC_CTRL_SW2, |
292 | }, |
293 | }; |
294 | |
295 | /** |
296 | * twl4030_madc_channel_raw_read() - Function to read a particular channel value |
297 | * @madc: pointer to struct twl4030_madc_data |
298 | * @reg: lsb of ADC Channel |
299 | * |
300 | * Return: 0 on success, an error code otherwise. |
301 | */ |
302 | static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg) |
303 | { |
304 | u16 val; |
305 | int ret; |
306 | /* |
307 | * For each ADC channel, we have MSB and LSB register pair. MSB address |
308 | * is always LSB address+1. reg parameter is the address of LSB register |
309 | */ |
310 | ret = twl_i2c_read_u16(mod_no: TWL4030_MODULE_MADC, val: &val, reg); |
311 | if (ret) { |
312 | dev_err(madc->dev, "unable to read register 0x%X\n" , reg); |
313 | return ret; |
314 | } |
315 | |
316 | return (int)(val >> 6); |
317 | } |
318 | |
319 | /* |
320 | * Return battery temperature in degrees Celsius |
321 | * Or < 0 on failure. |
322 | */ |
323 | static int twl4030battery_temperature(int raw_volt) |
324 | { |
325 | u8 val; |
326 | int temp, curr, volt, res, ret; |
327 | |
328 | volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R; |
329 | /* Getting and calculating the supply current in micro amperes */ |
330 | ret = twl_i2c_read_u8(mod_no: TWL_MODULE_MAIN_CHARGE, val: &val, |
331 | REG_BCICTL2); |
332 | if (ret < 0) |
333 | return ret; |
334 | |
335 | curr = ((val & TWL4030_BCI_ITHSENS) + 1) * 10; |
336 | /* Getting and calculating the thermistor resistance in ohms */ |
337 | res = volt * 1000 / curr; |
338 | /* calculating temperature */ |
339 | for (temp = 58; temp >= 0; temp--) { |
340 | int actual = twl4030_therm_tbl[temp]; |
341 | if ((actual - res) >= 0) |
342 | break; |
343 | } |
344 | |
345 | return temp + 1; |
346 | } |
347 | |
348 | static int twl4030battery_current(int raw_volt) |
349 | { |
350 | int ret; |
351 | u8 val; |
352 | |
353 | ret = twl_i2c_read_u8(mod_no: TWL_MODULE_MAIN_CHARGE, val: &val, |
354 | TWL4030_BCI_BCICTL1); |
355 | if (ret) |
356 | return ret; |
357 | if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */ |
358 | return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1; |
359 | else /* slope of 0.88 mV/mA */ |
360 | return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2; |
361 | } |
362 | |
363 | /* |
364 | * Function to read channel values |
365 | * @madc - pointer to twl4030_madc_data struct |
366 | * @reg_base - Base address of the first channel |
367 | * @Channels - 16 bit bitmap. If the bit is set, channel's value is read |
368 | * @buf - The channel values are stored here. if read fails error |
369 | * @raw - Return raw values without conversion |
370 | * value is stored |
371 | * Returns the number of successfully read channels. |
372 | */ |
373 | static int twl4030_madc_read_channels(struct twl4030_madc_data *madc, |
374 | u8 reg_base, unsigned |
375 | long channels, int *buf, |
376 | bool raw) |
377 | { |
378 | int count = 0; |
379 | int i; |
380 | u8 reg; |
381 | |
382 | for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) { |
383 | reg = reg_base + (2 * i); |
384 | buf[i] = twl4030_madc_channel_raw_read(madc, reg); |
385 | if (buf[i] < 0) { |
386 | dev_err(madc->dev, "Unable to read register 0x%X\n" , |
387 | reg); |
388 | return buf[i]; |
389 | } |
390 | if (raw) { |
391 | count++; |
392 | continue; |
393 | } |
394 | switch (i) { |
395 | case 10: |
396 | buf[i] = twl4030battery_current(raw_volt: buf[i]); |
397 | if (buf[i] < 0) { |
398 | dev_err(madc->dev, "err reading current\n" ); |
399 | return buf[i]; |
400 | } else { |
401 | count++; |
402 | buf[i] = buf[i] - 750; |
403 | } |
404 | break; |
405 | case 1: |
406 | buf[i] = twl4030battery_temperature(raw_volt: buf[i]); |
407 | if (buf[i] < 0) { |
408 | dev_err(madc->dev, "err reading temperature\n" ); |
409 | return buf[i]; |
410 | } else { |
411 | buf[i] -= 3; |
412 | count++; |
413 | } |
414 | break; |
415 | default: |
416 | count++; |
417 | /* Analog Input (V) = conv_result * step_size / R |
418 | * conv_result = decimal value of 10-bit conversion |
419 | * result |
420 | * step size = 1.5 / (2 ^ 10 -1) |
421 | * R = Prescaler ratio for input channels. |
422 | * Result given in mV hence multiplied by 1000. |
423 | */ |
424 | buf[i] = (buf[i] * 3 * 1000 * |
425 | twl4030_divider_ratios[i].denominator) |
426 | / (2 * 1023 * |
427 | twl4030_divider_ratios[i].numerator); |
428 | } |
429 | } |
430 | |
431 | return count; |
432 | } |
433 | |
434 | /* |
435 | * Disables irq. |
436 | * @madc - pointer to twl4030_madc_data struct |
437 | * @id - irq number to be disabled |
438 | * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2 |
439 | * corresponding to RT, SW1, SW2 conversion requests. |
440 | * Returns error if i2c read/write fails. |
441 | */ |
442 | static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id) |
443 | { |
444 | u8 val; |
445 | int ret; |
446 | |
447 | ret = twl_i2c_read_u8(mod_no: TWL4030_MODULE_MADC, val: &val, reg: madc->imr); |
448 | if (ret) { |
449 | dev_err(madc->dev, "unable to read imr register 0x%X\n" , |
450 | madc->imr); |
451 | return ret; |
452 | } |
453 | val |= (1 << id); |
454 | ret = twl_i2c_write_u8(mod_no: TWL4030_MODULE_MADC, val, reg: madc->imr); |
455 | if (ret) { |
456 | dev_err(madc->dev, |
457 | "unable to write imr register 0x%X\n" , madc->imr); |
458 | return ret; |
459 | } |
460 | |
461 | return 0; |
462 | } |
463 | |
464 | static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc) |
465 | { |
466 | struct twl4030_madc_data *madc = _madc; |
467 | const struct twl4030_madc_conversion_method *method; |
468 | u8 isr_val, imr_val; |
469 | int i, ret; |
470 | struct twl4030_madc_request *r; |
471 | |
472 | mutex_lock(&madc->lock); |
473 | ret = twl_i2c_read_u8(mod_no: TWL4030_MODULE_MADC, val: &isr_val, reg: madc->isr); |
474 | if (ret) { |
475 | dev_err(madc->dev, "unable to read isr register 0x%X\n" , |
476 | madc->isr); |
477 | goto err_i2c; |
478 | } |
479 | ret = twl_i2c_read_u8(mod_no: TWL4030_MODULE_MADC, val: &imr_val, reg: madc->imr); |
480 | if (ret) { |
481 | dev_err(madc->dev, "unable to read imr register 0x%X\n" , |
482 | madc->imr); |
483 | goto err_i2c; |
484 | } |
485 | isr_val &= ~imr_val; |
486 | for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { |
487 | if (!(isr_val & (1 << i))) |
488 | continue; |
489 | ret = twl4030_madc_disable_irq(madc, id: i); |
490 | if (ret < 0) |
491 | dev_dbg(madc->dev, "Disable interrupt failed %d\n" , i); |
492 | madc->requests[i].result_pending = true; |
493 | } |
494 | for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { |
495 | r = &madc->requests[i]; |
496 | /* No pending results for this method, move to next one */ |
497 | if (!r->result_pending) |
498 | continue; |
499 | method = &twl4030_conversion_methods[r->method]; |
500 | /* Read results */ |
501 | twl4030_madc_read_channels(madc, reg_base: method->rbase, |
502 | channels: r->channels, buf: r->rbuf, raw: r->raw); |
503 | /* Free request */ |
504 | r->result_pending = false; |
505 | r->active = false; |
506 | } |
507 | mutex_unlock(lock: &madc->lock); |
508 | |
509 | return IRQ_HANDLED; |
510 | |
511 | err_i2c: |
512 | /* |
513 | * In case of error check whichever request is active |
514 | * and service the same. |
515 | */ |
516 | for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { |
517 | r = &madc->requests[i]; |
518 | if (!r->active) |
519 | continue; |
520 | method = &twl4030_conversion_methods[r->method]; |
521 | /* Read results */ |
522 | twl4030_madc_read_channels(madc, reg_base: method->rbase, |
523 | channels: r->channels, buf: r->rbuf, raw: r->raw); |
524 | /* Free request */ |
525 | r->result_pending = false; |
526 | r->active = false; |
527 | } |
528 | mutex_unlock(lock: &madc->lock); |
529 | |
530 | return IRQ_HANDLED; |
531 | } |
532 | |
533 | /* |
534 | * Function which enables the madc conversion |
535 | * by writing to the control register. |
536 | * @madc - pointer to twl4030_madc_data struct |
537 | * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1 |
538 | * corresponding to RT SW1 or SW2 conversion methods. |
539 | * Returns 0 if succeeds else a negative error value |
540 | */ |
541 | static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc, |
542 | int conv_method) |
543 | { |
544 | const struct twl4030_madc_conversion_method *method; |
545 | int ret = 0; |
546 | |
547 | if (conv_method != TWL4030_MADC_SW1 && conv_method != TWL4030_MADC_SW2) |
548 | return -ENOTSUPP; |
549 | |
550 | method = &twl4030_conversion_methods[conv_method]; |
551 | ret = twl_i2c_write_u8(mod_no: TWL4030_MODULE_MADC, TWL4030_MADC_SW_START, |
552 | reg: method->ctrl); |
553 | if (ret) { |
554 | dev_err(madc->dev, "unable to write ctrl register 0x%X\n" , |
555 | method->ctrl); |
556 | return ret; |
557 | } |
558 | |
559 | return 0; |
560 | } |
561 | |
562 | /* |
563 | * Function that waits for conversion to be ready |
564 | * @madc - pointer to twl4030_madc_data struct |
565 | * @timeout_ms - timeout value in milliseconds |
566 | * @status_reg - ctrl register |
567 | * returns 0 if succeeds else a negative error value |
568 | */ |
569 | static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc, |
570 | unsigned int timeout_ms, |
571 | u8 status_reg) |
572 | { |
573 | unsigned long timeout; |
574 | int ret; |
575 | |
576 | timeout = jiffies + msecs_to_jiffies(m: timeout_ms); |
577 | do { |
578 | u8 reg; |
579 | |
580 | ret = twl_i2c_read_u8(mod_no: TWL4030_MODULE_MADC, val: ®, reg: status_reg); |
581 | if (ret) { |
582 | dev_err(madc->dev, |
583 | "unable to read status register 0x%X\n" , |
584 | status_reg); |
585 | return ret; |
586 | } |
587 | if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW)) |
588 | return 0; |
589 | usleep_range(min: 500, max: 2000); |
590 | } while (!time_after(jiffies, timeout)); |
591 | dev_err(madc->dev, "conversion timeout!\n" ); |
592 | |
593 | return -EAGAIN; |
594 | } |
595 | |
596 | /* |
597 | * An exported function which can be called from other kernel drivers. |
598 | * @req twl4030_madc_request structure |
599 | * req->rbuf will be filled with read values of channels based on the |
600 | * channel index. If a particular channel reading fails there will |
601 | * be a negative error value in the corresponding array element. |
602 | * returns 0 if succeeds else error value |
603 | */ |
604 | static int twl4030_madc_conversion(struct twl4030_madc_request *req) |
605 | { |
606 | const struct twl4030_madc_conversion_method *method; |
607 | int ret; |
608 | |
609 | if (!req || !twl4030_madc) |
610 | return -EINVAL; |
611 | |
612 | mutex_lock(&twl4030_madc->lock); |
613 | if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) { |
614 | ret = -EINVAL; |
615 | goto out; |
616 | } |
617 | /* Do we have a conversion request ongoing */ |
618 | if (twl4030_madc->requests[req->method].active) { |
619 | ret = -EBUSY; |
620 | goto out; |
621 | } |
622 | method = &twl4030_conversion_methods[req->method]; |
623 | /* Select channels to be converted */ |
624 | ret = twl_i2c_write_u16(mod_no: TWL4030_MODULE_MADC, val: req->channels, reg: method->sel); |
625 | if (ret) { |
626 | dev_err(twl4030_madc->dev, |
627 | "unable to write sel register 0x%X\n" , method->sel); |
628 | goto out; |
629 | } |
630 | /* Select averaging for all channels if do_avg is set */ |
631 | if (req->do_avg) { |
632 | ret = twl_i2c_write_u16(mod_no: TWL4030_MODULE_MADC, val: req->channels, |
633 | reg: method->avg); |
634 | if (ret) { |
635 | dev_err(twl4030_madc->dev, |
636 | "unable to write avg register 0x%X\n" , |
637 | method->avg); |
638 | goto out; |
639 | } |
640 | } |
641 | /* With RT method we should not be here anymore */ |
642 | if (req->method == TWL4030_MADC_RT) { |
643 | ret = -EINVAL; |
644 | goto out; |
645 | } |
646 | ret = twl4030_madc_start_conversion(madc: twl4030_madc, conv_method: req->method); |
647 | if (ret < 0) |
648 | goto out; |
649 | twl4030_madc->requests[req->method].active = true; |
650 | /* Wait until conversion is ready (ctrl register returns EOC) */ |
651 | ret = twl4030_madc_wait_conversion_ready(madc: twl4030_madc, timeout_ms: 5, status_reg: method->ctrl); |
652 | if (ret) { |
653 | twl4030_madc->requests[req->method].active = false; |
654 | goto out; |
655 | } |
656 | ret = twl4030_madc_read_channels(madc: twl4030_madc, reg_base: method->rbase, |
657 | channels: req->channels, buf: req->rbuf, raw: req->raw); |
658 | twl4030_madc->requests[req->method].active = false; |
659 | |
660 | out: |
661 | mutex_unlock(lock: &twl4030_madc->lock); |
662 | |
663 | return ret; |
664 | } |
665 | |
666 | /** |
667 | * twl4030_madc_set_current_generator() - setup bias current |
668 | * |
669 | * @madc: pointer to twl4030_madc_data struct |
670 | * @chan: can be one of the two values: |
671 | * 0 - Enables bias current for main battery type reading |
672 | * 1 - Enables bias current for main battery temperature sensing |
673 | * @on: enable or disable chan. |
674 | * |
675 | * Function to enable or disable bias current for |
676 | * main battery type reading or temperature sensing |
677 | */ |
678 | static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc, |
679 | int chan, int on) |
680 | { |
681 | int ret; |
682 | int regmask; |
683 | u8 regval; |
684 | |
685 | ret = twl_i2c_read_u8(mod_no: TWL_MODULE_MAIN_CHARGE, |
686 | val: ®val, TWL4030_BCI_BCICTL1); |
687 | if (ret) { |
688 | dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X" , |
689 | TWL4030_BCI_BCICTL1); |
690 | return ret; |
691 | } |
692 | |
693 | regmask = chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN; |
694 | if (on) |
695 | regval |= regmask; |
696 | else |
697 | regval &= ~regmask; |
698 | |
699 | ret = twl_i2c_write_u8(mod_no: TWL_MODULE_MAIN_CHARGE, |
700 | val: regval, TWL4030_BCI_BCICTL1); |
701 | if (ret) { |
702 | dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n" , |
703 | TWL4030_BCI_BCICTL1); |
704 | return ret; |
705 | } |
706 | |
707 | return 0; |
708 | } |
709 | |
710 | /* |
711 | * Function that sets MADC software power on bit to enable MADC |
712 | * @madc - pointer to twl4030_madc_data struct |
713 | * @on - Enable or disable MADC software power on bit. |
714 | * returns error if i2c read/write fails else 0 |
715 | */ |
716 | static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on) |
717 | { |
718 | u8 regval; |
719 | int ret; |
720 | |
721 | ret = twl_i2c_read_u8(mod_no: TWL_MODULE_MAIN_CHARGE, |
722 | val: ®val, TWL4030_MADC_CTRL1); |
723 | if (ret) { |
724 | dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n" , |
725 | TWL4030_MADC_CTRL1); |
726 | return ret; |
727 | } |
728 | if (on) |
729 | regval |= TWL4030_MADC_MADCON; |
730 | else |
731 | regval &= ~TWL4030_MADC_MADCON; |
732 | ret = twl_i2c_write_u8(mod_no: TWL4030_MODULE_MADC, val: regval, TWL4030_MADC_CTRL1); |
733 | if (ret) { |
734 | dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n" , |
735 | TWL4030_MADC_CTRL1); |
736 | return ret; |
737 | } |
738 | |
739 | return 0; |
740 | } |
741 | |
742 | /* |
743 | * Initialize MADC and request for threaded irq |
744 | */ |
745 | static int twl4030_madc_probe(struct platform_device *pdev) |
746 | { |
747 | struct twl4030_madc_data *madc; |
748 | struct twl4030_madc_platform_data *pdata = dev_get_platdata(dev: &pdev->dev); |
749 | struct device_node *np = pdev->dev.of_node; |
750 | int irq, ret; |
751 | u8 regval; |
752 | struct iio_dev *iio_dev = NULL; |
753 | |
754 | if (!pdata && !np) { |
755 | dev_err(&pdev->dev, "neither platform data nor Device Tree node available\n" ); |
756 | return -EINVAL; |
757 | } |
758 | |
759 | iio_dev = devm_iio_device_alloc(parent: &pdev->dev, sizeof_priv: sizeof(*madc)); |
760 | if (!iio_dev) { |
761 | dev_err(&pdev->dev, "failed allocating iio device\n" ); |
762 | return -ENOMEM; |
763 | } |
764 | |
765 | madc = iio_priv(indio_dev: iio_dev); |
766 | madc->dev = &pdev->dev; |
767 | |
768 | iio_dev->name = dev_name(dev: &pdev->dev); |
769 | iio_dev->info = &twl4030_madc_iio_info; |
770 | iio_dev->modes = INDIO_DIRECT_MODE; |
771 | iio_dev->channels = twl4030_madc_iio_channels; |
772 | iio_dev->num_channels = ARRAY_SIZE(twl4030_madc_iio_channels); |
773 | |
774 | /* |
775 | * Phoenix provides 2 interrupt lines. The first one is connected to |
776 | * the OMAP. The other one can be connected to the other processor such |
777 | * as modem. Hence two separate ISR and IMR registers. |
778 | */ |
779 | if (pdata) |
780 | madc->use_second_irq = (pdata->irq_line != 1); |
781 | else |
782 | madc->use_second_irq = of_property_read_bool(np, |
783 | propname: "ti,system-uses-second-madc-irq" ); |
784 | |
785 | madc->imr = madc->use_second_irq ? TWL4030_MADC_IMR2 : |
786 | TWL4030_MADC_IMR1; |
787 | madc->isr = madc->use_second_irq ? TWL4030_MADC_ISR2 : |
788 | TWL4030_MADC_ISR1; |
789 | |
790 | ret = twl4030_madc_set_power(madc, on: 1); |
791 | if (ret < 0) |
792 | return ret; |
793 | ret = twl4030_madc_set_current_generator(madc, chan: 0, on: 1); |
794 | if (ret < 0) |
795 | goto err_current_generator; |
796 | |
797 | ret = twl_i2c_read_u8(mod_no: TWL_MODULE_MAIN_CHARGE, |
798 | val: ®val, TWL4030_BCI_BCICTL1); |
799 | if (ret) { |
800 | dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n" , |
801 | TWL4030_BCI_BCICTL1); |
802 | goto err_i2c; |
803 | } |
804 | regval |= TWL4030_BCI_MESBAT; |
805 | ret = twl_i2c_write_u8(mod_no: TWL_MODULE_MAIN_CHARGE, |
806 | val: regval, TWL4030_BCI_BCICTL1); |
807 | if (ret) { |
808 | dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n" , |
809 | TWL4030_BCI_BCICTL1); |
810 | goto err_i2c; |
811 | } |
812 | |
813 | /* Check that MADC clock is on */ |
814 | ret = twl_i2c_read_u8(mod_no: TWL4030_MODULE_INTBR, val: ®val, TWL4030_REG_GPBR1); |
815 | if (ret) { |
816 | dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n" , |
817 | TWL4030_REG_GPBR1); |
818 | goto err_i2c; |
819 | } |
820 | |
821 | /* If MADC clk is not on, turn it on */ |
822 | if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) { |
823 | dev_info(&pdev->dev, "clk disabled, enabling\n" ); |
824 | regval |= TWL4030_GPBR1_MADC_HFCLK_EN; |
825 | ret = twl_i2c_write_u8(mod_no: TWL4030_MODULE_INTBR, val: regval, |
826 | TWL4030_REG_GPBR1); |
827 | if (ret) { |
828 | dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n" , |
829 | TWL4030_REG_GPBR1); |
830 | goto err_i2c; |
831 | } |
832 | } |
833 | |
834 | platform_set_drvdata(pdev, data: iio_dev); |
835 | mutex_init(&madc->lock); |
836 | |
837 | irq = platform_get_irq(pdev, 0); |
838 | ret = devm_request_threaded_irq(dev: &pdev->dev, irq, NULL, |
839 | thread_fn: twl4030_madc_threaded_irq_handler, |
840 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
841 | devname: "twl4030_madc" , dev_id: madc); |
842 | if (ret) { |
843 | dev_err(&pdev->dev, "could not request irq\n" ); |
844 | goto err_i2c; |
845 | } |
846 | twl4030_madc = madc; |
847 | |
848 | /* Configure MADC[3:6] */ |
849 | ret = twl_i2c_read_u8(mod_no: TWL_MODULE_USB, val: ®val, |
850 | TWL4030_USB_CARKIT_ANA_CTRL); |
851 | if (ret) { |
852 | dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL 0x%X\n" , |
853 | TWL4030_USB_CARKIT_ANA_CTRL); |
854 | goto err_i2c; |
855 | } |
856 | regval |= TWL4030_USB_SEL_MADC_MCPC; |
857 | ret = twl_i2c_write_u8(mod_no: TWL_MODULE_USB, val: regval, |
858 | TWL4030_USB_CARKIT_ANA_CTRL); |
859 | if (ret) { |
860 | dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n" , |
861 | TWL4030_USB_CARKIT_ANA_CTRL); |
862 | goto err_i2c; |
863 | } |
864 | |
865 | /* Enable 3v1 bias regulator for MADC[3:6] */ |
866 | madc->usb3v1 = devm_regulator_get(dev: madc->dev, id: "vusb3v1" ); |
867 | if (IS_ERR(ptr: madc->usb3v1)) { |
868 | ret = -ENODEV; |
869 | goto err_i2c; |
870 | } |
871 | |
872 | ret = regulator_enable(regulator: madc->usb3v1); |
873 | if (ret) { |
874 | dev_err(madc->dev, "could not enable 3v1 bias regulator\n" ); |
875 | goto err_i2c; |
876 | } |
877 | |
878 | ret = iio_device_register(iio_dev); |
879 | if (ret) { |
880 | dev_err(&pdev->dev, "could not register iio device\n" ); |
881 | goto err_usb3v1; |
882 | } |
883 | |
884 | return 0; |
885 | |
886 | err_usb3v1: |
887 | regulator_disable(regulator: madc->usb3v1); |
888 | err_i2c: |
889 | twl4030_madc_set_current_generator(madc, chan: 0, on: 0); |
890 | err_current_generator: |
891 | twl4030_madc_set_power(madc, on: 0); |
892 | return ret; |
893 | } |
894 | |
895 | static void twl4030_madc_remove(struct platform_device *pdev) |
896 | { |
897 | struct iio_dev *iio_dev = platform_get_drvdata(pdev); |
898 | struct twl4030_madc_data *madc = iio_priv(indio_dev: iio_dev); |
899 | |
900 | iio_device_unregister(indio_dev: iio_dev); |
901 | |
902 | twl4030_madc_set_current_generator(madc, chan: 0, on: 0); |
903 | twl4030_madc_set_power(madc, on: 0); |
904 | |
905 | regulator_disable(regulator: madc->usb3v1); |
906 | } |
907 | |
908 | #ifdef CONFIG_OF |
909 | static const struct of_device_id twl_madc_of_match[] = { |
910 | { .compatible = "ti,twl4030-madc" , }, |
911 | { }, |
912 | }; |
913 | MODULE_DEVICE_TABLE(of, twl_madc_of_match); |
914 | #endif |
915 | |
916 | static struct platform_driver twl4030_madc_driver = { |
917 | .probe = twl4030_madc_probe, |
918 | .remove_new = twl4030_madc_remove, |
919 | .driver = { |
920 | .name = "twl4030_madc" , |
921 | .of_match_table = of_match_ptr(twl_madc_of_match), |
922 | }, |
923 | }; |
924 | |
925 | module_platform_driver(twl4030_madc_driver); |
926 | |
927 | MODULE_DESCRIPTION("TWL4030 ADC driver" ); |
928 | MODULE_LICENSE("GPL" ); |
929 | MODULE_AUTHOR("J Keerthy" ); |
930 | MODULE_ALIAS("platform:twl4030_madc" ); |
931 | |