0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/interrupt.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/of_platform.h>
0022 #include <linux/mfd/twl.h>
0023 #include <linux/iio/iio.h>
0024 #include <linux/iio/sysfs.h>
0025
0026 #define DRIVER_NAME "twl6030_gpadc"
0027
0028
0029
0030
0031
0032
0033
0034 #define TWL6030_GPADC_USED_CHANNELS 13
0035 #define TWL6030_GPADC_MAX_CHANNELS 15
0036 #define TWL6032_GPADC_USED_CHANNELS 15
0037 #define TWL6032_GPADC_MAX_CHANNELS 19
0038 #define TWL6030_GPADC_NUM_TRIM_REGS 16
0039
0040 #define TWL6030_GPADC_CTRL_P1 0x05
0041
0042 #define TWL6032_GPADC_GPSELECT_ISB 0x07
0043 #define TWL6032_GPADC_CTRL_P1 0x08
0044
0045 #define TWL6032_GPADC_GPCH0_LSB 0x0d
0046 #define TWL6032_GPADC_GPCH0_MSB 0x0e
0047
0048 #define TWL6030_GPADC_CTRL_P1_SP1 BIT(3)
0049
0050 #define TWL6030_GPADC_GPCH0_LSB (0x29)
0051
0052 #define TWL6030_GPADC_RT_SW1_EOC_MASK BIT(5)
0053
0054 #define TWL6030_GPADC_TRIM1 0xCD
0055
0056 #define TWL6030_REG_TOGGLE1 0x90
0057 #define TWL6030_GPADCS BIT(1)
0058 #define TWL6030_GPADCR BIT(0)
0059
0060
0061
0062
0063
0064
0065
0066 struct twl6030_chnl_calib {
0067 s32 gain;
0068 s32 gain_error;
0069 s32 offset_error;
0070 };
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 struct twl6030_ideal_code {
0084 int channel;
0085 u16 code1;
0086 u16 code2;
0087 u16 volt1;
0088 u16 volt2;
0089 };
0090
0091 struct twl6030_gpadc_data;
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 struct twl6030_gpadc_platform_data {
0104 const int nchannels;
0105 const struct iio_chan_spec *iio_channels;
0106 const struct twl6030_ideal_code *ideal;
0107 int (*start_conversion)(int channel);
0108 u8 (*channel_to_reg)(int channel);
0109 int (*calibrate)(struct twl6030_gpadc_data *gpadc);
0110 };
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 struct twl6030_gpadc_data {
0122 struct device *dev;
0123 struct mutex lock;
0124 struct completion irq_complete;
0125 struct twl6030_chnl_calib *twl6030_cal_tbl;
0126 const struct twl6030_gpadc_platform_data *pdata;
0127 };
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 static const struct twl6030_ideal_code
0138 twl6030_ideal[TWL6030_GPADC_USED_CHANNELS] = {
0139 [0] = {
0140 .channel = 0,
0141 .code1 = 116,
0142 .code2 = 745,
0143 .volt1 = 141,
0144 .volt2 = 910,
0145 },
0146 [1] = {
0147 .channel = 1,
0148 .code1 = 82,
0149 .code2 = 900,
0150 .volt1 = 100,
0151 .volt2 = 1100,
0152 },
0153 [2] = {
0154 .channel = 2,
0155 .code1 = 55,
0156 .code2 = 818,
0157 .volt1 = 101,
0158 .volt2 = 1499,
0159 },
0160 [3] = {
0161 .channel = 3,
0162 .code1 = 82,
0163 .code2 = 900,
0164 .volt1 = 100,
0165 .volt2 = 1100,
0166 },
0167 [4] = {
0168 .channel = 4,
0169 .code1 = 82,
0170 .code2 = 900,
0171 .volt1 = 100,
0172 .volt2 = 1100,
0173 },
0174 [5] = {
0175 .channel = 5,
0176 .code1 = 82,
0177 .code2 = 900,
0178 .volt1 = 100,
0179 .volt2 = 1100,
0180 },
0181 [6] = {
0182 .channel = 6,
0183 .code1 = 82,
0184 .code2 = 900,
0185 .volt1 = 100,
0186 .volt2 = 1100,
0187 },
0188 [7] = {
0189 .channel = 7,
0190 .code1 = 614,
0191 .code2 = 941,
0192 .volt1 = 3001,
0193 .volt2 = 4599,
0194 },
0195 [8] = {
0196 .channel = 8,
0197 .code1 = 82,
0198 .code2 = 688,
0199 .volt1 = 501,
0200 .volt2 = 4203,
0201 },
0202 [9] = {
0203 .channel = 9,
0204 .code1 = 182,
0205 .code2 = 818,
0206 .volt1 = 2001,
0207 .volt2 = 8996,
0208 },
0209 [10] = {
0210 .channel = 10,
0211 .code1 = 149,
0212 .code2 = 818,
0213 .volt1 = 1001,
0214 .volt2 = 5497,
0215 },
0216 [11] = {
0217 .channel = 11,
0218 },
0219
0220
0221 [12] = {
0222 .channel = 14,
0223 .code1 = 48,
0224 .code2 = 714,
0225 .volt1 = 323,
0226 .volt2 = 4800,
0227 },
0228 };
0229
0230 static const struct twl6030_ideal_code
0231 twl6032_ideal[TWL6032_GPADC_USED_CHANNELS] = {
0232 [0] = {
0233 .channel = 0,
0234 .code1 = 1441,
0235 .code2 = 3276,
0236 .volt1 = 440,
0237 .volt2 = 1000,
0238 },
0239 [1] = {
0240 .channel = 1,
0241 .code1 = 1441,
0242 .code2 = 3276,
0243 .volt1 = 440,
0244 .volt2 = 1000,
0245 },
0246 [2] = {
0247 .channel = 2,
0248 .code1 = 1441,
0249 .code2 = 3276,
0250 .volt1 = 660,
0251 .volt2 = 1500,
0252 },
0253 [3] = {
0254
0255 .channel = 3,
0256 .code1 = 1441,
0257 .code2 = 3276,
0258 .volt1 = 440,
0259 .volt2 = 1000,
0260 },
0261 [4] = {
0262 .channel = 4,
0263 .code1 = 1441,
0264 .code2 = 3276,
0265 .volt1 = 440,
0266 .volt2 = 1000,
0267 },
0268 [5] = {
0269 .channel = 5,
0270 .code1 = 1441,
0271 .code2 = 3276,
0272 .volt1 = 440,
0273 .volt2 = 1000,
0274 },
0275 [6] = {
0276 .channel = 6,
0277 .code1 = 1441,
0278 .code2 = 3276,
0279 .volt1 = 440,
0280 .volt2 = 1000,
0281 },
0282 [7] = {
0283 .channel = 7,
0284 .code1 = 1441,
0285 .code2 = 3276,
0286 .volt1 = 2200,
0287 .volt2 = 5000,
0288 },
0289 [8] = {
0290 .channel = 8,
0291 .code1 = 1441,
0292 .code2 = 3276,
0293 .volt1 = 2200,
0294 .volt2 = 5000,
0295 },
0296 [9] = {
0297 .channel = 9,
0298 .code1 = 1441,
0299 .code2 = 3276,
0300 .volt1 = 3960,
0301 .volt2 = 9000,
0302 },
0303 [10] = {
0304 .channel = 10,
0305 .code1 = 150,
0306 .code2 = 751,
0307 .volt1 = 1000,
0308 .volt2 = 5000,
0309 },
0310 [11] = {
0311 .channel = 11,
0312 .code1 = 1441,
0313 .code2 = 3276,
0314 .volt1 = 660,
0315 .volt2 = 1500,
0316 },
0317
0318
0319 [12] = {
0320 .channel = 14,
0321 .code1 = 1441,
0322 .code2 = 3276,
0323 .volt1 = 2420,
0324 .volt2 = 5500,
0325 },
0326
0327
0328 [13] = {
0329 .channel = 17,
0330 },
0331 [14] = {
0332 .channel = 18,
0333 .code1 = 1441,
0334 .code2 = 3276,
0335 .volt1 = 2200,
0336 .volt2 = 5000,
0337 },
0338 };
0339
0340 static inline int twl6030_gpadc_write(u8 reg, u8 val)
0341 {
0342 return twl_i2c_write_u8(TWL6030_MODULE_GPADC, val, reg);
0343 }
0344
0345 static inline int twl6030_gpadc_read(u8 reg, u8 *val)
0346 {
0347
0348 return twl_i2c_read(TWL6030_MODULE_GPADC, val, reg, 2);
0349 }
0350
0351 static int twl6030_gpadc_enable_irq(u8 mask)
0352 {
0353 int ret;
0354
0355 ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_LINE_B);
0356 if (ret < 0)
0357 return ret;
0358
0359 ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_STS_B);
0360
0361 return ret;
0362 }
0363
0364 static void twl6030_gpadc_disable_irq(u8 mask)
0365 {
0366 twl6030_interrupt_mask(mask, REG_INT_MSK_LINE_B);
0367 twl6030_interrupt_mask(mask, REG_INT_MSK_STS_B);
0368 }
0369
0370 static irqreturn_t twl6030_gpadc_irq_handler(int irq, void *indio_dev)
0371 {
0372 struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
0373
0374 complete(&gpadc->irq_complete);
0375
0376 return IRQ_HANDLED;
0377 }
0378
0379 static int twl6030_start_conversion(int channel)
0380 {
0381 return twl6030_gpadc_write(TWL6030_GPADC_CTRL_P1,
0382 TWL6030_GPADC_CTRL_P1_SP1);
0383 }
0384
0385 static int twl6032_start_conversion(int channel)
0386 {
0387 int ret;
0388
0389 ret = twl6030_gpadc_write(TWL6032_GPADC_GPSELECT_ISB, channel);
0390 if (ret)
0391 return ret;
0392
0393 return twl6030_gpadc_write(TWL6032_GPADC_CTRL_P1,
0394 TWL6030_GPADC_CTRL_P1_SP1);
0395 }
0396
0397 static u8 twl6030_channel_to_reg(int channel)
0398 {
0399 return TWL6030_GPADC_GPCH0_LSB + 2 * channel;
0400 }
0401
0402 static u8 twl6032_channel_to_reg(int channel)
0403 {
0404
0405
0406
0407
0408
0409 return TWL6032_GPADC_GPCH0_LSB;
0410 }
0411
0412 static int twl6030_gpadc_lookup(const struct twl6030_ideal_code *ideal,
0413 int channel, int size)
0414 {
0415 int i;
0416
0417 for (i = 0; i < size; i++)
0418 if (ideal[i].channel == channel)
0419 break;
0420
0421 return i;
0422 }
0423
0424 static int twl6030_channel_calibrated(const struct twl6030_gpadc_platform_data
0425 *pdata, int channel)
0426 {
0427 const struct twl6030_ideal_code *ideal = pdata->ideal;
0428 int i;
0429
0430 i = twl6030_gpadc_lookup(ideal, channel, pdata->nchannels);
0431
0432 return pdata->ideal[i].code2;
0433 }
0434
0435 static int twl6030_gpadc_make_correction(struct twl6030_gpadc_data *gpadc,
0436 int channel, int raw_code)
0437 {
0438 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
0439 int corrected_code;
0440 int i;
0441
0442 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
0443 corrected_code = ((raw_code * 1000) -
0444 gpadc->twl6030_cal_tbl[i].offset_error) /
0445 gpadc->twl6030_cal_tbl[i].gain_error;
0446
0447 return corrected_code;
0448 }
0449
0450 static int twl6030_gpadc_get_raw(struct twl6030_gpadc_data *gpadc,
0451 int channel, int *res)
0452 {
0453 u8 reg = gpadc->pdata->channel_to_reg(channel);
0454 __le16 val;
0455 int raw_code;
0456 int ret;
0457
0458 ret = twl6030_gpadc_read(reg, (u8 *)&val);
0459 if (ret) {
0460 dev_dbg(gpadc->dev, "unable to read register 0x%X\n", reg);
0461 return ret;
0462 }
0463
0464 raw_code = le16_to_cpu(val);
0465 dev_dbg(gpadc->dev, "GPADC raw code: %d", raw_code);
0466
0467 if (twl6030_channel_calibrated(gpadc->pdata, channel))
0468 *res = twl6030_gpadc_make_correction(gpadc, channel, raw_code);
0469 else
0470 *res = raw_code;
0471
0472 return ret;
0473 }
0474
0475 static int twl6030_gpadc_get_processed(struct twl6030_gpadc_data *gpadc,
0476 int channel, int *val)
0477 {
0478 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
0479 int corrected_code;
0480 int channel_value;
0481 int i;
0482 int ret;
0483
0484 ret = twl6030_gpadc_get_raw(gpadc, channel, &corrected_code);
0485 if (ret)
0486 return ret;
0487
0488 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
0489 channel_value = corrected_code *
0490 gpadc->twl6030_cal_tbl[i].gain;
0491
0492
0493 channel_value /= 1000;
0494
0495 dev_dbg(gpadc->dev, "GPADC corrected code: %d", corrected_code);
0496 dev_dbg(gpadc->dev, "GPADC value: %d", channel_value);
0497
0498 *val = channel_value;
0499
0500 return ret;
0501 }
0502
0503 static int twl6030_gpadc_read_raw(struct iio_dev *indio_dev,
0504 const struct iio_chan_spec *chan,
0505 int *val, int *val2, long mask)
0506 {
0507 struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
0508 int ret;
0509 long timeout;
0510
0511 mutex_lock(&gpadc->lock);
0512
0513 ret = gpadc->pdata->start_conversion(chan->channel);
0514 if (ret) {
0515 dev_err(gpadc->dev, "failed to start conversion\n");
0516 goto err;
0517 }
0518
0519 timeout = wait_for_completion_interruptible_timeout(
0520 &gpadc->irq_complete, msecs_to_jiffies(5000));
0521 if (timeout == 0) {
0522 ret = -ETIMEDOUT;
0523 goto err;
0524 } else if (timeout < 0) {
0525 ret = -EINTR;
0526 goto err;
0527 }
0528
0529 switch (mask) {
0530 case IIO_CHAN_INFO_RAW:
0531 ret = twl6030_gpadc_get_raw(gpadc, chan->channel, val);
0532 ret = ret ? -EIO : IIO_VAL_INT;
0533 break;
0534
0535 case IIO_CHAN_INFO_PROCESSED:
0536 ret = twl6030_gpadc_get_processed(gpadc, chan->channel, val);
0537 ret = ret ? -EIO : IIO_VAL_INT;
0538 break;
0539
0540 default:
0541 break;
0542 }
0543 err:
0544 mutex_unlock(&gpadc->lock);
0545
0546 return ret;
0547 }
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560 static void twl6030_calibrate_channel(struct twl6030_gpadc_data *gpadc,
0561 int channel, int d1, int d2)
0562 {
0563 int b, k, gain, x1, x2, i;
0564 const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
0565
0566 i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
0567
0568
0569 gain = ((ideal[i].volt2 - ideal[i].volt1) * 1000) /
0570 (ideal[i].code2 - ideal[i].code1);
0571
0572 x1 = ideal[i].code1;
0573 x2 = ideal[i].code2;
0574
0575
0576 k = 1000 + (((d2 - d1) * 1000) / (x2 - x1));
0577
0578
0579 b = (d1 * 1000) - (k - 1000) * x1;
0580
0581 gpadc->twl6030_cal_tbl[i].gain = gain;
0582 gpadc->twl6030_cal_tbl[i].gain_error = k;
0583 gpadc->twl6030_cal_tbl[i].offset_error = b;
0584
0585 dev_dbg(gpadc->dev, "GPADC d1 for Chn: %d = %d\n", channel, d1);
0586 dev_dbg(gpadc->dev, "GPADC d2 for Chn: %d = %d\n", channel, d2);
0587 dev_dbg(gpadc->dev, "GPADC x1 for Chn: %d = %d\n", channel, x1);
0588 dev_dbg(gpadc->dev, "GPADC x2 for Chn: %d = %d\n", channel, x2);
0589 dev_dbg(gpadc->dev, "GPADC Gain for Chn: %d = %d\n", channel, gain);
0590 dev_dbg(gpadc->dev, "GPADC k for Chn: %d = %d\n", channel, k);
0591 dev_dbg(gpadc->dev, "GPADC b for Chn: %d = %d\n", channel, b);
0592 }
0593
0594 static inline int twl6030_gpadc_get_trim_offset(s8 d)
0595 {
0596
0597
0598
0599
0600
0601
0602
0603 __u32 temp = ((d & 0x7f) >> 1) | ((d & 1) << 6);
0604
0605 return sign_extend32(temp, 6);
0606 }
0607
0608 static int twl6030_calibration(struct twl6030_gpadc_data *gpadc)
0609 {
0610 int ret;
0611 int chn;
0612 u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
0613 s8 d1, d2;
0614
0615
0616
0617
0618
0619
0620
0621
0622 ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
0623 TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
0624 if (ret < 0) {
0625 dev_err(gpadc->dev, "calibration failed\n");
0626 return ret;
0627 }
0628
0629 for (chn = 0; chn < TWL6030_GPADC_MAX_CHANNELS; chn++) {
0630
0631 switch (chn) {
0632 case 0:
0633 d1 = trim_regs[0];
0634 d2 = trim_regs[1];
0635 break;
0636 case 1:
0637 case 3:
0638 case 4:
0639 case 5:
0640 case 6:
0641 d1 = trim_regs[4];
0642 d2 = trim_regs[5];
0643 break;
0644 case 2:
0645 d1 = trim_regs[12];
0646 d2 = trim_regs[13];
0647 break;
0648 case 7:
0649 d1 = trim_regs[6];
0650 d2 = trim_regs[7];
0651 break;
0652 case 8:
0653 d1 = trim_regs[2];
0654 d2 = trim_regs[3];
0655 break;
0656 case 9:
0657 d1 = trim_regs[8];
0658 d2 = trim_regs[9];
0659 break;
0660 case 10:
0661 d1 = trim_regs[10];
0662 d2 = trim_regs[11];
0663 break;
0664 case 14:
0665 d1 = trim_regs[14];
0666 d2 = trim_regs[15];
0667 break;
0668 default:
0669 continue;
0670 }
0671
0672 d1 = twl6030_gpadc_get_trim_offset(d1);
0673 d2 = twl6030_gpadc_get_trim_offset(d2);
0674
0675 twl6030_calibrate_channel(gpadc, chn, d1, d2);
0676 }
0677
0678 return 0;
0679 }
0680
0681 static int twl6032_get_trim_value(u8 *trim_regs, unsigned int reg0,
0682 unsigned int reg1, unsigned int mask0, unsigned int mask1,
0683 unsigned int shift0)
0684 {
0685 int val;
0686
0687 val = (trim_regs[reg0] & mask0) << shift0;
0688 val |= (trim_regs[reg1] & mask1) >> 1;
0689 if (trim_regs[reg1] & 0x01)
0690 val = -val;
0691
0692 return val;
0693 }
0694
0695 static int twl6032_calibration(struct twl6030_gpadc_data *gpadc)
0696 {
0697 int chn, d1 = 0, d2 = 0, temp;
0698 u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
0699 int ret;
0700
0701 ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
0702 TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
0703 if (ret < 0) {
0704 dev_err(gpadc->dev, "calibration failed\n");
0705 return ret;
0706 }
0707
0708
0709
0710
0711
0712
0713
0714 for (chn = 0; chn < TWL6032_GPADC_MAX_CHANNELS; chn++) {
0715
0716 switch (chn) {
0717 case 0:
0718 case 1:
0719 case 2:
0720 case 3:
0721 case 4:
0722 case 5:
0723 case 6:
0724 case 11:
0725 case 14:
0726 d1 = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
0727 0x06, 2);
0728 d2 = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
0729 0x06, 2);
0730 break;
0731 case 8:
0732 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
0733 0x06, 2);
0734 d1 = temp + twl6032_get_trim_value(trim_regs, 7, 6,
0735 0x18, 0x1E, 1);
0736
0737 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3F,
0738 0x06, 2);
0739 d2 = temp + twl6032_get_trim_value(trim_regs, 9, 7,
0740 0x1F, 0x06, 2);
0741 break;
0742 case 9:
0743 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
0744 0x06, 2);
0745 d1 = temp + twl6032_get_trim_value(trim_regs, 13, 11,
0746 0x18, 0x1E, 1);
0747
0748 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
0749 0x06, 2);
0750 d2 = temp + twl6032_get_trim_value(trim_regs, 15, 13,
0751 0x1F, 0x06, 1);
0752 break;
0753 case 10:
0754 d1 = twl6032_get_trim_value(trim_regs, 10, 8, 0x0f,
0755 0x0E, 3);
0756 d2 = twl6032_get_trim_value(trim_regs, 14, 12, 0x0f,
0757 0x0E, 3);
0758 break;
0759 case 7:
0760 case 18:
0761 temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
0762 0x06, 2);
0763
0764 d1 = (trim_regs[4] & 0x7E) >> 1;
0765 if (trim_regs[4] & 0x01)
0766 d1 = -d1;
0767 d1 += temp;
0768
0769 temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
0770 0x06, 2);
0771
0772 d2 = (trim_regs[5] & 0xFE) >> 1;
0773 if (trim_regs[5] & 0x01)
0774 d2 = -d2;
0775
0776 d2 += temp;
0777 break;
0778 default:
0779
0780 continue;
0781 }
0782
0783 twl6030_calibrate_channel(gpadc, chn, d1, d2);
0784 }
0785
0786 return 0;
0787 }
0788
0789 #define TWL6030_GPADC_CHAN(chn, _type, chan_info) { \
0790 .type = _type, \
0791 .channel = chn, \
0792 .info_mask_separate = BIT(chan_info), \
0793 .indexed = 1, \
0794 }
0795
0796 static const struct iio_chan_spec twl6030_gpadc_iio_channels[] = {
0797 TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0798 TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
0799 TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0800 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0801 TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
0802 TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0803 TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0804 TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0805 TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0806 TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0807 TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0808 TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
0809 TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0810 };
0811
0812 static const struct iio_chan_spec twl6032_gpadc_iio_channels[] = {
0813 TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0814 TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
0815 TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0816 TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0817 TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
0818 TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0819 TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0820 TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0821 TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0822 TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0823 TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0824 TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0825 TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0826 TWL6030_GPADC_CHAN(17, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
0827 TWL6030_GPADC_CHAN(18, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
0828 };
0829
0830 static const struct iio_info twl6030_gpadc_iio_info = {
0831 .read_raw = &twl6030_gpadc_read_raw,
0832 };
0833
0834 static const struct twl6030_gpadc_platform_data twl6030_pdata = {
0835 .iio_channels = twl6030_gpadc_iio_channels,
0836 .nchannels = TWL6030_GPADC_USED_CHANNELS,
0837 .ideal = twl6030_ideal,
0838 .start_conversion = twl6030_start_conversion,
0839 .channel_to_reg = twl6030_channel_to_reg,
0840 .calibrate = twl6030_calibration,
0841 };
0842
0843 static const struct twl6030_gpadc_platform_data twl6032_pdata = {
0844 .iio_channels = twl6032_gpadc_iio_channels,
0845 .nchannels = TWL6032_GPADC_USED_CHANNELS,
0846 .ideal = twl6032_ideal,
0847 .start_conversion = twl6032_start_conversion,
0848 .channel_to_reg = twl6032_channel_to_reg,
0849 .calibrate = twl6032_calibration,
0850 };
0851
0852 static const struct of_device_id of_twl6030_match_tbl[] = {
0853 {
0854 .compatible = "ti,twl6030-gpadc",
0855 .data = &twl6030_pdata,
0856 },
0857 {
0858 .compatible = "ti,twl6032-gpadc",
0859 .data = &twl6032_pdata,
0860 },
0861 { }
0862 };
0863 MODULE_DEVICE_TABLE(of, of_twl6030_match_tbl);
0864
0865 static int twl6030_gpadc_probe(struct platform_device *pdev)
0866 {
0867 struct device *dev = &pdev->dev;
0868 struct twl6030_gpadc_data *gpadc;
0869 const struct twl6030_gpadc_platform_data *pdata;
0870 const struct of_device_id *match;
0871 struct iio_dev *indio_dev;
0872 int irq;
0873 int ret;
0874
0875 match = of_match_device(of_twl6030_match_tbl, dev);
0876 if (!match)
0877 return -EINVAL;
0878
0879 pdata = match->data;
0880
0881 indio_dev = devm_iio_device_alloc(dev, sizeof(*gpadc));
0882 if (!indio_dev)
0883 return -ENOMEM;
0884
0885 gpadc = iio_priv(indio_dev);
0886
0887 gpadc->twl6030_cal_tbl = devm_kcalloc(dev,
0888 pdata->nchannels,
0889 sizeof(*gpadc->twl6030_cal_tbl),
0890 GFP_KERNEL);
0891 if (!gpadc->twl6030_cal_tbl)
0892 return -ENOMEM;
0893
0894 gpadc->dev = dev;
0895 gpadc->pdata = pdata;
0896
0897 platform_set_drvdata(pdev, indio_dev);
0898 mutex_init(&gpadc->lock);
0899 init_completion(&gpadc->irq_complete);
0900
0901 ret = pdata->calibrate(gpadc);
0902 if (ret < 0) {
0903 dev_err(dev, "failed to read calibration registers\n");
0904 return ret;
0905 }
0906
0907 irq = platform_get_irq(pdev, 0);
0908 if (irq < 0)
0909 return irq;
0910
0911 ret = devm_request_threaded_irq(dev, irq, NULL,
0912 twl6030_gpadc_irq_handler,
0913 IRQF_ONESHOT, "twl6030_gpadc", indio_dev);
0914 if (ret)
0915 return ret;
0916
0917 ret = twl6030_gpadc_enable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
0918 if (ret < 0) {
0919 dev_err(dev, "failed to enable GPADC interrupt\n");
0920 return ret;
0921 }
0922
0923 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
0924 TWL6030_REG_TOGGLE1);
0925 if (ret < 0) {
0926 dev_err(dev, "failed to enable GPADC module\n");
0927 return ret;
0928 }
0929
0930 indio_dev->name = DRIVER_NAME;
0931 indio_dev->info = &twl6030_gpadc_iio_info;
0932 indio_dev->modes = INDIO_DIRECT_MODE;
0933 indio_dev->channels = pdata->iio_channels;
0934 indio_dev->num_channels = pdata->nchannels;
0935
0936 return iio_device_register(indio_dev);
0937 }
0938
0939 static int twl6030_gpadc_remove(struct platform_device *pdev)
0940 {
0941 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
0942
0943 twl6030_gpadc_disable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
0944 iio_device_unregister(indio_dev);
0945
0946 return 0;
0947 }
0948
0949 static int twl6030_gpadc_suspend(struct device *pdev)
0950 {
0951 int ret;
0952
0953 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCR,
0954 TWL6030_REG_TOGGLE1);
0955 if (ret)
0956 dev_err(pdev, "error resetting GPADC (%d)!\n", ret);
0957
0958 return 0;
0959 };
0960
0961 static int twl6030_gpadc_resume(struct device *pdev)
0962 {
0963 int ret;
0964
0965 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
0966 TWL6030_REG_TOGGLE1);
0967 if (ret)
0968 dev_err(pdev, "error setting GPADC (%d)!\n", ret);
0969
0970 return 0;
0971 };
0972
0973 static DEFINE_SIMPLE_DEV_PM_OPS(twl6030_gpadc_pm_ops, twl6030_gpadc_suspend,
0974 twl6030_gpadc_resume);
0975
0976 static struct platform_driver twl6030_gpadc_driver = {
0977 .probe = twl6030_gpadc_probe,
0978 .remove = twl6030_gpadc_remove,
0979 .driver = {
0980 .name = DRIVER_NAME,
0981 .pm = pm_sleep_ptr(&twl6030_gpadc_pm_ops),
0982 .of_match_table = of_twl6030_match_tbl,
0983 },
0984 };
0985
0986 module_platform_driver(twl6030_gpadc_driver);
0987
0988 MODULE_ALIAS("platform:" DRIVER_NAME);
0989 MODULE_AUTHOR("Balaji T K <balajitk@ti.com>");
0990 MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
0991 MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com");
0992 MODULE_DESCRIPTION("twl6030 ADC driver");
0993 MODULE_LICENSE("GPL");