~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/mfd/twl4030-madc.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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
 */
 
58
struct 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
 
 
66
static struct twl4030_madc_data *twl4030_madc;
 
67
 
 
68
struct twl4030_prescale_divider_ratios {
 
69
        s16 numerator;
 
70
        s16 denominator;
 
71
};
 
72
 
 
73
static const struct twl4030_prescale_divider_ratios
 
74
twl4030_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
 */
 
97
static int therm_tbl[] = {
 
98
30800,  29500,  28300,  27100,
 
99
26000,  24900,  23900,  22900,  22000,  21100,  20300,  19400,  18700,  17900,
 
100
17200,  16500,  15900,  15300,  14700,  14100,  13600,  13100,  12600,  12100,
 
101
11600,  11200,  10800,  10400,  10000,  9630,   9280,   8950,   8620,   8310,
 
102
8020,   7730,   7460,   7200,   6950,   6710,   6470,   6250,   6040,   5830,
 
103
5640,   5450,   5260,   5090,   4920,   4760,   4600,   4450,   4310,   4170,
 
104
4040,   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
 */
 
115
static
 
116
const 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
 */
 
142
static 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
 */
 
169
static 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 */
 
176
        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
 
177
                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
 
 
194
static int twl4030battery_current(int raw_volt)
 
195
{
 
196
        int ret;
 
197
        u8 val;
 
198
 
 
199
        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
 
200
                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
 
214
 * value is stored
 
215
 * Returns the number of successfully read channels.
 
216
 */
 
217
static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
 
218
                                      u8 reg_base, unsigned
 
219
                                                long channels, int *buf)
 
220
{
 
221
        int count = 0, count_req = 0, i;
 
222
        u8 reg;
 
223
 
 
224
        for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
 
225
                reg = reg_base + 2 * i;
 
226
                buf[i] = twl4030_madc_channel_raw_read(madc, reg);
 
227
                if (buf[i] < 0) {
 
228
                        dev_err(madc->dev,
 
229
                                "Unable to read register 0x%X\n", reg);
 
230
                        count_req++;
 
231
                        continue;
 
232
                }
 
233
                switch (i) {
 
234
                case 10:
 
235
                        buf[i] = twl4030battery_current(buf[i]);
 
236
                        if (buf[i] < 0) {
 
237
                                dev_err(madc->dev, "err reading current\n");
 
238
                                count_req++;
 
239
                        } else {
 
240
                                count++;
 
241
                                buf[i] = buf[i] - 750;
 
242
                        }
 
243
                        break;
 
244
                case 1:
 
245
                        buf[i] = twl4030battery_temperature(buf[i]);
 
246
                        if (buf[i] < 0) {
 
247
                                dev_err(madc->dev, "err reading temperature\n");
 
248
                                count_req++;
 
249
                        } else {
 
250
                                buf[i] -= 3;
 
251
                                count++;
 
252
                        }
 
253
                        break;
 
254
                default:
 
255
                        count++;
 
256
                        /* Analog Input (V) = conv_result * step_size / R
 
257
                         * conv_result = decimal value of 10-bit conversion
 
258
                         *               result
 
259
                         * step size = 1.5 / (2 ^ 10 -1)
 
260
                         * R = Prescaler ratio for input channels.
 
261
                         * Result given in mV hence multiplied by 1000.
 
262
                         */
 
263
                        buf[i] = (buf[i] * 3 * 1000 *
 
264
                                 twl4030_divider_ratios[i].denominator)
 
265
                                / (2 * 1023 *
 
266
                                twl4030_divider_ratios[i].numerator);
 
267
                }
 
268
        }
 
269
        if (count_req)
 
270
                dev_err(madc->dev, "%d channel conversion failed\n", count_req);
 
271
 
 
272
        return count;
 
273
}
 
274
 
 
275
/*
 
276
 * Enables irq.
 
277
 * @madc - pointer to twl4030_madc_data struct
 
278
 * @id - irq number to be enabled
 
279
 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
 
280
 * corresponding to RT, SW1, SW2 conversion requests.
 
281
 * If the i2c read fails it returns an error else returns 0.
 
282
 */
 
283
static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
 
284
{
 
285
        u8 val;
 
286
        int ret;
 
287
 
 
288
        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
 
289
        if (ret) {
 
290
                dev_err(madc->dev, "unable to read imr register 0x%X\n",
 
291
                        madc->imr);
 
292
                return ret;
 
293
        }
 
294
        val &= ~(1 << id);
 
295
        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
 
296
        if (ret) {
 
297
                dev_err(madc->dev,
 
298
                        "unable to write imr register 0x%X\n", madc->imr);
 
299
                return ret;
 
300
 
 
301
        }
 
302
 
 
303
        return 0;
 
304
}
 
305
 
 
306
/*
 
307
 * Disables irq.
 
308
 * @madc - pointer to twl4030_madc_data struct
 
309
 * @id - irq number to be disabled
 
310
 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
 
311
 * corresponding to RT, SW1, SW2 conversion requests.
 
312
 * Returns error if i2c read/write fails.
 
313
 */
 
314
static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
 
315
{
 
316
        u8 val;
 
317
        int ret;
 
318
 
 
319
        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
 
320
        if (ret) {
 
321
                dev_err(madc->dev, "unable to read imr register 0x%X\n",
 
322
                        madc->imr);
 
323
                return ret;
 
324
        }
 
325
        val |= (1 << id);
 
326
        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
 
327
        if (ret) {
 
328
                dev_err(madc->dev,
 
329
                        "unable to write imr register 0x%X\n", madc->imr);
 
330
                return ret;
 
331
        }
 
332
 
 
333
        return 0;
 
334
}
 
335
 
 
336
static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
 
337
{
 
338
        struct twl4030_madc_data *madc = _madc;
 
339
        const struct twl4030_madc_conversion_method *method;
 
340
        u8 isr_val, imr_val;
 
341
        int i, len, ret;
 
342
        struct twl4030_madc_request *r;
 
343
 
 
344
        mutex_lock(&madc->lock);
 
345
        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
 
346
        if (ret) {
 
347
                dev_err(madc->dev, "unable to read isr register 0x%X\n",
 
348
                        madc->isr);
 
349
                goto err_i2c;
 
350
        }
 
351
        ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
 
352
        if (ret) {
 
353
                dev_err(madc->dev, "unable to read imr register 0x%X\n",
 
354
                        madc->imr);
 
355
                goto err_i2c;
 
356
        }
 
357
        isr_val &= ~imr_val;
 
358
        for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
 
359
                if (!(isr_val & (1 << i)))
 
360
                        continue;
 
361
                ret = twl4030_madc_disable_irq(madc, i);
 
362
                if (ret < 0)
 
363
                        dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
 
364
                madc->requests[i].result_pending = 1;
 
365
        }
 
366
        for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
 
367
                r = &madc->requests[i];
 
368
                /* No pending results for this method, move to next one */
 
369
                if (!r->result_pending)
 
370
                        continue;
 
371
                method = &twl4030_conversion_methods[r->method];
 
372
                /* Read results */
 
373
                len = twl4030_madc_read_channels(madc, method->rbase,
 
374
                                                 r->channels, r->rbuf);
 
375
                /* Return results to caller */
 
376
                if (r->func_cb != NULL) {
 
377
                        r->func_cb(len, r->channels, r->rbuf);
 
378
                        r->func_cb = NULL;
 
379
                }
 
380
                /* Free request */
 
381
                r->result_pending = 0;
 
382
                r->active = 0;
 
383
        }
 
384
        mutex_unlock(&madc->lock);
 
385
 
 
386
        return IRQ_HANDLED;
 
387
 
 
388
err_i2c:
 
389
        /*
 
390
         * In case of error check whichever request is active
 
391
         * and service the same.
 
392
         */
 
393
        for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
 
394
                r = &madc->requests[i];
 
395
                if (r->active == 0)
 
396
                        continue;
 
397
                method = &twl4030_conversion_methods[r->method];
 
398
                /* Read results */
 
399
                len = twl4030_madc_read_channels(madc, method->rbase,
 
400
                                                 r->channels, r->rbuf);
 
401
                /* Return results to caller */
 
402
                if (r->func_cb != NULL) {
 
403
                        r->func_cb(len, r->channels, r->rbuf);
 
404
                        r->func_cb = NULL;
 
405
                }
 
406
                /* Free request */
 
407
                r->result_pending = 0;
 
408
                r->active = 0;
 
409
        }
 
410
        mutex_unlock(&madc->lock);
 
411
 
 
412
        return IRQ_HANDLED;
 
413
}
 
414
 
 
415
static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
 
416
                                struct twl4030_madc_request *req)
 
417
{
 
418
        struct twl4030_madc_request *p;
 
419
        int ret;
 
420
 
 
421
        p = &madc->requests[req->method];
 
422
        memcpy(p, req, sizeof(*req));
 
423
        ret = twl4030_madc_enable_irq(madc, req->method);
 
424
        if (ret < 0) {
 
425
                dev_err(madc->dev, "enable irq failed!!\n");
 
426
                return ret;
 
427
        }
 
428
 
 
429
        return 0;
 
430
}
 
431
 
 
432
/*
 
433
 * Function which enables the madc conversion
 
434
 * by writing to the control register.
 
435
 * @madc - pointer to twl4030_madc_data struct
 
436
 * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
 
437
 * corresponding to RT SW1 or SW2 conversion methods.
 
438
 * Returns 0 if succeeds else a negative error value
 
439
 */
 
440
static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
 
441
                                         int conv_method)
 
442
{
 
443
        const struct twl4030_madc_conversion_method *method;
 
444
        int ret = 0;
 
445
        method = &twl4030_conversion_methods[conv_method];
 
446
        switch (conv_method) {
 
447
        case TWL4030_MADC_SW1:
 
448
        case TWL4030_MADC_SW2:
 
449
                ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
 
450
                                       TWL4030_MADC_SW_START, method->ctrl);
 
451
                if (ret) {
 
452
                        dev_err(madc->dev,
 
453
                                "unable to write ctrl register 0x%X\n",
 
454
                                method->ctrl);
 
455
                        return ret;
 
456
                }
 
457
                break;
 
458
        default:
 
459
                break;
 
460
        }
 
461
 
 
462
        return 0;
 
463
}
 
464
 
 
465
/*
 
466
 * Function that waits for conversion to be ready
 
467
 * @madc - pointer to twl4030_madc_data struct
 
468
 * @timeout_ms - timeout value in milliseconds
 
469
 * @status_reg - ctrl register
 
470
 * returns 0 if succeeds else a negative error value
 
471
 */
 
472
static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
 
473
                                              unsigned int timeout_ms,
 
474
                                              u8 status_reg)
 
475
{
 
476
        unsigned long timeout;
 
477
        int ret;
 
478
 
 
479
        timeout = jiffies + msecs_to_jiffies(timeout_ms);
 
480
        do {
 
481
                u8 reg;
 
482
 
 
483
                ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
 
484
                if (ret) {
 
485
                        dev_err(madc->dev,
 
486
                                "unable to read status register 0x%X\n",
 
487
                                status_reg);
 
488
                        return ret;
 
489
                }
 
490
                if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
 
491
                        return 0;
 
492
                usleep_range(500, 2000);
 
493
        } while (!time_after(jiffies, timeout));
 
494
        dev_err(madc->dev, "conversion timeout!\n");
 
495
 
 
496
        return -EAGAIN;
 
497
}
 
498
 
 
499
/*
 
500
 * An exported function which can be called from other kernel drivers.
 
501
 * @req twl4030_madc_request structure
 
502
 * req->rbuf will be filled with read values of channels based on the
 
503
 * channel index. If a particular channel reading fails there will
 
504
 * be a negative error value in the corresponding array element.
 
505
 * returns 0 if succeeds else error value
 
506
 */
 
507
int twl4030_madc_conversion(struct twl4030_madc_request *req)
 
508
{
 
509
        const struct twl4030_madc_conversion_method *method;
 
510
        u8 ch_msb, ch_lsb;
 
511
        int ret;
 
512
 
 
513
        if (!req || !twl4030_madc)
 
514
                return -EINVAL;
 
515
 
 
516
        mutex_lock(&twl4030_madc->lock);
 
517
        if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
 
518
                ret = -EINVAL;
 
519
                goto out;
 
520
        }
 
521
        /* Do we have a conversion request ongoing */
 
522
        if (twl4030_madc->requests[req->method].active) {
 
523
                ret = -EBUSY;
 
524
                goto out;
 
525
        }
 
526
        ch_msb = (req->channels >> 8) & 0xff;
 
527
        ch_lsb = req->channels & 0xff;
 
528
        method = &twl4030_conversion_methods[req->method];
 
529
        /* Select channels to be converted */
 
530
        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
 
531
        if (ret) {
 
532
                dev_err(twl4030_madc->dev,
 
533
                        "unable to write sel register 0x%X\n", method->sel + 1);
 
534
                goto out;
 
535
        }
 
536
        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
 
537
        if (ret) {
 
538
                dev_err(twl4030_madc->dev,
 
539
                        "unable to write sel register 0x%X\n", method->sel + 1);
 
540
                goto out;
 
541
        }
 
542
        /* Select averaging for all channels if do_avg is set */
 
543
        if (req->do_avg) {
 
544
                ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
 
545
                                       ch_msb, method->avg + 1);
 
546
                if (ret) {
 
547
                        dev_err(twl4030_madc->dev,
 
548
                                "unable to write avg register 0x%X\n",
 
549
                                method->avg + 1);
 
550
                        goto out;
 
551
                }
 
552
                ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
 
553
                                       ch_lsb, method->avg);
 
554
                if (ret) {
 
555
                        dev_err(twl4030_madc->dev,
 
556
                                "unable to write sel reg 0x%X\n",
 
557
                                method->sel + 1);
 
558
                        goto out;
 
559
                }
 
560
        }
 
561
        if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
 
562
                ret = twl4030_madc_set_irq(twl4030_madc, req);
 
563
                if (ret < 0)
 
564
                        goto out;
 
565
                ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
 
566
                if (ret < 0)
 
567
                        goto out;
 
568
                twl4030_madc->requests[req->method].active = 1;
 
569
                ret = 0;
 
570
                goto out;
 
571
        }
 
572
        /* With RT method we should not be here anymore */
 
573
        if (req->method == TWL4030_MADC_RT) {
 
574
                ret = -EINVAL;
 
575
                goto out;
 
576
        }
 
577
        ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
 
578
        if (ret < 0)
 
579
                goto out;
 
580
        twl4030_madc->requests[req->method].active = 1;
 
581
        /* Wait until conversion is ready (ctrl register returns EOC) */
 
582
        ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
 
583
        if (ret) {
 
584
                twl4030_madc->requests[req->method].active = 0;
 
585
                goto out;
 
586
        }
 
587
        ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
 
588
                                         req->channels, req->rbuf);
 
589
        twl4030_madc->requests[req->method].active = 0;
 
590
 
 
591
out:
 
592
        mutex_unlock(&twl4030_madc->lock);
 
593
 
 
594
        return ret;
 
595
}
 
596
EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
 
597
 
 
598
/*
 
599
 * Return channel value
 
600
 * Or < 0 on failure.
 
601
 */
 
602
int twl4030_get_madc_conversion(int channel_no)
 
603
{
 
604
        struct twl4030_madc_request req;
 
605
        int temp = 0;
 
606
        int ret;
 
607
 
 
608
        req.channels = (1 << channel_no);
 
609
        req.method = TWL4030_MADC_SW2;
 
610
        req.active = 0;
 
611
        req.func_cb = NULL;
 
612
        ret = twl4030_madc_conversion(&req);
 
613
        if (ret < 0)
 
614
                return ret;
 
615
        if (req.rbuf[channel_no] > 0)
 
616
                temp = req.rbuf[channel_no];
 
617
 
 
618
        return temp;
 
619
}
 
620
EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
 
621
 
 
622
/*
 
623
 * Function to enable or disable bias current for
 
624
 * main battery type reading or temperature sensing
 
625
 * @madc - pointer to twl4030_madc_data struct
 
626
 * @chan - can be one of the two values
 
627
 * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
 
628
 * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
 
629
 * sensing
 
630
 * @on - enable or disable chan.
 
631
 */
 
632
static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
 
633
                                              int chan, int on)
 
634
{
 
635
        int ret;
 
636
        u8 regval;
 
637
 
 
638
        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
 
639
                              &regval, TWL4030_BCI_BCICTL1);
 
640
        if (ret) {
 
641
                dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
 
642
                        TWL4030_BCI_BCICTL1);
 
643
                return ret;
 
644
        }
 
645
        if (on)
 
646
                regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
 
647
        else
 
648
                regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
 
649
        ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
 
650
                               regval, TWL4030_BCI_BCICTL1);
 
651
        if (ret) {
 
652
                dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
 
653
                        TWL4030_BCI_BCICTL1);
 
654
                return ret;
 
655
        }
 
656
 
 
657
        return 0;
 
658
}
 
659
 
 
660
/*
 
661
 * Function that sets MADC software power on bit to enable MADC
 
662
 * @madc - pointer to twl4030_madc_data struct
 
663
 * @on - Enable or disable MADC software powen on bit.
 
664
 * returns error if i2c read/write fails else 0
 
665
 */
 
666
static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
 
667
{
 
668
        u8 regval;
 
669
        int ret;
 
670
 
 
671
        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
 
672
                              &regval, TWL4030_MADC_CTRL1);
 
673
        if (ret) {
 
674
                dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
 
675
                        TWL4030_MADC_CTRL1);
 
676
                return ret;
 
677
        }
 
678
        if (on)
 
679
                regval |= TWL4030_MADC_MADCON;
 
680
        else
 
681
                regval &= ~TWL4030_MADC_MADCON;
 
682
        ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
 
683
        if (ret) {
 
684
                dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
 
685
                        TWL4030_MADC_CTRL1);
 
686
                return ret;
 
687
        }
 
688
 
 
689
        return 0;
 
690
}
 
691
 
 
692
/*
 
693
 * Initialize MADC and request for threaded irq
 
694
 */
 
695
static int __devinit twl4030_madc_probe(struct platform_device *pdev)
 
696
{
 
697
        struct twl4030_madc_data *madc;
 
698
        struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
 
699
        int ret;
 
700
        u8 regval;
 
701
 
 
702
        if (!pdata) {
 
703
                dev_err(&pdev->dev, "platform_data not available\n");
 
704
                return -EINVAL;
 
705
        }
 
706
        madc = kzalloc(sizeof(*madc), GFP_KERNEL);
 
707
        if (!madc)
 
708
                return -ENOMEM;
 
709
 
 
710
        madc->dev = &pdev->dev;
 
711
 
 
712
        /*
 
713
         * Phoenix provides 2 interrupt lines. The first one is connected to
 
714
         * the OMAP. The other one can be connected to the other processor such
 
715
         * as modem. Hence two separate ISR and IMR registers.
 
716
         */
 
717
        madc->imr = (pdata->irq_line == 1) ?
 
718
            TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
 
719
        madc->isr = (pdata->irq_line == 1) ?
 
720
            TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
 
721
        ret = twl4030_madc_set_power(madc, 1);
 
722
        if (ret < 0)
 
723
                goto err_power;
 
724
        ret = twl4030_madc_set_current_generator(madc, 0, 1);
 
725
        if (ret < 0)
 
726
                goto err_current_generator;
 
727
 
 
728
        ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
 
729
                              &regval, TWL4030_BCI_BCICTL1);
 
730
        if (ret) {
 
731
                dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
 
732
                        TWL4030_BCI_BCICTL1);
 
733
                goto err_i2c;
 
734
        }
 
735
        regval |= TWL4030_BCI_MESBAT;
 
736
        ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
 
737
                               regval, TWL4030_BCI_BCICTL1);
 
738
        if (ret) {
 
739
                dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
 
740
                        TWL4030_BCI_BCICTL1);
 
741
                goto err_i2c;
 
742
        }
 
743
 
 
744
        /* Check that MADC clock is on */
 
745
        ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
 
746
        if (ret) {
 
747
                dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
 
748
                                TWL4030_REG_GPBR1);
 
749
                goto err_i2c;
 
750
        }
 
751
 
 
752
        /* If MADC clk is not on, turn it on */
 
753
        if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
 
754
                dev_info(&pdev->dev, "clk disabled, enabling\n");
 
755
                regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
 
756
                ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
 
757
                                       TWL4030_REG_GPBR1);
 
758
                if (ret) {
 
759
                        dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
 
760
                                        TWL4030_REG_GPBR1);
 
761
                        goto err_i2c;
 
762
                }
 
763
        }
 
764
 
 
765
        platform_set_drvdata(pdev, madc);
 
766
        mutex_init(&madc->lock);
 
767
        ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
 
768
                                   twl4030_madc_threaded_irq_handler,
 
769
                                   IRQF_TRIGGER_RISING, "twl4030_madc", madc);
 
770
        if (ret) {
 
771
                dev_dbg(&pdev->dev, "could not request irq\n");
 
772
                goto err_irq;
 
773
        }
 
774
        twl4030_madc = madc;
 
775
        return 0;
 
776
err_irq:
 
777
        platform_set_drvdata(pdev, NULL);
 
778
err_i2c:
 
779
        twl4030_madc_set_current_generator(madc, 0, 0);
 
780
err_current_generator:
 
781
        twl4030_madc_set_power(madc, 0);
 
782
err_power:
 
783
        kfree(madc);
 
784
 
 
785
        return ret;
 
786
}
 
787
 
 
788
static int __devexit twl4030_madc_remove(struct platform_device *pdev)
 
789
{
 
790
        struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
 
791
 
 
792
        free_irq(platform_get_irq(pdev, 0), madc);
 
793
        platform_set_drvdata(pdev, NULL);
 
794
        twl4030_madc_set_current_generator(madc, 0, 0);
 
795
        twl4030_madc_set_power(madc, 0);
 
796
        kfree(madc);
 
797
 
 
798
        return 0;
 
799
}
 
800
 
 
801
static struct platform_driver twl4030_madc_driver = {
 
802
        .probe = twl4030_madc_probe,
 
803
        .remove = __exit_p(twl4030_madc_remove),
 
804
        .driver = {
 
805
                   .name = "twl4030_madc",
 
806
                   .owner = THIS_MODULE,
 
807
                   },
 
808
};
 
809
 
 
810
static int __init twl4030_madc_init(void)
 
811
{
 
812
        return platform_driver_register(&twl4030_madc_driver);
 
813
}
 
814
 
 
815
module_init(twl4030_madc_init);
 
816
 
 
817
static void __exit twl4030_madc_exit(void)
 
818
{
 
819
        platform_driver_unregister(&twl4030_madc_driver);
 
820
}
 
821
 
 
822
module_exit(twl4030_madc_exit);
 
823
 
 
824
MODULE_DESCRIPTION("TWL4030 ADC driver");
 
825
MODULE_LICENSE("GPL");
 
826
MODULE_AUTHOR("J Keerthy");
 
827
MODULE_ALIAS("platform:twl4030_madc");