light_adc.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2021 Alibaba Group Holding Limited.
  4. */
  5. #include <linux/module.h>
  6. #include <linux/platform_device.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/delay.h>
  9. #include <linux/kernel.h>
  10. #include <linux/slab.h>
  11. #include <linux/io.h>
  12. #include <linux/iopoll.h>
  13. #include <linux/clk.h>
  14. #include <linux/completion.h>
  15. #include <linux/of.h>
  16. #include <linux/of_irq.h>
  17. #include <linux/regulator/consumer.h>
  18. #include <linux/of_platform.h>
  19. #include <linux/err.h>
  20. #include <linux/iio/iio.h>
  21. #include <linux/iio/buffer.h>
  22. #include <linux/iio/sysfs.h>
  23. /* This will be the driver name the kernel reports */
  24. #define DRIVER_NAME "light-adc"
  25. /* ADC registers */
  26. #define LIGHT_ADC_PHY_CFG 0x00
  27. #define LIGHT_ADC_PHY_CTRL 0x04
  28. #define LIGHT_ADC_PHY_TEST 0x08
  29. #define LIGHT_ADC_OP_CTRL 0x0C
  30. #define LIGHT_ADC_OP_SINGLE_START 0x10
  31. #define LIGHT_ADC_FCLK_CTRL 0x14
  32. #define LIGHT_ADC_START_TIME 0x18
  33. #define LIGHT_ADC_SAMPLE_TIME 0x1C
  34. #define LIGHT_ADC_SAMPLE_DATA 0x20
  35. #define LIGHT_ADC_INT_CTRL1 0x50
  36. #define LIGHT_ADC_INT_CTRL2 0x54
  37. #define LIGHT_ADC_INT_STATUS 0x58
  38. #define LIGHT_ADC_INT_ACTUAL_VALUE_CH0 0x60
  39. #define LIGHT_ADC_INT_ACTUAL_VALUE_CH1 0x64
  40. #define LIGHT_ADC_INT_DELTA_VALUE_CH0 0x90
  41. #define LIGHT_ADC_INT_DELTA_VALUE_CH1 0x94
  42. /* Configuration register field define */
  43. #define LIGHT_ADC_PHY_CFG_SELRES_6BIT (0x0)
  44. #define LIGHT_ADC_PHY_CFG_SELRES_8BIT (0x1)
  45. #define LIGHT_ADC_PHY_CFG_SELRES_10BIT (0x2)
  46. #define LIGHT_ADC_PHY_CFG_SELRES_12BIT (0x3)
  47. #define LIGHT_ADC_PHY_CFG_SELDIFF_SINGLE_ENDED_INPUTS (0x0 << 4)
  48. #define LIGHT_ADC_PHY_CFG_SELDIFF_DIFFERENTIAL_INPUTS (0x1 << 4)
  49. #define LIGHT_ADC_PHY_CFG_SELBG_INTERNAL (0x1 << 8)
  50. #define LIGHT_ADC_PHY_CFG_SELBG_EXTERNAL (0x0 << 8)
  51. #define LIGHT_ADC_PHY_CFG_SELREF_INTERNAL (0x1 << 12)
  52. #define LIGHT_ADC_PHY_CFG_SELREF_EXT (0x0 << 12)
  53. /* PHY CTRL register field define */
  54. #define LIGHT_ADC_PHY_CTRL_ENOFFSET_EN (0x1 << 12)
  55. #define LIGHT_ADC_PHY_CTRL_ENOFFMEAS_EN (0x1 << 8)
  56. #define LIGHT_ADC_PHY_CTRL_RST_EN (0x1 << 4)
  57. #define LIGHT_ADC_PHY_CTRL_ENADC_EN (0x1 << 0)
  58. /* ADC OP ctrl field define */
  59. #define LIGHT_ADC_OP_CTRL_CH_EN_ALL GENMASK(19, 12)
  60. #define LIGHT_ADC_OP_CTRL_CH_EN_0 (12)
  61. #define LIGHT_ADC_OP_CTRL_MODE_SINGLE (0x1 << 0)
  62. #define LIGHT_ADC_OP_CTRL_MODE_CONTINOUS (0x0 << 0)
  63. /* ADC OP single start */
  64. #define LIGHT_ADC_OP_SINGLE_START_EN BIT(0)
  65. /* ADC fclk ctrl */
  66. #define LIGHT_ADC_FCLK_CTRL_FCLLK_DIV GENMASK(6, 0)
  67. #define LIGHT_ADC_FCLK_CTRL_TYP_1M (0x10004)
  68. #define LIGHT_ADC_START_TIME_TYP_1M (0x160)
  69. #define LIGHT_ADC_SAMPLE_TIME_TYP_1M (0x10)
  70. #define LIGHT_ADC_SAMPLE_TIME_TYP_6BIT (8)
  71. #define LIGHT_ADC_SAMPLE_TIME_TYP_8BIT (10)
  72. #define LIGHT_ADC_SAMPLE_TIME_TYP_10BIT (12)
  73. #define LIGHT_ADC_SAMPLE_TIME_TYP_12BIT (14)
  74. /* ADC sample data */
  75. #define LIGHT_ADC_SAMPLE_DATA_CH1 GENMASK(27, 16)
  76. #define LIGHT_ADC_SAMPLE_DATA_CH1_OFF (16)
  77. #define LIGHT_ADC_SAMPLE_DATA_CH1_VLD BIT(31)
  78. #define LIGHT_ADC_SAMPLE_DATA_CH1_NUMBER GENMASK(30, 28)
  79. #define LIGHT_ADC_SAMPLE_DATA_CH1_NUMBER_OFF (28)
  80. #define LIGHT_ADC_SAMPLE_DATA_CH0 GENMASK(11, 0)
  81. #define LIGHT_ADC_SAMPLE_DATA_CH0_VLD BIT(15)
  82. #define LIGHT_ADC_SAMPLE_DATA_CH0_OFF (0)
  83. #define LIGHT_ADC_SAMPLE_DATA_CH0_NUMBER GENMASK(14, 12)
  84. #define LIGHT_ADC_SAMPLE_DATA_CH0_NUMBER_OFF (12)
  85. /* ADC INT Ctrl */
  86. #define LIGHT_ADC_INT_CTRL1_CH1_INT_MODE BIT(1)
  87. #define LIGHT_ADC_INT_CTRL1_CH0_INT_MODE BIT(0)
  88. #define LIGHT_ADC_INT_CTRL2_CH1_INT_MASK BIT(1)
  89. #define LIGHT_ADC_INT_CTRL2_CH0_INT_MASK BIT(0)
  90. #define LIGHT_ADC_INT_STS_CH1_INT_STS BIT(1)
  91. #define LIGHT_ADC_INT_STS_CH0_INT_STS BIT(0)
  92. #define LIGHT_ADC_ACTUAL_VALUE_CH0_HVAL GENMASK(27, 16)
  93. #define LIGHT_ADC_ACTUAL_VALUE_CH0_HVAL_OFF (16)
  94. #define LIGHT_ADC_ACTUAL_VALUE_CH0_LVAL GENMASK(11, 0)
  95. #define LIGHT_ADC_ACTUAL_VALUE_CH0_LVAL_OFF (0)
  96. #define LIGHT_ADC_ACTUAL_VALUE_CH1_HVAL GENMASK(27, 16)
  97. #define LIGHT_ADC_ACTUAL_VALUE_CH1_HVAL_OFF (16)
  98. #define LIGHT_ADC_ACTUAL_VALUE_CH1_LVAL GENMASK(11, 0)
  99. #define LIGHT_ADC_ACTUAL_VALUE_CH1_LVAL_OFF (0)
  100. #define LIGHT_ADC_DLT_VALUE_CH0_HVAL GENMASK(27, 16)
  101. #define LIGHT_ADC_DLT_VALUE_CH0_HVAL_OFF (16)
  102. #define LIGHT_ADC_DLT_VALUE_CH0_LVAL GENMASK(11, 0)
  103. #define LIGHT_ADC_DLT_VALUE_CH0_LVAL_OFF (0)
  104. #define LIGHT_ADC_DLT_VALUE_CH1_HVAL GENMASK(27, 16)
  105. #define LIGHT_ADC_DLT_VALUE_CH1_HVAL_OFF (16)
  106. #define LIGHT_ADC_DLT_VALUE_CH1_LVAL GENMASK(11, 0)
  107. #define LIGHT_ADC_DLT_VALUE_CH1_LVAL_OFF (0)
  108. #define LIGHT_ADC_FIFO_DATA_SIZE 32
  109. #define LIGHT_ADC_PHY_ENCTR 0x8e0
  110. #define LIGHT_ADC_TIMEOUT 500000
  111. enum vol_ref {
  112. LIGHT_ADC_VOL_VREF,
  113. LIGHT_ADC_VOL_INTE,
  114. };
  115. enum input_mode_sel {
  116. LIGHT_ADC_SINGLE_ENDED_INPUTS,
  117. LIGHT_ADC_DIFFERENTIAL_INPUTS,
  118. };
  119. enum selres_sel {
  120. LIGHT_ADC_SELRES_6BIT = 6,
  121. LIGHT_ADC_SELRES_8BIT = 8,
  122. LIGHT_ADC_SELRES_10BIT = 10,
  123. LIGHT_ADC_SELRES_12BIT = 12,
  124. };
  125. enum offset_mode_sel {
  126. LIGHT_ADC_OFFSET_DIS = 0,
  127. LIGHT_ADC_OFFSET_EN,
  128. };
  129. enum conversion_mode_sel {
  130. LIGHT_ADC_MODE_SINGLE,
  131. LIGHT_ADC_MODE_CONTINOUS,
  132. };
  133. enum clk_sel {
  134. LIGHT_ADC_FCLK_TYP_1M,
  135. };
  136. enum int_actual_mask {
  137. LIGHT_ADC_ACTUAL_CH0,
  138. LIGHT_ADC_ACTUAL_CH1,
  139. LIGHT_ADC_ACTUAL_ALL,
  140. };
  141. enum int_delta_mask {
  142. LIGHT_ADC_DETAL_CH0,
  143. LIGHT_ADC_DETAL_CH1,
  144. LIGHT_ADC_DETAL_ALL,
  145. };
  146. struct light_adc_feature {
  147. enum selres_sel selres_sel;
  148. enum input_mode_sel input_mode;
  149. enum vol_ref vol_ref;
  150. enum offset_mode_sel offset_mode;
  151. enum conversion_mode_sel conv_mode;
  152. enum clk_sel clk_sel;
  153. enum int_actual_mask int_actual;
  154. enum int_delta_mask int_detal;
  155. };
  156. struct light_adc {
  157. struct device *dev;
  158. void __iomem *regs;
  159. struct clk *clk;
  160. u32 vref_uv;
  161. u32 value;
  162. struct regulator *vref;
  163. struct light_adc_feature adc_feature;
  164. u32 current_clk;
  165. u32 ch0_offmeas;
  166. u32 ch1_offmeas;
  167. struct completion completion;
  168. };
  169. static inline void light_adc_cfg_init(struct light_adc *info)
  170. {
  171. struct light_adc_feature *adc_feature = &info->adc_feature;
  172. /* set default Configuration for ADC controller */
  173. adc_feature->selres_sel = LIGHT_ADC_SELRES_12BIT;
  174. adc_feature->input_mode = LIGHT_ADC_SINGLE_ENDED_INPUTS;
  175. adc_feature->vol_ref = LIGHT_ADC_VOL_VREF;
  176. adc_feature->offset_mode = LIGHT_ADC_OFFSET_DIS;
  177. adc_feature->conv_mode = LIGHT_ADC_MODE_SINGLE;
  178. adc_feature->clk_sel = LIGHT_ADC_FCLK_TYP_1M;
  179. adc_feature->int_actual = LIGHT_ADC_ACTUAL_ALL;
  180. adc_feature->int_detal = LIGHT_ADC_DETAL_ALL;
  181. info->ch0_offmeas = 0;
  182. info->ch1_offmeas = 0;
  183. }
  184. static void light_adc_reg_set(struct light_adc *info)
  185. {
  186. struct light_adc_feature *adc_feature = &info->adc_feature;
  187. uint32_t phy_cfg = 0;
  188. uint32_t op_ctrl = 0;
  189. /* phy_cfg */
  190. switch (adc_feature->selres_sel) {
  191. case LIGHT_ADC_SELRES_6BIT:
  192. phy_cfg |= LIGHT_ADC_PHY_CFG_SELRES_6BIT;
  193. break;
  194. case LIGHT_ADC_SELRES_8BIT:
  195. phy_cfg |= LIGHT_ADC_PHY_CFG_SELRES_8BIT;
  196. break;
  197. case LIGHT_ADC_SELRES_10BIT:
  198. phy_cfg |= LIGHT_ADC_PHY_CFG_SELRES_10BIT;
  199. break;
  200. case LIGHT_ADC_SELRES_12BIT:
  201. phy_cfg |= LIGHT_ADC_PHY_CFG_SELRES_12BIT;
  202. break;
  203. default:
  204. break;
  205. }
  206. switch (adc_feature->input_mode) {
  207. case LIGHT_ADC_SINGLE_ENDED_INPUTS:
  208. phy_cfg |= LIGHT_ADC_PHY_CFG_SELDIFF_SINGLE_ENDED_INPUTS;
  209. break;
  210. case LIGHT_ADC_DIFFERENTIAL_INPUTS:
  211. phy_cfg |= LIGHT_ADC_PHY_CFG_SELDIFF_DIFFERENTIAL_INPUTS;
  212. break;
  213. default:
  214. break;
  215. }
  216. switch (adc_feature->vol_ref) {
  217. case LIGHT_ADC_VOL_VREF:
  218. phy_cfg |= LIGHT_ADC_PHY_CFG_SELBG_EXTERNAL | LIGHT_ADC_PHY_CFG_SELREF_EXT;
  219. break;
  220. case LIGHT_ADC_VOL_INTE:
  221. phy_cfg |= LIGHT_ADC_PHY_CFG_SELBG_INTERNAL | LIGHT_ADC_PHY_CFG_SELREF_INTERNAL;
  222. break;
  223. default:
  224. break;
  225. }
  226. /* op_ctrl */
  227. switch (adc_feature->conv_mode) {
  228. case LIGHT_ADC_MODE_SINGLE:
  229. op_ctrl |= LIGHT_ADC_OP_CTRL_MODE_SINGLE;
  230. break;
  231. case LIGHT_ADC_MODE_CONTINOUS:
  232. op_ctrl |= LIGHT_ADC_OP_CTRL_MODE_CONTINOUS;
  233. break;
  234. default:
  235. break;
  236. }
  237. writel(phy_cfg, info->regs + LIGHT_ADC_PHY_CFG);
  238. writel(op_ctrl, info->regs + LIGHT_ADC_OP_CTRL);
  239. writel(LIGHT_ADC_PHY_ENCTR, info->regs + LIGHT_ADC_PHY_TEST);
  240. /* disable the irq */
  241. writel(0xff, info->regs + LIGHT_ADC_INT_CTRL1);
  242. writel(0xff, info->regs + LIGHT_ADC_INT_CTRL2);
  243. if (adc_feature->conv_mode == LIGHT_ADC_MODE_CONTINOUS)
  244. writel(LIGHT_ADC_PHY_CTRL_ENADC_EN, info->regs + LIGHT_ADC_PHY_CTRL);
  245. }
  246. static void light_adc_fclk_set(struct light_adc *info)
  247. {
  248. struct light_adc_feature *adc_feature = &(info->adc_feature);
  249. int fclk_ctrl = 0;
  250. int start_time = 0;
  251. int sample_time = 0;
  252. switch (adc_feature->clk_sel) {
  253. case LIGHT_ADC_FCLK_TYP_1M:
  254. fclk_ctrl = LIGHT_ADC_FCLK_CTRL_TYP_1M;
  255. start_time = LIGHT_ADC_START_TIME_TYP_1M;
  256. if (adc_feature->selres_sel == LIGHT_ADC_SELRES_6BIT)
  257. sample_time = LIGHT_ADC_SAMPLE_TIME_TYP_6BIT;
  258. else if (adc_feature->selres_sel == LIGHT_ADC_SELRES_8BIT)
  259. sample_time = LIGHT_ADC_SAMPLE_TIME_TYP_8BIT;
  260. else if (adc_feature->selres_sel == LIGHT_ADC_SELRES_10BIT)
  261. sample_time = LIGHT_ADC_SAMPLE_TIME_TYP_10BIT;
  262. else if (adc_feature->selres_sel == LIGHT_ADC_SELRES_12BIT)
  263. sample_time = LIGHT_ADC_SAMPLE_TIME_TYP_12BIT;
  264. else {
  265. pr_err("[%s,%d]invalid selres select \n", __func__, __LINE__);
  266. return;
  267. }
  268. break;
  269. default:
  270. break;
  271. }
  272. writel(fclk_ctrl, info->regs + LIGHT_ADC_FCLK_CTRL);
  273. writel(start_time, info->regs + LIGHT_ADC_START_TIME);
  274. writel(sample_time, info->regs + LIGHT_ADC_SAMPLE_TIME);
  275. }
  276. static void light_adc_hw_init(struct light_adc *info)
  277. {
  278. light_adc_reg_set(info);
  279. light_adc_fclk_set(info);
  280. }
  281. #define LIGHT_ADC_CHAN(_idx, _chan_type) { \
  282. .type = (_chan_type), \
  283. .indexed = 1, \
  284. .channel = (_idx), \
  285. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  286. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
  287. BIT(IIO_CHAN_INFO_SAMP_FREQ), \
  288. }
  289. static const struct iio_chan_spec light_adc_iio_channels[] = {
  290. LIGHT_ADC_CHAN(0, IIO_VOLTAGE),
  291. LIGHT_ADC_CHAN(1, IIO_VOLTAGE),
  292. LIGHT_ADC_CHAN(2, IIO_VOLTAGE),
  293. LIGHT_ADC_CHAN(3, IIO_VOLTAGE),
  294. LIGHT_ADC_CHAN(4, IIO_VOLTAGE),
  295. LIGHT_ADC_CHAN(5, IIO_VOLTAGE),
  296. LIGHT_ADC_CHAN(6, IIO_VOLTAGE),
  297. LIGHT_ADC_CHAN(7, IIO_VOLTAGE),
  298. /* sentinel */
  299. };
  300. static irqreturn_t light_adc_isr(int irq, void *dev_id)
  301. {
  302. struct iio_dev *indio_dev = dev_id;
  303. struct light_adc *info = iio_priv(indio_dev);
  304. /* TBD */
  305. complete(&info->completion);
  306. return IRQ_HANDLED;
  307. }
  308. static int light_read_raw(struct iio_dev *indio_dev,
  309. struct iio_chan_spec const *chan,
  310. int *val,
  311. int *val2,
  312. long mask)
  313. {
  314. struct light_adc *info = iio_priv(indio_dev);
  315. int tmp;
  316. long ret;
  317. switch (mask) {
  318. case IIO_CHAN_INFO_RAW:
  319. mutex_lock(&indio_dev->mlock);
  320. if (info->adc_feature.conv_mode == LIGHT_ADC_MODE_SINGLE) {
  321. uint single_retry = LIGHT_ADC_FIFO_DATA_SIZE;
  322. uint ievent;
  323. uint vld_flag;
  324. uint op_ctrl = 0;
  325. uint real_chan;
  326. uint phy_ctrl;
  327. op_ctrl = readl(info->regs + LIGHT_ADC_OP_CTRL);
  328. op_ctrl &= ~LIGHT_ADC_OP_CTRL_CH_EN_ALL;
  329. op_ctrl |= (BIT(chan->channel + LIGHT_ADC_OP_CTRL_CH_EN_0) & LIGHT_ADC_OP_CTRL_CH_EN_ALL);
  330. writel(op_ctrl, info->regs + LIGHT_ADC_OP_CTRL);
  331. writel(LIGHT_ADC_PHY_CTRL_ENADC_EN, info->regs + LIGHT_ADC_PHY_CTRL);
  332. vld_flag = LIGHT_ADC_SAMPLE_DATA_CH0_VLD;
  333. while (single_retry--) {
  334. writel(LIGHT_ADC_OP_SINGLE_START_EN, info->regs + LIGHT_ADC_OP_SINGLE_START);
  335. /* wait the sampling result */
  336. ret = readl_poll_timeout(info->regs + LIGHT_ADC_SAMPLE_DATA,
  337. ievent,
  338. ievent & vld_flag, 100, LIGHT_ADC_TIMEOUT);
  339. if (ret)
  340. pr_err("wait the sampling timeout\n");
  341. real_chan = (ievent & LIGHT_ADC_SAMPLE_DATA_CH0_NUMBER) >> LIGHT_ADC_SAMPLE_DATA_CH0_NUMBER_OFF;
  342. if (real_chan == chan->channel)
  343. break;
  344. }
  345. phy_ctrl = readl(info->regs + LIGHT_ADC_PHY_CTRL);
  346. phy_ctrl &= ~ LIGHT_ADC_PHY_CTRL_ENADC_EN;
  347. writel(phy_ctrl, info->regs + LIGHT_ADC_PHY_CTRL);
  348. /* read the sampling data */
  349. *val = (ievent & LIGHT_ADC_SAMPLE_DATA_CH0) >> LIGHT_ADC_SAMPLE_DATA_CH0_OFF;
  350. } else {
  351. uint ievent;
  352. uint vld_flag;
  353. uint op_single;
  354. uint op_ctrl = 0;
  355. op_ctrl = readl(info->regs + LIGHT_ADC_OP_CTRL);
  356. op_ctrl &= ~LIGHT_ADC_OP_CTRL_CH_EN_ALL;
  357. op_ctrl |= (BIT(chan->channel + LIGHT_ADC_OP_CTRL_CH_EN_0) & LIGHT_ADC_OP_CTRL_CH_EN_ALL);
  358. writel(op_ctrl, info->regs + LIGHT_ADC_OP_CTRL);
  359. op_single = readl(info->regs + LIGHT_ADC_OP_SINGLE_START);
  360. op_single &= ~LIGHT_ADC_OP_SINGLE_START_EN;
  361. writel(op_single, info->regs + LIGHT_ADC_OP_SINGLE_START);
  362. vld_flag = LIGHT_ADC_SAMPLE_DATA_CH0_VLD | LIGHT_ADC_SAMPLE_DATA_CH1_VLD;
  363. /* wait the sampling result */
  364. ret = readl_poll_timeout(info->regs + LIGHT_ADC_SAMPLE_DATA,
  365. ievent,
  366. ievent & vld_flag, 10, LIGHT_ADC_TIMEOUT);
  367. if (ret)
  368. pr_err("wait the sampling timeout\n");
  369. /* read the sampling data */
  370. tmp = readl(info->regs + LIGHT_ADC_SAMPLE_DATA);
  371. if (tmp & LIGHT_ADC_SAMPLE_DATA_CH0_VLD)
  372. *val = (tmp & LIGHT_ADC_SAMPLE_DATA_CH0) >> LIGHT_ADC_SAMPLE_DATA_CH0_OFF;
  373. else {
  374. *val = (tmp & LIGHT_ADC_SAMPLE_DATA_CH1) >> LIGHT_ADC_SAMPLE_DATA_CH1_OFF;
  375. }
  376. }
  377. mutex_unlock(&indio_dev->mlock);
  378. return IIO_VAL_INT;
  379. case IIO_CHAN_INFO_SCALE:
  380. *val = info->vref_uv / 1000;
  381. *val2 = info->adc_feature.selres_sel;
  382. return IIO_VAL_FRACTIONAL_LOG2;
  383. case IIO_CHAN_INFO_SAMP_FREQ:
  384. *val = info->current_clk;
  385. *val2 = 0;
  386. return IIO_VAL_INT;
  387. default:
  388. break;
  389. }
  390. return -EINVAL;
  391. }
  392. static void light_adc_reset(struct light_adc *info)
  393. {
  394. u32 tmp;
  395. tmp = readl(info->regs + LIGHT_ADC_PHY_CTRL);
  396. tmp |= LIGHT_ADC_PHY_CTRL_RST_EN;
  397. writel(tmp, info->regs + LIGHT_ADC_PHY_CTRL);
  398. udelay(10);
  399. tmp &= ~LIGHT_ADC_PHY_CTRL_RST_EN;
  400. writel(tmp, info->regs + LIGHT_ADC_PHY_CTRL);
  401. }
  402. static void light_adc_set_clk(struct light_adc *info, int val)
  403. {
  404. int fclk_ctrl;
  405. u32 count;
  406. u32 apb_clk = clk_get_rate(info->clk);
  407. fclk_ctrl = readl(info->regs + LIGHT_ADC_FCLK_CTRL);
  408. count = DIV_ROUND_UP(apb_clk, val);
  409. info->current_clk = apb_clk / count;
  410. fclk_ctrl &= ~LIGHT_ADC_FCLK_CTRL_FCLLK_DIV;
  411. fclk_ctrl |= count;
  412. writel(fclk_ctrl, info->regs + LIGHT_ADC_FCLK_CTRL);
  413. }
  414. static int light_write_raw(struct iio_dev *indio_dev,
  415. struct iio_chan_spec const *chan,
  416. int val,
  417. int val2,
  418. long mask)
  419. {
  420. struct light_adc *info = iio_priv(indio_dev);
  421. if (mask != IIO_CHAN_INFO_SAMP_FREQ)
  422. return -EINVAL;
  423. mutex_lock(&indio_dev->mlock);
  424. light_adc_set_clk(info, val);
  425. mutex_unlock(&indio_dev->mlock);
  426. return 0;
  427. }
  428. static const struct iio_info light_adc_iio_info = {
  429. .read_raw = &light_read_raw,
  430. .write_raw = &light_write_raw,
  431. };
  432. static const struct of_device_id light_adc_match[] = {
  433. { .compatible = "thead,light-adc", },
  434. { /* sentinel */ }
  435. };
  436. MODULE_DEVICE_TABLE(of, light_adc_match);
  437. static ssize_t light_adc_res_show(struct device *dev, struct device_attribute *attr, char *buf)
  438. {
  439. struct platform_device *pdev = to_platform_device(dev);
  440. struct iio_dev *indio_dev = platform_get_drvdata(pdev);
  441. struct light_adc *info = iio_priv(indio_dev);
  442. size_t bufpos = 0, count = 5;
  443. snprintf(buf + bufpos, count - bufpos, "%.*x: ", 4, info->adc_feature.selres_sel);
  444. bufpos += 4;
  445. buf[bufpos++] = '\n';
  446. return bufpos;
  447. }
  448. static ssize_t light_adc_res_store(struct device *dev, struct device_attribute *attr,
  449. const char *buf, size_t size)
  450. {
  451. struct platform_device *pdev = to_platform_device(dev);
  452. struct iio_dev *indio_dev = platform_get_drvdata(pdev);
  453. struct light_adc *info = iio_priv(indio_dev);
  454. char *start = (char *)buf;
  455. unsigned long res;
  456. if (kstrtoul(start, 0, &res))
  457. return -EINVAL;
  458. switch (res) {
  459. case LIGHT_ADC_SELRES_6BIT:
  460. case LIGHT_ADC_SELRES_8BIT:
  461. case LIGHT_ADC_SELRES_10BIT:
  462. case LIGHT_ADC_SELRES_12BIT:
  463. info->adc_feature.selres_sel = res;
  464. light_adc_reset(info);
  465. light_adc_hw_init(info);
  466. break;
  467. default:
  468. dev_err(dev, "not support res\n");
  469. return -EINVAL;
  470. }
  471. return size;
  472. }
  473. static DEVICE_ATTR(light_adc_res, 0644, light_adc_res_show, light_adc_res_store);
  474. static int light_adc_probe(struct platform_device *pdev)
  475. {
  476. struct light_adc *info;
  477. struct iio_dev *indio_dev;
  478. struct resource *mem;
  479. int irq;
  480. int ret;
  481. indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct light_adc));
  482. if (!indio_dev) {
  483. dev_err(&pdev->dev, "Failed allocating iio device\n");
  484. return -ENOMEM;
  485. }
  486. info = iio_priv(indio_dev);
  487. info->dev = &pdev->dev;
  488. irq = platform_get_irq(pdev, 0);
  489. if (irq < 0)
  490. return irq;
  491. ret = devm_request_irq(info->dev, irq,
  492. light_adc_isr, 0,
  493. dev_name(&pdev->dev), indio_dev);
  494. if (ret < 0) {
  495. dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
  496. return ret;
  497. }
  498. mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  499. info->regs = devm_ioremap_resource(&pdev->dev, mem);
  500. if (IS_ERR(info->regs))
  501. return PTR_ERR(info->regs);
  502. info->clk = devm_clk_get(&pdev->dev, "adc");
  503. if (IS_ERR(info->clk)) {
  504. dev_err(&pdev->dev, "failed getting clock, err = %ld\n",
  505. PTR_ERR(info->clk));
  506. return PTR_ERR(info->clk);
  507. }
  508. info->vref = devm_regulator_get(&pdev->dev, "vref");
  509. if (IS_ERR(info->vref))
  510. return PTR_ERR(info->vref);
  511. ret = regulator_enable(info->vref);
  512. if (ret)
  513. return ret;
  514. info->vref_uv = regulator_get_voltage(info->vref);
  515. platform_set_drvdata(pdev, indio_dev);
  516. init_completion(&info->completion);
  517. indio_dev->name = dev_name(&pdev->dev);
  518. indio_dev->dev.parent = &pdev->dev;
  519. indio_dev->dev.of_node = pdev->dev.of_node;
  520. indio_dev->info = &light_adc_iio_info;
  521. indio_dev->modes = INDIO_DIRECT_MODE;
  522. indio_dev->channels = light_adc_iio_channels;
  523. indio_dev->num_channels = ARRAY_SIZE(light_adc_iio_channels);
  524. ret = clk_prepare_enable(info->clk);
  525. if (ret) {
  526. dev_err(&pdev->dev,
  527. "Could not prepare or enable the clock.\n");
  528. goto error_adc_clk_enable;
  529. }
  530. light_adc_cfg_init(info);
  531. light_adc_reset(info);
  532. light_adc_hw_init(info);
  533. ret = iio_device_register(indio_dev);
  534. if (ret) {
  535. dev_err(&pdev->dev, "Couldn't register the device.\n");
  536. goto error_iio_device_register;
  537. }
  538. ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light_adc_res.attr);
  539. if (ret) {
  540. dev_err(&pdev->dev, "Failed to create adc debug sysfs.\n");
  541. goto error_iio_device_register;
  542. }
  543. dev_info(&pdev->dev, "Thead light adc registered.\n");
  544. return 0;
  545. error_iio_device_register:
  546. clk_disable_unprepare(info->clk);
  547. error_adc_clk_enable:
  548. regulator_disable(info->vref);
  549. return ret;
  550. }
  551. static int light_adc_remove(struct platform_device *pdev)
  552. {
  553. struct iio_dev *indio_dev = platform_get_drvdata(pdev);
  554. struct light_adc *info = iio_priv(indio_dev);
  555. iio_device_unregister(indio_dev);
  556. regulator_disable(info->vref);
  557. clk_disable_unprepare(info->clk);
  558. return 0;
  559. }
  560. static int __maybe_unused light_adc_suspend(struct device *dev)
  561. {
  562. struct iio_dev *indio_dev = dev_get_drvdata(dev);
  563. struct light_adc *info = iio_priv(indio_dev);
  564. int phy_ctrl;
  565. phy_ctrl = readl(info->regs + LIGHT_ADC_PHY_CTRL);
  566. phy_ctrl &= ~ LIGHT_ADC_PHY_CTRL_ENADC_EN;
  567. writel(phy_ctrl, info->regs + LIGHT_ADC_PHY_CTRL);
  568. clk_disable_unprepare(info->clk);
  569. regulator_disable(info->vref);
  570. return 0;
  571. }
  572. static int __maybe_unused light_adc_resume(struct device *dev)
  573. {
  574. struct iio_dev *indio_dev = dev_get_drvdata(dev);
  575. struct light_adc *info = iio_priv(indio_dev);
  576. int ret;
  577. ret = regulator_enable(info->vref);
  578. if (ret)
  579. return ret;
  580. ret = clk_prepare_enable(info->clk);
  581. if (ret)
  582. goto disable_reg;
  583. light_adc_reset(info);
  584. light_adc_set_clk(info, info->current_clk);
  585. light_adc_hw_init(info);
  586. return 0;
  587. disable_reg:
  588. regulator_disable(info->vref);
  589. return ret;
  590. }
  591. static SIMPLE_DEV_PM_OPS(light_adc_pm_ops, light_adc_suspend, light_adc_resume);
  592. static struct platform_driver light_adc_driver = {
  593. .probe = light_adc_probe,
  594. .remove = light_adc_remove,
  595. .driver = {
  596. .name = DRIVER_NAME,
  597. .of_match_table = light_adc_match,
  598. .pm = &light_adc_pm_ops,
  599. },
  600. };
  601. module_platform_driver(light_adc_driver);
  602. MODULE_AUTHOR("fugang.duan <duanfugang.dfg@linux.alibaba.com>");
  603. MODULE_DESCRIPTION("Thead Light ADC driver");
  604. MODULE_LICENSE("GPL v2");