1223 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* ADC driver for AXP20X and AXP22X PMICs3 *4 * Copyright (c) 2016 Free Electrons NextThing Co.5 * Quentin Schulz <quentin.schulz@free-electrons.com>6 */7 8#include <linux/unaligned.h>9#include <linux/bitfield.h>10#include <linux/completion.h>11#include <linux/interrupt.h>12#include <linux/io.h>13#include <linux/module.h>14#include <linux/mod_devicetable.h>15#include <linux/platform_device.h>16#include <linux/pm_runtime.h>17#include <linux/property.h>18#include <linux/regmap.h>19#include <linux/thermal.h>20 21#include <linux/iio/iio.h>22#include <linux/iio/driver.h>23#include <linux/iio/machine.h>24#include <linux/mfd/axp20x.h>25 26#define AXP192_ADC_EN1_MASK GENMASK(7, 0)27#define AXP192_ADC_EN2_MASK (GENMASK(3, 0) | BIT(7))28 29#define AXP20X_ADC_EN1_MASK GENMASK(7, 0)30#define AXP20X_ADC_EN2_MASK (GENMASK(3, 2) | BIT(7))31 32#define AXP22X_ADC_EN1_MASK (GENMASK(7, 5) | BIT(0))33 34#define AXP717_ADC_EN1_MASK GENMASK(7, 0)35 36#define AXP192_GPIO30_IN_RANGE_GPIO0 BIT(0)37#define AXP192_GPIO30_IN_RANGE_GPIO1 BIT(1)38#define AXP192_GPIO30_IN_RANGE_GPIO2 BIT(2)39#define AXP192_GPIO30_IN_RANGE_GPIO3 BIT(3)40 41#define AXP20X_GPIO10_IN_RANGE_GPIO0 BIT(0)42#define AXP20X_GPIO10_IN_RANGE_GPIO1 BIT(1)43 44#define AXP20X_ADC_RATE_MASK GENMASK(7, 6)45#define AXP20X_ADC_RATE_HZ(x) ((ilog2((x) / 25) << 6) & AXP20X_ADC_RATE_MASK)46 47#define AXP22X_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK)48 49#define AXP717_ADC_DATA_TS 0x0050#define AXP717_ADC_DATA_TEMP 0x0151#define AXP717_ADC_DATA_VMID 0x0252#define AXP717_ADC_DATA_BKUP_BATT 0x0353 54#define AXP717_ADC_DATA_MASK GENMASK(13, 0)55 56#define AXP813_V_I_ADC_RATE_MASK GENMASK(5, 4)57#define AXP813_ADC_RATE_MASK (AXP20X_ADC_RATE_MASK | AXP813_V_I_ADC_RATE_MASK)58#define AXP813_TS_GPIO0_ADC_RATE_HZ(x) AXP20X_ADC_RATE_HZ(x)59#define AXP813_V_I_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 4) & AXP813_V_I_ADC_RATE_MASK)60#define AXP813_ADC_RATE_HZ(x) (AXP20X_ADC_RATE_HZ(x) | AXP813_V_I_ADC_RATE_HZ(x))61 62#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg) \63 { \64 .type = _type, \65 .indexed = 1, \66 .channel = _channel, \67 .address = _reg, \68 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \69 BIT(IIO_CHAN_INFO_SCALE), \70 .datasheet_name = _name, \71 }72 73#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \74 { \75 .type = _type, \76 .indexed = 1, \77 .channel = _channel, \78 .address = _reg, \79 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \80 BIT(IIO_CHAN_INFO_SCALE) |\81 BIT(IIO_CHAN_INFO_OFFSET),\82 .datasheet_name = _name, \83 }84 85struct axp_data;86 87struct axp20x_adc_iio {88 struct regmap *regmap;89 const struct axp_data *data;90};91 92enum axp192_adc_channel_v {93 AXP192_ACIN_V = 0,94 AXP192_VBUS_V,95 AXP192_TS_IN,96 AXP192_GPIO0_V,97 AXP192_GPIO1_V,98 AXP192_GPIO2_V,99 AXP192_GPIO3_V,100 AXP192_IPSOUT_V,101 AXP192_BATT_V,102};103 104enum axp192_adc_channel_i {105 AXP192_ACIN_I = 0,106 AXP192_VBUS_I,107 AXP192_BATT_CHRG_I,108 AXP192_BATT_DISCHRG_I,109};110 111enum axp20x_adc_channel_v {112 AXP20X_ACIN_V = 0,113 AXP20X_VBUS_V,114 AXP20X_TS_IN,115 AXP20X_GPIO0_V,116 AXP20X_GPIO1_V,117 AXP20X_IPSOUT_V,118 AXP20X_BATT_V,119};120 121enum axp20x_adc_channel_i {122 AXP20X_ACIN_I = 0,123 AXP20X_VBUS_I,124 AXP20X_BATT_CHRG_I,125 AXP20X_BATT_DISCHRG_I,126};127 128enum axp22x_adc_channel_v {129 AXP22X_TS_IN = 0,130 AXP22X_BATT_V,131};132 133enum axp22x_adc_channel_i {134 AXP22X_BATT_CHRG_I = 1,135 AXP22X_BATT_DISCHRG_I,136};137 138enum axp717_adc_channel_v {139 AXP717_BATT_V = 0,140 AXP717_TS_IN,141 AXP717_VBUS_V,142 AXP717_VSYS_V,143 AXP717_DIE_TEMP_V,144 AXP717_VMID_V = 6,145 AXP717_BKUP_BATT_V,146};147 148enum axp717_adc_channel_i {149 AXP717_BATT_CHRG_I = 5,150};151 152enum axp813_adc_channel_v {153 AXP813_TS_IN = 0,154 AXP813_GPIO0_V,155 AXP813_BATT_V,156};157 158static struct iio_map axp20x_maps[] = {159 {160 .consumer_dev_name = "axp20x-usb-power-supply",161 .consumer_channel = "vbus_v",162 .adc_channel_label = "vbus_v",163 }, {164 .consumer_dev_name = "axp20x-usb-power-supply",165 .consumer_channel = "vbus_i",166 .adc_channel_label = "vbus_i",167 }, {168 .consumer_dev_name = "axp20x-ac-power-supply",169 .consumer_channel = "acin_v",170 .adc_channel_label = "acin_v",171 }, {172 .consumer_dev_name = "axp20x-ac-power-supply",173 .consumer_channel = "acin_i",174 .adc_channel_label = "acin_i",175 }, {176 .consumer_dev_name = "axp20x-battery-power-supply",177 .consumer_channel = "batt_v",178 .adc_channel_label = "batt_v",179 }, {180 .consumer_dev_name = "axp20x-battery-power-supply",181 .consumer_channel = "batt_chrg_i",182 .adc_channel_label = "batt_chrg_i",183 }, {184 .consumer_dev_name = "axp20x-battery-power-supply",185 .consumer_channel = "batt_dischrg_i",186 .adc_channel_label = "batt_dischrg_i",187 }, { /* sentinel */ }188};189 190static struct iio_map axp22x_maps[] = {191 {192 .consumer_dev_name = "axp20x-battery-power-supply",193 .consumer_channel = "batt_v",194 .adc_channel_label = "batt_v",195 }, {196 .consumer_dev_name = "axp20x-battery-power-supply",197 .consumer_channel = "batt_chrg_i",198 .adc_channel_label = "batt_chrg_i",199 }, {200 .consumer_dev_name = "axp20x-battery-power-supply",201 .consumer_channel = "batt_dischrg_i",202 .adc_channel_label = "batt_dischrg_i",203 }, { /* sentinel */ }204};205 206static struct iio_map axp717_maps[] = {207 {208 .consumer_dev_name = "axp20x-usb-power-supply",209 .consumer_channel = "vbus_v",210 .adc_channel_label = "vbus_v",211 }, {212 .consumer_dev_name = "axp20x-battery-power-supply",213 .consumer_channel = "batt_v",214 .adc_channel_label = "batt_v",215 }, {216 .consumer_dev_name = "axp20x-battery-power-supply",217 .consumer_channel = "batt_chrg_i",218 .adc_channel_label = "batt_chrg_i",219 },220};221 222/*223 * Channels are mapped by physical system. Their channels share the same index.224 * i.e. acin_i is in_current0_raw and acin_v is in_voltage0_raw.225 * The only exception is for the battery. batt_v will be in_voltage6_raw and226 * charge current in_current6_raw and discharge current will be in_current7_raw.227 */228static const struct iio_chan_spec axp192_adc_channels[] = {229 AXP20X_ADC_CHANNEL(AXP192_ACIN_V, "acin_v", IIO_VOLTAGE,230 AXP20X_ACIN_V_ADC_H),231 AXP20X_ADC_CHANNEL(AXP192_ACIN_I, "acin_i", IIO_CURRENT,232 AXP20X_ACIN_I_ADC_H),233 AXP20X_ADC_CHANNEL(AXP192_VBUS_V, "vbus_v", IIO_VOLTAGE,234 AXP20X_VBUS_V_ADC_H),235 AXP20X_ADC_CHANNEL(AXP192_VBUS_I, "vbus_i", IIO_CURRENT,236 AXP20X_VBUS_I_ADC_H),237 {238 .type = IIO_TEMP,239 .address = AXP20X_TEMP_ADC_H,240 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |241 BIT(IIO_CHAN_INFO_SCALE) |242 BIT(IIO_CHAN_INFO_OFFSET),243 .datasheet_name = "pmic_temp",244 },245 AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO0_V, "gpio0_v", IIO_VOLTAGE,246 AXP20X_GPIO0_V_ADC_H),247 AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO1_V, "gpio1_v", IIO_VOLTAGE,248 AXP20X_GPIO1_V_ADC_H),249 AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO2_V, "gpio2_v", IIO_VOLTAGE,250 AXP192_GPIO2_V_ADC_H),251 AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO3_V, "gpio3_v", IIO_VOLTAGE,252 AXP192_GPIO3_V_ADC_H),253 AXP20X_ADC_CHANNEL(AXP192_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,254 AXP20X_IPSOUT_V_HIGH_H),255 AXP20X_ADC_CHANNEL(AXP192_BATT_V, "batt_v", IIO_VOLTAGE,256 AXP20X_BATT_V_H),257 AXP20X_ADC_CHANNEL(AXP192_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,258 AXP20X_BATT_CHRG_I_H),259 AXP20X_ADC_CHANNEL(AXP192_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,260 AXP20X_BATT_DISCHRG_I_H),261 AXP20X_ADC_CHANNEL(AXP192_TS_IN, "ts_v", IIO_VOLTAGE,262 AXP20X_TS_IN_H),263};264 265static const struct iio_chan_spec axp20x_adc_channels[] = {266 AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,267 AXP20X_ACIN_V_ADC_H),268 AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,269 AXP20X_ACIN_I_ADC_H),270 AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,271 AXP20X_VBUS_V_ADC_H),272 AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,273 AXP20X_VBUS_I_ADC_H),274 {275 .type = IIO_TEMP,276 .address = AXP20X_TEMP_ADC_H,277 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |278 BIT(IIO_CHAN_INFO_SCALE) |279 BIT(IIO_CHAN_INFO_OFFSET),280 .datasheet_name = "pmic_temp",281 },282 AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,283 AXP20X_GPIO0_V_ADC_H),284 AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,285 AXP20X_GPIO1_V_ADC_H),286 AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,287 AXP20X_IPSOUT_V_HIGH_H),288 AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,289 AXP20X_BATT_V_H),290 AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,291 AXP20X_BATT_CHRG_I_H),292 AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,293 AXP20X_BATT_DISCHRG_I_H),294 AXP20X_ADC_CHANNEL(AXP20X_TS_IN, "ts_v", IIO_VOLTAGE,295 AXP20X_TS_IN_H),296};297 298static const struct iio_chan_spec axp22x_adc_channels[] = {299 {300 .type = IIO_TEMP,301 .address = AXP22X_PMIC_TEMP_H,302 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |303 BIT(IIO_CHAN_INFO_SCALE) |304 BIT(IIO_CHAN_INFO_OFFSET),305 .datasheet_name = "pmic_temp",306 },307 AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,308 AXP20X_BATT_V_H),309 AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,310 AXP20X_BATT_CHRG_I_H),311 AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,312 AXP20X_BATT_DISCHRG_I_H),313 AXP20X_ADC_CHANNEL(AXP22X_TS_IN, "ts_v", IIO_VOLTAGE,314 AXP22X_TS_ADC_H),315};316 317/*318 * Scale and offset is unknown for temp, ts, batt_chrg_i, vmid_v, and319 * bkup_batt_v channels. Leaving scale and offset undefined for now.320 */321static const struct iio_chan_spec axp717_adc_channels[] = {322 AXP20X_ADC_CHANNEL(AXP717_BATT_V, "batt_v", IIO_VOLTAGE,323 AXP717_BATT_V_H),324 AXP20X_ADC_CHANNEL(AXP717_TS_IN, "ts_v", IIO_VOLTAGE,325 AXP717_ADC_DATA_H),326 AXP20X_ADC_CHANNEL(AXP717_VBUS_V, "vbus_v", IIO_VOLTAGE,327 AXP717_VBUS_V_H),328 AXP20X_ADC_CHANNEL(AXP717_VSYS_V, "vsys_v", IIO_VOLTAGE,329 AXP717_VSYS_V_H),330 AXP20X_ADC_CHANNEL(AXP717_DIE_TEMP_V, "pmic_temp", IIO_TEMP,331 AXP717_ADC_DATA_H),332 AXP20X_ADC_CHANNEL(AXP717_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,333 AXP717_BATT_CHRG_I_H),334 AXP20X_ADC_CHANNEL(AXP717_VMID_V, "vmid_v", IIO_VOLTAGE,335 AXP717_ADC_DATA_H),336 AXP20X_ADC_CHANNEL(AXP717_BKUP_BATT_V, "bkup_batt_v", IIO_VOLTAGE,337 AXP717_ADC_DATA_H),338};339 340static const struct iio_chan_spec axp813_adc_channels[] = {341 {342 .type = IIO_TEMP,343 .address = AXP22X_PMIC_TEMP_H,344 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |345 BIT(IIO_CHAN_INFO_SCALE) |346 BIT(IIO_CHAN_INFO_OFFSET),347 .datasheet_name = "pmic_temp",348 },349 AXP20X_ADC_CHANNEL(AXP813_GPIO0_V, "gpio0_v", IIO_VOLTAGE,350 AXP288_GP_ADC_H),351 AXP20X_ADC_CHANNEL(AXP813_BATT_V, "batt_v", IIO_VOLTAGE,352 AXP20X_BATT_V_H),353 AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,354 AXP20X_BATT_CHRG_I_H),355 AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,356 AXP20X_BATT_DISCHRG_I_H),357 AXP20X_ADC_CHANNEL(AXP813_TS_IN, "ts_v", IIO_VOLTAGE,358 AXP288_TS_ADC_H),359};360 361static int axp192_adc_raw(struct iio_dev *indio_dev,362 struct iio_chan_spec const *chan, int *val)363{364 struct axp20x_adc_iio *info = iio_priv(indio_dev);365 int ret, size;366 367 if (chan->type == IIO_CURRENT &&368 (chan->channel == AXP192_BATT_CHRG_I ||369 chan->channel == AXP192_BATT_DISCHRG_I))370 size = 13;371 else372 size = 12;373 374 ret = axp20x_read_variable_width(info->regmap, chan->address, size);375 if (ret < 0)376 return ret;377 378 *val = ret;379 return IIO_VAL_INT;380}381 382static int axp20x_adc_raw(struct iio_dev *indio_dev,383 struct iio_chan_spec const *chan, int *val)384{385 struct axp20x_adc_iio *info = iio_priv(indio_dev);386 int ret, size;387 388 /*389 * N.B.: Unlike the Chinese datasheets tell, the charging current is390 * stored on 12 bits, not 13 bits. Only discharging current is on 13391 * bits.392 */393 if (chan->type == IIO_CURRENT && chan->channel == AXP20X_BATT_DISCHRG_I)394 size = 13;395 else396 size = 12;397 398 ret = axp20x_read_variable_width(info->regmap, chan->address, size);399 if (ret < 0)400 return ret;401 402 *val = ret;403 return IIO_VAL_INT;404}405 406static int axp22x_adc_raw(struct iio_dev *indio_dev,407 struct iio_chan_spec const *chan, int *val)408{409 struct axp20x_adc_iio *info = iio_priv(indio_dev);410 int ret;411 412 ret = axp20x_read_variable_width(info->regmap, chan->address, 12);413 if (ret < 0)414 return ret;415 416 *val = ret;417 return IIO_VAL_INT;418}419 420static int axp717_adc_raw(struct iio_dev *indio_dev,421 struct iio_chan_spec const *chan, int *val)422{423 struct axp20x_adc_iio *info = iio_priv(indio_dev);424 u8 bulk_reg[2];425 int ret;426 427 /*428 * A generic "ADC data" channel is used for TS, tdie, vmid,429 * and vbackup. This channel must both first be enabled and430 * also selected before it can be read.431 */432 switch (chan->channel) {433 case AXP717_TS_IN:434 regmap_write(info->regmap, AXP717_ADC_DATA_SEL,435 AXP717_ADC_DATA_TS);436 break;437 case AXP717_DIE_TEMP_V:438 regmap_write(info->regmap, AXP717_ADC_DATA_SEL,439 AXP717_ADC_DATA_TEMP);440 break;441 case AXP717_VMID_V:442 regmap_write(info->regmap, AXP717_ADC_DATA_SEL,443 AXP717_ADC_DATA_VMID);444 break;445 case AXP717_BKUP_BATT_V:446 regmap_write(info->regmap, AXP717_ADC_DATA_SEL,447 AXP717_ADC_DATA_BKUP_BATT);448 break;449 default:450 break;451 }452 453 /*454 * All channels are 14 bits, with the first 2 bits on the high455 * register reserved and the remaining bits as the ADC value.456 */457 ret = regmap_bulk_read(info->regmap, chan->address, bulk_reg, 2);458 if (ret < 0)459 return ret;460 461 *val = FIELD_GET(AXP717_ADC_DATA_MASK, get_unaligned_be16(bulk_reg));462 return IIO_VAL_INT;463}464 465static int axp813_adc_raw(struct iio_dev *indio_dev,466 struct iio_chan_spec const *chan, int *val)467{468 struct axp20x_adc_iio *info = iio_priv(indio_dev);469 int ret;470 471 ret = axp20x_read_variable_width(info->regmap, chan->address, 12);472 if (ret < 0)473 return ret;474 475 *val = ret;476 return IIO_VAL_INT;477}478 479static int axp192_adc_scale_voltage(int channel, int *val, int *val2)480{481 switch (channel) {482 case AXP192_ACIN_V:483 case AXP192_VBUS_V:484 *val = 1;485 *val2 = 700000;486 return IIO_VAL_INT_PLUS_MICRO;487 488 case AXP192_GPIO0_V:489 case AXP192_GPIO1_V:490 case AXP192_GPIO2_V:491 case AXP192_GPIO3_V:492 *val = 0;493 *val2 = 500000;494 return IIO_VAL_INT_PLUS_MICRO;495 496 case AXP192_BATT_V:497 *val = 1;498 *val2 = 100000;499 return IIO_VAL_INT_PLUS_MICRO;500 501 case AXP192_IPSOUT_V:502 *val = 1;503 *val2 = 400000;504 return IIO_VAL_INT_PLUS_MICRO;505 506 case AXP192_TS_IN:507 /* 0.8 mV per LSB */508 *val = 0;509 *val2 = 800000;510 return IIO_VAL_INT_PLUS_MICRO;511 512 default:513 return -EINVAL;514 }515}516 517static int axp20x_adc_scale_voltage(int channel, int *val, int *val2)518{519 switch (channel) {520 case AXP20X_ACIN_V:521 case AXP20X_VBUS_V:522 *val = 1;523 *val2 = 700000;524 return IIO_VAL_INT_PLUS_MICRO;525 526 case AXP20X_GPIO0_V:527 case AXP20X_GPIO1_V:528 *val = 0;529 *val2 = 500000;530 return IIO_VAL_INT_PLUS_MICRO;531 532 case AXP20X_BATT_V:533 *val = 1;534 *val2 = 100000;535 return IIO_VAL_INT_PLUS_MICRO;536 537 case AXP20X_IPSOUT_V:538 *val = 1;539 *val2 = 400000;540 return IIO_VAL_INT_PLUS_MICRO;541 542 case AXP20X_TS_IN:543 /* 0.8 mV per LSB */544 *val = 0;545 *val2 = 800000;546 return IIO_VAL_INT_PLUS_MICRO;547 548 default:549 return -EINVAL;550 }551}552 553static int axp22x_adc_scale_voltage(int channel, int *val, int *val2)554{555 switch (channel) {556 case AXP22X_BATT_V:557 /* 1.1 mV per LSB */558 *val = 1;559 *val2 = 100000;560 return IIO_VAL_INT_PLUS_MICRO;561 562 case AXP22X_TS_IN:563 /* 0.8 mV per LSB */564 *val = 0;565 *val2 = 800000;566 return IIO_VAL_INT_PLUS_MICRO;567 568 default:569 return -EINVAL;570 }571}572static int axp813_adc_scale_voltage(int channel, int *val, int *val2)573{574 switch (channel) {575 case AXP813_GPIO0_V:576 *val = 0;577 *val2 = 800000;578 return IIO_VAL_INT_PLUS_MICRO;579 580 case AXP813_BATT_V:581 *val = 1;582 *val2 = 100000;583 return IIO_VAL_INT_PLUS_MICRO;584 585 case AXP813_TS_IN:586 /* 0.8 mV per LSB */587 *val = 0;588 *val2 = 800000;589 return IIO_VAL_INT_PLUS_MICRO;590 591 default:592 return -EINVAL;593 }594}595 596static int axp20x_adc_scale_current(int channel, int *val, int *val2)597{598 switch (channel) {599 case AXP20X_ACIN_I:600 *val = 0;601 *val2 = 625000;602 return IIO_VAL_INT_PLUS_MICRO;603 604 case AXP20X_VBUS_I:605 *val = 0;606 *val2 = 375000;607 return IIO_VAL_INT_PLUS_MICRO;608 609 case AXP20X_BATT_DISCHRG_I:610 case AXP20X_BATT_CHRG_I:611 *val = 0;612 *val2 = 500000;613 return IIO_VAL_INT_PLUS_MICRO;614 615 default:616 return -EINVAL;617 }618}619 620static int axp192_adc_scale(struct iio_chan_spec const *chan, int *val,621 int *val2)622{623 switch (chan->type) {624 case IIO_VOLTAGE:625 return axp192_adc_scale_voltage(chan->channel, val, val2);626 627 case IIO_CURRENT:628 /*629 * AXP192 current channels are identical to the AXP20x,630 * therefore we can re-use the scaling function.631 */632 return axp20x_adc_scale_current(chan->channel, val, val2);633 634 case IIO_TEMP:635 *val = 100;636 return IIO_VAL_INT;637 638 default:639 return -EINVAL;640 }641}642 643static int axp20x_adc_scale(struct iio_chan_spec const *chan, int *val,644 int *val2)645{646 switch (chan->type) {647 case IIO_VOLTAGE:648 return axp20x_adc_scale_voltage(chan->channel, val, val2);649 650 case IIO_CURRENT:651 return axp20x_adc_scale_current(chan->channel, val, val2);652 653 case IIO_TEMP:654 *val = 100;655 return IIO_VAL_INT;656 657 default:658 return -EINVAL;659 }660}661 662static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,663 int *val2)664{665 switch (chan->type) {666 case IIO_VOLTAGE:667 return axp22x_adc_scale_voltage(chan->channel, val, val2);668 669 case IIO_CURRENT:670 *val = 1;671 return IIO_VAL_INT;672 673 case IIO_TEMP:674 *val = 100;675 return IIO_VAL_INT;676 677 default:678 return -EINVAL;679 }680}681 682static int axp717_adc_scale(struct iio_chan_spec const *chan, int *val,683 int *val2)684{685 switch (chan->type) {686 case IIO_VOLTAGE:687 *val = 1;688 return IIO_VAL_INT;689 690 case IIO_CURRENT:691 *val = 1;692 return IIO_VAL_INT;693 694 case IIO_TEMP:695 *val = 100;696 return IIO_VAL_INT;697 698 default:699 return -EINVAL;700 }701}702 703static int axp813_adc_scale(struct iio_chan_spec const *chan, int *val,704 int *val2)705{706 switch (chan->type) {707 case IIO_VOLTAGE:708 return axp813_adc_scale_voltage(chan->channel, val, val2);709 710 case IIO_CURRENT:711 *val = 1;712 return IIO_VAL_INT;713 714 case IIO_TEMP:715 *val = 100;716 return IIO_VAL_INT;717 718 default:719 return -EINVAL;720 }721}722 723static int axp192_adc_offset_voltage(struct iio_dev *indio_dev, int channel,724 int *val)725{726 struct axp20x_adc_iio *info = iio_priv(indio_dev);727 unsigned int regval;728 int ret;729 730 ret = regmap_read(info->regmap, AXP192_GPIO30_IN_RANGE, ®val);731 if (ret < 0)732 return ret;733 734 switch (channel) {735 case AXP192_GPIO0_V:736 regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO0, regval);737 break;738 739 case AXP192_GPIO1_V:740 regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO1, regval);741 break;742 743 case AXP192_GPIO2_V:744 regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO2, regval);745 break;746 747 case AXP192_GPIO3_V:748 regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO3, regval);749 break;750 751 default:752 return -EINVAL;753 }754 755 *val = regval ? 700000 : 0;756 return IIO_VAL_INT;757}758 759static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel,760 int *val)761{762 struct axp20x_adc_iio *info = iio_priv(indio_dev);763 unsigned int regval;764 int ret;765 766 ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, ®val);767 if (ret < 0)768 return ret;769 770 switch (channel) {771 case AXP20X_GPIO0_V:772 regval = FIELD_GET(AXP20X_GPIO10_IN_RANGE_GPIO0, regval);773 break;774 775 case AXP20X_GPIO1_V:776 regval = FIELD_GET(AXP20X_GPIO10_IN_RANGE_GPIO1, regval);777 break;778 779 default:780 return -EINVAL;781 }782 783 *val = regval ? 700000 : 0;784 return IIO_VAL_INT;785}786 787static int axp192_adc_offset(struct iio_dev *indio_dev,788 struct iio_chan_spec const *chan, int *val)789{790 switch (chan->type) {791 case IIO_VOLTAGE:792 return axp192_adc_offset_voltage(indio_dev, chan->channel, val);793 794 case IIO_TEMP:795 *val = -1447;796 return IIO_VAL_INT;797 798 default:799 return -EINVAL;800 }801}802 803static int axp20x_adc_offset(struct iio_dev *indio_dev,804 struct iio_chan_spec const *chan, int *val)805{806 switch (chan->type) {807 case IIO_VOLTAGE:808 return axp20x_adc_offset_voltage(indio_dev, chan->channel, val);809 810 case IIO_TEMP:811 *val = -1447;812 return IIO_VAL_INT;813 814 default:815 return -EINVAL;816 }817}818 819static int axp192_read_raw(struct iio_dev *indio_dev,820 struct iio_chan_spec const *chan, int *val,821 int *val2, long mask)822{823 switch (mask) {824 case IIO_CHAN_INFO_OFFSET:825 return axp192_adc_offset(indio_dev, chan, val);826 827 case IIO_CHAN_INFO_SCALE:828 return axp192_adc_scale(chan, val, val2);829 830 case IIO_CHAN_INFO_RAW:831 return axp192_adc_raw(indio_dev, chan, val);832 833 default:834 return -EINVAL;835 }836}837 838static int axp20x_read_raw(struct iio_dev *indio_dev,839 struct iio_chan_spec const *chan, int *val,840 int *val2, long mask)841{842 switch (mask) {843 case IIO_CHAN_INFO_OFFSET:844 return axp20x_adc_offset(indio_dev, chan, val);845 846 case IIO_CHAN_INFO_SCALE:847 return axp20x_adc_scale(chan, val, val2);848 849 case IIO_CHAN_INFO_RAW:850 return axp20x_adc_raw(indio_dev, chan, val);851 852 default:853 return -EINVAL;854 }855}856 857static int axp22x_read_raw(struct iio_dev *indio_dev,858 struct iio_chan_spec const *chan, int *val,859 int *val2, long mask)860{861 switch (mask) {862 case IIO_CHAN_INFO_OFFSET:863 /* For PMIC temp only */864 *val = -2677;865 return IIO_VAL_INT;866 867 case IIO_CHAN_INFO_SCALE:868 return axp22x_adc_scale(chan, val, val2);869 870 case IIO_CHAN_INFO_RAW:871 return axp22x_adc_raw(indio_dev, chan, val);872 873 default:874 return -EINVAL;875 }876}877 878static int axp717_read_raw(struct iio_dev *indio_dev,879 struct iio_chan_spec const *chan, int *val,880 int *val2, long mask)881{882 switch (mask) {883 case IIO_CHAN_INFO_SCALE:884 return axp717_adc_scale(chan, val, val2);885 886 case IIO_CHAN_INFO_RAW:887 return axp717_adc_raw(indio_dev, chan, val);888 889 default:890 return -EINVAL;891 }892}893 894static int axp813_read_raw(struct iio_dev *indio_dev,895 struct iio_chan_spec const *chan, int *val,896 int *val2, long mask)897{898 switch (mask) {899 case IIO_CHAN_INFO_OFFSET:900 *val = -2667;901 return IIO_VAL_INT;902 903 case IIO_CHAN_INFO_SCALE:904 return axp813_adc_scale(chan, val, val2);905 906 case IIO_CHAN_INFO_RAW:907 return axp813_adc_raw(indio_dev, chan, val);908 909 default:910 return -EINVAL;911 }912}913 914static int axp192_write_raw(struct iio_dev *indio_dev,915 struct iio_chan_spec const *chan, int val, int val2,916 long mask)917{918 struct axp20x_adc_iio *info = iio_priv(indio_dev);919 unsigned int regmask, regval;920 921 /*922 * The AXP192 PMIC allows the user to choose between 0V and 0.7V offsets923 * for (independently) GPIO0-3 when in ADC mode.924 */925 if (mask != IIO_CHAN_INFO_OFFSET)926 return -EINVAL;927 928 if (val != 0 && val != 700000)929 return -EINVAL;930 931 switch (chan->channel) {932 case AXP192_GPIO0_V:933 regmask = AXP192_GPIO30_IN_RANGE_GPIO0;934 regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO0, !!val);935 break;936 937 case AXP192_GPIO1_V:938 regmask = AXP192_GPIO30_IN_RANGE_GPIO1;939 regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO1, !!val);940 break;941 942 case AXP192_GPIO2_V:943 regmask = AXP192_GPIO30_IN_RANGE_GPIO2;944 regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO2, !!val);945 break;946 947 case AXP192_GPIO3_V:948 regmask = AXP192_GPIO30_IN_RANGE_GPIO3;949 regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO3, !!val);950 break;951 952 default:953 return -EINVAL;954 }955 956 return regmap_update_bits(info->regmap, AXP192_GPIO30_IN_RANGE, regmask, regval);957}958 959static int axp20x_write_raw(struct iio_dev *indio_dev,960 struct iio_chan_spec const *chan, int val, int val2,961 long mask)962{963 struct axp20x_adc_iio *info = iio_priv(indio_dev);964 unsigned int regmask, regval;965 966 /*967 * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets968 * for (independently) GPIO0 and GPIO1 when in ADC mode.969 */970 if (mask != IIO_CHAN_INFO_OFFSET)971 return -EINVAL;972 973 if (val != 0 && val != 700000)974 return -EINVAL;975 976 switch (chan->channel) {977 case AXP20X_GPIO0_V:978 regmask = AXP20X_GPIO10_IN_RANGE_GPIO0;979 regval = FIELD_PREP(AXP20X_GPIO10_IN_RANGE_GPIO0, !!val);980 break;981 982 case AXP20X_GPIO1_V:983 regmask = AXP20X_GPIO10_IN_RANGE_GPIO1;984 regval = FIELD_PREP(AXP20X_GPIO10_IN_RANGE_GPIO1, !!val);985 break;986 987 default:988 return -EINVAL;989 }990 991 return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE, regmask, regval);992}993 994static const struct iio_info axp192_adc_iio_info = {995 .read_raw = axp192_read_raw,996 .write_raw = axp192_write_raw,997};998 999static const struct iio_info axp20x_adc_iio_info = {1000 .read_raw = axp20x_read_raw,1001 .write_raw = axp20x_write_raw,1002};1003 1004static const struct iio_info axp22x_adc_iio_info = {1005 .read_raw = axp22x_read_raw,1006};1007 1008static const struct iio_info axp717_adc_iio_info = {1009 .read_raw = axp717_read_raw,1010};1011 1012static const struct iio_info axp813_adc_iio_info = {1013 .read_raw = axp813_read_raw,1014};1015 1016static int axp20x_adc_rate(struct axp20x_adc_iio *info, int rate)1017{1018 return regmap_update_bits(info->regmap, AXP20X_ADC_RATE,1019 AXP20X_ADC_RATE_MASK,1020 AXP20X_ADC_RATE_HZ(rate));1021}1022 1023static int axp22x_adc_rate(struct axp20x_adc_iio *info, int rate)1024{1025 return regmap_update_bits(info->regmap, AXP20X_ADC_RATE,1026 AXP20X_ADC_RATE_MASK,1027 AXP22X_ADC_RATE_HZ(rate));1028}1029 1030static int axp813_adc_rate(struct axp20x_adc_iio *info, int rate)1031{1032 return regmap_update_bits(info->regmap, AXP813_ADC_RATE,1033 AXP813_ADC_RATE_MASK,1034 AXP813_ADC_RATE_HZ(rate));1035}1036 1037struct axp_data {1038 const struct iio_info *iio_info;1039 int num_channels;1040 struct iio_chan_spec const *channels;1041 unsigned long adc_en1;1042 unsigned long adc_en1_mask;1043 unsigned long adc_en2;1044 unsigned long adc_en2_mask;1045 int (*adc_rate)(struct axp20x_adc_iio *info,1046 int rate);1047 struct iio_map *maps;1048};1049 1050static const struct axp_data axp192_data = {1051 .iio_info = &axp192_adc_iio_info,1052 .num_channels = ARRAY_SIZE(axp192_adc_channels),1053 .channels = axp192_adc_channels,1054 .adc_en1_mask = AXP192_ADC_EN1_MASK,1055 .adc_en2_mask = AXP192_ADC_EN2_MASK,1056 .adc_rate = axp20x_adc_rate,1057 .maps = axp20x_maps,1058};1059 1060static const struct axp_data axp20x_data = {1061 .iio_info = &axp20x_adc_iio_info,1062 .num_channels = ARRAY_SIZE(axp20x_adc_channels),1063 .channels = axp20x_adc_channels,1064 .adc_en1 = AXP20X_ADC_EN1,1065 .adc_en1_mask = AXP20X_ADC_EN1_MASK,1066 .adc_en2 = AXP20X_ADC_EN2,1067 .adc_en2_mask = AXP20X_ADC_EN2_MASK,1068 .adc_rate = axp20x_adc_rate,1069 .maps = axp20x_maps,1070};1071 1072static const struct axp_data axp22x_data = {1073 .iio_info = &axp22x_adc_iio_info,1074 .num_channels = ARRAY_SIZE(axp22x_adc_channels),1075 .channels = axp22x_adc_channels,1076 .adc_en1 = AXP20X_ADC_EN1,1077 .adc_en1_mask = AXP22X_ADC_EN1_MASK,1078 .adc_rate = axp22x_adc_rate,1079 .maps = axp22x_maps,1080};1081 1082static const struct axp_data axp717_data = {1083 .iio_info = &axp717_adc_iio_info,1084 .num_channels = ARRAY_SIZE(axp717_adc_channels),1085 .channels = axp717_adc_channels,1086 .adc_en1 = AXP717_ADC_CH_EN_CONTROL,1087 .adc_en1_mask = AXP717_ADC_EN1_MASK,1088 .maps = axp717_maps,1089};1090 1091static const struct axp_data axp813_data = {1092 .iio_info = &axp813_adc_iio_info,1093 .num_channels = ARRAY_SIZE(axp813_adc_channels),1094 .channels = axp813_adc_channels,1095 .adc_en1 = AXP20X_ADC_EN1,1096 .adc_en1_mask = AXP22X_ADC_EN1_MASK,1097 .adc_rate = axp813_adc_rate,1098 .maps = axp22x_maps,1099};1100 1101static const struct of_device_id axp20x_adc_of_match[] = {1102 { .compatible = "x-powers,axp192-adc", .data = (void *)&axp192_data, },1103 { .compatible = "x-powers,axp209-adc", .data = (void *)&axp20x_data, },1104 { .compatible = "x-powers,axp221-adc", .data = (void *)&axp22x_data, },1105 { .compatible = "x-powers,axp717-adc", .data = (void *)&axp717_data, },1106 { .compatible = "x-powers,axp813-adc", .data = (void *)&axp813_data, },1107 { /* sentinel */ }1108};1109MODULE_DEVICE_TABLE(of, axp20x_adc_of_match);1110 1111static const struct platform_device_id axp20x_adc_id_match[] = {1112 { .name = "axp192-adc", .driver_data = (kernel_ulong_t)&axp192_data, },1113 { .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, },1114 { .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, },1115 { .name = "axp717-adc", .driver_data = (kernel_ulong_t)&axp717_data, },1116 { .name = "axp813-adc", .driver_data = (kernel_ulong_t)&axp813_data, },1117 { /* sentinel */ },1118};1119MODULE_DEVICE_TABLE(platform, axp20x_adc_id_match);1120 1121static int axp20x_probe(struct platform_device *pdev)1122{1123 struct axp20x_adc_iio *info;1124 struct iio_dev *indio_dev;1125 struct axp20x_dev *axp20x_dev;1126 int ret;1127 1128 axp20x_dev = dev_get_drvdata(pdev->dev.parent);1129 1130 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));1131 if (!indio_dev)1132 return -ENOMEM;1133 1134 info = iio_priv(indio_dev);1135 platform_set_drvdata(pdev, indio_dev);1136 1137 info->regmap = axp20x_dev->regmap;1138 indio_dev->modes = INDIO_DIRECT_MODE;1139 1140 if (!dev_fwnode(&pdev->dev)) {1141 const struct platform_device_id *id;1142 1143 id = platform_get_device_id(pdev);1144 info->data = (const struct axp_data *)id->driver_data;1145 } else {1146 struct device *dev = &pdev->dev;1147 1148 info->data = device_get_match_data(dev);1149 }1150 1151 indio_dev->name = platform_get_device_id(pdev)->name;1152 indio_dev->info = info->data->iio_info;1153 indio_dev->num_channels = info->data->num_channels;1154 indio_dev->channels = info->data->channels;1155 1156 /* Enable the ADCs on IP */1157 regmap_write(info->regmap, info->data->adc_en1,1158 info->data->adc_en1_mask);1159 1160 if (info->data->adc_en2_mask)1161 regmap_set_bits(info->regmap, info->data->adc_en2,1162 info->data->adc_en2_mask);1163 1164 /* Configure ADCs rate */1165 if (info->data->adc_rate)1166 info->data->adc_rate(info, 100);1167 1168 ret = iio_map_array_register(indio_dev, info->data->maps);1169 if (ret < 0) {1170 dev_err(&pdev->dev, "failed to register IIO maps: %d\n", ret);1171 goto fail_map;1172 }1173 1174 ret = iio_device_register(indio_dev);1175 if (ret < 0) {1176 dev_err(&pdev->dev, "could not register the device\n");1177 goto fail_register;1178 }1179 1180 return 0;1181 1182fail_register:1183 iio_map_array_unregister(indio_dev);1184 1185fail_map:1186 regmap_write(info->regmap, info->data->adc_en1, 0);1187 1188 if (info->data->adc_en2_mask)1189 regmap_write(info->regmap, info->data->adc_en2, 0);1190 1191 return ret;1192}1193 1194static void axp20x_remove(struct platform_device *pdev)1195{1196 struct iio_dev *indio_dev = platform_get_drvdata(pdev);1197 struct axp20x_adc_iio *info = iio_priv(indio_dev);1198 1199 iio_device_unregister(indio_dev);1200 iio_map_array_unregister(indio_dev);1201 1202 regmap_write(info->regmap, info->data->adc_en1, 0);1203 1204 if (info->data->adc_en2_mask)1205 regmap_write(info->regmap, info->data->adc_en2, 0);1206}1207 1208static struct platform_driver axp20x_adc_driver = {1209 .driver = {1210 .name = "axp20x-adc",1211 .of_match_table = axp20x_adc_of_match,1212 },1213 .id_table = axp20x_adc_id_match,1214 .probe = axp20x_probe,1215 .remove_new = axp20x_remove,1216};1217 1218module_platform_driver(axp20x_adc_driver);1219 1220MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");1221MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");1222MODULE_LICENSE("GPL");1223