ab8500-gpadc.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2010
  3. *
  4. * License Terms: GNU General Public License v2
  5. * Author: Arun R Murthy <arun.murthy@stericsson.com>
  6. */
  7. #include <linux/init.h>
  8. #include <linux/module.h>
  9. #include <linux/device.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/spinlock.h>
  12. #include <linux/delay.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/completion.h>
  15. #include <linux/regulator/consumer.h>
  16. #include <linux/err.h>
  17. #include <linux/slab.h>
  18. #include <linux/mfd/ab8500.h>
  19. #include <linux/mfd/abx500.h>
  20. #include <linux/mfd/ab8500/ab8500-gpadc.h>
  21. /*
  22. * GPADC register offsets
  23. * Bank : 0x0A
  24. */
  25. #define AB8500_GPADC_CTRL1_REG 0x00
  26. #define AB8500_GPADC_CTRL2_REG 0x01
  27. #define AB8500_GPADC_CTRL3_REG 0x02
  28. #define AB8500_GPADC_AUTO_TIMER_REG 0x03
  29. #define AB8500_GPADC_STAT_REG 0x04
  30. #define AB8500_GPADC_MANDATAL_REG 0x05
  31. #define AB8500_GPADC_MANDATAH_REG 0x06
  32. #define AB8500_GPADC_AUTODATAL_REG 0x07
  33. #define AB8500_GPADC_AUTODATAH_REG 0x08
  34. #define AB8500_GPADC_MUX_CTRL_REG 0x09
  35. /* gpadc constants */
  36. #define EN_VINTCORE12 0x04
  37. #define EN_VTVOUT 0x02
  38. #define EN_GPADC 0x01
  39. #define DIS_GPADC 0x00
  40. #define SW_AVG_16 0x60
  41. #define ADC_SW_CONV 0x04
  42. #define EN_BUF 0x40
  43. #define DIS_ZERO 0x00
  44. #define GPADC_BUSY 0x01
  45. /**
  46. * struct ab8500_gpadc - ab8500 GPADC device information
  47. * @dev: pointer to the struct device
  48. * @parent: pointer to the parent device structure ab8500
  49. * @ab8500_gpadc_complete: pointer to the struct completion, to indicate
  50. * the completion of gpadc conversion
  51. * @ab8500_gpadc_lock: structure of type mutex
  52. * @regu: pointer to the struct regulator
  53. * @irq: interrupt number that is used by gpadc
  54. */
  55. static struct ab8500_gpadc {
  56. struct device *dev;
  57. struct ab8500 *parent;
  58. struct completion ab8500_gpadc_complete;
  59. struct mutex ab8500_gpadc_lock;
  60. struct regulator *regu;
  61. int irq;
  62. } *di;
  63. /**
  64. * ab8500_gpadc_convert() - gpadc conversion
  65. * @input: analog input to be converted to digital data
  66. *
  67. * This function converts the selected analog i/p to digital
  68. * data. Thereafter calibration has to be made to obtain the
  69. * data in the required quantity measurement.
  70. */
  71. int ab8500_gpadc_convert(u8 input)
  72. {
  73. int ret;
  74. u16 data = 0;
  75. int looplimit = 0;
  76. u8 val, low_data, high_data;
  77. if (!di)
  78. return -ENODEV;
  79. mutex_lock(&di->ab8500_gpadc_lock);
  80. /* Enable VTVout LDO this is required for GPADC */
  81. regulator_enable(di->regu);
  82. /* Check if ADC is not busy, lock and proceed */
  83. do {
  84. ret = abx500_get_register_interruptible(di->dev, AB8500_GPADC,
  85. AB8500_GPADC_STAT_REG, &val);
  86. if (ret < 0)
  87. goto out;
  88. if (!(val & GPADC_BUSY))
  89. break;
  90. msleep(10);
  91. } while (++looplimit < 10);
  92. if (looplimit >= 10 && (val & GPADC_BUSY)) {
  93. dev_err(di->dev, "gpadc_conversion: GPADC busy");
  94. ret = -EINVAL;
  95. goto out;
  96. }
  97. /* Enable GPADC */
  98. ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_GPADC,
  99. AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC);
  100. if (ret < 0) {
  101. dev_err(di->dev, "gpadc_conversion: enable gpadc failed\n");
  102. goto out;
  103. }
  104. /* Select the input source and set average samples to 16 */
  105. ret = abx500_set_register_interruptible(di->dev, AB8500_GPADC,
  106. AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
  107. if (ret < 0) {
  108. dev_err(di->dev,
  109. "gpadc_conversion: set avg samples failed\n");
  110. goto out;
  111. }
  112. /* Enable ADC, Buffering and select rising edge, start Conversion */
  113. ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_GPADC,
  114. AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
  115. if (ret < 0) {
  116. dev_err(di->dev,
  117. "gpadc_conversion: select falling edge failed\n");
  118. goto out;
  119. }
  120. ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_GPADC,
  121. AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV);
  122. if (ret < 0) {
  123. dev_err(di->dev,
  124. "gpadc_conversion: start s/w conversion failed\n");
  125. goto out;
  126. }
  127. /* wait for completion of conversion */
  128. if (!wait_for_completion_timeout(&di->ab8500_gpadc_complete, 2*HZ)) {
  129. dev_err(di->dev,
  130. "timeout: didnt recieve GPADC conversion interrupt\n");
  131. ret = -EINVAL;
  132. goto out;
  133. }
  134. /* Read the converted RAW data */
  135. ret = abx500_get_register_interruptible(di->dev, AB8500_GPADC,
  136. AB8500_GPADC_MANDATAL_REG, &low_data);
  137. if (ret < 0) {
  138. dev_err(di->dev, "gpadc_conversion: read low data failed\n");
  139. goto out;
  140. }
  141. ret = abx500_get_register_interruptible(di->dev, AB8500_GPADC,
  142. AB8500_GPADC_MANDATAH_REG, &high_data);
  143. if (ret < 0) {
  144. dev_err(di->dev, "gpadc_conversion: read high data failed\n");
  145. goto out;
  146. }
  147. data = (high_data << 8) | low_data;
  148. /* Disable GPADC */
  149. ret = abx500_set_register_interruptible(di->dev, AB8500_GPADC,
  150. AB8500_GPADC_CTRL1_REG, DIS_GPADC);
  151. if (ret < 0) {
  152. dev_err(di->dev, "gpadc_conversion: disable gpadc failed\n");
  153. goto out;
  154. }
  155. /* Disable VTVout LDO this is required for GPADC */
  156. regulator_disable(di->regu);
  157. mutex_unlock(&di->ab8500_gpadc_lock);
  158. return data;
  159. out:
  160. /*
  161. * It has shown to be needed to turn off the GPADC if an error occurs,
  162. * otherwise we might have problem when waiting for the busy bit in the
  163. * GPADC status register to go low. In V1.1 there wait_for_completion
  164. * seems to timeout when waiting for an interrupt.. Not seen in V2.0
  165. */
  166. (void) abx500_set_register_interruptible(di->dev, AB8500_GPADC,
  167. AB8500_GPADC_CTRL1_REG, DIS_GPADC);
  168. regulator_disable(di->regu);
  169. mutex_unlock(&di->ab8500_gpadc_lock);
  170. dev_err(di->dev, "gpadc_conversion: Failed to AD convert channel %d\n",
  171. input);
  172. return ret;
  173. }
  174. EXPORT_SYMBOL(ab8500_gpadc_convert);
  175. /**
  176. * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion
  177. * @irq: irq number
  178. * @data: pointer to the data passed during request irq
  179. *
  180. * This is a interrupt service routine for s/w gpadc conversion completion.
  181. * Notifies the gpadc completion is completed and the converted raw value
  182. * can be read from the registers.
  183. * Returns IRQ status(IRQ_HANDLED)
  184. */
  185. static irqreturn_t ab8500_bm_gpswadcconvend_handler(int irq, void *_di)
  186. {
  187. struct ab8500_gpadc *gpadc = _di;
  188. complete(&gpadc->ab8500_gpadc_complete);
  189. return IRQ_HANDLED;
  190. }
  191. static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
  192. {
  193. int ret = 0;
  194. struct ab8500_gpadc *gpadc;
  195. gpadc = kzalloc(sizeof(struct ab8500_gpadc), GFP_KERNEL);
  196. if (!gpadc) {
  197. dev_err(&pdev->dev, "Error: No memory\n");
  198. return -ENOMEM;
  199. }
  200. gpadc->parent = dev_get_drvdata(pdev->dev.parent);
  201. gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END");
  202. if (gpadc->irq < 0) {
  203. dev_err(gpadc->dev, "failed to get platform irq-%d\n", di->irq);
  204. ret = gpadc->irq;
  205. goto fail;
  206. }
  207. gpadc->dev = &pdev->dev;
  208. mutex_init(&di->ab8500_gpadc_lock);
  209. /* Initialize completion used to notify completion of conversion */
  210. init_completion(&gpadc->ab8500_gpadc_complete);
  211. /* Register interrupt - SwAdcComplete */
  212. ret = request_threaded_irq(gpadc->irq, NULL,
  213. ab8500_bm_gpswadcconvend_handler,
  214. IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc", gpadc);
  215. if (ret < 0) {
  216. dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n",
  217. gpadc->irq);
  218. goto fail;
  219. }
  220. /* VTVout LDO used to power up ab8500-GPADC */
  221. gpadc->regu = regulator_get(&pdev->dev, "vddadc");
  222. if (IS_ERR(gpadc->regu)) {
  223. ret = PTR_ERR(gpadc->regu);
  224. dev_err(gpadc->dev, "failed to get vtvout LDO\n");
  225. goto fail;
  226. }
  227. di = gpadc;
  228. dev_dbg(gpadc->dev, "probe success\n");
  229. return 0;
  230. fail:
  231. kfree(gpadc);
  232. gpadc = NULL;
  233. return ret;
  234. }
  235. static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
  236. {
  237. struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev);
  238. /* remove interrupt - completion of Sw ADC conversion */
  239. free_irq(gpadc->irq, di);
  240. /* disable VTVout LDO that is being used by GPADC */
  241. regulator_put(gpadc->regu);
  242. kfree(gpadc);
  243. gpadc = NULL;
  244. return 0;
  245. }
  246. static struct platform_driver ab8500_gpadc_driver = {
  247. .probe = ab8500_gpadc_probe,
  248. .remove = __devexit_p(ab8500_gpadc_remove),
  249. .driver = {
  250. .name = "ab8500-gpadc",
  251. .owner = THIS_MODULE,
  252. },
  253. };
  254. static int __init ab8500_gpadc_init(void)
  255. {
  256. return platform_driver_register(&ab8500_gpadc_driver);
  257. }
  258. static void __exit ab8500_gpadc_exit(void)
  259. {
  260. platform_driver_unregister(&ab8500_gpadc_driver);
  261. }
  262. subsys_initcall_sync(ab8500_gpadc_init);
  263. module_exit(ab8500_gpadc_exit);
  264. MODULE_LICENSE("GPL v2");
  265. MODULE_AUTHOR("Arun R Murthy");
  266. MODULE_ALIAS("platform:ab8500_gpadc");
  267. MODULE_DESCRIPTION("AB8500 GPADC driver");