sec-irq.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * sec-irq.c
  3. *
  4. * Copyright (c) 2011 Samsung Electronics Co., Ltd
  5. * http://www.samsung.com
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. *
  12. */
  13. #include <linux/device.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/irq.h>
  16. #include <linux/regmap.h>
  17. #include <linux/mfd/samsung/core.h>
  18. #include <linux/mfd/samsung/irq.h>
  19. #include <linux/mfd/samsung/s2mps11.h>
  20. #include <linux/mfd/samsung/s5m8763.h>
  21. #include <linux/mfd/samsung/s5m8767.h>
  22. static struct regmap_irq s2mps11_irqs[] = {
  23. [S2MPS11_IRQ_PWRONF] = {
  24. .reg_offset = 0,
  25. .mask = S2MPS11_IRQ_PWRONF_MASK,
  26. },
  27. [S2MPS11_IRQ_PWRONR] = {
  28. .reg_offset = 0,
  29. .mask = S2MPS11_IRQ_PWRONR_MASK,
  30. },
  31. [S2MPS11_IRQ_JIGONBF] = {
  32. .reg_offset = 0,
  33. .mask = S2MPS11_IRQ_JIGONBF_MASK,
  34. },
  35. [S2MPS11_IRQ_JIGONBR] = {
  36. .reg_offset = 0,
  37. .mask = S2MPS11_IRQ_JIGONBR_MASK,
  38. },
  39. [S2MPS11_IRQ_ACOKBF] = {
  40. .reg_offset = 0,
  41. .mask = S2MPS11_IRQ_ACOKBF_MASK,
  42. },
  43. [S2MPS11_IRQ_ACOKBR] = {
  44. .reg_offset = 0,
  45. .mask = S2MPS11_IRQ_ACOKBR_MASK,
  46. },
  47. [S2MPS11_IRQ_PWRON1S] = {
  48. .reg_offset = 0,
  49. .mask = S2MPS11_IRQ_PWRON1S_MASK,
  50. },
  51. [S2MPS11_IRQ_MRB] = {
  52. .reg_offset = 0,
  53. .mask = S2MPS11_IRQ_MRB_MASK,
  54. },
  55. [S2MPS11_IRQ_RTC60S] = {
  56. .reg_offset = 1,
  57. .mask = S2MPS11_IRQ_RTC60S_MASK,
  58. },
  59. [S2MPS11_IRQ_RTCA1] = {
  60. .reg_offset = 1,
  61. .mask = S2MPS11_IRQ_RTCA1_MASK,
  62. },
  63. [S2MPS11_IRQ_RTCA2] = {
  64. .reg_offset = 1,
  65. .mask = S2MPS11_IRQ_RTCA2_MASK,
  66. },
  67. [S2MPS11_IRQ_SMPL] = {
  68. .reg_offset = 1,
  69. .mask = S2MPS11_IRQ_SMPL_MASK,
  70. },
  71. [S2MPS11_IRQ_RTC1S] = {
  72. .reg_offset = 1,
  73. .mask = S2MPS11_IRQ_RTC1S_MASK,
  74. },
  75. [S2MPS11_IRQ_WTSR] = {
  76. .reg_offset = 1,
  77. .mask = S2MPS11_IRQ_WTSR_MASK,
  78. },
  79. [S2MPS11_IRQ_INT120C] = {
  80. .reg_offset = 2,
  81. .mask = S2MPS11_IRQ_INT120C_MASK,
  82. },
  83. [S2MPS11_IRQ_INT140C] = {
  84. .reg_offset = 2,
  85. .mask = S2MPS11_IRQ_INT140C_MASK,
  86. },
  87. };
  88. static struct regmap_irq s5m8767_irqs[] = {
  89. [S5M8767_IRQ_PWRR] = {
  90. .reg_offset = 0,
  91. .mask = S5M8767_IRQ_PWRR_MASK,
  92. },
  93. [S5M8767_IRQ_PWRF] = {
  94. .reg_offset = 0,
  95. .mask = S5M8767_IRQ_PWRF_MASK,
  96. },
  97. [S5M8767_IRQ_PWR1S] = {
  98. .reg_offset = 0,
  99. .mask = S5M8767_IRQ_PWR1S_MASK,
  100. },
  101. [S5M8767_IRQ_JIGR] = {
  102. .reg_offset = 0,
  103. .mask = S5M8767_IRQ_JIGR_MASK,
  104. },
  105. [S5M8767_IRQ_JIGF] = {
  106. .reg_offset = 0,
  107. .mask = S5M8767_IRQ_JIGF_MASK,
  108. },
  109. [S5M8767_IRQ_LOWBAT2] = {
  110. .reg_offset = 0,
  111. .mask = S5M8767_IRQ_LOWBAT2_MASK,
  112. },
  113. [S5M8767_IRQ_LOWBAT1] = {
  114. .reg_offset = 0,
  115. .mask = S5M8767_IRQ_LOWBAT1_MASK,
  116. },
  117. [S5M8767_IRQ_MRB] = {
  118. .reg_offset = 1,
  119. .mask = S5M8767_IRQ_MRB_MASK,
  120. },
  121. [S5M8767_IRQ_DVSOK2] = {
  122. .reg_offset = 1,
  123. .mask = S5M8767_IRQ_DVSOK2_MASK,
  124. },
  125. [S5M8767_IRQ_DVSOK3] = {
  126. .reg_offset = 1,
  127. .mask = S5M8767_IRQ_DVSOK3_MASK,
  128. },
  129. [S5M8767_IRQ_DVSOK4] = {
  130. .reg_offset = 1,
  131. .mask = S5M8767_IRQ_DVSOK4_MASK,
  132. },
  133. [S5M8767_IRQ_RTC60S] = {
  134. .reg_offset = 2,
  135. .mask = S5M8767_IRQ_RTC60S_MASK,
  136. },
  137. [S5M8767_IRQ_RTCA1] = {
  138. .reg_offset = 2,
  139. .mask = S5M8767_IRQ_RTCA1_MASK,
  140. },
  141. [S5M8767_IRQ_RTCA2] = {
  142. .reg_offset = 2,
  143. .mask = S5M8767_IRQ_RTCA2_MASK,
  144. },
  145. [S5M8767_IRQ_SMPL] = {
  146. .reg_offset = 2,
  147. .mask = S5M8767_IRQ_SMPL_MASK,
  148. },
  149. [S5M8767_IRQ_RTC1S] = {
  150. .reg_offset = 2,
  151. .mask = S5M8767_IRQ_RTC1S_MASK,
  152. },
  153. [S5M8767_IRQ_WTSR] = {
  154. .reg_offset = 2,
  155. .mask = S5M8767_IRQ_WTSR_MASK,
  156. },
  157. };
  158. static struct regmap_irq s5m8763_irqs[] = {
  159. [S5M8763_IRQ_DCINF] = {
  160. .reg_offset = 0,
  161. .mask = S5M8763_IRQ_DCINF_MASK,
  162. },
  163. [S5M8763_IRQ_DCINR] = {
  164. .reg_offset = 0,
  165. .mask = S5M8763_IRQ_DCINR_MASK,
  166. },
  167. [S5M8763_IRQ_JIGF] = {
  168. .reg_offset = 0,
  169. .mask = S5M8763_IRQ_JIGF_MASK,
  170. },
  171. [S5M8763_IRQ_JIGR] = {
  172. .reg_offset = 0,
  173. .mask = S5M8763_IRQ_JIGR_MASK,
  174. },
  175. [S5M8763_IRQ_PWRONF] = {
  176. .reg_offset = 0,
  177. .mask = S5M8763_IRQ_PWRONF_MASK,
  178. },
  179. [S5M8763_IRQ_PWRONR] = {
  180. .reg_offset = 0,
  181. .mask = S5M8763_IRQ_PWRONR_MASK,
  182. },
  183. [S5M8763_IRQ_WTSREVNT] = {
  184. .reg_offset = 1,
  185. .mask = S5M8763_IRQ_WTSREVNT_MASK,
  186. },
  187. [S5M8763_IRQ_SMPLEVNT] = {
  188. .reg_offset = 1,
  189. .mask = S5M8763_IRQ_SMPLEVNT_MASK,
  190. },
  191. [S5M8763_IRQ_ALARM1] = {
  192. .reg_offset = 1,
  193. .mask = S5M8763_IRQ_ALARM1_MASK,
  194. },
  195. [S5M8763_IRQ_ALARM0] = {
  196. .reg_offset = 1,
  197. .mask = S5M8763_IRQ_ALARM0_MASK,
  198. },
  199. [S5M8763_IRQ_ONKEY1S] = {
  200. .reg_offset = 2,
  201. .mask = S5M8763_IRQ_ONKEY1S_MASK,
  202. },
  203. [S5M8763_IRQ_TOPOFFR] = {
  204. .reg_offset = 2,
  205. .mask = S5M8763_IRQ_TOPOFFR_MASK,
  206. },
  207. [S5M8763_IRQ_DCINOVPR] = {
  208. .reg_offset = 2,
  209. .mask = S5M8763_IRQ_DCINOVPR_MASK,
  210. },
  211. [S5M8763_IRQ_CHGRSTF] = {
  212. .reg_offset = 2,
  213. .mask = S5M8763_IRQ_CHGRSTF_MASK,
  214. },
  215. [S5M8763_IRQ_DONER] = {
  216. .reg_offset = 2,
  217. .mask = S5M8763_IRQ_DONER_MASK,
  218. },
  219. [S5M8763_IRQ_CHGFAULT] = {
  220. .reg_offset = 2,
  221. .mask = S5M8763_IRQ_CHGFAULT_MASK,
  222. },
  223. [S5M8763_IRQ_LOBAT1] = {
  224. .reg_offset = 3,
  225. .mask = S5M8763_IRQ_LOBAT1_MASK,
  226. },
  227. [S5M8763_IRQ_LOBAT2] = {
  228. .reg_offset = 3,
  229. .mask = S5M8763_IRQ_LOBAT2_MASK,
  230. },
  231. };
  232. static struct regmap_irq_chip s2mps11_irq_chip = {
  233. .name = "s2mps11",
  234. .irqs = s2mps11_irqs,
  235. .num_irqs = ARRAY_SIZE(s2mps11_irqs),
  236. .num_regs = 3,
  237. .status_base = S2MPS11_REG_INT1,
  238. .mask_base = S2MPS11_REG_INT1M,
  239. .ack_base = S2MPS11_REG_INT1,
  240. };
  241. static struct regmap_irq_chip s5m8767_irq_chip = {
  242. .name = "s5m8767",
  243. .irqs = s5m8767_irqs,
  244. .num_irqs = ARRAY_SIZE(s5m8767_irqs),
  245. .num_regs = 3,
  246. .status_base = S5M8767_REG_INT1,
  247. .mask_base = S5M8767_REG_INT1M,
  248. .ack_base = S5M8767_REG_INT1,
  249. };
  250. static struct regmap_irq_chip s5m8763_irq_chip = {
  251. .name = "s5m8763",
  252. .irqs = s5m8763_irqs,
  253. .num_irqs = ARRAY_SIZE(s5m8763_irqs),
  254. .num_regs = 4,
  255. .status_base = S5M8763_REG_IRQ1,
  256. .mask_base = S5M8763_REG_IRQM1,
  257. .ack_base = S5M8763_REG_IRQ1,
  258. };
  259. int sec_irq_init(struct sec_pmic_dev *sec_pmic)
  260. {
  261. int ret = 0;
  262. int type = sec_pmic->device_type;
  263. if (!sec_pmic->irq) {
  264. dev_warn(sec_pmic->dev,
  265. "No interrupt specified, no interrupts\n");
  266. sec_pmic->irq_base = 0;
  267. return 0;
  268. }
  269. switch (type) {
  270. case S5M8763X:
  271. ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
  272. IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  273. sec_pmic->irq_base, &s5m8763_irq_chip,
  274. &sec_pmic->irq_data);
  275. break;
  276. case S5M8767X:
  277. ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
  278. IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  279. sec_pmic->irq_base, &s5m8767_irq_chip,
  280. &sec_pmic->irq_data);
  281. break;
  282. case S2MPS11X:
  283. ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
  284. IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
  285. sec_pmic->irq_base, &s2mps11_irq_chip,
  286. &sec_pmic->irq_data);
  287. break;
  288. default:
  289. dev_err(sec_pmic->dev, "Unknown device type %d\n",
  290. sec_pmic->device_type);
  291. return -EINVAL;
  292. }
  293. if (ret != 0) {
  294. dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
  295. return ret;
  296. }
  297. return 0;
  298. }
  299. void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
  300. {
  301. regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
  302. }