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