|
@@ -97,6 +97,7 @@ static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
|
|
|
static bool is_batt_present(struct charger_manager *cm)
|
|
|
{
|
|
|
union power_supply_propval val;
|
|
|
+ struct power_supply *psy;
|
|
|
bool present = false;
|
|
|
int i, ret;
|
|
|
|
|
@@ -107,16 +108,27 @@ static bool is_batt_present(struct charger_manager *cm)
|
|
|
case CM_NO_BATTERY:
|
|
|
break;
|
|
|
case CM_FUEL_GAUGE:
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
+ if (!psy)
|
|
|
+ break;
|
|
|
+
|
|
|
+ ret = psy->get_property(psy,
|
|
|
POWER_SUPPLY_PROP_PRESENT, &val);
|
|
|
if (ret == 0 && val.intval)
|
|
|
present = true;
|
|
|
break;
|
|
|
case CM_CHARGER_STAT:
|
|
|
- for (i = 0; cm->charger_stat[i]; i++) {
|
|
|
- ret = cm->charger_stat[i]->get_property(
|
|
|
- cm->charger_stat[i],
|
|
|
- POWER_SUPPLY_PROP_PRESENT, &val);
|
|
|
+ for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
|
|
|
+ psy = power_supply_get_by_name(
|
|
|
+ cm->desc->psy_charger_stat[i]);
|
|
|
+ if (!psy) {
|
|
|
+ dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
|
|
|
+ cm->desc->psy_charger_stat[i]);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT,
|
|
|
+ &val);
|
|
|
if (ret == 0 && val.intval) {
|
|
|
present = true;
|
|
|
break;
|
|
@@ -139,14 +151,20 @@ static bool is_batt_present(struct charger_manager *cm)
|
|
|
static bool is_ext_pwr_online(struct charger_manager *cm)
|
|
|
{
|
|
|
union power_supply_propval val;
|
|
|
+ struct power_supply *psy;
|
|
|
bool online = false;
|
|
|
int i, ret;
|
|
|
|
|
|
/* If at least one of them has one, it's yes. */
|
|
|
- for (i = 0; cm->charger_stat[i]; i++) {
|
|
|
- ret = cm->charger_stat[i]->get_property(
|
|
|
- cm->charger_stat[i],
|
|
|
- POWER_SUPPLY_PROP_ONLINE, &val);
|
|
|
+ for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
|
|
|
+ psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
|
|
|
+ if (!psy) {
|
|
|
+ dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
|
|
|
+ cm->desc->psy_charger_stat[i]);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
|
|
|
if (ret == 0 && val.intval) {
|
|
|
online = true;
|
|
|
break;
|
|
@@ -167,12 +185,14 @@ static bool is_ext_pwr_online(struct charger_manager *cm)
|
|
|
static int get_batt_uV(struct charger_manager *cm, int *uV)
|
|
|
{
|
|
|
union power_supply_propval val;
|
|
|
+ struct power_supply *fuel_gauge;
|
|
|
int ret;
|
|
|
|
|
|
- if (!cm->fuel_gauge)
|
|
|
+ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
+ if (!fuel_gauge)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ ret = fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
|
|
|
if (ret)
|
|
|
return ret;
|
|
@@ -189,6 +209,7 @@ static bool is_charging(struct charger_manager *cm)
|
|
|
{
|
|
|
int i, ret;
|
|
|
bool charging = false;
|
|
|
+ struct power_supply *psy;
|
|
|
union power_supply_propval val;
|
|
|
|
|
|
/* If there is no battery, it cannot be charged */
|
|
@@ -196,17 +217,22 @@ static bool is_charging(struct charger_manager *cm)
|
|
|
return false;
|
|
|
|
|
|
/* If at least one of the charger is charging, return yes */
|
|
|
- for (i = 0; cm->charger_stat[i]; i++) {
|
|
|
+ for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
|
|
|
/* 1. The charger sholuld not be DISABLED */
|
|
|
if (cm->emergency_stop)
|
|
|
continue;
|
|
|
if (!cm->charger_enabled)
|
|
|
continue;
|
|
|
|
|
|
+ psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
|
|
|
+ if (!psy) {
|
|
|
+ dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
|
|
|
+ cm->desc->psy_charger_stat[i]);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
/* 2. The charger should be online (ext-power) */
|
|
|
- ret = cm->charger_stat[i]->get_property(
|
|
|
- cm->charger_stat[i],
|
|
|
- POWER_SUPPLY_PROP_ONLINE, &val);
|
|
|
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
|
|
|
if (ret) {
|
|
|
dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
|
|
|
cm->desc->psy_charger_stat[i]);
|
|
@@ -219,9 +245,7 @@ static bool is_charging(struct charger_manager *cm)
|
|
|
* 3. The charger should not be FULL, DISCHARGING,
|
|
|
* or NOT_CHARGING.
|
|
|
*/
|
|
|
- ret = cm->charger_stat[i]->get_property(
|
|
|
- cm->charger_stat[i],
|
|
|
- POWER_SUPPLY_PROP_STATUS, &val);
|
|
|
+ ret = psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &val);
|
|
|
if (ret) {
|
|
|
dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
|
|
|
cm->desc->psy_charger_stat[i]);
|
|
@@ -248,6 +272,7 @@ static bool is_full_charged(struct charger_manager *cm)
|
|
|
{
|
|
|
struct charger_desc *desc = cm->desc;
|
|
|
union power_supply_propval val;
|
|
|
+ struct power_supply *fuel_gauge;
|
|
|
int ret = 0;
|
|
|
int uV;
|
|
|
|
|
@@ -255,11 +280,15 @@ static bool is_full_charged(struct charger_manager *cm)
|
|
|
if (!is_batt_present(cm))
|
|
|
return false;
|
|
|
|
|
|
- if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) {
|
|
|
+ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
+ if (!fuel_gauge)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (desc->fullbatt_full_capacity > 0) {
|
|
|
val.intval = 0;
|
|
|
|
|
|
/* Not full if capacity of fuel gauge isn't full */
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ ret = fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CHARGE_FULL, &val);
|
|
|
if (!ret && val.intval > desc->fullbatt_full_capacity)
|
|
|
return true;
|
|
@@ -273,10 +302,10 @@ static bool is_full_charged(struct charger_manager *cm)
|
|
|
}
|
|
|
|
|
|
/* Full, if the capacity is more than fullbatt_soc */
|
|
|
- if (cm->fuel_gauge && desc->fullbatt_soc > 0) {
|
|
|
+ if (desc->fullbatt_soc > 0) {
|
|
|
val.intval = 0;
|
|
|
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ ret = fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CAPACITY, &val);
|
|
|
if (!ret && val.intval >= desc->fullbatt_soc)
|
|
|
return true;
|
|
@@ -551,6 +580,20 @@ static int check_charging_duration(struct charger_manager *cm)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int cm_get_battery_temperature_by_psy(struct charger_manager *cm,
|
|
|
+ int *temp)
|
|
|
+{
|
|
|
+ struct power_supply *fuel_gauge;
|
|
|
+
|
|
|
+ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
+ if (!fuel_gauge)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ return fuel_gauge->get_property(fuel_gauge,
|
|
|
+ POWER_SUPPLY_PROP_TEMP,
|
|
|
+ (union power_supply_propval *)temp);
|
|
|
+}
|
|
|
+
|
|
|
static int cm_get_battery_temperature(struct charger_manager *cm,
|
|
|
int *temp)
|
|
|
{
|
|
@@ -560,15 +603,18 @@ static int cm_get_battery_temperature(struct charger_manager *cm,
|
|
|
return -ENODEV;
|
|
|
|
|
|
#ifdef CONFIG_THERMAL
|
|
|
- ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);
|
|
|
- if (!ret)
|
|
|
- /* Calibrate temperature unit */
|
|
|
- *temp /= 100;
|
|
|
-#else
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
- POWER_SUPPLY_PROP_TEMP,
|
|
|
- (union power_supply_propval *)temp);
|
|
|
+ if (cm->tzd_batt) {
|
|
|
+ ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);
|
|
|
+ if (!ret)
|
|
|
+ /* Calibrate temperature unit */
|
|
|
+ *temp /= 100;
|
|
|
+ } else
|
|
|
#endif
|
|
|
+ {
|
|
|
+ /* if-else continued from CONFIG_THERMAL */
|
|
|
+ ret = cm_get_battery_temperature_by_psy(cm, temp);
|
|
|
+ }
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -827,6 +873,7 @@ static int charger_get_property(struct power_supply *psy,
|
|
|
struct charger_manager *cm = container_of(psy,
|
|
|
struct charger_manager, charger_psy);
|
|
|
struct charger_desc *desc = cm->desc;
|
|
|
+ struct power_supply *fuel_gauge;
|
|
|
int ret = 0;
|
|
|
int uV;
|
|
|
|
|
@@ -857,14 +904,20 @@ static int charger_get_property(struct power_supply *psy,
|
|
|
ret = get_batt_uV(cm, &val->intval);
|
|
|
break;
|
|
|
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
+ if (!fuel_gauge) {
|
|
|
+ ret = -ENODEV;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ret = fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CURRENT_NOW, val);
|
|
|
break;
|
|
|
case POWER_SUPPLY_PROP_TEMP:
|
|
|
case POWER_SUPPLY_PROP_TEMP_AMBIENT:
|
|
|
return cm_get_battery_temperature(cm, &val->intval);
|
|
|
case POWER_SUPPLY_PROP_CAPACITY:
|
|
|
- if (!cm->fuel_gauge) {
|
|
|
+ fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
|
|
|
+ if (!fuel_gauge) {
|
|
|
ret = -ENODEV;
|
|
|
break;
|
|
|
}
|
|
@@ -875,7 +928,7 @@ static int charger_get_property(struct power_supply *psy,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ ret = fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CAPACITY, val);
|
|
|
if (ret)
|
|
|
break;
|
|
@@ -924,7 +977,14 @@ static int charger_get_property(struct power_supply *psy,
|
|
|
break;
|
|
|
case POWER_SUPPLY_PROP_CHARGE_NOW:
|
|
|
if (is_charging(cm)) {
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ fuel_gauge = power_supply_get_by_name(
|
|
|
+ cm->desc->psy_fuel_gauge);
|
|
|
+ if (!fuel_gauge) {
|
|
|
+ ret = -ENODEV;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CHARGE_NOW,
|
|
|
val);
|
|
|
if (ret) {
|
|
@@ -970,6 +1030,7 @@ static struct power_supply psy_default = {
|
|
|
.properties = default_charger_props,
|
|
|
.num_properties = ARRAY_SIZE(default_charger_props),
|
|
|
.get_property = charger_get_property,
|
|
|
+ .no_thermal = true,
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -1485,14 +1546,15 @@ err:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int cm_init_thermal_data(struct charger_manager *cm)
|
|
|
+static int cm_init_thermal_data(struct charger_manager *cm,
|
|
|
+ struct power_supply *fuel_gauge)
|
|
|
{
|
|
|
struct charger_desc *desc = cm->desc;
|
|
|
union power_supply_propval val;
|
|
|
int ret;
|
|
|
|
|
|
/* Verify whether fuel gauge provides battery temperature */
|
|
|
- ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ ret = fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_TEMP, &val);
|
|
|
|
|
|
if (!ret) {
|
|
@@ -1502,8 +1564,6 @@ static int cm_init_thermal_data(struct charger_manager *cm)
|
|
|
cm->desc->measure_battery_temp = true;
|
|
|
}
|
|
|
#ifdef CONFIG_THERMAL
|
|
|
- cm->tzd_batt = cm->fuel_gauge->tzd;
|
|
|
-
|
|
|
if (ret && desc->thermal_zone) {
|
|
|
cm->tzd_batt =
|
|
|
thermal_zone_get_zone_by_name(desc->thermal_zone);
|
|
@@ -1666,6 +1726,7 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|
|
int ret = 0, i = 0;
|
|
|
int j = 0;
|
|
|
union power_supply_propval val;
|
|
|
+ struct power_supply *fuel_gauge;
|
|
|
|
|
|
if (g_desc && !rtc_dev && g_desc->rtc_name) {
|
|
|
rtc_dev = rtc_class_open(g_desc->rtc_name);
|
|
@@ -1729,23 +1790,20 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|
|
while (desc->psy_charger_stat[i])
|
|
|
i++;
|
|
|
|
|
|
- cm->charger_stat = devm_kzalloc(&pdev->dev,
|
|
|
- sizeof(struct power_supply *) * i, GFP_KERNEL);
|
|
|
- if (!cm->charger_stat)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
+ /* Check if charger's supplies are present at probe */
|
|
|
for (i = 0; desc->psy_charger_stat[i]; i++) {
|
|
|
- cm->charger_stat[i] = power_supply_get_by_name(
|
|
|
- desc->psy_charger_stat[i]);
|
|
|
- if (!cm->charger_stat[i]) {
|
|
|
+ struct power_supply *psy;
|
|
|
+
|
|
|
+ psy = power_supply_get_by_name(desc->psy_charger_stat[i]);
|
|
|
+ if (!psy) {
|
|
|
dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
|
|
|
desc->psy_charger_stat[i]);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
|
|
|
- if (!cm->fuel_gauge) {
|
|
|
+ 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;
|
|
@@ -1788,13 +1846,13 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|
|
cm->charger_psy.num_properties = psy_default.num_properties;
|
|
|
|
|
|
/* Find which optional psy-properties are available */
|
|
|
- if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ if (!fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
|
|
|
cm->charger_psy.properties[cm->charger_psy.num_properties] =
|
|
|
POWER_SUPPLY_PROP_CHARGE_NOW;
|
|
|
cm->charger_psy.num_properties++;
|
|
|
}
|
|
|
- if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
|
|
|
+ if (!fuel_gauge->get_property(fuel_gauge,
|
|
|
POWER_SUPPLY_PROP_CURRENT_NOW,
|
|
|
&val)) {
|
|
|
cm->charger_psy.properties[cm->charger_psy.num_properties] =
|
|
@@ -1802,7 +1860,7 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|
|
cm->charger_psy.num_properties++;
|
|
|
}
|
|
|
|
|
|
- ret = cm_init_thermal_data(cm);
|
|
|
+ ret = cm_init_thermal_data(cm, fuel_gauge);
|
|
|
if (ret) {
|
|
|
dev_err(&pdev->dev, "Failed to initialize thermal data\n");
|
|
|
cm->desc->measure_battery_temp = false;
|
|
@@ -2066,8 +2124,8 @@ static bool find_power_supply(struct charger_manager *cm,
|
|
|
int i;
|
|
|
bool found = false;
|
|
|
|
|
|
- for (i = 0; cm->charger_stat[i]; i++) {
|
|
|
- if (psy == cm->charger_stat[i]) {
|
|
|
+ for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
|
|
|
+ if (!strcmp(psy->name, cm->desc->psy_charger_stat[i])) {
|
|
|
found = true;
|
|
|
break;
|
|
|
}
|