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