hal_tpadc.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. /*
  2. * ===========================================================================================
  3. *
  4. * Filename: hal_tpadc.c
  5. *
  6. * Description: tpadc hal layer code
  7. *
  8. * Version: Melis3.0
  9. * Create: 2020-1-14
  10. * Revision: none
  11. * Compiler: GCC:version 9.2.1 20170904 (release),ARM/embedded-7-branch revision 255204
  12. *
  13. * Author: liuyu@allwinnertech.com
  14. * Organization: SWC-BPD
  15. * Last Modified: 2021-1-14
  16. *
  17. * ===========================================================================================
  18. */
  19. #include <hal_interrupt.h>
  20. #include <hal_clk.h>
  21. #include <hal_reset.h>
  22. #include "sunxi_hal_tpadc.h"
  23. hal_tpadc_t hal_tpadc;
  24. static void sunxi_flush_fifo(unsigned long reg_base)
  25. {
  26. uint32_t reg_val;
  27. reg_val = readl(reg_base + TP_INT_FIFOC);
  28. reg_val = SET_BITS(TP_FIFO_FLUSH, TP_FIFO_FLUSH_WIDTH,reg_val, 0x1);
  29. writel(reg_val, reg_base + TP_INT_FIFOC);
  30. }
  31. static void sunxi_clear_fifo_status(unsigned long reg_base)
  32. {
  33. uint32_t reg_val;
  34. reg_val = readl(reg_base + TP_INT_FIFOS);
  35. reg_val = SET_BITS(FIFO_OVERRUN_PENDING, FIFO_OVERRUN_PENDIN_WIDTH,
  36. reg_val, 0x0);
  37. reg_val = SET_BITS(FIFO_DATA_PENDING, FIFO_DATA_PENDING_WIDTH,
  38. reg_val, 0x0);
  39. writel(reg_val, reg_base + TP_INT_FIFOS);
  40. }
  41. static void sunxi_set_acqiure_time(unsigned long reg_base, uint32_t val)
  42. {
  43. uint32_t reg_val;
  44. reg_val = readl(reg_base + TP_CTRL0);
  45. reg_val = SET_BITS(TACQ, TACQ_WIDTH, reg_val, val);
  46. writel(reg_val, reg_base + TP_CTRL0);
  47. }
  48. static void sunxi_set_frequency_divider(unsigned long reg_base, uint32_t val)
  49. {
  50. uint32_t reg_val;
  51. reg_val = readl(reg_base + TP_CTRL0);
  52. reg_val = SET_BITS(FS_DIV, FS_DIV_WIDTH, reg_val, val);
  53. writel(reg_val, reg_base + TP_CTRL0);
  54. }
  55. static void sunxi_set_clk_divider(unsigned long reg_base, uint32_t val)
  56. {
  57. uint32_t reg_val;
  58. reg_val = readl(reg_base + TP_CTRL0);
  59. reg_val = SET_BITS(ADC_CLK_DIVIDER, ADC_CLK_DIVIDER_WIDTH, reg_val, val);
  60. writel(reg_val, reg_base + TP_CTRL0);
  61. }
  62. static void sunxi_select_delay_mode(unsigned long reg_base, uint32_t val)
  63. {
  64. uint32_t reg_val;
  65. reg_val = readl(reg_base + TP_CTRL0);
  66. reg_val = SET_BITS(ADC_FIRST_DLY_MODE, ADC_FIRST_DLY_MODE_WIDTH,reg_val, val);
  67. writel(reg_val, reg_base + TP_CTRL0);
  68. }
  69. static void sunxi_set_dealy_time(unsigned long reg_base, uint32_t val)
  70. {
  71. uint32_t reg_val;
  72. reg_val = readl(reg_base + TP_CTRL0);
  73. reg_val = SET_BITS(ADC_FIRST_DLY, ADC_FIRST_DLY_WIDTH,reg_val, val);
  74. writel(reg_val, reg_base + TP_CTRL0);
  75. }
  76. static void sunxi_clk_init(unsigned long reg_base)
  77. {
  78. sunxi_set_acqiure_time(reg_base, 0x02); //2us
  79. sunxi_set_frequency_divider(reg_base, 0xb);
  80. sunxi_set_clk_divider(reg_base, 0x3);
  81. sunxi_select_delay_mode(reg_base, 0x1);
  82. sunxi_set_dealy_time(reg_base, 0xf);
  83. }
  84. static uint32_t sunxi_tpadc_adc_ch_select(unsigned long reg_base, tp_channel_id id)
  85. {
  86. uint32_t reg_val;
  87. reg_val = readl(reg_base + TP_CTRL1);
  88. switch (id) {
  89. case TP_CH_0:
  90. reg_val |= TP_CH0_SELECT;
  91. break;
  92. case TP_CH_1:
  93. reg_val |= TP_CH1_SELECT;
  94. break;
  95. case TP_CH_2:
  96. reg_val |= TP_CH2_SELECT;
  97. break;
  98. case TP_CH_3:
  99. reg_val |= TP_CH3_SELECT;
  100. break;
  101. default:
  102. TPADC_ERR("%s, invalid channel id!", __func__);
  103. return TPADC_ERROR;
  104. }
  105. writel(reg_val, reg_base + TP_CTRL1);
  106. return 0;
  107. }
  108. /* 0:TAPADC 1: ADC*/
  109. static void sunxi_tpadc_mode_select(unsigned long reg_base, uint32_t val)
  110. {
  111. uint32_t reg_val;
  112. reg_val = readl(reg_base + TP_CTRL1);
  113. reg_val = SET_BITS(TP_MODE_SELECT, TP_MODE_SELECT_WIDTH,reg_val, val);
  114. writel(reg_val, reg_base + TP_CTRL1);
  115. }
  116. static void sunxi_tpadc_enable(unsigned long reg_base, uint32_t val)
  117. {
  118. uint32_t reg_val;
  119. reg_val = readl(reg_base + TP_CTRL1);
  120. reg_val = SET_BITS(TP_EN, TP_EN_WIDTH, reg_val, val);
  121. writel(reg_val, reg_base + TP_CTRL1);
  122. }
  123. static void sunxi_set_up_debou_time(unsigned long reg_base, uint32_t val)
  124. {
  125. uint32_t reg_val;
  126. reg_val = readl(reg_base + TP_CTRL1);
  127. reg_val = SET_BITS(TP_DEBOUNCE, TP_DEBOUNCE_WIDTH, reg_val, val);
  128. writel(reg_val, reg_base + TP_CTRL1);
  129. }
  130. static void sunxi_set_pressure_thresholed(unsigned long reg_base, uint32_t val)
  131. {
  132. uint32_t reg_val;
  133. reg_val = readl(reg_base + TP_CTRL2);
  134. reg_val = SET_BITS(PRE_MEA, PRE_MEA_WIDTH, reg_val, val);
  135. writel(reg_val, reg_base + TP_CTRL2);
  136. }
  137. static void sunxi_pressure_enable(unsigned long reg_base)
  138. {
  139. uint32_t reg_val;
  140. reg_val = readl(reg_base + TP_CTRL2);
  141. reg_val = SET_BITS(PRE_MEA_EN, PRE_MEA_EN_WIDTH, reg_val, 0x1);
  142. writel(reg_val, reg_base + TP_CTRL2);
  143. }
  144. /* 0: x_data y_data x_data y_data */
  145. static void sunxi_tp_mode_fifo_select(unsigned long reg_base, uint32_t val)
  146. {
  147. uint32_t reg_val;
  148. reg_val = readl(reg_base + TP_CTRL2);
  149. reg_val = SET_BITS(TP_FIFO_MODE, TP_FIFO_MODE_WIDTH, reg_val, val);
  150. writel(reg_val, reg_base + TP_CTRL2);
  151. }
  152. static void sunxi_set_sensitivity(unsigned long reg_base, uint32_t val)
  153. {
  154. uint32_t reg_val;
  155. reg_val = readl(reg_base + TP_CTRL2);
  156. reg_val = SET_BITS(TP_SENSITIVE, TP_SENSITIVE_WIDTH, reg_val, val);
  157. writel(reg_val, reg_base + TP_CTRL2);
  158. }
  159. static void sunxi_set_filter_type(unsigned long reg_base, uint32_t val)
  160. {
  161. uint32_t reg_val;
  162. reg_val = readl(reg_base + TP_CTRL3);
  163. reg_val = SET_BITS(FILTER_TYPE, FILTER_TYPE_WIDTH, reg_val, val);
  164. writel(reg_val, reg_base + TP_CTRL3);
  165. }
  166. static void sunxi_filter_enable(unsigned long reg_base)
  167. {
  168. uint32_t reg_val;
  169. reg_val = readl(reg_base + TP_CTRL3);
  170. reg_val = SET_BITS(FILTER_EN, FILTER_EN_WIDTH, reg_val, 0x1);
  171. writel(reg_val, reg_base + TP_CTRL3);
  172. }
  173. static void sunxi_downirq_enable(unsigned long reg_base)
  174. {
  175. uint32_t reg_val;
  176. reg_val = readl(reg_base + TP_INT_FIFOC);
  177. reg_val = SET_BITS(TP_DOWN_IRQ_EN, TP_DOWN_IRQ_ENWIDTH, reg_val, 0x1);
  178. writel(reg_val, reg_base + TP_INT_FIFOC);
  179. }
  180. static void sunxi_upirq_enable(unsigned long reg_base)
  181. {
  182. uint32_t reg_val;
  183. reg_val = readl(reg_base + TP_INT_FIFOC);
  184. reg_val = SET_BITS(TP_UP_IRQ_EN, TP_UP_IRQ_EN_WIDTH, reg_val, 0x1);
  185. writel(reg_val, reg_base + TP_INT_FIFOC);
  186. }
  187. static void sunxi_drq_enable(unsigned long reg_base)
  188. {
  189. uint32_t reg_val;
  190. reg_val = readl(reg_base + TP_INT_FIFOC);
  191. reg_val = SET_BITS(TP_DATA_DRQ_EN, TP_DATA_DRQ_EN_WIDTH, reg_val, 0x1);
  192. writel(reg_val, reg_base + TP_INT_FIFOC);
  193. }
  194. static void sunxi_set_trig_level(unsigned long reg_base, uint32_t val)
  195. {
  196. uint32_t reg_val;
  197. reg_val = readl(reg_base + TP_INT_FIFOC);
  198. reg_val = SET_BITS(TP_FIFO_TRIG, TP_FIFO_TRIG_WIDTH, reg_val, val);
  199. writel(reg_val, reg_base + TP_INT_FIFOC);
  200. }
  201. static void sunxi_xydata_change_enable(unsigned long reg_base, uint32_t val)
  202. {
  203. uint32_t reg_val;
  204. reg_val = readl(reg_base + TP_INT_FIFOC);
  205. reg_val = SET_BITS(TP_DATA_XY_CHANGE, TP_DATA_XY_CHANGE_WIDTH, reg_val, val);
  206. writel(reg_val, reg_base + TP_INT_FIFOC);
  207. }
  208. static void sunxi_irq_enable(unsigned long reg_base)
  209. {
  210. uint32_t reg_val;
  211. reg_val = readl(reg_base + TP_INT_FIFOC);
  212. reg_val = SET_BITS(TP_DATA_IRQ_EN, TP_DATA_IRQ_EN_WIDTH, reg_val, 0x1);
  213. writel(reg_val, reg_base + TP_INT_FIFOC);
  214. }
  215. static void sunxi_irq_disable(unsigned long reg_base)
  216. {
  217. uint32_t reg_val;
  218. reg_val = readl(reg_base + TP_INT_FIFOC);
  219. reg_val = SET_BITS(TP_DATA_IRQ_EN, TP_DATA_IRQ_EN_WIDTH, reg_val, 0x0);
  220. writel(reg_val, reg_base + TP_INT_FIFOC);
  221. }
  222. static void sunxi_overrun_enable(unsigned long reg_base)
  223. {
  224. uint32_t reg_val;
  225. reg_val = readl(reg_base + TP_INT_FIFOC);
  226. reg_val = SET_BITS(TP_FIFO_OVERRUN_IRQ, TP_FIFO_OVERRUN_IRQ_WIDTH, reg_val, 0x1);
  227. writel(reg_val, reg_base + TP_INT_FIFOC);
  228. }
  229. static u32 sunxi_tpadc_irq_status(unsigned long reg_base)
  230. {
  231. return readl(reg_base + TP_INT_FIFOS);
  232. }
  233. static void sunxi_tpadc_clear_pending(unsigned long reg_base)
  234. {
  235. int reg;
  236. reg = readl(reg_base + TP_INT_FIFOS);
  237. writel(reg, reg_base + TP_INT_FIFOS);
  238. }
  239. static u32 sunxi_tpadc_ch_select(unsigned long reg_base, tp_channel_id id)
  240. {
  241. u32 reg_val;
  242. reg_val = readl(reg_base + TP_CTRL1);
  243. switch (id) {
  244. case TP_CH_0:
  245. reg_val |= TP_CH0_SELECT;
  246. break;
  247. case TP_CH_1:
  248. reg_val |= TP_CH1_SELECT;
  249. break;
  250. case TP_CH_2:
  251. reg_val |= TP_CH2_SELECT;
  252. break;
  253. case TP_CH_3:
  254. reg_val |= TP_CH3_SELECT;
  255. break;
  256. default:
  257. TPADC_ERR("%s, invalid channel id!", __func__);
  258. return -1;
  259. }
  260. writel(reg_val, reg_base + TP_CTRL1);
  261. return 0;
  262. }
  263. static int sunxi_tpadc_ch_deselect(unsigned long reg_base, tp_channel_id id)
  264. {
  265. u32 reg_val;
  266. reg_val = readl(reg_base + TP_CTRL1);
  267. switch (id) {
  268. case TP_CH_0:
  269. reg_val &= ~TP_CH0_SELECT;
  270. break;
  271. case TP_CH_1:
  272. reg_val &= ~TP_CH1_SELECT;
  273. break;
  274. case TP_CH_2:
  275. reg_val &= ~TP_CH2_SELECT;
  276. break;
  277. case TP_CH_3:
  278. reg_val &= ~TP_CH3_SELECT;
  279. break;
  280. default:
  281. TPADC_ERR("%s, invalid channel id!", __func__);
  282. return -1;
  283. }
  284. writel(reg_val, reg_base + TP_CTRL1);
  285. return 0;
  286. }
  287. static u32 hal_tpadc_data_read(unsigned long reg_base)
  288. {
  289. hal_tpadc_t *tpadc = &hal_tpadc;
  290. return readl(reg_base + TP_DATA);
  291. }
  292. static int hal_tpadc_callback(uint32_t data, data_flag_t flag)
  293. {
  294. TPADC_INFO("tpadc : tpadc mode interrupt, data_flag is %ld", flag);
  295. return 0;
  296. }
  297. static int hal_tpadc_adc_callback(uint32_t data, tp_channel_id channel)
  298. {
  299. TPADC_INFO("tpadc : auxiliary adc mode interrupt");
  300. return 0;
  301. }
  302. static void sunxi_tpadc_setup(hal_tpadc_t *tpadc)
  303. {
  304. u32 i;
  305. tpadc->reg_base = (unsigned long)TPADC_BASE;
  306. tpadc->irq_num = SUNXI_TPADC_IRQ;
  307. tpadc->rst_clk_id = (hal_reset_id_t)RST_BUS_TPADC;
  308. tpadc->bus_clk_id = (hal_clk_id_t)CLK_BUS_TPADC;
  309. tpadc->mod_clk_id = (hal_clk_id_t)CLK_TPADC;
  310. tpadc->callback = hal_tpadc_callback;
  311. for(i=0; i<TP_CH_MAX; i++)
  312. tpadc->adc_callback[i] = hal_tpadc_adc_callback;
  313. }
  314. static hal_tpadc_status_t hal_tpadc_clk_init(hal_tpadc_t *tpadc)
  315. {
  316. hal_clk_type_t clk_type = HAL_SUNXI_CCU;
  317. hal_clk_id_t bus_clk_id = tpadc->bus_clk_id;
  318. hal_clk_id_t mod_clk_id = tpadc->mod_clk_id;
  319. hal_reset_type_t reset_type = HAL_SUNXI_RESET;
  320. hal_reset_id_t tpadc_reset_id = tpadc->rst_clk_id;
  321. struct reset_control *reset;
  322. reset = hal_reset_control_get(reset_type, tpadc_reset_id);
  323. if (hal_reset_control_deassert(reset))
  324. {
  325. TPADC_ERR("tpadc reset deassert failed!");
  326. return TPADC_ERROR;
  327. }
  328. hal_reset_control_put(reset);
  329. tpadc->mod_clk = hal_clock_get(clk_type, mod_clk_id);
  330. if (hal_clock_enable(tpadc->mod_clk))
  331. {
  332. TPADC_ERR("tpadc mod clk enable mclk failed!");
  333. return TPADC_ERROR;
  334. }
  335. tpadc->bus_clk = hal_clock_get(clk_type, bus_clk_id);
  336. if (hal_clock_enable(tpadc->bus_clk))
  337. {
  338. TPADC_ERR("tpadc bus clk enable mclk failed!");
  339. return TPADC_ERROR;
  340. }
  341. return TPADC_OK;
  342. }
  343. static hal_tpadc_status_t hal_tpadc_clk_exit(hal_tpadc_t *tpadc)
  344. {
  345. hal_clock_disable(tpadc->bus_clk);
  346. hal_clock_put(tpadc->bus_clk);
  347. hal_clock_disable(tpadc->mod_clk);
  348. hal_clock_put(tpadc->mod_clk);
  349. return TPADC_OK;
  350. }
  351. /* the rtpadc tpadc mode interface */
  352. static irqreturn_t tpadc_handler(int irq, void *dev)
  353. {
  354. hal_tpadc_t *tpadc = (hal_tpadc_t *)dev;
  355. u32 reg_val;
  356. u32 x_data, y_data;
  357. u32 i;
  358. reg_val = sunxi_tpadc_irq_status(tpadc->reg_base);
  359. if (reg_val & TP_DATAPEND) {
  360. x_data = hal_tpadc_data_read(tpadc->reg_base);
  361. tpadc->callback(x_data, DATA_X);
  362. y_data = hal_tpadc_data_read(tpadc->reg_base);
  363. tpadc->callback(y_data, DATA_Y);
  364. }
  365. if (reg_val & TP_UPPEND) {
  366. tpadc->callback(0, DATA_UP);
  367. }
  368. if (reg_val & TP_DOWNPEND) {
  369. TPADC_INFO("touch down ");
  370. }
  371. sunxi_tpadc_clear_pending(tpadc->reg_base);
  372. return TPADC_OK;
  373. }
  374. hal_tpadc_status_t hal_tpadc_register_callback(tpadc_usercallback_t user_callback)
  375. {
  376. hal_tpadc_t *tpadc = &hal_tpadc;
  377. if (user_callback == NULL)
  378. return TPADC_ERROR;
  379. else
  380. tpadc->callback = user_callback;
  381. return TPADC_OK;
  382. }
  383. hal_tpadc_status_t hal_tpadc_init(void)
  384. {
  385. hal_tpadc_t *tpadc = &hal_tpadc;
  386. u32 clk_in;
  387. sunxi_tpadc_setup(tpadc);
  388. if (hal_tpadc_clk_init(tpadc))
  389. {
  390. TPADC_ERR("tpadc init clk error");
  391. return TPADC_ERROR;
  392. }
  393. /* clear status */
  394. sunxi_flush_fifo(tpadc->reg_base);
  395. sunxi_clear_fifo_status(tpadc->reg_base);
  396. sunxi_clk_init(tpadc->reg_base);
  397. sunxi_tpadc_mode_select(tpadc->reg_base, 0);
  398. sunxi_tpadc_enable(tpadc->reg_base, 1);
  399. sunxi_set_up_debou_time(tpadc->reg_base, 0x00);
  400. sunxi_set_pressure_thresholed(tpadc->reg_base, 0x800fff);
  401. sunxi_pressure_enable(tpadc->reg_base);
  402. sunxi_tp_mode_fifo_select(tpadc->reg_base, 0x00);
  403. sunxi_set_sensitivity(tpadc->reg_base, 0xf);
  404. sunxi_set_filter_type(tpadc->reg_base, 0x1);
  405. sunxi_filter_enable(tpadc->reg_base);
  406. sunxi_downirq_enable(tpadc->reg_base);
  407. sunxi_upirq_enable(tpadc->reg_base);
  408. sunxi_drq_enable(tpadc->reg_base);
  409. sunxi_set_trig_level(tpadc->reg_base, 0x1);
  410. sunxi_xydata_change_enable(tpadc->reg_base, 0);
  411. sunxi_irq_enable(tpadc->reg_base);
  412. sunxi_overrun_enable(tpadc->reg_base);
  413. sunxi_tpadc_clear_pending(tpadc->reg_base);
  414. if (request_irq(tpadc->irq_num, tpadc_handler, 0, "tpadc", tpadc))
  415. {
  416. TPADC_ERR("tpadc request irq(%d) failed \n", tpadc->irq_num);
  417. return TPADC_ERROR;
  418. }
  419. enable_irq(tpadc->irq_num);
  420. TPADC_INFO("tpadc init success");
  421. return TPADC_OK;
  422. }
  423. hal_tpadc_status_t hal_tpadc_exit(void)
  424. {
  425. hal_tpadc_t *tpadc = &hal_tpadc;
  426. sunxi_irq_disable(tpadc->reg_base);
  427. free_irq(tpadc->irq_num, tpadc);
  428. hal_tpadc_clk_exit(tpadc);
  429. return TPADC_OK;
  430. }
  431. hal_tpadc_status_t hal_tpadc_resume(void)
  432. {
  433. hal_tpadc_t *tpadc = &hal_tpadc;
  434. hal_tpadc_clk_init(tpadc);
  435. sunxi_tpadc_enable(tpadc->reg_base, 1);
  436. return TPADC_OK;
  437. }
  438. hal_tpadc_status_t hal_tpadc_suspend(void)
  439. {
  440. hal_tpadc_t *tpadc = &hal_tpadc;
  441. sunxi_tpadc_enable(tpadc->reg_base, 0);
  442. hal_tpadc_clk_exit(tpadc);
  443. return TPADC_OK;
  444. }
  445. /* the rtpadc adc mode interface*/
  446. static irqreturn_t tpadc_adc_handler(int irq, void *dev)
  447. {
  448. hal_tpadc_t *tpadc = (hal_tpadc_t *)dev;
  449. u32 reg_val;
  450. u32 data;
  451. reg_val = sunxi_tpadc_irq_status(tpadc->reg_base);
  452. if (reg_val & TP_DATAPEND) {
  453. reg_val = readl(tpadc->reg_base + TP_CTRL1);
  454. if (reg_val & TP_CH0_SELECT)
  455. {
  456. data = hal_tpadc_data_read(tpadc->reg_base);
  457. if (tpadc->adc_callback[0])
  458. tpadc->adc_callback[0](data, TP_CH0_SELECT);
  459. }
  460. if (reg_val & TP_CH1_SELECT)
  461. {
  462. data = hal_tpadc_data_read(tpadc->reg_base);
  463. if (tpadc->adc_callback[1])
  464. tpadc->adc_callback[1](data, TP_CH1_SELECT);
  465. }
  466. if (reg_val & TP_CH2_SELECT)
  467. {
  468. data = hal_tpadc_data_read(tpadc->reg_base);
  469. if (tpadc->adc_callback[2])
  470. tpadc->adc_callback[2](data, TP_CH2_SELECT);
  471. }
  472. if (reg_val & TP_CH3_SELECT)
  473. {
  474. data = hal_tpadc_data_read(tpadc->reg_base);
  475. if (tpadc->adc_callback[3])
  476. tpadc->adc_callback[3](data, TP_CH3_SELECT);
  477. }
  478. if (reg_val & 0x0)
  479. {
  480. TPADC_ERR("no channel init, you need init 1~4 channel first");
  481. return -IRQ_HANDLED;
  482. }
  483. }
  484. sunxi_tpadc_clear_pending(tpadc->reg_base);
  485. return IRQ_NONE;
  486. }
  487. hal_tpadc_status_t hal_tpadc_adc_register_callback(tp_channel_id channel, tpadc_adc_usercallback_t user_adc_callback)
  488. {
  489. hal_tpadc_t *tpadc = &hal_tpadc;
  490. if (user_adc_callback == NULL)
  491. return TPADC_ERROR;
  492. else
  493. tpadc->adc_callback[channel] = user_adc_callback;
  494. return TPADC_OK;
  495. }
  496. hal_tpadc_status_t hal_tpadc_adc_init(void)
  497. {
  498. hal_tpadc_t *tpadc = &hal_tpadc;
  499. u32 clk_in;
  500. sunxi_tpadc_setup(tpadc);
  501. if (hal_tpadc_clk_init(tpadc))
  502. {
  503. TPADC_ERR("tpadc init clk error");
  504. return TPADC_ERROR;
  505. }
  506. /* clear status */
  507. sunxi_flush_fifo(tpadc->reg_base);
  508. sunxi_clear_fifo_status(tpadc->reg_base);
  509. sunxi_clk_init(tpadc->reg_base);
  510. sunxi_tpadc_mode_select(tpadc->reg_base, 1);
  511. sunxi_tpadc_enable(tpadc->reg_base, 1);
  512. sunxi_set_filter_type(tpadc->reg_base, 0x1);
  513. sunxi_filter_enable(tpadc->reg_base);
  514. sunxi_downirq_enable(tpadc->reg_base);
  515. sunxi_upirq_enable(tpadc->reg_base);
  516. sunxi_set_trig_level(tpadc->reg_base, 0x3);
  517. sunxi_irq_enable(tpadc->reg_base);
  518. sunxi_tpadc_clear_pending(tpadc->reg_base);
  519. if (request_irq(tpadc->irq_num, tpadc_adc_handler, 0, "tpadc", tpadc))
  520. {
  521. TPADC_ERR("tpadc request irq(%d) failed \n", tpadc->irq_num);
  522. return TPADC_ERROR;
  523. }
  524. enable_irq(tpadc->irq_num);
  525. TPADC_INFO("tpadc init success");
  526. return TPADC_OK;
  527. }
  528. hal_tpadc_status_t hal_tpadc_adc_channel_init(tp_channel_id channel)
  529. {
  530. hal_tpadc_t *tpadc = &hal_tpadc;
  531. if (sunxi_tpadc_adc_ch_select(tpadc->reg_base, channel))
  532. {
  533. TPADC_ERR("TPADC adc mode channel select error");
  534. return -1;
  535. }
  536. return 0;
  537. }
  538. hal_tpadc_status_t hal_tpadc_adc_exit()
  539. {
  540. hal_tpadc_t *tpadc = &hal_tpadc;
  541. sunxi_irq_disable(tpadc->reg_base);
  542. free_irq(tpadc->irq_num, tpadc);
  543. hal_clock_disable(tpadc->bus_clk);
  544. hal_clock_put(tpadc->bus_clk);
  545. hal_clock_disable(tpadc->mod_clk);
  546. hal_clock_put(tpadc->mod_clk);
  547. return TPADC_OK;
  548. }