power: bms/ccadc: move ccadc calibration to ccadc driver

There is a dependency for the CCADC calibration work on the BMS
driver. This prevents some devices that do not use the BMS
to utilize the CCADC.

Remove this dependency by moving the ccadc calibration
work to the CCADC driver to avoid this.

Change-Id: If43c781d6d2bc27f64dbbe594b6e81c5a5642f0b
Signed-off-by: David Keitel <dkeitel@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index bef5cdc..fc886ed 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -364,6 +364,7 @@
 static struct pm8xxx_ccadc_platform_data
 apq8064_pm8xxx_ccadc_pdata = {
 	.r_sense		= 10,
+	.calib_delay_ms		= 600000,
 };
 
 static struct pm8921_bms_platform_data
@@ -372,7 +373,6 @@
 	.r_sense		= 10,
 	.i_test			= 2500,
 	.v_failure		= 3000,
-	.calib_delay_ms		= 600000,
 	.max_voltage_uv		= MAX_VOLTAGE_MV * 1000,
 };
 
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 188cf39..e6a13b1 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -328,6 +328,7 @@
 
 static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
 	.r_sense		= 10,
+	.calib_delay_ms		= 600000,
 };
 
 static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
@@ -343,7 +344,6 @@
 	.r_sense		= 10,
 	.i_test			= 2500,
 	.v_failure		= 3000,
-	.calib_delay_ms		= 600000,
 	.max_voltage_uv		= MAX_VOLTAGE_MV * 1000,
 };
 
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 977dbb2..fc924a8 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -442,7 +442,6 @@
 	.r_sense		= 10,
 	.i_test			= 2500,
 	.v_failure		= 3000,
-	.calib_delay_ms		= 600000,
 	.max_voltage_uv		= MAX_VOLTAGE_MV * 1000,
 	.rconn_mohm		= 30,
 };
@@ -567,6 +566,7 @@
 
 static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
 	.r_sense		= 10,
+	.calib_delay_ms		= 600000,
 };
 
 /**
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index b0439bc..73c042d 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -100,8 +100,6 @@
 	struct sf_lut		*rbatt_sf_lut;
 	int			delta_rbatt_mohm;
 	struct work_struct	calib_hkadc_work;
-	struct delayed_work	calib_ccadc_work;
-	unsigned int		calib_delay_ms;
 	unsigned int		revision;
 	unsigned int		xoadc_v0625_usb_present;
 	unsigned int		xoadc_v0625_usb_absent;
@@ -1604,18 +1602,6 @@
 	schedule_work(&the_chip->calib_hkadc_work);
 }
 
-static void calibrate_ccadc_work(struct work_struct *work)
-{
-	struct pm8921_bms_chip *chip = container_of(work,
-				struct pm8921_bms_chip, calib_ccadc_work.work);
-
-	pm8xxx_calib_ccadc();
-	calib_hkadc(chip);
-	schedule_delayed_work(&chip->calib_ccadc_work,
-			round_jiffies_relative(msecs_to_jiffies
-			(chip->calib_delay_ms)));
-}
-
 int pm8921_bms_get_vsense_avg(int *result)
 {
 	int rc = -EINVAL;
@@ -2601,7 +2587,6 @@
 	chip->r_sense = pdata->r_sense;
 	chip->i_test = pdata->i_test;
 	chip->v_failure = pdata->v_failure;
-	chip->calib_delay_ms = pdata->calib_delay_ms;
 	chip->max_voltage_uv = pdata->max_voltage_uv;
 	chip->batt_type = pdata->battery_type;
 	chip->rconn_mohm = pdata->rconn_mohm;
@@ -2655,11 +2640,6 @@
 	}
 	check_initial_ocv(chip);
 
-	INIT_DELAYED_WORK(&chip->calib_ccadc_work, calibrate_ccadc_work);
-	/* begin calibration only on chips > 2.0 */
-	if (chip->revision >= PM8XXX_REVISION_8921_2p0)
-		schedule_delayed_work(&chip->calib_ccadc_work, 0);
-
 	/* initial hkadc calibration */
 	schedule_work(&chip->calib_hkadc_work);
 	/* enable the vbatt reading interrupts for scheduling hkadc calib */
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index ce72a5b..ef31575 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -70,8 +70,10 @@
 	u16			ccadc_offset;
 	int			ccadc_gain_uv;
 	unsigned int		revision;
+	unsigned int		calib_delay_ms;
 	int			eoc_irq;
 	int			r_sense;
+	struct delayed_work	calib_ccadc_work;
 };
 
 static struct pm8xxx_ccadc_chip *the_chip;
@@ -334,6 +336,11 @@
 	u16 result;
 	int i, rc;
 
+	if (!the_chip) {
+		pr_err("chip not initialized\n");
+		return;
+	}
+
 	rc = pm8xxx_readb(the_chip->dev->parent,
 					ADC_ARB_SECP_CNTRL, &sec_cntrl);
 	if (rc < 0) {
@@ -473,6 +480,17 @@
 }
 EXPORT_SYMBOL(pm8xxx_calib_ccadc);
 
+static void calibrate_ccadc_work(struct work_struct *work)
+{
+	struct pm8xxx_ccadc_chip *chip = container_of(work,
+			struct pm8xxx_ccadc_chip, calib_ccadc_work.work);
+
+	pm8xxx_calib_ccadc();
+	schedule_delayed_work(&chip->calib_ccadc_work,
+			round_jiffies_relative(msecs_to_jiffies
+			(chip->calib_delay_ms)));
+}
+
 static irqreturn_t pm8921_bms_ccadc_eoc_handler(int irq, void *data)
 {
 	u8 data_msb, data_lsb;
@@ -671,6 +689,7 @@
 	chip->revision = pm8xxx_get_revision(chip->dev->parent);
 	chip->eoc_irq = res->start;
 	chip->r_sense = pdata->r_sense;
+	chip->calib_delay_ms = pdata->calib_delay_ms;
 
 	calib_ccadc_read_offset_and_gain(chip,
 					&chip->ccadc_gain_uv,
@@ -682,6 +701,10 @@
 		pr_err("failed to request %d irq rc= %d\n", chip->eoc_irq, rc);
 		goto free_chip;
 	}
+
+	INIT_DELAYED_WORK(&chip->calib_ccadc_work, calibrate_ccadc_work);
+	schedule_delayed_work(&chip->calib_ccadc_work, 0);
+
 	disable_irq_nosync(chip->eoc_irq);
 
 	platform_set_drvdata(pdev, chip);
diff --git a/include/linux/mfd/pm8xxx/ccadc.h b/include/linux/mfd/pm8xxx/ccadc.h
index 23d0fb0..0bd4cc3 100644
--- a/include/linux/mfd/pm8xxx/ccadc.h
+++ b/include/linux/mfd/pm8xxx/ccadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,9 +20,11 @@
 /**
  * struct pm8xxx_ccadc_platform_data -
  * @r_sense:		sense resistor value in (mOhms)
+ * @calib_delay_ms:	how often should the adc calculate gain and offset
  */
 struct pm8xxx_ccadc_platform_data {
-	int r_sense;
+	int		r_sense;
+	unsigned int	calib_delay_ms;
 };
 
 #define CCADC_READING_RESOLUTION_N_V1	1085069
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 537e0b5..90c2d99 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -117,7 +117,6 @@
  * @i_test:		current at which the unusable charger cutoff is to be
  *			calculated or the peak system current (mA)
  * @v_failure:		the voltage at which the battery is considered empty(mV)
- * @calib_delay_ms:	how often should the adc calculate gain and offset
  * @enable_fcc_learning:	if set the driver will learn full charge
  *				capacity of the battery upon end of charge
  */
@@ -127,7 +126,6 @@
 	unsigned int			r_sense;
 	unsigned int			i_test;
 	unsigned int			v_failure;
-	unsigned int			calib_delay_ms;
 	unsigned int			max_voltage_uv;
 	unsigned int			rconn_mohm;
 	int				enable_fcc_learning;