aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/ab8500-gpadc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/ab8500-gpadc.c')
-rw-r--r--drivers/mfd/ab8500-gpadc.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index f16afb234ff9..e985d1701a83 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -143,12 +143,15 @@ struct ab8500_gpadc *ab8500_gpadc_get(char *name)
143} 143}
144EXPORT_SYMBOL(ab8500_gpadc_get); 144EXPORT_SYMBOL(ab8500_gpadc_get);
145 145
146static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input, 146/**
147 * ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage
148 */
149int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 channel,
147 int ad_value) 150 int ad_value)
148{ 151{
149 int res; 152 int res;
150 153
151 switch (input) { 154 switch (channel) {
152 case MAIN_CHARGER_V: 155 case MAIN_CHARGER_V:
153 /* For some reason we don't have calibrated data */ 156 /* For some reason we don't have calibrated data */
154 if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) { 157 if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
@@ -232,18 +235,46 @@ static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
232 } 235 }
233 return res; 236 return res;
234} 237}
238EXPORT_SYMBOL(ab8500_gpadc_ad_to_voltage);
235 239
236/** 240/**
237 * ab8500_gpadc_convert() - gpadc conversion 241 * ab8500_gpadc_convert() - gpadc conversion
238 * @input: analog input to be converted to digital data 242 * @channel: analog channel to be converted to digital data
239 * 243 *
240 * This function converts the selected analog i/p to digital 244 * This function converts the selected analog i/p to digital
241 * data. 245 * data.
242 */ 246 */
243int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input) 247int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel)
248{
249 int ad_value;
250 int voltage;
251
252 ad_value = ab8500_gpadc_read_raw(gpadc, channel);
253 if (ad_value < 0) {
254 dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n", channel);
255 return ad_value;
256 }
257
258 voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value);
259
260 if (voltage < 0)
261 dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
262 " %d AD: 0x%x\n", channel, ad_value);
263
264 return voltage;
265}
266EXPORT_SYMBOL(ab8500_gpadc_convert);
267
268/**
269 * ab8500_gpadc_read_raw() - gpadc read
270 * @channel: analog channel to be read
271 *
272 * This function obtains the raw ADC value, this then needs
273 * to be converted by calling ab8500_gpadc_ad_to_voltage()
274 */
275int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel)
244{ 276{
245 int ret; 277 int ret;
246 u16 data = 0;
247 int looplimit = 0; 278 int looplimit = 0;
248 u8 val, low_data, high_data; 279 u8 val, low_data, high_data;
249 280
@@ -278,9 +309,9 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
278 goto out; 309 goto out;
279 } 310 }
280 311
281 /* Select the input source and set average samples to 16 */ 312 /* Select the channel source and set average samples to 16 */
282 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, 313 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
283 AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16)); 314 AB8500_GPADC_CTRL2_REG, (channel | SW_AVG_16));
284 if (ret < 0) { 315 if (ret < 0) {
285 dev_err(gpadc->dev, 316 dev_err(gpadc->dev,
286 "gpadc_conversion: set avg samples failed\n"); 317 "gpadc_conversion: set avg samples failed\n");
@@ -292,7 +323,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
292 * charging current sense if it needed, ABB 3.0 needs some special 323 * charging current sense if it needed, ABB 3.0 needs some special
293 * treatment too. 324 * treatment too.
294 */ 325 */
295 switch (input) { 326 switch (channel) {
296 case MAIN_CHARGER_C: 327 case MAIN_CHARGER_C:
297 case USB_CHARGER_C: 328 case USB_CHARGER_C:
298 ret = abx500_mask_and_set_register_interruptible(gpadc->dev, 329 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
@@ -359,7 +390,6 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
359 goto out; 390 goto out;
360 } 391 }
361 392
362 data = (high_data << 8) | low_data;
363 /* Disable GPADC */ 393 /* Disable GPADC */
364 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC, 394 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
365 AB8500_GPADC_CTRL1_REG, DIS_GPADC); 395 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
@@ -370,8 +400,8 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
370 /* Disable VTVout LDO this is required for GPADC */ 400 /* Disable VTVout LDO this is required for GPADC */
371 regulator_disable(gpadc->regu); 401 regulator_disable(gpadc->regu);
372 mutex_unlock(&gpadc->ab8500_gpadc_lock); 402 mutex_unlock(&gpadc->ab8500_gpadc_lock);
373 ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data); 403
374 return ret; 404 return (high_data << 8) | low_data;
375 405
376out: 406out:
377 /* 407 /*
@@ -385,10 +415,10 @@ out:
385 regulator_disable(gpadc->regu); 415 regulator_disable(gpadc->regu);
386 mutex_unlock(&gpadc->ab8500_gpadc_lock); 416 mutex_unlock(&gpadc->ab8500_gpadc_lock);
387 dev_err(gpadc->dev, 417 dev_err(gpadc->dev,
388 "gpadc_conversion: Failed to AD convert channel %d\n", input); 418 "gpadc_conversion: Failed to AD convert channel %d\n", channel);
389 return ret; 419 return ret;
390} 420}
391EXPORT_SYMBOL(ab8500_gpadc_convert); 421EXPORT_SYMBOL(ab8500_gpadc_read_raw);
392 422
393/** 423/**
394 * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion 424 * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion