Commit c1f73028 authored by Jonathan Bakker's avatar Jonathan Bakker Committed by Sebastian Reichel

power: supply: charger-manager: Update extcon functions

In commit 830ae442 ("extcon: Remove the deprecated extcon functions")
the function extcon_register_interest became a no-op returning an error,
leading to non-functional behaviour in charger-manager.

Additionally, a translation table is needed between the text representation
of the extcon cable names and their IDs is needed.  In order to retain DT
compatibility, TA and CHARGE-DOWNSTREAM are added as they were present up
until commit 11eecf91 ("extcon: Modify the id and name of external
connector")
Signed-off-by: default avatarJonathan Bakker <xc-racer2@live.ca>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
parent 9434e453
...@@ -26,6 +26,29 @@ ...@@ -26,6 +26,29 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/thermal.h> #include <linux/thermal.h>
static struct {
const char *name;
u64 extcon_type;
} extcon_mapping[] = {
/* Current textual representations */
{ "USB", EXTCON_USB },
{ "USB-HOST", EXTCON_USB_HOST },
{ "SDP", EXTCON_CHG_USB_SDP },
{ "DCP", EXTCON_CHG_USB_DCP },
{ "CDP", EXTCON_CHG_USB_CDP },
{ "ACA", EXTCON_CHG_USB_ACA },
{ "FAST-CHARGER", EXTCON_CHG_USB_FAST },
{ "SLOW-CHARGER", EXTCON_CHG_USB_SLOW },
{ "WPT", EXTCON_CHG_WPT },
{ "PD", EXTCON_CHG_USB_PD },
{ "DOCK", EXTCON_DOCK },
{ "JIG", EXTCON_JIG },
{ "MECHANICAL", EXTCON_MECHANICAL },
/* Deprecated textual representations */
{ "TA", EXTCON_CHG_USB_SDP },
{ "CHARGE-DOWNSTREAM", EXTCON_CHG_USB_CDP },
};
/* /*
* Default temperature threshold for charging. * Default temperature threshold for charging.
* Every temperature units are in tenth of centigrade. * Every temperature units are in tenth of centigrade.
...@@ -950,7 +973,8 @@ static int charger_extcon_notifier(struct notifier_block *self, ...@@ -950,7 +973,8 @@ static int charger_extcon_notifier(struct notifier_block *self,
static int charger_extcon_init(struct charger_manager *cm, static int charger_extcon_init(struct charger_manager *cm,
struct charger_cable *cable) struct charger_cable *cable)
{ {
int ret; int ret, i;
u64 extcon_type = EXTCON_NONE;
/* /*
* Charger manager use Extcon framework to identify * Charger manager use Extcon framework to identify
...@@ -959,14 +983,39 @@ static int charger_extcon_init(struct charger_manager *cm, ...@@ -959,14 +983,39 @@ static int charger_extcon_init(struct charger_manager *cm,
*/ */
INIT_WORK(&cable->wq, charger_extcon_work); INIT_WORK(&cable->wq, charger_extcon_work);
cable->nb.notifier_call = charger_extcon_notifier; cable->nb.notifier_call = charger_extcon_notifier;
ret = extcon_register_interest(&cable->extcon_dev,
cable->extcon_name, cable->name, &cable->nb); cable->extcon_dev = extcon_get_extcon_dev(cable->extcon_name);
if (IS_ERR_OR_NULL(cable->extcon_dev)) {
pr_err("Cannot find extcon_dev for %s (cable: %s)\n",
cable->extcon_name, cable->name);
if (cable->extcon_dev == NULL)
return -EPROBE_DEFER;
else
return PTR_ERR(cable->extcon_dev);
}
for (i = 0; i < ARRAY_SIZE(extcon_mapping); i++) {
if (!strcmp(cable->name, extcon_mapping[i].name)) {
extcon_type = extcon_mapping[i].extcon_type;
break;
}
}
if (extcon_type == EXTCON_NONE) {
pr_err("Cannot find cable for type %s", cable->name);
return -EINVAL;
}
cable->extcon_type = extcon_type;
ret = devm_extcon_register_notifier(cm->dev, cable->extcon_dev,
cable->extcon_type, &cable->nb);
if (ret < 0) { if (ret < 0) {
pr_info("Cannot register extcon_dev for %s(cable: %s)\n", pr_err("Cannot register extcon_dev for %s (cable: %s)\n",
cable->extcon_name, cable->name); cable->extcon_name, cable->name);
return ret;
} }
return ret; return 0;
} }
/** /**
...@@ -983,6 +1032,7 @@ static int charger_manager_register_extcon(struct charger_manager *cm) ...@@ -983,6 +1032,7 @@ static int charger_manager_register_extcon(struct charger_manager *cm)
{ {
struct charger_desc *desc = cm->desc; struct charger_desc *desc = cm->desc;
struct charger_regulator *charger; struct charger_regulator *charger;
unsigned long event;
int ret; int ret;
int i; int i;
int j; int j;
...@@ -1010,6 +1060,11 @@ static int charger_manager_register_extcon(struct charger_manager *cm) ...@@ -1010,6 +1060,11 @@ static int charger_manager_register_extcon(struct charger_manager *cm)
} }
cable->charger = charger; cable->charger = charger;
cable->cm = cm; cable->cm = cm;
event = extcon_get_state(cable->extcon_dev,
cable->extcon_type);
charger_extcon_notifier(&cable->nb,
event, NULL);
} }
} }
...@@ -1370,7 +1425,6 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1370,7 +1425,6 @@ static int charger_manager_probe(struct platform_device *pdev)
struct charger_desc *desc = cm_get_drv_data(pdev); struct charger_desc *desc = cm_get_drv_data(pdev);
struct charger_manager *cm; struct charger_manager *cm;
int ret, i = 0; int ret, i = 0;
int j = 0;
union power_supply_propval val; union power_supply_propval val;
struct power_supply *fuel_gauge; struct power_supply *fuel_gauge;
enum power_supply_property *properties; enum power_supply_property *properties;
...@@ -1572,12 +1626,6 @@ static int charger_manager_probe(struct platform_device *pdev) ...@@ -1572,12 +1626,6 @@ static int charger_manager_probe(struct platform_device *pdev)
struct charger_regulator *charger; struct charger_regulator *charger;
charger = &desc->charger_regulators[i]; charger = &desc->charger_regulators[i];
for (j = 0; j < charger->num_cables; j++) {
struct charger_cable *cable = &charger->cables[j];
/* Remove notifier block if only edev exists */
if (cable->extcon_dev.edev)
extcon_unregister_interest(&cable->extcon_dev);
}
regulator_put(desc->charger_regulators[i].consumer); regulator_put(desc->charger_regulators[i].consumer);
} }
...@@ -1592,7 +1640,6 @@ static int charger_manager_remove(struct platform_device *pdev) ...@@ -1592,7 +1640,6 @@ static int charger_manager_remove(struct platform_device *pdev)
struct charger_manager *cm = platform_get_drvdata(pdev); struct charger_manager *cm = platform_get_drvdata(pdev);
struct charger_desc *desc = cm->desc; struct charger_desc *desc = cm->desc;
int i = 0; int i = 0;
int j = 0;
/* Remove from the list */ /* Remove from the list */
mutex_lock(&cm_list_mtx); mutex_lock(&cm_list_mtx);
...@@ -1602,15 +1649,6 @@ static int charger_manager_remove(struct platform_device *pdev) ...@@ -1602,15 +1649,6 @@ static int charger_manager_remove(struct platform_device *pdev)
cancel_work_sync(&setup_polling); cancel_work_sync(&setup_polling);
cancel_delayed_work_sync(&cm_monitor_work); cancel_delayed_work_sync(&cm_monitor_work);
for (i = 0 ; i < desc->num_charger_regulators ; i++) {
struct charger_regulator *charger
= &desc->charger_regulators[i];
for (j = 0 ; j < charger->num_cables ; j++) {
struct charger_cable *cable = &charger->cables[j];
extcon_unregister_interest(&cable->extcon_dev);
}
}
for (i = 0 ; i < desc->num_charger_regulators ; i++) for (i = 0 ; i < desc->num_charger_regulators ; i++)
regulator_put(desc->charger_regulators[i].consumer); regulator_put(desc->charger_regulators[i].consumer);
......
...@@ -40,7 +40,7 @@ enum cm_batt_temp { ...@@ -40,7 +40,7 @@ enum cm_batt_temp {
/** /**
* struct charger_cable * struct charger_cable
* @extcon_name: the name of extcon device. * @extcon_name: the name of extcon device.
* @name: the name of charger cable(external connector). * @name: the name of the cable connector
* @extcon_dev: the extcon device. * @extcon_dev: the extcon device.
* @wq: the workqueue to control charger according to the state of * @wq: the workqueue to control charger according to the state of
* charger cable. If charger cable is attached, enable charger. * charger cable. If charger cable is attached, enable charger.
...@@ -56,9 +56,10 @@ enum cm_batt_temp { ...@@ -56,9 +56,10 @@ enum cm_batt_temp {
struct charger_cable { struct charger_cable {
const char *extcon_name; const char *extcon_name;
const char *name; const char *name;
struct extcon_dev *extcon_dev;
u64 extcon_type;
/* The charger-manager use Extcon framework */ /* The charger-manager use Extcon framework */
struct extcon_specific_cable_nb extcon_dev;
struct work_struct wq; struct work_struct wq;
struct notifier_block nb; struct notifier_block nb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment