blob: 93ef91229cd3533d056760f7648b6b3e128aa731 [file] [log] [blame]
Keerthyf99c1d42011-03-01 19:12:26 +05301/*
2 *
3 * TWL4030 MADC module driver-This driver monitors the real time
4 * conversion of analog signals like battery temperature,
5 * battery type, battery level etc.
6 *
7 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
8 * J Keerthy <j-keerthy@ti.com>
9 *
10 * Based on twl4030-madc.c
11 * Copyright (C) 2008 Nokia Corporation
12 * Mikko Ylinen <mikko.k.ylinen@nokia.com>
13 *
14 * Amit Kucheria <amit.kucheria@canonical.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * version 2 as published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * 02110-1301 USA
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/device.h>
34#include <linux/interrupt.h>
35#include <linux/kernel.h>
36#include <linux/delay.h>
37#include <linux/platform_device.h>
38#include <linux/slab.h>
39#include <linux/i2c/twl.h>
40#include <linux/i2c/twl4030-madc.h>
41#include <linux/module.h>
42#include <linux/stddef.h>
43#include <linux/mutex.h>
44#include <linux/bitops.h>
45#include <linux/jiffies.h>
46#include <linux/types.h>
47#include <linux/gfp.h>
48#include <linux/err.h>
49
Sebastian Reichel2f39b702014-03-16 02:43:26 +010050#include <linux/iio/iio.h>
51
Keerthyf99c1d42011-03-01 19:12:26 +053052/*
53 * struct twl4030_madc_data - a container for madc info
54 * @dev - pointer to device structure for madc
55 * @lock - mutex protecting this data structure
56 * @requests - Array of request struct corresponding to SW1, SW2 and RT
Sebastian Reichel2f39b702014-03-16 02:43:26 +010057 * @use_second_irq - IRQ selection (main or co-processor)
Keerthyf99c1d42011-03-01 19:12:26 +053058 * @imr - Interrupt mask register of MADC
59 * @isr - Interrupt status register of MADC
60 */
61struct twl4030_madc_data {
62 struct device *dev;
63 struct mutex lock; /* mutex protecting this data structure */
64 struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
Sebastian Reichel2f39b702014-03-16 02:43:26 +010065 bool use_second_irq;
Keerthyf99c1d42011-03-01 19:12:26 +053066 int imr;
67 int isr;
68};
69
Sebastian Reichel2f39b702014-03-16 02:43:26 +010070static int twl4030_madc_read(struct iio_dev *iio_dev,
71 const struct iio_chan_spec *chan,
72 int *val, int *val2, long mask)
73{
74 struct twl4030_madc_data *madc = iio_priv(iio_dev);
75 struct twl4030_madc_request req;
76 int ret;
77
78 req.method = madc->use_second_irq ? TWL4030_MADC_SW2 : TWL4030_MADC_SW1;
79
80 req.channels = BIT(chan->channel);
81 req.active = false;
82 req.func_cb = NULL;
83 req.type = TWL4030_MADC_WAIT;
84 req.raw = !(mask == IIO_CHAN_INFO_PROCESSED);
85 req.do_avg = (mask == IIO_CHAN_INFO_AVERAGE_RAW);
86
87 ret = twl4030_madc_conversion(&req);
88 if (ret < 0)
89 return ret;
90
91 *val = req.rbuf[chan->channel];
92
93 return IIO_VAL_INT;
94}
95
96static const struct iio_info twl4030_madc_iio_info = {
97 .read_raw = &twl4030_madc_read,
98 .driver_module = THIS_MODULE,
99};
100
101#define TWL4030_ADC_CHANNEL(_channel, _type, _name) { \
102 .type = _type, \
103 .channel = _channel, \
104 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
105 BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \
106 BIT(IIO_CHAN_INFO_PROCESSED), \
107 .datasheet_name = _name, \
108 .indexed = 1, \
109}
110
111static const struct iio_chan_spec twl4030_madc_iio_channels[] = {
112 TWL4030_ADC_CHANNEL(0, IIO_VOLTAGE, "ADCIN0"),
113 TWL4030_ADC_CHANNEL(1, IIO_TEMP, "ADCIN1"),
114 TWL4030_ADC_CHANNEL(2, IIO_VOLTAGE, "ADCIN2"),
115 TWL4030_ADC_CHANNEL(3, IIO_VOLTAGE, "ADCIN3"),
116 TWL4030_ADC_CHANNEL(4, IIO_VOLTAGE, "ADCIN4"),
117 TWL4030_ADC_CHANNEL(5, IIO_VOLTAGE, "ADCIN5"),
118 TWL4030_ADC_CHANNEL(6, IIO_VOLTAGE, "ADCIN6"),
119 TWL4030_ADC_CHANNEL(7, IIO_VOLTAGE, "ADCIN7"),
120 TWL4030_ADC_CHANNEL(8, IIO_VOLTAGE, "ADCIN8"),
121 TWL4030_ADC_CHANNEL(9, IIO_VOLTAGE, "ADCIN9"),
122 TWL4030_ADC_CHANNEL(10, IIO_CURRENT, "ADCIN10"),
123 TWL4030_ADC_CHANNEL(11, IIO_VOLTAGE, "ADCIN11"),
124 TWL4030_ADC_CHANNEL(12, IIO_VOLTAGE, "ADCIN12"),
125 TWL4030_ADC_CHANNEL(13, IIO_VOLTAGE, "ADCIN13"),
126 TWL4030_ADC_CHANNEL(14, IIO_VOLTAGE, "ADCIN14"),
127 TWL4030_ADC_CHANNEL(15, IIO_VOLTAGE, "ADCIN15"),
128};
129
Keerthyf99c1d42011-03-01 19:12:26 +0530130static struct twl4030_madc_data *twl4030_madc;
131
132struct twl4030_prescale_divider_ratios {
133 s16 numerator;
134 s16 denominator;
135};
136
137static const struct twl4030_prescale_divider_ratios
138twl4030_divider_ratios[16] = {
139 {1, 1}, /* CHANNEL 0 No Prescaler */
140 {1, 1}, /* CHANNEL 1 No Prescaler */
141 {6, 10}, /* CHANNEL 2 */
142 {6, 10}, /* CHANNEL 3 */
143 {6, 10}, /* CHANNEL 4 */
144 {6, 10}, /* CHANNEL 5 */
145 {6, 10}, /* CHANNEL 6 */
146 {6, 10}, /* CHANNEL 7 */
147 {3, 14}, /* CHANNEL 8 */
148 {1, 3}, /* CHANNEL 9 */
149 {1, 1}, /* CHANNEL 10 No Prescaler */
150 {15, 100}, /* CHANNEL 11 */
151 {1, 4}, /* CHANNEL 12 */
152 {1, 1}, /* CHANNEL 13 Reserved channels */
153 {1, 1}, /* CHANNEL 14 Reseved channels */
154 {5, 11}, /* CHANNEL 15 */
155};
156
157
158/*
159 * Conversion table from -3 to 55 degree Celcius
160 */
161static int therm_tbl[] = {
16230800, 29500, 28300, 27100,
16326000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
16417200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
16511600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
1668020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
1675640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
1684040, 3910, 3790, 3670, 3550
169};
170
171/*
172 * Structure containing the registers
173 * of different conversion methods supported by MADC.
174 * Hardware or RT real time conversion request initiated by external host
175 * processor for RT Signal conversions.
176 * External host processors can also request for non RT conversions
177 * SW1 and SW2 software conversions also called asynchronous or GPC request.
178 */
179static
180const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
181 [TWL4030_MADC_RT] = {
182 .sel = TWL4030_MADC_RTSELECT_LSB,
183 .avg = TWL4030_MADC_RTAVERAGE_LSB,
184 .rbase = TWL4030_MADC_RTCH0_LSB,
185 },
186 [TWL4030_MADC_SW1] = {
187 .sel = TWL4030_MADC_SW1SELECT_LSB,
188 .avg = TWL4030_MADC_SW1AVERAGE_LSB,
189 .rbase = TWL4030_MADC_GPCH0_LSB,
190 .ctrl = TWL4030_MADC_CTRL_SW1,
191 },
192 [TWL4030_MADC_SW2] = {
193 .sel = TWL4030_MADC_SW2SELECT_LSB,
194 .avg = TWL4030_MADC_SW2AVERAGE_LSB,
195 .rbase = TWL4030_MADC_GPCH0_LSB,
196 .ctrl = TWL4030_MADC_CTRL_SW2,
197 },
198};
199
200/*
201 * Function to read a particular channel value.
202 * @madc - pointer to struct twl4030_madc_data
203 * @reg - lsb of ADC Channel
204 * If the i2c read fails it returns an error else returns 0.
205 */
206static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
207{
208 u8 msb, lsb;
209 int ret;
210 /*
211 * For each ADC channel, we have MSB and LSB register pair. MSB address
212 * is always LSB address+1. reg parameter is the address of LSB register
213 */
214 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1);
215 if (ret) {
216 dev_err(madc->dev, "unable to read MSB register 0x%X\n",
217 reg + 1);
218 return ret;
219 }
220 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg);
221 if (ret) {
222 dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg);
223 return ret;
224 }
225
226 return (int)(((msb << 8) | lsb) >> 6);
227}
228
229/*
230 * Return battery temperature
231 * Or < 0 on failure.
232 */
233static int twl4030battery_temperature(int raw_volt)
234{
235 u8 val;
236 int temp, curr, volt, res, ret;
237
238 volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
239 /* Getting and calculating the supply current in micro ampers */
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100240 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
Keerthyf99c1d42011-03-01 19:12:26 +0530241 REG_BCICTL2);
242 if (ret < 0)
243 return ret;
244 curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
245 /* Getting and calculating the thermistor resistance in ohms */
246 res = volt * 1000 / curr;
247 /* calculating temperature */
248 for (temp = 58; temp >= 0; temp--) {
249 int actual = therm_tbl[temp];
250
251 if ((actual - res) >= 0)
252 break;
253 }
254
255 return temp + 1;
256}
257
258static int twl4030battery_current(int raw_volt)
259{
260 int ret;
261 u8 val;
262
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100263 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
Keerthyf99c1d42011-03-01 19:12:26 +0530264 TWL4030_BCI_BCICTL1);
265 if (ret)
266 return ret;
267 if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
268 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
269 else /* slope of 0.88 mV/mA */
270 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
271}
272/*
273 * Function to read channel values
274 * @madc - pointer to twl4030_madc_data struct
275 * @reg_base - Base address of the first channel
276 * @Channels - 16 bit bitmap. If the bit is set, channel value is read
277 * @buf - The channel values are stored here. if read fails error
Pali Rohára5055d52013-02-15 23:56:49 +0100278 * @raw - Return raw values without conversion
Keerthyf99c1d42011-03-01 19:12:26 +0530279 * value is stored
280 * Returns the number of successfully read channels.
281 */
282static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
283 u8 reg_base, unsigned
Pali Rohára5055d52013-02-15 23:56:49 +0100284 long channels, int *buf,
285 bool raw)
Keerthyf99c1d42011-03-01 19:12:26 +0530286{
287 int count = 0, count_req = 0, i;
288 u8 reg;
289
290 for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
291 reg = reg_base + 2 * i;
292 buf[i] = twl4030_madc_channel_raw_read(madc, reg);
293 if (buf[i] < 0) {
294 dev_err(madc->dev,
295 "Unable to read register 0x%X\n", reg);
296 count_req++;
297 continue;
298 }
Pali Rohára5055d52013-02-15 23:56:49 +0100299 if (raw) {
300 count++;
301 continue;
302 }
Keerthyf99c1d42011-03-01 19:12:26 +0530303 switch (i) {
304 case 10:
305 buf[i] = twl4030battery_current(buf[i]);
306 if (buf[i] < 0) {
307 dev_err(madc->dev, "err reading current\n");
308 count_req++;
309 } else {
310 count++;
311 buf[i] = buf[i] - 750;
312 }
313 break;
314 case 1:
315 buf[i] = twl4030battery_temperature(buf[i]);
316 if (buf[i] < 0) {
317 dev_err(madc->dev, "err reading temperature\n");
318 count_req++;
319 } else {
320 buf[i] -= 3;
321 count++;
322 }
323 break;
324 default:
325 count++;
326 /* Analog Input (V) = conv_result * step_size / R
327 * conv_result = decimal value of 10-bit conversion
328 * result
329 * step size = 1.5 / (2 ^ 10 -1)
330 * R = Prescaler ratio for input channels.
331 * Result given in mV hence multiplied by 1000.
332 */
333 buf[i] = (buf[i] * 3 * 1000 *
334 twl4030_divider_ratios[i].denominator)
335 / (2 * 1023 *
336 twl4030_divider_ratios[i].numerator);
337 }
338 }
339 if (count_req)
340 dev_err(madc->dev, "%d channel conversion failed\n", count_req);
341
342 return count;
343}
344
345/*
346 * Enables irq.
347 * @madc - pointer to twl4030_madc_data struct
348 * @id - irq number to be enabled
349 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
350 * corresponding to RT, SW1, SW2 conversion requests.
351 * If the i2c read fails it returns an error else returns 0.
352 */
353static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
354{
355 u8 val;
356 int ret;
357
358 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
359 if (ret) {
360 dev_err(madc->dev, "unable to read imr register 0x%X\n",
361 madc->imr);
362 return ret;
363 }
364 val &= ~(1 << id);
365 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
366 if (ret) {
367 dev_err(madc->dev,
368 "unable to write imr register 0x%X\n", madc->imr);
369 return ret;
370
371 }
372
373 return 0;
374}
375
376/*
377 * Disables irq.
378 * @madc - pointer to twl4030_madc_data struct
379 * @id - irq number to be disabled
380 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
381 * corresponding to RT, SW1, SW2 conversion requests.
382 * Returns error if i2c read/write fails.
383 */
384static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
385{
386 u8 val;
387 int ret;
388
389 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
390 if (ret) {
391 dev_err(madc->dev, "unable to read imr register 0x%X\n",
392 madc->imr);
393 return ret;
394 }
395 val |= (1 << id);
396 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
397 if (ret) {
398 dev_err(madc->dev,
399 "unable to write imr register 0x%X\n", madc->imr);
400 return ret;
401 }
402
403 return 0;
404}
405
406static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
407{
408 struct twl4030_madc_data *madc = _madc;
409 const struct twl4030_madc_conversion_method *method;
410 u8 isr_val, imr_val;
411 int i, len, ret;
412 struct twl4030_madc_request *r;
413
414 mutex_lock(&madc->lock);
415 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
416 if (ret) {
417 dev_err(madc->dev, "unable to read isr register 0x%X\n",
418 madc->isr);
419 goto err_i2c;
420 }
421 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
422 if (ret) {
423 dev_err(madc->dev, "unable to read imr register 0x%X\n",
424 madc->imr);
425 goto err_i2c;
426 }
427 isr_val &= ~imr_val;
428 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
429 if (!(isr_val & (1 << i)))
430 continue;
431 ret = twl4030_madc_disable_irq(madc, i);
432 if (ret < 0)
433 dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
434 madc->requests[i].result_pending = 1;
435 }
436 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
437 r = &madc->requests[i];
438 /* No pending results for this method, move to next one */
439 if (!r->result_pending)
440 continue;
441 method = &twl4030_conversion_methods[r->method];
442 /* Read results */
443 len = twl4030_madc_read_channels(madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100444 r->channels, r->rbuf, r->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530445 /* Return results to caller */
446 if (r->func_cb != NULL) {
447 r->func_cb(len, r->channels, r->rbuf);
448 r->func_cb = NULL;
449 }
450 /* Free request */
451 r->result_pending = 0;
452 r->active = 0;
453 }
454 mutex_unlock(&madc->lock);
455
456 return IRQ_HANDLED;
457
458err_i2c:
459 /*
460 * In case of error check whichever request is active
461 * and service the same.
462 */
463 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
464 r = &madc->requests[i];
465 if (r->active == 0)
466 continue;
467 method = &twl4030_conversion_methods[r->method];
468 /* Read results */
469 len = twl4030_madc_read_channels(madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100470 r->channels, r->rbuf, r->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530471 /* Return results to caller */
472 if (r->func_cb != NULL) {
473 r->func_cb(len, r->channels, r->rbuf);
474 r->func_cb = NULL;
475 }
476 /* Free request */
477 r->result_pending = 0;
478 r->active = 0;
479 }
480 mutex_unlock(&madc->lock);
481
482 return IRQ_HANDLED;
483}
484
485static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
486 struct twl4030_madc_request *req)
487{
488 struct twl4030_madc_request *p;
489 int ret;
490
491 p = &madc->requests[req->method];
492 memcpy(p, req, sizeof(*req));
493 ret = twl4030_madc_enable_irq(madc, req->method);
494 if (ret < 0) {
495 dev_err(madc->dev, "enable irq failed!!\n");
496 return ret;
497 }
498
499 return 0;
500}
501
502/*
503 * Function which enables the madc conversion
504 * by writing to the control register.
505 * @madc - pointer to twl4030_madc_data struct
506 * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
507 * corresponding to RT SW1 or SW2 conversion methods.
508 * Returns 0 if succeeds else a negative error value
509 */
510static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
511 int conv_method)
512{
513 const struct twl4030_madc_conversion_method *method;
514 int ret = 0;
515 method = &twl4030_conversion_methods[conv_method];
516 switch (conv_method) {
517 case TWL4030_MADC_SW1:
518 case TWL4030_MADC_SW2:
519 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
520 TWL4030_MADC_SW_START, method->ctrl);
521 if (ret) {
522 dev_err(madc->dev,
523 "unable to write ctrl register 0x%X\n",
524 method->ctrl);
525 return ret;
526 }
527 break;
528 default:
529 break;
530 }
531
532 return 0;
533}
534
535/*
536 * Function that waits for conversion to be ready
537 * @madc - pointer to twl4030_madc_data struct
538 * @timeout_ms - timeout value in milliseconds
539 * @status_reg - ctrl register
540 * returns 0 if succeeds else a negative error value
541 */
542static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
543 unsigned int timeout_ms,
544 u8 status_reg)
545{
546 unsigned long timeout;
547 int ret;
548
549 timeout = jiffies + msecs_to_jiffies(timeout_ms);
550 do {
551 u8 reg;
552
553 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
554 if (ret) {
555 dev_err(madc->dev,
556 "unable to read status register 0x%X\n",
557 status_reg);
558 return ret;
559 }
560 if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
561 return 0;
562 usleep_range(500, 2000);
563 } while (!time_after(jiffies, timeout));
564 dev_err(madc->dev, "conversion timeout!\n");
565
566 return -EAGAIN;
567}
568
569/*
570 * An exported function which can be called from other kernel drivers.
571 * @req twl4030_madc_request structure
572 * req->rbuf will be filled with read values of channels based on the
573 * channel index. If a particular channel reading fails there will
574 * be a negative error value in the corresponding array element.
575 * returns 0 if succeeds else error value
576 */
577int twl4030_madc_conversion(struct twl4030_madc_request *req)
578{
579 const struct twl4030_madc_conversion_method *method;
580 u8 ch_msb, ch_lsb;
581 int ret;
582
Kyle Mannad0e84ca2011-08-11 22:33:14 -0500583 if (!req || !twl4030_madc)
Keerthyf99c1d42011-03-01 19:12:26 +0530584 return -EINVAL;
Kyle Mannad0e84ca2011-08-11 22:33:14 -0500585
Keerthyf99c1d42011-03-01 19:12:26 +0530586 mutex_lock(&twl4030_madc->lock);
587 if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
588 ret = -EINVAL;
589 goto out;
590 }
591 /* Do we have a conversion request ongoing */
592 if (twl4030_madc->requests[req->method].active) {
593 ret = -EBUSY;
594 goto out;
595 }
596 ch_msb = (req->channels >> 8) & 0xff;
597 ch_lsb = req->channels & 0xff;
598 method = &twl4030_conversion_methods[req->method];
599 /* Select channels to be converted */
600 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
601 if (ret) {
602 dev_err(twl4030_madc->dev,
603 "unable to write sel register 0x%X\n", method->sel + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530604 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530605 }
606 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
607 if (ret) {
608 dev_err(twl4030_madc->dev,
609 "unable to write sel register 0x%X\n", method->sel + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530610 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530611 }
612 /* Select averaging for all channels if do_avg is set */
613 if (req->do_avg) {
614 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
615 ch_msb, method->avg + 1);
616 if (ret) {
617 dev_err(twl4030_madc->dev,
618 "unable to write avg register 0x%X\n",
619 method->avg + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530620 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530621 }
622 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
623 ch_lsb, method->avg);
624 if (ret) {
625 dev_err(twl4030_madc->dev,
626 "unable to write sel reg 0x%X\n",
627 method->sel + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530628 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530629 }
630 }
631 if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
632 ret = twl4030_madc_set_irq(twl4030_madc, req);
633 if (ret < 0)
634 goto out;
635 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
636 if (ret < 0)
637 goto out;
638 twl4030_madc->requests[req->method].active = 1;
639 ret = 0;
640 goto out;
641 }
642 /* With RT method we should not be here anymore */
643 if (req->method == TWL4030_MADC_RT) {
644 ret = -EINVAL;
645 goto out;
646 }
647 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
648 if (ret < 0)
649 goto out;
650 twl4030_madc->requests[req->method].active = 1;
651 /* Wait until conversion is ready (ctrl register returns EOC) */
652 ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
653 if (ret) {
654 twl4030_madc->requests[req->method].active = 0;
655 goto out;
656 }
657 ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100658 req->channels, req->rbuf, req->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530659 twl4030_madc->requests[req->method].active = 0;
660
661out:
662 mutex_unlock(&twl4030_madc->lock);
663
664 return ret;
665}
666EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
667
668/*
669 * Return channel value
670 * Or < 0 on failure.
671 */
672int twl4030_get_madc_conversion(int channel_no)
673{
674 struct twl4030_madc_request req;
675 int temp = 0;
676 int ret;
677
678 req.channels = (1 << channel_no);
679 req.method = TWL4030_MADC_SW2;
680 req.active = 0;
681 req.func_cb = NULL;
682 ret = twl4030_madc_conversion(&req);
683 if (ret < 0)
684 return ret;
685 if (req.rbuf[channel_no] > 0)
686 temp = req.rbuf[channel_no];
687
688 return temp;
689}
690EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
691
692/*
693 * Function to enable or disable bias current for
694 * main battery type reading or temperature sensing
695 * @madc - pointer to twl4030_madc_data struct
696 * @chan - can be one of the two values
697 * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
698 * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
699 * sensing
700 * @on - enable or disable chan.
701 */
702static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
703 int chan, int on)
704{
705 int ret;
706 u8 regval;
707
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100708 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530709 &regval, TWL4030_BCI_BCICTL1);
710 if (ret) {
711 dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
712 TWL4030_BCI_BCICTL1);
713 return ret;
714 }
715 if (on)
716 regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
717 else
718 regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100719 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530720 regval, TWL4030_BCI_BCICTL1);
721 if (ret) {
722 dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
723 TWL4030_BCI_BCICTL1);
724 return ret;
725 }
726
727 return 0;
728}
729
730/*
731 * Function that sets MADC software power on bit to enable MADC
732 * @madc - pointer to twl4030_madc_data struct
733 * @on - Enable or disable MADC software powen on bit.
734 * returns error if i2c read/write fails else 0
735 */
736static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
737{
738 u8 regval;
739 int ret;
740
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100741 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530742 &regval, TWL4030_MADC_CTRL1);
743 if (ret) {
744 dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
745 TWL4030_MADC_CTRL1);
746 return ret;
747 }
748 if (on)
749 regval |= TWL4030_MADC_MADCON;
750 else
751 regval &= ~TWL4030_MADC_MADCON;
752 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
753 if (ret) {
754 dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
755 TWL4030_MADC_CTRL1);
756 return ret;
757 }
758
759 return 0;
760}
761
762/*
763 * Initialize MADC and request for threaded irq
764 */
Bill Pembertonf791be42012-11-19 13:23:04 -0500765static int twl4030_madc_probe(struct platform_device *pdev)
Keerthyf99c1d42011-03-01 19:12:26 +0530766{
767 struct twl4030_madc_data *madc;
Jingoo Han334a41c2013-07-30 17:10:05 +0900768 struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100769 struct device_node *np = pdev->dev.of_node;
Sebastian Reichele7f22b72014-03-16 02:43:25 +0100770 int irq, ret;
Keerthyf99c1d42011-03-01 19:12:26 +0530771 u8 regval;
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100772 struct iio_dev *iio_dev = NULL;
Keerthyf99c1d42011-03-01 19:12:26 +0530773
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100774 if (!pdata && !np) {
775 dev_err(&pdev->dev, "neither platform data nor Device Tree node available\n");
Keerthyf99c1d42011-03-01 19:12:26 +0530776 return -EINVAL;
777 }
Keerthyf99c1d42011-03-01 19:12:26 +0530778
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100779 iio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*madc));
780 if (!iio_dev) {
781 dev_err(&pdev->dev, "failed allocating iio device\n");
782 return -ENOMEM;
783 }
784
785 madc = iio_priv(iio_dev);
Kyle Manna66cc5b82011-08-11 22:33:12 -0500786 madc->dev = &pdev->dev;
787
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100788 iio_dev->name = dev_name(&pdev->dev);
789 iio_dev->dev.parent = &pdev->dev;
790 iio_dev->dev.of_node = pdev->dev.of_node;
791 iio_dev->info = &twl4030_madc_iio_info;
792 iio_dev->modes = INDIO_DIRECT_MODE;
793 iio_dev->channels = twl4030_madc_iio_channels;
794 iio_dev->num_channels = ARRAY_SIZE(twl4030_madc_iio_channels);
795
Keerthyf99c1d42011-03-01 19:12:26 +0530796 /*
797 * Phoenix provides 2 interrupt lines. The first one is connected to
798 * the OMAP. The other one can be connected to the other processor such
799 * as modem. Hence two separate ISR and IMR registers.
800 */
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100801 if (pdata)
802 madc->use_second_irq = (pdata->irq_line != 1);
803 else
804 madc->use_second_irq = of_property_read_bool(np,
805 "ti,system-uses-second-madc-irq");
806
807 madc->imr = madc->use_second_irq ? TWL4030_MADC_IMR2 :
808 TWL4030_MADC_IMR1;
809 madc->isr = madc->use_second_irq ? TWL4030_MADC_ISR2 :
810 TWL4030_MADC_ISR1;
811
Keerthyf99c1d42011-03-01 19:12:26 +0530812 ret = twl4030_madc_set_power(madc, 1);
813 if (ret < 0)
Sebastian Reichele7f22b72014-03-16 02:43:25 +0100814 return ret;
Keerthyf99c1d42011-03-01 19:12:26 +0530815 ret = twl4030_madc_set_current_generator(madc, 0, 1);
816 if (ret < 0)
817 goto err_current_generator;
818
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100819 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530820 &regval, TWL4030_BCI_BCICTL1);
821 if (ret) {
822 dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
823 TWL4030_BCI_BCICTL1);
824 goto err_i2c;
825 }
826 regval |= TWL4030_BCI_MESBAT;
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100827 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530828 regval, TWL4030_BCI_BCICTL1);
829 if (ret) {
830 dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
831 TWL4030_BCI_BCICTL1);
832 goto err_i2c;
833 }
Kyle Manna3d6271f2011-08-11 22:33:13 -0500834
835 /* Check that MADC clock is on */
836 ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
837 if (ret) {
838 dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
839 TWL4030_REG_GPBR1);
840 goto err_i2c;
841 }
842
843 /* If MADC clk is not on, turn it on */
844 if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
845 dev_info(&pdev->dev, "clk disabled, enabling\n");
846 regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
847 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
848 TWL4030_REG_GPBR1);
849 if (ret) {
850 dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
851 TWL4030_REG_GPBR1);
852 goto err_i2c;
853 }
854 }
855
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100856 platform_set_drvdata(pdev, iio_dev);
Keerthyf99c1d42011-03-01 19:12:26 +0530857 mutex_init(&madc->lock);
Sebastian Reichele7f22b72014-03-16 02:43:25 +0100858
859 irq = platform_get_irq(pdev, 0);
860 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
Keerthyf99c1d42011-03-01 19:12:26 +0530861 twl4030_madc_threaded_irq_handler,
862 IRQF_TRIGGER_RISING, "twl4030_madc", madc);
863 if (ret) {
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100864 dev_err(&pdev->dev, "could not request irq\n");
Jingoo Hanc3d6a0a2013-05-06 13:08:08 +0900865 goto err_i2c;
Keerthyf99c1d42011-03-01 19:12:26 +0530866 }
867 twl4030_madc = madc;
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100868
869 ret = iio_device_register(iio_dev);
870 if (ret) {
871 dev_err(&pdev->dev, "could not register iio device\n");
872 goto err_i2c;
873 }
874
Keerthyf99c1d42011-03-01 19:12:26 +0530875 return 0;
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100876
Keerthyf99c1d42011-03-01 19:12:26 +0530877err_i2c:
878 twl4030_madc_set_current_generator(madc, 0, 0);
879err_current_generator:
880 twl4030_madc_set_power(madc, 0);
Keerthyf99c1d42011-03-01 19:12:26 +0530881 return ret;
882}
883
Bill Pemberton4740f732012-11-19 13:26:01 -0500884static int twl4030_madc_remove(struct platform_device *pdev)
Keerthyf99c1d42011-03-01 19:12:26 +0530885{
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100886 struct iio_dev *iio_dev = platform_get_drvdata(pdev);
887 struct twl4030_madc_data *madc = iio_priv(iio_dev);
888
889 iio_device_unregister(iio_dev);
Keerthyf99c1d42011-03-01 19:12:26 +0530890
Keerthyf99c1d42011-03-01 19:12:26 +0530891 twl4030_madc_set_current_generator(madc, 0, 0);
892 twl4030_madc_set_power(madc, 0);
Keerthyf99c1d42011-03-01 19:12:26 +0530893
894 return 0;
895}
896
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100897#ifdef CONFIG_OF
898static const struct of_device_id twl_madc_of_match[] = {
899 { .compatible = "ti,twl4030-madc", },
900 { },
901};
902MODULE_DEVICE_TABLE(of, twl_madc_of_match);
903#endif
904
Keerthyf99c1d42011-03-01 19:12:26 +0530905static struct platform_driver twl4030_madc_driver = {
906 .probe = twl4030_madc_probe,
Arnd Bergmann03715412013-03-14 22:56:38 +0100907 .remove = twl4030_madc_remove,
Keerthyf99c1d42011-03-01 19:12:26 +0530908 .driver = {
909 .name = "twl4030_madc",
910 .owner = THIS_MODULE,
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100911 .of_match_table = of_match_ptr(twl_madc_of_match),
Keerthyf99c1d42011-03-01 19:12:26 +0530912 },
913};
914
Mark Brown65349d62011-11-23 22:58:34 +0000915module_platform_driver(twl4030_madc_driver);
Keerthyf99c1d42011-03-01 19:12:26 +0530916
917MODULE_DESCRIPTION("TWL4030 ADC driver");
918MODULE_LICENSE("GPL");
919MODULE_AUTHOR("J Keerthy");
Axel Lin0ea3e832011-03-07 11:02:29 +0800920MODULE_ALIAS("platform:twl4030_madc");