summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorJonghwa Lee <jonghwa3.lee@samsung.com>2013-10-22 17:35:58 +0900
committerChanho Park <chanho61.park@samsung.com>2014-11-18 11:44:58 +0900
commita51c738a2af8107e391114d73ae5c79c383b2732 (patch)
tree63ed3806eb4105fa3139ea727b7c0a2694607c04 /drivers/power
parent47e614255e64ed56e6661021bcaacc5447f8ca1d (diff)
downloadlinux-3.10-a51c738a2af8107e391114d73ae5c79c383b2732.tar.gz
linux-3.10-a51c738a2af8107e391114d73ae5c79c383b2732.tar.bz2
linux-3.10-a51c738a2af8107e391114d73ae5c79c383b2732.zip
charger-manager : Add default battery temperature checking funtion.
During the charger manager driver's probing time, it can't succeed if there's no pre-defined .temperature_out_of_range callback function. But if fuel gauge supports battery temperature measurement, we can use it directly. That's what cm_default_get_temp() function does. With flag measure_batter_temp ON, we normally use cm_default_get_temp() for .temperature_out_of_range callback funtion. The TEMP_AMBIENT property is only used for pre-defined one. Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/charger-manager.c97
1 files changed, 79 insertions, 18 deletions
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index 1e2201f5a51..108c00c771b 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -552,7 +552,7 @@ static int check_charging_duration(struct charger_manager *cm)
static bool _cm_monitor(struct charger_manager *cm)
{
struct charger_desc *desc = cm->desc;
- int temp = desc->temperature_out_of_range(&cm->last_temp_mC);
+ int temp = desc->temperature_out_of_range(cm);
dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n",
cm->last_temp_mC / 1000, cm->last_temp_mC % 1000);
@@ -804,18 +804,19 @@ static int charger_get_property(struct power_supply *psy,
POWER_SUPPLY_PROP_CURRENT_NOW, val);
break;
case POWER_SUPPLY_PROP_TEMP:
- /* in thenth of centigrade */
+ /* in tenth of centigrade */
if (cm->last_temp_mC == INT_MIN)
- desc->temperature_out_of_range(&cm->last_temp_mC);
- val->intval = cm->last_temp_mC / 100;
+ desc->temperature_out_of_range(cm);
+
+ val->intval = cm->last_temp_mC;
if (!desc->measure_battery_temp)
ret = -ENODEV;
break;
case POWER_SUPPLY_PROP_TEMP_AMBIENT:
- /* in thenth of centigrade */
+ /* in tenth of centigrade */
if (cm->last_temp_mC == INT_MIN)
- desc->temperature_out_of_range(&cm->last_temp_mC);
- val->intval = cm->last_temp_mC / 100;
+ desc->temperature_out_of_range(cm);
+ val->intval = cm->last_temp_mC;
if (desc->measure_battery_temp)
ret = -ENODEV;
break;
@@ -1461,16 +1462,75 @@ err:
return ret;
}
+/* Every temperature units are in milli centigrade */
+#define CM_DEFAULT_TEMP_ALERT_DIFF 10000
+#define CM_DEFAULT_TEMP_ALERT_MAX 127000
+#define CM_DEFAULT_TEMP_ALERT_MIN (-127000)
+
+static int cm_default_get_temp(struct charger_manager *cm)
+{
+ struct charger_desc *desc = cm->desc;
+ union power_supply_propval val;
+ static int temp_alert_min = 0;
+ static int temp_alert_max = 0;
+ static int temp_alert_diff = 0;
+ static int last_temp_status = 0;
+ int ret;
+
+ if (!temp_alert_min && !temp_alert_max) {
+ /* Initialize minimum temperature for alert */
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
+ &val);
+ temp_alert_min = ret ? desc->temp_alert_min :
+ min(desc->temp_alert_min, val.intval);
+ if (!temp_alert_min)
+ temp_alert_min = CM_DEFAULT_TEMP_ALERT_MIN;
+
+ /* Initialize maximum temperature for alert */
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
+ &val);
+ temp_alert_max = ret ? desc->temp_alert_max :
+ min(desc->temp_alert_max, val.intval);
+ if (!temp_alert_max)
+ temp_alert_max = CM_DEFAULT_TEMP_ALERT_MAX;
+
+ temp_alert_diff = desc->temp_alert_diff ?
+ : CM_DEFAULT_TEMP_ALERT_DIFF;
+ }
+
+ /* Get battery temperature */
+ ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
+ POWER_SUPPLY_PROP_TEMP,
+ &val);
+ if (ret) {
+ cm->last_temp_mC = INT_MIN;
+ return 0;
+ }
+
+ cm->last_temp_mC = val.intval;
+
+ if (cm->last_temp_mC > temp_alert_max || (last_temp_status &&
+ cm->last_temp_mC + temp_alert_diff > temp_alert_max)) {
+ /* OVERHEAT */
+ last_temp_status = 1;
+ } else if (cm->last_temp_mC < temp_alert_min || (last_temp_status &&
+ cm->last_temp_mC < temp_alert_min + temp_alert_diff)) {
+ /* Too COLD */
+ last_temp_status = -1;
+ } else {
+ last_temp_status = 0;
+ }
+
+ return last_temp_status;
+}
+
/*
* Charger driver platform data
* To do : Should be transferred to DT.
*/
-static int thermistor_ck(int *mC)
-{
- return 0;
-}
-
static char *charger_stats[] = {
#if defined(CONFIG_CHARGER_MAX77693)
"max77693-charger",
@@ -1537,7 +1597,6 @@ static struct charger_desc cm_drv_data = {
.charger_regulators = regulators,
.num_charger_regulators = ARRAY_SIZE(regulators),
- .temperature_out_of_range = thermistor_ck,
.measure_battery_temp = true,
.charging_max_duration_ms = (6 * 60 * 60 * 1000), /* 6hr */
@@ -1674,11 +1733,6 @@ static int charger_manager_probe(struct platform_device *pdev)
return -EINVAL;
}
- if (!desc->temperature_out_of_range) {
- dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
- return -EINVAL;
- }
-
if (!desc->charging_max_duration_ms ||
!desc->discharging_max_duration_ms) {
dev_info(&pdev->dev, "Cannot limit charging duration "
@@ -1723,7 +1777,14 @@ static int charger_manager_probe(struct platform_device *pdev)
if (desc->measure_battery_temp) {
cm_chg_add_property(POWER_SUPPLY_PROP_TEMP);
+ desc->temperature_out_of_range = cm_default_get_temp;
} else {
+ if (!desc->temperature_out_of_range) {
+ dev_err(&pdev->dev,
+ "%s : No battery thermometer exists\n",
+ __func__);
+ return -EINVAL;
+ }
cm_chg_add_property(POWER_SUPPLY_PROP_TEMP_AMBIENT);
}