1022 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * TWL6030 GPADC module driver4 *5 * Copyright (C) 2009-2013 Texas Instruments Inc.6 * Nishant Kamat <nskamat@ti.com>7 * Balaji T K <balajitk@ti.com>8 * Graeme Gregory <gg@slimlogic.co.uk>9 * Girish S Ghongdemath <girishsg@ti.com>10 * Ambresh K <ambresh@ti.com>11 * Oleksandr Kozaruk <oleksandr.kozaruk@ti.com12 *13 * Based on twl4030-madc.c14 * Copyright (C) 2008 Nokia Corporation15 * Mikko Ylinen <mikko.k.ylinen@nokia.com>16 */17#include <linux/interrupt.h>18#include <linux/kernel.h>19#include <linux/mod_devicetable.h>20#include <linux/module.h>21#include <linux/platform_device.h>22#include <linux/property.h>23#include <linux/mfd/twl.h>24#include <linux/iio/iio.h>25#include <linux/iio/sysfs.h>26 27#define DRIVER_NAME "twl6030_gpadc"28 29/*30 * twl6030 per TRM has 17 channels, and twl6032 has 19 channels31 * 2 test network channels are not used,32 * 2 die temperature channels are not used either, as it is not33 * defined how to convert ADC value to temperature34 */35#define TWL6030_GPADC_USED_CHANNELS 1336#define TWL6030_GPADC_MAX_CHANNELS 1537#define TWL6032_GPADC_USED_CHANNELS 1538#define TWL6032_GPADC_MAX_CHANNELS 1939#define TWL6030_GPADC_NUM_TRIM_REGS 1640 41#define TWL6030_GPADC_CTRL_P1 0x0542 43#define TWL6032_GPADC_GPSELECT_ISB 0x0744#define TWL6032_GPADC_CTRL_P1 0x0845 46#define TWL6032_GPADC_GPCH0_LSB 0x0d47#define TWL6032_GPADC_GPCH0_MSB 0x0e48 49#define TWL6030_GPADC_CTRL_P1_SP1 BIT(3)50 51#define TWL6030_GPADC_GPCH0_LSB (0x29)52 53#define TWL6030_GPADC_RT_SW1_EOC_MASK BIT(5)54 55#define TWL6030_GPADC_TRIM1 0xCD56 57#define TWL6030_REG_TOGGLE1 0x9058#define TWL6030_GPADCS BIT(1)59#define TWL6030_GPADCR BIT(0)60 61#define USB_VBUS_CTRL_SET 0x0462#define USB_ID_CTRL_SET 0x0663 64#define TWL6030_MISC1 0xE465#define VBUS_MEAS 0x0166#define ID_MEAS 0x0167 68#define VAC_MEAS 0x0469#define VBAT_MEAS 0x0270#define BB_MEAS 0x0171 72 73/**74 * struct twl6030_chnl_calib - channel calibration75 * @gain: slope coefficient for ideal curve76 * @gain_error: gain error77 * @offset_error: offset of the real curve78 */79struct twl6030_chnl_calib {80 s32 gain;81 s32 gain_error;82 s32 offset_error;83};84 85/**86 * struct twl6030_ideal_code - GPADC calibration parameters87 * GPADC is calibrated in two points: close to the beginning and88 * to the and of the measurable input range89 *90 * @channel: channel number91 * @code1: ideal code for the input at the beginning92 * @code2: ideal code for at the end of the range93 * @volt1: voltage input at the beginning(low voltage)94 * @volt2: voltage input at the end(high voltage)95 */96struct twl6030_ideal_code {97 int channel;98 u16 code1;99 u16 code2;100 u16 volt1;101 u16 volt2;102};103 104struct twl6030_gpadc_data;105 106/**107 * struct twl6030_gpadc_platform_data - platform specific data108 * @nchannels: number of GPADC channels109 * @iio_channels: iio channels110 * @ideal: pointer to calibration parameters111 * @start_conversion: pointer to ADC start conversion function112 * @channel_to_reg: pointer to ADC function to convert channel to113 * register address for reading conversion result114 * @calibrate: pointer to calibration function115 */116struct twl6030_gpadc_platform_data {117 const int nchannels;118 const struct iio_chan_spec *iio_channels;119 const struct twl6030_ideal_code *ideal;120 int (*start_conversion)(int channel);121 u8 (*channel_to_reg)(int channel);122 int (*calibrate)(struct twl6030_gpadc_data *gpadc);123};124 125/**126 * struct twl6030_gpadc_data - GPADC data127 * @dev: device pointer128 * @lock: mutual exclusion lock for the structure129 * @irq_complete: completion to signal end of conversion130 * @twl6030_cal_tbl: pointer to calibration data for each131 * channel with gain error and offset132 * @pdata: pointer to device specific data133 */134struct twl6030_gpadc_data {135 struct device *dev;136 struct mutex lock;137 struct completion irq_complete;138 struct twl6030_chnl_calib *twl6030_cal_tbl;139 const struct twl6030_gpadc_platform_data *pdata;140};141 142/*143 * channels 11, 12, 13, 15 and 16 have no calibration data144 * calibration offset is same for channels 1, 3, 4, 5145 *146 * The data is taken from GPADC_TRIM registers description.147 * GPADC_TRIM registers keep difference between the code measured148 * at volt1 and volt2 input voltages and corresponding code1 and code2149 */150static const struct twl6030_ideal_code151 twl6030_ideal[TWL6030_GPADC_USED_CHANNELS] = {152 [0] = { /* ch 0, external, battery type, resistor value */153 .channel = 0,154 .code1 = 116,155 .code2 = 745,156 .volt1 = 141,157 .volt2 = 910,158 },159 [1] = { /* ch 1, external, battery temperature, NTC resistor value */160 .channel = 1,161 .code1 = 82,162 .code2 = 900,163 .volt1 = 100,164 .volt2 = 1100,165 },166 [2] = { /* ch 2, external, audio accessory/general purpose */167 .channel = 2,168 .code1 = 55,169 .code2 = 818,170 .volt1 = 101,171 .volt2 = 1499,172 },173 [3] = { /* ch 3, external, general purpose */174 .channel = 3,175 .code1 = 82,176 .code2 = 900,177 .volt1 = 100,178 .volt2 = 1100,179 },180 [4] = { /* ch 4, external, temperature measurement/general purpose */181 .channel = 4,182 .code1 = 82,183 .code2 = 900,184 .volt1 = 100,185 .volt2 = 1100,186 },187 [5] = { /* ch 5, external, general purpose */188 .channel = 5,189 .code1 = 82,190 .code2 = 900,191 .volt1 = 100,192 .volt2 = 1100,193 },194 [6] = { /* ch 6, external, general purpose */195 .channel = 6,196 .code1 = 82,197 .code2 = 900,198 .volt1 = 100,199 .volt2 = 1100,200 },201 [7] = { /* ch 7, internal, main battery */202 .channel = 7,203 .code1 = 614,204 .code2 = 941,205 .volt1 = 3001,206 .volt2 = 4599,207 },208 [8] = { /* ch 8, internal, backup battery */209 .channel = 8,210 .code1 = 82,211 .code2 = 688,212 .volt1 = 501,213 .volt2 = 4203,214 },215 [9] = { /* ch 9, internal, external charger input */216 .channel = 9,217 .code1 = 182,218 .code2 = 818,219 .volt1 = 2001,220 .volt2 = 8996,221 },222 [10] = { /* ch 10, internal, VBUS */223 .channel = 10,224 .code1 = 149,225 .code2 = 818,226 .volt1 = 1001,227 .volt2 = 5497,228 },229 [11] = { /* ch 11, internal, VBUS charging current */230 .channel = 11,231 },232 /* ch 12, internal, Die temperature */233 /* ch 13, internal, Die temperature */234 [12] = { /* ch 14, internal, USB ID line */235 .channel = 14,236 .code1 = 48,237 .code2 = 714,238 .volt1 = 323,239 .volt2 = 4800,240 },241};242 243static const struct twl6030_ideal_code244 twl6032_ideal[TWL6032_GPADC_USED_CHANNELS] = {245 [0] = { /* ch 0, external, battery type, resistor value */246 .channel = 0,247 .code1 = 1441,248 .code2 = 3276,249 .volt1 = 440,250 .volt2 = 1000,251 },252 [1] = { /* ch 1, external, battery temperature, NTC resistor value */253 .channel = 1,254 .code1 = 1441,255 .code2 = 3276,256 .volt1 = 440,257 .volt2 = 1000,258 },259 [2] = { /* ch 2, external, audio accessory/general purpose */260 .channel = 2,261 .code1 = 1441,262 .code2 = 3276,263 .volt1 = 660,264 .volt2 = 1500,265 },266 [3] = { /* ch 3, external, temperature with external diode/general267 purpose */268 .channel = 3,269 .code1 = 1441,270 .code2 = 3276,271 .volt1 = 440,272 .volt2 = 1000,273 },274 [4] = { /* ch 4, external, temperature measurement/general purpose */275 .channel = 4,276 .code1 = 1441,277 .code2 = 3276,278 .volt1 = 440,279 .volt2 = 1000,280 },281 [5] = { /* ch 5, external, general purpose */282 .channel = 5,283 .code1 = 1441,284 .code2 = 3276,285 .volt1 = 440,286 .volt2 = 1000,287 },288 [6] = { /* ch 6, external, general purpose */289 .channel = 6,290 .code1 = 1441,291 .code2 = 3276,292 .volt1 = 440,293 .volt2 = 1000,294 },295 [7] = { /* ch7, internal, system supply */296 .channel = 7,297 .code1 = 1441,298 .code2 = 3276,299 .volt1 = 2200,300 .volt2 = 5000,301 },302 [8] = { /* ch8, internal, backup battery */303 .channel = 8,304 .code1 = 1441,305 .code2 = 3276,306 .volt1 = 2200,307 .volt2 = 5000,308 },309 [9] = { /* ch 9, internal, external charger input */310 .channel = 9,311 .code1 = 1441,312 .code2 = 3276,313 .volt1 = 3960,314 .volt2 = 9000,315 },316 [10] = { /* ch10, internal, VBUS */317 .channel = 10,318 .code1 = 150,319 .code2 = 751,320 .volt1 = 1000,321 .volt2 = 5000,322 },323 [11] = { /* ch 11, internal, VBUS DC-DC output current */324 .channel = 11,325 .code1 = 1441,326 .code2 = 3276,327 .volt1 = 660,328 .volt2 = 1500,329 },330 /* ch 12, internal, Die temperature */331 /* ch 13, internal, Die temperature */332 [12] = { /* ch 14, internal, USB ID line */333 .channel = 14,334 .code1 = 1441,335 .code2 = 3276,336 .volt1 = 2420,337 .volt2 = 5500,338 },339 /* ch 15, internal, test network */340 /* ch 16, internal, test network */341 [13] = { /* ch 17, internal, battery charging current */342 .channel = 17,343 },344 [14] = { /* ch 18, internal, battery voltage */345 .channel = 18,346 .code1 = 1441,347 .code2 = 3276,348 .volt1 = 2200,349 .volt2 = 5000,350 },351};352 353static inline int twl6030_gpadc_write(u8 reg, u8 val)354{355 return twl_i2c_write_u8(TWL6030_MODULE_GPADC, val, reg);356}357 358static inline int twl6030_gpadc_read(u8 reg, u8 *val)359{360 361 return twl_i2c_read(TWL6030_MODULE_GPADC, val, reg, 2);362}363 364static int twl6030_gpadc_enable_irq(u8 mask)365{366 int ret;367 368 ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_LINE_B);369 if (ret < 0)370 return ret;371 372 ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_STS_B);373 374 return ret;375}376 377static void twl6030_gpadc_disable_irq(u8 mask)378{379 twl6030_interrupt_mask(mask, REG_INT_MSK_LINE_B);380 twl6030_interrupt_mask(mask, REG_INT_MSK_STS_B);381}382 383static irqreturn_t twl6030_gpadc_irq_handler(int irq, void *indio_dev)384{385 struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);386 387 complete(&gpadc->irq_complete);388 389 return IRQ_HANDLED;390}391 392static int twl6030_start_conversion(int channel)393{394 return twl6030_gpadc_write(TWL6030_GPADC_CTRL_P1,395 TWL6030_GPADC_CTRL_P1_SP1);396}397 398static int twl6032_start_conversion(int channel)399{400 int ret;401 402 ret = twl6030_gpadc_write(TWL6032_GPADC_GPSELECT_ISB, channel);403 if (ret)404 return ret;405 406 return twl6030_gpadc_write(TWL6032_GPADC_CTRL_P1,407 TWL6030_GPADC_CTRL_P1_SP1);408}409 410static u8 twl6030_channel_to_reg(int channel)411{412 return TWL6030_GPADC_GPCH0_LSB + 2 * channel;413}414 415static u8 twl6032_channel_to_reg(int channel)416{417 /*418 * for any prior chosen channel, when the conversion is ready419 * the result is avalable in GPCH0_LSB, GPCH0_MSB.420 */421 422 return TWL6032_GPADC_GPCH0_LSB;423}424 425static int twl6030_gpadc_lookup(const struct twl6030_ideal_code *ideal,426 int channel, int size)427{428 int i;429 430 for (i = 0; i < size; i++)431 if (ideal[i].channel == channel)432 break;433 434 return i;435}436 437static int twl6030_channel_calibrated(const struct twl6030_gpadc_platform_data438 *pdata, int channel)439{440 const struct twl6030_ideal_code *ideal = pdata->ideal;441 int i;442 443 i = twl6030_gpadc_lookup(ideal, channel, pdata->nchannels);444 /* not calibrated channels have 0 in all structure members */445 return pdata->ideal[i].code2;446}447 448static int twl6030_gpadc_make_correction(struct twl6030_gpadc_data *gpadc,449 int channel, int raw_code)450{451 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;452 int corrected_code;453 int i;454 455 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);456 corrected_code = ((raw_code * 1000) -457 gpadc->twl6030_cal_tbl[i].offset_error) /458 gpadc->twl6030_cal_tbl[i].gain_error;459 460 return corrected_code;461}462 463static int twl6030_gpadc_get_raw(struct twl6030_gpadc_data *gpadc,464 int channel, int *res)465{466 u8 reg = gpadc->pdata->channel_to_reg(channel);467 __le16 val;468 int raw_code;469 int ret;470 471 ret = twl6030_gpadc_read(reg, (u8 *)&val);472 if (ret) {473 dev_dbg(gpadc->dev, "unable to read register 0x%X\n", reg);474 return ret;475 }476 477 raw_code = le16_to_cpu(val);478 dev_dbg(gpadc->dev, "GPADC raw code: %d", raw_code);479 480 if (twl6030_channel_calibrated(gpadc->pdata, channel))481 *res = twl6030_gpadc_make_correction(gpadc, channel, raw_code);482 else483 *res = raw_code;484 485 return ret;486}487 488static int twl6030_gpadc_get_processed(struct twl6030_gpadc_data *gpadc,489 int channel, int *val)490{491 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;492 int corrected_code;493 int channel_value;494 int i;495 int ret;496 497 ret = twl6030_gpadc_get_raw(gpadc, channel, &corrected_code);498 if (ret)499 return ret;500 501 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);502 channel_value = corrected_code *503 gpadc->twl6030_cal_tbl[i].gain;504 505 /* Shift back into mV range */506 channel_value /= 1000;507 508 dev_dbg(gpadc->dev, "GPADC corrected code: %d", corrected_code);509 dev_dbg(gpadc->dev, "GPADC value: %d", channel_value);510 511 *val = channel_value;512 513 return ret;514}515 516static int twl6030_gpadc_read_raw(struct iio_dev *indio_dev,517 const struct iio_chan_spec *chan,518 int *val, int *val2, long mask)519{520 struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);521 int ret;522 long time_left;523 524 mutex_lock(&gpadc->lock);525 526 ret = gpadc->pdata->start_conversion(chan->channel);527 if (ret) {528 dev_err(gpadc->dev, "failed to start conversion\n");529 goto err;530 }531 /* wait for conversion to complete */532 time_left = wait_for_completion_interruptible_timeout(533 &gpadc->irq_complete, msecs_to_jiffies(5000));534 if (time_left == 0) {535 ret = -ETIMEDOUT;536 goto err;537 } else if (time_left < 0) {538 ret = -EINTR;539 goto err;540 }541 542 switch (mask) {543 case IIO_CHAN_INFO_RAW:544 ret = twl6030_gpadc_get_raw(gpadc, chan->channel, val);545 ret = ret ? -EIO : IIO_VAL_INT;546 break;547 548 case IIO_CHAN_INFO_PROCESSED:549 ret = twl6030_gpadc_get_processed(gpadc, chan->channel, val);550 ret = ret ? -EIO : IIO_VAL_INT;551 break;552 553 default:554 break;555 }556err:557 mutex_unlock(&gpadc->lock);558 559 return ret;560}561 562/*563 * The GPADC channels are calibrated using a two point calibration method.564 * The channels measured with two known values: volt1 and volt2, and565 * ideal corresponding output codes are known: code1, code2.566 * The difference(d1, d2) between ideal and measured codes stored in trim567 * registers.568 * The goal is to find offset and gain of the real curve for each calibrated569 * channel.570 * gain: k = 1 + ((d2 - d1) / (x2 - x1))571 * offset: b = d1 + (k - 1) * x1572 */573static void twl6030_calibrate_channel(struct twl6030_gpadc_data *gpadc,574 int channel, int d1, int d2)575{576 int b, k, gain, x1, x2, i;577 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;578 579 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);580 581 /* Gain */582 gain = ((ideal[i].volt2 - ideal[i].volt1) * 1000) /583 (ideal[i].code2 - ideal[i].code1);584 585 x1 = ideal[i].code1;586 x2 = ideal[i].code2;587 588 /* k - real curve gain */589 k = 1000 + (((d2 - d1) * 1000) / (x2 - x1));590 591 /* b - offset of the real curve gain */592 b = (d1 * 1000) - (k - 1000) * x1;593 594 gpadc->twl6030_cal_tbl[i].gain = gain;595 gpadc->twl6030_cal_tbl[i].gain_error = k;596 gpadc->twl6030_cal_tbl[i].offset_error = b;597 598 dev_dbg(gpadc->dev, "GPADC d1 for Chn: %d = %d\n", channel, d1);599 dev_dbg(gpadc->dev, "GPADC d2 for Chn: %d = %d\n", channel, d2);600 dev_dbg(gpadc->dev, "GPADC x1 for Chn: %d = %d\n", channel, x1);601 dev_dbg(gpadc->dev, "GPADC x2 for Chn: %d = %d\n", channel, x2);602 dev_dbg(gpadc->dev, "GPADC Gain for Chn: %d = %d\n", channel, gain);603 dev_dbg(gpadc->dev, "GPADC k for Chn: %d = %d\n", channel, k);604 dev_dbg(gpadc->dev, "GPADC b for Chn: %d = %d\n", channel, b);605}606 607static inline int twl6030_gpadc_get_trim_offset(s8 d)608{609 /*610 * XXX NOTE!611 * bit 0 - sign, bit 7 - reserved, 6..1 - trim value612 * though, the documentation states that trim value613 * is absolute value, the correct conversion results are614 * obtained if the value is interpreted as 2's complement.615 */616 __u32 temp = ((d & 0x7f) >> 1) | ((d & 1) << 6);617 618 return sign_extend32(temp, 6);619}620 621static int twl6030_calibration(struct twl6030_gpadc_data *gpadc)622{623 int ret;624 int chn;625 u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];626 s8 d1, d2;627 628 /*629 * for calibration two measurements have been performed at630 * factory, for some channels, during the production test and631 * have been stored in registers. This two stored values are632 * used to correct the measurements. The values represent633 * offsets for the given input from the output on ideal curve.634 */635 ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,636 TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);637 if (ret < 0) {638 dev_err(gpadc->dev, "calibration failed\n");639 return ret;640 }641 642 for (chn = 0; chn < TWL6030_GPADC_MAX_CHANNELS; chn++) {643 644 switch (chn) {645 case 0:646 d1 = trim_regs[0];647 d2 = trim_regs[1];648 break;649 case 1:650 case 3:651 case 4:652 case 5:653 case 6:654 d1 = trim_regs[4];655 d2 = trim_regs[5];656 break;657 case 2:658 d1 = trim_regs[12];659 d2 = trim_regs[13];660 break;661 case 7:662 d1 = trim_regs[6];663 d2 = trim_regs[7];664 break;665 case 8:666 d1 = trim_regs[2];667 d2 = trim_regs[3];668 break;669 case 9:670 d1 = trim_regs[8];671 d2 = trim_regs[9];672 break;673 case 10:674 d1 = trim_regs[10];675 d2 = trim_regs[11];676 break;677 case 14:678 d1 = trim_regs[14];679 d2 = trim_regs[15];680 break;681 default:682 continue;683 }684 685 d1 = twl6030_gpadc_get_trim_offset(d1);686 d2 = twl6030_gpadc_get_trim_offset(d2);687 688 twl6030_calibrate_channel(gpadc, chn, d1, d2);689 }690 691 return 0;692}693 694static int twl6032_get_trim_value(u8 *trim_regs, unsigned int reg0,695 unsigned int reg1, unsigned int mask0, unsigned int mask1,696 unsigned int shift0)697{698 int val;699 700 val = (trim_regs[reg0] & mask0) << shift0;701 val |= (trim_regs[reg1] & mask1) >> 1;702 if (trim_regs[reg1] & 0x01)703 val = -val;704 705 return val;706}707 708static int twl6032_calibration(struct twl6030_gpadc_data *gpadc)709{710 int chn, d1 = 0, d2 = 0, temp;711 u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];712 int ret;713 714 ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,715 TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);716 if (ret < 0) {717 dev_err(gpadc->dev, "calibration failed\n");718 return ret;719 }720 721 /*722 * Loop to calculate the value needed for returning voltages from723 * GPADC not values.724 *725 * gain is calculated to 3 decimal places fixed point.726 */727 for (chn = 0; chn < TWL6032_GPADC_MAX_CHANNELS; chn++) {728 729 switch (chn) {730 case 0:731 case 1:732 case 2:733 case 3:734 case 4:735 case 5:736 case 6:737 case 11:738 case 14:739 d1 = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,740 0x06, 2);741 d2 = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,742 0x06, 2);743 break;744 case 8:745 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,746 0x06, 2);747 d1 = temp + twl6032_get_trim_value(trim_regs, 7, 6,748 0x18, 0x1E, 1);749 750 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3F,751 0x06, 2);752 d2 = temp + twl6032_get_trim_value(trim_regs, 9, 7,753 0x1F, 0x06, 2);754 break;755 case 9:756 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,757 0x06, 2);758 d1 = temp + twl6032_get_trim_value(trim_regs, 13, 11,759 0x18, 0x1E, 1);760 761 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,762 0x06, 2);763 d2 = temp + twl6032_get_trim_value(trim_regs, 15, 13,764 0x1F, 0x06, 1);765 break;766 case 10:767 d1 = twl6032_get_trim_value(trim_regs, 10, 8, 0x0f,768 0x0E, 3);769 d2 = twl6032_get_trim_value(trim_regs, 14, 12, 0x0f,770 0x0E, 3);771 break;772 case 7:773 case 18:774 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,775 0x06, 2);776 777 d1 = (trim_regs[4] & 0x7E) >> 1;778 if (trim_regs[4] & 0x01)779 d1 = -d1;780 d1 += temp;781 782 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,783 0x06, 2);784 785 d2 = (trim_regs[5] & 0xFE) >> 1;786 if (trim_regs[5] & 0x01)787 d2 = -d2;788 789 d2 += temp;790 break;791 default:792 /* No data for other channels */793 continue;794 }795 796 twl6030_calibrate_channel(gpadc, chn, d1, d2);797 }798 799 return 0;800}801 802#define TWL6030_GPADC_CHAN(chn, _type, chan_info) { \803 .type = _type, \804 .channel = chn, \805 .info_mask_separate = BIT(chan_info), \806 .indexed = 1, \807}808 809static const struct iio_chan_spec twl6030_gpadc_iio_channels[] = {810 TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),811 TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),812 TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),813 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),814 TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),815 TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),816 TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),817 TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),818 TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),819 TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),820 TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),821 TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),822 TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),823};824 825static const struct iio_chan_spec twl6032_gpadc_iio_channels[] = {826 TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),827 TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),828 TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),829 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),830 TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),831 TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),832 TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),833 TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),834 TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),835 TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),836 TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),837 TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),838 TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),839 TWL6030_GPADC_CHAN(17, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),840 TWL6030_GPADC_CHAN(18, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),841};842 843static const struct iio_info twl6030_gpadc_iio_info = {844 .read_raw = &twl6030_gpadc_read_raw,845};846 847static const struct twl6030_gpadc_platform_data twl6030_pdata = {848 .iio_channels = twl6030_gpadc_iio_channels,849 .nchannels = TWL6030_GPADC_USED_CHANNELS,850 .ideal = twl6030_ideal,851 .start_conversion = twl6030_start_conversion,852 .channel_to_reg = twl6030_channel_to_reg,853 .calibrate = twl6030_calibration,854};855 856static const struct twl6030_gpadc_platform_data twl6032_pdata = {857 .iio_channels = twl6032_gpadc_iio_channels,858 .nchannels = TWL6032_GPADC_USED_CHANNELS,859 .ideal = twl6032_ideal,860 .start_conversion = twl6032_start_conversion,861 .channel_to_reg = twl6032_channel_to_reg,862 .calibrate = twl6032_calibration,863};864 865static const struct of_device_id of_twl6030_match_tbl[] = {866 {867 .compatible = "ti,twl6030-gpadc",868 .data = &twl6030_pdata,869 },870 {871 .compatible = "ti,twl6032-gpadc",872 .data = &twl6032_pdata,873 },874 { /* end */ }875};876MODULE_DEVICE_TABLE(of, of_twl6030_match_tbl);877 878static int twl6030_gpadc_probe(struct platform_device *pdev)879{880 struct device *dev = &pdev->dev;881 struct twl6030_gpadc_data *gpadc;882 const struct twl6030_gpadc_platform_data *pdata;883 struct iio_dev *indio_dev;884 int irq;885 int ret;886 887 pdata = device_get_match_data(&pdev->dev);888 if (!pdata)889 return -EINVAL;890 891 indio_dev = devm_iio_device_alloc(dev, sizeof(*gpadc));892 if (!indio_dev)893 return -ENOMEM;894 895 gpadc = iio_priv(indio_dev);896 897 gpadc->twl6030_cal_tbl = devm_kcalloc(dev,898 pdata->nchannels,899 sizeof(*gpadc->twl6030_cal_tbl),900 GFP_KERNEL);901 if (!gpadc->twl6030_cal_tbl)902 return -ENOMEM;903 904 gpadc->dev = dev;905 gpadc->pdata = pdata;906 907 platform_set_drvdata(pdev, indio_dev);908 mutex_init(&gpadc->lock);909 init_completion(&gpadc->irq_complete);910 911 ret = pdata->calibrate(gpadc);912 if (ret < 0) {913 dev_err(dev, "failed to read calibration registers\n");914 return ret;915 }916 917 irq = platform_get_irq(pdev, 0);918 if (irq < 0)919 return irq;920 921 ret = devm_request_threaded_irq(dev, irq, NULL,922 twl6030_gpadc_irq_handler,923 IRQF_ONESHOT, "twl6030_gpadc", indio_dev);924 if (ret)925 return ret;926 927 ret = twl6030_gpadc_enable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);928 if (ret < 0) {929 dev_err(dev, "failed to enable GPADC interrupt\n");930 return ret;931 }932 933 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,934 TWL6030_REG_TOGGLE1);935 if (ret < 0) {936 dev_err(dev, "failed to enable GPADC module\n");937 return ret;938 }939 940 ret = twl_i2c_write_u8(TWL_MODULE_USB, VBUS_MEAS, USB_VBUS_CTRL_SET);941 if (ret < 0) {942 dev_err(dev, "failed to wire up inputs\n");943 return ret;944 }945 946 ret = twl_i2c_write_u8(TWL_MODULE_USB, ID_MEAS, USB_ID_CTRL_SET);947 if (ret < 0) {948 dev_err(dev, "failed to wire up inputs\n");949 return ret;950 }951 952 ret = twl_i2c_write_u8(TWL6030_MODULE_ID0,953 VBAT_MEAS | BB_MEAS | VAC_MEAS,954 TWL6030_MISC1);955 if (ret < 0) {956 dev_err(dev, "failed to wire up inputs\n");957 return ret;958 }959 960 indio_dev->name = DRIVER_NAME;961 indio_dev->info = &twl6030_gpadc_iio_info;962 indio_dev->modes = INDIO_DIRECT_MODE;963 indio_dev->channels = pdata->iio_channels;964 indio_dev->num_channels = pdata->nchannels;965 966 return iio_device_register(indio_dev);967}968 969static void twl6030_gpadc_remove(struct platform_device *pdev)970{971 struct iio_dev *indio_dev = platform_get_drvdata(pdev);972 973 twl6030_gpadc_disable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);974 iio_device_unregister(indio_dev);975}976 977static int twl6030_gpadc_suspend(struct device *pdev)978{979 int ret;980 981 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCR,982 TWL6030_REG_TOGGLE1);983 if (ret)984 dev_err(pdev, "error resetting GPADC (%d)!\n", ret);985 986 return 0;987};988 989static int twl6030_gpadc_resume(struct device *pdev)990{991 int ret;992 993 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,994 TWL6030_REG_TOGGLE1);995 if (ret)996 dev_err(pdev, "error setting GPADC (%d)!\n", ret);997 998 return 0;999};1000 1001static DEFINE_SIMPLE_DEV_PM_OPS(twl6030_gpadc_pm_ops, twl6030_gpadc_suspend,1002 twl6030_gpadc_resume);1003 1004static struct platform_driver twl6030_gpadc_driver = {1005 .probe = twl6030_gpadc_probe,1006 .remove_new = twl6030_gpadc_remove,1007 .driver = {1008 .name = DRIVER_NAME,1009 .pm = pm_sleep_ptr(&twl6030_gpadc_pm_ops),1010 .of_match_table = of_twl6030_match_tbl,1011 },1012};1013 1014module_platform_driver(twl6030_gpadc_driver);1015 1016MODULE_ALIAS("platform:" DRIVER_NAME);1017MODULE_AUTHOR("Balaji T K <balajitk@ti.com>");1018MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");1019MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com");1020MODULE_DESCRIPTION("twl6030 ADC driver");1021MODULE_LICENSE("GPL");1022