hwmon: msm_adc: Calibrate HK/XOADC

Calibration for HK/XOADC is done once at init by
msm_adc before the first ADC reading is processed.

Calibration performed for every ADC read is expensive
and not recommended. Remove support to request
calibration by ADC clients.

Add stubs for pmic8058 xoadc functions to fix
featurization

Change-Id: I7f0e165bddaa49c5daf33df5ed77428ccc1434c5
Signed-off-by: Vijayakumar Muthuvel Manickam <vmuthuve@codeaurora.org>
diff --git a/drivers/hwmon/msm_adc.c b/drivers/hwmon/msm_adc.c
index 42bcd07..b8d581e 100644
--- a/drivers/hwmon/msm_adc.c
+++ b/drivers/hwmon/msm_adc.c
@@ -98,6 +98,8 @@
 /* Needed to support file_op interfaces */
 static struct msm_adc_drv *msm_adc_drv;
 
+static bool conv_first_request;
+
 static ssize_t msm_adc_show_curr(struct device *dev,
 				struct device_attribute *devattr, char *buf);
 
@@ -726,6 +728,16 @@
 	struct msm_adc_platform_data *pdata =
 					msm_adc_drv->pdev->dev.platform_data;
 	struct msm_adc_channels *channel = &pdata->channel[hwmon_chan];
+	int ret = 0;
+
+	if (conv_first_request) {
+		ret = pm8058_xoadc_calib_device(channel->adc_dev_instance);
+		if (ret) {
+			pr_err("pmic8058 xoadc calibration failed, retry\n");
+			return ret;
+		}
+		conv_first_request = false;
+	}
 
 	channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
 									&slot);
@@ -813,6 +825,16 @@
 					msm_adc_drv->pdev->dev.platform_data;
 	struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
 	struct adc_conv_slot *slot;
+	int ret;
+
+	if (conv_first_request) {
+		ret = pm8058_xoadc_calib_device(channel->adc_dev_instance);
+		if (ret) {
+			pr_err("pmic8058 xoadc calibration failed, retry\n");
+			return ret;
+		}
+		conv_first_request = false;
+	}
 
 	channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
 									&slot);
@@ -871,46 +893,6 @@
 	return rc;
 }
 
-int32_t adc_calib_request(void *h, struct completion *calib_complete_evt)
-{
-	struct msm_client_data *client = (struct msm_client_data *)h;
-	struct msm_adc_platform_data *pdata =
-					msm_adc_drv->pdev->dev.platform_data;
-	struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
-	struct adc_conv_slot *slot;
-	int rc, calib_status;
-
-	channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
-				&slot);
-	if (slot) {
-		slot->conv.result.chan = client->adc_chan;
-		slot->blocking = 0;
-		slot->compk = calib_complete_evt;
-		slot->adc_request = START_OF_CALIBRATION;
-		slot->chan_path = channel->chan_path_type;
-		slot->chan_adc_config = channel->adc_config_type;
-		slot->chan_adc_calib = channel->adc_calib_type;
-		rc = channel->adc_access_fn->adc_calibrate(
-			channel->adc_dev_instance, slot, &calib_status);
-
-		if (calib_status == CALIB_NOT_REQUIRED) {
-			channel->adc_access_fn->adc_restore_slot(
-					channel->adc_dev_instance, slot);
-			/* client will always wait in case when
-				calibration is not required */
-			complete(calib_complete_evt);
-		} else {
-			atomic_inc(&msm_adc_drv->total_outst);
-			mutex_lock(&client->lock);
-			client->num_outstanding++;
-			mutex_unlock(&client->lock);
-		}
-
-		return rc;
-	}
-	return -EBUSY;
-}
-
 static void msm_rpc_adc_conv_cb(void *context, u32 param,
 			    void *evt_buf, u32 len)
 {
@@ -1458,6 +1440,7 @@
 		else
 			msm_rpc_adc_init(pdev);
 	}
+	conv_first_request = true;
 
 	pr_info("msm_adc successfully registered\n");
 
diff --git a/drivers/thermal/pmic8058-tm.c b/drivers/thermal/pmic8058-tm.c
index cc98f37..2589494 100644
--- a/drivers/thermal/pmic8058-tm.c
+++ b/drivers/thermal/pmic8058-tm.c
@@ -351,7 +351,6 @@
 
 static int __devinit pmic8058_tm_probe(struct platform_device *pdev)
 {
-	DECLARE_COMPLETION_ONSTACK(wait);
 	struct pm8058_tm_device *tmdev;
 	struct pm8058_chip *pm_chip;
 	unsigned int irq;
@@ -382,10 +381,6 @@
 		return rc;
 	}
 
-	/* calibrate the die temperature sensor */
-	if (adc_calib_request(tmdev->adc_handle, &wait) == CALIB_STARTED)
-		wait_for_completion(&wait);
-
 	tmdev->pm_chip = pm_chip;
 	tmdev->tz_dev = thermal_zone_device_register("pm8058_tz",
 						     PM8058_TRIP_NUM, tmdev,
diff --git a/include/linux/msm_adc.h b/include/linux/msm_adc.h
index 9818cf0..5d5fb1b 100644
--- a/include/linux/msm_adc.h
+++ b/include/linux/msm_adc.h
@@ -343,7 +343,6 @@
 int32_t adc_channel_close(void *h);
 int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt);
 int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result);
-int32_t adc_calib_request(void *h, struct completion *calib_complete_evt);
 #else
 int32_t adc_channel_open(uint32_t channel, void **h)
 {
@@ -365,11 +364,6 @@
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_calib_request(void *h, struct completion *calib_complete_evt)
-{
-	pr_err("%s.not supported.\n", __func__);
-	return -ENODEV;
-}
 #endif /* CONFIG_SENSORS_MSM_ADC */
 #endif
 #endif /* __MSM_ADC_H */
diff --git a/include/linux/pmic8058-xoadc.h b/include/linux/pmic8058-xoadc.h
index 8a5820f..f72ad66 100644
--- a/include/linux/pmic8058-xoadc.h
+++ b/include/linux/pmic8058-xoadc.h
@@ -65,20 +65,57 @@
 	u32 xoadc_wakeup;
 };
 
-int32_t pm8058_xoadc_read_adc_code(uint32_t , int32_t *data);
+#ifdef CONFIG_PMIC8058_XOADC
+int32_t pm8058_xoadc_read_adc_code(uint32_t adc_instance, int32_t *data);
 
-int32_t pm8058_xoadc_select_chan_and_start_conv(uint32_t,
-						struct adc_conv_slot *);
+int32_t pm8058_xoadc_select_chan_and_start_conv(uint32_t adc_instance,
+						struct adc_conv_slot *slot);
 
-void pm8058_xoadc_slot_request(uint32_t, struct adc_conv_slot **slot);
+void pm8058_xoadc_slot_request(uint32_t adc_instance,
+		struct adc_conv_slot **slot);
 
-void pm8058_xoadc_restore_slot(uint32_t, struct adc_conv_slot *slot);
+void pm8058_xoadc_restore_slot(uint32_t adc_instance,
+		struct adc_conv_slot *slot);
 
-struct adc_properties *pm8058_xoadc_get_properties(uint32_t);
+struct adc_properties *pm8058_xoadc_get_properties(uint32_t dev_instance);
 
-int32_t pm8058_xoadc_calibrate(uint32_t, struct adc_conv_slot *, int *);
+int32_t pm8058_xoadc_calibrate(uint32_t dev_instance,
+		struct adc_conv_slot *slot, int * calib_status);
 
 int32_t pm8058_xoadc_registered(void);
 
 int32_t pm8058_xoadc_calib_device(uint32_t adc_instance);
+
+#else
+
+static inline int32_t pm8058_xoadc_read_adc_code(uint32_t adc_instance,
+		int32_t *data)
+{ return -ENXIO; }
+
+static inline int32_t pm8058_xoadc_select_chan_and_start_conv(
+		uint32_t adc_instance, struct adc_conv_slot *slot)
+{ return -ENXIO; }
+
+static inline void pm8058_xoadc_slot_request(uint32_t adc_instance,
+		struct adc_conv_slot **slot)
+{ return; }
+
+static inline void pm8058_xoadc_restore_slot(uint32_t adc_instance,
+		struct adc_conv_slot *slot)
+{ return; }
+
+static inline struct adc_properties *pm8058_xoadc_get_properties(
+		uint32_t dev_instance)
+{ return NULL; }
+
+static inline int32_t pm8058_xoadc_calibrate(uint32_t dev_instance,
+		struct adc_conv_slot *slot, int *calib_status)
+{ return -ENXIO; }
+
+static inline int32_t pm8058_xoadc_registered(void)
+{ return -ENXIO; }
+
+static inline int32_t pm8058_xoadc_calib_device(uint32_t adc_instance)
+{ return -ENXIO; }
+#endif
 #endif