linux/drivers/iio/adc/axp20x_adc.c
<<
>>
Prefs
   1/* ADC driver for AXP20X and AXP22X PMICs
   2 *
   3 * Copyright (c) 2016 Free Electrons NextThing Co.
   4 *      Quentin Schulz <quentin.schulz@free-electrons.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify it under
   7 * the terms of the GNU General Public License version 2 as published by the
   8 * Free Software Foundation.
   9 */
  10
  11#include <linux/completion.h>
  12#include <linux/interrupt.h>
  13#include <linux/io.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/pm_runtime.h>
  19#include <linux/regmap.h>
  20#include <linux/thermal.h>
  21
  22#include <linux/iio/iio.h>
  23#include <linux/iio/driver.h>
  24#include <linux/iio/machine.h>
  25#include <linux/mfd/axp20x.h>
  26
  27#define AXP20X_ADC_EN1_MASK                     GENMASK(7, 0)
  28
  29#define AXP20X_ADC_EN2_MASK                     (GENMASK(3, 2) | BIT(7))
  30#define AXP22X_ADC_EN1_MASK                     (GENMASK(7, 5) | BIT(0))
  31
  32#define AXP20X_GPIO10_IN_RANGE_GPIO0            BIT(0)
  33#define AXP20X_GPIO10_IN_RANGE_GPIO1            BIT(1)
  34#define AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(x)     ((x) & BIT(0))
  35#define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x)     (((x) & BIT(0)) << 1)
  36
  37#define AXP20X_ADC_RATE_MASK                    GENMASK(7, 6)
  38#define AXP813_V_I_ADC_RATE_MASK                GENMASK(5, 4)
  39#define AXP813_ADC_RATE_MASK                    (AXP20X_ADC_RATE_MASK | AXP813_V_I_ADC_RATE_MASK)
  40#define AXP20X_ADC_RATE_HZ(x)                   ((ilog2((x) / 25) << 6) & AXP20X_ADC_RATE_MASK)
  41#define AXP22X_ADC_RATE_HZ(x)                   ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK)
  42#define AXP813_TS_GPIO0_ADC_RATE_HZ(x)          AXP20X_ADC_RATE_HZ(x)
  43#define AXP813_V_I_ADC_RATE_HZ(x)               ((ilog2((x) / 100) << 4) & AXP813_V_I_ADC_RATE_MASK)
  44#define AXP813_ADC_RATE_HZ(x)                   (AXP20X_ADC_RATE_HZ(x) | AXP813_V_I_ADC_RATE_HZ(x))
  45
  46#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)        \
  47        {                                                       \
  48                .type = _type,                                  \
  49                .indexed = 1,                                   \
  50                .channel = _channel,                            \
  51                .address = _reg,                                \
  52                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
  53                                      BIT(IIO_CHAN_INFO_SCALE), \
  54                .datasheet_name = _name,                        \
  55        }
  56
  57#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
  58        {                                                       \
  59                .type = _type,                                  \
  60                .indexed = 1,                                   \
  61                .channel = _channel,                            \
  62                .address = _reg,                                \
  63                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
  64                                      BIT(IIO_CHAN_INFO_SCALE) |\
  65                                      BIT(IIO_CHAN_INFO_OFFSET),\
  66                .datasheet_name = _name,                        \
  67        }
  68
  69struct axp_data;
  70
  71struct axp20x_adc_iio {
  72        struct regmap           *regmap;
  73        struct axp_data         *data;
  74};
  75
  76enum axp20x_adc_channel_v {
  77        AXP20X_ACIN_V = 0,
  78        AXP20X_VBUS_V,
  79        AXP20X_TS_IN,
  80        AXP20X_GPIO0_V,
  81        AXP20X_GPIO1_V,
  82        AXP20X_IPSOUT_V,
  83        AXP20X_BATT_V,
  84};
  85
  86enum axp20x_adc_channel_i {
  87        AXP20X_ACIN_I = 0,
  88        AXP20X_VBUS_I,
  89        AXP20X_BATT_CHRG_I,
  90        AXP20X_BATT_DISCHRG_I,
  91};
  92
  93enum axp22x_adc_channel_v {
  94        AXP22X_TS_IN = 0,
  95        AXP22X_BATT_V,
  96};
  97
  98enum axp22x_adc_channel_i {
  99        AXP22X_BATT_CHRG_I = 1,
 100        AXP22X_BATT_DISCHRG_I,
 101};
 102
 103enum axp813_adc_channel_v {
 104        AXP813_TS_IN = 0,
 105        AXP813_GPIO0_V,
 106        AXP813_BATT_V,
 107};
 108
 109static struct iio_map axp20x_maps[] = {
 110        {
 111                .consumer_dev_name = "axp20x-usb-power-supply",
 112                .consumer_channel = "vbus_v",
 113                .adc_channel_label = "vbus_v",
 114        }, {
 115                .consumer_dev_name = "axp20x-usb-power-supply",
 116                .consumer_channel = "vbus_i",
 117                .adc_channel_label = "vbus_i",
 118        }, {
 119                .consumer_dev_name = "axp20x-ac-power-supply",
 120                .consumer_channel = "acin_v",
 121                .adc_channel_label = "acin_v",
 122        }, {
 123                .consumer_dev_name = "axp20x-ac-power-supply",
 124                .consumer_channel = "acin_i",
 125                .adc_channel_label = "acin_i",
 126        }, {
 127                .consumer_dev_name = "axp20x-battery-power-supply",
 128                .consumer_channel = "batt_v",
 129                .adc_channel_label = "batt_v",
 130        }, {
 131                .consumer_dev_name = "axp20x-battery-power-supply",
 132                .consumer_channel = "batt_chrg_i",
 133                .adc_channel_label = "batt_chrg_i",
 134        }, {
 135                .consumer_dev_name = "axp20x-battery-power-supply",
 136                .consumer_channel = "batt_dischrg_i",
 137                .adc_channel_label = "batt_dischrg_i",
 138        }, { /* sentinel */ }
 139};
 140
 141static struct iio_map axp22x_maps[] = {
 142        {
 143                .consumer_dev_name = "axp20x-battery-power-supply",
 144                .consumer_channel = "batt_v",
 145                .adc_channel_label = "batt_v",
 146        }, {
 147                .consumer_dev_name = "axp20x-battery-power-supply",
 148                .consumer_channel = "batt_chrg_i",
 149                .adc_channel_label = "batt_chrg_i",
 150        }, {
 151                .consumer_dev_name = "axp20x-battery-power-supply",
 152                .consumer_channel = "batt_dischrg_i",
 153                .adc_channel_label = "batt_dischrg_i",
 154        }, { /* sentinel */ }
 155};
 156
 157/*
 158 * Channels are mapped by physical system. Their channels share the same index.
 159 * i.e. acin_i is in_current0_raw and acin_v is in_voltage0_raw.
 160 * The only exception is for the battery. batt_v will be in_voltage6_raw and
 161 * charge current in_current6_raw and discharge current will be in_current7_raw.
 162 */
 163static const struct iio_chan_spec axp20x_adc_channels[] = {
 164        AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,
 165                           AXP20X_ACIN_V_ADC_H),
 166        AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,
 167                           AXP20X_ACIN_I_ADC_H),
 168        AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,
 169                           AXP20X_VBUS_V_ADC_H),
 170        AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,
 171                           AXP20X_VBUS_I_ADC_H),
 172        {
 173                .type = IIO_TEMP,
 174                .address = AXP20X_TEMP_ADC_H,
 175                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 176                                      BIT(IIO_CHAN_INFO_SCALE) |
 177                                      BIT(IIO_CHAN_INFO_OFFSET),
 178                .datasheet_name = "pmic_temp",
 179        },
 180        AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,
 181                                  AXP20X_GPIO0_V_ADC_H),
 182        AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,
 183                                  AXP20X_GPIO1_V_ADC_H),
 184        AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,
 185                           AXP20X_IPSOUT_V_HIGH_H),
 186        AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,
 187                           AXP20X_BATT_V_H),
 188        AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
 189                           AXP20X_BATT_CHRG_I_H),
 190        AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
 191                           AXP20X_BATT_DISCHRG_I_H),
 192};
 193
 194static const struct iio_chan_spec axp22x_adc_channels[] = {
 195        {
 196                .type = IIO_TEMP,
 197                .address = AXP22X_PMIC_TEMP_H,
 198                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 199                                      BIT(IIO_CHAN_INFO_SCALE) |
 200                                      BIT(IIO_CHAN_INFO_OFFSET),
 201                .datasheet_name = "pmic_temp",
 202        },
 203        AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,
 204                           AXP20X_BATT_V_H),
 205        AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
 206                           AXP20X_BATT_CHRG_I_H),
 207        AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
 208                           AXP20X_BATT_DISCHRG_I_H),
 209};
 210
 211static const struct iio_chan_spec axp813_adc_channels[] = {
 212        {
 213                .type = IIO_TEMP,
 214                .address = AXP22X_PMIC_TEMP_H,
 215                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 216                                      BIT(IIO_CHAN_INFO_SCALE) |
 217                                      BIT(IIO_CHAN_INFO_OFFSET),
 218                .datasheet_name = "pmic_temp",
 219        },
 220        AXP20X_ADC_CHANNEL(AXP813_GPIO0_V, "gpio0_v", IIO_VOLTAGE,
 221                           AXP288_GP_ADC_H),
 222        AXP20X_ADC_CHANNEL(AXP813_BATT_V, "batt_v", IIO_VOLTAGE,
 223                           AXP20X_BATT_V_H),
 224        AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
 225                           AXP20X_BATT_CHRG_I_H),
 226        AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
 227                           AXP20X_BATT_DISCHRG_I_H),
 228};
 229
 230static int axp20x_adc_raw(struct iio_dev *indio_dev,
 231                          struct iio_chan_spec const *chan, int *val)
 232{
 233        struct axp20x_adc_iio *info = iio_priv(indio_dev);
 234        int size = 12;
 235
 236        /*
 237         * N.B.:  Unlike the Chinese datasheets tell, the charging current is
 238         * stored on 12 bits, not 13 bits. Only discharging current is on 13
 239         * bits.
 240         */
 241        if (chan->type == IIO_CURRENT && chan->channel == AXP20X_BATT_DISCHRG_I)
 242                size = 13;
 243        else
 244                size = 12;
 245
 246        *val = axp20x_read_variable_width(info->regmap, chan->address, size);
 247        if (*val < 0)
 248                return *val;
 249
 250        return IIO_VAL_INT;
 251}
 252
 253static int axp22x_adc_raw(struct iio_dev *indio_dev,
 254                          struct iio_chan_spec const *chan, int *val)
 255{
 256        struct axp20x_adc_iio *info = iio_priv(indio_dev);
 257        int size;
 258
 259        /*
 260         * N.B.: Unlike the Chinese datasheets tell, the charging current is
 261         * stored on 12 bits, not 13 bits. Only discharging current is on 13
 262         * bits.
 263         */
 264        if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I)
 265                size = 13;
 266        else
 267                size = 12;
 268
 269        *val = axp20x_read_variable_width(info->regmap, chan->address, size);
 270        if (*val < 0)
 271                return *val;
 272
 273        return IIO_VAL_INT;
 274}
 275
 276static int axp813_adc_raw(struct iio_dev *indio_dev,
 277                          struct iio_chan_spec const *chan, int *val)
 278{
 279        struct axp20x_adc_iio *info = iio_priv(indio_dev);
 280
 281        *val = axp20x_read_variable_width(info->regmap, chan->address, 12);
 282        if (*val < 0)
 283                return *val;
 284
 285        return IIO_VAL_INT;
 286}
 287
 288static int axp20x_adc_scale_voltage(int channel, int *val, int *val2)
 289{
 290        switch (channel) {
 291        case AXP20X_ACIN_V:
 292        case AXP20X_VBUS_V:
 293                *val = 1;
 294                *val2 = 700000;
 295                return IIO_VAL_INT_PLUS_MICRO;
 296
 297        case AXP20X_GPIO0_V:
 298        case AXP20X_GPIO1_V:
 299                *val = 0;
 300                *val2 = 500000;
 301                return IIO_VAL_INT_PLUS_MICRO;
 302
 303        case AXP20X_BATT_V:
 304                *val = 1;
 305                *val2 = 100000;
 306                return IIO_VAL_INT_PLUS_MICRO;
 307
 308        case AXP20X_IPSOUT_V:
 309                *val = 1;
 310                *val2 = 400000;
 311                return IIO_VAL_INT_PLUS_MICRO;
 312
 313        default:
 314                return -EINVAL;
 315        }
 316}
 317
 318static int axp813_adc_scale_voltage(int channel, int *val, int *val2)
 319{
 320        switch (channel) {
 321        case AXP813_GPIO0_V:
 322                *val = 0;
 323                *val2 = 800000;
 324                return IIO_VAL_INT_PLUS_MICRO;
 325
 326        case AXP813_BATT_V:
 327                *val = 1;
 328                *val2 = 100000;
 329                return IIO_VAL_INT_PLUS_MICRO;
 330
 331        default:
 332                return -EINVAL;
 333        }
 334}
 335
 336static int axp20x_adc_scale_current(int channel, int *val, int *val2)
 337{
 338        switch (channel) {
 339        case AXP20X_ACIN_I:
 340                *val = 0;
 341                *val2 = 625000;
 342                return IIO_VAL_INT_PLUS_MICRO;
 343
 344        case AXP20X_VBUS_I:
 345                *val = 0;
 346                *val2 = 375000;
 347                return IIO_VAL_INT_PLUS_MICRO;
 348
 349        case AXP20X_BATT_DISCHRG_I:
 350        case AXP20X_BATT_CHRG_I:
 351                *val = 0;
 352                *val2 = 500000;
 353                return IIO_VAL_INT_PLUS_MICRO;
 354
 355        default:
 356                return -EINVAL;
 357        }
 358}
 359
 360static int axp20x_adc_scale(struct iio_chan_spec const *chan, int *val,
 361                            int *val2)
 362{
 363        switch (chan->type) {
 364        case IIO_VOLTAGE:
 365                return axp20x_adc_scale_voltage(chan->channel, val, val2);
 366
 367        case IIO_CURRENT:
 368                return axp20x_adc_scale_current(chan->channel, val, val2);
 369
 370        case IIO_TEMP:
 371                *val = 100;
 372                return IIO_VAL_INT;
 373
 374        default:
 375                return -EINVAL;
 376        }
 377}
 378
 379static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
 380                            int *val2)
 381{
 382        switch (chan->type) {
 383        case IIO_VOLTAGE:
 384                if (chan->channel != AXP22X_BATT_V)
 385                        return -EINVAL;
 386
 387                *val = 1;
 388                *val2 = 100000;
 389                return IIO_VAL_INT_PLUS_MICRO;
 390
 391        case IIO_CURRENT:
 392                *val = 0;
 393                *val2 = 500000;
 394                return IIO_VAL_INT_PLUS_MICRO;
 395
 396        case IIO_TEMP:
 397                *val = 100;
 398                return IIO_VAL_INT;
 399
 400        default:
 401                return -EINVAL;
 402        }
 403}
 404
 405static int axp813_adc_scale(struct iio_chan_spec const *chan, int *val,
 406                            int *val2)
 407{
 408        switch (chan->type) {
 409        case IIO_VOLTAGE:
 410                return axp813_adc_scale_voltage(chan->channel, val, val2);
 411
 412        case IIO_CURRENT:
 413                *val = 1;
 414                return IIO_VAL_INT;
 415
 416        case IIO_TEMP:
 417                *val = 100;
 418                return IIO_VAL_INT;
 419
 420        default:
 421                return -EINVAL;
 422        }
 423}
 424
 425static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel,
 426                                     int *val)
 427{
 428        struct axp20x_adc_iio *info = iio_priv(indio_dev);
 429        int ret;
 430
 431        ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, val);
 432        if (ret < 0)
 433                return ret;
 434
 435        switch (channel) {
 436        case AXP20X_GPIO0_V:
 437                *val &= AXP20X_GPIO10_IN_RANGE_GPIO0;
 438                break;
 439
 440        case AXP20X_GPIO1_V:
 441                *val &= AXP20X_GPIO10_IN_RANGE_GPIO1;
 442                break;
 443
 444        default:
 445                return -EINVAL;
 446        }
 447
 448        *val = *val ? 700000 : 0;
 449
 450        return IIO_VAL_INT;
 451}
 452
 453static int axp20x_adc_offset(struct iio_dev *indio_dev,
 454                             struct iio_chan_spec const *chan, int *val)
 455{
 456        switch (chan->type) {
 457        case IIO_VOLTAGE:
 458                return axp20x_adc_offset_voltage(indio_dev, chan->channel, val);
 459
 460        case IIO_TEMP:
 461                *val = -1447;
 462                return IIO_VAL_INT;
 463
 464        default:
 465                return -EINVAL;
 466        }
 467}
 468
 469static int axp20x_read_raw(struct iio_dev *indio_dev,
 470                           struct iio_chan_spec const *chan, int *val,
 471                           int *val2, long mask)
 472{
 473        switch (mask) {
 474        case IIO_CHAN_INFO_OFFSET:
 475                return axp20x_adc_offset(indio_dev, chan, val);
 476
 477        case IIO_CHAN_INFO_SCALE:
 478                return axp20x_adc_scale(chan, val, val2);
 479
 480        case IIO_CHAN_INFO_RAW:
 481                return axp20x_adc_raw(indio_dev, chan, val);
 482
 483        default:
 484                return -EINVAL;
 485        }
 486}
 487
 488static int axp22x_read_raw(struct iio_dev *indio_dev,
 489                           struct iio_chan_spec const *chan, int *val,
 490                           int *val2, long mask)
 491{
 492        switch (mask) {
 493        case IIO_CHAN_INFO_OFFSET:
 494                *val = -2677;
 495                return IIO_VAL_INT;
 496
 497        case IIO_CHAN_INFO_SCALE:
 498                return axp22x_adc_scale(chan, val, val2);
 499
 500        case IIO_CHAN_INFO_RAW:
 501                return axp22x_adc_raw(indio_dev, chan, val);
 502
 503        default:
 504                return -EINVAL;
 505        }
 506}
 507
 508static int axp813_read_raw(struct iio_dev *indio_dev,
 509                           struct iio_chan_spec const *chan, int *val,
 510                           int *val2, long mask)
 511{
 512        switch (mask) {
 513        case IIO_CHAN_INFO_OFFSET:
 514                *val = -2667;
 515                return IIO_VAL_INT;
 516
 517        case IIO_CHAN_INFO_SCALE:
 518                return axp813_adc_scale(chan, val, val2);
 519
 520        case IIO_CHAN_INFO_RAW:
 521                return axp813_adc_raw(indio_dev, chan, val);
 522
 523        default:
 524                return -EINVAL;
 525        }
 526}
 527
 528static int axp20x_write_raw(struct iio_dev *indio_dev,
 529                            struct iio_chan_spec const *chan, int val, int val2,
 530                            long mask)
 531{
 532        struct axp20x_adc_iio *info = iio_priv(indio_dev);
 533        unsigned int reg, regval;
 534
 535        /*
 536         * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets
 537         * for (independently) GPIO0 and GPIO1 when in ADC mode.
 538         */
 539        if (mask != IIO_CHAN_INFO_OFFSET)
 540                return -EINVAL;
 541
 542        if (val != 0 && val != 700000)
 543                return -EINVAL;
 544
 545        val = val ? 1 : 0;
 546
 547        switch (chan->channel) {
 548        case AXP20X_GPIO0_V:
 549                reg = AXP20X_GPIO10_IN_RANGE_GPIO0;
 550                regval = AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(val);
 551                break;
 552
 553        case AXP20X_GPIO1_V:
 554                reg = AXP20X_GPIO10_IN_RANGE_GPIO1;
 555                regval = AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(val);
 556                break;
 557
 558        default:
 559                return -EINVAL;
 560        }
 561
 562        return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE, reg,
 563                                  regval);
 564}
 565
 566static const struct iio_info axp20x_adc_iio_info = {
 567        .read_raw = axp20x_read_raw,
 568        .write_raw = axp20x_write_raw,
 569};
 570
 571static const struct iio_info axp22x_adc_iio_info = {
 572        .read_raw = axp22x_read_raw,
 573};
 574
 575static const struct iio_info axp813_adc_iio_info = {
 576        .read_raw = axp813_read_raw,
 577};
 578
 579static int axp20x_adc_rate(struct axp20x_adc_iio *info, int rate)
 580{
 581        return regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
 582                                  AXP20X_ADC_RATE_MASK,
 583                                  AXP20X_ADC_RATE_HZ(rate));
 584}
 585
 586static int axp22x_adc_rate(struct axp20x_adc_iio *info, int rate)
 587{
 588        return regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
 589                                  AXP20X_ADC_RATE_MASK,
 590                                  AXP22X_ADC_RATE_HZ(rate));
 591}
 592
 593static int axp813_adc_rate(struct axp20x_adc_iio *info, int rate)
 594{
 595        return regmap_update_bits(info->regmap, AXP813_ADC_RATE,
 596                                 AXP813_ADC_RATE_MASK,
 597                                 AXP813_ADC_RATE_HZ(rate));
 598}
 599
 600struct axp_data {
 601        const struct iio_info           *iio_info;
 602        int                             num_channels;
 603        struct iio_chan_spec const      *channels;
 604        unsigned long                   adc_en1_mask;
 605        int                             (*adc_rate)(struct axp20x_adc_iio *info,
 606                                                    int rate);
 607        bool                            adc_en2;
 608        struct iio_map                  *maps;
 609};
 610
 611static const struct axp_data axp20x_data = {
 612        .iio_info = &axp20x_adc_iio_info,
 613        .num_channels = ARRAY_SIZE(axp20x_adc_channels),
 614        .channels = axp20x_adc_channels,
 615        .adc_en1_mask = AXP20X_ADC_EN1_MASK,
 616        .adc_rate = axp20x_adc_rate,
 617        .adc_en2 = true,
 618        .maps = axp20x_maps,
 619};
 620
 621static const struct axp_data axp22x_data = {
 622        .iio_info = &axp22x_adc_iio_info,
 623        .num_channels = ARRAY_SIZE(axp22x_adc_channels),
 624        .channels = axp22x_adc_channels,
 625        .adc_en1_mask = AXP22X_ADC_EN1_MASK,
 626        .adc_rate = axp22x_adc_rate,
 627        .adc_en2 = false,
 628        .maps = axp22x_maps,
 629};
 630
 631static const struct axp_data axp813_data = {
 632        .iio_info = &axp813_adc_iio_info,
 633        .num_channels = ARRAY_SIZE(axp813_adc_channels),
 634        .channels = axp813_adc_channels,
 635        .adc_en1_mask = AXP22X_ADC_EN1_MASK,
 636        .adc_rate = axp813_adc_rate,
 637        .adc_en2 = false,
 638        .maps = axp22x_maps,
 639};
 640
 641static const struct of_device_id axp20x_adc_of_match[] = {
 642        { .compatible = "x-powers,axp209-adc", .data = (void *)&axp20x_data, },
 643        { .compatible = "x-powers,axp221-adc", .data = (void *)&axp22x_data, },
 644        { .compatible = "x-powers,axp813-adc", .data = (void *)&axp813_data, },
 645        { /* sentinel */ }
 646};
 647MODULE_DEVICE_TABLE(of, axp20x_adc_of_match);
 648
 649static const struct platform_device_id axp20x_adc_id_match[] = {
 650        { .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, },
 651        { .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, },
 652        { .name = "axp813-adc", .driver_data = (kernel_ulong_t)&axp813_data, },
 653        { /* sentinel */ },
 654};
 655MODULE_DEVICE_TABLE(platform, axp20x_adc_id_match);
 656
 657static int axp20x_probe(struct platform_device *pdev)
 658{
 659        struct axp20x_adc_iio *info;
 660        struct iio_dev *indio_dev;
 661        struct axp20x_dev *axp20x_dev;
 662        int ret;
 663
 664        axp20x_dev = dev_get_drvdata(pdev->dev.parent);
 665
 666        indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
 667        if (!indio_dev)
 668                return -ENOMEM;
 669
 670        info = iio_priv(indio_dev);
 671        platform_set_drvdata(pdev, indio_dev);
 672
 673        info->regmap = axp20x_dev->regmap;
 674        indio_dev->dev.parent = &pdev->dev;
 675        indio_dev->dev.of_node = pdev->dev.of_node;
 676        indio_dev->modes = INDIO_DIRECT_MODE;
 677
 678        if (!pdev->dev.of_node) {
 679                const struct platform_device_id *id;
 680
 681                id = platform_get_device_id(pdev);
 682                info->data = (struct axp_data *)id->driver_data;
 683        } else {
 684                struct device *dev = &pdev->dev;
 685
 686                info->data = (struct axp_data *)of_device_get_match_data(dev);
 687        }
 688
 689        indio_dev->name = platform_get_device_id(pdev)->name;
 690        indio_dev->info = info->data->iio_info;
 691        indio_dev->num_channels = info->data->num_channels;
 692        indio_dev->channels = info->data->channels;
 693
 694        /* Enable the ADCs on IP */
 695        regmap_write(info->regmap, AXP20X_ADC_EN1, info->data->adc_en1_mask);
 696
 697        if (info->data->adc_en2)
 698                /* Enable GPIO0/1 and internal temperature ADCs */
 699                regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
 700                                   AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
 701
 702        /* Configure ADCs rate */
 703        info->data->adc_rate(info, 100);
 704
 705        ret = iio_map_array_register(indio_dev, info->data->maps);
 706        if (ret < 0) {
 707                dev_err(&pdev->dev, "failed to register IIO maps: %d\n", ret);
 708                goto fail_map;
 709        }
 710
 711        ret = iio_device_register(indio_dev);
 712        if (ret < 0) {
 713                dev_err(&pdev->dev, "could not register the device\n");
 714                goto fail_register;
 715        }
 716
 717        return 0;
 718
 719fail_register:
 720        iio_map_array_unregister(indio_dev);
 721
 722fail_map:
 723        regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
 724
 725        if (info->data->adc_en2)
 726                regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
 727
 728        return ret;
 729}
 730
 731static int axp20x_remove(struct platform_device *pdev)
 732{
 733        struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 734        struct axp20x_adc_iio *info = iio_priv(indio_dev);
 735
 736        iio_device_unregister(indio_dev);
 737        iio_map_array_unregister(indio_dev);
 738
 739        regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
 740
 741        if (info->data->adc_en2)
 742                regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
 743
 744        return 0;
 745}
 746
 747static struct platform_driver axp20x_adc_driver = {
 748        .driver = {
 749                .name = "axp20x-adc",
 750                .of_match_table = of_match_ptr(axp20x_adc_of_match),
 751        },
 752        .id_table = axp20x_adc_id_match,
 753        .probe = axp20x_probe,
 754        .remove = axp20x_remove,
 755};
 756
 757module_platform_driver(axp20x_adc_driver);
 758
 759MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
 760MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
 761MODULE_LICENSE("GPL");
 762