0001
0002
0003
0004
0005
0006 #include <linux/bitops.h>
0007 #include <linux/completion.h>
0008 #include <linux/delay.h>
0009 #include <linux/err.h>
0010 #include <linux/iio/iio.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/kernel.h>
0013 #include <linux/mutex.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/of_device.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/regmap.h>
0019 #include <linux/slab.h>
0020
0021
0022 #define IADC_REVISION2 0x1
0023 #define IADC_REVISION2_SUPPORTED_IADC 1
0024
0025 #define IADC_PERPH_TYPE 0x4
0026 #define IADC_PERPH_TYPE_ADC 8
0027
0028 #define IADC_PERPH_SUBTYPE 0x5
0029 #define IADC_PERPH_SUBTYPE_IADC 3
0030
0031 #define IADC_STATUS1 0x8
0032 #define IADC_STATUS1_OP_MODE 4
0033 #define IADC_STATUS1_REQ_STS BIT(1)
0034 #define IADC_STATUS1_EOC BIT(0)
0035 #define IADC_STATUS1_REQ_STS_EOC_MASK 0x3
0036
0037 #define IADC_MODE_CTL 0x40
0038 #define IADC_OP_MODE_SHIFT 3
0039 #define IADC_OP_MODE_NORMAL 0
0040 #define IADC_TRIM_EN BIT(0)
0041
0042 #define IADC_EN_CTL1 0x46
0043 #define IADC_EN_CTL1_SET BIT(7)
0044
0045 #define IADC_CH_SEL_CTL 0x48
0046
0047 #define IADC_DIG_PARAM 0x50
0048 #define IADC_DIG_DEC_RATIO_SEL_SHIFT 2
0049
0050 #define IADC_HW_SETTLE_DELAY 0x51
0051
0052 #define IADC_CONV_REQ 0x52
0053 #define IADC_CONV_REQ_SET BIT(7)
0054
0055 #define IADC_FAST_AVG_CTL 0x5a
0056 #define IADC_FAST_AVG_EN 0x5b
0057 #define IADC_FAST_AVG_EN_SET BIT(7)
0058
0059 #define IADC_PERH_RESET_CTL3 0xda
0060 #define IADC_FOLLOW_WARM_RB BIT(2)
0061
0062 #define IADC_DATA 0x60
0063
0064 #define IADC_SEC_ACCESS 0xd0
0065 #define IADC_SEC_ACCESS_DATA 0xa5
0066
0067 #define IADC_NOMINAL_RSENSE 0xf4
0068 #define IADC_NOMINAL_RSENSE_SIGN_MASK BIT(7)
0069
0070 #define IADC_REF_GAIN_MICRO_VOLTS 17857
0071
0072 #define IADC_INT_RSENSE_DEVIATION 15625
0073
0074 #define IADC_INT_RSENSE_IDEAL_VALUE 10000
0075 #define IADC_INT_RSENSE_DEFAULT_VALUE 7800
0076 #define IADC_INT_RSENSE_DEFAULT_GF 9000
0077 #define IADC_INT_RSENSE_DEFAULT_SMIC 9700
0078
0079 #define IADC_CONV_TIME_MIN_US 2000
0080 #define IADC_CONV_TIME_MAX_US 2100
0081
0082 #define IADC_DEF_PRESCALING 0
0083 #define IADC_DEF_DECIMATION 0
0084 #define IADC_DEF_HW_SETTLE_TIME 0
0085 #define IADC_DEF_AVG_SAMPLES 0
0086
0087
0088 #define IADC_INT_RSENSE 0
0089 #define IADC_EXT_RSENSE 1
0090 #define IADC_GAIN_17P857MV 3
0091 #define IADC_EXT_OFFSET_CSP_CSN 5
0092 #define IADC_INT_OFFSET_CSP2_CSN2 6
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 struct iadc_chip {
0107 struct regmap *regmap;
0108 struct device *dev;
0109 u16 base;
0110 bool poll_eoc;
0111 u32 rsense[2];
0112 u16 offset[2];
0113 u16 gain;
0114 struct mutex lock;
0115 struct completion complete;
0116 };
0117
0118 static int iadc_read(struct iadc_chip *iadc, u16 offset, u8 *data)
0119 {
0120 unsigned int val;
0121 int ret;
0122
0123 ret = regmap_read(iadc->regmap, iadc->base + offset, &val);
0124 if (ret < 0)
0125 return ret;
0126
0127 *data = val;
0128 return 0;
0129 }
0130
0131 static int iadc_write(struct iadc_chip *iadc, u16 offset, u8 data)
0132 {
0133 return regmap_write(iadc->regmap, iadc->base + offset, data);
0134 }
0135
0136 static int iadc_reset(struct iadc_chip *iadc)
0137 {
0138 u8 data;
0139 int ret;
0140
0141 ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
0142 if (ret < 0)
0143 return ret;
0144
0145 ret = iadc_read(iadc, IADC_PERH_RESET_CTL3, &data);
0146 if (ret < 0)
0147 return ret;
0148
0149 ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
0150 if (ret < 0)
0151 return ret;
0152
0153 data |= IADC_FOLLOW_WARM_RB;
0154
0155 return iadc_write(iadc, IADC_PERH_RESET_CTL3, data);
0156 }
0157
0158 static int iadc_set_state(struct iadc_chip *iadc, bool state)
0159 {
0160 return iadc_write(iadc, IADC_EN_CTL1, state ? IADC_EN_CTL1_SET : 0);
0161 }
0162
0163 static void iadc_status_show(struct iadc_chip *iadc)
0164 {
0165 u8 mode, sta1, chan, dig, en, req;
0166 int ret;
0167
0168 ret = iadc_read(iadc, IADC_MODE_CTL, &mode);
0169 if (ret < 0)
0170 return;
0171
0172 ret = iadc_read(iadc, IADC_DIG_PARAM, &dig);
0173 if (ret < 0)
0174 return;
0175
0176 ret = iadc_read(iadc, IADC_CH_SEL_CTL, &chan);
0177 if (ret < 0)
0178 return;
0179
0180 ret = iadc_read(iadc, IADC_CONV_REQ, &req);
0181 if (ret < 0)
0182 return;
0183
0184 ret = iadc_read(iadc, IADC_STATUS1, &sta1);
0185 if (ret < 0)
0186 return;
0187
0188 ret = iadc_read(iadc, IADC_EN_CTL1, &en);
0189 if (ret < 0)
0190 return;
0191
0192 dev_err(iadc->dev,
0193 "mode:%02x en:%02x chan:%02x dig:%02x req:%02x sta1:%02x\n",
0194 mode, en, chan, dig, req, sta1);
0195 }
0196
0197 static int iadc_configure(struct iadc_chip *iadc, int channel)
0198 {
0199 u8 decim, mode;
0200 int ret;
0201
0202
0203 mode = (IADC_OP_MODE_NORMAL << IADC_OP_MODE_SHIFT) | IADC_TRIM_EN;
0204 ret = iadc_write(iadc, IADC_MODE_CTL, mode);
0205 if (ret < 0)
0206 return ret;
0207
0208
0209 ret = iadc_write(iadc, IADC_CH_SEL_CTL, channel);
0210 if (ret < 0)
0211 return ret;
0212
0213
0214 decim = IADC_DEF_DECIMATION << IADC_DIG_DEC_RATIO_SEL_SHIFT;
0215 ret = iadc_write(iadc, IADC_DIG_PARAM, decim);
0216 if (ret < 0)
0217 return ret;
0218
0219
0220 ret = iadc_write(iadc, IADC_HW_SETTLE_DELAY, IADC_DEF_HW_SETTLE_TIME);
0221 if (ret < 0)
0222 return ret;
0223
0224 ret = iadc_write(iadc, IADC_FAST_AVG_CTL, IADC_DEF_AVG_SAMPLES);
0225 if (ret < 0)
0226 return ret;
0227
0228 if (IADC_DEF_AVG_SAMPLES)
0229 ret = iadc_write(iadc, IADC_FAST_AVG_EN, IADC_FAST_AVG_EN_SET);
0230 else
0231 ret = iadc_write(iadc, IADC_FAST_AVG_EN, 0);
0232
0233 if (ret < 0)
0234 return ret;
0235
0236 if (!iadc->poll_eoc)
0237 reinit_completion(&iadc->complete);
0238
0239 ret = iadc_set_state(iadc, true);
0240 if (ret < 0)
0241 return ret;
0242
0243
0244 return iadc_write(iadc, IADC_CONV_REQ, IADC_CONV_REQ_SET);
0245 }
0246
0247 static int iadc_poll_wait_eoc(struct iadc_chip *iadc, unsigned int interval_us)
0248 {
0249 unsigned int count, retry;
0250 int ret;
0251 u8 sta1;
0252
0253 retry = interval_us / IADC_CONV_TIME_MIN_US;
0254
0255 for (count = 0; count < retry; count++) {
0256 ret = iadc_read(iadc, IADC_STATUS1, &sta1);
0257 if (ret < 0)
0258 return ret;
0259
0260 sta1 &= IADC_STATUS1_REQ_STS_EOC_MASK;
0261 if (sta1 == IADC_STATUS1_EOC)
0262 return 0;
0263
0264 usleep_range(IADC_CONV_TIME_MIN_US, IADC_CONV_TIME_MAX_US);
0265 }
0266
0267 iadc_status_show(iadc);
0268
0269 return -ETIMEDOUT;
0270 }
0271
0272 static int iadc_read_result(struct iadc_chip *iadc, u16 *data)
0273 {
0274 return regmap_bulk_read(iadc->regmap, iadc->base + IADC_DATA, data, 2);
0275 }
0276
0277 static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data)
0278 {
0279 unsigned int wait;
0280 int ret;
0281
0282 ret = iadc_configure(iadc, chan);
0283 if (ret < 0)
0284 goto exit;
0285
0286 wait = BIT(IADC_DEF_AVG_SAMPLES) * IADC_CONV_TIME_MIN_US * 2;
0287
0288 if (iadc->poll_eoc) {
0289 ret = iadc_poll_wait_eoc(iadc, wait);
0290 } else {
0291 ret = wait_for_completion_timeout(&iadc->complete,
0292 usecs_to_jiffies(wait));
0293 if (!ret)
0294 ret = -ETIMEDOUT;
0295 else
0296
0297 ret = iadc_poll_wait_eoc(iadc, IADC_CONV_TIME_MIN_US);
0298 }
0299
0300 if (!ret)
0301 ret = iadc_read_result(iadc, data);
0302 exit:
0303 iadc_set_state(iadc, false);
0304 if (ret < 0)
0305 dev_err(iadc->dev, "conversion failed\n");
0306
0307 return ret;
0308 }
0309
0310 static int iadc_read_raw(struct iio_dev *indio_dev,
0311 struct iio_chan_spec const *chan,
0312 int *val, int *val2, long mask)
0313 {
0314 struct iadc_chip *iadc = iio_priv(indio_dev);
0315 s32 isense_ua, vsense_uv;
0316 u16 adc_raw, vsense_raw;
0317 int ret;
0318
0319 switch (mask) {
0320 case IIO_CHAN_INFO_RAW:
0321 mutex_lock(&iadc->lock);
0322 ret = iadc_do_conversion(iadc, chan->channel, &adc_raw);
0323 mutex_unlock(&iadc->lock);
0324 if (ret < 0)
0325 return ret;
0326
0327 vsense_raw = adc_raw - iadc->offset[chan->channel];
0328
0329 vsense_uv = vsense_raw * IADC_REF_GAIN_MICRO_VOLTS;
0330 vsense_uv /= (s32)iadc->gain - iadc->offset[chan->channel];
0331
0332 isense_ua = vsense_uv / iadc->rsense[chan->channel];
0333
0334 dev_dbg(iadc->dev, "off %d gain %d adc %d %duV I %duA\n",
0335 iadc->offset[chan->channel], iadc->gain,
0336 adc_raw, vsense_uv, isense_ua);
0337
0338 *val = isense_ua;
0339 return IIO_VAL_INT;
0340 case IIO_CHAN_INFO_SCALE:
0341 *val = 0;
0342 *val2 = 1000;
0343 return IIO_VAL_INT_PLUS_MICRO;
0344 }
0345
0346 return -EINVAL;
0347 }
0348
0349 static const struct iio_info iadc_info = {
0350 .read_raw = iadc_read_raw,
0351 };
0352
0353 static irqreturn_t iadc_isr(int irq, void *dev_id)
0354 {
0355 struct iadc_chip *iadc = dev_id;
0356
0357 complete(&iadc->complete);
0358
0359 return IRQ_HANDLED;
0360 }
0361
0362 static int iadc_update_offset(struct iadc_chip *iadc)
0363 {
0364 int ret;
0365
0366 ret = iadc_do_conversion(iadc, IADC_GAIN_17P857MV, &iadc->gain);
0367 if (ret < 0)
0368 return ret;
0369
0370 ret = iadc_do_conversion(iadc, IADC_INT_OFFSET_CSP2_CSN2,
0371 &iadc->offset[IADC_INT_RSENSE]);
0372 if (ret < 0)
0373 return ret;
0374
0375 if (iadc->gain == iadc->offset[IADC_INT_RSENSE]) {
0376 dev_err(iadc->dev, "error: internal offset == gain %d\n",
0377 iadc->gain);
0378 return -EINVAL;
0379 }
0380
0381 ret = iadc_do_conversion(iadc, IADC_EXT_OFFSET_CSP_CSN,
0382 &iadc->offset[IADC_EXT_RSENSE]);
0383 if (ret < 0)
0384 return ret;
0385
0386 if (iadc->gain == iadc->offset[IADC_EXT_RSENSE]) {
0387 dev_err(iadc->dev, "error: external offset == gain %d\n",
0388 iadc->gain);
0389 return -EINVAL;
0390 }
0391
0392 return 0;
0393 }
0394
0395 static int iadc_version_check(struct iadc_chip *iadc)
0396 {
0397 u8 val;
0398 int ret;
0399
0400 ret = iadc_read(iadc, IADC_PERPH_TYPE, &val);
0401 if (ret < 0)
0402 return ret;
0403
0404 if (val < IADC_PERPH_TYPE_ADC) {
0405 dev_err(iadc->dev, "%d is not ADC\n", val);
0406 return -EINVAL;
0407 }
0408
0409 ret = iadc_read(iadc, IADC_PERPH_SUBTYPE, &val);
0410 if (ret < 0)
0411 return ret;
0412
0413 if (val < IADC_PERPH_SUBTYPE_IADC) {
0414 dev_err(iadc->dev, "%d is not IADC\n", val);
0415 return -EINVAL;
0416 }
0417
0418 ret = iadc_read(iadc, IADC_REVISION2, &val);
0419 if (ret < 0)
0420 return ret;
0421
0422 if (val < IADC_REVISION2_SUPPORTED_IADC) {
0423 dev_err(iadc->dev, "revision %d not supported\n", val);
0424 return -EINVAL;
0425 }
0426
0427 return 0;
0428 }
0429
0430 static int iadc_rsense_read(struct iadc_chip *iadc, struct device_node *node)
0431 {
0432 int ret, sign, int_sense;
0433 u8 deviation;
0434
0435 ret = of_property_read_u32(node, "qcom,external-resistor-micro-ohms",
0436 &iadc->rsense[IADC_EXT_RSENSE]);
0437 if (ret < 0)
0438 iadc->rsense[IADC_EXT_RSENSE] = IADC_INT_RSENSE_IDEAL_VALUE;
0439
0440 if (!iadc->rsense[IADC_EXT_RSENSE]) {
0441 dev_err(iadc->dev, "external resistor can't be zero Ohms");
0442 return -EINVAL;
0443 }
0444
0445 ret = iadc_read(iadc, IADC_NOMINAL_RSENSE, &deviation);
0446 if (ret < 0)
0447 return ret;
0448
0449
0450
0451
0452
0453 sign = (deviation & IADC_NOMINAL_RSENSE_SIGN_MASK) ? -1 : 1;
0454
0455 deviation &= ~IADC_NOMINAL_RSENSE_SIGN_MASK;
0456
0457
0458 int_sense = IADC_INT_RSENSE_IDEAL_VALUE * 1000;
0459 int_sense += sign * deviation * IADC_INT_RSENSE_DEVIATION;
0460 int_sense /= 1000;
0461
0462 iadc->rsense[IADC_INT_RSENSE] = int_sense;
0463 return 0;
0464 }
0465
0466 static const struct iio_chan_spec iadc_channels[] = {
0467 {
0468 .type = IIO_CURRENT,
0469 .datasheet_name = "INTERNAL_RSENSE",
0470 .channel = 0,
0471 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0472 BIT(IIO_CHAN_INFO_SCALE),
0473 .indexed = 1,
0474 },
0475 {
0476 .type = IIO_CURRENT,
0477 .datasheet_name = "EXTERNAL_RSENSE",
0478 .channel = 1,
0479 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0480 BIT(IIO_CHAN_INFO_SCALE),
0481 .indexed = 1,
0482 },
0483 };
0484
0485 static int iadc_probe(struct platform_device *pdev)
0486 {
0487 struct device_node *node = pdev->dev.of_node;
0488 struct device *dev = &pdev->dev;
0489 struct iio_dev *indio_dev;
0490 struct iadc_chip *iadc;
0491 int ret, irq_eoc;
0492 u32 res;
0493
0494 indio_dev = devm_iio_device_alloc(dev, sizeof(*iadc));
0495 if (!indio_dev)
0496 return -ENOMEM;
0497
0498 iadc = iio_priv(indio_dev);
0499 iadc->dev = dev;
0500
0501 iadc->regmap = dev_get_regmap(dev->parent, NULL);
0502 if (!iadc->regmap)
0503 return -ENODEV;
0504
0505 init_completion(&iadc->complete);
0506 mutex_init(&iadc->lock);
0507
0508 ret = of_property_read_u32(node, "reg", &res);
0509 if (ret < 0)
0510 return -ENODEV;
0511
0512 iadc->base = res;
0513
0514 ret = iadc_version_check(iadc);
0515 if (ret < 0)
0516 return -ENODEV;
0517
0518 ret = iadc_rsense_read(iadc, node);
0519 if (ret < 0)
0520 return -ENODEV;
0521
0522 dev_dbg(iadc->dev, "sense resistors %d and %d micro Ohm\n",
0523 iadc->rsense[IADC_INT_RSENSE],
0524 iadc->rsense[IADC_EXT_RSENSE]);
0525
0526 irq_eoc = platform_get_irq(pdev, 0);
0527 if (irq_eoc == -EPROBE_DEFER)
0528 return irq_eoc;
0529
0530 if (irq_eoc < 0)
0531 iadc->poll_eoc = true;
0532
0533 ret = iadc_reset(iadc);
0534 if (ret < 0) {
0535 dev_err(dev, "reset failed\n");
0536 return ret;
0537 }
0538
0539 if (!iadc->poll_eoc) {
0540 ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0,
0541 "spmi-iadc", iadc);
0542 if (!ret)
0543 enable_irq_wake(irq_eoc);
0544 else
0545 return ret;
0546 } else {
0547 device_init_wakeup(iadc->dev, 1);
0548 }
0549
0550 ret = iadc_update_offset(iadc);
0551 if (ret < 0) {
0552 dev_err(dev, "failed offset calibration\n");
0553 return ret;
0554 }
0555
0556 indio_dev->name = pdev->name;
0557 indio_dev->modes = INDIO_DIRECT_MODE;
0558 indio_dev->info = &iadc_info;
0559 indio_dev->channels = iadc_channels;
0560 indio_dev->num_channels = ARRAY_SIZE(iadc_channels);
0561
0562 return devm_iio_device_register(dev, indio_dev);
0563 }
0564
0565 static const struct of_device_id iadc_match_table[] = {
0566 { .compatible = "qcom,spmi-iadc" },
0567 { }
0568 };
0569
0570 MODULE_DEVICE_TABLE(of, iadc_match_table);
0571
0572 static struct platform_driver iadc_driver = {
0573 .driver = {
0574 .name = "qcom-spmi-iadc",
0575 .of_match_table = iadc_match_table,
0576 },
0577 .probe = iadc_probe,
0578 };
0579
0580 module_platform_driver(iadc_driver);
0581
0582 MODULE_ALIAS("platform:qcom-spmi-iadc");
0583 MODULE_DESCRIPTION("Qualcomm SPMI PMIC current ADC driver");
0584 MODULE_LICENSE("GPL v2");
0585 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");