axp20x_adc.c 18 KB

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