blob: 42bd3ea5df3c3f07207b44bf6360fde54fb23b7f [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
50/*
51 * struct twl4030_madc_data - a container for madc info
52 * @dev - pointer to device structure for madc
53 * @lock - mutex protecting this data structure
54 * @requests - Array of request struct corresponding to SW1, SW2 and RT
55 * @imr - Interrupt mask register of MADC
56 * @isr - Interrupt status register of MADC
57 */
58struct twl4030_madc_data {
59 struct device *dev;
60 struct mutex lock; /* mutex protecting this data structure */
61 struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
62 int imr;
63 int isr;
64};
65
66static struct twl4030_madc_data *twl4030_madc;
67
68struct twl4030_prescale_divider_ratios {
69 s16 numerator;
70 s16 denominator;
71};
72
73static const struct twl4030_prescale_divider_ratios
74twl4030_divider_ratios[16] = {
75 {1, 1}, /* CHANNEL 0 No Prescaler */
76 {1, 1}, /* CHANNEL 1 No Prescaler */
77 {6, 10}, /* CHANNEL 2 */
78 {6, 10}, /* CHANNEL 3 */
79 {6, 10}, /* CHANNEL 4 */
80 {6, 10}, /* CHANNEL 5 */
81 {6, 10}, /* CHANNEL 6 */
82 {6, 10}, /* CHANNEL 7 */
83 {3, 14}, /* CHANNEL 8 */
84 {1, 3}, /* CHANNEL 9 */
85 {1, 1}, /* CHANNEL 10 No Prescaler */
86 {15, 100}, /* CHANNEL 11 */
87 {1, 4}, /* CHANNEL 12 */
88 {1, 1}, /* CHANNEL 13 Reserved channels */
89 {1, 1}, /* CHANNEL 14 Reseved channels */
90 {5, 11}, /* CHANNEL 15 */
91};
92
93
94/*
95 * Conversion table from -3 to 55 degree Celcius
96 */
97static int therm_tbl[] = {
9830800, 29500, 28300, 27100,
9926000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
10017200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
10111600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
1028020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
1035640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
1044040, 3910, 3790, 3670, 3550
105};
106
107/*
108 * Structure containing the registers
109 * of different conversion methods supported by MADC.
110 * Hardware or RT real time conversion request initiated by external host
111 * processor for RT Signal conversions.
112 * External host processors can also request for non RT conversions
113 * SW1 and SW2 software conversions also called asynchronous or GPC request.
114 */
115static
116const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
117 [TWL4030_MADC_RT] = {
118 .sel = TWL4030_MADC_RTSELECT_LSB,
119 .avg = TWL4030_MADC_RTAVERAGE_LSB,
120 .rbase = TWL4030_MADC_RTCH0_LSB,
121 },
122 [TWL4030_MADC_SW1] = {
123 .sel = TWL4030_MADC_SW1SELECT_LSB,
124 .avg = TWL4030_MADC_SW1AVERAGE_LSB,
125 .rbase = TWL4030_MADC_GPCH0_LSB,
126 .ctrl = TWL4030_MADC_CTRL_SW1,
127 },
128 [TWL4030_MADC_SW2] = {
129 .sel = TWL4030_MADC_SW2SELECT_LSB,
130 .avg = TWL4030_MADC_SW2AVERAGE_LSB,
131 .rbase = TWL4030_MADC_GPCH0_LSB,
132 .ctrl = TWL4030_MADC_CTRL_SW2,
133 },
134};
135
136/*
137 * Function to read a particular channel value.
138 * @madc - pointer to struct twl4030_madc_data
139 * @reg - lsb of ADC Channel
140 * If the i2c read fails it returns an error else returns 0.
141 */
142static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
143{
144 u8 msb, lsb;
145 int ret;
146 /*
147 * For each ADC channel, we have MSB and LSB register pair. MSB address
148 * is always LSB address+1. reg parameter is the address of LSB register
149 */
150 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1);
151 if (ret) {
152 dev_err(madc->dev, "unable to read MSB register 0x%X\n",
153 reg + 1);
154 return ret;
155 }
156 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg);
157 if (ret) {
158 dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg);
159 return ret;
160 }
161
162 return (int)(((msb << 8) | lsb) >> 6);
163}
164
165/*
166 * Return battery temperature
167 * Or < 0 on failure.
168 */
169static int twl4030battery_temperature(int raw_volt)
170{
171 u8 val;
172 int temp, curr, volt, res, ret;
173
174 volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
175 /* Getting and calculating the supply current in micro ampers */
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100176 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
Keerthyf99c1d42011-03-01 19:12:26 +0530177 REG_BCICTL2);
178 if (ret < 0)
179 return ret;
180 curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
181 /* Getting and calculating the thermistor resistance in ohms */
182 res = volt * 1000 / curr;
183 /* calculating temperature */
184 for (temp = 58; temp >= 0; temp--) {
185 int actual = therm_tbl[temp];
186
187 if ((actual - res) >= 0)
188 break;
189 }
190
191 return temp + 1;
192}
193
194static int twl4030battery_current(int raw_volt)
195{
196 int ret;
197 u8 val;
198
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100199 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
Keerthyf99c1d42011-03-01 19:12:26 +0530200 TWL4030_BCI_BCICTL1);
201 if (ret)
202 return ret;
203 if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
204 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
205 else /* slope of 0.88 mV/mA */
206 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
207}
208/*
209 * Function to read channel values
210 * @madc - pointer to twl4030_madc_data struct
211 * @reg_base - Base address of the first channel
212 * @Channels - 16 bit bitmap. If the bit is set, channel value is read
213 * @buf - The channel values are stored here. if read fails error
Pali Rohára5055d52013-02-15 23:56:49 +0100214 * @raw - Return raw values without conversion
Keerthyf99c1d42011-03-01 19:12:26 +0530215 * value is stored
216 * Returns the number of successfully read channels.
217 */
218static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
219 u8 reg_base, unsigned
Pali Rohára5055d52013-02-15 23:56:49 +0100220 long channels, int *buf,
221 bool raw)
Keerthyf99c1d42011-03-01 19:12:26 +0530222{
223 int count = 0, count_req = 0, i;
224 u8 reg;
225
226 for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
227 reg = reg_base + 2 * i;
228 buf[i] = twl4030_madc_channel_raw_read(madc, reg);
229 if (buf[i] < 0) {
230 dev_err(madc->dev,
231 "Unable to read register 0x%X\n", reg);
232 count_req++;
233 continue;
234 }
Pali Rohára5055d52013-02-15 23:56:49 +0100235 if (raw) {
236 count++;
237 continue;
238 }
Keerthyf99c1d42011-03-01 19:12:26 +0530239 switch (i) {
240 case 10:
241 buf[i] = twl4030battery_current(buf[i]);
242 if (buf[i] < 0) {
243 dev_err(madc->dev, "err reading current\n");
244 count_req++;
245 } else {
246 count++;
247 buf[i] = buf[i] - 750;
248 }
249 break;
250 case 1:
251 buf[i] = twl4030battery_temperature(buf[i]);
252 if (buf[i] < 0) {
253 dev_err(madc->dev, "err reading temperature\n");
254 count_req++;
255 } else {
256 buf[i] -= 3;
257 count++;
258 }
259 break;
260 default:
261 count++;
262 /* Analog Input (V) = conv_result * step_size / R
263 * conv_result = decimal value of 10-bit conversion
264 * result
265 * step size = 1.5 / (2 ^ 10 -1)
266 * R = Prescaler ratio for input channels.
267 * Result given in mV hence multiplied by 1000.
268 */
269 buf[i] = (buf[i] * 3 * 1000 *
270 twl4030_divider_ratios[i].denominator)
271 / (2 * 1023 *
272 twl4030_divider_ratios[i].numerator);
273 }
274 }
275 if (count_req)
276 dev_err(madc->dev, "%d channel conversion failed\n", count_req);
277
278 return count;
279}
280
281/*
282 * Enables irq.
283 * @madc - pointer to twl4030_madc_data struct
284 * @id - irq number to be enabled
285 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
286 * corresponding to RT, SW1, SW2 conversion requests.
287 * If the i2c read fails it returns an error else returns 0.
288 */
289static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
290{
291 u8 val;
292 int ret;
293
294 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
295 if (ret) {
296 dev_err(madc->dev, "unable to read imr register 0x%X\n",
297 madc->imr);
298 return ret;
299 }
300 val &= ~(1 << id);
301 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
302 if (ret) {
303 dev_err(madc->dev,
304 "unable to write imr register 0x%X\n", madc->imr);
305 return ret;
306
307 }
308
309 return 0;
310}
311
312/*
313 * Disables irq.
314 * @madc - pointer to twl4030_madc_data struct
315 * @id - irq number to be disabled
316 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
317 * corresponding to RT, SW1, SW2 conversion requests.
318 * Returns error if i2c read/write fails.
319 */
320static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
321{
322 u8 val;
323 int ret;
324
325 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
326 if (ret) {
327 dev_err(madc->dev, "unable to read imr register 0x%X\n",
328 madc->imr);
329 return ret;
330 }
331 val |= (1 << id);
332 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
333 if (ret) {
334 dev_err(madc->dev,
335 "unable to write imr register 0x%X\n", madc->imr);
336 return ret;
337 }
338
339 return 0;
340}
341
342static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
343{
344 struct twl4030_madc_data *madc = _madc;
345 const struct twl4030_madc_conversion_method *method;
346 u8 isr_val, imr_val;
347 int i, len, ret;
348 struct twl4030_madc_request *r;
349
350 mutex_lock(&madc->lock);
351 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
352 if (ret) {
353 dev_err(madc->dev, "unable to read isr register 0x%X\n",
354 madc->isr);
355 goto err_i2c;
356 }
357 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
358 if (ret) {
359 dev_err(madc->dev, "unable to read imr register 0x%X\n",
360 madc->imr);
361 goto err_i2c;
362 }
363 isr_val &= ~imr_val;
364 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
365 if (!(isr_val & (1 << i)))
366 continue;
367 ret = twl4030_madc_disable_irq(madc, i);
368 if (ret < 0)
369 dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
370 madc->requests[i].result_pending = 1;
371 }
372 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
373 r = &madc->requests[i];
374 /* No pending results for this method, move to next one */
375 if (!r->result_pending)
376 continue;
377 method = &twl4030_conversion_methods[r->method];
378 /* Read results */
379 len = twl4030_madc_read_channels(madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100380 r->channels, r->rbuf, r->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530381 /* Return results to caller */
382 if (r->func_cb != NULL) {
383 r->func_cb(len, r->channels, r->rbuf);
384 r->func_cb = NULL;
385 }
386 /* Free request */
387 r->result_pending = 0;
388 r->active = 0;
389 }
390 mutex_unlock(&madc->lock);
391
392 return IRQ_HANDLED;
393
394err_i2c:
395 /*
396 * In case of error check whichever request is active
397 * and service the same.
398 */
399 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
400 r = &madc->requests[i];
401 if (r->active == 0)
402 continue;
403 method = &twl4030_conversion_methods[r->method];
404 /* Read results */
405 len = twl4030_madc_read_channels(madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100406 r->channels, r->rbuf, r->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530407 /* Return results to caller */
408 if (r->func_cb != NULL) {
409 r->func_cb(len, r->channels, r->rbuf);
410 r->func_cb = NULL;
411 }
412 /* Free request */
413 r->result_pending = 0;
414 r->active = 0;
415 }
416 mutex_unlock(&madc->lock);
417
418 return IRQ_HANDLED;
419}
420
421static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
422 struct twl4030_madc_request *req)
423{
424 struct twl4030_madc_request *p;
425 int ret;
426
427 p = &madc->requests[req->method];
428 memcpy(p, req, sizeof(*req));
429 ret = twl4030_madc_enable_irq(madc, req->method);
430 if (ret < 0) {
431 dev_err(madc->dev, "enable irq failed!!\n");
432 return ret;
433 }
434
435 return 0;
436}
437
438/*
439 * Function which enables the madc conversion
440 * by writing to the control register.
441 * @madc - pointer to twl4030_madc_data struct
442 * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
443 * corresponding to RT SW1 or SW2 conversion methods.
444 * Returns 0 if succeeds else a negative error value
445 */
446static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
447 int conv_method)
448{
449 const struct twl4030_madc_conversion_method *method;
450 int ret = 0;
451 method = &twl4030_conversion_methods[conv_method];
452 switch (conv_method) {
453 case TWL4030_MADC_SW1:
454 case TWL4030_MADC_SW2:
455 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
456 TWL4030_MADC_SW_START, method->ctrl);
457 if (ret) {
458 dev_err(madc->dev,
459 "unable to write ctrl register 0x%X\n",
460 method->ctrl);
461 return ret;
462 }
463 break;
464 default:
465 break;
466 }
467
468 return 0;
469}
470
471/*
472 * Function that waits for conversion to be ready
473 * @madc - pointer to twl4030_madc_data struct
474 * @timeout_ms - timeout value in milliseconds
475 * @status_reg - ctrl register
476 * returns 0 if succeeds else a negative error value
477 */
478static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
479 unsigned int timeout_ms,
480 u8 status_reg)
481{
482 unsigned long timeout;
483 int ret;
484
485 timeout = jiffies + msecs_to_jiffies(timeout_ms);
486 do {
487 u8 reg;
488
489 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
490 if (ret) {
491 dev_err(madc->dev,
492 "unable to read status register 0x%X\n",
493 status_reg);
494 return ret;
495 }
496 if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
497 return 0;
498 usleep_range(500, 2000);
499 } while (!time_after(jiffies, timeout));
500 dev_err(madc->dev, "conversion timeout!\n");
501
502 return -EAGAIN;
503}
504
505/*
506 * An exported function which can be called from other kernel drivers.
507 * @req twl4030_madc_request structure
508 * req->rbuf will be filled with read values of channels based on the
509 * channel index. If a particular channel reading fails there will
510 * be a negative error value in the corresponding array element.
511 * returns 0 if succeeds else error value
512 */
513int twl4030_madc_conversion(struct twl4030_madc_request *req)
514{
515 const struct twl4030_madc_conversion_method *method;
516 u8 ch_msb, ch_lsb;
517 int ret;
518
Kyle Mannad0e84ca2011-08-11 22:33:14 -0500519 if (!req || !twl4030_madc)
Keerthyf99c1d42011-03-01 19:12:26 +0530520 return -EINVAL;
Kyle Mannad0e84ca2011-08-11 22:33:14 -0500521
Keerthyf99c1d42011-03-01 19:12:26 +0530522 mutex_lock(&twl4030_madc->lock);
523 if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
524 ret = -EINVAL;
525 goto out;
526 }
527 /* Do we have a conversion request ongoing */
528 if (twl4030_madc->requests[req->method].active) {
529 ret = -EBUSY;
530 goto out;
531 }
532 ch_msb = (req->channels >> 8) & 0xff;
533 ch_lsb = req->channels & 0xff;
534 method = &twl4030_conversion_methods[req->method];
535 /* Select channels to be converted */
536 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
537 if (ret) {
538 dev_err(twl4030_madc->dev,
539 "unable to write sel register 0x%X\n", method->sel + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530540 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530541 }
542 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
543 if (ret) {
544 dev_err(twl4030_madc->dev,
545 "unable to write sel register 0x%X\n", method->sel + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530546 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530547 }
548 /* Select averaging for all channels if do_avg is set */
549 if (req->do_avg) {
550 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
551 ch_msb, method->avg + 1);
552 if (ret) {
553 dev_err(twl4030_madc->dev,
554 "unable to write avg register 0x%X\n",
555 method->avg + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530556 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530557 }
558 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
559 ch_lsb, method->avg);
560 if (ret) {
561 dev_err(twl4030_madc->dev,
562 "unable to write sel reg 0x%X\n",
563 method->sel + 1);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530564 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530565 }
566 }
567 if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
568 ret = twl4030_madc_set_irq(twl4030_madc, req);
569 if (ret < 0)
570 goto out;
571 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
572 if (ret < 0)
573 goto out;
574 twl4030_madc->requests[req->method].active = 1;
575 ret = 0;
576 goto out;
577 }
578 /* With RT method we should not be here anymore */
579 if (req->method == TWL4030_MADC_RT) {
580 ret = -EINVAL;
581 goto out;
582 }
583 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
584 if (ret < 0)
585 goto out;
586 twl4030_madc->requests[req->method].active = 1;
587 /* Wait until conversion is ready (ctrl register returns EOC) */
588 ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
589 if (ret) {
590 twl4030_madc->requests[req->method].active = 0;
591 goto out;
592 }
593 ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100594 req->channels, req->rbuf, req->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530595 twl4030_madc->requests[req->method].active = 0;
596
597out:
598 mutex_unlock(&twl4030_madc->lock);
599
600 return ret;
601}
602EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
603
604/*
605 * Return channel value
606 * Or < 0 on failure.
607 */
608int twl4030_get_madc_conversion(int channel_no)
609{
610 struct twl4030_madc_request req;
611 int temp = 0;
612 int ret;
613
614 req.channels = (1 << channel_no);
615 req.method = TWL4030_MADC_SW2;
616 req.active = 0;
617 req.func_cb = NULL;
618 ret = twl4030_madc_conversion(&req);
619 if (ret < 0)
620 return ret;
621 if (req.rbuf[channel_no] > 0)
622 temp = req.rbuf[channel_no];
623
624 return temp;
625}
626EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
627
628/*
629 * Function to enable or disable bias current for
630 * main battery type reading or temperature sensing
631 * @madc - pointer to twl4030_madc_data struct
632 * @chan - can be one of the two values
633 * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
634 * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
635 * sensing
636 * @on - enable or disable chan.
637 */
638static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
639 int chan, int on)
640{
641 int ret;
642 u8 regval;
643
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100644 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530645 &regval, TWL4030_BCI_BCICTL1);
646 if (ret) {
647 dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
648 TWL4030_BCI_BCICTL1);
649 return ret;
650 }
651 if (on)
652 regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
653 else
654 regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100655 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530656 regval, TWL4030_BCI_BCICTL1);
657 if (ret) {
658 dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
659 TWL4030_BCI_BCICTL1);
660 return ret;
661 }
662
663 return 0;
664}
665
666/*
667 * Function that sets MADC software power on bit to enable MADC
668 * @madc - pointer to twl4030_madc_data struct
669 * @on - Enable or disable MADC software powen on bit.
670 * returns error if i2c read/write fails else 0
671 */
672static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
673{
674 u8 regval;
675 int ret;
676
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100677 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530678 &regval, TWL4030_MADC_CTRL1);
679 if (ret) {
680 dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
681 TWL4030_MADC_CTRL1);
682 return ret;
683 }
684 if (on)
685 regval |= TWL4030_MADC_MADCON;
686 else
687 regval &= ~TWL4030_MADC_MADCON;
688 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
689 if (ret) {
690 dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
691 TWL4030_MADC_CTRL1);
692 return ret;
693 }
694
695 return 0;
696}
697
698/*
699 * Initialize MADC and request for threaded irq
700 */
Bill Pembertonf791be42012-11-19 13:23:04 -0500701static int twl4030_madc_probe(struct platform_device *pdev)
Keerthyf99c1d42011-03-01 19:12:26 +0530702{
703 struct twl4030_madc_data *madc;
704 struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
705 int ret;
706 u8 regval;
707
708 if (!pdata) {
709 dev_err(&pdev->dev, "platform_data not available\n");
710 return -EINVAL;
711 }
712 madc = kzalloc(sizeof(*madc), GFP_KERNEL);
713 if (!madc)
714 return -ENOMEM;
715
Kyle Manna66cc5b82011-08-11 22:33:12 -0500716 madc->dev = &pdev->dev;
717
Keerthyf99c1d42011-03-01 19:12:26 +0530718 /*
719 * Phoenix provides 2 interrupt lines. The first one is connected to
720 * the OMAP. The other one can be connected to the other processor such
721 * as modem. Hence two separate ISR and IMR registers.
722 */
723 madc->imr = (pdata->irq_line == 1) ?
724 TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
725 madc->isr = (pdata->irq_line == 1) ?
726 TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
727 ret = twl4030_madc_set_power(madc, 1);
728 if (ret < 0)
729 goto err_power;
730 ret = twl4030_madc_set_current_generator(madc, 0, 1);
731 if (ret < 0)
732 goto err_current_generator;
733
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100734 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530735 &regval, TWL4030_BCI_BCICTL1);
736 if (ret) {
737 dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
738 TWL4030_BCI_BCICTL1);
739 goto err_i2c;
740 }
741 regval |= TWL4030_BCI_MESBAT;
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100742 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530743 regval, TWL4030_BCI_BCICTL1);
744 if (ret) {
745 dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
746 TWL4030_BCI_BCICTL1);
747 goto err_i2c;
748 }
Kyle Manna3d6271f2011-08-11 22:33:13 -0500749
750 /* Check that MADC clock is on */
751 ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
752 if (ret) {
753 dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
754 TWL4030_REG_GPBR1);
755 goto err_i2c;
756 }
757
758 /* If MADC clk is not on, turn it on */
759 if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
760 dev_info(&pdev->dev, "clk disabled, enabling\n");
761 regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
762 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
763 TWL4030_REG_GPBR1);
764 if (ret) {
765 dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
766 TWL4030_REG_GPBR1);
767 goto err_i2c;
768 }
769 }
770
Keerthyf99c1d42011-03-01 19:12:26 +0530771 platform_set_drvdata(pdev, madc);
772 mutex_init(&madc->lock);
773 ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
774 twl4030_madc_threaded_irq_handler,
775 IRQF_TRIGGER_RISING, "twl4030_madc", madc);
776 if (ret) {
777 dev_dbg(&pdev->dev, "could not request irq\n");
778 goto err_irq;
779 }
780 twl4030_madc = madc;
781 return 0;
782err_irq:
783 platform_set_drvdata(pdev, NULL);
784err_i2c:
785 twl4030_madc_set_current_generator(madc, 0, 0);
786err_current_generator:
787 twl4030_madc_set_power(madc, 0);
788err_power:
789 kfree(madc);
790
791 return ret;
792}
793
Bill Pemberton4740f732012-11-19 13:26:01 -0500794static int twl4030_madc_remove(struct platform_device *pdev)
Keerthyf99c1d42011-03-01 19:12:26 +0530795{
796 struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
797
798 free_irq(platform_get_irq(pdev, 0), madc);
799 platform_set_drvdata(pdev, NULL);
800 twl4030_madc_set_current_generator(madc, 0, 0);
801 twl4030_madc_set_power(madc, 0);
802 kfree(madc);
803
804 return 0;
805}
806
807static struct platform_driver twl4030_madc_driver = {
808 .probe = twl4030_madc_probe,
Arnd Bergmann03715412013-03-14 22:56:38 +0100809 .remove = twl4030_madc_remove,
Keerthyf99c1d42011-03-01 19:12:26 +0530810 .driver = {
811 .name = "twl4030_madc",
812 .owner = THIS_MODULE,
813 },
814};
815
Mark Brown65349d62011-11-23 22:58:34 +0000816module_platform_driver(twl4030_madc_driver);
Keerthyf99c1d42011-03-01 19:12:26 +0530817
818MODULE_DESCRIPTION("TWL4030 ADC driver");
819MODULE_LICENSE("GPL");
820MODULE_AUTHOR("J Keerthy");
Axel Lin0ea3e832011-03-07 11:02:29 +0800821MODULE_ALIAS("platform:twl4030_madc");