wm831x-auxadc.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * wm831x-auxadc.c -- AUXADC for Wolfson WM831x PMICs
  4. *
  5. * Copyright 2009-2011 Wolfson Microelectronics PLC.
  6. *
  7. * Author: Mark Brown <[email protected]>
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/delay.h>
  12. #include <linux/mfd/core.h>
  13. #include <linux/slab.h>
  14. #include <linux/list.h>
  15. #include <linux/mfd/wm831x/core.h>
  16. #include <linux/mfd/wm831x/pdata.h>
  17. #include <linux/mfd/wm831x/irq.h>
  18. #include <linux/mfd/wm831x/auxadc.h>
  19. #include <linux/mfd/wm831x/otp.h>
  20. #include <linux/mfd/wm831x/regulator.h>
  21. struct wm831x_auxadc_req {
  22. struct list_head list;
  23. enum wm831x_auxadc input;
  24. int val;
  25. struct completion done;
  26. };
  27. static int wm831x_auxadc_read_irq(struct wm831x *wm831x,
  28. enum wm831x_auxadc input)
  29. {
  30. struct wm831x_auxadc_req *req;
  31. int ret;
  32. bool ena = false;
  33. req = kzalloc(sizeof(*req), GFP_KERNEL);
  34. if (!req)
  35. return -ENOMEM;
  36. init_completion(&req->done);
  37. req->input = input;
  38. req->val = -ETIMEDOUT;
  39. mutex_lock(&wm831x->auxadc_lock);
  40. /* Enqueue the request */
  41. list_add(&req->list, &wm831x->auxadc_pending);
  42. ena = !wm831x->auxadc_active;
  43. if (ena) {
  44. ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
  45. WM831X_AUX_ENA, WM831X_AUX_ENA);
  46. if (ret != 0) {
  47. dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n",
  48. ret);
  49. goto out;
  50. }
  51. }
  52. /* Enable the conversion if not already running */
  53. if (!(wm831x->auxadc_active & (1 << input))) {
  54. ret = wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE,
  55. 1 << input, 1 << input);
  56. if (ret != 0) {
  57. dev_err(wm831x->dev,
  58. "Failed to set AUXADC source: %d\n", ret);
  59. goto out;
  60. }
  61. wm831x->auxadc_active |= 1 << input;
  62. }
  63. /* We convert at the fastest rate possible */
  64. if (ena) {
  65. ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
  66. WM831X_AUX_CVT_ENA |
  67. WM831X_AUX_RATE_MASK,
  68. WM831X_AUX_CVT_ENA |
  69. WM831X_AUX_RATE_MASK);
  70. if (ret != 0) {
  71. dev_err(wm831x->dev, "Failed to start AUXADC: %d\n",
  72. ret);
  73. goto out;
  74. }
  75. }
  76. mutex_unlock(&wm831x->auxadc_lock);
  77. /* Wait for an interrupt */
  78. wait_for_completion_timeout(&req->done, msecs_to_jiffies(500));
  79. mutex_lock(&wm831x->auxadc_lock);
  80. ret = req->val;
  81. out:
  82. list_del(&req->list);
  83. mutex_unlock(&wm831x->auxadc_lock);
  84. kfree(req);
  85. return ret;
  86. }
  87. static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
  88. {
  89. struct wm831x *wm831x = irq_data;
  90. struct wm831x_auxadc_req *req;
  91. int ret, input, val;
  92. ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
  93. if (ret < 0) {
  94. dev_err(wm831x->dev,
  95. "Failed to read AUXADC data: %d\n", ret);
  96. return IRQ_NONE;
  97. }
  98. input = ((ret & WM831X_AUX_DATA_SRC_MASK)
  99. >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
  100. if (input == 14)
  101. input = WM831X_AUX_CAL;
  102. val = ret & WM831X_AUX_DATA_MASK;
  103. mutex_lock(&wm831x->auxadc_lock);
  104. /* Disable this conversion, we're about to complete all users */
  105. wm831x_set_bits(wm831x, WM831X_AUXADC_SOURCE,
  106. 1 << input, 0);
  107. wm831x->auxadc_active &= ~(1 << input);
  108. /* Turn off the entire convertor if idle */
  109. if (!wm831x->auxadc_active)
  110. wm831x_reg_write(wm831x, WM831X_AUXADC_CONTROL, 0);
  111. /* Wake up any threads waiting for this request */
  112. list_for_each_entry(req, &wm831x->auxadc_pending, list) {
  113. if (req->input == input) {
  114. req->val = val;
  115. complete(&req->done);
  116. }
  117. }
  118. mutex_unlock(&wm831x->auxadc_lock);
  119. return IRQ_HANDLED;
  120. }
  121. static int wm831x_auxadc_read_polled(struct wm831x *wm831x,
  122. enum wm831x_auxadc input)
  123. {
  124. int ret, src, timeout;
  125. mutex_lock(&wm831x->auxadc_lock);
  126. ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
  127. WM831X_AUX_ENA, WM831X_AUX_ENA);
  128. if (ret < 0) {
  129. dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret);
  130. goto out;
  131. }
  132. /* We force a single source at present */
  133. src = input;
  134. ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE,
  135. 1 << src);
  136. if (ret < 0) {
  137. dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret);
  138. goto out;
  139. }
  140. ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
  141. WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA);
  142. if (ret < 0) {
  143. dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret);
  144. goto disable;
  145. }
  146. /* If we're not using interrupts then poll the
  147. * interrupt status register */
  148. timeout = 5;
  149. while (timeout) {
  150. msleep(1);
  151. ret = wm831x_reg_read(wm831x,
  152. WM831X_INTERRUPT_STATUS_1);
  153. if (ret < 0) {
  154. dev_err(wm831x->dev,
  155. "ISR 1 read failed: %d\n", ret);
  156. goto disable;
  157. }
  158. /* Did it complete? */
  159. if (ret & WM831X_AUXADC_DATA_EINT) {
  160. wm831x_reg_write(wm831x,
  161. WM831X_INTERRUPT_STATUS_1,
  162. WM831X_AUXADC_DATA_EINT);
  163. break;
  164. } else {
  165. dev_err(wm831x->dev,
  166. "AUXADC conversion timeout\n");
  167. ret = -EBUSY;
  168. goto disable;
  169. }
  170. }
  171. ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
  172. if (ret < 0) {
  173. dev_err(wm831x->dev,
  174. "Failed to read AUXADC data: %d\n", ret);
  175. goto disable;
  176. }
  177. src = ((ret & WM831X_AUX_DATA_SRC_MASK)
  178. >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
  179. if (src == 14)
  180. src = WM831X_AUX_CAL;
  181. if (src != input) {
  182. dev_err(wm831x->dev, "Data from source %d not %d\n",
  183. src, input);
  184. ret = -EINVAL;
  185. } else {
  186. ret &= WM831X_AUX_DATA_MASK;
  187. }
  188. disable:
  189. wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0);
  190. out:
  191. mutex_unlock(&wm831x->auxadc_lock);
  192. return ret;
  193. }
  194. /**
  195. * wm831x_auxadc_read: Read a value from the WM831x AUXADC
  196. *
  197. * @wm831x: Device to read from.
  198. * @input: AUXADC input to read.
  199. */
  200. int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
  201. {
  202. return wm831x->auxadc_read(wm831x, input);
  203. }
  204. EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
  205. /**
  206. * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
  207. *
  208. * @wm831x: Device to read from.
  209. * @input: AUXADC input to read.
  210. */
  211. int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input)
  212. {
  213. int ret;
  214. ret = wm831x_auxadc_read(wm831x, input);
  215. if (ret < 0)
  216. return ret;
  217. ret *= 1465;
  218. return ret;
  219. }
  220. EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv);
  221. void wm831x_auxadc_init(struct wm831x *wm831x)
  222. {
  223. int ret;
  224. mutex_init(&wm831x->auxadc_lock);
  225. INIT_LIST_HEAD(&wm831x->auxadc_pending);
  226. if (wm831x->irq) {
  227. wm831x->auxadc_read = wm831x_auxadc_read_irq;
  228. ret = request_threaded_irq(wm831x_irq(wm831x,
  229. WM831X_IRQ_AUXADC_DATA),
  230. NULL, wm831x_auxadc_irq,
  231. IRQF_ONESHOT,
  232. "auxadc", wm831x);
  233. if (ret < 0) {
  234. dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
  235. ret);
  236. wm831x->auxadc_read = NULL;
  237. }
  238. }
  239. if (!wm831x->auxadc_read)
  240. wm831x->auxadc_read = wm831x_auxadc_read_polled;
  241. }