2011-02-22 12:11:13 +03:00
/*
* Copyright ( C ) ST - Ericsson SA 2010
*
* License Terms : GNU General Public License v2
* Author : Arun R Murthy < arun . murthy @ stericsson . com >
2011-03-05 13:46:13 +03:00
* Author : Daniel Willerud < daniel . willerud @ stericsson . com >
2011-03-05 13:46:37 +03:00
* Author : Johan Palsson < johan . palsson @ stericsson . com >
2016-10-30 04:24:38 +03:00
* Author : M ' boumba Cedric Madianga
2011-02-22 12:11:13 +03:00
*/
# include <linux/init.h>
# include <linux/device.h>
# include <linux/interrupt.h>
# include <linux/spinlock.h>
# include <linux/delay.h>
2013-02-04 12:33:13 +04:00
# include <linux/pm_runtime.h>
2011-02-22 12:11:13 +03:00
# include <linux/platform_device.h>
# include <linux/completion.h>
# include <linux/regulator/consumer.h>
# include <linux/err.h>
# include <linux/slab.h>
2011-03-05 13:46:13 +03:00
# include <linux/list.h>
2011-02-22 12:11:13 +03:00
# include <linux/mfd/abx500.h>
2011-12-02 17:16:33 +04:00
# include <linux/mfd/abx500/ab8500.h>
# include <linux/mfd/abx500/ab8500-gpadc.h>
2011-02-22 12:11:13 +03:00
/*
* GPADC register offsets
* Bank : 0x0A
*/
# define AB8500_GPADC_CTRL1_REG 0x00
# define AB8500_GPADC_CTRL2_REG 0x01
# define AB8500_GPADC_CTRL3_REG 0x02
# define AB8500_GPADC_AUTO_TIMER_REG 0x03
# define AB8500_GPADC_STAT_REG 0x04
# define AB8500_GPADC_MANDATAL_REG 0x05
# define AB8500_GPADC_MANDATAH_REG 0x06
# define AB8500_GPADC_AUTODATAL_REG 0x07
# define AB8500_GPADC_AUTODATAH_REG 0x08
# define AB8500_GPADC_MUX_CTRL_REG 0x09
2013-02-11 14:38:00 +04:00
# define AB8540_GPADC_MANDATA2L_REG 0x09
# define AB8540_GPADC_MANDATA2H_REG 0x0A
# define AB8540_GPADC_APEAAX_REG 0x10
# define AB8540_GPADC_APEAAT_REG 0x11
# define AB8540_GPADC_APEAAM_REG 0x12
# define AB8540_GPADC_APEAAH_REG 0x13
# define AB8540_GPADC_APEAAL_REG 0x14
2011-02-22 12:11:13 +03:00
2011-03-05 13:46:37 +03:00
/*
* OTP register offsets
* Bank : 0x15
*/
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
# define AB8500_GPADC_CAL_1 0x0F
# define AB8500_GPADC_CAL_2 0x10
# define AB8500_GPADC_CAL_3 0x11
# define AB8500_GPADC_CAL_4 0x12
# define AB8500_GPADC_CAL_5 0x13
# define AB8500_GPADC_CAL_6 0x14
# define AB8500_GPADC_CAL_7 0x15
2013-02-11 14:38:00 +04:00
/* New calibration for 8540 */
# define AB8540_GPADC_OTP4_REG_7 0x38
# define AB8540_GPADC_OTP4_REG_6 0x39
# define AB8540_GPADC_OTP4_REG_5 0x3A
2011-03-05 13:46:37 +03:00
2011-02-22 12:11:13 +03:00
/* gpadc constants */
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
# define EN_VINTCORE12 0x04
# define EN_VTVOUT 0x02
# define EN_GPADC 0x01
# define DIS_GPADC 0x00
# define AVG_1 0x00
# define AVG_4 0x20
# define AVG_8 0x40
# define AVG_16 0x60
# define ADC_SW_CONV 0x04
# define EN_ICHAR 0x80
# define BTEMP_PULL_UP 0x08
# define EN_BUF 0x40
# define DIS_ZERO 0x00
# define GPADC_BUSY 0x01
# define EN_FALLING 0x10
# define EN_TRIG_EDGE 0x02
# define EN_VBIAS_XTAL_TEMP 0x02
2011-02-22 12:11:13 +03:00
2011-03-05 13:46:37 +03:00
/* GPADC constants from AB8500 spec, UM0836 */
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
# define ADC_RESOLUTION 1024
# define ADC_CH_BTEMP_MIN 0
# define ADC_CH_BTEMP_MAX 1350
# define ADC_CH_DIETEMP_MIN 0
# define ADC_CH_DIETEMP_MAX 1350
# define ADC_CH_CHG_V_MIN 0
# define ADC_CH_CHG_V_MAX 20030
# define ADC_CH_ACCDET2_MIN 0
# define ADC_CH_ACCDET2_MAX 2500
# define ADC_CH_VBAT_MIN 2300
# define ADC_CH_VBAT_MAX 4800
# define ADC_CH_CHG_I_MIN 0
# define ADC_CH_CHG_I_MAX 1500
# define ADC_CH_BKBAT_MIN 0
# define ADC_CH_BKBAT_MAX 3200
2011-03-05 13:46:37 +03:00
2013-02-11 14:38:00 +04:00
/* GPADC constants from AB8540 spec */
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
# define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat */
# define ADC_CH_IBAT_MAX 6000
# define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat */
# define ADC_CH_IBAT_MAX_V 60
# define IBAT_VDROP_L (-56) /* mV */
# define IBAT_VDROP_H 56
2013-02-11 14:38:00 +04:00
2011-03-05 13:46:37 +03:00
/* This is used to not lose precision when dividing to get gain and offset */
2013-02-11 14:38:00 +04:00
# define CALIB_SCALE 1000
/*
* Number of bits shift used to not lose precision
* when dividing to get ibat gain .
*/
# define CALIB_SHIFT_IBAT 20
2011-03-05 13:46:37 +03:00
2013-02-04 12:33:13 +04:00
/* Time in ms before disabling regulator */
# define GPADC_AUDOSUSPEND_DELAY 1
2013-01-28 13:20:45 +04:00
# define CONVERSION_TIME 500 /* ms */
2011-03-05 13:46:37 +03:00
enum cal_channels {
ADC_INPUT_VMAIN = 0 ,
ADC_INPUT_BTEMP ,
ADC_INPUT_VBAT ,
2013-02-11 14:38:00 +04:00
ADC_INPUT_IBAT ,
2011-03-05 13:46:37 +03:00
NBR_CAL_INPUTS ,
} ;
/**
* struct adc_cal_data - Table for storing gain and offset for the calibrated
* ADC channels
* @ gain : Gain of the ADC channel
* @ offset : Offset of the ADC channel
*/
struct adc_cal_data {
2013-02-11 14:38:00 +04:00
s64 gain ;
s64 offset ;
2013-02-26 18:02:31 +04:00
u16 otp_calib_hi ;
u16 otp_calib_lo ;
2011-03-05 13:46:37 +03:00
} ;
2011-02-22 12:11:13 +03:00
/**
2011-03-05 13:46:37 +03:00
* struct ab8500_gpadc - AB8500 GPADC device information
2011-02-22 12:11:13 +03:00
* @ dev : pointer to the struct device
2011-03-05 13:46:13 +03:00
* @ node : a list of AB8500 GPADCs , hence prepared for
reentrance
2012-02-09 15:06:47 +04:00
* @ parent : pointer to the struct ab8500
2011-02-22 12:11:13 +03:00
* @ ab8500_gpadc_complete : pointer to the struct completion , to indicate
* the completion of gpadc conversion
* @ ab8500_gpadc_lock : structure of type mutex
* @ regu : pointer to the struct regulator
2013-02-26 14:06:55 +04:00
* @ irq_sw : interrupt number that is used by gpadc for Sw
* conversion
* @ irq_hw : interrupt number that is used by gpadc for Hw
* conversion
2011-03-05 13:46:37 +03:00
* @ cal_data array of ADC calibration data structs
2011-02-22 12:11:13 +03:00
*/
2011-03-05 13:46:13 +03:00
struct ab8500_gpadc {
2011-02-22 12:11:13 +03:00
struct device * dev ;
2011-03-05 13:46:13 +03:00
struct list_head node ;
2012-02-09 15:06:47 +04:00
struct ab8500 * parent ;
2011-02-22 12:11:13 +03:00
struct completion ab8500_gpadc_complete ;
struct mutex ab8500_gpadc_lock ;
struct regulator * regu ;
2013-02-26 14:06:55 +04:00
int irq_sw ;
int irq_hw ;
2011-03-05 13:46:37 +03:00
struct adc_cal_data cal_data [ NBR_CAL_INPUTS ] ;
2011-03-05 13:46:13 +03:00
} ;
static LIST_HEAD ( ab8500_gpadc_list ) ;
/**
* ab8500_gpadc_get ( ) - returns a reference to the primary AB8500 GPADC
* ( i . e . the first GPADC in the instance list )
*/
struct ab8500_gpadc * ab8500_gpadc_get ( char * name )
{
struct ab8500_gpadc * gpadc ;
list_for_each_entry ( gpadc , & ab8500_gpadc_list , node ) {
if ( ! strcmp ( name , dev_name ( gpadc - > dev ) ) )
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
return gpadc ;
2011-03-05 13:46:13 +03:00
}
return ERR_PTR ( - ENOENT ) ;
}
EXPORT_SYMBOL ( ab8500_gpadc_get ) ;
2011-02-22 12:11:13 +03:00
2011-08-10 17:09:43 +04:00
/**
* ab8500_gpadc_ad_to_voltage ( ) - Convert a raw ADC value to a voltage
*/
int ab8500_gpadc_ad_to_voltage ( struct ab8500_gpadc * gpadc , u8 channel ,
2011-03-05 13:46:37 +03:00
int ad_value )
{
int res ;
2011-08-10 17:09:43 +04:00
switch ( channel ) {
2011-03-05 13:46:37 +03:00
case MAIN_CHARGER_V :
/* For some reason we don't have calibrated data */
if ( ! gpadc - > cal_data [ ADC_INPUT_VMAIN ] . gain ) {
res = ADC_CH_CHG_V_MIN + ( ADC_CH_CHG_V_MAX -
ADC_CH_CHG_V_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
}
/* Here we can use the calibrated data */
res = ( int ) ( ad_value * gpadc - > cal_data [ ADC_INPUT_VMAIN ] . gain +
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . offset ) / CALIB_SCALE ;
break ;
2013-02-11 14:38:00 +04:00
case XTAL_TEMP :
2011-03-05 13:46:37 +03:00
case BAT_CTRL :
case BTEMP_BALL :
case ACC_DETECT1 :
case ADC_AUX1 :
case ADC_AUX2 :
/* For some reason we don't have calibrated data */
if ( ! gpadc - > cal_data [ ADC_INPUT_BTEMP ] . gain ) {
res = ADC_CH_BTEMP_MIN + ( ADC_CH_BTEMP_MAX -
ADC_CH_BTEMP_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
}
/* Here we can use the calibrated data */
res = ( int ) ( ad_value * gpadc - > cal_data [ ADC_INPUT_BTEMP ] . gain +
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . offset ) / CALIB_SCALE ;
break ;
case MAIN_BAT_V :
2013-02-11 14:38:00 +04:00
case VBAT_TRUE_MEAS :
2011-03-05 13:46:37 +03:00
/* For some reason we don't have calibrated data */
if ( ! gpadc - > cal_data [ ADC_INPUT_VBAT ] . gain ) {
res = ADC_CH_VBAT_MIN + ( ADC_CH_VBAT_MAX -
ADC_CH_VBAT_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
}
/* Here we can use the calibrated data */
res = ( int ) ( ad_value * gpadc - > cal_data [ ADC_INPUT_VBAT ] . gain +
gpadc - > cal_data [ ADC_INPUT_VBAT ] . offset ) / CALIB_SCALE ;
break ;
case DIE_TEMP :
res = ADC_CH_DIETEMP_MIN +
( ADC_CH_DIETEMP_MAX - ADC_CH_DIETEMP_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
case ACC_DETECT2 :
res = ADC_CH_ACCDET2_MIN +
( ADC_CH_ACCDET2_MAX - ADC_CH_ACCDET2_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
case VBUS_V :
res = ADC_CH_CHG_V_MIN +
( ADC_CH_CHG_V_MAX - ADC_CH_CHG_V_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
case MAIN_CHARGER_C :
case USB_CHARGER_C :
res = ADC_CH_CHG_I_MIN +
( ADC_CH_CHG_I_MAX - ADC_CH_CHG_I_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
case BK_BAT_V :
res = ADC_CH_BKBAT_MIN +
( ADC_CH_BKBAT_MAX - ADC_CH_BKBAT_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
2013-02-11 14:38:00 +04:00
case IBAT_VIRTUAL_CHANNEL :
/* For some reason we don't have calibrated data */
if ( ! gpadc - > cal_data [ ADC_INPUT_IBAT ] . gain ) {
res = ADC_CH_IBAT_MIN + ( ADC_CH_IBAT_MAX -
ADC_CH_IBAT_MIN ) * ad_value /
ADC_RESOLUTION ;
break ;
}
/* Here we can use the calibrated data */
res = ( int ) ( ad_value * gpadc - > cal_data [ ADC_INPUT_IBAT ] . gain +
gpadc - > cal_data [ ADC_INPUT_IBAT ] . offset )
> > CALIB_SHIFT_IBAT ;
break ;
2011-03-05 13:46:37 +03:00
default :
dev_err ( gpadc - > dev ,
" unknown channel, not possible to convert \n " ) ;
res = - EINVAL ;
break ;
}
return res ;
}
2011-08-10 17:09:43 +04:00
EXPORT_SYMBOL ( ab8500_gpadc_ad_to_voltage ) ;
2011-03-05 13:46:37 +03:00
2011-02-22 12:11:13 +03:00
/**
2013-02-26 14:06:55 +04:00
* ab8500_gpadc_sw_hw_convert ( ) - gpadc conversion
2011-08-10 17:09:43 +04:00
* @ channel : analog channel to be converted to digital data
2013-02-26 14:06:55 +04:00
* @ avg_sample : number of ADC sample to average
* @ trig_egde : selected ADC trig edge
* @ trig_timer : selected ADC trigger delay timer
* @ conv_type : selected conversion type ( HW or SW conversion )
2011-02-22 12:11:13 +03:00
*
* This function converts the selected analog i / p to digital
2011-03-05 13:46:37 +03:00
* data .
2011-02-22 12:11:13 +03:00
*/
2013-02-26 14:06:55 +04:00
int ab8500_gpadc_sw_hw_convert ( struct ab8500_gpadc * gpadc , u8 channel ,
u8 avg_sample , u8 trig_edge , u8 trig_timer , u8 conv_type )
2011-08-10 17:09:43 +04:00
{
int ad_value ;
int voltage ;
2013-02-26 14:06:55 +04:00
ad_value = ab8500_gpadc_read_raw ( gpadc , channel , avg_sample ,
trig_edge , trig_timer , conv_type ) ;
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
/* On failure retry a second time */
2012-04-17 18:10:46 +04:00
if ( ad_value < 0 )
2013-02-26 14:06:55 +04:00
ad_value = ab8500_gpadc_read_raw ( gpadc , channel , avg_sample ,
trig_edge , trig_timer , conv_type ) ;
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
if ( ad_value < 0 ) {
2013-02-26 14:06:55 +04:00
dev_err ( gpadc - > dev , " GPADC raw value failed ch: %d \n " ,
channel ) ;
2011-08-10 17:09:43 +04:00
return ad_value ;
}
voltage = ab8500_gpadc_ad_to_voltage ( gpadc , channel , ad_value ) ;
if ( voltage < 0 )
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
dev_err ( gpadc - > dev ,
" GPADC to voltage conversion failed ch: %d AD: 0x%x \n " ,
channel , ad_value ) ;
2011-08-10 17:09:43 +04:00
return voltage ;
}
2013-04-23 20:30:52 +04:00
EXPORT_SYMBOL ( ab8500_gpadc_sw_hw_convert ) ;
2011-08-10 17:09:43 +04:00
/**
* ab8500_gpadc_read_raw ( ) - gpadc read
* @ channel : analog channel to be read
2013-02-26 14:06:55 +04:00
* @ avg_sample : number of ADC sample to average
* @ trig_edge : selected trig edge
* @ trig_timer : selected ADC trigger delay timer
* @ conv_type : selected conversion type ( HW or SW conversion )
2011-08-10 17:09:43 +04:00
*
2013-02-26 14:06:55 +04:00
* This function obtains the raw ADC value for an hardware conversion ,
* this then needs to be converted by calling ab8500_gpadc_ad_to_voltage ( )
2011-08-10 17:09:43 +04:00
*/
2013-02-26 14:06:55 +04:00
int ab8500_gpadc_read_raw ( struct ab8500_gpadc * gpadc , u8 channel ,
u8 avg_sample , u8 trig_edge , u8 trig_timer , u8 conv_type )
2013-02-11 14:38:00 +04:00
{
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
return ab8500_gpadc_double_read_raw ( gpadc , channel , avg_sample ,
trig_edge , trig_timer , conv_type ,
NULL ) ;
2013-02-11 14:38:00 +04:00
}
int ab8500_gpadc_double_read_raw ( struct ab8500_gpadc * gpadc , u8 channel ,
u8 avg_sample , u8 trig_edge , u8 trig_timer , u8 conv_type ,
int * ibat )
2011-02-22 12:11:13 +03:00
{
int ret ;
int looplimit = 0 ;
2013-02-11 14:49:41 +04:00
unsigned long completion_timeout ;
2013-02-11 14:38:00 +04:00
u8 val , low_data , high_data , low_data2 , high_data2 ;
2013-02-11 14:49:41 +04:00
u8 val_reg1 = 0 ;
unsigned int delay_min = 0 ;
unsigned int delay_max = 0 ;
u8 data_low_addr , data_high_addr ;
2011-02-22 12:11:13 +03:00
2011-03-05 13:46:13 +03:00
if ( ! gpadc )
2011-02-22 12:11:13 +03:00
return - ENODEV ;
2013-02-12 19:04:09 +04:00
/* check if convertion is supported */
if ( ( gpadc - > irq_sw < 0 ) & & ( conv_type = = ADC_SW ) )
return - ENOTSUPP ;
if ( ( gpadc - > irq_hw < 0 ) & & ( conv_type = = ADC_HW ) )
return - ENOTSUPP ;
2013-02-04 12:33:13 +04:00
2011-03-05 13:46:13 +03:00
mutex_lock ( & gpadc - > ab8500_gpadc_lock ) ;
2011-02-22 12:11:13 +03:00
/* Enable VTVout LDO this is required for GPADC */
2013-02-04 12:33:13 +04:00
pm_runtime_get_sync ( gpadc - > dev ) ;
2011-02-22 12:11:13 +03:00
/* Check if ADC is not busy, lock and proceed */
do {
2011-03-05 13:46:13 +03:00
ret = abx500_get_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8500_GPADC_STAT_REG , & val ) ;
2011-02-22 12:11:13 +03:00
if ( ret < 0 )
goto out ;
if ( ! ( val & GPADC_BUSY ) )
break ;
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
msleep ( 20 ) ;
2011-02-22 12:11:13 +03:00
} while ( + + looplimit < 10 ) ;
if ( looplimit > = 10 & & ( val & GPADC_BUSY ) ) {
2011-03-05 13:46:13 +03:00
dev_err ( gpadc - > dev , " gpadc_conversion: GPADC busy " ) ;
2011-02-22 12:11:13 +03:00
ret = - EINVAL ;
goto out ;
}
/* Enable GPADC */
2013-02-11 14:49:41 +04:00
val_reg1 | = EN_GPADC ;
2011-05-08 02:55:31 +04:00
2013-02-26 14:06:55 +04:00
/* Select the channel source and set average samples */
switch ( avg_sample ) {
case SAMPLE_1 :
val = channel | AVG_1 ;
break ;
case SAMPLE_4 :
val = channel | AVG_4 ;
break ;
case SAMPLE_8 :
val = channel | AVG_8 ;
break ;
default :
val = channel | AVG_16 ;
break ;
2011-02-22 12:11:13 +03:00
}
2011-05-08 02:55:31 +04:00
2013-02-11 14:49:41 +04:00
if ( conv_type = = ADC_HW ) {
2013-02-26 14:06:55 +04:00
ret = abx500_set_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8500_GPADC_CTRL3_REG , val ) ;
2013-02-11 14:49:41 +04:00
val_reg1 | = EN_TRIG_EDGE ;
if ( trig_edge )
val_reg1 | = EN_FALLING ;
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
} else
2013-02-26 14:06:55 +04:00
ret = abx500_set_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8500_GPADC_CTRL2_REG , val ) ;
2011-02-22 12:11:13 +03:00
if ( ret < 0 ) {
2011-03-05 13:46:13 +03:00
dev_err ( gpadc - > dev ,
2011-02-22 12:11:13 +03:00
" gpadc_conversion: set avg samples failed \n " ) ;
goto out ;
}
2011-05-08 02:55:31 +04:00
2011-03-05 13:46:45 +03:00
/*
* Enable ADC , buffering , select rising edge and enable ADC path
2011-05-08 02:55:31 +04:00
* charging current sense if it needed , ABB 3.0 needs some special
* treatment too .
2011-03-05 13:46:45 +03:00
*/
2011-08-10 17:09:43 +04:00
switch ( channel ) {
2011-03-05 13:46:45 +03:00
case MAIN_CHARGER_C :
case USB_CHARGER_C :
2013-02-11 14:49:41 +04:00
val_reg1 | = EN_BUF | EN_ICHAR ;
2011-03-05 13:46:45 +03:00
break ;
2011-05-08 02:55:31 +04:00
case BTEMP_BALL :
2012-02-09 15:06:47 +04:00
if ( ! is_ab8500_2p0_or_earlier ( gpadc - > parent ) ) {
2013-02-11 14:49:41 +04:00
val_reg1 | = EN_BUF | BTEMP_PULL_UP ;
/*
* Delay might be needed for ABB8500 cut 3.0 , if not ,
* remove when hardware will be availible
*/
delay_min = 1000 ; /* Delay in micro seconds */
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
delay_max = 10000 ; /* large range optimises sleepmode */
2011-05-08 02:55:31 +04:00
break ;
}
/* Intentional fallthrough */
2011-03-05 13:46:45 +03:00
default :
2013-02-11 14:49:41 +04:00
val_reg1 | = EN_BUF ;
2011-03-05 13:46:45 +03:00
break ;
}
2013-02-11 14:49:41 +04:00
/* Write configuration to register */
ret = abx500_set_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8500_GPADC_CTRL1_REG , val_reg1 ) ;
2011-02-22 12:11:13 +03:00
if ( ret < 0 ) {
2011-03-05 13:46:13 +03:00
dev_err ( gpadc - > dev ,
2013-02-11 14:49:41 +04:00
" gpadc_conversion: set Control register failed \n " ) ;
2011-02-22 12:11:13 +03:00
goto out ;
}
2011-05-08 02:55:31 +04:00
2013-02-11 14:49:41 +04:00
if ( delay_min ! = 0 )
usleep_range ( delay_min , delay_max ) ;
2013-02-26 14:06:55 +04:00
if ( conv_type = = ADC_HW ) {
2013-02-11 14:49:41 +04:00
/* Set trigger delay timer */
2013-02-26 14:06:55 +04:00
ret = abx500_set_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8500_GPADC_AUTO_TIMER_REG , trig_timer ) ;
if ( ret < 0 ) {
dev_err ( gpadc - > dev ,
" gpadc_conversion: trig timer failed \n " ) ;
goto out ;
}
2013-02-11 14:49:41 +04:00
completion_timeout = 2 * HZ ;
data_low_addr = AB8500_GPADC_AUTODATAL_REG ;
data_high_addr = AB8500_GPADC_AUTODATAH_REG ;
} else {
/* Start SW conversion */
2013-02-26 14:06:55 +04:00
ret = abx500_mask_and_set_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8500_GPADC_CTRL1_REG ,
ADC_SW_CONV , ADC_SW_CONV ) ;
if ( ret < 0 ) {
dev_err ( gpadc - > dev ,
" gpadc_conversion: start s/w conv failed \n " ) ;
goto out ;
}
2013-02-11 14:49:41 +04:00
completion_timeout = msecs_to_jiffies ( CONVERSION_TIME ) ;
data_low_addr = AB8500_GPADC_MANDATAL_REG ;
data_high_addr = AB8500_GPADC_MANDATAH_REG ;
2011-02-22 12:11:13 +03:00
}
2013-02-26 14:06:55 +04:00
2011-02-22 12:11:13 +03:00
/* wait for completion of conversion */
2013-01-28 13:20:45 +04:00
if ( ! wait_for_completion_timeout ( & gpadc - > ab8500_gpadc_complete ,
2013-02-11 14:49:41 +04:00
completion_timeout ) ) {
2011-03-05 13:46:13 +03:00
dev_err ( gpadc - > dev ,
2013-02-11 14:49:41 +04:00
" timeout didn't receive GPADC conv interrupt \n " ) ;
2011-02-22 12:11:13 +03:00
ret = - EINVAL ;
goto out ;
}
/* Read the converted RAW data */
2013-02-11 14:49:41 +04:00
ret = abx500_get_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , data_low_addr , & low_data ) ;
2011-02-22 12:11:13 +03:00
if ( ret < 0 ) {
2011-03-05 13:46:13 +03:00
dev_err ( gpadc - > dev , " gpadc_conversion: read low data failed \n " ) ;
2011-02-22 12:11:13 +03:00
goto out ;
}
2013-02-11 14:49:41 +04:00
ret = abx500_get_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , data_high_addr , & high_data ) ;
2011-02-22 12:11:13 +03:00
if ( ret < 0 ) {
2013-02-11 14:49:41 +04:00
dev_err ( gpadc - > dev , " gpadc_conversion: read high data failed \n " ) ;
2011-02-22 12:11:13 +03:00
goto out ;
}
2013-02-11 14:38:00 +04:00
/* Check if double convertion is required */
if ( ( channel = = BAT_CTRL_AND_IBAT ) | |
( channel = = VBAT_MEAS_AND_IBAT ) | |
( channel = = VBAT_TRUE_MEAS_AND_IBAT ) | |
( channel = = BAT_TEMP_AND_IBAT ) ) {
if ( conv_type = = ADC_HW ) {
/* not supported */
ret = - ENOTSUPP ;
dev_err ( gpadc - > dev ,
" gpadc_conversion: only SW double conversion supported \n " ) ;
goto out ;
} else {
/* Read the converted RAW data 2 */
ret = abx500_get_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8540_GPADC_MANDATA2L_REG ,
& low_data2 ) ;
if ( ret < 0 ) {
dev_err ( gpadc - > dev ,
" gpadc_conversion: read sw low data 2 failed \n " ) ;
goto out ;
}
ret = abx500_get_register_interruptible ( gpadc - > dev ,
AB8500_GPADC , AB8540_GPADC_MANDATA2H_REG ,
& high_data2 ) ;
if ( ret < 0 ) {
dev_err ( gpadc - > dev ,
" gpadc_conversion: read sw high data 2 failed \n " ) ;
goto out ;
}
if ( ibat ! = NULL ) {
* ibat = ( high_data2 < < 8 ) | low_data2 ;
} else {
dev_warn ( gpadc - > dev ,
" gpadc_conversion: ibat not stored \n " ) ;
}
}
}
2011-02-22 12:11:13 +03:00
/* Disable GPADC */
2011-03-05 13:46:13 +03:00
ret = abx500_set_register_interruptible ( gpadc - > dev , AB8500_GPADC ,
2011-02-22 12:11:13 +03:00
AB8500_GPADC_CTRL1_REG , DIS_GPADC ) ;
if ( ret < 0 ) {
2011-03-05 13:46:13 +03:00
dev_err ( gpadc - > dev , " gpadc_conversion: disable gpadc failed \n " ) ;
2011-02-22 12:11:13 +03:00
goto out ;
}
2013-02-04 12:33:13 +04:00
2013-02-26 14:06:55 +04:00
/* Disable VTVout LDO this is required for GPADC */
2013-02-04 12:33:13 +04:00
pm_runtime_mark_last_busy ( gpadc - > dev ) ;
pm_runtime_put_autosuspend ( gpadc - > dev ) ;
2011-03-05 13:46:13 +03:00
mutex_unlock ( & gpadc - > ab8500_gpadc_lock ) ;
2011-08-10 17:09:43 +04:00
return ( high_data < < 8 ) | low_data ;
2011-02-22 12:11:13 +03:00
out :
/*
* It has shown to be needed to turn off the GPADC if an error occurs ,
* otherwise we might have problem when waiting for the busy bit in the
* GPADC status register to go low . In V1 .1 there wait_for_completion
* seems to timeout when waiting for an interrupt . . Not seen in V2 .0
*/
2011-03-05 13:46:13 +03:00
( void ) abx500_set_register_interruptible ( gpadc - > dev , AB8500_GPADC ,
2011-02-22 12:11:13 +03:00
AB8500_GPADC_CTRL1_REG , DIS_GPADC ) ;
2013-02-04 12:33:13 +04:00
pm_runtime_put ( gpadc - > dev ) ;
2011-03-05 13:46:13 +03:00
mutex_unlock ( & gpadc - > ab8500_gpadc_lock ) ;
dev_err ( gpadc - > dev ,
2011-08-10 17:09:43 +04:00
" gpadc_conversion: Failed to AD convert channel %d \n " , channel ) ;
2011-02-22 12:11:13 +03:00
return ret ;
}
2011-08-10 17:09:43 +04:00
EXPORT_SYMBOL ( ab8500_gpadc_read_raw ) ;
2011-02-22 12:11:13 +03:00
/**
2013-02-26 14:06:55 +04:00
* ab8500_bm_gpadcconvend_handler ( ) - isr for gpadc conversion completion
2011-02-22 12:11:13 +03:00
* @ irq : irq number
* @ data : pointer to the data passed during request irq
*
2013-02-26 14:06:55 +04:00
* This is a interrupt service routine for gpadc conversion completion .
2011-02-22 12:11:13 +03:00
* Notifies the gpadc completion is completed and the converted raw value
* can be read from the registers .
* Returns IRQ status ( IRQ_HANDLED )
*/
2013-02-26 14:06:55 +04:00
static irqreturn_t ab8500_bm_gpadcconvend_handler ( int irq , void * _gpadc )
2011-02-22 12:11:13 +03:00
{
2011-03-05 13:46:13 +03:00
struct ab8500_gpadc * gpadc = _gpadc ;
2011-02-22 12:11:13 +03:00
complete ( & gpadc - > ab8500_gpadc_complete ) ;
return IRQ_HANDLED ;
}
2011-03-05 13:46:37 +03:00
static int otp_cal_regs [ ] = {
AB8500_GPADC_CAL_1 ,
AB8500_GPADC_CAL_2 ,
AB8500_GPADC_CAL_3 ,
AB8500_GPADC_CAL_4 ,
AB8500_GPADC_CAL_5 ,
AB8500_GPADC_CAL_6 ,
AB8500_GPADC_CAL_7 ,
} ;
2013-02-11 14:38:00 +04:00
static int otp4_cal_regs [ ] = {
AB8540_GPADC_OTP4_REG_7 ,
AB8540_GPADC_OTP4_REG_6 ,
AB8540_GPADC_OTP4_REG_5 ,
} ;
2011-03-05 13:46:37 +03:00
static void ab8500_gpadc_read_calibration_data ( struct ab8500_gpadc * gpadc )
{
int i ;
int ret [ ARRAY_SIZE ( otp_cal_regs ) ] ;
u8 gpadc_cal [ ARRAY_SIZE ( otp_cal_regs ) ] ;
2013-02-11 14:38:00 +04:00
int ret_otp4 [ ARRAY_SIZE ( otp4_cal_regs ) ] ;
u8 gpadc_otp4 [ ARRAY_SIZE ( otp4_cal_regs ) ] ;
2011-03-05 13:46:37 +03:00
int vmain_high , vmain_low ;
int btemp_high , btemp_low ;
int vbat_high , vbat_low ;
2013-02-11 14:38:00 +04:00
int ibat_high , ibat_low ;
s64 V_gain , V_offset , V2A_gain , V2A_offset ;
struct ab8500 * ab8500 ;
ab8500 = gpadc - > parent ;
2011-03-05 13:46:37 +03:00
/* First we read all OTP registers and store the error code */
for ( i = 0 ; i < ARRAY_SIZE ( otp_cal_regs ) ; i + + ) {
ret [ i ] = abx500_get_register_interruptible ( gpadc - > dev ,
AB8500_OTP_EMUL , otp_cal_regs [ i ] , & gpadc_cal [ i ] ) ;
if ( ret [ i ] < 0 )
dev_err ( gpadc - > dev , " %s: read otp reg 0x%02x failed \n " ,
__func__ , otp_cal_regs [ i ] ) ;
}
/*
* The ADC calibration data is stored in OTP registers .
* The layout of the calibration data is outlined below and a more
* detailed description can be found in UM0836
*
* vm_h / l = vmain_high / low
* bt_h / l = btemp_high / low
* vb_h / l = vbat_high / low
*
2013-02-11 14:38:00 +04:00
* Data bits 8500 / 9540 :
2011-03-05 13:46:37 +03:00
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | | vm_h9 | vm_h8
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
*
2013-02-11 14:38:00 +04:00
* Data bits 8540 :
* OTP2
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* |
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | vm_h9 | vm_h8 | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
*
* Data bits 8540 :
* OTP4
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | | ib_h9 | ib_h8 | ib_h7
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | ib_h6 | ib_h5 | ib_h4 | ib_h3 | ib_h2 | ib_h1 | ib_h0 | ib_l5
* | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . .
* | ib_l4 | ib_l3 | ib_l2 | ib_l1 | ib_l0 |
*
2011-03-05 13:46:37 +03:00
*
* Ideal output ADC codes corresponding to injected input voltages
* during manufacturing is :
*
* vmain_high : Vin = 19500 mV / ADC ideal code = 997
* vmain_low : Vin = 315 mV / ADC ideal code = 16
* btemp_high : Vin = 1300 mV / ADC ideal code = 985
* btemp_low : Vin = 21 mV / ADC ideal code = 16
* vbat_high : Vin = 4700 mV / ADC ideal code = 982
* vbat_low : Vin = 2380 mV / ADC ideal code = 33
*/
2013-02-11 14:38:00 +04:00
if ( is_ab8540 ( ab8500 ) ) {
/* Calculate gain and offset for VMAIN if all reads succeeded*/
if ( ! ( ret [ 1 ] < 0 | | ret [ 2 ] < 0 ) ) {
vmain_high = ( ( ( gpadc_cal [ 1 ] & 0xFF ) < < 2 ) |
( ( gpadc_cal [ 2 ] & 0xC0 ) > > 6 ) ) ;
vmain_low = ( ( gpadc_cal [ 2 ] & 0x3E ) > > 1 ) ;
2013-02-26 18:02:31 +04:00
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . otp_calib_hi =
( u16 ) vmain_high ;
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . otp_calib_lo =
( u16 ) vmain_low ;
2013-02-11 14:38:00 +04:00
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . gain = CALIB_SCALE *
( 19500 - 315 ) / ( vmain_high - vmain_low ) ;
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . offset = CALIB_SCALE *
19500 - ( CALIB_SCALE * ( 19500 - 315 ) /
( vmain_high - vmain_low ) ) * vmain_high ;
} else {
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . gain = 0 ;
}
2011-03-05 13:46:37 +03:00
2013-02-11 14:38:00 +04:00
/* Read IBAT calibration Data */
for ( i = 0 ; i < ARRAY_SIZE ( otp4_cal_regs ) ; i + + ) {
ret_otp4 [ i ] = abx500_get_register_interruptible (
gpadc - > dev , AB8500_OTP_EMUL ,
otp4_cal_regs [ i ] , & gpadc_otp4 [ i ] ) ;
if ( ret_otp4 [ i ] < 0 )
dev_err ( gpadc - > dev ,
" %s: read otp4 reg 0x%02x failed \n " ,
__func__ , otp4_cal_regs [ i ] ) ;
}
2011-03-05 13:46:37 +03:00
2013-02-11 14:38:00 +04:00
/* Calculate gain and offset for IBAT if all reads succeeded */
if ( ! ( ret_otp4 [ 0 ] < 0 | | ret_otp4 [ 1 ] < 0 | | ret_otp4 [ 2 ] < 0 ) ) {
ibat_high = ( ( ( gpadc_otp4 [ 0 ] & 0x07 ) < < 7 ) |
( ( gpadc_otp4 [ 1 ] & 0xFE ) > > 1 ) ) ;
ibat_low = ( ( ( gpadc_otp4 [ 1 ] & 0x01 ) < < 5 ) |
( ( gpadc_otp4 [ 2 ] & 0xF8 ) > > 3 ) ) ;
2013-02-26 18:02:31 +04:00
gpadc - > cal_data [ ADC_INPUT_IBAT ] . otp_calib_hi =
( u16 ) ibat_high ;
gpadc - > cal_data [ ADC_INPUT_IBAT ] . otp_calib_lo =
( u16 ) ibat_low ;
2013-02-11 14:38:00 +04:00
V_gain = ( ( IBAT_VDROP_H - IBAT_VDROP_L )
< < CALIB_SHIFT_IBAT ) / ( ibat_high - ibat_low ) ;
V_offset = ( IBAT_VDROP_H < < CALIB_SHIFT_IBAT ) -
( ( ( IBAT_VDROP_H - IBAT_VDROP_L ) < <
CALIB_SHIFT_IBAT ) / ( ibat_high - ibat_low ) )
* ibat_high ;
/*
* Result obtained is in mV ( at a scale factor ) ,
* we need to calculate gain and offset to get mA
*/
V2A_gain = ( ADC_CH_IBAT_MAX - ADC_CH_IBAT_MIN ) /
( ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V ) ;
V2A_offset = ( ( ADC_CH_IBAT_MAX_V * ADC_CH_IBAT_MIN -
ADC_CH_IBAT_MAX * ADC_CH_IBAT_MIN_V )
< < CALIB_SHIFT_IBAT )
/ ( ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V ) ;
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
gpadc - > cal_data [ ADC_INPUT_IBAT ] . gain =
V_gain * V2A_gain ;
gpadc - > cal_data [ ADC_INPUT_IBAT ] . offset =
V_offset * V2A_gain + V2A_offset ;
2013-02-11 14:38:00 +04:00
} else {
gpadc - > cal_data [ ADC_INPUT_IBAT ] . gain = 0 ;
}
2011-03-05 13:46:37 +03:00
2013-02-11 14:38:00 +04:00
dev_dbg ( gpadc - > dev , " IBAT gain %llu offset %llu \n " ,
gpadc - > cal_data [ ADC_INPUT_IBAT ] . gain ,
gpadc - > cal_data [ ADC_INPUT_IBAT ] . offset ) ;
2011-03-05 13:46:37 +03:00
} else {
2013-02-11 14:38:00 +04:00
/* Calculate gain and offset for VMAIN if all reads succeeded */
if ( ! ( ret [ 0 ] < 0 | | ret [ 1 ] < 0 | | ret [ 2 ] < 0 ) ) {
vmain_high = ( ( ( gpadc_cal [ 0 ] & 0x03 ) < < 8 ) |
( ( gpadc_cal [ 1 ] & 0x3F ) < < 2 ) |
( ( gpadc_cal [ 2 ] & 0xC0 ) > > 6 ) ) ;
vmain_low = ( ( gpadc_cal [ 2 ] & 0x3E ) > > 1 ) ;
2013-02-26 18:02:31 +04:00
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . otp_calib_hi =
( u16 ) vmain_high ;
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . otp_calib_lo =
( u16 ) vmain_low ;
2013-02-11 14:38:00 +04:00
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . gain = CALIB_SCALE *
( 19500 - 315 ) / ( vmain_high - vmain_low ) ;
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . offset = CALIB_SCALE *
19500 - ( CALIB_SCALE * ( 19500 - 315 ) /
( vmain_high - vmain_low ) ) * vmain_high ;
} else {
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . gain = 0 ;
}
2011-03-05 13:46:37 +03:00
}
/* Calculate gain and offset for BTEMP if all reads succeeded */
if ( ! ( ret [ 2 ] < 0 | | ret [ 3 ] < 0 | | ret [ 4 ] < 0 ) ) {
btemp_high = ( ( ( gpadc_cal [ 2 ] & 0x01 ) < < 9 ) |
2013-02-11 14:38:00 +04:00
( gpadc_cal [ 3 ] < < 1 ) | ( ( gpadc_cal [ 4 ] & 0x80 ) > > 7 ) ) ;
2011-03-05 13:46:37 +03:00
btemp_low = ( ( gpadc_cal [ 4 ] & 0x7C ) > > 2 ) ;
2013-02-26 18:02:31 +04:00
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . otp_calib_hi = ( u16 ) btemp_high ;
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . otp_calib_lo = ( u16 ) btemp_low ;
2011-03-05 13:46:37 +03:00
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . gain =
CALIB_SCALE * ( 1300 - 21 ) / ( btemp_high - btemp_low ) ;
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . offset = CALIB_SCALE * 1300 -
2013-02-11 14:38:00 +04:00
( CALIB_SCALE * ( 1300 - 21 ) / ( btemp_high - btemp_low ) )
* btemp_high ;
2011-03-05 13:46:37 +03:00
} else {
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . gain = 0 ;
}
/* Calculate gain and offset for VBAT if all reads succeeded */
if ( ! ( ret [ 4 ] < 0 | | ret [ 5 ] < 0 | | ret [ 6 ] < 0 ) ) {
vbat_high = ( ( ( gpadc_cal [ 4 ] & 0x03 ) < < 8 ) | gpadc_cal [ 5 ] ) ;
vbat_low = ( ( gpadc_cal [ 6 ] & 0xFC ) > > 2 ) ;
2013-02-26 18:02:31 +04:00
gpadc - > cal_data [ ADC_INPUT_VBAT ] . otp_calib_hi = ( u16 ) vbat_high ;
gpadc - > cal_data [ ADC_INPUT_VBAT ] . otp_calib_lo = ( u16 ) vbat_low ;
2011-03-05 13:46:37 +03:00
gpadc - > cal_data [ ADC_INPUT_VBAT ] . gain = CALIB_SCALE *
( 4700 - 2380 ) / ( vbat_high - vbat_low ) ;
gpadc - > cal_data [ ADC_INPUT_VBAT ] . offset = CALIB_SCALE * 4700 -
( CALIB_SCALE * ( 4700 - 2380 ) /
( vbat_high - vbat_low ) ) * vbat_high ;
} else {
gpadc - > cal_data [ ADC_INPUT_VBAT ] . gain = 0 ;
}
dev_dbg ( gpadc - > dev , " VMAIN gain %llu offset %llu \n " ,
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . gain ,
gpadc - > cal_data [ ADC_INPUT_VMAIN ] . offset ) ;
dev_dbg ( gpadc - > dev , " BTEMP gain %llu offset %llu \n " ,
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . gain ,
gpadc - > cal_data [ ADC_INPUT_BTEMP ] . offset ) ;
dev_dbg ( gpadc - > dev , " VBAT gain %llu offset %llu \n " ,
gpadc - > cal_data [ ADC_INPUT_VBAT ] . gain ,
gpadc - > cal_data [ ADC_INPUT_VBAT ] . offset ) ;
}
2014-12-05 05:04:12 +03:00
# ifdef CONFIG_PM
2013-02-04 12:33:13 +04:00
static int ab8500_gpadc_runtime_suspend ( struct device * dev )
{
struct ab8500_gpadc * gpadc = dev_get_drvdata ( dev ) ;
regulator_disable ( gpadc - > regu ) ;
return 0 ;
}
static int ab8500_gpadc_runtime_resume ( struct device * dev )
{
struct ab8500_gpadc * gpadc = dev_get_drvdata ( dev ) ;
2013-03-09 13:46:45 +04:00
int ret ;
2013-02-04 12:33:13 +04:00
2013-03-09 13:46:45 +04:00
ret = regulator_enable ( gpadc - > regu ) ;
if ( ret )
dev_err ( dev , " Failed to enable vtvout LDO: %d \n " , ret ) ;
return ret ;
2013-02-04 12:33:13 +04:00
}
2013-08-02 09:20:51 +04:00
# endif
2013-02-04 12:33:13 +04:00
2013-08-02 09:21:26 +04:00
# ifdef CONFIG_PM_SLEEP
2012-04-12 10:15:05 +04:00
static int ab8500_gpadc_suspend ( struct device * dev )
{
struct ab8500_gpadc * gpadc = dev_get_drvdata ( dev ) ;
mutex_lock ( & gpadc - > ab8500_gpadc_lock ) ;
pm_runtime_get_sync ( dev ) ;
regulator_disable ( gpadc - > regu ) ;
return 0 ;
}
static int ab8500_gpadc_resume ( struct device * dev )
{
struct ab8500_gpadc * gpadc = dev_get_drvdata ( dev ) ;
2013-05-02 18:46:34 +04:00
int ret ;
2012-04-12 10:15:05 +04:00
2013-05-02 18:46:34 +04:00
ret = regulator_enable ( gpadc - > regu ) ;
if ( ret )
dev_err ( dev , " Failed to enable vtvout LDO: %d \n " , ret ) ;
2012-04-12 10:15:05 +04:00
pm_runtime_mark_last_busy ( gpadc - > dev ) ;
pm_runtime_put_autosuspend ( gpadc - > dev ) ;
mutex_unlock ( & gpadc - > ab8500_gpadc_lock ) ;
2013-05-02 18:46:34 +04:00
return ret ;
2012-04-12 10:15:05 +04:00
}
2013-08-02 09:21:26 +04:00
# endif
2012-04-12 10:15:05 +04:00
2012-11-19 22:23:04 +04:00
static int ab8500_gpadc_probe ( struct platform_device * pdev )
2011-02-22 12:11:13 +03:00
{
int ret = 0 ;
struct ab8500_gpadc * gpadc ;
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
gpadc = devm_kzalloc ( & pdev - > dev ,
sizeof ( struct ab8500_gpadc ) , GFP_KERNEL ) ;
if ( ! gpadc )
2011-02-22 12:11:13 +03:00
return - ENOMEM ;
2013-02-26 14:06:55 +04:00
gpadc - > irq_sw = platform_get_irq_byname ( pdev , " SW_CONV_END " ) ;
2013-02-12 19:04:09 +04:00
if ( gpadc - > irq_sw < 0 )
dev_err ( gpadc - > dev , " failed to get platform sw_conv_end irq \n " ) ;
2013-02-26 14:06:55 +04:00
gpadc - > irq_hw = platform_get_irq_byname ( pdev , " HW_CONV_END " ) ;
2013-02-12 19:04:09 +04:00
if ( gpadc - > irq_hw < 0 )
dev_err ( gpadc - > dev , " failed to get platform hw_conv_end irq \n " ) ;
2011-02-22 12:11:13 +03:00
gpadc - > dev = & pdev - > dev ;
2012-02-09 15:06:47 +04:00
gpadc - > parent = dev_get_drvdata ( pdev - > dev . parent ) ;
2011-03-05 13:46:13 +03:00
mutex_init ( & gpadc - > ab8500_gpadc_lock ) ;
2011-02-22 12:11:13 +03:00
/* Initialize completion used to notify completion of conversion */
init_completion ( & gpadc - > ab8500_gpadc_complete ) ;
2013-02-26 14:06:55 +04:00
/* Register interrupts */
2013-02-12 19:04:09 +04:00
if ( gpadc - > irq_sw > = 0 ) {
ret = request_threaded_irq ( gpadc - > irq_sw , NULL ,
ab8500_bm_gpadcconvend_handler ,
2015-05-16 21:42:16 +03:00
IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT ,
" ab8500-gpadc-sw " ,
2013-02-12 19:04:09 +04:00
gpadc ) ;
if ( ret < 0 ) {
dev_err ( gpadc - > dev ,
" Failed to register interrupt irq: %d \n " ,
gpadc - > irq_sw ) ;
goto fail ;
}
2013-02-26 14:06:55 +04:00
}
2013-02-12 19:04:09 +04:00
if ( gpadc - > irq_hw > = 0 ) {
ret = request_threaded_irq ( gpadc - > irq_hw , NULL ,
ab8500_bm_gpadcconvend_handler ,
2015-05-16 21:42:16 +03:00
IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT ,
" ab8500-gpadc-hw " ,
2013-02-12 19:04:09 +04:00
gpadc ) ;
if ( ret < 0 ) {
dev_err ( gpadc - > dev ,
" Failed to register interrupt irq: %d \n " ,
gpadc - > irq_hw ) ;
goto fail_irq ;
}
2011-02-22 12:11:13 +03:00
}
/* VTVout LDO used to power up ab8500-GPADC */
2013-03-09 13:46:45 +04:00
gpadc - > regu = devm_regulator_get ( & pdev - > dev , " vddadc " ) ;
2011-02-22 12:11:13 +03:00
if ( IS_ERR ( gpadc - > regu ) ) {
ret = PTR_ERR ( gpadc - > regu ) ;
dev_err ( gpadc - > dev , " failed to get vtvout LDO \n " ) ;
2011-03-05 13:46:27 +03:00
goto fail_irq ;
2011-02-22 12:11:13 +03:00
}
2013-02-04 12:33:13 +04:00
platform_set_drvdata ( pdev , gpadc ) ;
2013-03-09 13:46:45 +04:00
ret = regulator_enable ( gpadc - > regu ) ;
if ( ret ) {
dev_err ( gpadc - > dev , " Failed to enable vtvout LDO: %d \n " , ret ) ;
goto fail_enable ;
}
2013-02-04 12:33:13 +04:00
pm_runtime_set_autosuspend_delay ( gpadc - > dev , GPADC_AUDOSUSPEND_DELAY ) ;
pm_runtime_use_autosuspend ( gpadc - > dev ) ;
pm_runtime_set_active ( gpadc - > dev ) ;
pm_runtime_enable ( gpadc - > dev ) ;
2011-03-05 13:46:37 +03:00
ab8500_gpadc_read_calibration_data ( gpadc ) ;
2011-03-05 13:46:13 +03:00
list_add_tail ( & gpadc - > node , & ab8500_gpadc_list ) ;
2011-02-22 12:11:13 +03:00
dev_dbg ( gpadc - > dev , " probe success \n " ) ;
2013-02-12 19:04:09 +04:00
2011-02-22 12:11:13 +03:00
return 0 ;
2013-03-09 13:46:45 +04:00
fail_enable :
2011-03-05 13:46:27 +03:00
fail_irq :
2013-02-26 14:06:55 +04:00
free_irq ( gpadc - > irq_sw , gpadc ) ;
free_irq ( gpadc - > irq_hw , gpadc ) ;
2011-02-22 12:11:13 +03:00
fail :
return ret ;
}
2012-11-19 22:26:01 +04:00
static int ab8500_gpadc_remove ( struct platform_device * pdev )
2011-02-22 12:11:13 +03:00
{
struct ab8500_gpadc * gpadc = platform_get_drvdata ( pdev ) ;
2011-03-05 13:46:13 +03:00
/* remove this gpadc entry from the list */
list_del ( & gpadc - > node ) ;
2011-02-22 12:11:13 +03:00
/* remove interrupt - completion of Sw ADC conversion */
2013-02-12 19:04:09 +04:00
if ( gpadc - > irq_sw > = 0 )
free_irq ( gpadc - > irq_sw , gpadc ) ;
if ( gpadc - > irq_hw > = 0 )
free_irq ( gpadc - > irq_hw , gpadc ) ;
2013-02-04 12:33:13 +04:00
pm_runtime_get_sync ( gpadc - > dev ) ;
pm_runtime_disable ( gpadc - > dev ) ;
regulator_disable ( gpadc - > regu ) ;
pm_runtime_set_suspended ( gpadc - > dev ) ;
pm_runtime_put_noidle ( gpadc - > dev ) ;
2011-02-22 12:11:13 +03:00
return 0 ;
}
2013-02-04 12:33:13 +04:00
static const struct dev_pm_ops ab8500_gpadc_pm_ops = {
SET_RUNTIME_PM_OPS ( ab8500_gpadc_runtime_suspend ,
ab8500_gpadc_runtime_resume ,
PM / Runtime: Rework the "runtime idle" helper routine
The "runtime idle" helper routine, rpm_idle(), currently ignores
return values from .runtime_idle() callbacks executed by it.
However, it turns out that many subsystems use
pm_generic_runtime_idle() which checks the return value of the
driver's callback and executes pm_runtime_suspend() for the device
unless that value is not 0. If that logic is moved to rpm_idle()
instead, pm_generic_runtime_idle() can be dropped and its users
will not need any .runtime_idle() callbacks any more.
Moreover, the PCI, SCSI, and SATA subsystems' .runtime_idle()
routines, pci_pm_runtime_idle(), scsi_runtime_idle(), and
ata_port_runtime_idle(), respectively, as well as a few drivers'
ones may be simplified if rpm_idle() calls rpm_suspend() after 0 has
been returned by the .runtime_idle() callback executed by it.
To reduce overall code bloat, make the changes described above.
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Kevin Hilman <khilman@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
2013-06-03 23:49:52 +04:00
NULL )
2012-04-12 10:15:05 +04:00
SET_SYSTEM_SLEEP_PM_OPS ( ab8500_gpadc_suspend ,
ab8500_gpadc_resume )
2013-02-04 12:33:13 +04:00
} ;
2011-02-22 12:11:13 +03:00
static struct platform_driver ab8500_gpadc_driver = {
. probe = ab8500_gpadc_probe ,
2012-11-19 22:20:24 +04:00
. remove = ab8500_gpadc_remove ,
2011-02-22 12:11:13 +03:00
. driver = {
. name = " ab8500-gpadc " ,
2013-02-04 12:33:13 +04:00
. pm = & ab8500_gpadc_pm_ops ,
2011-02-22 12:11:13 +03:00
} ,
} ;
static int __init ab8500_gpadc_init ( void )
{
return platform_driver_register ( & ab8500_gpadc_driver ) ;
}
2016-10-30 04:24:38 +03:00
subsys_initcall_sync ( ab8500_gpadc_init ) ;
2011-02-22 12:11:13 +03:00
2013-02-26 18:02:31 +04:00
/**
* ab8540_gpadc_get_otp ( ) - returns OTP values
*
*/
void ab8540_gpadc_get_otp ( struct ab8500_gpadc * gpadc ,
u16 * vmain_l , u16 * vmain_h , u16 * btemp_l , u16 * btemp_h ,
u16 * vbat_l , u16 * vbat_h , u16 * ibat_l , u16 * ibat_h )
{
* vmain_l = gpadc - > cal_data [ ADC_INPUT_VMAIN ] . otp_calib_lo ;
* vmain_h = gpadc - > cal_data [ ADC_INPUT_VMAIN ] . otp_calib_hi ;
* btemp_l = gpadc - > cal_data [ ADC_INPUT_BTEMP ] . otp_calib_lo ;
* btemp_h = gpadc - > cal_data [ ADC_INPUT_BTEMP ] . otp_calib_hi ;
mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ib
t*/
WARNING: line over 80 characters
+#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
WARNING: suspect code indent for conditional statements (16, 20)
+ if (!strcmp(name, dev_name(gpadc->dev)))
+ return gpadc;
WARNING: suspect code indent for conditional statements (0, 16)
+if (ad_value < 0) {
+ dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
WARNING: quoted string split across lines
+ dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
+ " %d AD: 0x%x\n", channel, ad_value);
WARNING: Missing a blank line after declarations
+ int raw_data;
+ raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
WARNING: msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt
+ msleep(10);
ERROR: else should follow close brace '}'
+ }
+ else
WARNING: line over 80 characters
+ delay_max = 10000; /* large range to optimise sleep mode */
WARNING: line over 80 characters
+ gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
WARNING: line over 80 characters
+ gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
WARNING: Possible unnecessary 'out of memory' message
+ if (!gpadc) {
+ dev_err(&pdev->dev, "Error: No memory\n");
WARNING: space prohibited before semicolon
+ return ;
WARNING: void function return statements are not generally useful
+ return ;
+}
WARNING: quoted string split across lines
+MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
+ "M'boumba Cedric Madianga");
total: 1 errors, 14 warnings, 1089 lines checked
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
2015-10-28 13:32:10 +03:00
* vbat_l = gpadc - > cal_data [ ADC_INPUT_VBAT ] . otp_calib_lo ;
* vbat_h = gpadc - > cal_data [ ADC_INPUT_VBAT ] . otp_calib_hi ;
* ibat_l = gpadc - > cal_data [ ADC_INPUT_IBAT ] . otp_calib_lo ;
* ibat_h = gpadc - > cal_data [ ADC_INPUT_IBAT ] . otp_calib_hi ;
2013-02-26 18:02:31 +04:00
}