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