summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajagopala V <rajagopala.v@stericsson.com>2011-12-20 12:43:05 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:01:18 +0200
commit028210d984a5ca2dae29d4aebea90bfd98f0371b (patch)
tree569e581e13a97121312a9c3b90076d787a1c0e9a
parent3a3a2a4eb80d4ed20313afd53b2bd50f499af253 (diff)
power: ab5500-btemp: support btemp_ball node measurement
Support battery temperature measurement through btemp_ball node for btemp gpadc auto trigger. ST-Ericsson Linux next: NA ST-Ericsson ID: 372448 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I7e99a106a5840d21a108a0bae04e79f091bb26e1 Signed-off-by: Rajagopala V <rajagopala.v@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/43249 Reviewed-by: QABUILD Reviewed-by: Arun MURTHY <arun.murthy@stericsson.com> Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
-rw-r--r--drivers/mfd/ab5500-gpadc.c21
-rw-r--r--drivers/power/ab5500_btemp.c105
2 files changed, 74 insertions, 52 deletions
diff --git a/drivers/mfd/ab5500-gpadc.c b/drivers/mfd/ab5500-gpadc.c
index d099f1b9d73..4718e26bee8 100644
--- a/drivers/mfd/ab5500-gpadc.c
+++ b/drivers/mfd/ab5500-gpadc.c
@@ -134,6 +134,9 @@
#define ADC_RESOLUTION 1023
#define AUTO_ADC_RESOLUTION 255
+/* ADOUT prestart time */
+#define ADOUT0_TRIGX_PRESTART 0x18
+
enum adc_auto_channels {
ADC_INPUT_TRIG0 = 0,
ADC_INPUT_TRIG1,
@@ -350,7 +353,7 @@ int ab5500_gpadc_convert(struct ab5500_gpadc *gpadc, u8 input)
case BTEMP_BALL:
ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
AB5500_BANK_ADC, AB5500_GPADC_MANUAL_MODE_CTRL,
- MUX_SCALE_BDATA_MASK, MUX_SCALE_BDATA27);
+ MUX_SCALE_BDATA_MASK, MUX_SCALE_BDATA18);
if (ret < 0) {
dev_err(gpadc->dev, "gpadc: fail to set mux scale\n");
goto out;
@@ -425,6 +428,8 @@ int ab5500_gpadc_convert(struct ab5500_gpadc *gpadc, u8 input)
dev_err(gpadc->dev, "gpadc: fail to set ADOUT\n");
goto out;
}
+ /* delay required to ramp up voltage on BDATA node */
+ usleep_range(10000, 12000);
}
ret = abx500_set_register_interruptible(gpadc->dev, AB5500_BANK_ADC,
AB5500_GPADC_MANUAL_MUX_CTRL, adc_tab[input].mux);
@@ -533,6 +538,7 @@ static int ab5500_gpadc_program_auto(struct ab5500_gpadc *gpadc, int trig)
#define MIN_INDEX 0x02
#define MAX_INDEX 0x03
#define CTRL_INDEX 0x01
+
ret = abx500_set_register_interruptible(gpadc->dev, AB5500_BANK_ADC,
AB5500_GPADC_AUTO_TRIG_INDEX + (trig << 2) + MIN_INDEX,
gpadc->adc_trig[trig].trig_min);
@@ -709,7 +715,6 @@ int ab5500_gpadc_convert_auto(struct ab5500_gpadc *gpadc,
goto out;
}
switch (in->mux) {
- case BTEMP_BALL:
case MAIN_BAT_V:
/*
* The value of mux scale volatage depends
@@ -727,6 +732,18 @@ int ab5500_gpadc_convert_auto(struct ab5500_gpadc *gpadc,
"gpadc: failed to read status\n");
goto out;
}
+
+ case BTEMP_BALL:
+ ret = abx500_set_register_interruptible(
+ gpadc->dev, AB5500_BANK_ADC,
+ AB5500_GPADC_AUTO_TRIG_ADOUT0_CTRL,
+ ADOUT0_TRIGX_PRESTART);
+ if (ret < 0) {
+ dev_err(gpadc->dev,
+ "gpadc: failed to set prestart\n");
+ goto out;
+ }
+
case ACC_DETECT2:
case ACC_DETECT3:
case VBUS_V:
diff --git a/drivers/power/ab5500_btemp.c b/drivers/power/ab5500_btemp.c
index 3ce07f149e2..cfaab870cab 100644
--- a/drivers/power/ab5500_btemp.c
+++ b/drivers/power/ab5500_btemp.c
@@ -124,31 +124,32 @@ int ab5500_btemp_get_batctrl_temp(struct ab5500_btemp *di)
}
/**
- * ab5500_btemp_batctrl_volt_to_res() - convert batctrl voltage to resistance
+ * ab5500_btemp_volt_to_res() - convert batctrl voltage to resistance
* @di: pointer to the ab5500_btemp structure
- * @v_batctrl: measured batctrl voltage
+ * @volt: measured batctrl/btemp_ball voltage
+ * @batcrtl: batctrl/btemp_ball node
*
* This function returns the battery resistance that is
- * derived from the BATCTRL voltage.
+ * derived from the BATCTRL/BTEMP_BALL voltage.
* Returns value in Ohms.
*/
-static int ab5500_btemp_batctrl_volt_to_res(struct ab5500_btemp *di,
- int v_batctrl)
+static int ab5500_btemp_volt_to_res(struct ab5500_btemp *di,
+ int volt, bool batctrl)
{
int rbs;
- if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL) {
+ if (batctrl) {
/*
* If the battery has internal NTC, we use the current
* source to calculate the resistance, 7uA or 20uA
*/
- rbs = v_batctrl * 1000 / di->curr_source;
+ rbs = volt * 1000 / di->curr_source;
} else {
/*
- * BAT_CTRL is internally
+ * BTEMP_BALL is internally
* connected to 1.8V through a 10k resistor
*/
- rbs = (10000 * (v_batctrl)) / (1800 - v_batctrl);
+ rbs = (10000 * volt) / (1800 - volt);
}
return rbs;
}
@@ -266,7 +267,7 @@ static int ab5500_btemp_get_batctrl_res(struct ab5500_btemp *di)
}
batctrl = ab5500_btemp_read_batctrl_voltage(di);
- res = ab5500_btemp_batctrl_volt_to_res(di, batctrl);
+ res = ab5500_btemp_volt_to_res(di, batctrl, true);
ret = ab5500_btemp_curr_source_enable(di, false);
if (ret) {
@@ -281,6 +282,36 @@ static int ab5500_btemp_get_batctrl_res(struct ab5500_btemp *di)
}
/**
+ * ab5500_btemp_get_btemp_ball_res() - get battery resistance
+ * @di: pointer to the ab5500_btemp structure
+ *
+ * This function returns the battery pack identification
+ * resistance using resistor pull-up mode. Returns value in Ohms.
+ */
+static int ab5500_btemp_get_btemp_ball_res(struct ab5500_btemp *di)
+{
+ int ret, vntc;
+
+ ret = abx500_mask_and_set_register_interruptible(di->dev,
+ AB5500_BANK_FG_BATTCOM_ACC, AB5500_UART,
+ UART_MODE, ADOUT_10K_PULL_UP);
+ if (ret) {
+ dev_err(di->dev,
+ "failed to enable 10k pull up to Vadout\n");
+ return ret;
+ }
+
+ vntc = ab5500_gpadc_convert(di->gpadc, BTEMP_BALL);
+ if (vntc < 0) {
+ dev_err(di->dev, "%s gpadc conversion failed,"
+ " using previous value\n", __func__);
+ return vntc;
+ }
+
+ return ab5500_btemp_volt_to_res(di, vntc, false);
+}
+
+/**
* ab5500_btemp_res_to_temp() - resistance to temperature
* @di: pointer to the ab5500_btemp structure
* @tbl: pointer to the resiatance to temperature table
@@ -324,55 +355,29 @@ static int ab5500_btemp_res_to_temp(struct ab5500_btemp *di,
*/
static int ab5500_btemp_measure_temp(struct ab5500_btemp *di)
{
- int temp, ret;
- static int prev;
- int rbat, vntc;
- int rntc = 0;
+ int temp, rbat;
u8 id;
id = di->bat->batt_id;
if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL &&
- id != BATTERY_UNKNOWN && !di->bat->auto_trig) {
+ id != BATTERY_UNKNOWN && !di->bat->auto_trig)
rbat = ab5500_btemp_get_batctrl_res(di);
- if (rbat < 0) {
- dev_err(di->dev, "%s get batctrl res failed\n",
- __func__);
- /*
- * Return out-of-range temperature so that
- * charging is stopped
- */
- return BTEMP_THERMAL_LOW_LIMIT;
- }
+ else
+ rbat = ab5500_btemp_get_btemp_ball_res(di);
- temp = ab5500_btemp_res_to_temp(di,
- di->bat->bat_type[id].r_to_t_tbl,
- di->bat->bat_type[id].n_temp_tbl_elements, rbat);
- } else {
- ret = abx500_mask_and_set_register_interruptible(di->dev,
- AB5500_BANK_FG_BATTCOM_ACC, AB5500_UART,
- UART_MODE, ADOUT_10K_PULL_UP);
- if (ret) {
- dev_err(di->dev,
- "failed to enable 10k pull up to Vadout\n");
- }
- vntc = ab5500_gpadc_convert(di->gpadc, BTEMP_BALL);
- if (vntc < 0) {
- dev_err(di->dev,
- "%s gpadc conversion failed,"
- " using previous value\n", __func__);
- return prev;
- }
+ if (rbat < 0) {
+ dev_err(di->dev, "%s failed to get resistance\n", __func__);
/*
- * The PCB NTC is sourced from 2.75v via a 10kOhm
- * resistor.
+ * Return out-of-range temperature so that
+ * charging is stopped
*/
- rntc = 10000 * vntc / (27500 - vntc);
-
- temp = ab5500_btemp_res_to_temp(di,
- di->bat->bat_type[id].r_to_t_tbl,
- di->bat->bat_type[id].n_temp_tbl_elements, rntc);
- prev = temp;
+ return BTEMP_THERMAL_LOW_LIMIT;
}
+
+ temp = ab5500_btemp_res_to_temp(di,
+ di->bat->bat_type[id].r_to_t_tbl,
+ di->bat->bat_type[id].n_temp_tbl_elements, rbat);
+
dev_dbg(di->dev, "Battery temperature is %d\n", temp);
return temp;
}