#define AXP288_EXTCON_DEV_NAME "axp288_extcon"
#define USB_HOST_EXTCON_DEV_NAME "INT3496:00"
+static const unsigned int cable_ids[] =
+ { EXTCON_CHG_USB_SDP, EXTCON_CHG_USB_CDP, EXTCON_CHG_USB_DCP };
+
enum {
VBUS_OV_IRQ = 0,
CHARGE_DONE_IRQ,
struct extcon_dev *edev;
bool connected;
enum power_supply_type chg_type;
- struct notifier_block nb;
+ struct notifier_block nb[ARRAY_SIZE(cable_ids)];
struct work_struct work;
} cable;
power_supply_changed(info->psy_usb);
}
-static int axp288_charger_handle_cable_evt(struct notifier_block *nb,
- unsigned long event, void *param)
+/*
+ * We need 3 copies of this, because there is no way to find out for which
+ * cable id we are being called from the passed in arguments; and we must
+ * have a separate nb for each extcon_register_notifier call.
+ */
+static int axp288_charger_handle_cable0_evt(struct notifier_block *nb,
+ unsigned long event, void *param)
{
struct axp288_chrg_info *info =
- container_of(nb, struct axp288_chrg_info, cable.nb);
+ container_of(nb, struct axp288_chrg_info, cable.nb[0]);
+ schedule_work(&info->cable.work);
+ return NOTIFY_OK;
+}
+static int axp288_charger_handle_cable1_evt(struct notifier_block *nb,
+ unsigned long event, void *param)
+{
+ struct axp288_chrg_info *info =
+ container_of(nb, struct axp288_chrg_info, cable.nb[1]);
schedule_work(&info->cable.work);
+ return NOTIFY_OK;
+}
+static int axp288_charger_handle_cable2_evt(struct notifier_block *nb,
+ unsigned long event, void *param)
+{
+ struct axp288_chrg_info *info =
+ container_of(nb, struct axp288_chrg_info, cable.nb[2]);
+ schedule_work(&info->cable.work);
return NOTIFY_OK;
}
struct device *dev = &pdev->dev;
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
struct power_supply_config charger_cfg = {};
- unsigned int cable_ids[] = { EXTCON_CHG_USB_SDP, EXTCON_CHG_USB_CDP,
- EXTCON_CHG_USB_DCP };
-
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
/* Register for extcon notification */
INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker);
- info->cable.nb.notifier_call = axp288_charger_handle_cable_evt;
+ info->cable.nb[0].notifier_call = axp288_charger_handle_cable0_evt;
+ info->cable.nb[1].notifier_call = axp288_charger_handle_cable1_evt;
+ info->cable.nb[2].notifier_call = axp288_charger_handle_cable2_evt;
for (i = 0; i < ARRAY_SIZE(cable_ids); i++) {
ret = devm_extcon_register_notifier(dev, info->cable.edev,
- cable_ids[i], &info->cable.nb);
+ cable_ids[i], &info->cable.nb[i]);
if (ret) {
dev_err(dev, "failed to register extcon notifier for %u: %d\n",
cable_ids[i], ret);