blob: 0c74869a540ad390a0f995a702ee953cf53e0669 [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
Keerthyf99c1d42011-03-01 19:12:26 +053032#include <linux/device.h>
33#include <linux/interrupt.h>
34#include <linux/kernel.h>
35#include <linux/delay.h>
36#include <linux/platform_device.h>
37#include <linux/slab.h>
38#include <linux/i2c/twl.h>
39#include <linux/i2c/twl4030-madc.h>
40#include <linux/module.h>
41#include <linux/stddef.h>
42#include <linux/mutex.h>
43#include <linux/bitops.h>
44#include <linux/jiffies.h>
45#include <linux/types.h>
46#include <linux/gfp.h>
47#include <linux/err.h>
Adam YH Lee7cc97d72015-08-04 11:15:48 -070048#include <linux/regulator/consumer.h>
Keerthyf99c1d42011-03-01 19:12:26 +053049
Sebastian Reichel2f39b702014-03-16 02:43:26 +010050#include <linux/iio/iio.h>
51
Adam YH Lee7cc97d72015-08-04 11:15:48 -070052#define TWL4030_USB_SEL_MADC_MCPC (1<<3)
53#define TWL4030_USB_CARKIT_ANA_CTRL 0xBB
54
Sebastian Reichel99be0242014-03-16 02:43:27 +010055/**
Keerthyf99c1d42011-03-01 19:12:26 +053056 * struct twl4030_madc_data - a container for madc info
Sebastian Reichel99be0242014-03-16 02:43:27 +010057 * @dev: Pointer to device structure for madc
58 * @lock: Mutex protecting this data structure
Adam YH Lee7cc97d72015-08-04 11:15:48 -070059 * @regulator: Pointer to bias regulator for madc
Sebastian Reichel99be0242014-03-16 02:43:27 +010060 * @requests: Array of request struct corresponding to SW1, SW2 and RT
61 * @use_second_irq: IRQ selection (main or co-processor)
62 * @imr: Interrupt mask register of MADC
63 * @isr: Interrupt status register of MADC
Keerthyf99c1d42011-03-01 19:12:26 +053064 */
65struct twl4030_madc_data {
66 struct device *dev;
67 struct mutex lock; /* mutex protecting this data structure */
Adam YH Lee7cc97d72015-08-04 11:15:48 -070068 struct regulator *usb3v1;
Keerthyf99c1d42011-03-01 19:12:26 +053069 struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
Sebastian Reichel2f39b702014-03-16 02:43:26 +010070 bool use_second_irq;
Sebastian Reichel99be0242014-03-16 02:43:27 +010071 u8 imr;
72 u8 isr;
Keerthyf99c1d42011-03-01 19:12:26 +053073};
74
Sebastian Reichel2f39b702014-03-16 02:43:26 +010075static int twl4030_madc_read(struct iio_dev *iio_dev,
76 const struct iio_chan_spec *chan,
77 int *val, int *val2, long mask)
78{
79 struct twl4030_madc_data *madc = iio_priv(iio_dev);
80 struct twl4030_madc_request req;
81 int ret;
82
83 req.method = madc->use_second_irq ? TWL4030_MADC_SW2 : TWL4030_MADC_SW1;
84
85 req.channels = BIT(chan->channel);
86 req.active = false;
87 req.func_cb = NULL;
88 req.type = TWL4030_MADC_WAIT;
89 req.raw = !(mask == IIO_CHAN_INFO_PROCESSED);
90 req.do_avg = (mask == IIO_CHAN_INFO_AVERAGE_RAW);
91
92 ret = twl4030_madc_conversion(&req);
93 if (ret < 0)
94 return ret;
95
96 *val = req.rbuf[chan->channel];
97
98 return IIO_VAL_INT;
99}
100
101static const struct iio_info twl4030_madc_iio_info = {
102 .read_raw = &twl4030_madc_read,
103 .driver_module = THIS_MODULE,
104};
105
106#define TWL4030_ADC_CHANNEL(_channel, _type, _name) { \
107 .type = _type, \
108 .channel = _channel, \
109 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
110 BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \
111 BIT(IIO_CHAN_INFO_PROCESSED), \
112 .datasheet_name = _name, \
113 .indexed = 1, \
114}
115
116static const struct iio_chan_spec twl4030_madc_iio_channels[] = {
117 TWL4030_ADC_CHANNEL(0, IIO_VOLTAGE, "ADCIN0"),
118 TWL4030_ADC_CHANNEL(1, IIO_TEMP, "ADCIN1"),
119 TWL4030_ADC_CHANNEL(2, IIO_VOLTAGE, "ADCIN2"),
120 TWL4030_ADC_CHANNEL(3, IIO_VOLTAGE, "ADCIN3"),
121 TWL4030_ADC_CHANNEL(4, IIO_VOLTAGE, "ADCIN4"),
122 TWL4030_ADC_CHANNEL(5, IIO_VOLTAGE, "ADCIN5"),
123 TWL4030_ADC_CHANNEL(6, IIO_VOLTAGE, "ADCIN6"),
124 TWL4030_ADC_CHANNEL(7, IIO_VOLTAGE, "ADCIN7"),
125 TWL4030_ADC_CHANNEL(8, IIO_VOLTAGE, "ADCIN8"),
126 TWL4030_ADC_CHANNEL(9, IIO_VOLTAGE, "ADCIN9"),
127 TWL4030_ADC_CHANNEL(10, IIO_CURRENT, "ADCIN10"),
128 TWL4030_ADC_CHANNEL(11, IIO_VOLTAGE, "ADCIN11"),
129 TWL4030_ADC_CHANNEL(12, IIO_VOLTAGE, "ADCIN12"),
130 TWL4030_ADC_CHANNEL(13, IIO_VOLTAGE, "ADCIN13"),
131 TWL4030_ADC_CHANNEL(14, IIO_VOLTAGE, "ADCIN14"),
132 TWL4030_ADC_CHANNEL(15, IIO_VOLTAGE, "ADCIN15"),
133};
134
Keerthyf99c1d42011-03-01 19:12:26 +0530135static struct twl4030_madc_data *twl4030_madc;
136
137struct twl4030_prescale_divider_ratios {
138 s16 numerator;
139 s16 denominator;
140};
141
142static const struct twl4030_prescale_divider_ratios
143twl4030_divider_ratios[16] = {
144 {1, 1}, /* CHANNEL 0 No Prescaler */
145 {1, 1}, /* CHANNEL 1 No Prescaler */
146 {6, 10}, /* CHANNEL 2 */
147 {6, 10}, /* CHANNEL 3 */
148 {6, 10}, /* CHANNEL 4 */
149 {6, 10}, /* CHANNEL 5 */
150 {6, 10}, /* CHANNEL 6 */
151 {6, 10}, /* CHANNEL 7 */
152 {3, 14}, /* CHANNEL 8 */
153 {1, 3}, /* CHANNEL 9 */
154 {1, 1}, /* CHANNEL 10 No Prescaler */
155 {15, 100}, /* CHANNEL 11 */
156 {1, 4}, /* CHANNEL 12 */
157 {1, 1}, /* CHANNEL 13 Reserved channels */
158 {1, 1}, /* CHANNEL 14 Reseved channels */
159 {5, 11}, /* CHANNEL 15 */
160};
161
162
Sebastian Reichel99be0242014-03-16 02:43:27 +0100163/* Conversion table from -3 to 55 degrees Celcius */
164static int twl4030_therm_tbl[] = {
165 30800, 29500, 28300, 27100,
166 26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700,
167 17900, 17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100,
168 12600, 12100, 11600, 11200, 10800, 10400, 10000, 9630, 9280,
169 8950, 8620, 8310, 8020, 7730, 7460, 7200, 6950, 6710,
170 6470, 6250, 6040, 5830, 5640, 5450, 5260, 5090, 4920,
171 4760, 4600, 4450, 4310, 4170, 4040, 3910, 3790, 3670,
172 3550
Keerthyf99c1d42011-03-01 19:12:26 +0530173};
174
175/*
176 * Structure containing the registers
177 * of different conversion methods supported by MADC.
178 * Hardware or RT real time conversion request initiated by external host
179 * processor for RT Signal conversions.
180 * External host processors can also request for non RT conversions
181 * SW1 and SW2 software conversions also called asynchronous or GPC request.
182 */
183static
184const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
185 [TWL4030_MADC_RT] = {
186 .sel = TWL4030_MADC_RTSELECT_LSB,
187 .avg = TWL4030_MADC_RTAVERAGE_LSB,
188 .rbase = TWL4030_MADC_RTCH0_LSB,
189 },
190 [TWL4030_MADC_SW1] = {
191 .sel = TWL4030_MADC_SW1SELECT_LSB,
192 .avg = TWL4030_MADC_SW1AVERAGE_LSB,
193 .rbase = TWL4030_MADC_GPCH0_LSB,
194 .ctrl = TWL4030_MADC_CTRL_SW1,
195 },
196 [TWL4030_MADC_SW2] = {
197 .sel = TWL4030_MADC_SW2SELECT_LSB,
198 .avg = TWL4030_MADC_SW2AVERAGE_LSB,
199 .rbase = TWL4030_MADC_GPCH0_LSB,
200 .ctrl = TWL4030_MADC_CTRL_SW2,
201 },
202};
203
Sebastian Reichel99be0242014-03-16 02:43:27 +0100204/**
205 * twl4030_madc_channel_raw_read() - Function to read a particular channel value
206 * @madc: pointer to struct twl4030_madc_data
207 * @reg: lsb of ADC Channel
208 *
209 * Return: 0 on success, an error code otherwise.
Keerthyf99c1d42011-03-01 19:12:26 +0530210 */
211static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
212{
Sebastian Reichel168ae302014-03-16 02:43:29 +0100213 u16 val;
Keerthyf99c1d42011-03-01 19:12:26 +0530214 int ret;
215 /*
216 * For each ADC channel, we have MSB and LSB register pair. MSB address
217 * is always LSB address+1. reg parameter is the address of LSB register
218 */
Sebastian Reichel168ae302014-03-16 02:43:29 +0100219 ret = twl_i2c_read_u16(TWL4030_MODULE_MADC, &val, reg);
Keerthyf99c1d42011-03-01 19:12:26 +0530220 if (ret) {
Sebastian Reichel168ae302014-03-16 02:43:29 +0100221 dev_err(madc->dev, "unable to read register 0x%X\n", reg);
Keerthyf99c1d42011-03-01 19:12:26 +0530222 return ret;
223 }
224
Sebastian Reichel168ae302014-03-16 02:43:29 +0100225 return (int)(val >> 6);
Keerthyf99c1d42011-03-01 19:12:26 +0530226}
227
228/*
Sebastian Reichel99be0242014-03-16 02:43:27 +0100229 * Return battery temperature in degrees Celsius
Keerthyf99c1d42011-03-01 19:12:26 +0530230 * Or < 0 on failure.
231 */
232static int twl4030battery_temperature(int raw_volt)
233{
234 u8 val;
235 int temp, curr, volt, res, ret;
236
237 volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
Sebastian Reichel99be0242014-03-16 02:43:27 +0100238 /* Getting and calculating the supply current in micro amperes */
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100239 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
Keerthyf99c1d42011-03-01 19:12:26 +0530240 REG_BCICTL2);
241 if (ret < 0)
242 return ret;
Sebastian Reichel99be0242014-03-16 02:43:27 +0100243
H. Nikolaus Schaller0cbb39f2015-05-28 21:50:18 +0200244 curr = ((val & TWL4030_BCI_ITHSENS) + 1) * 10;
Keerthyf99c1d42011-03-01 19:12:26 +0530245 /* Getting and calculating the thermistor resistance in ohms */
246 res = volt * 1000 / curr;
247 /* calculating temperature */
248 for (temp = 58; temp >= 0; temp--) {
Sebastian Reichel99be0242014-03-16 02:43:27 +0100249 int actual = twl4030_therm_tbl[temp];
Keerthyf99c1d42011-03-01 19:12:26 +0530250 if ((actual - res) >= 0)
251 break;
252 }
253
254 return temp + 1;
255}
256
257static int twl4030battery_current(int raw_volt)
258{
259 int ret;
260 u8 val;
261
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100262 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
Keerthyf99c1d42011-03-01 19:12:26 +0530263 TWL4030_BCI_BCICTL1);
264 if (ret)
265 return ret;
266 if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
267 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
268 else /* slope of 0.88 mV/mA */
269 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
270}
Sebastian Reichel99be0242014-03-16 02:43:27 +0100271
Keerthyf99c1d42011-03-01 19:12:26 +0530272/*
273 * Function to read channel values
274 * @madc - pointer to twl4030_madc_data struct
275 * @reg_base - Base address of the first channel
Sebastian Reichel99be0242014-03-16 02:43:27 +0100276 * @Channels - 16 bit bitmap. If the bit is set, channel's value is read
Keerthyf99c1d42011-03-01 19:12:26 +0530277 * @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{
Sebastian Reichel99be0242014-03-16 02:43:27 +0100287 int count = 0;
288 int i;
Keerthyf99c1d42011-03-01 19:12:26 +0530289 u8 reg;
290
291 for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
Sebastian Reichel99be0242014-03-16 02:43:27 +0100292 reg = reg_base + (2 * i);
Keerthyf99c1d42011-03-01 19:12:26 +0530293 buf[i] = twl4030_madc_channel_raw_read(madc, reg);
294 if (buf[i] < 0) {
Sebastian Reichel99be0242014-03-16 02:43:27 +0100295 dev_err(madc->dev, "Unable to read register 0x%X\n",
296 reg);
297 return buf[i];
Keerthyf99c1d42011-03-01 19:12:26 +0530298 }
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");
Sebastian Reichel99be0242014-03-16 02:43:27 +0100308 return buf[i];
Keerthyf99c1d42011-03-01 19:12:26 +0530309 } 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");
Sebastian Reichel99be0242014-03-16 02:43:27 +0100318 return buf[i];
Keerthyf99c1d42011-03-01 19:12:26 +0530319 } 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 }
Keerthyf99c1d42011-03-01 19:12:26 +0530339
340 return count;
341}
342
343/*
344 * Enables irq.
345 * @madc - pointer to twl4030_madc_data struct
346 * @id - irq number to be enabled
347 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
348 * corresponding to RT, SW1, SW2 conversion requests.
349 * If the i2c read fails it returns an error else returns 0.
350 */
351static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
352{
353 u8 val;
354 int ret;
355
356 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
357 if (ret) {
358 dev_err(madc->dev, "unable to read imr register 0x%X\n",
359 madc->imr);
360 return ret;
361 }
Sebastian Reichel99be0242014-03-16 02:43:27 +0100362
Keerthyf99c1d42011-03-01 19:12:26 +0530363 val &= ~(1 << id);
364 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
365 if (ret) {
366 dev_err(madc->dev,
367 "unable to write imr register 0x%X\n", madc->imr);
368 return ret;
Keerthyf99c1d42011-03-01 19:12:26 +0530369 }
370
371 return 0;
372}
373
374/*
375 * Disables irq.
376 * @madc - pointer to twl4030_madc_data struct
377 * @id - irq number to be disabled
378 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
379 * corresponding to RT, SW1, SW2 conversion requests.
380 * Returns error if i2c read/write fails.
381 */
382static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
383{
384 u8 val;
385 int ret;
386
387 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
388 if (ret) {
389 dev_err(madc->dev, "unable to read imr register 0x%X\n",
390 madc->imr);
391 return ret;
392 }
393 val |= (1 << id);
394 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
395 if (ret) {
396 dev_err(madc->dev,
397 "unable to write imr register 0x%X\n", madc->imr);
398 return ret;
399 }
400
401 return 0;
402}
403
404static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
405{
406 struct twl4030_madc_data *madc = _madc;
407 const struct twl4030_madc_conversion_method *method;
408 u8 isr_val, imr_val;
409 int i, len, ret;
410 struct twl4030_madc_request *r;
411
412 mutex_lock(&madc->lock);
413 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
414 if (ret) {
415 dev_err(madc->dev, "unable to read isr register 0x%X\n",
416 madc->isr);
417 goto err_i2c;
418 }
419 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
420 if (ret) {
421 dev_err(madc->dev, "unable to read imr register 0x%X\n",
422 madc->imr);
423 goto err_i2c;
424 }
425 isr_val &= ~imr_val;
426 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
427 if (!(isr_val & (1 << i)))
428 continue;
429 ret = twl4030_madc_disable_irq(madc, i);
430 if (ret < 0)
Sebastian Reichel99be0242014-03-16 02:43:27 +0100431 dev_dbg(madc->dev, "Disable interrupt failed %d\n", i);
Keerthyf99c1d42011-03-01 19:12:26 +0530432 madc->requests[i].result_pending = 1;
433 }
434 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
435 r = &madc->requests[i];
436 /* No pending results for this method, move to next one */
437 if (!r->result_pending)
438 continue;
439 method = &twl4030_conversion_methods[r->method];
440 /* Read results */
441 len = twl4030_madc_read_channels(madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100442 r->channels, r->rbuf, r->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530443 /* Return results to caller */
444 if (r->func_cb != NULL) {
445 r->func_cb(len, r->channels, r->rbuf);
446 r->func_cb = NULL;
447 }
448 /* Free request */
449 r->result_pending = 0;
450 r->active = 0;
451 }
452 mutex_unlock(&madc->lock);
453
454 return IRQ_HANDLED;
455
456err_i2c:
457 /*
458 * In case of error check whichever request is active
459 * and service the same.
460 */
461 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
462 r = &madc->requests[i];
463 if (r->active == 0)
464 continue;
465 method = &twl4030_conversion_methods[r->method];
466 /* Read results */
467 len = twl4030_madc_read_channels(madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100468 r->channels, r->rbuf, r->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530469 /* Return results to caller */
470 if (r->func_cb != NULL) {
471 r->func_cb(len, r->channels, r->rbuf);
472 r->func_cb = NULL;
473 }
474 /* Free request */
475 r->result_pending = 0;
476 r->active = 0;
477 }
478 mutex_unlock(&madc->lock);
479
480 return IRQ_HANDLED;
481}
482
483static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
484 struct twl4030_madc_request *req)
485{
486 struct twl4030_madc_request *p;
487 int ret;
488
489 p = &madc->requests[req->method];
490 memcpy(p, req, sizeof(*req));
491 ret = twl4030_madc_enable_irq(madc, req->method);
492 if (ret < 0) {
493 dev_err(madc->dev, "enable irq failed!!\n");
494 return ret;
495 }
496
497 return 0;
498}
499
500/*
501 * Function which enables the madc conversion
502 * by writing to the control register.
503 * @madc - pointer to twl4030_madc_data struct
504 * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
505 * corresponding to RT SW1 or SW2 conversion methods.
506 * Returns 0 if succeeds else a negative error value
507 */
508static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
509 int conv_method)
510{
511 const struct twl4030_madc_conversion_method *method;
512 int ret = 0;
Sebastian Reichel99be0242014-03-16 02:43:27 +0100513
514 if (conv_method != TWL4030_MADC_SW1 && conv_method != TWL4030_MADC_SW2)
515 return -ENOTSUPP;
516
Keerthyf99c1d42011-03-01 19:12:26 +0530517 method = &twl4030_conversion_methods[conv_method];
Sebastian Reichel99be0242014-03-16 02:43:27 +0100518 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, TWL4030_MADC_SW_START,
519 method->ctrl);
520 if (ret) {
521 dev_err(madc->dev, "unable to write ctrl register 0x%X\n",
522 method->ctrl);
523 return ret;
Keerthyf99c1d42011-03-01 19:12:26 +0530524 }
525
526 return 0;
527}
528
529/*
530 * Function that waits for conversion to be ready
531 * @madc - pointer to twl4030_madc_data struct
532 * @timeout_ms - timeout value in milliseconds
533 * @status_reg - ctrl register
534 * returns 0 if succeeds else a negative error value
535 */
536static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
537 unsigned int timeout_ms,
538 u8 status_reg)
539{
540 unsigned long timeout;
541 int ret;
542
543 timeout = jiffies + msecs_to_jiffies(timeout_ms);
544 do {
545 u8 reg;
546
547 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
548 if (ret) {
549 dev_err(madc->dev,
550 "unable to read status register 0x%X\n",
551 status_reg);
552 return ret;
553 }
554 if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
555 return 0;
556 usleep_range(500, 2000);
557 } while (!time_after(jiffies, timeout));
558 dev_err(madc->dev, "conversion timeout!\n");
559
560 return -EAGAIN;
561}
562
563/*
564 * An exported function which can be called from other kernel drivers.
565 * @req twl4030_madc_request structure
566 * req->rbuf will be filled with read values of channels based on the
567 * channel index. If a particular channel reading fails there will
568 * be a negative error value in the corresponding array element.
569 * returns 0 if succeeds else error value
570 */
571int twl4030_madc_conversion(struct twl4030_madc_request *req)
572{
573 const struct twl4030_madc_conversion_method *method;
Keerthyf99c1d42011-03-01 19:12:26 +0530574 int ret;
575
Kyle Mannad0e84ca2011-08-11 22:33:14 -0500576 if (!req || !twl4030_madc)
Keerthyf99c1d42011-03-01 19:12:26 +0530577 return -EINVAL;
Kyle Mannad0e84ca2011-08-11 22:33:14 -0500578
Keerthyf99c1d42011-03-01 19:12:26 +0530579 mutex_lock(&twl4030_madc->lock);
580 if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
581 ret = -EINVAL;
582 goto out;
583 }
584 /* Do we have a conversion request ongoing */
585 if (twl4030_madc->requests[req->method].active) {
586 ret = -EBUSY;
587 goto out;
588 }
Keerthyf99c1d42011-03-01 19:12:26 +0530589 method = &twl4030_conversion_methods[req->method];
590 /* Select channels to be converted */
Sebastian Reichel168ae302014-03-16 02:43:29 +0100591 ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels, method->sel);
Keerthyf99c1d42011-03-01 19:12:26 +0530592 if (ret) {
593 dev_err(twl4030_madc->dev,
Sebastian Reichel168ae302014-03-16 02:43:29 +0100594 "unable to write sel register 0x%X\n", method->sel);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530595 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530596 }
597 /* Select averaging for all channels if do_avg is set */
598 if (req->do_avg) {
Sebastian Reichel168ae302014-03-16 02:43:29 +0100599 ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels,
600 method->avg);
Keerthyf99c1d42011-03-01 19:12:26 +0530601 if (ret) {
602 dev_err(twl4030_madc->dev,
603 "unable to write avg register 0x%X\n",
Sebastian Reichel99be0242014-03-16 02:43:27 +0100604 method->avg);
Sanjeev Premie178ccb2011-07-11 20:50:31 +0530605 goto out;
Keerthyf99c1d42011-03-01 19:12:26 +0530606 }
607 }
608 if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
609 ret = twl4030_madc_set_irq(twl4030_madc, req);
610 if (ret < 0)
611 goto out;
612 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
613 if (ret < 0)
614 goto out;
615 twl4030_madc->requests[req->method].active = 1;
616 ret = 0;
617 goto out;
618 }
619 /* With RT method we should not be here anymore */
620 if (req->method == TWL4030_MADC_RT) {
621 ret = -EINVAL;
622 goto out;
623 }
624 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
625 if (ret < 0)
626 goto out;
627 twl4030_madc->requests[req->method].active = 1;
628 /* Wait until conversion is ready (ctrl register returns EOC) */
629 ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
630 if (ret) {
631 twl4030_madc->requests[req->method].active = 0;
632 goto out;
633 }
634 ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
Pali Rohára5055d52013-02-15 23:56:49 +0100635 req->channels, req->rbuf, req->raw);
Keerthyf99c1d42011-03-01 19:12:26 +0530636 twl4030_madc->requests[req->method].active = 0;
637
638out:
639 mutex_unlock(&twl4030_madc->lock);
640
641 return ret;
642}
643EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
644
Keerthyf99c1d42011-03-01 19:12:26 +0530645int twl4030_get_madc_conversion(int channel_no)
646{
647 struct twl4030_madc_request req;
648 int temp = 0;
649 int ret;
650
651 req.channels = (1 << channel_no);
652 req.method = TWL4030_MADC_SW2;
653 req.active = 0;
Paul Kocialkowskie0326be2014-05-24 13:09:00 +0100654 req.raw = 0;
Keerthyf99c1d42011-03-01 19:12:26 +0530655 req.func_cb = NULL;
656 ret = twl4030_madc_conversion(&req);
657 if (ret < 0)
658 return ret;
659 if (req.rbuf[channel_no] > 0)
660 temp = req.rbuf[channel_no];
661
662 return temp;
663}
664EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
665
Sebastian Reichel99be0242014-03-16 02:43:27 +0100666/**
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:
H. Nikolaus Schaller994bda82015-05-28 21:50:19 +0200671 * 0 - Enables bias current for main battery type reading
672 * 1 - Enables bias current for main battery temperature sensing
Sebastian Reichel99be0242014-03-16 02:43:27 +0100673 * @on: enable or disable chan.
674 *
Keerthyf99c1d42011-03-01 19:12:26 +0530675 * Function to enable or disable bias current for
676 * main battery type reading or temperature sensing
Keerthyf99c1d42011-03-01 19:12:26 +0530677 */
678static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
679 int chan, int on)
680{
681 int ret;
Sebastian Reichel99be0242014-03-16 02:43:27 +0100682 int regmask;
Keerthyf99c1d42011-03-01 19:12:26 +0530683 u8 regval;
684
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100685 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530686 &regval, 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 }
Sebastian Reichel99be0242014-03-16 02:43:27 +0100692
693 regmask = chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
Keerthyf99c1d42011-03-01 19:12:26 +0530694 if (on)
Sebastian Reichel99be0242014-03-16 02:43:27 +0100695 regval |= regmask;
Keerthyf99c1d42011-03-01 19:12:26 +0530696 else
Sebastian Reichel99be0242014-03-16 02:43:27 +0100697 regval &= ~regmask;
698
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100699 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530700 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
Sebastian Reichel99be0242014-03-16 02:43:27 +0100713 * @on - Enable or disable MADC software power on bit.
Keerthyf99c1d42011-03-01 19:12:26 +0530714 * returns error if i2c read/write fails else 0
715 */
716static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
717{
718 u8 regval;
719 int ret;
720
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100721 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530722 &regval, 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(TWL4030_MODULE_MADC, 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 */
Bill Pembertonf791be42012-11-19 13:23:04 -0500745static int twl4030_madc_probe(struct platform_device *pdev)
Keerthyf99c1d42011-03-01 19:12:26 +0530746{
747 struct twl4030_madc_data *madc;
Jingoo Han334a41c2013-07-30 17:10:05 +0900748 struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100749 struct device_node *np = pdev->dev.of_node;
Sebastian Reichele7f22b72014-03-16 02:43:25 +0100750 int irq, ret;
Keerthyf99c1d42011-03-01 19:12:26 +0530751 u8 regval;
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100752 struct iio_dev *iio_dev = NULL;
Keerthyf99c1d42011-03-01 19:12:26 +0530753
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100754 if (!pdata && !np) {
755 dev_err(&pdev->dev, "neither platform data nor Device Tree node available\n");
Keerthyf99c1d42011-03-01 19:12:26 +0530756 return -EINVAL;
757 }
Keerthyf99c1d42011-03-01 19:12:26 +0530758
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100759 iio_dev = devm_iio_device_alloc(&pdev->dev, 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(iio_dev);
Kyle Manna66cc5b82011-08-11 22:33:12 -0500766 madc->dev = &pdev->dev;
767
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100768 iio_dev->name = dev_name(&pdev->dev);
769 iio_dev->dev.parent = &pdev->dev;
770 iio_dev->dev.of_node = pdev->dev.of_node;
771 iio_dev->info = &twl4030_madc_iio_info;
772 iio_dev->modes = INDIO_DIRECT_MODE;
773 iio_dev->channels = twl4030_madc_iio_channels;
774 iio_dev->num_channels = ARRAY_SIZE(twl4030_madc_iio_channels);
775
Keerthyf99c1d42011-03-01 19:12:26 +0530776 /*
777 * Phoenix provides 2 interrupt lines. The first one is connected to
778 * the OMAP. The other one can be connected to the other processor such
779 * as modem. Hence two separate ISR and IMR registers.
780 */
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100781 if (pdata)
782 madc->use_second_irq = (pdata->irq_line != 1);
783 else
784 madc->use_second_irq = of_property_read_bool(np,
785 "ti,system-uses-second-madc-irq");
786
787 madc->imr = madc->use_second_irq ? TWL4030_MADC_IMR2 :
788 TWL4030_MADC_IMR1;
789 madc->isr = madc->use_second_irq ? TWL4030_MADC_ISR2 :
790 TWL4030_MADC_ISR1;
791
Keerthyf99c1d42011-03-01 19:12:26 +0530792 ret = twl4030_madc_set_power(madc, 1);
793 if (ret < 0)
Sebastian Reichele7f22b72014-03-16 02:43:25 +0100794 return ret;
Keerthyf99c1d42011-03-01 19:12:26 +0530795 ret = twl4030_madc_set_current_generator(madc, 0, 1);
796 if (ret < 0)
797 goto err_current_generator;
798
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100799 ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530800 &regval, TWL4030_BCI_BCICTL1);
801 if (ret) {
802 dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
803 TWL4030_BCI_BCICTL1);
804 goto err_i2c;
805 }
806 regval |= TWL4030_BCI_MESBAT;
Peter Ujfalusie45342f2012-11-13 09:28:51 +0100807 ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
Keerthyf99c1d42011-03-01 19:12:26 +0530808 regval, TWL4030_BCI_BCICTL1);
809 if (ret) {
810 dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
811 TWL4030_BCI_BCICTL1);
812 goto err_i2c;
813 }
Kyle Manna3d6271f2011-08-11 22:33:13 -0500814
815 /* Check that MADC clock is on */
816 ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
817 if (ret) {
818 dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
819 TWL4030_REG_GPBR1);
820 goto err_i2c;
821 }
822
823 /* If MADC clk is not on, turn it on */
824 if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
825 dev_info(&pdev->dev, "clk disabled, enabling\n");
826 regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
827 ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
828 TWL4030_REG_GPBR1);
829 if (ret) {
830 dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
831 TWL4030_REG_GPBR1);
832 goto err_i2c;
833 }
834 }
835
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100836 platform_set_drvdata(pdev, iio_dev);
Keerthyf99c1d42011-03-01 19:12:26 +0530837 mutex_init(&madc->lock);
Sebastian Reichele7f22b72014-03-16 02:43:25 +0100838
839 irq = platform_get_irq(pdev, 0);
840 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
Keerthyf99c1d42011-03-01 19:12:26 +0530841 twl4030_madc_threaded_irq_handler,
Fabio Estevam6c0d48c2015-05-24 17:39:04 -0300842 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
843 "twl4030_madc", madc);
Keerthyf99c1d42011-03-01 19:12:26 +0530844 if (ret) {
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100845 dev_err(&pdev->dev, "could not request irq\n");
Jingoo Hanc3d6a0a2013-05-06 13:08:08 +0900846 goto err_i2c;
Keerthyf99c1d42011-03-01 19:12:26 +0530847 }
848 twl4030_madc = madc;
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100849
Adam YH Lee7cc97d72015-08-04 11:15:48 -0700850 /* Configure MADC[3:6] */
851 ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
852 TWL4030_USB_CARKIT_ANA_CTRL);
853 if (ret) {
854 dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL 0x%X\n",
855 TWL4030_USB_CARKIT_ANA_CTRL);
856 goto err_i2c;
857 }
858 regval |= TWL4030_USB_SEL_MADC_MCPC;
859 ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
860 TWL4030_USB_CARKIT_ANA_CTRL);
861 if (ret) {
862 dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
863 TWL4030_USB_CARKIT_ANA_CTRL);
864 goto err_i2c;
865 }
866
867 /* Enable 3v1 bias regulator for MADC[3:6] */
868 madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
869 if (IS_ERR(madc->usb3v1))
870 return -ENODEV;
871
872 ret = regulator_enable(madc->usb3v1);
873 if (ret)
874 dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
875
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100876 ret = iio_device_register(iio_dev);
877 if (ret) {
878 dev_err(&pdev->dev, "could not register iio device\n");
879 goto err_i2c;
880 }
881
Keerthyf99c1d42011-03-01 19:12:26 +0530882 return 0;
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100883
Keerthyf99c1d42011-03-01 19:12:26 +0530884err_i2c:
885 twl4030_madc_set_current_generator(madc, 0, 0);
886err_current_generator:
887 twl4030_madc_set_power(madc, 0);
Keerthyf99c1d42011-03-01 19:12:26 +0530888 return ret;
889}
890
Bill Pemberton4740f732012-11-19 13:26:01 -0500891static int twl4030_madc_remove(struct platform_device *pdev)
Keerthyf99c1d42011-03-01 19:12:26 +0530892{
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100893 struct iio_dev *iio_dev = platform_get_drvdata(pdev);
894 struct twl4030_madc_data *madc = iio_priv(iio_dev);
895
896 iio_device_unregister(iio_dev);
Keerthyf99c1d42011-03-01 19:12:26 +0530897
Keerthyf99c1d42011-03-01 19:12:26 +0530898 twl4030_madc_set_current_generator(madc, 0, 0);
899 twl4030_madc_set_power(madc, 0);
Keerthyf99c1d42011-03-01 19:12:26 +0530900
Adam YH Lee7cc97d72015-08-04 11:15:48 -0700901 regulator_disable(madc->usb3v1);
902
Keerthyf99c1d42011-03-01 19:12:26 +0530903 return 0;
904}
905
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100906#ifdef CONFIG_OF
907static const struct of_device_id twl_madc_of_match[] = {
908 { .compatible = "ti,twl4030-madc", },
909 { },
910};
911MODULE_DEVICE_TABLE(of, twl_madc_of_match);
912#endif
913
Keerthyf99c1d42011-03-01 19:12:26 +0530914static struct platform_driver twl4030_madc_driver = {
915 .probe = twl4030_madc_probe,
Arnd Bergmann03715412013-03-14 22:56:38 +0100916 .remove = twl4030_madc_remove,
Keerthyf99c1d42011-03-01 19:12:26 +0530917 .driver = {
918 .name = "twl4030_madc",
Sebastian Reichel2f39b702014-03-16 02:43:26 +0100919 .of_match_table = of_match_ptr(twl_madc_of_match),
Sebastian Reichel99be0242014-03-16 02:43:27 +0100920 },
Keerthyf99c1d42011-03-01 19:12:26 +0530921};
922
Mark Brown65349d62011-11-23 22:58:34 +0000923module_platform_driver(twl4030_madc_driver);
Keerthyf99c1d42011-03-01 19:12:26 +0530924
925MODULE_DESCRIPTION("TWL4030 ADC driver");
926MODULE_LICENSE("GPL");
927MODULE_AUTHOR("J Keerthy");
Axel Lin0ea3e832011-03-07 11:02:29 +0800928MODULE_ALIAS("platform:twl4030_madc");