axp20x_adc.c 30 KB

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