From c20e18eae813b75b311ca48603033cd53a5809b7 Mon Sep 17 00:00:00 2001 From: mahj8 Date: Fri, 8 Oct 2021 18:09:07 +0800 Subject: [PATCH] sgm41542: provide some api for charger class register charger device and provide some api for charger class Change-Id: I2c458b2f0f33bca9e0b24ae6602b14c0ad492d6f Signed-off-by: mahj8 Reviewed-on: https://gerrit.mot.com/2085447 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Huosheng Liao Submit-Approved: Jira Key Reviewed-by: Shicheng Gong --- drivers/power/sgm4154x_chg_mmi/Android.mk | 3 +- drivers/power/sgm4154x_chg_mmi/Kbuild | 2 +- .../power/sgm4154x_chg_mmi/sgm4154x_charger.c | 335 ++++++++++++------ .../power/sgm4154x_chg_mmi/sgm4154x_charger.h | 6 +- 4 files changed, 235 insertions(+), 111 deletions(-) diff --git a/drivers/power/sgm4154x_chg_mmi/Android.mk b/drivers/power/sgm4154x_chg_mmi/Android.mk index cbedf20f1262..d859fc87f37d 100644 --- a/drivers/power/sgm4154x_chg_mmi/Android.mk +++ b/drivers/power/sgm4154x_chg_mmi/Android.mk @@ -8,6 +8,7 @@ LOCAL_MODULE := sgm4154x_charger.ko LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) - +LOCAL_ADDITIONAL_DEPENDENCIES := $(KERNEL_MODULES_OUT)/mmi_discrete_charger_class.ko +KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki include $(DLKM_DIR)/AndroidKernelModule.mk diff --git a/drivers/power/sgm4154x_chg_mmi/Kbuild b/drivers/power/sgm4154x_chg_mmi/Kbuild index 6e60f407aef7..8b62c67c5d66 100644 --- a/drivers/power/sgm4154x_chg_mmi/Kbuild +++ b/drivers/power/sgm4154x_chg_mmi/Kbuild @@ -5,4 +5,4 @@ EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include \ obj-m += sgm4154x_charger.o - +KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../mmi_discrete_charger/$(GKI_OBJ_MODULE_DIR)/Module.symvers diff --git a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c index 8fd9a0a00485..6a2717e8d41d 100644 --- a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c +++ b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c @@ -19,6 +19,9 @@ #include #include "sgm4154x_charger.h" +#include +#include + static struct power_supply_desc sgm4154x_power_supply_desc; /* SGM4154x REG06 BOOST_LIM[5:4], uV */ @@ -647,10 +650,28 @@ static int sgm4154x_get_state(struct sgm4154x_device *sgm, return 0; } -/*mahj:for build -static int sgm4154x_set_hiz_en(struct sgm4154x_device *sgm, bool hiz_en) + +static int sgm4154x_is_hiz_en(struct charger_device *chg_dev, bool *hiz_en) { int reg_val; + int ret = 0; + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + + ret = regmap_read(sgm->regmap, SGM4154x_CHRG_CTRL_0, ®_val); + if (ret){ + pr_err("%s read SGM4154x_CHRG_CTRL_0 fail\n",__func__); + return ret; + } + *hiz_en = !!(reg_val & SGM4154x_HIZ_EN); + + dev_notice(sgm->dev, "%s:%d", __func__, *hiz_en); + return ret; +} + +static int sgm4154x_set_hiz_en(struct charger_device *chg_dev, bool hiz_en) +{ + int reg_val; + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); dev_notice(sgm->dev, "%s:%d", __func__, hiz_en); reg_val = hiz_en ? SGM4154x_HIZ_EN : 0; @@ -658,7 +679,7 @@ static int sgm4154x_set_hiz_en(struct sgm4154x_device *sgm, bool hiz_en) return regmap_update_bits(sgm->regmap, SGM4154x_CHRG_CTRL_0, SGM4154x_HIZ_EN, reg_val); } -*/ + int sgm4154x_enable_charger(struct sgm4154x_device *sgm) { int ret; @@ -688,13 +709,19 @@ int sgm4154x_disable_watchdog(struct sgm4154x_device *sgm) return ret; } -int sgm4154x_disable_jeita(struct sgm4154x_device *sgm) +int sgm4154x_enable_hw_jeita(struct charger_device *chg_dev, bool en) { - int ret; - printk("sgm4154x_disable_jeita\n"); - ret = regmap_update_bits(sgm->regmap, SGM4154x_CHRG_CTRL_d, SGM4154x_JEITA_ENABLE_MASK, - SGM4154x_JEITA_DISABLE); - return ret; + int rc = 0; + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + + rc = regmap_update_bits(sgm->regmap, SGM4154x_CHRG_CTRL_d, SGM4154x_JEITA_ENABLE_MASK, + en ? SGM4154x_JEITA_ENABLE : SGM4154x_JEITA_DISABLE); + + pr_info("%s, %s hw jeita %s\n", __func__, + en ? "enable" : "disable", + rc ? "failed" : "success"); + + return rc; } int sgm4154x_disable_vindpm_int_pulse(struct sgm4154x_device *sgm) @@ -886,7 +913,6 @@ static int sgm4154x_property_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: - //case POWER_SUPPLY_PROP_CHARGING_ENABLED: return true; default: return false; @@ -903,12 +929,6 @@ static int sgm4154x_charger_set_property(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: ret = sgm4154x_set_input_curr_lim(sgm, val->intval); break; -/* case POWER_SUPPLY_PROP_CHARGING_ENABLED: - if (val->intval) - ret = sgm4154x_enable_charger(sgm); - else - ret = sgm4154x_disable_charger(sgm); - break;*/ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: ret = sgm4154x_set_input_volt_lim(sgm, val->intval); break; @@ -956,8 +976,6 @@ static int sgm4154x_charger_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; break; case SGM4154x_TERM_CHRG: - val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; - break; case SGM4154x_NOT_CHRGING: val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; break; @@ -1009,7 +1027,7 @@ static int sgm4154x_charger_get_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - //val->intval = state.vbus_adc; + sgm4154x_get_usb_voltage_now(sgm, &val->intval); break; case POWER_SUPPLY_PROP_CURRENT_NOW: @@ -1033,11 +1051,6 @@ static int sgm4154x_charger_get_property(struct power_supply *psy, val->intval = ret; ret = 0; break; - -/* case POWER_SUPPLY_PROP_CHARGING_ENABLED: - val->intval = !state.hiz_en; - break;*/ - default: return -EINVAL; } @@ -1209,24 +1222,22 @@ static void charger_monitor_work_func(struct work_struct *work) if (!sgm->state.chrg_type) { pr_err("%s not present vbus_status \n",__func__); - //goto OUT; + goto OUT; } - //MMI_STOPSHIP PMIC:force 5V2A charging - sgm4154x_set_input_curr_lim(sgm, 2400000); - sgm4154x_set_ichrg_curr(sgm, SGM4154x_ICHRG_I_DEF_uA); - sgm4154x_set_chrg_volt(sgm,4400000); - sgm4154x_dump_register(sgm); pr_err("%s\n",__func__); -//OUT: +OUT: schedule_delayed_work(&sgm->charge_monitor_work, 10*HZ); } static void sgm4154x_vbus_remove(struct sgm4154x_device * sgm) { dev_err(sgm->dev, "Vbus removed, disable charge\n"); + sgm->typec_apsd_rerun_done = false; + sgm->chg_dev->noti.apsd_done = false; + sgm->chg_dev->noti.hvdcp_done = false; sgm->real_charger_type = POWER_SUPPLY_TYPE_UNKNOWN; sgm4154x_disable_charger(sgm); sgm4154x_request_dpdm(sgm, true); @@ -1336,6 +1347,8 @@ static void hvdcp_detect_work_func(struct work_struct *work) sgm->real_charger_type = charger_type; //notify charging policy to update charger type + sgm->chg_dev->noti.hvdcp_done = true; + charger_dev_notify(sgm->chg_dev); err: return; @@ -1345,8 +1358,6 @@ static void charger_detect_work_func(struct work_struct *work) { struct delayed_work *charge_detect_delayed_work = NULL; struct sgm4154x_device * sgm = NULL; - //static int charge_type_old = 0; - int curr_in_limit = 0; struct sgm4154x_state state; int ret; @@ -1404,19 +1415,16 @@ static void charger_detect_work_func(struct work_struct *work) switch(sgm->state.chrg_type) { case SGM4154x_USB_SDP: pr_err("SGM4154x charger type: SDP\n"); - curr_in_limit = 500000; sgm->real_charger_type = POWER_SUPPLY_TYPE_USB; break; case SGM4154x_USB_CDP: pr_err("SGM4154x charger type: CDP\n"); - curr_in_limit = 1500000; sgm->real_charger_type = POWER_SUPPLY_TYPE_USB_CDP; break; case SGM4154x_USB_DCP: pr_err("SGM4154x charger type: DCP\n"); - curr_in_limit = 2400000; sgm->real_charger_type = POWER_SUPPLY_TYPE_USB_DCP; schedule_delayed_work(&sgm->hvdcp_detect_delayed_work, 0); break; @@ -1424,7 +1432,6 @@ static void charger_detect_work_func(struct work_struct *work) case SGM4154x_UNKNOWN: case SGM4154x_NON_STANDARD: pr_err("SGM4154x charger type: UNKNOWN\n"); - curr_in_limit = 500000; sgm->real_charger_type = POWER_SUPPLY_TYPE_USB_FLOAT; break; @@ -1434,29 +1441,21 @@ static void charger_detect_work_func(struct work_struct *work) default: pr_err("SGM4154x charger type: default\n"); - //curr_in_limit = 500000; - //break; return; } - curr_in_limit = 2400000; - //set charge parameters - dev_err(sgm->dev, "Update: curr_in_limit = %d\n", curr_in_limit); - sgm4154x_set_input_curr_lim(sgm, curr_in_limit); - sgm4154x_set_ichrg_curr(sgm, SGM4154x_ICHRG_I_DEF_uA); - sgm4154x_set_chrg_volt(sgm,4400000); - //notify charging policy to update charger type #endif //enable charge sgm4154x_enable_charger(sgm); sgm4154x_dump_register(sgm); - power_supply_changed(sgm->charger); + sgm->chg_dev->noti.apsd_done = true; + charger_dev_notify(sgm->chg_dev); return; vbus_remove: - power_supply_changed(sgm->charger); + charger_dev_notify(sgm->chg_dev); err: //release wakelock @@ -1478,43 +1477,6 @@ static irqreturn_t sgm4154x_irq_handler_thread(int irq, void *private) return IRQ_HANDLED; } -static int sgm4154x_usb_get_property(struct power_supply *psy, - enum power_supply_property psp, union power_supply_propval *val) -{ - struct sgm4154x_device *sgm = power_supply_get_drvdata(psy); - struct sgm4154x_state state; - int ret = 0; - - mutex_lock(&sgm->lock); - //ret = sgm4154x_get_state(sgm, &state); - state = sgm->state; - mutex_unlock(&sgm->lock); - if (ret) - return ret; - - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: -#if defined(__SGM41542_CHIP_ID__)|| defined(__SGM41516D_CHIP_ID__) - if ((state.chrg_type == SGM4154x_USB_SDP) || - (state.chrg_type == SGM4154x_USB_CDP)) - val->intval = 1; - else - val->intval = 0; -#endif - break; - case POWER_SUPPLY_PROP_PRESENT: - ret = sgm4154x_get_usb_present(sgm); - if (ret) - return -EINVAL; - val->intval = sgm->state.vbus_gd; - break; - default: - return -EINVAL; - } - - return 0; -} - static enum power_supply_property sgm4154x_power_supply_props[] = { POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_MODEL_NAME, @@ -1530,17 +1492,12 @@ static enum power_supply_property sgm4154x_power_supply_props[] = { POWER_SUPPLY_PROP_PRESENT }; -static enum power_supply_property sgm4154x_usb_props[] = { - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_PRESENT, -}; - static char *sgm4154x_charger_supplied_to[] = { "battery", }; static struct power_supply_desc sgm4154x_power_supply_desc = { - .name = "sgm4154x-charger", + .name = "charger", .type = POWER_SUPPLY_TYPE_MAINS, .usb_types = sgm4154x_usb_type, .num_usb_types = ARRAY_SIZE(sgm4154x_usb_type), @@ -1551,14 +1508,6 @@ static struct power_supply_desc sgm4154x_power_supply_desc = { .property_is_writeable = sgm4154x_property_is_writeable, }; -static const struct power_supply_desc sgm4154x_usb_desc = { - .name = "usb", - .type = POWER_SUPPLY_TYPE_USB, - .get_property = sgm4154x_usb_get_property, - .properties = sgm4154x_usb_props, - .num_properties = ARRAY_SIZE(sgm4154x_usb_props), -}; - static const struct regmap_config sgm4154x_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -1581,12 +1530,6 @@ static int sgm4154x_power_supply_init(struct sgm4154x_device *sgm, if (IS_ERR(sgm->charger)) return -EINVAL; - sgm->usb = devm_power_supply_register(sgm->dev, - &sgm4154x_usb_desc, - &psy_cfg); - if (IS_ERR(sgm->usb)) - return -EINVAL; - return 0; } @@ -1647,7 +1590,7 @@ static int sgm4154x_hw_init(struct sgm4154x_device *sgm) if (ret) goto err_out; - ret = sgm4154x_disable_jeita(sgm); + ret = sgm4154x_enable_hw_jeita(sgm->chg_dev, false); if (ret) goto err_out; @@ -1687,6 +1630,13 @@ static int sgm4154x_parse_dt(struct sgm4154x_device *sgm) u32 val = 0; int irq_gpio = 0, irqn = 0; int chg_en_gpio = 0; + + if (of_property_read_string(sgm->dev->of_node, "charger_name", + &sgm->chg_dev_name) < 0) { + sgm->chg_dev_name = "master_chg"; + pr_warn("no charger name\n"); + } + #if 0 ret = device_property_read_u32(sgm->dev, "watchdog-timer", &sgm->watchdog_timer); @@ -2089,6 +2039,170 @@ static int sgm4154x_parse_dt_adc_channels(struct sgm4154x_device *sgm) return 0; } +static int sgm4154x_set_icl(struct charger_device *chg_dev, u32 uA) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + + pr_info("%s set icl curr = %d\n", __func__, uA); + + return sgm4154x_set_input_curr_lim(sgm, uA); +} + +static int sgm4154x_get_icl(struct charger_device *chg_dev, u32 *uA) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + + *uA = sgm4154x_get_input_curr_lim(sgm); + + pr_info("%s get icl curr = %d\n", __func__, *uA); + + return 0; +} + +static int sgm4154x_enable_otg(struct charger_device *chg_dev, bool enable) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + int rc = 0; + + if (enable) + rc = sgm4154x_enable_vbus(sgm->otg_rdev); + else + rc = sgm4154x_disable_vbus(sgm->otg_rdev); + + pr_info("%s, %s otg %s\n", __func__, + enable ? "enable" : "disable", + rc ? "failed" : "success"); + + return rc; +} + +static int sgm4154x_enable_charging(struct charger_device *chg_dev, bool enable) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + int rc = 0; + + rc = regmap_update_bits(sgm->regmap, SGM4154x_CHRG_CTRL_1, SGM4154x_CHRG_EN, + enable ? SGM4154x_CHRG_EN : 0); + + pr_info("%s, %s charging %s\n", __func__, + enable ? "enable" : "disable", + rc ? "failed" : "success"); + + return rc; +} + +static int sgm4154x_set_charging_current(struct charger_device *chg_dev, u32 uA) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + int rc = 0; + + rc = sgm4154x_set_ichrg_curr(sgm, uA); + + pr_info("%s set charging curr = %d, %s\n", __func__, uA, rc ? "failed" : "success"); + + return rc; +} + +static int sgm4154x_set_charging_voltage(struct charger_device *chg_dev, u32 uV) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + int rc = 0; + + rc = sgm4154x_set_chrg_volt(sgm, uV); + + pr_info("%s set charging volt = %d, %s\n", __func__, uV, rc ? "failed" : "success"); + + return rc; +} + +static int sgm4154x_is_charging_halted(struct charger_device *chg_dev, bool *en) +{ + int rc = 0; + int chrg_stat = 0; + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + + rc = regmap_read(sgm->regmap, SGM4154x_CHRG_STAT, &chrg_stat); + if (rc){ + pr_err("%s read SGM4154x_CHRG_STAT fail\n",__func__); + return rc; + } + + chrg_stat = chrg_stat & SGM4154x_CHG_STAT_MASK; + switch(chrg_stat) { + case SGM4154x_NOT_CHRGING: + case SGM4154x_TERM_CHRG: + *en = true; + break; + case SGM4154x_PRECHRG: + case SGM4154x_FAST_CHRG: + *en = false; + break; + default: + break; + } + + return rc; +} + +static int sgm4154x_set_boost_current_limit(struct charger_device *chg_dev, u32 uA) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + int rc = 0; + + rc = sgm4154x_set_otg_current(sgm, uA); + + pr_info("%s set boost current limit = %d, %s\n", __func__, uA, rc ? "failed" : "success"); + + return rc; +} + +static int sgm4154x_get_real_charger_type(struct charger_device *chg_dev, int *chg_type) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + + *chg_type = sgm->real_charger_type; + + return 0; +} + +static int sgm4154x_dump_registers(struct charger_device *chg_dev, struct seq_file *m) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + int i = 0; + u32 reg = 0; + int rc = 0; + + for(i=0; i<=SGM4154x_CHRG_CTRL_f; i++) { + rc = regmap_read(sgm->regmap, i, ®); + if (rc) + continue; + seq_printf(m, "%s REG[0x%x]=0x%x\n", __func__, i, reg); + } + + return rc; +} + +static const struct charger_properties sgm4154x_chg_props = { + .alias_name = "sgm4154x", +}; + +static struct charger_ops sgm4154x_chg_ops = { + .get_real_charger_type = sgm4154x_get_real_charger_type, + .set_usb_suspend = sgm4154x_set_hiz_en, + .is_usb_suspend = sgm4154x_is_hiz_en, + .set_input_current = sgm4154x_set_icl, + .get_input_current = sgm4154x_get_icl, + .enable_hw_jeita = sgm4154x_enable_hw_jeita, + .enable_otg = sgm4154x_enable_otg, + .set_boost_current_limit = sgm4154x_set_boost_current_limit, + .enable_charging = sgm4154x_enable_charging, + .set_charging_current = sgm4154x_set_charging_current, + .set_constant_voltage = sgm4154x_set_charging_voltage, + .is_charge_halted = sgm4154x_is_charging_halted, + + .dump_registers = sgm4154x_dump_registers, + +}; static int sgm4154x_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -2138,6 +2252,15 @@ static int sgm4154x_probe(struct i2c_client *client, return ret; } + sgm->chg_dev = charger_device_register(sgm->chg_dev_name, + &client->dev, sgm, + &sgm4154x_chg_ops, + &sgm4154x_chg_props); + if (IS_ERR_OR_NULL(sgm->chg_dev)) { + ret = PTR_ERR(sgm->chg_dev); + return ret; + } + name = devm_kasprintf(sgm->dev, GFP_KERNEL, "%s", "sgm4154x suspend wakelock"); sgm->charger_wakelock = diff --git a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h index a893e373c5c8..b4f10b79a17c 100644 --- a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h +++ b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h @@ -183,7 +183,8 @@ /* customer define jeita paramter */ #define SGM4154x_JEITA_ENABLE_MASK GENMASK(0, 0) -#define SGM4154x_JEITA_DISABLE 0 +#define SGM4154x_JEITA_ENABLE BIT(0) +#define SGM4154x_JEITA_DISABLE 0 #define JEITA_TEMP_ABOVE_T4_CV 0 #define JEITA_TEMP_T3_TO_T4_CV 4100000 #define JEITA_TEMP_T2_TO_T3_CV 4350000 @@ -289,9 +290,8 @@ struct sgm4154x_device { struct sgm4154x_init_data init_data; struct sgm4154x_state state; u32 watchdog_timer; - #if defined(CONFIG_MTK_GAUGE_VERSION) && (CONFIG_MTK_GAUGE_VERSION == 30) + const char *chg_dev_name; struct charger_device *chg_dev; - #endif struct regulator_dev *otg_rdev; struct delayed_work charge_detect_delayed_work;