wm8350-irq.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. /*
  2. * wm8350-irq.c -- IRQ support for Wolfson WM8350
  3. *
  4. * Copyright 2007, 2008, 2009 Wolfson Microelectronics PLC.
  5. *
  6. * Author: Liam Girdwood, Mark Brown
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. *
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/init.h>
  17. #include <linux/bug.h>
  18. #include <linux/device.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/workqueue.h>
  21. #include <linux/mfd/wm8350/core.h>
  22. #include <linux/mfd/wm8350/audio.h>
  23. #include <linux/mfd/wm8350/comparator.h>
  24. #include <linux/mfd/wm8350/gpio.h>
  25. #include <linux/mfd/wm8350/pmic.h>
  26. #include <linux/mfd/wm8350/rtc.h>
  27. #include <linux/mfd/wm8350/supply.h>
  28. #include <linux/mfd/wm8350/wdt.h>
  29. static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
  30. {
  31. mutex_lock(&wm8350->irq_mutex);
  32. if (wm8350->irq[irq].handler)
  33. wm8350->irq[irq].handler(wm8350, irq, wm8350->irq[irq].data);
  34. else {
  35. dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
  36. irq);
  37. wm8350_mask_irq(wm8350, irq);
  38. }
  39. mutex_unlock(&wm8350->irq_mutex);
  40. }
  41. /*
  42. * This is a threaded IRQ handler so can access I2C/SPI. Since all
  43. * interrupts are clear on read the IRQ line will be reasserted and
  44. * the physical IRQ will be handled again if another interrupt is
  45. * asserted while we run - in the normal course of events this is a
  46. * rare occurrence so we save I2C/SPI reads.
  47. */
  48. static irqreturn_t wm8350_irq(int irq, void *data)
  49. {
  50. struct wm8350 *wm8350 = data;
  51. u16 level_one, status1, status2, comp;
  52. /* TODO: Use block reads to improve performance? */
  53. level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
  54. & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
  55. status1 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_1)
  56. & ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_1_MASK);
  57. status2 = wm8350_reg_read(wm8350, WM8350_INT_STATUS_2)
  58. & ~wm8350_reg_read(wm8350, WM8350_INT_STATUS_2_MASK);
  59. comp = wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS)
  60. & ~wm8350_reg_read(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK);
  61. /* over current */
  62. if (level_one & WM8350_OC_INT) {
  63. u16 oc;
  64. oc = wm8350_reg_read(wm8350, WM8350_OVER_CURRENT_INT_STATUS);
  65. oc &= ~wm8350_reg_read(wm8350,
  66. WM8350_OVER_CURRENT_INT_STATUS_MASK);
  67. if (oc & WM8350_OC_LS_EINT) /* limit switch */
  68. wm8350_irq_call_handler(wm8350, WM8350_IRQ_OC_LS);
  69. }
  70. /* under voltage */
  71. if (level_one & WM8350_UV_INT) {
  72. u16 uv;
  73. uv = wm8350_reg_read(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS);
  74. uv &= ~wm8350_reg_read(wm8350,
  75. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK);
  76. if (uv & WM8350_UV_DC1_EINT)
  77. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC1);
  78. if (uv & WM8350_UV_DC2_EINT)
  79. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC2);
  80. if (uv & WM8350_UV_DC3_EINT)
  81. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC3);
  82. if (uv & WM8350_UV_DC4_EINT)
  83. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC4);
  84. if (uv & WM8350_UV_DC5_EINT)
  85. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC5);
  86. if (uv & WM8350_UV_DC6_EINT)
  87. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_DC6);
  88. if (uv & WM8350_UV_LDO1_EINT)
  89. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO1);
  90. if (uv & WM8350_UV_LDO2_EINT)
  91. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO2);
  92. if (uv & WM8350_UV_LDO3_EINT)
  93. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO3);
  94. if (uv & WM8350_UV_LDO4_EINT)
  95. wm8350_irq_call_handler(wm8350, WM8350_IRQ_UV_LDO4);
  96. }
  97. /* charger, RTC */
  98. if (status1) {
  99. if (status1 & WM8350_CHG_BAT_HOT_EINT)
  100. wm8350_irq_call_handler(wm8350,
  101. WM8350_IRQ_CHG_BAT_HOT);
  102. if (status1 & WM8350_CHG_BAT_COLD_EINT)
  103. wm8350_irq_call_handler(wm8350,
  104. WM8350_IRQ_CHG_BAT_COLD);
  105. if (status1 & WM8350_CHG_BAT_FAIL_EINT)
  106. wm8350_irq_call_handler(wm8350,
  107. WM8350_IRQ_CHG_BAT_FAIL);
  108. if (status1 & WM8350_CHG_TO_EINT)
  109. wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_TO);
  110. if (status1 & WM8350_CHG_END_EINT)
  111. wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_END);
  112. if (status1 & WM8350_CHG_START_EINT)
  113. wm8350_irq_call_handler(wm8350, WM8350_IRQ_CHG_START);
  114. if (status1 & WM8350_CHG_FAST_RDY_EINT)
  115. wm8350_irq_call_handler(wm8350,
  116. WM8350_IRQ_CHG_FAST_RDY);
  117. if (status1 & WM8350_CHG_VBATT_LT_3P9_EINT)
  118. wm8350_irq_call_handler(wm8350,
  119. WM8350_IRQ_CHG_VBATT_LT_3P9);
  120. if (status1 & WM8350_CHG_VBATT_LT_3P1_EINT)
  121. wm8350_irq_call_handler(wm8350,
  122. WM8350_IRQ_CHG_VBATT_LT_3P1);
  123. if (status1 & WM8350_CHG_VBATT_LT_2P85_EINT)
  124. wm8350_irq_call_handler(wm8350,
  125. WM8350_IRQ_CHG_VBATT_LT_2P85);
  126. if (status1 & WM8350_RTC_ALM_EINT)
  127. wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_ALM);
  128. if (status1 & WM8350_RTC_SEC_EINT)
  129. wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_SEC);
  130. if (status1 & WM8350_RTC_PER_EINT)
  131. wm8350_irq_call_handler(wm8350, WM8350_IRQ_RTC_PER);
  132. }
  133. /* current sink, system, aux adc */
  134. if (status2) {
  135. if (status2 & WM8350_CS1_EINT)
  136. wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS1);
  137. if (status2 & WM8350_CS2_EINT)
  138. wm8350_irq_call_handler(wm8350, WM8350_IRQ_CS2);
  139. if (status2 & WM8350_SYS_HYST_COMP_FAIL_EINT)
  140. wm8350_irq_call_handler(wm8350,
  141. WM8350_IRQ_SYS_HYST_COMP_FAIL);
  142. if (status2 & WM8350_SYS_CHIP_GT115_EINT)
  143. wm8350_irq_call_handler(wm8350,
  144. WM8350_IRQ_SYS_CHIP_GT115);
  145. if (status2 & WM8350_SYS_CHIP_GT140_EINT)
  146. wm8350_irq_call_handler(wm8350,
  147. WM8350_IRQ_SYS_CHIP_GT140);
  148. if (status2 & WM8350_SYS_WDOG_TO_EINT)
  149. wm8350_irq_call_handler(wm8350,
  150. WM8350_IRQ_SYS_WDOG_TO);
  151. if (status2 & WM8350_AUXADC_DATARDY_EINT)
  152. wm8350_irq_call_handler(wm8350,
  153. WM8350_IRQ_AUXADC_DATARDY);
  154. if (status2 & WM8350_AUXADC_DCOMP4_EINT)
  155. wm8350_irq_call_handler(wm8350,
  156. WM8350_IRQ_AUXADC_DCOMP4);
  157. if (status2 & WM8350_AUXADC_DCOMP3_EINT)
  158. wm8350_irq_call_handler(wm8350,
  159. WM8350_IRQ_AUXADC_DCOMP3);
  160. if (status2 & WM8350_AUXADC_DCOMP2_EINT)
  161. wm8350_irq_call_handler(wm8350,
  162. WM8350_IRQ_AUXADC_DCOMP2);
  163. if (status2 & WM8350_AUXADC_DCOMP1_EINT)
  164. wm8350_irq_call_handler(wm8350,
  165. WM8350_IRQ_AUXADC_DCOMP1);
  166. if (status2 & WM8350_USB_LIMIT_EINT)
  167. wm8350_irq_call_handler(wm8350, WM8350_IRQ_USB_LIMIT);
  168. }
  169. /* wake, codec, ext */
  170. if (comp) {
  171. if (comp & WM8350_WKUP_OFF_STATE_EINT)
  172. wm8350_irq_call_handler(wm8350,
  173. WM8350_IRQ_WKUP_OFF_STATE);
  174. if (comp & WM8350_WKUP_HIB_STATE_EINT)
  175. wm8350_irq_call_handler(wm8350,
  176. WM8350_IRQ_WKUP_HIB_STATE);
  177. if (comp & WM8350_WKUP_CONV_FAULT_EINT)
  178. wm8350_irq_call_handler(wm8350,
  179. WM8350_IRQ_WKUP_CONV_FAULT);
  180. if (comp & WM8350_WKUP_WDOG_RST_EINT)
  181. wm8350_irq_call_handler(wm8350,
  182. WM8350_IRQ_WKUP_WDOG_RST);
  183. if (comp & WM8350_WKUP_GP_PWR_ON_EINT)
  184. wm8350_irq_call_handler(wm8350,
  185. WM8350_IRQ_WKUP_GP_PWR_ON);
  186. if (comp & WM8350_WKUP_ONKEY_EINT)
  187. wm8350_irq_call_handler(wm8350, WM8350_IRQ_WKUP_ONKEY);
  188. if (comp & WM8350_WKUP_GP_WAKEUP_EINT)
  189. wm8350_irq_call_handler(wm8350,
  190. WM8350_IRQ_WKUP_GP_WAKEUP);
  191. if (comp & WM8350_CODEC_JCK_DET_L_EINT)
  192. wm8350_irq_call_handler(wm8350,
  193. WM8350_IRQ_CODEC_JCK_DET_L);
  194. if (comp & WM8350_CODEC_JCK_DET_R_EINT)
  195. wm8350_irq_call_handler(wm8350,
  196. WM8350_IRQ_CODEC_JCK_DET_R);
  197. if (comp & WM8350_CODEC_MICSCD_EINT)
  198. wm8350_irq_call_handler(wm8350,
  199. WM8350_IRQ_CODEC_MICSCD);
  200. if (comp & WM8350_CODEC_MICD_EINT)
  201. wm8350_irq_call_handler(wm8350, WM8350_IRQ_CODEC_MICD);
  202. if (comp & WM8350_EXT_USB_FB_EINT)
  203. wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_USB_FB);
  204. if (comp & WM8350_EXT_WALL_FB_EINT)
  205. wm8350_irq_call_handler(wm8350,
  206. WM8350_IRQ_EXT_WALL_FB);
  207. if (comp & WM8350_EXT_BAT_FB_EINT)
  208. wm8350_irq_call_handler(wm8350, WM8350_IRQ_EXT_BAT_FB);
  209. }
  210. if (level_one & WM8350_GP_INT) {
  211. int i;
  212. u16 gpio;
  213. gpio = wm8350_reg_read(wm8350, WM8350_GPIO_INT_STATUS);
  214. gpio &= ~wm8350_reg_read(wm8350,
  215. WM8350_GPIO_INT_STATUS_MASK);
  216. for (i = 0; i < 12; i++) {
  217. if (gpio & (1 << i))
  218. wm8350_irq_call_handler(wm8350,
  219. WM8350_IRQ_GPIO(i));
  220. }
  221. }
  222. return IRQ_HANDLED;
  223. }
  224. int wm8350_register_irq(struct wm8350 *wm8350, int irq,
  225. void (*handler) (struct wm8350 *, int, void *),
  226. void *data)
  227. {
  228. if (irq < 0 || irq > WM8350_NUM_IRQ || !handler)
  229. return -EINVAL;
  230. if (wm8350->irq[irq].handler)
  231. return -EBUSY;
  232. mutex_lock(&wm8350->irq_mutex);
  233. wm8350->irq[irq].handler = handler;
  234. wm8350->irq[irq].data = data;
  235. mutex_unlock(&wm8350->irq_mutex);
  236. return 0;
  237. }
  238. EXPORT_SYMBOL_GPL(wm8350_register_irq);
  239. int wm8350_free_irq(struct wm8350 *wm8350, int irq)
  240. {
  241. if (irq < 0 || irq > WM8350_NUM_IRQ)
  242. return -EINVAL;
  243. mutex_lock(&wm8350->irq_mutex);
  244. wm8350->irq[irq].handler = NULL;
  245. mutex_unlock(&wm8350->irq_mutex);
  246. return 0;
  247. }
  248. EXPORT_SYMBOL_GPL(wm8350_free_irq);
  249. int wm8350_mask_irq(struct wm8350 *wm8350, int irq)
  250. {
  251. switch (irq) {
  252. case WM8350_IRQ_CHG_BAT_HOT:
  253. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  254. WM8350_IM_CHG_BAT_HOT_EINT);
  255. case WM8350_IRQ_CHG_BAT_COLD:
  256. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  257. WM8350_IM_CHG_BAT_COLD_EINT);
  258. case WM8350_IRQ_CHG_BAT_FAIL:
  259. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  260. WM8350_IM_CHG_BAT_FAIL_EINT);
  261. case WM8350_IRQ_CHG_TO:
  262. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  263. WM8350_IM_CHG_TO_EINT);
  264. case WM8350_IRQ_CHG_END:
  265. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  266. WM8350_IM_CHG_END_EINT);
  267. case WM8350_IRQ_CHG_START:
  268. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  269. WM8350_IM_CHG_START_EINT);
  270. case WM8350_IRQ_CHG_FAST_RDY:
  271. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  272. WM8350_IM_CHG_FAST_RDY_EINT);
  273. case WM8350_IRQ_RTC_PER:
  274. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  275. WM8350_IM_RTC_PER_EINT);
  276. case WM8350_IRQ_RTC_SEC:
  277. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  278. WM8350_IM_RTC_SEC_EINT);
  279. case WM8350_IRQ_RTC_ALM:
  280. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  281. WM8350_IM_RTC_ALM_EINT);
  282. case WM8350_IRQ_CHG_VBATT_LT_3P9:
  283. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  284. WM8350_IM_CHG_VBATT_LT_3P9_EINT);
  285. case WM8350_IRQ_CHG_VBATT_LT_3P1:
  286. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  287. WM8350_IM_CHG_VBATT_LT_3P1_EINT);
  288. case WM8350_IRQ_CHG_VBATT_LT_2P85:
  289. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  290. WM8350_IM_CHG_VBATT_LT_2P85_EINT);
  291. case WM8350_IRQ_CS1:
  292. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  293. WM8350_IM_CS1_EINT);
  294. case WM8350_IRQ_CS2:
  295. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  296. WM8350_IM_CS2_EINT);
  297. case WM8350_IRQ_USB_LIMIT:
  298. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  299. WM8350_IM_USB_LIMIT_EINT);
  300. case WM8350_IRQ_AUXADC_DATARDY:
  301. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  302. WM8350_IM_AUXADC_DATARDY_EINT);
  303. case WM8350_IRQ_AUXADC_DCOMP4:
  304. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  305. WM8350_IM_AUXADC_DCOMP4_EINT);
  306. case WM8350_IRQ_AUXADC_DCOMP3:
  307. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  308. WM8350_IM_AUXADC_DCOMP3_EINT);
  309. case WM8350_IRQ_AUXADC_DCOMP2:
  310. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  311. WM8350_IM_AUXADC_DCOMP2_EINT);
  312. case WM8350_IRQ_AUXADC_DCOMP1:
  313. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  314. WM8350_IM_AUXADC_DCOMP1_EINT);
  315. case WM8350_IRQ_SYS_HYST_COMP_FAIL:
  316. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  317. WM8350_IM_SYS_HYST_COMP_FAIL_EINT);
  318. case WM8350_IRQ_SYS_CHIP_GT115:
  319. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  320. WM8350_IM_SYS_CHIP_GT115_EINT);
  321. case WM8350_IRQ_SYS_CHIP_GT140:
  322. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  323. WM8350_IM_SYS_CHIP_GT140_EINT);
  324. case WM8350_IRQ_SYS_WDOG_TO:
  325. return wm8350_set_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  326. WM8350_IM_SYS_WDOG_TO_EINT);
  327. case WM8350_IRQ_UV_LDO4:
  328. return wm8350_set_bits(wm8350,
  329. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  330. WM8350_IM_UV_LDO4_EINT);
  331. case WM8350_IRQ_UV_LDO3:
  332. return wm8350_set_bits(wm8350,
  333. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  334. WM8350_IM_UV_LDO3_EINT);
  335. case WM8350_IRQ_UV_LDO2:
  336. return wm8350_set_bits(wm8350,
  337. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  338. WM8350_IM_UV_LDO2_EINT);
  339. case WM8350_IRQ_UV_LDO1:
  340. return wm8350_set_bits(wm8350,
  341. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  342. WM8350_IM_UV_LDO1_EINT);
  343. case WM8350_IRQ_UV_DC6:
  344. return wm8350_set_bits(wm8350,
  345. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  346. WM8350_IM_UV_DC6_EINT);
  347. case WM8350_IRQ_UV_DC5:
  348. return wm8350_set_bits(wm8350,
  349. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  350. WM8350_IM_UV_DC5_EINT);
  351. case WM8350_IRQ_UV_DC4:
  352. return wm8350_set_bits(wm8350,
  353. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  354. WM8350_IM_UV_DC4_EINT);
  355. case WM8350_IRQ_UV_DC3:
  356. return wm8350_set_bits(wm8350,
  357. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  358. WM8350_IM_UV_DC3_EINT);
  359. case WM8350_IRQ_UV_DC2:
  360. return wm8350_set_bits(wm8350,
  361. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  362. WM8350_IM_UV_DC2_EINT);
  363. case WM8350_IRQ_UV_DC1:
  364. return wm8350_set_bits(wm8350,
  365. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  366. WM8350_IM_UV_DC1_EINT);
  367. case WM8350_IRQ_OC_LS:
  368. return wm8350_set_bits(wm8350,
  369. WM8350_OVER_CURRENT_INT_STATUS_MASK,
  370. WM8350_IM_OC_LS_EINT);
  371. case WM8350_IRQ_EXT_USB_FB:
  372. return wm8350_set_bits(wm8350,
  373. WM8350_COMPARATOR_INT_STATUS_MASK,
  374. WM8350_IM_EXT_USB_FB_EINT);
  375. case WM8350_IRQ_EXT_WALL_FB:
  376. return wm8350_set_bits(wm8350,
  377. WM8350_COMPARATOR_INT_STATUS_MASK,
  378. WM8350_IM_EXT_WALL_FB_EINT);
  379. case WM8350_IRQ_EXT_BAT_FB:
  380. return wm8350_set_bits(wm8350,
  381. WM8350_COMPARATOR_INT_STATUS_MASK,
  382. WM8350_IM_EXT_BAT_FB_EINT);
  383. case WM8350_IRQ_CODEC_JCK_DET_L:
  384. return wm8350_set_bits(wm8350,
  385. WM8350_COMPARATOR_INT_STATUS_MASK,
  386. WM8350_IM_CODEC_JCK_DET_L_EINT);
  387. case WM8350_IRQ_CODEC_JCK_DET_R:
  388. return wm8350_set_bits(wm8350,
  389. WM8350_COMPARATOR_INT_STATUS_MASK,
  390. WM8350_IM_CODEC_JCK_DET_R_EINT);
  391. case WM8350_IRQ_CODEC_MICSCD:
  392. return wm8350_set_bits(wm8350,
  393. WM8350_COMPARATOR_INT_STATUS_MASK,
  394. WM8350_IM_CODEC_MICSCD_EINT);
  395. case WM8350_IRQ_CODEC_MICD:
  396. return wm8350_set_bits(wm8350,
  397. WM8350_COMPARATOR_INT_STATUS_MASK,
  398. WM8350_IM_CODEC_MICD_EINT);
  399. case WM8350_IRQ_WKUP_OFF_STATE:
  400. return wm8350_set_bits(wm8350,
  401. WM8350_COMPARATOR_INT_STATUS_MASK,
  402. WM8350_IM_WKUP_OFF_STATE_EINT);
  403. case WM8350_IRQ_WKUP_HIB_STATE:
  404. return wm8350_set_bits(wm8350,
  405. WM8350_COMPARATOR_INT_STATUS_MASK,
  406. WM8350_IM_WKUP_HIB_STATE_EINT);
  407. case WM8350_IRQ_WKUP_CONV_FAULT:
  408. return wm8350_set_bits(wm8350,
  409. WM8350_COMPARATOR_INT_STATUS_MASK,
  410. WM8350_IM_WKUP_CONV_FAULT_EINT);
  411. case WM8350_IRQ_WKUP_WDOG_RST:
  412. return wm8350_set_bits(wm8350,
  413. WM8350_COMPARATOR_INT_STATUS_MASK,
  414. WM8350_IM_WKUP_OFF_STATE_EINT);
  415. case WM8350_IRQ_WKUP_GP_PWR_ON:
  416. return wm8350_set_bits(wm8350,
  417. WM8350_COMPARATOR_INT_STATUS_MASK,
  418. WM8350_IM_WKUP_GP_PWR_ON_EINT);
  419. case WM8350_IRQ_WKUP_ONKEY:
  420. return wm8350_set_bits(wm8350,
  421. WM8350_COMPARATOR_INT_STATUS_MASK,
  422. WM8350_IM_WKUP_ONKEY_EINT);
  423. case WM8350_IRQ_WKUP_GP_WAKEUP:
  424. return wm8350_set_bits(wm8350,
  425. WM8350_COMPARATOR_INT_STATUS_MASK,
  426. WM8350_IM_WKUP_GP_WAKEUP_EINT);
  427. case WM8350_IRQ_GPIO(0):
  428. return wm8350_set_bits(wm8350,
  429. WM8350_GPIO_INT_STATUS_MASK,
  430. WM8350_IM_GP0_EINT);
  431. case WM8350_IRQ_GPIO(1):
  432. return wm8350_set_bits(wm8350,
  433. WM8350_GPIO_INT_STATUS_MASK,
  434. WM8350_IM_GP1_EINT);
  435. case WM8350_IRQ_GPIO(2):
  436. return wm8350_set_bits(wm8350,
  437. WM8350_GPIO_INT_STATUS_MASK,
  438. WM8350_IM_GP2_EINT);
  439. case WM8350_IRQ_GPIO(3):
  440. return wm8350_set_bits(wm8350,
  441. WM8350_GPIO_INT_STATUS_MASK,
  442. WM8350_IM_GP3_EINT);
  443. case WM8350_IRQ_GPIO(4):
  444. return wm8350_set_bits(wm8350,
  445. WM8350_GPIO_INT_STATUS_MASK,
  446. WM8350_IM_GP4_EINT);
  447. case WM8350_IRQ_GPIO(5):
  448. return wm8350_set_bits(wm8350,
  449. WM8350_GPIO_INT_STATUS_MASK,
  450. WM8350_IM_GP5_EINT);
  451. case WM8350_IRQ_GPIO(6):
  452. return wm8350_set_bits(wm8350,
  453. WM8350_GPIO_INT_STATUS_MASK,
  454. WM8350_IM_GP6_EINT);
  455. case WM8350_IRQ_GPIO(7):
  456. return wm8350_set_bits(wm8350,
  457. WM8350_GPIO_INT_STATUS_MASK,
  458. WM8350_IM_GP7_EINT);
  459. case WM8350_IRQ_GPIO(8):
  460. return wm8350_set_bits(wm8350,
  461. WM8350_GPIO_INT_STATUS_MASK,
  462. WM8350_IM_GP8_EINT);
  463. case WM8350_IRQ_GPIO(9):
  464. return wm8350_set_bits(wm8350,
  465. WM8350_GPIO_INT_STATUS_MASK,
  466. WM8350_IM_GP9_EINT);
  467. case WM8350_IRQ_GPIO(10):
  468. return wm8350_set_bits(wm8350,
  469. WM8350_GPIO_INT_STATUS_MASK,
  470. WM8350_IM_GP10_EINT);
  471. case WM8350_IRQ_GPIO(11):
  472. return wm8350_set_bits(wm8350,
  473. WM8350_GPIO_INT_STATUS_MASK,
  474. WM8350_IM_GP11_EINT);
  475. case WM8350_IRQ_GPIO(12):
  476. return wm8350_set_bits(wm8350,
  477. WM8350_GPIO_INT_STATUS_MASK,
  478. WM8350_IM_GP12_EINT);
  479. default:
  480. dev_warn(wm8350->dev, "Attempting to mask unknown IRQ %d\n",
  481. irq);
  482. return -EINVAL;
  483. }
  484. return 0;
  485. }
  486. EXPORT_SYMBOL_GPL(wm8350_mask_irq);
  487. int wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
  488. {
  489. switch (irq) {
  490. case WM8350_IRQ_CHG_BAT_HOT:
  491. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  492. WM8350_IM_CHG_BAT_HOT_EINT);
  493. case WM8350_IRQ_CHG_BAT_COLD:
  494. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  495. WM8350_IM_CHG_BAT_COLD_EINT);
  496. case WM8350_IRQ_CHG_BAT_FAIL:
  497. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  498. WM8350_IM_CHG_BAT_FAIL_EINT);
  499. case WM8350_IRQ_CHG_TO:
  500. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  501. WM8350_IM_CHG_TO_EINT);
  502. case WM8350_IRQ_CHG_END:
  503. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  504. WM8350_IM_CHG_END_EINT);
  505. case WM8350_IRQ_CHG_START:
  506. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  507. WM8350_IM_CHG_START_EINT);
  508. case WM8350_IRQ_CHG_FAST_RDY:
  509. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  510. WM8350_IM_CHG_FAST_RDY_EINT);
  511. case WM8350_IRQ_RTC_PER:
  512. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  513. WM8350_IM_RTC_PER_EINT);
  514. case WM8350_IRQ_RTC_SEC:
  515. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  516. WM8350_IM_RTC_SEC_EINT);
  517. case WM8350_IRQ_RTC_ALM:
  518. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  519. WM8350_IM_RTC_ALM_EINT);
  520. case WM8350_IRQ_CHG_VBATT_LT_3P9:
  521. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  522. WM8350_IM_CHG_VBATT_LT_3P9_EINT);
  523. case WM8350_IRQ_CHG_VBATT_LT_3P1:
  524. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  525. WM8350_IM_CHG_VBATT_LT_3P1_EINT);
  526. case WM8350_IRQ_CHG_VBATT_LT_2P85:
  527. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK,
  528. WM8350_IM_CHG_VBATT_LT_2P85_EINT);
  529. case WM8350_IRQ_CS1:
  530. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  531. WM8350_IM_CS1_EINT);
  532. case WM8350_IRQ_CS2:
  533. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  534. WM8350_IM_CS2_EINT);
  535. case WM8350_IRQ_USB_LIMIT:
  536. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  537. WM8350_IM_USB_LIMIT_EINT);
  538. case WM8350_IRQ_AUXADC_DATARDY:
  539. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  540. WM8350_IM_AUXADC_DATARDY_EINT);
  541. case WM8350_IRQ_AUXADC_DCOMP4:
  542. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  543. WM8350_IM_AUXADC_DCOMP4_EINT);
  544. case WM8350_IRQ_AUXADC_DCOMP3:
  545. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  546. WM8350_IM_AUXADC_DCOMP3_EINT);
  547. case WM8350_IRQ_AUXADC_DCOMP2:
  548. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  549. WM8350_IM_AUXADC_DCOMP2_EINT);
  550. case WM8350_IRQ_AUXADC_DCOMP1:
  551. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  552. WM8350_IM_AUXADC_DCOMP1_EINT);
  553. case WM8350_IRQ_SYS_HYST_COMP_FAIL:
  554. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  555. WM8350_IM_SYS_HYST_COMP_FAIL_EINT);
  556. case WM8350_IRQ_SYS_CHIP_GT115:
  557. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  558. WM8350_IM_SYS_CHIP_GT115_EINT);
  559. case WM8350_IRQ_SYS_CHIP_GT140:
  560. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  561. WM8350_IM_SYS_CHIP_GT140_EINT);
  562. case WM8350_IRQ_SYS_WDOG_TO:
  563. return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_2_MASK,
  564. WM8350_IM_SYS_WDOG_TO_EINT);
  565. case WM8350_IRQ_UV_LDO4:
  566. return wm8350_clear_bits(wm8350,
  567. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  568. WM8350_IM_UV_LDO4_EINT);
  569. case WM8350_IRQ_UV_LDO3:
  570. return wm8350_clear_bits(wm8350,
  571. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  572. WM8350_IM_UV_LDO3_EINT);
  573. case WM8350_IRQ_UV_LDO2:
  574. return wm8350_clear_bits(wm8350,
  575. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  576. WM8350_IM_UV_LDO2_EINT);
  577. case WM8350_IRQ_UV_LDO1:
  578. return wm8350_clear_bits(wm8350,
  579. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  580. WM8350_IM_UV_LDO1_EINT);
  581. case WM8350_IRQ_UV_DC6:
  582. return wm8350_clear_bits(wm8350,
  583. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  584. WM8350_IM_UV_DC6_EINT);
  585. case WM8350_IRQ_UV_DC5:
  586. return wm8350_clear_bits(wm8350,
  587. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  588. WM8350_IM_UV_DC5_EINT);
  589. case WM8350_IRQ_UV_DC4:
  590. return wm8350_clear_bits(wm8350,
  591. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  592. WM8350_IM_UV_DC4_EINT);
  593. case WM8350_IRQ_UV_DC3:
  594. return wm8350_clear_bits(wm8350,
  595. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  596. WM8350_IM_UV_DC3_EINT);
  597. case WM8350_IRQ_UV_DC2:
  598. return wm8350_clear_bits(wm8350,
  599. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  600. WM8350_IM_UV_DC2_EINT);
  601. case WM8350_IRQ_UV_DC1:
  602. return wm8350_clear_bits(wm8350,
  603. WM8350_UNDER_VOLTAGE_INT_STATUS_MASK,
  604. WM8350_IM_UV_DC1_EINT);
  605. case WM8350_IRQ_OC_LS:
  606. return wm8350_clear_bits(wm8350,
  607. WM8350_OVER_CURRENT_INT_STATUS_MASK,
  608. WM8350_IM_OC_LS_EINT);
  609. case WM8350_IRQ_EXT_USB_FB:
  610. return wm8350_clear_bits(wm8350,
  611. WM8350_COMPARATOR_INT_STATUS_MASK,
  612. WM8350_IM_EXT_USB_FB_EINT);
  613. case WM8350_IRQ_EXT_WALL_FB:
  614. return wm8350_clear_bits(wm8350,
  615. WM8350_COMPARATOR_INT_STATUS_MASK,
  616. WM8350_IM_EXT_WALL_FB_EINT);
  617. case WM8350_IRQ_EXT_BAT_FB:
  618. return wm8350_clear_bits(wm8350,
  619. WM8350_COMPARATOR_INT_STATUS_MASK,
  620. WM8350_IM_EXT_BAT_FB_EINT);
  621. case WM8350_IRQ_CODEC_JCK_DET_L:
  622. return wm8350_clear_bits(wm8350,
  623. WM8350_COMPARATOR_INT_STATUS_MASK,
  624. WM8350_IM_CODEC_JCK_DET_L_EINT);
  625. case WM8350_IRQ_CODEC_JCK_DET_R:
  626. return wm8350_clear_bits(wm8350,
  627. WM8350_COMPARATOR_INT_STATUS_MASK,
  628. WM8350_IM_CODEC_JCK_DET_R_EINT);
  629. case WM8350_IRQ_CODEC_MICSCD:
  630. return wm8350_clear_bits(wm8350,
  631. WM8350_COMPARATOR_INT_STATUS_MASK,
  632. WM8350_IM_CODEC_MICSCD_EINT);
  633. case WM8350_IRQ_CODEC_MICD:
  634. return wm8350_clear_bits(wm8350,
  635. WM8350_COMPARATOR_INT_STATUS_MASK,
  636. WM8350_IM_CODEC_MICD_EINT);
  637. case WM8350_IRQ_WKUP_OFF_STATE:
  638. return wm8350_clear_bits(wm8350,
  639. WM8350_COMPARATOR_INT_STATUS_MASK,
  640. WM8350_IM_WKUP_OFF_STATE_EINT);
  641. case WM8350_IRQ_WKUP_HIB_STATE:
  642. return wm8350_clear_bits(wm8350,
  643. WM8350_COMPARATOR_INT_STATUS_MASK,
  644. WM8350_IM_WKUP_HIB_STATE_EINT);
  645. case WM8350_IRQ_WKUP_CONV_FAULT:
  646. return wm8350_clear_bits(wm8350,
  647. WM8350_COMPARATOR_INT_STATUS_MASK,
  648. WM8350_IM_WKUP_CONV_FAULT_EINT);
  649. case WM8350_IRQ_WKUP_WDOG_RST:
  650. return wm8350_clear_bits(wm8350,
  651. WM8350_COMPARATOR_INT_STATUS_MASK,
  652. WM8350_IM_WKUP_OFF_STATE_EINT);
  653. case WM8350_IRQ_WKUP_GP_PWR_ON:
  654. return wm8350_clear_bits(wm8350,
  655. WM8350_COMPARATOR_INT_STATUS_MASK,
  656. WM8350_IM_WKUP_GP_PWR_ON_EINT);
  657. case WM8350_IRQ_WKUP_ONKEY:
  658. return wm8350_clear_bits(wm8350,
  659. WM8350_COMPARATOR_INT_STATUS_MASK,
  660. WM8350_IM_WKUP_ONKEY_EINT);
  661. case WM8350_IRQ_WKUP_GP_WAKEUP:
  662. return wm8350_clear_bits(wm8350,
  663. WM8350_COMPARATOR_INT_STATUS_MASK,
  664. WM8350_IM_WKUP_GP_WAKEUP_EINT);
  665. case WM8350_IRQ_GPIO(0):
  666. return wm8350_clear_bits(wm8350,
  667. WM8350_GPIO_INT_STATUS_MASK,
  668. WM8350_IM_GP0_EINT);
  669. case WM8350_IRQ_GPIO(1):
  670. return wm8350_clear_bits(wm8350,
  671. WM8350_GPIO_INT_STATUS_MASK,
  672. WM8350_IM_GP1_EINT);
  673. case WM8350_IRQ_GPIO(2):
  674. return wm8350_clear_bits(wm8350,
  675. WM8350_GPIO_INT_STATUS_MASK,
  676. WM8350_IM_GP2_EINT);
  677. case WM8350_IRQ_GPIO(3):
  678. return wm8350_clear_bits(wm8350,
  679. WM8350_GPIO_INT_STATUS_MASK,
  680. WM8350_IM_GP3_EINT);
  681. case WM8350_IRQ_GPIO(4):
  682. return wm8350_clear_bits(wm8350,
  683. WM8350_GPIO_INT_STATUS_MASK,
  684. WM8350_IM_GP4_EINT);
  685. case WM8350_IRQ_GPIO(5):
  686. return wm8350_clear_bits(wm8350,
  687. WM8350_GPIO_INT_STATUS_MASK,
  688. WM8350_IM_GP5_EINT);
  689. case WM8350_IRQ_GPIO(6):
  690. return wm8350_clear_bits(wm8350,
  691. WM8350_GPIO_INT_STATUS_MASK,
  692. WM8350_IM_GP6_EINT);
  693. case WM8350_IRQ_GPIO(7):
  694. return wm8350_clear_bits(wm8350,
  695. WM8350_GPIO_INT_STATUS_MASK,
  696. WM8350_IM_GP7_EINT);
  697. case WM8350_IRQ_GPIO(8):
  698. return wm8350_clear_bits(wm8350,
  699. WM8350_GPIO_INT_STATUS_MASK,
  700. WM8350_IM_GP8_EINT);
  701. case WM8350_IRQ_GPIO(9):
  702. return wm8350_clear_bits(wm8350,
  703. WM8350_GPIO_INT_STATUS_MASK,
  704. WM8350_IM_GP9_EINT);
  705. case WM8350_IRQ_GPIO(10):
  706. return wm8350_clear_bits(wm8350,
  707. WM8350_GPIO_INT_STATUS_MASK,
  708. WM8350_IM_GP10_EINT);
  709. case WM8350_IRQ_GPIO(11):
  710. return wm8350_clear_bits(wm8350,
  711. WM8350_GPIO_INT_STATUS_MASK,
  712. WM8350_IM_GP11_EINT);
  713. case WM8350_IRQ_GPIO(12):
  714. return wm8350_clear_bits(wm8350,
  715. WM8350_GPIO_INT_STATUS_MASK,
  716. WM8350_IM_GP12_EINT);
  717. default:
  718. dev_warn(wm8350->dev, "Attempting to unmask unknown IRQ %d\n",
  719. irq);
  720. return -EINVAL;
  721. }
  722. return 0;
  723. }
  724. EXPORT_SYMBOL_GPL(wm8350_unmask_irq);
  725. int wm8350_irq_init(struct wm8350 *wm8350, int irq,
  726. struct wm8350_platform_data *pdata)
  727. {
  728. int ret;
  729. int flags = IRQF_ONESHOT;
  730. if (!irq) {
  731. dev_err(wm8350->dev, "No IRQ configured\n");
  732. return -EINVAL;
  733. }
  734. wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
  735. wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
  736. wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
  737. wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
  738. wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
  739. wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
  740. mutex_init(&wm8350->irq_mutex);
  741. wm8350->chip_irq = irq;
  742. if (pdata && pdata->irq_high) {
  743. flags |= IRQF_TRIGGER_HIGH;
  744. wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
  745. WM8350_IRQ_POL);
  746. } else {
  747. flags |= IRQF_TRIGGER_LOW;
  748. wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
  749. WM8350_IRQ_POL);
  750. }
  751. ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
  752. "wm8350", wm8350);
  753. if (ret != 0)
  754. dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
  755. return ret;
  756. }
  757. int wm8350_irq_exit(struct wm8350 *wm8350)
  758. {
  759. free_irq(wm8350->chip_irq, wm8350);
  760. return 0;
  761. }