blob: d2d8cbaf6ab076d0bd9207719bec87a2d4dfbd21 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/mutex.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/err.h>
19#include <linux/msm_adc.h>
20#include <linux/pmic8058-xoadc.h>
21#include <linux/mfd/pmic8058.h>
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <linux/ratelimit.h>
25#include <linux/delay.h>
26
27#include <mach/mpp.h>
28#include <mach/msm_xo.h>
29
30#define ADC_DRIVER_NAME "pm8058-xoadc"
31
32#define MAX_QUEUE_LENGTH 0X15
33#define MAX_CHANNEL_PROPERTIES_QUEUE 0X7
34#define MAX_QUEUE_SLOT 0x1
35
36/* User Processor */
37#define ADC_ARB_USRP_CNTRL 0x197
38 #define ADC_ARB_USRP_CNTRL_EN_ARB BIT(0)
39 #define ADC_ARB_USRP_CNTRL_RSV1 BIT(1)
40 #define ADC_ARB_USRP_CNTRL_RSV2 BIT(2)
41 #define ADC_ARB_USRP_CNTRL_RSV3 BIT(3)
42 #define ADC_ARB_USRP_CNTRL_RSV4 BIT(4)
43 #define ADC_ARB_USRP_CNTRL_RSV5 BIT(5)
44 #define ADC_ARB_USRP_CNTRL_EOC BIT(6)
45 #define ADC_ARB_USRP_CNTRL_REQ BIT(7)
46
47#define ADC_ARB_USRP_AMUX_CNTRL 0x198
48#define ADC_ARB_USRP_ANA_PARAM 0x199
49#define ADC_ARB_USRP_DIG_PARAM 0x19A
50#define ADC_ARB_USRP_RSV 0x19B
51
52#define ADC_ARB_USRP_DATA0 0x19D
53#define ADC_ARB_USRP_DATA1 0x19C
54
55struct pmic8058_adc {
56 struct xoadc_platform_data *pdata;
57 struct pm8058_chip *pm_chip;
58 struct adc_properties *adc_prop;
59 struct xoadc_conv_state conv[2];
60 int xoadc_queue_count;
61 int adc_irq;
62 struct linear_graph *adc_graph;
63 struct xoadc_conv_state *conv_slot_request;
64 struct xoadc_conv_state *conv_queue_list;
65 struct adc_conv_slot conv_queue_elements[MAX_QUEUE_LENGTH];
66 int xoadc_num;
67 struct msm_xo_voter *adc_voter;
68};
69
70static struct pmic8058_adc *pmic_adc[XOADC_PMIC_0 + 1];
71
72static bool xoadc_initialized, xoadc_calib_first_adc;
73
74DEFINE_RATELIMIT_STATE(pm8058_xoadc_msg_ratelimit,
75 DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);
76
77static inline int pm8058_xoadc_can_print(void)
78{
79 return __ratelimit(&pm8058_xoadc_msg_ratelimit);
80}
81
82int32_t pm8058_xoadc_registered(void)
83{
84 return xoadc_initialized;
85}
86EXPORT_SYMBOL(pm8058_xoadc_registered);
87
88void pm8058_xoadc_restore_slot(uint32_t adc_instance,
89 struct adc_conv_slot *slot)
90{
91 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
92 struct xoadc_conv_state *slot_state = adc_pmic->conv_slot_request;
93
94 mutex_lock(&slot_state->list_lock);
95 list_add(&slot->list, &slot_state->slots);
96 mutex_unlock(&slot_state->list_lock);
97}
98EXPORT_SYMBOL(pm8058_xoadc_restore_slot);
99
100void pm8058_xoadc_slot_request(uint32_t adc_instance,
101 struct adc_conv_slot **slot)
102{
103 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
104 struct xoadc_conv_state *slot_state = adc_pmic->conv_slot_request;
105
106 mutex_lock(&slot_state->list_lock);
107
108 if (!list_empty(&slot_state->slots)) {
109 *slot = list_first_entry(&slot_state->slots,
110 struct adc_conv_slot, list);
111 list_del(&(*slot)->list);
112 } else
113 *slot = NULL;
114
115 mutex_unlock(&slot_state->list_lock);
116}
117EXPORT_SYMBOL(pm8058_xoadc_slot_request);
118
119static int32_t pm8058_xoadc_arb_cntrl(uint32_t arb_cntrl,
120 uint32_t adc_instance)
121{
122 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
123 int i, rc;
124 u8 data_arb_cntrl;
125
126 data_arb_cntrl = ADC_ARB_USRP_CNTRL_EOC |
127 ADC_ARB_USRP_CNTRL_RSV5 |
128 ADC_ARB_USRP_CNTRL_RSV4;
129
130 if (arb_cntrl) {
131 data_arb_cntrl |= ADC_ARB_USRP_CNTRL_EN_ARB;
132 msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_ON);
133 adc_pmic->pdata->xoadc_mpp_config();
134 }
135
136 /* Write twice to the CNTRL register for the arbiter settings
137 to take into effect */
138 for (i = 0; i < 2; i++) {
139 rc = pm8058_write(adc_pmic->pm_chip, ADC_ARB_USRP_CNTRL,
140 &data_arb_cntrl, 1);
141 if (rc < 0) {
142 pr_debug("%s: PM8058 write failed\n", __func__);
143 return rc;
144 }
145 }
146
147 if (!arb_cntrl)
148 msm_xo_mode_vote(adc_pmic->adc_voter, MSM_XO_MODE_OFF);
149
150 return 0;
151}
152
153static int32_t pm8058_xoadc_configure(uint32_t adc_instance,
154 struct adc_conv_slot *slot)
155{
156
157 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
158 u8 data_arb_cntrl, data_amux_chan, data_arb_rsv, data_ana_param;
159 u8 data_dig_param, data_ana_param2;
160 int rc;
161
162 rc = pm8058_xoadc_arb_cntrl(1, adc_instance);
163 if (rc < 0) {
164 pr_debug("%s: Configuring ADC Arbiter"
165 "enable failed\n", __func__);
166 return rc;
167 }
168
169 switch (slot->chan_path) {
170
171 case CHAN_PATH_TYPE1:
172 data_amux_chan = CHANNEL_VCOIN << 4;
173 data_arb_rsv = 0x20;
174 slot->chan_properties.gain_numerator = 1;
175 slot->chan_properties.gain_denominator = 2;
176 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
177 break;
178
179 case CHAN_PATH_TYPE2:
180 data_amux_chan = CHANNEL_VBAT << 4;
181 data_arb_rsv = 0x20;
182 slot->chan_properties.gain_numerator = 1;
183 slot->chan_properties.gain_denominator = 3;
184 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
185 break;
186
187 case CHAN_PATH_TYPE3:
188 data_amux_chan = CHANNEL_VCHG << 4;
189 data_arb_rsv = 0x20;
190 slot->chan_properties.gain_numerator = 1;
191 slot->chan_properties.gain_denominator = 10;
192 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
193 break;
194
195 case CHAN_PATH_TYPE4:
196 data_amux_chan = CHANNEL_CHG_MONITOR << 4;
197 data_arb_rsv = 0x20;
198 slot->chan_properties.gain_numerator = 1;
199 slot->chan_properties.gain_denominator = 1;
200 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
201 break;
202
203 case CHAN_PATH_TYPE5:
204 data_amux_chan = CHANNEL_VPH_PWR << 4;
205 data_arb_rsv = 0x20;
206 slot->chan_properties.gain_numerator = 1;
207 slot->chan_properties.gain_denominator = 3;
208 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
209 break;
210
211 case CHAN_PATH_TYPE6:
212 data_amux_chan = CHANNEL_MPP5 << 4;
213 data_arb_rsv = 0x20;
214 slot->chan_properties.gain_numerator = 1;
215 slot->chan_properties.gain_denominator = 1;
216 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
217 break;
218
219 case CHAN_PATH_TYPE7:
220 data_amux_chan = CHANNEL_MPP6 << 4;
221 data_arb_rsv = 0x20;
222 slot->chan_properties.gain_numerator = 1;
223 slot->chan_properties.gain_denominator = 1;
224 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
225 break;
226
227 case CHAN_PATH_TYPE8:
228 data_amux_chan = CHANNEL_MPP7 << 4;
229 data_arb_rsv = 0x20;
230 slot->chan_properties.gain_numerator = 1;
231 slot->chan_properties.gain_denominator = 2;
232 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
233 break;
234
235 case CHAN_PATH_TYPE9:
236 data_amux_chan = CHANNEL_MPP8 << 4;
237 data_arb_rsv = 0x20;
238 slot->chan_properties.gain_numerator = 1;
239 slot->chan_properties.gain_denominator = 2;
240 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
241 break;
242
243 case CHAN_PATH_TYPE10:
244 data_amux_chan = CHANNEL_MPP9 << 4;
245 data_arb_rsv = 0x20;
246 slot->chan_properties.gain_numerator = 1;
247 slot->chan_properties.gain_denominator = 3;
248 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
249 break;
250
251 case CHAN_PATH_TYPE11:
252 data_amux_chan = CHANNEL_USB_VBUS << 4;
253 data_arb_rsv = 0x20;
254 slot->chan_properties.gain_numerator = 1;
255 slot->chan_properties.gain_denominator = 3;
256 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
257 break;
258
259 case CHAN_PATH_TYPE12:
260 data_amux_chan = CHANNEL_DIE_TEMP << 4;
261 data_arb_rsv = 0x20;
262 slot->chan_properties.gain_numerator = 1;
263 slot->chan_properties.gain_denominator = 1;
264 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
265 break;
266
267 case CHAN_PATH_TYPE13:
268 data_amux_chan = CHANNEL_125V << 4;
269 data_arb_rsv = 0x20;
270 slot->chan_properties.gain_numerator = 1;
271 slot->chan_properties.gain_denominator = 1;
272 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
273 break;
274
275 case CHAN_PATH_TYPE14:
276 data_amux_chan = CHANNEL_INTERNAL_2 << 4;
277 data_arb_rsv = 0x20;
278 slot->chan_properties.gain_numerator = 1;
279 slot->chan_properties.gain_denominator = 1;
280 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
281 break;
282
283 case CHAN_PATH_TYPE_NONE:
284 data_amux_chan = CHANNEL_MUXOFF << 4;
285 data_arb_rsv = 0x10;
286 slot->chan_properties.gain_numerator = 1;
287 slot->chan_properties.gain_denominator = 1;
288 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[1];
289 break;
290
291 case CHAN_PATH_TYPE15:
292 data_amux_chan = CHANNEL_INTERNAL << 4;
293 data_arb_rsv = 0x20;
294 slot->chan_properties.gain_numerator = 1;
295 slot->chan_properties.gain_denominator = 1;
296 slot->chan_properties.adc_graph = &adc_pmic->adc_graph[0];
297 break;
298 }
299
300 rc = pm8058_write(adc_pmic->pm_chip,
301 ADC_ARB_USRP_AMUX_CNTRL, &data_amux_chan, 1);
302 if (rc < 0) {
303 pr_debug("%s: PM8058 write failed\n", __func__);
304 return rc;
305 }
306
307 rc = pm8058_write(adc_pmic->pm_chip,
308 ADC_ARB_USRP_RSV, &data_arb_rsv, 1);
309 if (rc < 0) {
310 pr_debug("%s: PM8058 write failed\n", __func__);
311 return rc;
312 }
313
314 /* Set default clock rate to 2.4 MHz XO ADC clock digital */
315 switch (slot->chan_adc_config) {
316
317 case ADC_CONFIG_TYPE1:
318 data_ana_param = 0xFE;
319 data_dig_param = 0x23;
320 data_ana_param2 = 0xFF;
321 /* AMUX register data to start the ADC conversion */
322 data_arb_cntrl = 0xF1;
323 break;
324
325 case ADC_CONFIG_TYPE2:
326 data_ana_param = 0xFE;
327 data_dig_param = 0x03;
328 data_ana_param2 = 0xFF;
329 /* AMUX register data to start the ADC conversion */
330 data_arb_cntrl = 0xF1;
331 break;
332 }
333
334 rc = pm8058_write(adc_pmic->pm_chip,
335 ADC_ARB_USRP_ANA_PARAM, &data_ana_param, 1);
336 if (rc < 0) {
337 pr_debug("%s: PM8058 write failed\n", __func__);
338 return rc;
339 }
340
341 rc = pm8058_write(adc_pmic->pm_chip,
342 ADC_ARB_USRP_DIG_PARAM, &data_dig_param, 1);
343 if (rc < 0) {
344 pr_debug("%s: PM8058 write failed\n", __func__);
345 return rc;
346 }
347
348 rc = pm8058_write(adc_pmic->pm_chip,
349 ADC_ARB_USRP_ANA_PARAM, &data_ana_param2, 1);
350 if (rc < 0) {
351 pr_debug("%s: PM8058 write failed\n", __func__);
352 return rc;
353 }
354
355 enable_irq(adc_pmic->adc_irq);
356
357 rc = pm8058_write(adc_pmic->pm_chip,
358 ADC_ARB_USRP_CNTRL, &data_arb_cntrl, 1);
359 if (rc < 0) {
360 pr_debug("%s: PM8058 write failed\n", __func__);
361 return rc;
362 }
363
364 return 0;
365}
366
367int32_t pm8058_xoadc_select_chan_and_start_conv(uint32_t adc_instance,
368 struct adc_conv_slot *slot)
369{
370 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
371 struct xoadc_conv_state *slot_state = adc_pmic->conv_queue_list;
372
373 if (!xoadc_initialized)
374 return -ENODEV;
375
376 mutex_lock(&slot_state->list_lock);
377 list_add_tail(&slot->list, &slot_state->slots);
378 if (adc_pmic->xoadc_queue_count == 0) {
379 if (adc_pmic->pdata->xoadc_vreg_set != NULL)
380 adc_pmic->pdata->xoadc_vreg_set(1);
381 pm8058_xoadc_configure(adc_instance, slot);
382 }
383 adc_pmic->xoadc_queue_count++;
384 mutex_unlock(&slot_state->list_lock);
385
386 return 0;
387}
388EXPORT_SYMBOL(pm8058_xoadc_select_chan_and_start_conv);
389
390static int32_t pm8058_xoadc_dequeue_slot_request(uint32_t adc_instance,
391 struct adc_conv_slot **slot)
392{
393 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
394 struct xoadc_conv_state *slot_state = adc_pmic->conv_queue_list;
395 int rc = 0;
396
397 mutex_lock(&slot_state->list_lock);
398 if (adc_pmic->xoadc_queue_count > 0 &&
399 !list_empty(&slot_state->slots)) {
400 *slot = list_first_entry(&slot_state->slots,
401 struct adc_conv_slot, list);
402 list_del(&(*slot)->list);
403 } else
404 rc = -EINVAL;
405 mutex_unlock(&slot_state->list_lock);
406
407 if (rc < 0) {
408 if (pm8058_xoadc_can_print())
409 pr_err("Pmic 8058 xoadc spurious interrupt detected\n");
410 return rc;
411 }
412
413 return 0;
414}
415
416int32_t pm8058_xoadc_read_adc_code(uint32_t adc_instance, int32_t *data)
417{
418 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
419 struct xoadc_conv_state *slot_state = adc_pmic->conv_queue_list;
420 uint8_t rslt_lsb, rslt_msb;
421 struct adc_conv_slot *slot;
422 int32_t rc, max_ideal_adc_code = 1 << adc_pmic->adc_prop->bitresolution;
423
424 if (!xoadc_initialized)
425 return -ENODEV;
426
427 rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA0, &rslt_lsb, 1);
428 if (rc < 0) {
429 pr_debug("%s: PM8058 read failed\n", __func__);
430 return rc;
431 }
432
433 rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA1, &rslt_msb, 1);
434 if (rc < 0) {
435 pr_debug("%s: PM8058 read failed\n", __func__);
436 return rc;
437 }
438
439 *data = (rslt_msb << 8) | rslt_lsb;
440
441 /* Use the midpoint to determine underflow or overflow */
442 if (*data > max_ideal_adc_code + (max_ideal_adc_code >> 1))
443 *data |= ((1 << (8 * sizeof(*data) -
444 adc_pmic->adc_prop->bitresolution)) - 1) <<
445 adc_pmic->adc_prop->bitresolution;
446 /* Return if this is a calibration run since there
447 * is no need to check requests in the waiting queue */
448 if (xoadc_calib_first_adc)
449 return 0;
450
451 mutex_lock(&slot_state->list_lock);
452 adc_pmic->xoadc_queue_count--;
453 if (adc_pmic->xoadc_queue_count > 0) {
454 slot = list_first_entry(&slot_state->slots,
455 struct adc_conv_slot, list);
456 pm8058_xoadc_configure(adc_instance, slot);
457 }
458 mutex_unlock(&slot_state->list_lock);
459
460 mutex_lock(&slot_state->list_lock);
461 /* Default value for switching off the arbiter after reading
462 the ADC value. Bit 0 set to 0. */
463 if (adc_pmic->xoadc_queue_count == 0) {
464 rc = pm8058_xoadc_arb_cntrl(0, adc_instance);
465 if (rc < 0) {
466 pr_debug("%s: Configuring ADC Arbiter disable"
467 "failed\n", __func__);
468 return rc;
469 }
470 if (adc_pmic->pdata->xoadc_vreg_set != NULL)
471 adc_pmic->pdata->xoadc_vreg_set(0);
472 }
473 mutex_unlock(&slot_state->list_lock);
474
475 return 0;
476}
477EXPORT_SYMBOL(pm8058_xoadc_read_adc_code);
478
479static irqreturn_t pm8058_xoadc(int irq, void *dev_id)
480{
481 struct pmic8058_adc *xoadc_8058 = dev_id;
482 struct adc_conv_slot *slot = NULL;
483 int rc;
484
485 disable_irq_nosync(xoadc_8058->adc_irq);
486
487 if (xoadc_calib_first_adc)
488 return IRQ_HANDLED;
489
490 rc = pm8058_xoadc_dequeue_slot_request(xoadc_8058->xoadc_num, &slot);
491
492 if (rc < 0)
493 return IRQ_NONE;
494
495 if (rc == 0)
496 msm_adc_conv_cb(slot, 0, NULL, 0);
497
498 return IRQ_HANDLED;
499}
500
501struct adc_properties *pm8058_xoadc_get_properties(uint32_t dev_instance)
502{
503 struct pmic8058_adc *xoadc_8058 = pmic_adc[dev_instance];
504
505 return xoadc_8058->adc_prop;
506}
507EXPORT_SYMBOL(pm8058_xoadc_get_properties);
508
509int32_t pm8058_xoadc_calib_device(uint32_t adc_instance)
510{
511 struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
512 struct adc_conv_slot *slot;
513 int rc, offset_xoadc, slope_xoadc, calib_read_1, calib_read_2;
514
515 if (adc_pmic->pdata->xoadc_vreg_set != NULL)
516 adc_pmic->pdata->xoadc_vreg_set(1);
517
518 pm8058_xoadc_slot_request(adc_instance, &slot);
519 if (slot) {
520 slot->chan_path = CHAN_PATH_TYPE13;
521 slot->chan_adc_config = ADC_CONFIG_TYPE2;
522 slot->chan_adc_calib = ADC_CONFIG_TYPE2;
523 xoadc_calib_first_adc = true;
524 rc = pm8058_xoadc_configure(adc_instance, slot);
525 if (rc) {
526 pr_err("pm8058_xoadc configure failed\n");
527 goto fail;
528 }
529 } else {
530 rc = -EINVAL;
531 goto fail;
532 }
533
534 msleep(3);
535
536 rc = pm8058_xoadc_read_adc_code(adc_instance, &calib_read_1);
537 if (rc) {
538 pr_err("pm8058_xoadc read adc failed\n");
539 xoadc_calib_first_adc = false;
540 goto fail;
541 }
542 xoadc_calib_first_adc = false;
543
544 pm8058_xoadc_slot_request(adc_instance, &slot);
545 if (slot) {
546 slot->chan_path = CHAN_PATH_TYPE15;
547 slot->chan_adc_config = ADC_CONFIG_TYPE2;
548 slot->chan_adc_calib = ADC_CONFIG_TYPE2;
549 xoadc_calib_first_adc = true;
550 rc = pm8058_xoadc_configure(adc_instance, slot);
551 if (rc) {
552 pr_err("pm8058_xoadc configure failed\n");
553 goto fail;
554 }
555 } else {
556 rc = -EINVAL;
557 goto fail;
558 }
559
560 msleep(3);
561
562 rc = pm8058_xoadc_read_adc_code(adc_instance, &calib_read_2);
563 if (rc) {
564 pr_err("pm8058_xoadc read adc failed\n");
565 xoadc_calib_first_adc = false;
566 goto fail;
567 }
568 xoadc_calib_first_adc = false;
569
570 pm8058_xoadc_restore_slot(adc_instance, slot);
571
572 slope_xoadc = (((calib_read_1 - calib_read_2) << 10)/
573 CHANNEL_ADC_625_MV);
574 offset_xoadc = calib_read_2 -
575 ((slope_xoadc * CHANNEL_ADC_625_MV) >> 10);
576
577 printk(KERN_INFO"pmic8058_xoadc:The offset for AMUX calibration"
578 "was %d\n", offset_xoadc);
579
580 adc_pmic->adc_graph[0].offset = offset_xoadc;
581 adc_pmic->adc_graph[0].dy = (calib_read_1 - calib_read_2);
582 adc_pmic->adc_graph[0].dx = CHANNEL_ADC_625_MV;
583
584 /* Retain ideal calibration settings for therm readings */
585 adc_pmic->adc_graph[1].offset = 0 ;
586 adc_pmic->adc_graph[1].dy = (1 << 15) - 1;
587 adc_pmic->adc_graph[1].dx = 2200;
588
589 if (adc_pmic->pdata->xoadc_vreg_set != NULL)
590 adc_pmic->pdata->xoadc_vreg_set(0);
591
592 return 0;
593fail:
594 if (adc_pmic->pdata->xoadc_vreg_set != NULL)
595 adc_pmic->pdata->xoadc_vreg_set(0);
596
597 return rc;
598}
599EXPORT_SYMBOL(pm8058_xoadc_calib_device);
600
601int32_t pm8058_xoadc_calibrate(uint32_t dev_instance,
602 struct adc_conv_slot *slot, int *calib_status)
603{
604 *calib_status = CALIB_NOT_REQUIRED;
605
606 return 0;
607}
608EXPORT_SYMBOL(pm8058_xoadc_calibrate);
609
610static int __devexit pm8058_xoadc_teardown(struct platform_device *pdev)
611{
612 struct pmic8058_adc *adc_pmic = platform_get_drvdata(pdev);
613
614 if (adc_pmic->pdata->xoadc_vreg_shutdown != NULL)
615 adc_pmic->pdata->xoadc_vreg_shutdown();
616
617 msm_xo_put(adc_pmic->adc_voter);
618 platform_set_drvdata(pdev, adc_pmic->pm_chip);
619 device_init_wakeup(&pdev->dev, 0);
620 kfree(adc_pmic);
621 xoadc_initialized = false;
622
623 return 0;
624}
625
626static int __devinit pm8058_xoadc_probe(struct platform_device *pdev)
627{
628 struct xoadc_platform_data *pdata = pdev->dev.platform_data;
629 struct pm8058_chip *pm_chip;
630 struct pmic8058_adc *adc_pmic;
631 int i, rc = 0;
632
633 pm_chip = dev_get_drvdata(pdev->dev.parent);
634 if (pm_chip == NULL) {
635 dev_err(&pdev->dev, "no parent data passed in\n");
636 return -EFAULT;
637 }
638
639 if (!pdata) {
640 dev_err(&pdev->dev, "no platform data?\n");
641 return -EINVAL;
642 }
643
644 adc_pmic = kzalloc(sizeof(struct pmic8058_adc), GFP_KERNEL);
645 if (!adc_pmic) {
646 dev_err(&pdev->dev, "Unable to allocate memory\n");
647 return -ENOMEM;
648 }
649
650 adc_pmic->pm_chip = pm_chip;
651 adc_pmic->adc_prop = pdata->xoadc_prop;
652 adc_pmic->xoadc_num = pdata->xoadc_num;
653 adc_pmic->xoadc_queue_count = 0;
654
655 platform_set_drvdata(pdev, adc_pmic);
656
657 if (adc_pmic->xoadc_num > XOADC_PMIC_0) {
658 dev_err(&pdev->dev, "ADC device not supported\n");
659 rc = -EINVAL;
660 goto err_cleanup;
661 }
662
663 adc_pmic->pdata = pdata;
664 adc_pmic->adc_graph = kzalloc(sizeof(struct linear_graph)
665 * MAX_CHANNEL_PROPERTIES_QUEUE, GFP_KERNEL);
666 if (!adc_pmic->adc_graph) {
667 dev_err(&pdev->dev, "Unable to allocate memory\n");
668 rc = -ENOMEM;
669 goto err_cleanup;
670 }
671
672 /* Will be replaced by individual channel calibration */
673 for (i = 0; i < MAX_CHANNEL_PROPERTIES_QUEUE; i++) {
674 adc_pmic->adc_graph[i].offset = 0 ;
675 adc_pmic->adc_graph[i].dy = (1 << 15) - 1;
676 adc_pmic->adc_graph[i].dx = 2200;
677 }
678
679 if (pdata->xoadc_mpp_config != NULL)
680 pdata->xoadc_mpp_config();
681
682 adc_pmic->conv_slot_request = &adc_pmic->conv[0];
683 adc_pmic->conv_slot_request->context =
684 &adc_pmic->conv_queue_elements[0];
685
686 mutex_init(&adc_pmic->conv_slot_request->list_lock);
687 INIT_LIST_HEAD(&adc_pmic->conv_slot_request->slots);
688
689 /* tie each slot and initwork them */
690 for (i = 0; i < MAX_QUEUE_LENGTH; i++) {
691 list_add(&adc_pmic->conv_slot_request->context[i].list,
692 &adc_pmic->conv_slot_request->slots);
693 INIT_WORK(&adc_pmic->conv_slot_request->context[i].work,
694 msm_adc_wq_work);
695 init_completion(&adc_pmic->conv_slot_request->context[i].comp);
696 adc_pmic->conv_slot_request->context[i].idx = i;
697 }
698
699 adc_pmic->conv_queue_list = &adc_pmic->conv[1];
700
701 mutex_init(&adc_pmic->conv_queue_list->list_lock);
702 INIT_LIST_HEAD(&adc_pmic->conv_queue_list->slots);
703
704 adc_pmic->adc_irq = platform_get_irq(pdev, 0);
705 if (adc_pmic->adc_irq < 0) {
706 rc = -ENXIO;
707 goto err_cleanup;
708 }
709
710 rc = request_threaded_irq(adc_pmic->adc_irq,
711 NULL, pm8058_xoadc,
712 IRQF_TRIGGER_RISING, "pm8058_adc_interrupt", adc_pmic);
713 if (rc) {
714 dev_err(&pdev->dev, "failed to request adc irq\n");
715 goto err_cleanup;
716 }
717
718 disable_irq(adc_pmic->adc_irq);
719
720 device_init_wakeup(&pdev->dev, pdata->xoadc_wakeup);
721
722 if (adc_pmic->adc_voter == NULL) {
723 adc_pmic->adc_voter = msm_xo_get(MSM_XO_TCXO_D1,
724 "pmic8058_xoadc");
725 if (IS_ERR(adc_pmic->adc_voter)) {
726 dev_err(&pdev->dev, "Failed to get XO vote\n");
727 goto err_cleanup;
728 }
729 }
730
731 pmic_adc[adc_pmic->xoadc_num] = adc_pmic;
732
733 if (pdata->xoadc_vreg_setup != NULL)
734 pdata->xoadc_vreg_setup();
735
736 xoadc_initialized = true;
737 xoadc_calib_first_adc = false;
738
739 return 0;
740
741err_cleanup:
742 pm8058_xoadc_teardown(pdev);
743
744 return rc;
745}
746
747static struct platform_driver pm8058_xoadc_driver = {
748 .probe = pm8058_xoadc_probe,
749 .remove = __devexit_p(pm8058_xoadc_teardown),
750 .driver = {
751 .name = "pm8058-xoadc",
752 .owner = THIS_MODULE,
753 },
754};
755
756static int __init pm8058_xoadc_init(void)
757{
758 return platform_driver_register(&pm8058_xoadc_driver);
759}
760module_init(pm8058_xoadc_init);
761
762static void __exit pm8058_xoadc_exit(void)
763{
764 platform_driver_unregister(&pm8058_xoadc_driver);
765}
766module_exit(pm8058_xoadc_exit);
767
768MODULE_ALIAS("platform:pmic8058_xoadc");
769MODULE_DESCRIPTION("PMIC8058 XOADC driver");
770MODULE_LICENSE("GPL v2");