diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-08 05:19:40 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-08 05:20:34 -0400 |
commit | 8b5fd8516cfdd187f35c45f5f818da94aa3b42e9 (patch) | |
tree | 5a2d4a3143f3573aafa2fa180991485e45ac5f8e /drivers/mfd/ab8500-gpadc.c | |
parent | 9d66b568a215fe2da2a9db736ebf9b8d66082d88 (diff) | |
parent | b09f86dbfc20d9420dac43dba016cb65b582c983 (diff) |
Merge branch 'for-mfd-and-power' of git://git.linaro.org/people/ljones/linux-3.0-ux500
Conflicts:
drivers/mfd/ab8500-gpadc.c
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/ab8500-gpadc.c')
-rw-r--r-- | drivers/mfd/ab8500-gpadc.c | 559 |
1 files changed, 456 insertions, 103 deletions
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index 5f341a50ee5a..65f72284185d 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c | |||
@@ -37,6 +37,13 @@ | |||
37 | #define AB8500_GPADC_AUTODATAL_REG 0x07 | 37 | #define AB8500_GPADC_AUTODATAL_REG 0x07 |
38 | #define AB8500_GPADC_AUTODATAH_REG 0x08 | 38 | #define AB8500_GPADC_AUTODATAH_REG 0x08 |
39 | #define AB8500_GPADC_MUX_CTRL_REG 0x09 | 39 | #define AB8500_GPADC_MUX_CTRL_REG 0x09 |
40 | #define AB8540_GPADC_MANDATA2L_REG 0x09 | ||
41 | #define AB8540_GPADC_MANDATA2H_REG 0x0A | ||
42 | #define AB8540_GPADC_APEAAX_REG 0x10 | ||
43 | #define AB8540_GPADC_APEAAT_REG 0x11 | ||
44 | #define AB8540_GPADC_APEAAM_REG 0x12 | ||
45 | #define AB8540_GPADC_APEAAH_REG 0x13 | ||
46 | #define AB8540_GPADC_APEAAL_REG 0x14 | ||
40 | 47 | ||
41 | /* | 48 | /* |
42 | * OTP register offsets | 49 | * OTP register offsets |
@@ -49,19 +56,29 @@ | |||
49 | #define AB8500_GPADC_CAL_5 0x13 | 56 | #define AB8500_GPADC_CAL_5 0x13 |
50 | #define AB8500_GPADC_CAL_6 0x14 | 57 | #define AB8500_GPADC_CAL_6 0x14 |
51 | #define AB8500_GPADC_CAL_7 0x15 | 58 | #define AB8500_GPADC_CAL_7 0x15 |
59 | /* New calibration for 8540 */ | ||
60 | #define AB8540_GPADC_OTP4_REG_7 0x38 | ||
61 | #define AB8540_GPADC_OTP4_REG_6 0x39 | ||
62 | #define AB8540_GPADC_OTP4_REG_5 0x3A | ||
52 | 63 | ||
53 | /* gpadc constants */ | 64 | /* gpadc constants */ |
54 | #define EN_VINTCORE12 0x04 | 65 | #define EN_VINTCORE12 0x04 |
55 | #define EN_VTVOUT 0x02 | 66 | #define EN_VTVOUT 0x02 |
56 | #define EN_GPADC 0x01 | 67 | #define EN_GPADC 0x01 |
57 | #define DIS_GPADC 0x00 | 68 | #define DIS_GPADC 0x00 |
58 | #define SW_AVG_16 0x60 | 69 | #define AVG_1 0x00 |
70 | #define AVG_4 0x20 | ||
71 | #define AVG_8 0x40 | ||
72 | #define AVG_16 0x60 | ||
59 | #define ADC_SW_CONV 0x04 | 73 | #define ADC_SW_CONV 0x04 |
60 | #define EN_ICHAR 0x80 | 74 | #define EN_ICHAR 0x80 |
61 | #define BTEMP_PULL_UP 0x08 | 75 | #define BTEMP_PULL_UP 0x08 |
62 | #define EN_BUF 0x40 | 76 | #define EN_BUF 0x40 |
63 | #define DIS_ZERO 0x00 | 77 | #define DIS_ZERO 0x00 |
64 | #define GPADC_BUSY 0x01 | 78 | #define GPADC_BUSY 0x01 |
79 | #define EN_FALLING 0x10 | ||
80 | #define EN_TRIG_EDGE 0x02 | ||
81 | #define EN_VBIAS_XTAL_TEMP 0x02 | ||
65 | 82 | ||
66 | /* GPADC constants from AB8500 spec, UM0836 */ | 83 | /* GPADC constants from AB8500 spec, UM0836 */ |
67 | #define ADC_RESOLUTION 1024 | 84 | #define ADC_RESOLUTION 1024 |
@@ -80,8 +97,21 @@ | |||
80 | #define ADC_CH_BKBAT_MIN 0 | 97 | #define ADC_CH_BKBAT_MIN 0 |
81 | #define ADC_CH_BKBAT_MAX 3200 | 98 | #define ADC_CH_BKBAT_MAX 3200 |
82 | 99 | ||
100 | /* GPADC constants from AB8540 spec */ | ||
101 | #define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat*/ | ||
102 | #define ADC_CH_IBAT_MAX 6000 | ||
103 | #define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/ | ||
104 | #define ADC_CH_IBAT_MAX_V 60 | ||
105 | #define IBAT_VDROP_L (-56) /* mV */ | ||
106 | #define IBAT_VDROP_H 56 | ||
107 | |||
83 | /* This is used to not lose precision when dividing to get gain and offset */ | 108 | /* This is used to not lose precision when dividing to get gain and offset */ |
84 | #define CALIB_SCALE 1000 | 109 | #define CALIB_SCALE 1000 |
110 | /* | ||
111 | * Number of bits shift used to not lose precision | ||
112 | * when dividing to get ibat gain. | ||
113 | */ | ||
114 | #define CALIB_SHIFT_IBAT 20 | ||
85 | 115 | ||
86 | /* Time in ms before disabling regulator */ | 116 | /* Time in ms before disabling regulator */ |
87 | #define GPADC_AUDOSUSPEND_DELAY 1 | 117 | #define GPADC_AUDOSUSPEND_DELAY 1 |
@@ -92,6 +122,7 @@ enum cal_channels { | |||
92 | ADC_INPUT_VMAIN = 0, | 122 | ADC_INPUT_VMAIN = 0, |
93 | ADC_INPUT_BTEMP, | 123 | ADC_INPUT_BTEMP, |
94 | ADC_INPUT_VBAT, | 124 | ADC_INPUT_VBAT, |
125 | ADC_INPUT_IBAT, | ||
95 | NBR_CAL_INPUTS, | 126 | NBR_CAL_INPUTS, |
96 | }; | 127 | }; |
97 | 128 | ||
@@ -102,8 +133,10 @@ enum cal_channels { | |||
102 | * @offset: Offset of the ADC channel | 133 | * @offset: Offset of the ADC channel |
103 | */ | 134 | */ |
104 | struct adc_cal_data { | 135 | struct adc_cal_data { |
105 | u64 gain; | 136 | s64 gain; |
106 | u64 offset; | 137 | s64 offset; |
138 | u16 otp_calib_hi; | ||
139 | u16 otp_calib_lo; | ||
107 | }; | 140 | }; |
108 | 141 | ||
109 | /** | 142 | /** |
@@ -116,7 +149,10 @@ struct adc_cal_data { | |||
116 | * the completion of gpadc conversion | 149 | * the completion of gpadc conversion |
117 | * @ab8500_gpadc_lock: structure of type mutex | 150 | * @ab8500_gpadc_lock: structure of type mutex |
118 | * @regu: pointer to the struct regulator | 151 | * @regu: pointer to the struct regulator |
119 | * @irq: interrupt number that is used by gpadc | 152 | * @irq_sw: interrupt number that is used by gpadc for Sw |
153 | * conversion | ||
154 | * @irq_hw: interrupt number that is used by gpadc for Hw | ||
155 | * conversion | ||
120 | * @cal_data array of ADC calibration data structs | 156 | * @cal_data array of ADC calibration data structs |
121 | */ | 157 | */ |
122 | struct ab8500_gpadc { | 158 | struct ab8500_gpadc { |
@@ -126,7 +162,8 @@ struct ab8500_gpadc { | |||
126 | struct completion ab8500_gpadc_complete; | 162 | struct completion ab8500_gpadc_complete; |
127 | struct mutex ab8500_gpadc_lock; | 163 | struct mutex ab8500_gpadc_lock; |
128 | struct regulator *regu; | 164 | struct regulator *regu; |
129 | int irq; | 165 | int irq_sw; |
166 | int irq_hw; | ||
130 | struct adc_cal_data cal_data[NBR_CAL_INPUTS]; | 167 | struct adc_cal_data cal_data[NBR_CAL_INPUTS]; |
131 | }; | 168 | }; |
132 | 169 | ||
@@ -171,6 +208,7 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, | |||
171 | gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE; | 208 | gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE; |
172 | break; | 209 | break; |
173 | 210 | ||
211 | case XTAL_TEMP: | ||
174 | case BAT_CTRL: | 212 | case BAT_CTRL: |
175 | case BTEMP_BALL: | 213 | case BTEMP_BALL: |
176 | case ACC_DETECT1: | 214 | case ACC_DETECT1: |
@@ -189,6 +227,7 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, | |||
189 | break; | 227 | break; |
190 | 228 | ||
191 | case MAIN_BAT_V: | 229 | case MAIN_BAT_V: |
230 | case VBAT_TRUE_MEAS: | ||
192 | /* For some reason we don't have calibrated data */ | 231 | /* For some reason we don't have calibrated data */ |
193 | if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) { | 232 | if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) { |
194 | res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX - | 233 | res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX - |
@@ -232,6 +271,20 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, | |||
232 | ADC_RESOLUTION; | 271 | ADC_RESOLUTION; |
233 | break; | 272 | break; |
234 | 273 | ||
274 | case IBAT_VIRTUAL_CHANNEL: | ||
275 | /* For some reason we don't have calibrated data */ | ||
276 | if (!gpadc->cal_data[ADC_INPUT_IBAT].gain) { | ||
277 | res = ADC_CH_IBAT_MIN + (ADC_CH_IBAT_MAX - | ||
278 | ADC_CH_IBAT_MIN) * ad_value / | ||
279 | ADC_RESOLUTION; | ||
280 | break; | ||
281 | } | ||
282 | /* Here we can use the calibrated data */ | ||
283 | res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_IBAT].gain + | ||
284 | gpadc->cal_data[ADC_INPUT_IBAT].offset) | ||
285 | >> CALIB_SHIFT_IBAT; | ||
286 | break; | ||
287 | |||
235 | default: | 288 | default: |
236 | dev_err(gpadc->dev, | 289 | dev_err(gpadc->dev, |
237 | "unknown channel, not possible to convert\n"); | 290 | "unknown channel, not possible to convert\n"); |
@@ -244,25 +297,35 @@ int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel, | |||
244 | EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage); | 297 | EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage); |
245 | 298 | ||
246 | /** | 299 | /** |
247 | * ab8500_gpadc_convert() - gpadc conversion | 300 | * ab8500_gpadc_sw_hw_convert() - gpadc conversion |
248 | * @channel: analog channel to be converted to digital data | 301 | * @channel: analog channel to be converted to digital data |
302 | * @avg_sample: number of ADC sample to average | ||
303 | * @trig_egde: selected ADC trig edge | ||
304 | * @trig_timer: selected ADC trigger delay timer | ||
305 | * @conv_type: selected conversion type (HW or SW conversion) | ||
249 | * | 306 | * |
250 | * This function converts the selected analog i/p to digital | 307 | * This function converts the selected analog i/p to digital |
251 | * data. | 308 | * data. |
252 | */ | 309 | */ |
253 | int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel) | 310 | int ab8500_gpadc_sw_hw_convert(struct ab8500_gpadc *gpadc, u8 channel, |
311 | u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type) | ||
254 | { | 312 | { |
255 | int ad_value; | 313 | int ad_value; |
256 | int voltage; | 314 | int voltage; |
257 | 315 | ||
258 | ad_value = ab8500_gpadc_read_raw(gpadc, channel); | 316 | ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample, |
259 | if (ad_value < 0) { | 317 | trig_edge, trig_timer, conv_type); |
260 | dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel); | 318 | /* On failure retry a second time */ |
319 | if (ad_value < 0) | ||
320 | ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample, | ||
321 | trig_edge, trig_timer, conv_type); | ||
322 | if (ad_value < 0) { | ||
323 | dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", | ||
324 | channel); | ||
261 | return ad_value; | 325 | return ad_value; |
262 | } | 326 | } |
263 | 327 | ||
264 | voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value); | 328 | voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value); |
265 | |||
266 | if (voltage < 0) | 329 | if (voltage < 0) |
267 | dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:" | 330 | dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:" |
268 | " %d AD: 0x%x\n", channel, ad_value); | 331 | " %d AD: 0x%x\n", channel, ad_value); |
@@ -274,21 +337,46 @@ EXPORT_SYMBOL(ab8500_gpadc_convert); | |||
274 | /** | 337 | /** |
275 | * ab8500_gpadc_read_raw() - gpadc read | 338 | * ab8500_gpadc_read_raw() - gpadc read |
276 | * @channel: analog channel to be read | 339 | * @channel: analog channel to be read |
340 | * @avg_sample: number of ADC sample to average | ||
341 | * @trig_edge: selected trig edge | ||
342 | * @trig_timer: selected ADC trigger delay timer | ||
343 | * @conv_type: selected conversion type (HW or SW conversion) | ||
277 | * | 344 | * |
278 | * This function obtains the raw ADC value, this then needs | 345 | * This function obtains the raw ADC value for an hardware conversion, |
279 | * to be converted by calling ab8500_gpadc_ad_to_voltage() | 346 | * this then needs to be converted by calling ab8500_gpadc_ad_to_voltage() |
280 | */ | 347 | */ |
281 | int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) | 348 | int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, |
349 | u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type) | ||
350 | { | ||
351 | int raw_data; | ||
352 | raw_data = ab8500_gpadc_double_read_raw(gpadc, channel, | ||
353 | avg_sample, trig_edge, trig_timer, conv_type, NULL); | ||
354 | return raw_data; | ||
355 | } | ||
356 | |||
357 | int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, | ||
358 | u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type, | ||
359 | int *ibat) | ||
282 | { | 360 | { |
283 | int ret; | 361 | int ret; |
284 | int looplimit = 0; | 362 | int looplimit = 0; |
285 | u8 val, low_data, high_data; | 363 | unsigned long completion_timeout; |
364 | u8 val, low_data, high_data, low_data2, high_data2; | ||
365 | u8 val_reg1 = 0; | ||
366 | unsigned int delay_min = 0; | ||
367 | unsigned int delay_max = 0; | ||
368 | u8 data_low_addr, data_high_addr; | ||
286 | 369 | ||
287 | if (!gpadc) | 370 | if (!gpadc) |
288 | return -ENODEV; | 371 | return -ENODEV; |
289 | 372 | ||
290 | mutex_lock(&gpadc->ab8500_gpadc_lock); | 373 | /* check if convertion is supported */ |
374 | if ((gpadc->irq_sw < 0) && (conv_type == ADC_SW)) | ||
375 | return -ENOTSUPP; | ||
376 | if ((gpadc->irq_hw < 0) && (conv_type == ADC_HW)) | ||
377 | return -ENOTSUPP; | ||
291 | 378 | ||
379 | mutex_lock(&gpadc->ab8500_gpadc_lock); | ||
292 | /* Enable VTVout LDO this is required for GPADC */ | 380 | /* Enable VTVout LDO this is required for GPADC */ |
293 | pm_runtime_get_sync(gpadc->dev); | 381 | pm_runtime_get_sync(gpadc->dev); |
294 | 382 | ||
@@ -309,16 +397,34 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) | |||
309 | } | 397 | } |
310 | 398 | ||
311 | /* Enable GPADC */ | 399 | /* Enable GPADC */ |
312 | ret = abx500_mask_and_set_register_interruptible(gpadc->dev, | 400 | val_reg1 |= EN_GPADC; |
313 | AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC); | 401 | |
314 | if (ret < 0) { | 402 | /* Select the channel source and set average samples */ |
315 | dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n"); | 403 | switch (avg_sample) { |
316 | goto out; | 404 | case SAMPLE_1: |
405 | val = channel | AVG_1; | ||
406 | break; | ||
407 | case SAMPLE_4: | ||
408 | val = channel | AVG_4; | ||
409 | break; | ||
410 | case SAMPLE_8: | ||
411 | val = channel | AVG_8; | ||
412 | break; | ||
413 | default: | ||
414 | val = channel | AVG_16; | ||
415 | break; | ||
317 | } | 416 | } |
318 | 417 | ||
319 | /* Select the channel source and set average samples to 16 */ | 418 | if (conv_type == ADC_HW) { |
320 | ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, | 419 | ret = abx500_set_register_interruptible(gpadc->dev, |
321 | AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16)); | 420 | AB8500_GPADC, AB8500_GPADC_CTRL3_REG, val); |
421 | val_reg1 |= EN_TRIG_EDGE; | ||
422 | if (trig_edge) | ||
423 | val_reg1 |= EN_FALLING; | ||
424 | } | ||
425 | else | ||
426 | ret = abx500_set_register_interruptible(gpadc->dev, | ||
427 | AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val); | ||
322 | if (ret < 0) { | 428 | if (ret < 0) { |
323 | dev_err(gpadc->dev, | 429 | dev_err(gpadc->dev, |
324 | "gpadc_conversion: set avg samples failed\n"); | 430 | "gpadc_conversion: set avg samples failed\n"); |
@@ -333,71 +439,129 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) | |||
333 | switch (channel) { | 439 | switch (channel) { |
334 | case MAIN_CHARGER_C: | 440 | case MAIN_CHARGER_C: |
335 | case USB_CHARGER_C: | 441 | case USB_CHARGER_C: |
336 | ret = abx500_mask_and_set_register_interruptible(gpadc->dev, | 442 | val_reg1 |= EN_BUF | EN_ICHAR; |
337 | AB8500_GPADC, AB8500_GPADC_CTRL1_REG, | ||
338 | EN_BUF | EN_ICHAR, | ||
339 | EN_BUF | EN_ICHAR); | ||
340 | break; | 443 | break; |
341 | case BTEMP_BALL: | 444 | case BTEMP_BALL: |
342 | if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { | 445 | if (!is_ab8500_2p0_or_earlier(gpadc->parent)) { |
343 | /* Turn on btemp pull-up on ABB 3.0 */ | 446 | val_reg1 |= EN_BUF | BTEMP_PULL_UP; |
344 | ret = abx500_mask_and_set_register_interruptible( | 447 | /* |
345 | gpadc->dev, | 448 | * Delay might be needed for ABB8500 cut 3.0, if not, |
346 | AB8500_GPADC, AB8500_GPADC_CTRL1_REG, | 449 | * remove when hardware will be availible |
347 | EN_BUF | BTEMP_PULL_UP, | 450 | */ |
348 | EN_BUF | BTEMP_PULL_UP); | 451 | delay_min = 1000; /* Delay in micro seconds */ |
349 | 452 | delay_max = 10000; /* large range to optimise sleep mode */ | |
350 | /* | ||
351 | * Delay might be needed for ABB8500 cut 3.0, if not, remove | ||
352 | * when hardware will be available | ||
353 | */ | ||
354 | usleep_range(1000, 1000); | ||
355 | break; | 453 | break; |
356 | } | 454 | } |
357 | /* Intentional fallthrough */ | 455 | /* Intentional fallthrough */ |
358 | default: | 456 | default: |
359 | ret = abx500_mask_and_set_register_interruptible(gpadc->dev, | 457 | val_reg1 |= EN_BUF; |
360 | AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF); | ||
361 | break; | 458 | break; |
362 | } | 459 | } |
460 | |||
461 | /* Write configuration to register */ | ||
462 | ret = abx500_set_register_interruptible(gpadc->dev, | ||
463 | AB8500_GPADC, AB8500_GPADC_CTRL1_REG, val_reg1); | ||
363 | if (ret < 0) { | 464 | if (ret < 0) { |
364 | dev_err(gpadc->dev, | 465 | dev_err(gpadc->dev, |
365 | "gpadc_conversion: select falling edge failed\n"); | 466 | "gpadc_conversion: set Control register failed\n"); |
366 | goto out; | 467 | goto out; |
367 | } | 468 | } |
368 | 469 | ||
369 | ret = abx500_mask_and_set_register_interruptible(gpadc->dev, | 470 | if (delay_min != 0) |
370 | AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV); | 471 | usleep_range(delay_min, delay_max); |
371 | if (ret < 0) { | 472 | |
372 | dev_err(gpadc->dev, | 473 | if (conv_type == ADC_HW) { |
373 | "gpadc_conversion: start s/w conversion failed\n"); | 474 | /* Set trigger delay timer */ |
374 | goto out; | 475 | ret = abx500_set_register_interruptible(gpadc->dev, |
476 | AB8500_GPADC, AB8500_GPADC_AUTO_TIMER_REG, trig_timer); | ||
477 | if (ret < 0) { | ||
478 | dev_err(gpadc->dev, | ||
479 | "gpadc_conversion: trig timer failed\n"); | ||
480 | goto out; | ||
481 | } | ||
482 | completion_timeout = 2 * HZ; | ||
483 | data_low_addr = AB8500_GPADC_AUTODATAL_REG; | ||
484 | data_high_addr = AB8500_GPADC_AUTODATAH_REG; | ||
485 | } else { | ||
486 | /* Start SW conversion */ | ||
487 | ret = abx500_mask_and_set_register_interruptible(gpadc->dev, | ||
488 | AB8500_GPADC, AB8500_GPADC_CTRL1_REG, | ||
489 | ADC_SW_CONV, ADC_SW_CONV); | ||
490 | if (ret < 0) { | ||
491 | dev_err(gpadc->dev, | ||
492 | "gpadc_conversion: start s/w conv failed\n"); | ||
493 | goto out; | ||
494 | } | ||
495 | completion_timeout = msecs_to_jiffies(CONVERSION_TIME); | ||
496 | data_low_addr = AB8500_GPADC_MANDATAL_REG; | ||
497 | data_high_addr = AB8500_GPADC_MANDATAH_REG; | ||
375 | } | 498 | } |
499 | |||
376 | /* wait for completion of conversion */ | 500 | /* wait for completion of conversion */ |
377 | if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, | 501 | if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, |
378 | msecs_to_jiffies(CONVERSION_TIME))) { | 502 | completion_timeout)) { |
379 | dev_err(gpadc->dev, | 503 | dev_err(gpadc->dev, |
380 | "timeout: didn't receive GPADC conversion interrupt\n"); | 504 | "timeout didn't receive GPADC conv interrupt\n"); |
381 | ret = -EINVAL; | 505 | ret = -EINVAL; |
382 | goto out; | 506 | goto out; |
383 | } | 507 | } |
384 | 508 | ||
385 | /* Read the converted RAW data */ | 509 | /* Read the converted RAW data */ |
386 | ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC, | 510 | ret = abx500_get_register_interruptible(gpadc->dev, |
387 | AB8500_GPADC_MANDATAL_REG, &low_data); | 511 | AB8500_GPADC, data_low_addr, &low_data); |
388 | if (ret < 0) { | 512 | if (ret < 0) { |
389 | dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n"); | 513 | dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n"); |
390 | goto out; | 514 | goto out; |
391 | } | 515 | } |
392 | 516 | ||
393 | ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC, | 517 | ret = abx500_get_register_interruptible(gpadc->dev, |
394 | AB8500_GPADC_MANDATAH_REG, &high_data); | 518 | AB8500_GPADC, data_high_addr, &high_data); |
395 | if (ret < 0) { | 519 | if (ret < 0) { |
396 | dev_err(gpadc->dev, | 520 | dev_err(gpadc->dev, "gpadc_conversion: read high data failed\n"); |
397 | "gpadc_conversion: read high data failed\n"); | ||
398 | goto out; | 521 | goto out; |
399 | } | 522 | } |
400 | 523 | ||
524 | /* Check if double convertion is required */ | ||
525 | if ((channel == BAT_CTRL_AND_IBAT) || | ||
526 | (channel == VBAT_MEAS_AND_IBAT) || | ||
527 | (channel == VBAT_TRUE_MEAS_AND_IBAT) || | ||
528 | (channel == BAT_TEMP_AND_IBAT)) { | ||
529 | |||
530 | if (conv_type == ADC_HW) { | ||
531 | /* not supported */ | ||
532 | ret = -ENOTSUPP; | ||
533 | dev_err(gpadc->dev, | ||
534 | "gpadc_conversion: only SW double conversion supported\n"); | ||
535 | goto out; | ||
536 | } else { | ||
537 | /* Read the converted RAW data 2 */ | ||
538 | ret = abx500_get_register_interruptible(gpadc->dev, | ||
539 | AB8500_GPADC, AB8540_GPADC_MANDATA2L_REG, | ||
540 | &low_data2); | ||
541 | if (ret < 0) { | ||
542 | dev_err(gpadc->dev, | ||
543 | "gpadc_conversion: read sw low data 2 failed\n"); | ||
544 | goto out; | ||
545 | } | ||
546 | |||
547 | ret = abx500_get_register_interruptible(gpadc->dev, | ||
548 | AB8500_GPADC, AB8540_GPADC_MANDATA2H_REG, | ||
549 | &high_data2); | ||
550 | if (ret < 0) { | ||
551 | dev_err(gpadc->dev, | ||
552 | "gpadc_conversion: read sw high data 2 failed\n"); | ||
553 | goto out; | ||
554 | } | ||
555 | if (ibat != NULL) { | ||
556 | *ibat = (high_data2 << 8) | low_data2; | ||
557 | } else { | ||
558 | dev_warn(gpadc->dev, | ||
559 | "gpadc_conversion: ibat not stored\n"); | ||
560 | } | ||
561 | |||
562 | } | ||
563 | } | ||
564 | |||
401 | /* Disable GPADC */ | 565 | /* Disable GPADC */ |
402 | ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, | 566 | ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, |
403 | AB8500_GPADC_CTRL1_REG, DIS_GPADC); | 567 | AB8500_GPADC_CTRL1_REG, DIS_GPADC); |
@@ -406,6 +570,7 @@ int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel) | |||
406 | goto out; | 570 | goto out; |
407 | } | 571 | } |
408 | 572 | ||
573 | /* Disable VTVout LDO this is required for GPADC */ | ||
409 | pm_runtime_mark_last_busy(gpadc->dev); | 574 | pm_runtime_mark_last_busy(gpadc->dev); |
410 | pm_runtime_put_autosuspend(gpadc->dev); | 575 | pm_runtime_put_autosuspend(gpadc->dev); |
411 | 576 | ||
@@ -422,9 +587,7 @@ out: | |||
422 | */ | 587 | */ |
423 | (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, | 588 | (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, |
424 | AB8500_GPADC_CTRL1_REG, DIS_GPADC); | 589 | AB8500_GPADC_CTRL1_REG, DIS_GPADC); |
425 | |||
426 | pm_runtime_put(gpadc->dev); | 590 | pm_runtime_put(gpadc->dev); |
427 | |||
428 | mutex_unlock(&gpadc->ab8500_gpadc_lock); | 591 | mutex_unlock(&gpadc->ab8500_gpadc_lock); |
429 | dev_err(gpadc->dev, | 592 | dev_err(gpadc->dev, |
430 | "gpadc_conversion: Failed to AD convert channel %d\n", channel); | 593 | "gpadc_conversion: Failed to AD convert channel %d\n", channel); |
@@ -433,16 +596,16 @@ out: | |||
433 | EXPORT_SYMBOL(ab8500_gpadc_read_raw); | 596 | EXPORT_SYMBOL(ab8500_gpadc_read_raw); |
434 | 597 | ||
435 | /** | 598 | /** |
436 | * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion | 599 | * ab8500_bm_gpadcconvend_handler() - isr for gpadc conversion completion |
437 | * @irq: irq number | 600 | * @irq: irq number |
438 | * @data: pointer to the data passed during request irq | 601 | * @data: pointer to the data passed during request irq |
439 | * | 602 | * |
440 | * This is a interrupt service routine for s/w gpadc conversion completion. | 603 | * This is a interrupt service routine for gpadc conversion completion. |
441 | * Notifies the gpadc completion is completed and the converted raw value | 604 | * Notifies the gpadc completion is completed and the converted raw value |
442 | * can be read from the registers. | 605 | * can be read from the registers. |
443 | * Returns IRQ status(IRQ_HANDLED) | 606 | * Returns IRQ status(IRQ_HANDLED) |
444 | */ | 607 | */ |
445 | static irqreturn_t ab8500_bm_gpswadcconvend_handler(int irq, void *_gpadc) | 608 | static irqreturn_t ab8500_bm_gpadcconvend_handler(int irq, void *_gpadc) |
446 | { | 609 | { |
447 | struct ab8500_gpadc *gpadc = _gpadc; | 610 | struct ab8500_gpadc *gpadc = _gpadc; |
448 | 611 | ||
@@ -461,15 +624,27 @@ static int otp_cal_regs[] = { | |||
461 | AB8500_GPADC_CAL_7, | 624 | AB8500_GPADC_CAL_7, |
462 | }; | 625 | }; |
463 | 626 | ||
627 | static int otp4_cal_regs[] = { | ||
628 | AB8540_GPADC_OTP4_REG_7, | ||
629 | AB8540_GPADC_OTP4_REG_6, | ||
630 | AB8540_GPADC_OTP4_REG_5, | ||
631 | }; | ||
632 | |||
464 | static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) | 633 | static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) |
465 | { | 634 | { |
466 | int i; | 635 | int i; |
467 | int ret[ARRAY_SIZE(otp_cal_regs)]; | 636 | int ret[ARRAY_SIZE(otp_cal_regs)]; |
468 | u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)]; | 637 | u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)]; |
469 | 638 | int ret_otp4[ARRAY_SIZE(otp4_cal_regs)]; | |
639 | u8 gpadc_otp4[ARRAY_SIZE(otp4_cal_regs)]; | ||
470 | int vmain_high, vmain_low; | 640 | int vmain_high, vmain_low; |
471 | int btemp_high, btemp_low; | 641 | int btemp_high, btemp_low; |
472 | int vbat_high, vbat_low; | 642 | int vbat_high, vbat_low; |
643 | int ibat_high, ibat_low; | ||
644 | s64 V_gain, V_offset, V2A_gain, V2A_offset; | ||
645 | struct ab8500 *ab8500; | ||
646 | |||
647 | ab8500 = gpadc->parent; | ||
473 | 648 | ||
474 | /* First we read all OTP registers and store the error code */ | 649 | /* First we read all OTP registers and store the error code */ |
475 | for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) { | 650 | for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) { |
@@ -489,7 +664,7 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) | |||
489 | * bt_h/l = btemp_high/low | 664 | * bt_h/l = btemp_high/low |
490 | * vb_h/l = vbat_high/low | 665 | * vb_h/l = vbat_high/low |
491 | * | 666 | * |
492 | * Data bits: | 667 | * Data bits 8500/9540: |
493 | * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 668 | * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
494 | * |.......|.......|.......|.......|.......|.......|.......|....... | 669 | * |.......|.......|.......|.......|.......|.......|.......|....... |
495 | * | | vm_h9 | vm_h8 | 670 | * | | vm_h9 | vm_h8 |
@@ -507,6 +682,35 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) | |||
507 | * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 | | 682 | * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 | |
508 | * |.......|.......|.......|.......|.......|.......|.......|....... | 683 | * |.......|.......|.......|.......|.......|.......|.......|....... |
509 | * | 684 | * |
685 | * Data bits 8540: | ||
686 | * OTP2 | ||
687 | * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
688 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
689 | * | | ||
690 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
691 | * | vm_h9 | vm_h8 | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2 | ||
692 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
693 | * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9 | ||
694 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
695 | * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1 | ||
696 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
697 | * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8 | ||
698 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
699 | * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0 | ||
700 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
701 | * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 | | ||
702 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
703 | * | ||
704 | * Data bits 8540: | ||
705 | * OTP4 | ||
706 | * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
707 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
708 | * | | ib_h9 | ib_h8 | ib_h7 | ||
709 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
710 | * | ib_h6 | ib_h5 | ib_h4 | ib_h3 | ib_h2 | ib_h1 | ib_h0 | ib_l5 | ||
711 | * |.......|.......|.......|.......|.......|.......|.......|....... | ||
712 | * | ib_l4 | ib_l3 | ib_l2 | ib_l1 | ib_l0 | | ||
713 | * | ||
510 | * | 714 | * |
511 | * Ideal output ADC codes corresponding to injected input voltages | 715 | * Ideal output ADC codes corresponding to injected input voltages |
512 | * during manufacturing is: | 716 | * during manufacturing is: |
@@ -519,38 +723,116 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) | |||
519 | * vbat_low: Vin = 2380mV / ADC ideal code = 33 | 723 | * vbat_low: Vin = 2380mV / ADC ideal code = 33 |
520 | */ | 724 | */ |
521 | 725 | ||
522 | /* Calculate gain and offset for VMAIN if all reads succeeded */ | 726 | if (is_ab8540(ab8500)) { |
523 | if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) { | 727 | /* Calculate gain and offset for VMAIN if all reads succeeded*/ |
524 | vmain_high = (((gpadc_cal[0] & 0x03) << 8) | | 728 | if (!(ret[1] < 0 || ret[2] < 0)) { |
525 | ((gpadc_cal[1] & 0x3F) << 2) | | 729 | vmain_high = (((gpadc_cal[1] & 0xFF) << 2) | |
526 | ((gpadc_cal[2] & 0xC0) >> 6)); | 730 | ((gpadc_cal[2] & 0xC0) >> 6)); |
731 | vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); | ||
732 | |||
733 | gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi = | ||
734 | (u16)vmain_high; | ||
735 | gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo = | ||
736 | (u16)vmain_low; | ||
737 | |||
738 | gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * | ||
739 | (19500 - 315) / (vmain_high - vmain_low); | ||
740 | gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * | ||
741 | 19500 - (CALIB_SCALE * (19500 - 315) / | ||
742 | (vmain_high - vmain_low)) * vmain_high; | ||
743 | } else { | ||
744 | gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; | ||
745 | } | ||
527 | 746 | ||
528 | vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); | 747 | /* Read IBAT calibration Data */ |
748 | for (i = 0; i < ARRAY_SIZE(otp4_cal_regs); i++) { | ||
749 | ret_otp4[i] = abx500_get_register_interruptible( | ||
750 | gpadc->dev, AB8500_OTP_EMUL, | ||
751 | otp4_cal_regs[i], &gpadc_otp4[i]); | ||
752 | if (ret_otp4[i] < 0) | ||
753 | dev_err(gpadc->dev, | ||
754 | "%s: read otp4 reg 0x%02x failed\n", | ||
755 | __func__, otp4_cal_regs[i]); | ||
756 | } | ||
529 | 757 | ||
530 | gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * | 758 | /* Calculate gain and offset for IBAT if all reads succeeded */ |
531 | (19500 - 315) / (vmain_high - vmain_low); | 759 | if (!(ret_otp4[0] < 0 || ret_otp4[1] < 0 || ret_otp4[2] < 0)) { |
760 | ibat_high = (((gpadc_otp4[0] & 0x07) << 7) | | ||
761 | ((gpadc_otp4[1] & 0xFE) >> 1)); | ||
762 | ibat_low = (((gpadc_otp4[1] & 0x01) << 5) | | ||
763 | ((gpadc_otp4[2] & 0xF8) >> 3)); | ||
764 | |||
765 | gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi = | ||
766 | (u16)ibat_high; | ||
767 | gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo = | ||
768 | (u16)ibat_low; | ||
769 | |||
770 | V_gain = ((IBAT_VDROP_H - IBAT_VDROP_L) | ||
771 | << CALIB_SHIFT_IBAT) / (ibat_high - ibat_low); | ||
772 | |||
773 | V_offset = (IBAT_VDROP_H << CALIB_SHIFT_IBAT) - | ||
774 | (((IBAT_VDROP_H - IBAT_VDROP_L) << | ||
775 | CALIB_SHIFT_IBAT) / (ibat_high - ibat_low)) | ||
776 | * ibat_high; | ||
777 | /* | ||
778 | * Result obtained is in mV (at a scale factor), | ||
779 | * we need to calculate gain and offset to get mA | ||
780 | */ | ||
781 | V2A_gain = (ADC_CH_IBAT_MAX - ADC_CH_IBAT_MIN)/ | ||
782 | (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V); | ||
783 | V2A_offset = ((ADC_CH_IBAT_MAX_V * ADC_CH_IBAT_MIN - | ||
784 | ADC_CH_IBAT_MAX * ADC_CH_IBAT_MIN_V) | ||
785 | << CALIB_SHIFT_IBAT) | ||
786 | / (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V); | ||
787 | |||
788 | gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain; | ||
789 | gpadc->cal_data[ADC_INPUT_IBAT].offset = V_offset * | ||
790 | V2A_gain + V2A_offset; | ||
791 | } else { | ||
792 | gpadc->cal_data[ADC_INPUT_IBAT].gain = 0; | ||
793 | } | ||
532 | 794 | ||
533 | gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * 19500 - | 795 | dev_dbg(gpadc->dev, "IBAT gain %llu offset %llu\n", |
534 | (CALIB_SCALE * (19500 - 315) / | 796 | gpadc->cal_data[ADC_INPUT_IBAT].gain, |
535 | (vmain_high - vmain_low)) * vmain_high; | 797 | gpadc->cal_data[ADC_INPUT_IBAT].offset); |
536 | } else { | 798 | } else { |
537 | gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; | 799 | /* Calculate gain and offset for VMAIN if all reads succeeded */ |
800 | if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) { | ||
801 | vmain_high = (((gpadc_cal[0] & 0x03) << 8) | | ||
802 | ((gpadc_cal[1] & 0x3F) << 2) | | ||
803 | ((gpadc_cal[2] & 0xC0) >> 6)); | ||
804 | vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); | ||
805 | |||
806 | gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi = | ||
807 | (u16)vmain_high; | ||
808 | gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo = | ||
809 | (u16)vmain_low; | ||
810 | |||
811 | gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * | ||
812 | (19500 - 315) / (vmain_high - vmain_low); | ||
813 | |||
814 | gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * | ||
815 | 19500 - (CALIB_SCALE * (19500 - 315) / | ||
816 | (vmain_high - vmain_low)) * vmain_high; | ||
817 | } else { | ||
818 | gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; | ||
819 | } | ||
538 | } | 820 | } |
539 | 821 | ||
540 | /* Calculate gain and offset for BTEMP if all reads succeeded */ | 822 | /* Calculate gain and offset for BTEMP if all reads succeeded */ |
541 | if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) { | 823 | if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) { |
542 | btemp_high = (((gpadc_cal[2] & 0x01) << 9) | | 824 | btemp_high = (((gpadc_cal[2] & 0x01) << 9) | |
543 | (gpadc_cal[3] << 1) | | 825 | (gpadc_cal[3] << 1) | ((gpadc_cal[4] & 0x80) >> 7)); |
544 | ((gpadc_cal[4] & 0x80) >> 7)); | ||
545 | |||
546 | btemp_low = ((gpadc_cal[4] & 0x7C) >> 2); | 826 | btemp_low = ((gpadc_cal[4] & 0x7C) >> 2); |
547 | 827 | ||
828 | gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi = (u16)btemp_high; | ||
829 | gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo = (u16)btemp_low; | ||
830 | |||
548 | gpadc->cal_data[ADC_INPUT_BTEMP].gain = | 831 | gpadc->cal_data[ADC_INPUT_BTEMP].gain = |
549 | CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); | 832 | CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); |
550 | |||
551 | gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 - | 833 | gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 - |
552 | (CALIB_SCALE * (1300 - 21) / | 834 | (CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low)) |
553 | (btemp_high - btemp_low)) * btemp_high; | 835 | * btemp_high; |
554 | } else { | 836 | } else { |
555 | gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0; | 837 | gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0; |
556 | } | 838 | } |
@@ -560,9 +842,11 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc) | |||
560 | vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]); | 842 | vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]); |
561 | vbat_low = ((gpadc_cal[6] & 0xFC) >> 2); | 843 | vbat_low = ((gpadc_cal[6] & 0xFC) >> 2); |
562 | 844 | ||
845 | gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi = (u16)vbat_high; | ||
846 | gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo = (u16)vbat_low; | ||
847 | |||
563 | gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE * | 848 | gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE * |
564 | (4700 - 2380) / (vbat_high - vbat_low); | 849 | (4700 - 2380) / (vbat_high - vbat_low); |
565 | |||
566 | gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 - | 850 | gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 - |
567 | (CALIB_SCALE * (4700 - 2380) / | 851 | (CALIB_SCALE * (4700 - 2380) / |
568 | (vbat_high - vbat_low)) * vbat_high; | 852 | (vbat_high - vbat_low)) * vbat_high; |
@@ -608,6 +892,31 @@ static int ab8500_gpadc_runtime_idle(struct device *dev) | |||
608 | return 0; | 892 | return 0; |
609 | } | 893 | } |
610 | 894 | ||
895 | static int ab8500_gpadc_suspend(struct device *dev) | ||
896 | { | ||
897 | struct ab8500_gpadc *gpadc = dev_get_drvdata(dev); | ||
898 | |||
899 | mutex_lock(&gpadc->ab8500_gpadc_lock); | ||
900 | |||
901 | pm_runtime_get_sync(dev); | ||
902 | |||
903 | regulator_disable(gpadc->regu); | ||
904 | return 0; | ||
905 | } | ||
906 | |||
907 | static int ab8500_gpadc_resume(struct device *dev) | ||
908 | { | ||
909 | struct ab8500_gpadc *gpadc = dev_get_drvdata(dev); | ||
910 | |||
911 | regulator_enable(gpadc->regu); | ||
912 | |||
913 | pm_runtime_mark_last_busy(gpadc->dev); | ||
914 | pm_runtime_put_autosuspend(gpadc->dev); | ||
915 | |||
916 | mutex_unlock(&gpadc->ab8500_gpadc_lock); | ||
917 | return 0; | ||
918 | } | ||
919 | |||
611 | static int ab8500_gpadc_probe(struct platform_device *pdev) | 920 | static int ab8500_gpadc_probe(struct platform_device *pdev) |
612 | { | 921 | { |
613 | int ret = 0; | 922 | int ret = 0; |
@@ -619,13 +928,13 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) | |||
619 | return -ENOMEM; | 928 | return -ENOMEM; |
620 | } | 929 | } |
621 | 930 | ||
622 | gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END"); | 931 | gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END"); |
623 | if (gpadc->irq < 0) { | 932 | if (gpadc->irq_sw < 0) |
624 | dev_err(&pdev->dev, "failed to get platform irq-%d\n", | 933 | dev_err(gpadc->dev, "failed to get platform sw_conv_end irq\n"); |
625 | gpadc->irq); | 934 | |
626 | ret = gpadc->irq; | 935 | gpadc->irq_hw = platform_get_irq_byname(pdev, "HW_CONV_END"); |
627 | goto fail; | 936 | if (gpadc->irq_hw < 0) |
628 | } | 937 | dev_err(gpadc->dev, "failed to get platform hw_conv_end irq\n"); |
629 | 938 | ||
630 | gpadc->dev = &pdev->dev; | 939 | gpadc->dev = &pdev->dev; |
631 | gpadc->parent = dev_get_drvdata(pdev->dev.parent); | 940 | gpadc->parent = dev_get_drvdata(pdev->dev.parent); |
@@ -634,15 +943,31 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) | |||
634 | /* Initialize completion used to notify completion of conversion */ | 943 | /* Initialize completion used to notify completion of conversion */ |
635 | init_completion(&gpadc->ab8500_gpadc_complete); | 944 | init_completion(&gpadc->ab8500_gpadc_complete); |
636 | 945 | ||
637 | /* Register interrupt - SwAdcComplete */ | 946 | /* Register interrupts */ |
638 | ret = request_threaded_irq(gpadc->irq, NULL, | 947 | if (gpadc->irq_sw >= 0) { |
639 | ab8500_bm_gpswadcconvend_handler, | 948 | ret = request_threaded_irq(gpadc->irq_sw, NULL, |
640 | IRQF_ONESHOT | IRQF_NO_SUSPEND | IRQF_SHARED, | 949 | ab8500_bm_gpadcconvend_handler, |
641 | "ab8500-gpadc", gpadc); | 950 | IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw", |
642 | if (ret < 0) { | 951 | gpadc); |
643 | dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n", | 952 | if (ret < 0) { |
644 | gpadc->irq); | 953 | dev_err(gpadc->dev, |
645 | goto fail; | 954 | "Failed to register interrupt irq: %d\n", |
955 | gpadc->irq_sw); | ||
956 | goto fail; | ||
957 | } | ||
958 | } | ||
959 | |||
960 | if (gpadc->irq_hw >= 0) { | ||
961 | ret = request_threaded_irq(gpadc->irq_hw, NULL, | ||
962 | ab8500_bm_gpadcconvend_handler, | ||
963 | IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw", | ||
964 | gpadc); | ||
965 | if (ret < 0) { | ||
966 | dev_err(gpadc->dev, | ||
967 | "Failed to register interrupt irq: %d\n", | ||
968 | gpadc->irq_hw); | ||
969 | goto fail_irq; | ||
970 | } | ||
646 | } | 971 | } |
647 | 972 | ||
648 | /* VTVout LDO used to power up ab8500-GPADC */ | 973 | /* VTVout LDO used to power up ab8500-GPADC */ |
@@ -669,11 +994,13 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) | |||
669 | ab8500_gpadc_read_calibration_data(gpadc); | 994 | ab8500_gpadc_read_calibration_data(gpadc); |
670 | list_add_tail(&gpadc->node, &ab8500_gpadc_list); | 995 | list_add_tail(&gpadc->node, &ab8500_gpadc_list); |
671 | dev_dbg(gpadc->dev, "probe success\n"); | 996 | dev_dbg(gpadc->dev, "probe success\n"); |
997 | |||
672 | return 0; | 998 | return 0; |
673 | 999 | ||
674 | fail_enable: | 1000 | fail_enable: |
675 | fail_irq: | 1001 | fail_irq: |
676 | free_irq(gpadc->irq, gpadc); | 1002 | free_irq(gpadc->irq_sw, gpadc); |
1003 | free_irq(gpadc->irq_hw, gpadc); | ||
677 | fail: | 1004 | fail: |
678 | kfree(gpadc); | 1005 | kfree(gpadc); |
679 | gpadc = NULL; | 1006 | gpadc = NULL; |
@@ -687,7 +1014,10 @@ static int ab8500_gpadc_remove(struct platform_device *pdev) | |||
687 | /* remove this gpadc entry from the list */ | 1014 | /* remove this gpadc entry from the list */ |
688 | list_del(&gpadc->node); | 1015 | list_del(&gpadc->node); |
689 | /* remove interrupt - completion of Sw ADC conversion */ | 1016 | /* remove interrupt - completion of Sw ADC conversion */ |
690 | free_irq(gpadc->irq, gpadc); | 1017 | if (gpadc->irq_sw >= 0) |
1018 | free_irq(gpadc->irq_sw, gpadc); | ||
1019 | if (gpadc->irq_hw >= 0) | ||
1020 | free_irq(gpadc->irq_hw, gpadc); | ||
691 | 1021 | ||
692 | pm_runtime_get_sync(gpadc->dev); | 1022 | pm_runtime_get_sync(gpadc->dev); |
693 | pm_runtime_disable(gpadc->dev); | 1023 | pm_runtime_disable(gpadc->dev); |
@@ -707,6 +1037,9 @@ static const struct dev_pm_ops ab8500_gpadc_pm_ops = { | |||
707 | SET_RUNTIME_PM_OPS(ab8500_gpadc_runtime_suspend, | 1037 | SET_RUNTIME_PM_OPS(ab8500_gpadc_runtime_suspend, |
708 | ab8500_gpadc_runtime_resume, | 1038 | ab8500_gpadc_runtime_resume, |
709 | ab8500_gpadc_runtime_idle) | 1039 | ab8500_gpadc_runtime_idle) |
1040 | SET_SYSTEM_SLEEP_PM_OPS(ab8500_gpadc_suspend, | ||
1041 | ab8500_gpadc_resume) | ||
1042 | |||
710 | }; | 1043 | }; |
711 | 1044 | ||
712 | static struct platform_driver ab8500_gpadc_driver = { | 1045 | static struct platform_driver ab8500_gpadc_driver = { |
@@ -729,10 +1062,30 @@ static void __exit ab8500_gpadc_exit(void) | |||
729 | platform_driver_unregister(&ab8500_gpadc_driver); | 1062 | platform_driver_unregister(&ab8500_gpadc_driver); |
730 | } | 1063 | } |
731 | 1064 | ||
1065 | /** | ||
1066 | * ab8540_gpadc_get_otp() - returns OTP values | ||
1067 | * | ||
1068 | */ | ||
1069 | void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc, | ||
1070 | u16 *vmain_l, u16 *vmain_h, u16 *btemp_l, u16 *btemp_h, | ||
1071 | u16 *vbat_l, u16 *vbat_h, u16 *ibat_l, u16 *ibat_h) | ||
1072 | { | ||
1073 | *vmain_l = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo; | ||
1074 | *vmain_h = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi; | ||
1075 | *btemp_l = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo; | ||
1076 | *btemp_h = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi; | ||
1077 | *vbat_l = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo; | ||
1078 | *vbat_h = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi; | ||
1079 | *ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo; | ||
1080 | *ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi; | ||
1081 | return ; | ||
1082 | } | ||
1083 | |||
732 | subsys_initcall_sync(ab8500_gpadc_init); | 1084 | subsys_initcall_sync(ab8500_gpadc_init); |
733 | module_exit(ab8500_gpadc_exit); | 1085 | module_exit(ab8500_gpadc_exit); |
734 | 1086 | ||
735 | MODULE_LICENSE("GPL v2"); | 1087 | MODULE_LICENSE("GPL v2"); |
736 | MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson"); | 1088 | MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson," |
1089 | "M'boumba Cedric Madianga"); | ||
737 | MODULE_ALIAS("platform:ab8500_gpadc"); | 1090 | MODULE_ALIAS("platform:ab8500_gpadc"); |
738 | MODULE_DESCRIPTION("AB8500 GPADC driver"); | 1091 | MODULE_DESCRIPTION("AB8500 GPADC driver"); |