|
@@ -107,6 +107,7 @@ static bool is_batt_present(struct charger_manager *cm)
|
|
|
&val);
|
|
&val);
|
|
|
if (ret == 0 && val.intval)
|
|
if (ret == 0 && val.intval)
|
|
|
present = true;
|
|
present = true;
|
|
|
|
|
+ power_supply_put(psy);
|
|
|
break;
|
|
break;
|
|
|
case CM_CHARGER_STAT:
|
|
case CM_CHARGER_STAT:
|
|
|
for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
|
|
for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
|
|
@@ -120,6 +121,7 @@ static bool is_batt_present(struct charger_manager *cm)
|
|
|
|
|
|
|
|
ret = power_supply_get_property(psy,
|
|
ret = power_supply_get_property(psy,
|
|
|
POWER_SUPPLY_PROP_PRESENT, &val);
|
|
POWER_SUPPLY_PROP_PRESENT, &val);
|
|
|
|
|
+ power_supply_put(psy);
|
|
|
if (ret == 0 && val.intval) {
|
|
if (ret == 0 && val.intval) {
|
|
|
present = true;
|
|
present = true;
|
|
|
break;
|
|
break;
|
|
@@ -157,6 +159,7 @@ static bool is_ext_pwr_online(struct charger_manager *cm)
|
|
|
|
|
|
|
|
ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE,
|
|
ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE,
|
|
|
&val);
|
|
&val);
|
|
|
|
|
+ power_supply_put(psy);
|
|
|
if (ret == 0 && val.intval) {
|
|
if (ret == 0 && val.intval) {
|
|
|
online = true;
|
|
online = true;
|
|
|
break;
|
|
break;
|
|
@@ -186,6 +189,7 @@ static int get_batt_uV(struct charger_manager *cm, int *uV)
|
|
|
|
|
|
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
|
|
POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
|
|
|
|
|
+ power_supply_put(fuel_gauge);
|
|
|
if (ret)
|
|
if (ret)
|
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
|
@@ -229,10 +233,13 @@ static bool is_charging(struct charger_manager *cm)
|
|
|
if (ret) {
|
|
if (ret) {
|
|
|
dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
|
|
dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
|
|
|
cm->desc->psy_charger_stat[i]);
|
|
cm->desc->psy_charger_stat[i]);
|
|
|
|
|
+ power_supply_put(psy);
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- if (val.intval == 0)
|
|
|
|
|
|
|
+ if (val.intval == 0) {
|
|
|
|
|
+ power_supply_put(psy);
|
|
|
continue;
|
|
continue;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
|
* 3. The charger should not be FULL, DISCHARGING,
|
|
* 3. The charger should not be FULL, DISCHARGING,
|
|
@@ -240,6 +247,7 @@ static bool is_charging(struct charger_manager *cm)
|
|
|
*/
|
|
*/
|
|
|
ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS,
|
|
ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS,
|
|
|
&val);
|
|
&val);
|
|
|
|
|
+ power_supply_put(psy);
|
|
|
if (ret) {
|
|
if (ret) {
|
|
|
dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
|
|
dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
|
|
|
cm->desc->psy_charger_stat[i]);
|
|
cm->desc->psy_charger_stat[i]);
|
|
@@ -267,6 +275,7 @@ static bool is_full_charged(struct charger_manager *cm)
|
|
|
struct charger_desc *desc = cm->desc;
|
|
struct charger_desc *desc = cm->desc;
|
|
|
union power_supply_propval val;
|
|
union power_supply_propval val;
|
|
|
struct power_supply *fuel_gauge;
|
|
struct power_supply *fuel_gauge;
|
|
|
|
|
+ bool is_full = false;
|
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
int uV;
|
|
int uV;
|
|
|
|
|
|
|
@@ -284,15 +293,19 @@ static bool is_full_charged(struct charger_manager *cm)
|
|
|
/* Not full if capacity of fuel gauge isn't full */
|
|
/* Not full if capacity of fuel gauge isn't full */
|
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CHARGE_FULL, &val);
|
|
POWER_SUPPLY_PROP_CHARGE_FULL, &val);
|
|
|
- if (!ret && val.intval > desc->fullbatt_full_capacity)
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ if (!ret && val.intval > desc->fullbatt_full_capacity) {
|
|
|
|
|
+ is_full = true;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Full, if it's over the fullbatt voltage */
|
|
/* Full, if it's over the fullbatt voltage */
|
|
|
if (desc->fullbatt_uV > 0) {
|
|
if (desc->fullbatt_uV > 0) {
|
|
|
ret = get_batt_uV(cm, &uV);
|
|
ret = get_batt_uV(cm, &uV);
|
|
|
- if (!ret && uV >= desc->fullbatt_uV)
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ if (!ret && uV >= desc->fullbatt_uV) {
|
|
|
|
|
+ is_full = true;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Full, if the capacity is more than fullbatt_soc */
|
|
/* Full, if the capacity is more than fullbatt_soc */
|
|
@@ -301,11 +314,15 @@ static bool is_full_charged(struct charger_manager *cm)
|
|
|
|
|
|
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CAPACITY, &val);
|
|
POWER_SUPPLY_PROP_CAPACITY, &val);
|
|
|
- if (!ret && val.intval >= desc->fullbatt_soc)
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ if (!ret && val.intval >= desc->fullbatt_soc) {
|
|
|
|
|
+ is_full = true;
|
|
|
|
|
+ goto out;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+out:
|
|
|
|
|
+ power_supply_put(fuel_gauge);
|
|
|
|
|
+ return is_full;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -578,14 +595,18 @@ static int cm_get_battery_temperature_by_psy(struct charger_manager *cm,
|
|
|
int *temp)
|
|
int *temp)
|
|
|
{
|
|
{
|
|
|
struct power_supply *fuel_gauge;
|
|
struct power_supply *fuel_gauge;
|
|
|
|
|
+ int ret;
|
|
|
|
|
|
|
|
fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
if (!fuel_gauge)
|
|
if (!fuel_gauge)
|
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
- return power_supply_get_property(fuel_gauge,
|
|
|
|
|
|
|
+ ret = power_supply_get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_TEMP,
|
|
POWER_SUPPLY_PROP_TEMP,
|
|
|
(union power_supply_propval *)temp);
|
|
(union power_supply_propval *)temp);
|
|
|
|
|
+ power_supply_put(fuel_gauge);
|
|
|
|
|
+
|
|
|
|
|
+ return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static int cm_get_battery_temperature(struct charger_manager *cm,
|
|
static int cm_get_battery_temperature(struct charger_manager *cm,
|
|
@@ -866,7 +887,7 @@ static int charger_get_property(struct power_supply *psy,
|
|
|
{
|
|
{
|
|
|
struct charger_manager *cm = power_supply_get_drvdata(psy);
|
|
struct charger_manager *cm = power_supply_get_drvdata(psy);
|
|
|
struct charger_desc *desc = cm->desc;
|
|
struct charger_desc *desc = cm->desc;
|
|
|
- struct power_supply *fuel_gauge;
|
|
|
|
|
|
|
+ struct power_supply *fuel_gauge = NULL;
|
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
int uV;
|
|
int uV;
|
|
|
|
|
|
|
@@ -909,18 +930,18 @@ static int charger_get_property(struct power_supply *psy,
|
|
|
case POWER_SUPPLY_PROP_TEMP_AMBIENT:
|
|
case POWER_SUPPLY_PROP_TEMP_AMBIENT:
|
|
|
return cm_get_battery_temperature(cm, &val->intval);
|
|
return cm_get_battery_temperature(cm, &val->intval);
|
|
|
case POWER_SUPPLY_PROP_CAPACITY:
|
|
case POWER_SUPPLY_PROP_CAPACITY:
|
|
|
- fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
|
|
- if (!fuel_gauge) {
|
|
|
|
|
- ret = -ENODEV;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (!is_batt_present(cm)) {
|
|
if (!is_batt_present(cm)) {
|
|
|
/* There is no battery. Assume 100% */
|
|
/* There is no battery. Assume 100% */
|
|
|
val->intval = 100;
|
|
val->intval = 100;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
|
|
+ if (!fuel_gauge) {
|
|
|
|
|
+ ret = -ENODEV;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
ret = power_supply_get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CAPACITY, val);
|
|
POWER_SUPPLY_PROP_CAPACITY, val);
|
|
|
if (ret)
|
|
if (ret)
|
|
@@ -995,6 +1016,8 @@ static int charger_get_property(struct power_supply *psy,
|
|
|
default:
|
|
default:
|
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
}
|
|
}
|
|
|
|
|
+ if (fuel_gauge)
|
|
|
|
|
+ power_supply_put(fuel_gauge);
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1676,13 +1699,7 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|
|
desc->psy_charger_stat[i]);
|
|
desc->psy_charger_stat[i]);
|
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
|
|
|
|
|
- if (!fuel_gauge) {
|
|
|
|
|
- dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
|
|
|
|
|
- desc->psy_fuel_gauge);
|
|
|
|
|
- return -ENODEV;
|
|
|
|
|
|
|
+ power_supply_put(psy);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (desc->polling_interval_ms == 0 ||
|
|
if (desc->polling_interval_ms == 0 ||
|
|
@@ -1722,6 +1739,12 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|
|
cm->charger_psy_desc.num_properties = psy_default.num_properties;
|
|
cm->charger_psy_desc.num_properties = psy_default.num_properties;
|
|
|
|
|
|
|
|
/* Find which optional psy-properties are available */
|
|
/* Find which optional psy-properties are available */
|
|
|
|
|
+ fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
|
|
|
|
|
+ if (!fuel_gauge) {
|
|
|
|
|
+ dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
|
|
|
|
|
+ desc->psy_fuel_gauge);
|
|
|
|
|
+ return -ENODEV;
|
|
|
|
|
+ }
|
|
|
if (!power_supply_get_property(fuel_gauge,
|
|
if (!power_supply_get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
|
|
POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
|
|
|
cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
|
|
cm->charger_psy_desc.properties[cm->charger_psy_desc.num_properties] =
|
|
@@ -1741,6 +1764,7 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|
|
dev_err(&pdev->dev, "Failed to initialize thermal data\n");
|
|
dev_err(&pdev->dev, "Failed to initialize thermal data\n");
|
|
|
cm->desc->measure_battery_temp = false;
|
|
cm->desc->measure_battery_temp = false;
|
|
|
}
|
|
}
|
|
|
|
|
+ power_supply_put(fuel_gauge);
|
|
|
|
|
|
|
|
INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
|
|
INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
|
|
|
|
|
|