power: pm8xxx-ccadc: implement quick calibration
There are certain systems that wakeup every so often to do some
housekeeping work. We don't want to run a full calibration
when the system wakeups.
For such systems runs a quick calibration with just two samples.
Use the periodic_wakeup flag to indicate such a system.
CRs-Fixed: 454221
Change-Id: Ifc86414f7fab4d0921e3289d6e52b9e077a1f625
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index 7e37daa..5313593 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -81,6 +81,7 @@
int r_sense_uohm;
struct delayed_work calib_ccadc_work;
struct mutex calib_mutex;
+ bool periodic_wakeup;
};
static struct pm8xxx_ccadc_chip *the_chip;
@@ -367,7 +368,7 @@
return 0;
}
-void pm8xxx_calib_ccadc(void)
+static void __pm8xxx_calib_ccadc(int sample_count)
{
u8 data_msb, data_lsb, sec_cntrl;
int result_offset, result_gain;
@@ -379,6 +380,8 @@
return;
}
+ pr_debug("sample_count = %d\n", sample_count);
+
mutex_lock(&the_chip->calib_mutex);
rc = pm8xxx_readb(the_chip->dev->parent,
ADC_ARB_SECP_CNTRL, &sec_cntrl);
@@ -405,7 +408,7 @@
}
result_offset = 0;
- for (i = 0; i < SAMPLE_COUNT; i++) {
+ for (i = 0; i < sample_count; i++) {
/* Short analog inputs to CCADC internally to ground */
rc = pm8xxx_writeb(the_chip->dev->parent, ADC_ARB_SECP_RSV,
CCADC_CALIB_RSV_GND);
@@ -431,7 +434,7 @@
result_offset += result;
}
- result_offset = result_offset / SAMPLE_COUNT;
+ result_offset = result_offset / sample_count;
pr_debug("offset result_offset = 0x%x, voltage = %llduV\n",
@@ -470,7 +473,7 @@
}
result_gain = 0;
- for (i = 0; i < SAMPLE_COUNT; i++) {
+ for (i = 0; i < sample_count; i++) {
rc = pm8xxx_writeb(the_chip->dev->parent,
ADC_ARB_SECP_RSV, CCADC_CALIB_RSV_25MV);
if (rc < 0) {
@@ -494,7 +497,7 @@
result_gain += result;
}
- result_gain = result_gain / SAMPLE_COUNT;
+ result_gain = result_gain / sample_count;
/*
* result_offset includes INTRINSIC OFFSET
@@ -519,6 +522,16 @@
calibration_unlock:
mutex_unlock(&the_chip->calib_mutex);
}
+
+static void pm8xxx_calib_ccadc_quick(void)
+{
+ __pm8xxx_calib_ccadc(2);
+}
+
+void pm8xxx_calib_ccadc(void)
+{
+ __pm8xxx_calib_ccadc(SAMPLE_COUNT);
+}
EXPORT_SYMBOL(pm8xxx_calib_ccadc);
static void calibrate_ccadc_work(struct work_struct *work)
@@ -737,6 +750,7 @@
chip->r_sense_uohm = pdata->r_sense_uohm;
chip->calib_delay_ms = pdata->calib_delay_ms;
chip->batt_temp_channel = pdata->ccadc_cdata.batt_temp_channel;
+ chip->periodic_wakeup = pdata->periodic_wakeup;
mutex_init(&chip->calib_mutex);
calib_ccadc_read_offset_and_gain(chip,
@@ -793,6 +807,12 @@
pr_err("unable to get current time: %d\n", rc);
return 0;
}
+
+ if (the_chip->periodic_wakeup) {
+ pm8xxx_calib_ccadc_quick();
+ return 0;
+ }
+
if (current_time_sec > the_chip->last_calib_time) {
time_since_last_calib = current_time_sec -
the_chip->last_calib_time;
@@ -803,9 +823,11 @@
|| delta_temp > CCADC_CALIB_TEMP_THRESH) {
the_chip->last_calib_time = current_time_sec;
the_chip->last_calib_temp = batt_temp;
- pm8xxx_calib_ccadc();
+ cancel_delayed_work(&the_chip->calib_ccadc_work);
+ schedule_delayed_work(&the_chip->calib_ccadc_work, 0);
}
}
+
return 0;
}