Loading drivers/power/supply/qcom/smb1351-charger.c +137 −37 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ Loading @@ -8,15 +8,18 @@ #include <linux/i2c.h> #include <linux/debugfs.h> #include <linux/errno.h> #include <linux/extcon.h> #include <linux/extcon-provider.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/power_supply.h> #include <linux/regulator/driver.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/machine.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/mutex.h> #include <linux/delay.h> #include <linux/pinctrl/consumer.h> Loading Loading @@ -493,6 +496,8 @@ struct smb1351_charger { struct regulator *dpdm_reg; enum power_supply_type charger_type; bool otg_enable; int usb_id_gpio; int usb_id_irq; }; struct smb_irq_info { Loading Loading @@ -1135,8 +1140,7 @@ static int smb1351_hw_init(struct smb1351_charger *chip) static enum power_supply_property smb1351_battery_properties[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CHARGING_ENABLED, POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_HEALTH, Loading Loading @@ -1223,7 +1227,7 @@ static int smb1351_get_prop_charge_type(struct smb1351_charger *chip) if (reg == STATUS_FAST_CHARGING) return POWER_SUPPLY_CHARGE_TYPE_FAST; else if (reg == STATUS_TAPER_CHARGING) return POWER_SUPPLY_CHARGE_TYPE_TAPER; return POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE; else if (reg == STATUS_PRE_CHARGING) return POWER_SUPPLY_CHARGE_TYPE_TRICKLE; else Loading Loading @@ -1321,15 +1325,65 @@ static char *smb1351_usb_supplicants[] = { "bms", }; static enum power_supply_usb_type smb1351_usb_psy_supported_types[] = { POWER_SUPPLY_USB_TYPE_UNKNOWN, POWER_SUPPLY_USB_TYPE_SDP, POWER_SUPPLY_USB_TYPE_DCP, POWER_SUPPLY_USB_TYPE_CDP, POWER_SUPPLY_USB_TYPE_ACA, }; static enum power_supply_property smb1351_usb_properties[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_TYPE, POWER_SUPPLY_PROP_REAL_TYPE, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, POWER_SUPPLY_PROP_USB_TYPE, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, }; static void smb1351_update_desc_type(struct smb1351_charger *chip) { switch (chip->charger_type) { case POWER_SUPPLY_TYPE_USB_CDP: case POWER_SUPPLY_TYPE_USB_DCP: case POWER_SUPPLY_TYPE_USB: case POWER_SUPPLY_TYPE_USB_ACA: chip->usb_psy_d.type = chip->charger_type; break; case POWER_SUPPLY_TYPE_USB_HVDCP: chip->usb_psy_d.type = POWER_SUPPLY_TYPE_USB_DCP; break; default: chip->usb_psy_d.type = POWER_SUPPLY_TYPE_USB; break; } } static void smb1351_get_usb_type(struct smb1351_charger *chip, union power_supply_propval *val) { switch (chip->charger_type) { case POWER_SUPPLY_TYPE_USB_CDP: val->intval = POWER_SUPPLY_USB_TYPE_CDP; break; case POWER_SUPPLY_TYPE_USB_DCP: val->intval = POWER_SUPPLY_USB_TYPE_DCP; break; case POWER_SUPPLY_TYPE_USB: val->intval = POWER_SUPPLY_USB_TYPE_SDP; break; case POWER_SUPPLY_TYPE_USB_ACA: val->intval = POWER_SUPPLY_USB_TYPE_ACA; break; case POWER_SUPPLY_TYPE_USB_HVDCP: val->intval = POWER_SUPPLY_USB_TYPE_DCP; break; default: val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN; break; } } static int smb1351_usb_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) Loading @@ -1338,7 +1392,7 @@ static int smb1351_usb_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: val->intval = chip->usb_psy_ma * 1000; break; case POWER_SUPPLY_PROP_PRESENT: Loading @@ -1347,16 +1401,8 @@ static int smb1351_usb_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_ONLINE: val->intval = chip->chg_present && !chip->usb_suspended_status; break; case POWER_SUPPLY_PROP_TYPE: val->intval = chip->charger_type; break; case POWER_SUPPLY_PROP_REAL_TYPE: if (chip->charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) val->intval = POWER_SUPPLY_TYPE_USB_DCP; else if (chip->charger_type == POWER_SUPPLY_TYPE_UNKNOWN) val->intval = POWER_SUPPLY_TYPE_USB; else val->intval = chip->charger_type; case POWER_SUPPLY_PROP_USB_TYPE: smb1351_get_usb_type(chip, val); break; default: return -EINVAL; Loading @@ -1372,7 +1418,7 @@ static int smb1351_usb_set_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: chip->usb_psy_ma = val->intval / 1000; smb1351_enable_volatile_writes(chip); smb1351_set_usb_chg_current(chip, chip->usb_psy_ma); Loading Loading @@ -1402,8 +1448,7 @@ static int smb1351_batt_property_is_writeable(struct power_supply *psy, enum power_supply_property psp) { switch (psp) { case POWER_SUPPLY_PROP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: case POWER_SUPPLY_PROP_CAPACITY: return 1; default: Loading Loading @@ -1456,12 +1501,9 @@ static int smb1351_battery_set_property(struct power_supply *psy, return -EINVAL; } break; case POWER_SUPPLY_PROP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: smb1351_usb_suspend(chip, USER, !val->intval); break; case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: smb1351_battchg_disable(chip, USER, !val->intval); break; case POWER_SUPPLY_PROP_CAPACITY: chip->fake_battery_soc = val->intval; power_supply_changed(chip->batt_psy); Loading Loading @@ -1489,12 +1531,9 @@ static int smb1351_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY: val->intval = smb1351_get_prop_batt_capacity(chip); break; case POWER_SUPPLY_PROP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: val->intval = !chip->usb_suspended_status; break; case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: val->intval = !chip->battchg_disabled_status; break; case POWER_SUPPLY_PROP_CHARGE_TYPE: val->intval = smb1351_get_prop_charge_type(chip); break; Loading Loading @@ -1534,7 +1573,6 @@ static void smb1351_hvdcp_det_work(struct work_struct *work) { int rc; u8 reg; union power_supply_propval pval = {0, }; struct smb1351_charger *chip = container_of(work, struct smb1351_charger, hvdcp_det_work.work); Loading @@ -1546,12 +1584,6 @@ static void smb1351_hvdcp_det_work(struct work_struct *work) } pr_debug("STATUS_7_REG = 0x%02X\n", reg); if (reg) { pr_debug("HVDCP detected; notifying USB PSY\n"); pval.intval = POWER_SUPPLY_TYPE_USB_HVDCP; power_supply_set_property(chip->usb_psy, POWER_SUPPLY_PROP_TYPE, &pval); } end: pm_relax(chip->dev); } Loading Loading @@ -1675,6 +1707,8 @@ static int smb1351_apsd_complete_handler(struct smb1351_charger *chip, smb1351_request_dpdm(chip, false); } smb1351_update_desc_type(chip); return 0; } Loading Loading @@ -2058,6 +2092,27 @@ static irqreturn_t smb1351_chg_stat_handler(int irq, void *dev_id) return IRQ_HANDLED; } irqreturn_t smb1351_usb_id_irq_handler(int irq, void *data) { struct smb1351_charger *chip = data; bool id_state; int rc = 0; id_state = gpio_get_value(chip->usb_id_gpio); pr_debug("id_state=%d\n", id_state); rc = smb1351_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, id_state ? 0 : CMD_OTG_EN_BIT); if (rc < 0) pr_err("Failed to %s OTG\n", id_state ? "disable" : "enable"); else pr_debug("SMB1351 OTG %s\n", id_state ? "disabled" : "enabled"); extcon_set_state_sync(chip->extcon, EXTCON_USB_HOST, !id_state); return IRQ_HANDLED; } #define LAST_CNFG_REG 0x16 static int show_cnfg_regs(struct seq_file *m, void *data) { Loading Loading @@ -2396,6 +2451,9 @@ static int smb1351_determine_initial_state(struct smb1351_charger *chip) smb1351_apsd_complete_handler(chip, 1); } if (chip->usb_id_gpio > 0) smb1351_usb_id_irq_handler(0, chip); return 0; fail_init_status: Loading Loading @@ -2457,6 +2515,24 @@ static int create_debugfs_entries(struct smb1351_charger *chip) return 0; } static int smb1351_init_otg(struct smb1351_charger *chip) { chip->usb_id_gpio = chip->usb_id_irq = -EINVAL; if (of_find_property(chip->dev->of_node, "qcom,usb-id-gpio", NULL)) chip->usb_id_gpio = of_get_named_gpio(chip->dev->of_node, "qcom,usb-id-gpio", 0); chip->usb_id_irq = of_irq_get_byname(chip->dev->of_node, "smb1351_usb_id_irq"); if (chip->usb_id_irq < 0 || chip->usb_id_gpio < 0) pr_err("OTG irq (%d) / gpio (%d) not defined\n", chip->usb_id_irq, chip->usb_id_gpio); return 0; } static int smb1351_main_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { Loading Loading @@ -2502,6 +2578,8 @@ static int smb1351_main_charger_probe(struct i2c_client *client, chip->usb_psy_d.get_property = smb1351_usb_get_property; chip->usb_psy_d.set_property = smb1351_usb_set_property; chip->usb_psy_d.properties = smb1351_usb_properties; chip->usb_psy_d.usb_types = smb1351_usb_psy_supported_types, chip->usb_psy_d.num_usb_types = ARRAY_SIZE(smb1351_usb_psy_supported_types); chip->usb_psy_d.num_properties = ARRAY_SIZE(smb1351_usb_properties); chip->usb_psy_d.property_is_writeable = smb1351_usb_is_writeable; Loading Loading @@ -2576,6 +2654,12 @@ static int smb1351_main_charger_probe(struct i2c_client *client, goto fail_smb1351_hw_init; } rc = smb1351_init_otg(chip); if (rc < 0) { dev_err(chip->dev, "Couldn't init otg rc=%d\n", rc); return rc; } rc = smb1351_determine_initial_state(chip); if (rc) { pr_err("Couldn't determine initial state rc=%d\n", rc); Loading @@ -2596,6 +2680,22 @@ static int smb1351_main_charger_probe(struct i2c_client *client, enable_irq_wake(client->irq); } if (chip->usb_id_irq > 0 && chip->usb_id_gpio > 0) { rc = devm_request_threaded_irq(chip->dev, chip->usb_id_irq, NULL, smb1351_usb_id_irq_handler, IRQF_ONESHOT | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "smb1351_usb_id_irq", chip); if (rc < 0) { pr_err("Failed to register id-irq rc=%d\n", rc); return rc; } enable_irq_wake(chip->usb_id_irq); } create_debugfs_entries(chip); dump_regs(chip); Loading Loading
drivers/power/supply/qcom/smb1351-charger.c +137 −37 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "%s: " fmt, __func__ Loading @@ -8,15 +8,18 @@ #include <linux/i2c.h> #include <linux/debugfs.h> #include <linux/errno.h> #include <linux/extcon.h> #include <linux/extcon-provider.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/power_supply.h> #include <linux/regulator/driver.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/machine.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/mutex.h> #include <linux/delay.h> #include <linux/pinctrl/consumer.h> Loading Loading @@ -493,6 +496,8 @@ struct smb1351_charger { struct regulator *dpdm_reg; enum power_supply_type charger_type; bool otg_enable; int usb_id_gpio; int usb_id_irq; }; struct smb_irq_info { Loading Loading @@ -1135,8 +1140,7 @@ static int smb1351_hw_init(struct smb1351_charger *chip) static enum power_supply_property smb1351_battery_properties[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CHARGING_ENABLED, POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_HEALTH, Loading Loading @@ -1223,7 +1227,7 @@ static int smb1351_get_prop_charge_type(struct smb1351_charger *chip) if (reg == STATUS_FAST_CHARGING) return POWER_SUPPLY_CHARGE_TYPE_FAST; else if (reg == STATUS_TAPER_CHARGING) return POWER_SUPPLY_CHARGE_TYPE_TAPER; return POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE; else if (reg == STATUS_PRE_CHARGING) return POWER_SUPPLY_CHARGE_TYPE_TRICKLE; else Loading Loading @@ -1321,15 +1325,65 @@ static char *smb1351_usb_supplicants[] = { "bms", }; static enum power_supply_usb_type smb1351_usb_psy_supported_types[] = { POWER_SUPPLY_USB_TYPE_UNKNOWN, POWER_SUPPLY_USB_TYPE_SDP, POWER_SUPPLY_USB_TYPE_DCP, POWER_SUPPLY_USB_TYPE_CDP, POWER_SUPPLY_USB_TYPE_ACA, }; static enum power_supply_property smb1351_usb_properties[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_TYPE, POWER_SUPPLY_PROP_REAL_TYPE, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, POWER_SUPPLY_PROP_USB_TYPE, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, }; static void smb1351_update_desc_type(struct smb1351_charger *chip) { switch (chip->charger_type) { case POWER_SUPPLY_TYPE_USB_CDP: case POWER_SUPPLY_TYPE_USB_DCP: case POWER_SUPPLY_TYPE_USB: case POWER_SUPPLY_TYPE_USB_ACA: chip->usb_psy_d.type = chip->charger_type; break; case POWER_SUPPLY_TYPE_USB_HVDCP: chip->usb_psy_d.type = POWER_SUPPLY_TYPE_USB_DCP; break; default: chip->usb_psy_d.type = POWER_SUPPLY_TYPE_USB; break; } } static void smb1351_get_usb_type(struct smb1351_charger *chip, union power_supply_propval *val) { switch (chip->charger_type) { case POWER_SUPPLY_TYPE_USB_CDP: val->intval = POWER_SUPPLY_USB_TYPE_CDP; break; case POWER_SUPPLY_TYPE_USB_DCP: val->intval = POWER_SUPPLY_USB_TYPE_DCP; break; case POWER_SUPPLY_TYPE_USB: val->intval = POWER_SUPPLY_USB_TYPE_SDP; break; case POWER_SUPPLY_TYPE_USB_ACA: val->intval = POWER_SUPPLY_USB_TYPE_ACA; break; case POWER_SUPPLY_TYPE_USB_HVDCP: val->intval = POWER_SUPPLY_USB_TYPE_DCP; break; default: val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN; break; } } static int smb1351_usb_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) Loading @@ -1338,7 +1392,7 @@ static int smb1351_usb_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: val->intval = chip->usb_psy_ma * 1000; break; case POWER_SUPPLY_PROP_PRESENT: Loading @@ -1347,16 +1401,8 @@ static int smb1351_usb_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_ONLINE: val->intval = chip->chg_present && !chip->usb_suspended_status; break; case POWER_SUPPLY_PROP_TYPE: val->intval = chip->charger_type; break; case POWER_SUPPLY_PROP_REAL_TYPE: if (chip->charger_type == POWER_SUPPLY_TYPE_USB_HVDCP) val->intval = POWER_SUPPLY_TYPE_USB_DCP; else if (chip->charger_type == POWER_SUPPLY_TYPE_UNKNOWN) val->intval = POWER_SUPPLY_TYPE_USB; else val->intval = chip->charger_type; case POWER_SUPPLY_PROP_USB_TYPE: smb1351_get_usb_type(chip, val); break; default: return -EINVAL; Loading @@ -1372,7 +1418,7 @@ static int smb1351_usb_set_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_SDP_CURRENT_MAX: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: chip->usb_psy_ma = val->intval / 1000; smb1351_enable_volatile_writes(chip); smb1351_set_usb_chg_current(chip, chip->usb_psy_ma); Loading Loading @@ -1402,8 +1448,7 @@ static int smb1351_batt_property_is_writeable(struct power_supply *psy, enum power_supply_property psp) { switch (psp) { case POWER_SUPPLY_PROP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: case POWER_SUPPLY_PROP_CAPACITY: return 1; default: Loading Loading @@ -1456,12 +1501,9 @@ static int smb1351_battery_set_property(struct power_supply *psy, return -EINVAL; } break; case POWER_SUPPLY_PROP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: smb1351_usb_suspend(chip, USER, !val->intval); break; case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: smb1351_battchg_disable(chip, USER, !val->intval); break; case POWER_SUPPLY_PROP_CAPACITY: chip->fake_battery_soc = val->intval; power_supply_changed(chip->batt_psy); Loading Loading @@ -1489,12 +1531,9 @@ static int smb1351_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY: val->intval = smb1351_get_prop_batt_capacity(chip); break; case POWER_SUPPLY_PROP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: val->intval = !chip->usb_suspended_status; break; case POWER_SUPPLY_PROP_BATTERY_CHARGING_ENABLED: val->intval = !chip->battchg_disabled_status; break; case POWER_SUPPLY_PROP_CHARGE_TYPE: val->intval = smb1351_get_prop_charge_type(chip); break; Loading Loading @@ -1534,7 +1573,6 @@ static void smb1351_hvdcp_det_work(struct work_struct *work) { int rc; u8 reg; union power_supply_propval pval = {0, }; struct smb1351_charger *chip = container_of(work, struct smb1351_charger, hvdcp_det_work.work); Loading @@ -1546,12 +1584,6 @@ static void smb1351_hvdcp_det_work(struct work_struct *work) } pr_debug("STATUS_7_REG = 0x%02X\n", reg); if (reg) { pr_debug("HVDCP detected; notifying USB PSY\n"); pval.intval = POWER_SUPPLY_TYPE_USB_HVDCP; power_supply_set_property(chip->usb_psy, POWER_SUPPLY_PROP_TYPE, &pval); } end: pm_relax(chip->dev); } Loading Loading @@ -1675,6 +1707,8 @@ static int smb1351_apsd_complete_handler(struct smb1351_charger *chip, smb1351_request_dpdm(chip, false); } smb1351_update_desc_type(chip); return 0; } Loading Loading @@ -2058,6 +2092,27 @@ static irqreturn_t smb1351_chg_stat_handler(int irq, void *dev_id) return IRQ_HANDLED; } irqreturn_t smb1351_usb_id_irq_handler(int irq, void *data) { struct smb1351_charger *chip = data; bool id_state; int rc = 0; id_state = gpio_get_value(chip->usb_id_gpio); pr_debug("id_state=%d\n", id_state); rc = smb1351_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT, id_state ? 0 : CMD_OTG_EN_BIT); if (rc < 0) pr_err("Failed to %s OTG\n", id_state ? "disable" : "enable"); else pr_debug("SMB1351 OTG %s\n", id_state ? "disabled" : "enabled"); extcon_set_state_sync(chip->extcon, EXTCON_USB_HOST, !id_state); return IRQ_HANDLED; } #define LAST_CNFG_REG 0x16 static int show_cnfg_regs(struct seq_file *m, void *data) { Loading Loading @@ -2396,6 +2451,9 @@ static int smb1351_determine_initial_state(struct smb1351_charger *chip) smb1351_apsd_complete_handler(chip, 1); } if (chip->usb_id_gpio > 0) smb1351_usb_id_irq_handler(0, chip); return 0; fail_init_status: Loading Loading @@ -2457,6 +2515,24 @@ static int create_debugfs_entries(struct smb1351_charger *chip) return 0; } static int smb1351_init_otg(struct smb1351_charger *chip) { chip->usb_id_gpio = chip->usb_id_irq = -EINVAL; if (of_find_property(chip->dev->of_node, "qcom,usb-id-gpio", NULL)) chip->usb_id_gpio = of_get_named_gpio(chip->dev->of_node, "qcom,usb-id-gpio", 0); chip->usb_id_irq = of_irq_get_byname(chip->dev->of_node, "smb1351_usb_id_irq"); if (chip->usb_id_irq < 0 || chip->usb_id_gpio < 0) pr_err("OTG irq (%d) / gpio (%d) not defined\n", chip->usb_id_irq, chip->usb_id_gpio); return 0; } static int smb1351_main_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { Loading Loading @@ -2502,6 +2578,8 @@ static int smb1351_main_charger_probe(struct i2c_client *client, chip->usb_psy_d.get_property = smb1351_usb_get_property; chip->usb_psy_d.set_property = smb1351_usb_set_property; chip->usb_psy_d.properties = smb1351_usb_properties; chip->usb_psy_d.usb_types = smb1351_usb_psy_supported_types, chip->usb_psy_d.num_usb_types = ARRAY_SIZE(smb1351_usb_psy_supported_types); chip->usb_psy_d.num_properties = ARRAY_SIZE(smb1351_usb_properties); chip->usb_psy_d.property_is_writeable = smb1351_usb_is_writeable; Loading Loading @@ -2576,6 +2654,12 @@ static int smb1351_main_charger_probe(struct i2c_client *client, goto fail_smb1351_hw_init; } rc = smb1351_init_otg(chip); if (rc < 0) { dev_err(chip->dev, "Couldn't init otg rc=%d\n", rc); return rc; } rc = smb1351_determine_initial_state(chip); if (rc) { pr_err("Couldn't determine initial state rc=%d\n", rc); Loading @@ -2596,6 +2680,22 @@ static int smb1351_main_charger_probe(struct i2c_client *client, enable_irq_wake(client->irq); } if (chip->usb_id_irq > 0 && chip->usb_id_gpio > 0) { rc = devm_request_threaded_irq(chip->dev, chip->usb_id_irq, NULL, smb1351_usb_id_irq_handler, IRQF_ONESHOT | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "smb1351_usb_id_irq", chip); if (rc < 0) { pr_err("Failed to register id-irq rc=%d\n", rc); return rc; } enable_irq_wake(chip->usb_id_irq); } create_debugfs_entries(chip); dump_regs(chip); Loading