axp20x_adc.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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. #include <linux/completion.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/io.h>
  13. #include <linux/module.h>
  14. #include <linux/of.h>
  15. #include <linux/of_device.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/pm_runtime.h>
  18. #include <linux/regmap.h>
  19. #include <linux/thermal.h>
  20. #include <linux/iio/iio.h>
  21. #include <linux/iio/driver.h>
  22. #include <linux/iio/machine.h>
  23. #include <linux/mfd/axp20x.h>
  24. #define AXP20X_ADC_EN1_MASK GENMASK(7, 0)
  25. #define AXP20X_ADC_EN2_MASK (GENMASK(3, 2) | BIT(7))
  26. #define AXP22X_ADC_EN1_MASK (GENMASK(7, 5) | BIT(0))
  27. #define AXP20X_GPIO10_IN_RANGE_GPIO0 BIT(0)
  28. #define AXP20X_GPIO10_IN_RANGE_GPIO1 BIT(1)
  29. #define AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(x) ((x) & BIT(0))
  30. #define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x) (((x) & BIT(0)) << 1)
  31. #define AXP20X_ADC_RATE_MASK GENMASK(7, 6)
  32. #define AXP20X_ADC_RATE_HZ(x) ((ilog2((x) / 25) << 6) & AXP20X_ADC_RATE_MASK)
  33. #define AXP22X_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK)
  34. #define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg) \
  35. { \
  36. .type = _type, \
  37. .indexed = 1, \
  38. .channel = _channel, \
  39. .address = _reg, \
  40. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
  41. BIT(IIO_CHAN_INFO_SCALE), \
  42. .datasheet_name = _name, \
  43. }
  44. #define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
  45. { \
  46. .type = _type, \
  47. .indexed = 1, \
  48. .channel = _channel, \
  49. .address = _reg, \
  50. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
  51. BIT(IIO_CHAN_INFO_SCALE) |\
  52. BIT(IIO_CHAN_INFO_OFFSET),\
  53. .datasheet_name = _name, \
  54. }
  55. struct axp_data;
  56. struct axp20x_adc_iio {
  57. struct regmap *regmap;
  58. struct axp_data *data;
  59. };
  60. enum axp20x_adc_channel_v {
  61. AXP20X_ACIN_V = 0,
  62. AXP20X_VBUS_V,
  63. AXP20X_TS_IN,
  64. AXP20X_GPIO0_V,
  65. AXP20X_GPIO1_V,
  66. AXP20X_IPSOUT_V,
  67. AXP20X_BATT_V,
  68. };
  69. enum axp20x_adc_channel_i {
  70. AXP20X_ACIN_I = 0,
  71. AXP20X_VBUS_I,
  72. AXP20X_BATT_CHRG_I,
  73. AXP20X_BATT_DISCHRG_I,
  74. };
  75. enum axp22x_adc_channel_v {
  76. AXP22X_TS_IN = 0,
  77. AXP22X_BATT_V,
  78. };
  79. enum axp22x_adc_channel_i {
  80. AXP22X_BATT_CHRG_I = 1,
  81. AXP22X_BATT_DISCHRG_I,
  82. };
  83. static struct iio_map axp20x_maps[] = {
  84. {
  85. .consumer_dev_name = "axp20x-usb-power-supply",
  86. .consumer_channel = "vbus_v",
  87. .adc_channel_label = "vbus_v",
  88. }, {
  89. .consumer_dev_name = "axp20x-usb-power-supply",
  90. .consumer_channel = "vbus_i",
  91. .adc_channel_label = "vbus_i",
  92. }, {
  93. .consumer_dev_name = "axp20x-ac-power-supply",
  94. .consumer_channel = "acin_v",
  95. .adc_channel_label = "acin_v",
  96. }, {
  97. .consumer_dev_name = "axp20x-ac-power-supply",
  98. .consumer_channel = "acin_i",
  99. .adc_channel_label = "acin_i",
  100. }, {
  101. .consumer_dev_name = "axp20x-battery-power-supply",
  102. .consumer_channel = "batt_v",
  103. .adc_channel_label = "batt_v",
  104. }, {
  105. .consumer_dev_name = "axp20x-battery-power-supply",
  106. .consumer_channel = "batt_chrg_i",
  107. .adc_channel_label = "batt_chrg_i",
  108. }, {
  109. .consumer_dev_name = "axp20x-battery-power-supply",
  110. .consumer_channel = "batt_dischrg_i",
  111. .adc_channel_label = "batt_dischrg_i",
  112. }, { /* sentinel */ }
  113. };
  114. static struct iio_map axp22x_maps[] = {
  115. {
  116. .consumer_dev_name = "axp20x-battery-power-supply",
  117. .consumer_channel = "batt_v",
  118. .adc_channel_label = "batt_v",
  119. }, {
  120. .consumer_dev_name = "axp20x-battery-power-supply",
  121. .consumer_channel = "batt_chrg_i",
  122. .adc_channel_label = "batt_chrg_i",
  123. }, {
  124. .consumer_dev_name = "axp20x-battery-power-supply",
  125. .consumer_channel = "batt_dischrg_i",
  126. .adc_channel_label = "batt_dischrg_i",
  127. }, { /* sentinel */ }
  128. };
  129. /*
  130. * Channels are mapped by physical system. Their channels share the same index.
  131. * i.e. acin_i is in_current0_raw and acin_v is in_voltage0_raw.
  132. * The only exception is for the battery. batt_v will be in_voltage6_raw and
  133. * charge current in_current6_raw and discharge current will be in_current7_raw.
  134. */
  135. static const struct iio_chan_spec axp20x_adc_channels[] = {
  136. AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,
  137. AXP20X_ACIN_V_ADC_H),
  138. AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,
  139. AXP20X_ACIN_I_ADC_H),
  140. AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,
  141. AXP20X_VBUS_V_ADC_H),
  142. AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,
  143. AXP20X_VBUS_I_ADC_H),
  144. {
  145. .type = IIO_TEMP,
  146. .address = AXP20X_TEMP_ADC_H,
  147. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  148. BIT(IIO_CHAN_INFO_SCALE) |
  149. BIT(IIO_CHAN_INFO_OFFSET),
  150. .datasheet_name = "pmic_temp",
  151. },
  152. AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,
  153. AXP20X_GPIO0_V_ADC_H),
  154. AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,
  155. AXP20X_GPIO1_V_ADC_H),
  156. AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,
  157. AXP20X_IPSOUT_V_HIGH_H),
  158. AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,
  159. AXP20X_BATT_V_H),
  160. AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
  161. AXP20X_BATT_CHRG_I_H),
  162. AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
  163. AXP20X_BATT_DISCHRG_I_H),
  164. };
  165. static const struct iio_chan_spec axp22x_adc_channels[] = {
  166. {
  167. .type = IIO_TEMP,
  168. .address = AXP22X_PMIC_TEMP_H,
  169. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  170. BIT(IIO_CHAN_INFO_SCALE) |
  171. BIT(IIO_CHAN_INFO_OFFSET),
  172. .datasheet_name = "pmic_temp",
  173. },
  174. AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,
  175. AXP20X_BATT_V_H),
  176. AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
  177. AXP20X_BATT_CHRG_I_H),
  178. AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
  179. AXP20X_BATT_DISCHRG_I_H),
  180. };
  181. static int axp20x_adc_raw(struct iio_dev *indio_dev,
  182. struct iio_chan_spec const *chan, int *val)
  183. {
  184. struct axp20x_adc_iio *info = iio_priv(indio_dev);
  185. int size = 12;
  186. /*
  187. * N.B.: Unlike the Chinese datasheets tell, the charging current is
  188. * stored on 12 bits, not 13 bits. Only discharging current is on 13
  189. * bits.
  190. */
  191. if (chan->type == IIO_CURRENT && chan->channel == AXP20X_BATT_DISCHRG_I)
  192. size = 13;
  193. else
  194. size = 12;
  195. *val = axp20x_read_variable_width(info->regmap, chan->address, size);
  196. if (*val < 0)
  197. return *val;
  198. return IIO_VAL_INT;
  199. }
  200. static int axp22x_adc_raw(struct iio_dev *indio_dev,
  201. struct iio_chan_spec const *chan, int *val)
  202. {
  203. struct axp20x_adc_iio *info = iio_priv(indio_dev);
  204. int size;
  205. /*
  206. * N.B.: Unlike the Chinese datasheets tell, the charging current is
  207. * stored on 12 bits, not 13 bits. Only discharging current is on 13
  208. * bits.
  209. */
  210. if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I)
  211. size = 13;
  212. else
  213. size = 12;
  214. *val = axp20x_read_variable_width(info->regmap, chan->address, size);
  215. if (*val < 0)
  216. return *val;
  217. return IIO_VAL_INT;
  218. }
  219. static int axp20x_adc_scale_voltage(int channel, int *val, int *val2)
  220. {
  221. switch (channel) {
  222. case AXP20X_ACIN_V:
  223. case AXP20X_VBUS_V:
  224. *val = 1;
  225. *val2 = 700000;
  226. return IIO_VAL_INT_PLUS_MICRO;
  227. case AXP20X_GPIO0_V:
  228. case AXP20X_GPIO1_V:
  229. *val = 0;
  230. *val2 = 500000;
  231. return IIO_VAL_INT_PLUS_MICRO;
  232. case AXP20X_BATT_V:
  233. *val = 1;
  234. *val2 = 100000;
  235. return IIO_VAL_INT_PLUS_MICRO;
  236. case AXP20X_IPSOUT_V:
  237. *val = 1;
  238. *val2 = 400000;
  239. return IIO_VAL_INT_PLUS_MICRO;
  240. default:
  241. return -EINVAL;
  242. }
  243. }
  244. static int axp20x_adc_scale_current(int channel, int *val, int *val2)
  245. {
  246. switch (channel) {
  247. case AXP20X_ACIN_I:
  248. *val = 0;
  249. *val2 = 625000;
  250. return IIO_VAL_INT_PLUS_MICRO;
  251. case AXP20X_VBUS_I:
  252. *val = 0;
  253. *val2 = 375000;
  254. return IIO_VAL_INT_PLUS_MICRO;
  255. case AXP20X_BATT_DISCHRG_I:
  256. case AXP20X_BATT_CHRG_I:
  257. *val = 0;
  258. *val2 = 500000;
  259. return IIO_VAL_INT_PLUS_MICRO;
  260. default:
  261. return -EINVAL;
  262. }
  263. }
  264. static int axp20x_adc_scale(struct iio_chan_spec const *chan, int *val,
  265. int *val2)
  266. {
  267. switch (chan->type) {
  268. case IIO_VOLTAGE:
  269. return axp20x_adc_scale_voltage(chan->channel, val, val2);
  270. case IIO_CURRENT:
  271. return axp20x_adc_scale_current(chan->channel, val, val2);
  272. case IIO_TEMP:
  273. *val = 100;
  274. return IIO_VAL_INT;
  275. default:
  276. return -EINVAL;
  277. }
  278. }
  279. static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
  280. int *val2)
  281. {
  282. switch (chan->type) {
  283. case IIO_VOLTAGE:
  284. if (chan->channel != AXP22X_BATT_V)
  285. return -EINVAL;
  286. *val = 1;
  287. *val2 = 100000;
  288. return IIO_VAL_INT_PLUS_MICRO;
  289. case IIO_CURRENT:
  290. *val = 0;
  291. *val2 = 500000;
  292. return IIO_VAL_INT_PLUS_MICRO;
  293. case IIO_TEMP:
  294. *val = 100;
  295. return IIO_VAL_INT;
  296. default:
  297. return -EINVAL;
  298. }
  299. }
  300. static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel,
  301. int *val)
  302. {
  303. struct axp20x_adc_iio *info = iio_priv(indio_dev);
  304. int ret;
  305. ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, val);
  306. if (ret < 0)
  307. return ret;
  308. switch (channel) {
  309. case AXP20X_GPIO0_V:
  310. *val &= AXP20X_GPIO10_IN_RANGE_GPIO0;
  311. break;
  312. case AXP20X_GPIO1_V:
  313. *val &= AXP20X_GPIO10_IN_RANGE_GPIO1;
  314. break;
  315. default:
  316. return -EINVAL;
  317. }
  318. *val = !!(*val) * 700000;
  319. return IIO_VAL_INT;
  320. }
  321. static int axp20x_adc_offset(struct iio_dev *indio_dev,
  322. struct iio_chan_spec const *chan, int *val)
  323. {
  324. switch (chan->type) {
  325. case IIO_VOLTAGE:
  326. return axp20x_adc_offset_voltage(indio_dev, chan->channel, val);
  327. case IIO_TEMP:
  328. *val = -1447;
  329. return IIO_VAL_INT;
  330. default:
  331. return -EINVAL;
  332. }
  333. }
  334. static int axp20x_read_raw(struct iio_dev *indio_dev,
  335. struct iio_chan_spec const *chan, int *val,
  336. int *val2, long mask)
  337. {
  338. switch (mask) {
  339. case IIO_CHAN_INFO_OFFSET:
  340. return axp20x_adc_offset(indio_dev, chan, val);
  341. case IIO_CHAN_INFO_SCALE:
  342. return axp20x_adc_scale(chan, val, val2);
  343. case IIO_CHAN_INFO_RAW:
  344. return axp20x_adc_raw(indio_dev, chan, val);
  345. default:
  346. return -EINVAL;
  347. }
  348. }
  349. static int axp22x_read_raw(struct iio_dev *indio_dev,
  350. struct iio_chan_spec const *chan, int *val,
  351. int *val2, long mask)
  352. {
  353. switch (mask) {
  354. case IIO_CHAN_INFO_OFFSET:
  355. *val = -2677;
  356. return IIO_VAL_INT;
  357. case IIO_CHAN_INFO_SCALE:
  358. return axp22x_adc_scale(chan, val, val2);
  359. case IIO_CHAN_INFO_RAW:
  360. return axp22x_adc_raw(indio_dev, chan, val);
  361. default:
  362. return -EINVAL;
  363. }
  364. }
  365. static int axp20x_write_raw(struct iio_dev *indio_dev,
  366. struct iio_chan_spec const *chan, int val, int val2,
  367. long mask)
  368. {
  369. struct axp20x_adc_iio *info = iio_priv(indio_dev);
  370. unsigned int reg, regval;
  371. /*
  372. * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets
  373. * for (independently) GPIO0 and GPIO1 when in ADC mode.
  374. */
  375. if (mask != IIO_CHAN_INFO_OFFSET)
  376. return -EINVAL;
  377. if (val != 0 && val != 700000)
  378. return -EINVAL;
  379. switch (chan->channel) {
  380. case AXP20X_GPIO0_V:
  381. reg = AXP20X_GPIO10_IN_RANGE_GPIO0;
  382. regval = AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val);
  383. break;
  384. case AXP20X_GPIO1_V:
  385. reg = AXP20X_GPIO10_IN_RANGE_GPIO1;
  386. regval = AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val);
  387. break;
  388. default:
  389. return -EINVAL;
  390. }
  391. return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE, reg,
  392. regval);
  393. }
  394. static const struct iio_info axp20x_adc_iio_info = {
  395. .read_raw = axp20x_read_raw,
  396. .write_raw = axp20x_write_raw,
  397. .driver_module = THIS_MODULE,
  398. };
  399. static const struct iio_info axp22x_adc_iio_info = {
  400. .read_raw = axp22x_read_raw,
  401. .driver_module = THIS_MODULE,
  402. };
  403. static int axp20x_adc_rate(int rate)
  404. {
  405. return AXP20X_ADC_RATE_HZ(rate);
  406. }
  407. static int axp22x_adc_rate(int rate)
  408. {
  409. return AXP22X_ADC_RATE_HZ(rate);
  410. }
  411. struct axp_data {
  412. const struct iio_info *iio_info;
  413. int num_channels;
  414. struct iio_chan_spec const *channels;
  415. unsigned long adc_en1_mask;
  416. int (*adc_rate)(int rate);
  417. bool adc_en2;
  418. struct iio_map *maps;
  419. };
  420. static const struct axp_data axp20x_data = {
  421. .iio_info = &axp20x_adc_iio_info,
  422. .num_channels = ARRAY_SIZE(axp20x_adc_channels),
  423. .channels = axp20x_adc_channels,
  424. .adc_en1_mask = AXP20X_ADC_EN1_MASK,
  425. .adc_rate = axp20x_adc_rate,
  426. .adc_en2 = true,
  427. .maps = axp20x_maps,
  428. };
  429. static const struct axp_data axp22x_data = {
  430. .iio_info = &axp22x_adc_iio_info,
  431. .num_channels = ARRAY_SIZE(axp22x_adc_channels),
  432. .channels = axp22x_adc_channels,
  433. .adc_en1_mask = AXP22X_ADC_EN1_MASK,
  434. .adc_rate = axp22x_adc_rate,
  435. .adc_en2 = false,
  436. .maps = axp22x_maps,
  437. };
  438. static const struct platform_device_id axp20x_adc_id_match[] = {
  439. { .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, },
  440. { .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, },
  441. { /* sentinel */ },
  442. };
  443. MODULE_DEVICE_TABLE(platform, axp20x_adc_id_match);
  444. static int axp20x_probe(struct platform_device *pdev)
  445. {
  446. struct axp20x_adc_iio *info;
  447. struct iio_dev *indio_dev;
  448. struct axp20x_dev *axp20x_dev;
  449. int ret;
  450. axp20x_dev = dev_get_drvdata(pdev->dev.parent);
  451. indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
  452. if (!indio_dev)
  453. return -ENOMEM;
  454. info = iio_priv(indio_dev);
  455. platform_set_drvdata(pdev, indio_dev);
  456. info->regmap = axp20x_dev->regmap;
  457. indio_dev->dev.parent = &pdev->dev;
  458. indio_dev->dev.of_node = pdev->dev.of_node;
  459. indio_dev->modes = INDIO_DIRECT_MODE;
  460. info->data = (struct axp_data *)platform_get_device_id(pdev)->driver_data;
  461. indio_dev->name = platform_get_device_id(pdev)->name;
  462. indio_dev->info = info->data->iio_info;
  463. indio_dev->num_channels = info->data->num_channels;
  464. indio_dev->channels = info->data->channels;
  465. /* Enable the ADCs on IP */
  466. regmap_write(info->regmap, AXP20X_ADC_EN1, info->data->adc_en1_mask);
  467. if (info->data->adc_en2)
  468. /* Enable GPIO0/1 and internal temperature ADCs */
  469. regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
  470. AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
  471. /* Configure ADCs rate */
  472. regmap_update_bits(info->regmap, AXP20X_ADC_RATE, AXP20X_ADC_RATE_MASK,
  473. info->data->adc_rate(100));
  474. ret = iio_map_array_register(indio_dev, info->data->maps);
  475. if (ret < 0) {
  476. dev_err(&pdev->dev, "failed to register IIO maps: %d\n", ret);
  477. goto fail_map;
  478. }
  479. ret = iio_device_register(indio_dev);
  480. if (ret < 0) {
  481. dev_err(&pdev->dev, "could not register the device\n");
  482. goto fail_register;
  483. }
  484. return 0;
  485. fail_register:
  486. iio_map_array_unregister(indio_dev);
  487. fail_map:
  488. regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
  489. if (info->data->adc_en2)
  490. regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
  491. return ret;
  492. }
  493. static int axp20x_remove(struct platform_device *pdev)
  494. {
  495. struct iio_dev *indio_dev = platform_get_drvdata(pdev);
  496. struct axp20x_adc_iio *info = iio_priv(indio_dev);
  497. iio_device_unregister(indio_dev);
  498. iio_map_array_unregister(indio_dev);
  499. regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
  500. if (info->data->adc_en2)
  501. regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
  502. return 0;
  503. }
  504. static struct platform_driver axp20x_adc_driver = {
  505. .driver = {
  506. .name = "axp20x-adc",
  507. },
  508. .id_table = axp20x_adc_id_match,
  509. .probe = axp20x_probe,
  510. .remove = axp20x_remove,
  511. };
  512. module_platform_driver(axp20x_adc_driver);
  513. MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
  514. MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
  515. MODULE_LICENSE("GPL");