root/drivers/iio/adc/qcom-spmi-iadc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iadc_read
  2. iadc_write
  3. iadc_reset
  4. iadc_set_state
  5. iadc_status_show
  6. iadc_configure
  7. iadc_poll_wait_eoc
  8. iadc_read_result
  9. iadc_do_conversion
  10. iadc_read_raw
  11. iadc_isr
  12. iadc_update_offset
  13. iadc_version_check
  14. iadc_rsense_read
  15. iadc_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
   4  */
   5 
   6 #include <linux/bitops.h>
   7 #include <linux/completion.h>
   8 #include <linux/delay.h>
   9 #include <linux/err.h>
  10 #include <linux/iio/iio.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/kernel.h>
  13 #include <linux/mutex.h>
  14 #include <linux/module.h>
  15 #include <linux/of.h>
  16 #include <linux/of_device.h>
  17 #include <linux/platform_device.h>
  18 #include <linux/regmap.h>
  19 #include <linux/slab.h>
  20 
  21 /* IADC register and bit definition */
  22 #define IADC_REVISION2                          0x1
  23 #define IADC_REVISION2_SUPPORTED_IADC           1
  24 
  25 #define IADC_PERPH_TYPE                         0x4
  26 #define IADC_PERPH_TYPE_ADC                     8
  27 
  28 #define IADC_PERPH_SUBTYPE                      0x5
  29 #define IADC_PERPH_SUBTYPE_IADC                 3
  30 
  31 #define IADC_STATUS1                            0x8
  32 #define IADC_STATUS1_OP_MODE                    4
  33 #define IADC_STATUS1_REQ_STS                    BIT(1)
  34 #define IADC_STATUS1_EOC                        BIT(0)
  35 #define IADC_STATUS1_REQ_STS_EOC_MASK           0x3
  36 
  37 #define IADC_MODE_CTL                           0x40
  38 #define IADC_OP_MODE_SHIFT                      3
  39 #define IADC_OP_MODE_NORMAL                     0
  40 #define IADC_TRIM_EN                            BIT(0)
  41 
  42 #define IADC_EN_CTL1                            0x46
  43 #define IADC_EN_CTL1_SET                        BIT(7)
  44 
  45 #define IADC_CH_SEL_CTL                         0x48
  46 
  47 #define IADC_DIG_PARAM                          0x50
  48 #define IADC_DIG_DEC_RATIO_SEL_SHIFT            2
  49 
  50 #define IADC_HW_SETTLE_DELAY                    0x51
  51 
  52 #define IADC_CONV_REQ                           0x52
  53 #define IADC_CONV_REQ_SET                       BIT(7)
  54 
  55 #define IADC_FAST_AVG_CTL                       0x5a
  56 #define IADC_FAST_AVG_EN                        0x5b
  57 #define IADC_FAST_AVG_EN_SET                    BIT(7)
  58 
  59 #define IADC_PERH_RESET_CTL3                    0xda
  60 #define IADC_FOLLOW_WARM_RB                     BIT(2)
  61 
  62 #define IADC_DATA                               0x60    /* 16 bits */
  63 
  64 #define IADC_SEC_ACCESS                         0xd0
  65 #define IADC_SEC_ACCESS_DATA                    0xa5
  66 
  67 #define IADC_NOMINAL_RSENSE                     0xf4
  68 #define IADC_NOMINAL_RSENSE_SIGN_MASK           BIT(7)
  69 
  70 #define IADC_REF_GAIN_MICRO_VOLTS               17857
  71 
  72 #define IADC_INT_RSENSE_DEVIATION               15625   /* nano Ohms per bit */
  73 
  74 #define IADC_INT_RSENSE_IDEAL_VALUE             10000   /* micro Ohms */
  75 #define IADC_INT_RSENSE_DEFAULT_VALUE           7800    /* micro Ohms */
  76 #define IADC_INT_RSENSE_DEFAULT_GF              9000    /* micro Ohms */
  77 #define IADC_INT_RSENSE_DEFAULT_SMIC            9700    /* micro Ohms */
  78 
  79 #define IADC_CONV_TIME_MIN_US                   2000
  80 #define IADC_CONV_TIME_MAX_US                   2100
  81 
  82 #define IADC_DEF_PRESCALING                     0 /* 1:1 */
  83 #define IADC_DEF_DECIMATION                     0 /* 512 */
  84 #define IADC_DEF_HW_SETTLE_TIME                 0 /* 0 us */
  85 #define IADC_DEF_AVG_SAMPLES                    0 /* 1 sample */
  86 
  87 /* IADC channel list */
  88 #define IADC_INT_RSENSE                         0
  89 #define IADC_EXT_RSENSE                         1
  90 #define IADC_GAIN_17P857MV                      3
  91 #define IADC_EXT_OFFSET_CSP_CSN                 5
  92 #define IADC_INT_OFFSET_CSP2_CSN2               6
  93 
  94 /**
  95  * struct iadc_chip - IADC Current ADC device structure.
  96  * @regmap: regmap for register read/write.
  97  * @dev: This device pointer.
  98  * @base: base offset for the ADC peripheral.
  99  * @rsense: Values of the internal and external sense resister in micro Ohms.
 100  * @poll_eoc: Poll for end of conversion instead of waiting for IRQ.
 101  * @offset: Raw offset values for the internal and external channels.
 102  * @gain: Raw gain of the channels.
 103  * @lock: ADC lock for access to the peripheral.
 104  * @complete: ADC notification after end of conversion interrupt is received.
 105  */
 106 struct iadc_chip {
 107         struct regmap   *regmap;
 108         struct device   *dev;
 109         u16             base;
 110         bool            poll_eoc;
 111         u32             rsense[2];
 112         u16             offset[2];
 113         u16             gain;
 114         struct mutex    lock;
 115         struct completion complete;
 116 };
 117 
 118 static int iadc_read(struct iadc_chip *iadc, u16 offset, u8 *data)
 119 {
 120         unsigned int val;
 121         int ret;
 122 
 123         ret = regmap_read(iadc->regmap, iadc->base + offset, &val);
 124         if (ret < 0)
 125                 return ret;
 126 
 127         *data = val;
 128         return 0;
 129 }
 130 
 131 static int iadc_write(struct iadc_chip *iadc, u16 offset, u8 data)
 132 {
 133         return regmap_write(iadc->regmap, iadc->base + offset, data);
 134 }
 135 
 136 static int iadc_reset(struct iadc_chip *iadc)
 137 {
 138         u8 data;
 139         int ret;
 140 
 141         ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
 142         if (ret < 0)
 143                 return ret;
 144 
 145         ret = iadc_read(iadc, IADC_PERH_RESET_CTL3, &data);
 146         if (ret < 0)
 147                 return ret;
 148 
 149         ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
 150         if (ret < 0)
 151                 return ret;
 152 
 153         data |= IADC_FOLLOW_WARM_RB;
 154 
 155         return iadc_write(iadc, IADC_PERH_RESET_CTL3, data);
 156 }
 157 
 158 static int iadc_set_state(struct iadc_chip *iadc, bool state)
 159 {
 160         return iadc_write(iadc, IADC_EN_CTL1, state ? IADC_EN_CTL1_SET : 0);
 161 }
 162 
 163 static void iadc_status_show(struct iadc_chip *iadc)
 164 {
 165         u8 mode, sta1, chan, dig, en, req;
 166         int ret;
 167 
 168         ret = iadc_read(iadc, IADC_MODE_CTL, &mode);
 169         if (ret < 0)
 170                 return;
 171 
 172         ret = iadc_read(iadc, IADC_DIG_PARAM, &dig);
 173         if (ret < 0)
 174                 return;
 175 
 176         ret = iadc_read(iadc, IADC_CH_SEL_CTL, &chan);
 177         if (ret < 0)
 178                 return;
 179 
 180         ret = iadc_read(iadc, IADC_CONV_REQ, &req);
 181         if (ret < 0)
 182                 return;
 183 
 184         ret = iadc_read(iadc, IADC_STATUS1, &sta1);
 185         if (ret < 0)
 186                 return;
 187 
 188         ret = iadc_read(iadc, IADC_EN_CTL1, &en);
 189         if (ret < 0)
 190                 return;
 191 
 192         dev_err(iadc->dev,
 193                 "mode:%02x en:%02x chan:%02x dig:%02x req:%02x sta1:%02x\n",
 194                 mode, en, chan, dig, req, sta1);
 195 }
 196 
 197 static int iadc_configure(struct iadc_chip *iadc, int channel)
 198 {
 199         u8 decim, mode;
 200         int ret;
 201 
 202         /* Mode selection */
 203         mode = (IADC_OP_MODE_NORMAL << IADC_OP_MODE_SHIFT) | IADC_TRIM_EN;
 204         ret = iadc_write(iadc, IADC_MODE_CTL, mode);
 205         if (ret < 0)
 206                 return ret;
 207 
 208         /* Channel selection */
 209         ret = iadc_write(iadc, IADC_CH_SEL_CTL, channel);
 210         if (ret < 0)
 211                 return ret;
 212 
 213         /* Digital parameter setup */
 214         decim = IADC_DEF_DECIMATION << IADC_DIG_DEC_RATIO_SEL_SHIFT;
 215         ret = iadc_write(iadc, IADC_DIG_PARAM, decim);
 216         if (ret < 0)
 217                 return ret;
 218 
 219         /* HW settle time delay */
 220         ret = iadc_write(iadc, IADC_HW_SETTLE_DELAY, IADC_DEF_HW_SETTLE_TIME);
 221         if (ret < 0)
 222                 return ret;
 223 
 224         ret = iadc_write(iadc, IADC_FAST_AVG_CTL, IADC_DEF_AVG_SAMPLES);
 225         if (ret < 0)
 226                 return ret;
 227 
 228         if (IADC_DEF_AVG_SAMPLES)
 229                 ret = iadc_write(iadc, IADC_FAST_AVG_EN, IADC_FAST_AVG_EN_SET);
 230         else
 231                 ret = iadc_write(iadc, IADC_FAST_AVG_EN, 0);
 232 
 233         if (ret < 0)
 234                 return ret;
 235 
 236         if (!iadc->poll_eoc)
 237                 reinit_completion(&iadc->complete);
 238 
 239         ret = iadc_set_state(iadc, true);
 240         if (ret < 0)
 241                 return ret;
 242 
 243         /* Request conversion */
 244         return iadc_write(iadc, IADC_CONV_REQ, IADC_CONV_REQ_SET);
 245 }
 246 
 247 static int iadc_poll_wait_eoc(struct iadc_chip *iadc, unsigned int interval_us)
 248 {
 249         unsigned int count, retry;
 250         int ret;
 251         u8 sta1;
 252 
 253         retry = interval_us / IADC_CONV_TIME_MIN_US;
 254 
 255         for (count = 0; count < retry; count++) {
 256                 ret = iadc_read(iadc, IADC_STATUS1, &sta1);
 257                 if (ret < 0)
 258                         return ret;
 259 
 260                 sta1 &= IADC_STATUS1_REQ_STS_EOC_MASK;
 261                 if (sta1 == IADC_STATUS1_EOC)
 262                         return 0;
 263 
 264                 usleep_range(IADC_CONV_TIME_MIN_US, IADC_CONV_TIME_MAX_US);
 265         }
 266 
 267         iadc_status_show(iadc);
 268 
 269         return -ETIMEDOUT;
 270 }
 271 
 272 static int iadc_read_result(struct iadc_chip *iadc, u16 *data)
 273 {
 274         return regmap_bulk_read(iadc->regmap, iadc->base + IADC_DATA, data, 2);
 275 }
 276 
 277 static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data)
 278 {
 279         unsigned int wait;
 280         int ret;
 281 
 282         ret = iadc_configure(iadc, chan);
 283         if (ret < 0)
 284                 goto exit;
 285 
 286         wait = BIT(IADC_DEF_AVG_SAMPLES) * IADC_CONV_TIME_MIN_US * 2;
 287 
 288         if (iadc->poll_eoc) {
 289                 ret = iadc_poll_wait_eoc(iadc, wait);
 290         } else {
 291                 ret = wait_for_completion_timeout(&iadc->complete,
 292                         usecs_to_jiffies(wait));
 293                 if (!ret)
 294                         ret = -ETIMEDOUT;
 295                 else
 296                         /* double check conversion status */
 297                         ret = iadc_poll_wait_eoc(iadc, IADC_CONV_TIME_MIN_US);
 298         }
 299 
 300         if (!ret)
 301                 ret = iadc_read_result(iadc, data);
 302 exit:
 303         iadc_set_state(iadc, false);
 304         if (ret < 0)
 305                 dev_err(iadc->dev, "conversion failed\n");
 306 
 307         return ret;
 308 }
 309 
 310 static int iadc_read_raw(struct iio_dev *indio_dev,
 311                          struct iio_chan_spec const *chan,
 312                          int *val, int *val2, long mask)
 313 {
 314         struct iadc_chip *iadc = iio_priv(indio_dev);
 315         s32 isense_ua, vsense_uv;
 316         u16 adc_raw, vsense_raw;
 317         int ret;
 318 
 319         switch (mask) {
 320         case IIO_CHAN_INFO_RAW:
 321                 mutex_lock(&iadc->lock);
 322                 ret = iadc_do_conversion(iadc, chan->channel, &adc_raw);
 323                 mutex_unlock(&iadc->lock);
 324                 if (ret < 0)
 325                         return ret;
 326 
 327                 vsense_raw = adc_raw - iadc->offset[chan->channel];
 328 
 329                 vsense_uv = vsense_raw * IADC_REF_GAIN_MICRO_VOLTS;
 330                 vsense_uv /= (s32)iadc->gain - iadc->offset[chan->channel];
 331 
 332                 isense_ua = vsense_uv / iadc->rsense[chan->channel];
 333 
 334                 dev_dbg(iadc->dev, "off %d gain %d adc %d %duV I %duA\n",
 335                         iadc->offset[chan->channel], iadc->gain,
 336                         adc_raw, vsense_uv, isense_ua);
 337 
 338                 *val = isense_ua;
 339                 return IIO_VAL_INT;
 340         case IIO_CHAN_INFO_SCALE:
 341                 *val = 0;
 342                 *val2 = 1000;
 343                 return IIO_VAL_INT_PLUS_MICRO;
 344         }
 345 
 346         return -EINVAL;
 347 }
 348 
 349 static const struct iio_info iadc_info = {
 350         .read_raw = iadc_read_raw,
 351 };
 352 
 353 static irqreturn_t iadc_isr(int irq, void *dev_id)
 354 {
 355         struct iadc_chip *iadc = dev_id;
 356 
 357         complete(&iadc->complete);
 358 
 359         return IRQ_HANDLED;
 360 }
 361 
 362 static int iadc_update_offset(struct iadc_chip *iadc)
 363 {
 364         int ret;
 365 
 366         ret = iadc_do_conversion(iadc, IADC_GAIN_17P857MV, &iadc->gain);
 367         if (ret < 0)
 368                 return ret;
 369 
 370         ret = iadc_do_conversion(iadc, IADC_INT_OFFSET_CSP2_CSN2,
 371                                  &iadc->offset[IADC_INT_RSENSE]);
 372         if (ret < 0)
 373                 return ret;
 374 
 375         if (iadc->gain == iadc->offset[IADC_INT_RSENSE]) {
 376                 dev_err(iadc->dev, "error: internal offset == gain %d\n",
 377                         iadc->gain);
 378                 return -EINVAL;
 379         }
 380 
 381         ret = iadc_do_conversion(iadc, IADC_EXT_OFFSET_CSP_CSN,
 382                                  &iadc->offset[IADC_EXT_RSENSE]);
 383         if (ret < 0)
 384                 return ret;
 385 
 386         if (iadc->gain == iadc->offset[IADC_EXT_RSENSE]) {
 387                 dev_err(iadc->dev, "error: external offset == gain %d\n",
 388                         iadc->gain);
 389                 return -EINVAL;
 390         }
 391 
 392         return 0;
 393 }
 394 
 395 static int iadc_version_check(struct iadc_chip *iadc)
 396 {
 397         u8 val;
 398         int ret;
 399 
 400         ret = iadc_read(iadc, IADC_PERPH_TYPE, &val);
 401         if (ret < 0)
 402                 return ret;
 403 
 404         if (val < IADC_PERPH_TYPE_ADC) {
 405                 dev_err(iadc->dev, "%d is not ADC\n", val);
 406                 return -EINVAL;
 407         }
 408 
 409         ret = iadc_read(iadc, IADC_PERPH_SUBTYPE, &val);
 410         if (ret < 0)
 411                 return ret;
 412 
 413         if (val < IADC_PERPH_SUBTYPE_IADC) {
 414                 dev_err(iadc->dev, "%d is not IADC\n", val);
 415                 return -EINVAL;
 416         }
 417 
 418         ret = iadc_read(iadc, IADC_REVISION2, &val);
 419         if (ret < 0)
 420                 return ret;
 421 
 422         if (val < IADC_REVISION2_SUPPORTED_IADC) {
 423                 dev_err(iadc->dev, "revision %d not supported\n", val);
 424                 return -EINVAL;
 425         }
 426 
 427         return 0;
 428 }
 429 
 430 static int iadc_rsense_read(struct iadc_chip *iadc, struct device_node *node)
 431 {
 432         int ret, sign, int_sense;
 433         u8 deviation;
 434 
 435         ret = of_property_read_u32(node, "qcom,external-resistor-micro-ohms",
 436                                    &iadc->rsense[IADC_EXT_RSENSE]);
 437         if (ret < 0)
 438                 iadc->rsense[IADC_EXT_RSENSE] = IADC_INT_RSENSE_IDEAL_VALUE;
 439 
 440         if (!iadc->rsense[IADC_EXT_RSENSE]) {
 441                 dev_err(iadc->dev, "external resistor can't be zero Ohms");
 442                 return -EINVAL;
 443         }
 444 
 445         ret = iadc_read(iadc, IADC_NOMINAL_RSENSE, &deviation);
 446         if (ret < 0)
 447                 return ret;
 448 
 449         /*
 450          * Deviation value stored is an offset from 10 mili Ohms, bit 7 is
 451          * the sign, the remaining bits have an LSB of 15625 nano Ohms.
 452          */
 453         sign = (deviation & IADC_NOMINAL_RSENSE_SIGN_MASK) ? -1 : 1;
 454 
 455         deviation &= ~IADC_NOMINAL_RSENSE_SIGN_MASK;
 456 
 457         /* Scale it to nono Ohms */
 458         int_sense = IADC_INT_RSENSE_IDEAL_VALUE * 1000;
 459         int_sense += sign * deviation * IADC_INT_RSENSE_DEVIATION;
 460         int_sense /= 1000; /* micro Ohms */
 461 
 462         iadc->rsense[IADC_INT_RSENSE] = int_sense;
 463         return 0;
 464 }
 465 
 466 static const struct iio_chan_spec iadc_channels[] = {
 467         {
 468                 .type = IIO_CURRENT,
 469                 .datasheet_name = "INTERNAL_RSENSE",
 470                 .channel = 0,
 471                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 472                                       BIT(IIO_CHAN_INFO_SCALE),
 473                 .indexed = 1,
 474         },
 475         {
 476                 .type = IIO_CURRENT,
 477                 .datasheet_name = "EXTERNAL_RSENSE",
 478                 .channel = 1,
 479                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 480                                       BIT(IIO_CHAN_INFO_SCALE),
 481                 .indexed = 1,
 482         },
 483 };
 484 
 485 static int iadc_probe(struct platform_device *pdev)
 486 {
 487         struct device_node *node = pdev->dev.of_node;
 488         struct device *dev = &pdev->dev;
 489         struct iio_dev *indio_dev;
 490         struct iadc_chip *iadc;
 491         int ret, irq_eoc;
 492         u32 res;
 493 
 494         indio_dev = devm_iio_device_alloc(dev, sizeof(*iadc));
 495         if (!indio_dev)
 496                 return -ENOMEM;
 497 
 498         iadc = iio_priv(indio_dev);
 499         iadc->dev = dev;
 500 
 501         iadc->regmap = dev_get_regmap(dev->parent, NULL);
 502         if (!iadc->regmap)
 503                 return -ENODEV;
 504 
 505         init_completion(&iadc->complete);
 506         mutex_init(&iadc->lock);
 507 
 508         ret = of_property_read_u32(node, "reg", &res);
 509         if (ret < 0)
 510                 return -ENODEV;
 511 
 512         iadc->base = res;
 513 
 514         ret = iadc_version_check(iadc);
 515         if (ret < 0)
 516                 return -ENODEV;
 517 
 518         ret = iadc_rsense_read(iadc, node);
 519         if (ret < 0)
 520                 return -ENODEV;
 521 
 522         dev_dbg(iadc->dev, "sense resistors %d and %d micro Ohm\n",
 523                 iadc->rsense[IADC_INT_RSENSE],
 524                 iadc->rsense[IADC_EXT_RSENSE]);
 525 
 526         irq_eoc = platform_get_irq(pdev, 0);
 527         if (irq_eoc == -EPROBE_DEFER)
 528                 return irq_eoc;
 529 
 530         if (irq_eoc < 0)
 531                 iadc->poll_eoc = true;
 532 
 533         ret = iadc_reset(iadc);
 534         if (ret < 0) {
 535                 dev_err(dev, "reset failed\n");
 536                 return ret;
 537         }
 538 
 539         if (!iadc->poll_eoc) {
 540                 ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0,
 541                                         "spmi-iadc", iadc);
 542                 if (!ret)
 543                         enable_irq_wake(irq_eoc);
 544                 else
 545                         return ret;
 546         } else {
 547                 device_init_wakeup(iadc->dev, 1);
 548         }
 549 
 550         ret = iadc_update_offset(iadc);
 551         if (ret < 0) {
 552                 dev_err(dev, "failed offset calibration\n");
 553                 return ret;
 554         }
 555 
 556         indio_dev->dev.parent = dev;
 557         indio_dev->dev.of_node = node;
 558         indio_dev->name = pdev->name;
 559         indio_dev->modes = INDIO_DIRECT_MODE;
 560         indio_dev->info = &iadc_info;
 561         indio_dev->channels = iadc_channels;
 562         indio_dev->num_channels = ARRAY_SIZE(iadc_channels);
 563 
 564         return devm_iio_device_register(dev, indio_dev);
 565 }
 566 
 567 static const struct of_device_id iadc_match_table[] = {
 568         { .compatible = "qcom,spmi-iadc" },
 569         { }
 570 };
 571 
 572 MODULE_DEVICE_TABLE(of, iadc_match_table);
 573 
 574 static struct platform_driver iadc_driver = {
 575         .driver = {
 576                    .name = "qcom-spmi-iadc",
 577                    .of_match_table = iadc_match_table,
 578         },
 579         .probe = iadc_probe,
 580 };
 581 
 582 module_platform_driver(iadc_driver);
 583 
 584 MODULE_ALIAS("platform:qcom-spmi-iadc");
 585 MODULE_DESCRIPTION("Qualcomm SPMI PMIC current ADC driver");
 586 MODULE_LICENSE("GPL v2");
 587 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");

/* [<][>][^][v][top][bottom][index][help] */