Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/drivers/mfd/twl4030-madc.c

  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 module_platform_driver(twl4030_madc_driver);
811 
812 MODULE_DESCRIPTION("TWL4030 ADC driver");
813 MODULE_LICENSE("GPL");
814 MODULE_AUTHOR("J Keerthy");
815 MODULE_ALIAS("platform:twl4030_madc");
816 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us