linux/drivers/iio/adc/qcom-spmi-iadc.c
<<
>>
Prefs
   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 */
 106struct 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
 118static 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
 131static int iadc_write(struct iadc_chip *iadc, u16 offset, u8 data)
 132{
 133        return regmap_write(iadc->regmap, iadc->base + offset, data);
 134}
 135
 136static 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
 158static 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
 163static 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
 197static 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
 247static 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
 272static 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
 277static 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);
 302exit:
 303        iadc_set_state(iadc, false);
 304        if (ret < 0)
 305                dev_err(iadc->dev, "conversion failed\n");
 306
 307        return ret;
 308}
 309
 310static 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
 349static const struct iio_info iadc_info = {
 350        .read_raw = iadc_read_raw,
 351};
 352
 353static 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
 362static 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
 395static 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
 430static 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
 466static 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
 485static 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->name = pdev->name;
 557        indio_dev->modes = INDIO_DIRECT_MODE;
 558        indio_dev->info = &iadc_info;
 559        indio_dev->channels = iadc_channels;
 560        indio_dev->num_channels = ARRAY_SIZE(iadc_channels);
 561
 562        return devm_iio_device_register(dev, indio_dev);
 563}
 564
 565static const struct of_device_id iadc_match_table[] = {
 566        { .compatible = "qcom,spmi-iadc" },
 567        { }
 568};
 569
 570MODULE_DEVICE_TABLE(of, iadc_match_table);
 571
 572static struct platform_driver iadc_driver = {
 573        .driver = {
 574                   .name = "qcom-spmi-iadc",
 575                   .of_match_table = iadc_match_table,
 576        },
 577        .probe = iadc_probe,
 578};
 579
 580module_platform_driver(iadc_driver);
 581
 582MODULE_ALIAS("platform:qcom-spmi-iadc");
 583MODULE_DESCRIPTION("Qualcomm SPMI PMIC current ADC driver");
 584MODULE_LICENSE("GPL v2");
 585MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
 586