diff --git a/drivers/power/mmi_charger/Kbuild b/drivers/power/mmi_charger/Kbuild index 420e219dffd4..30520260b1b9 100755 --- a/drivers/power/mmi_charger/Kbuild +++ b/drivers/power/mmi_charger/Kbuild @@ -1,5 +1,6 @@ # add -Wall to try to catch everything we can. EXTRA_CFLAGS += -Wall EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/power/mmi_charger +EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include obj-m += mmi_charger.o diff --git a/drivers/power/mmi_charger/README b/drivers/power/mmi_charger/README index d45eb86cdbd2..fe1c591a127d 100644 --- a/drivers/power/mmi_charger/README +++ b/drivers/power/mmi_charger/README @@ -47,14 +47,20 @@ Benefit from this new Motorola charger driver design: Motorola common charger driver is built as DLKM: Module Name: mmi_charger.ko Log Tag: mmi_charger -IPC Log: /d/ipc_logging/charger/log +IPC Log: /d/ipc_logging/mmi_charger/log Support Platform: platform independent -Motorola low level charger driver is built as DLKM: +Motorola platform charger driver is built as DLKM: +(1) qti_glink_charger Module Name: qti_glink_charger.ko Log Tag: qti_glink_charger -IPC Log: /d/ipc_logging/charger/log -Support Platform: SM8350 or similar architecture(adsp and HLOS connection over glink) +IPC Log: /d/ipc_logging/mmi_charger/log +Support Platform: SM8350/SM7325(adsp and HLOS connection over glink) +(2) qpnp_smb_basic_charger +Module Name: qpnp_smb_basic_charger.ko +Log Tag: pmxxx_charger +IPC Log: /d/ipc_logging/mmi_charger/log +Support Platform: SM6125/SM710/SM636/SM7250/SM6350(qpnp smb charger with multi-battery support) devicetree properties description: mmi_charger: @@ -100,6 +106,18 @@ defaults to 0. Definition: Set this value to allow power in mW draw from QC3.0 charger, used when a QC3.0 charger is detected. If not set, 15W power is allowed. +- mmi,pd-power-max + Usage: optional + Value Type: + Definition: Set this value to allow power in mW draw from pd charger, used + when a pd charger is detected. If not set, 15W power is allowed. + +- mmi,wls-power-max + Usage: optional + Value Type: + Definition: Set this value to allow power in mW draw from wireless charger, used + when a wireless charger is detected. If not set, 5W power is allowed. + - mmi,heartbeat-interval Usage: optional Value Type: @@ -115,9 +133,11 @@ mmi_charger: mmi,charger { mmi,heartbeat-interval = <60000>; mmi,dcp-power-max = <10000>; mmi,hvdcp-power-max = <200000>; + mmi,pd-power-max = <200000>; + mmi,wls-power-max = <100000>; }; -qti_glink_charger: +platform low level charger: - mmi,mmi-temp-zones Usage: optional Value Type: Array of tuples of @@ -182,6 +202,14 @@ If not defined, defaults to 4000. in demo mode. This value is used as the max float voltage for battery charging in demo mode. If not defined, defaults to 4000. +- profile-ids-map + Usage: optional(qti_glink_charger specific) + Value Type: Array of + Definition: Unlimited array of arrays. Each internal array needs to have a set +of 2 data members, each one representing this sequence: Battery Profile ID +(in integer value), Battery Serial Number(provided by battery spec). Battery +profile ID will be set to 0 if this property is not specified. + - mmi,mmi-ffc-zones Usage: optional Value Type: Array of tuples of @@ -193,18 +221,30 @@ related to charging limitations based on temperature specifications when the battery supports Flash Fast Charging. - mmi,profile-data-block-size - Usage: optional + Usage: optional(qti_glink_charger specific) Value Type: Definition: It will define the profile data member count each block line in the profile data array. If not defined, defaults to 4. - mmi,profile-data - Usage: optional + Usage: optional(qti_glink_charger specific) Value Type: Array of tuples of Definition: Unlimited array of arrays. Each internal array needs to have a set with member count specified by property "mmi,profile-data-block-size". The content for each line is defined by the target user of the profile data. +- battery-names + Usage: optional(pm7250b_mmi specific) + Value Type: Array of + Definition: Unlimited array of arrays. Each internal array specifics a power supply + name which is used by the driver to get the battery information. + +- supplied-from + Usage: optional(pm7250b_mmi specific) + Value Type: Array of + Definition: Unlimited array of arrays. Each internal array specifics a power supply + name, the change of which the battery is sensitive to. + Example: qti_glink_charger: mmi,qti-glink-charger { compatible = "mmi,qti-glink-charger"; @@ -239,6 +279,70 @@ qti_glink_charger: mmi,qti-glink-charger { <45 4250 3600 3000>, <45 4350 3000 2000>, <60 4200 2185 0>; + profile-ids-map = "0", "unknown-sn", "100750", "SB18C85232"; +}; + +Single-battery Pack: +pm7250b_mmi: qcom,qpnp-smb5-mmi { + status = "ok"; + compatible = "mmi,qpnp-smb-basic-charger"; + mmi,pmic-revid = <&pm7250b_revid>; + mmi,usbpd-phandle = <&pm7250b_pdphy>; + battery-names = "battery"; + supplied-from = "qcom_battery", "mmi_battery"; + + mmi,chrg-iterm-ma = <243>; + mmi,vfloat-comp-uv = <20000>; + mmi,fg-iterm-ma = <400>; + mmi,max-fv-mv = <4450>; + mmi,max-fcc-ma = <4000>; + mmi,demo-fv-mv = <4000>; + mmi,df-serialnum = "SB18C85232"; + mmi,mmi-temp-zones = <0 4200 1000 0>, + <10 4200 2500 1000>, + <15 0 2500 2500>, + <45 4200 4000 4000>, + <60 4200 3600 0>; +}; + +Multi-battery Pack: +pm7250b_mmi: qcom,qpnp-smb5-mmi { + status = "ok"; + compatible = "mmi,qpnp-smb-basic-charger"; + mmi,pmic-revid = <&pm7250b_revid>; + mmi,usbpd-phandle = <&pm7250b_pdphy>; + battery-names = "fg_main_battery", "fg_flip_battery"; + supplied-from = "qcom_battery", "mmi_battery", "fg_main_battery", "fg_flip_battery"; +}; + +&main_battery { + mmi,chrg-iterm-ma = <50>; + mmi,vfloat-comp-uv = <20000>; + mmi,fg-iterm-ma = <100>; + mmi,max-fv-mv = <4450>; + mmi,max-fcc-ma = <4000>; + mmi,demo-fv-mv = <4000>; + mmi,df-serialnum = "main_battery-sn"; + mmi,mmi-temp-zones = <0 4200 243 0>, + <10 4200 608 243>, + <15 0 608 608>, + <45 4450 1210 1200>, + <60 4200 608 0>; +}; + +&flip_battery { + mmi,chrg-iterm-ma = <50>; + mmi,vfloat-comp-uv = <20000>; + mmi,fg-iterm-ma = <100>; + mmi,max-fv-mv = <4450>; + mmi,max-fcc-ma = <4000>; + mmi,demo-fv-mv = <4000>; + mmi,df-serialnum = "flip_battery-sn"; + mmi,mmi-temp-zones = <0 4200 300 0>, + <10 4200 750 300>, + <15 0 750 750>, + <45 4450 1250 1200>, + <60 4200 750 0>; }; ========================== diff --git a/drivers/power/mmi_charger/mmi_charger.c b/drivers/power/mmi_charger/mmi_charger.c index 44a37b9f6ce4..aaf9332695dc 100644 --- a/drivers/power/mmi_charger/mmi_charger.c +++ b/drivers/power/mmi_charger/mmi_charger.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "mmi_charger.h" @@ -177,6 +178,8 @@ struct mmi_charger_chip { int combo_soc; int combo_age; int combo_status; + int combo_health; + int combo_temp; int charge_full; int charge_full_design; int init_cycles; @@ -1368,7 +1371,7 @@ static int mmi_combine_battery_soc(struct mmi_charger_chip *chip) static int mmi_combine_battery_status(struct mmi_charger_chip *chip) { - int status = POWER_SUPPLY_STATUS_DISCHARGING; + int status = POWER_SUPPLY_STATUS_UNKNOWN; struct mmi_battery_pack *battery = NULL; list_for_each_entry(battery, &chip->battery_list, list) { @@ -1442,6 +1445,8 @@ static void mmi_update_battery_status(struct mmi_charger_chip *chip) int status; int cycles; bool mmi_changed = false; + int batt_temp; + int batt_health = POWER_SUPPLY_HEALTH_UNKNOWN; int charger_rate = POWER_SUPPLY_CHARGE_RATE_NONE; int max_charger_rate = POWER_SUPPLY_CHARGE_RATE_NONE; struct mmi_charger *charger = NULL; @@ -1537,12 +1542,32 @@ static void mmi_update_battery_status(struct mmi_charger_chip *chip) charge_rate[chip->max_charger_rate]); } + list_for_each_entry(battery, &chip->battery_list, list) { + if (batt_health == POWER_SUPPLY_HEALTH_UNKNOWN) { + batt_health = battery->health; + batt_temp = battery->info->batt_temp; + continue; + } + if (battery->info->batt_temp > batt_temp) { + batt_temp = battery->info->batt_temp; + batt_health = battery->health; + } + } + if (chip->combo_health != batt_health || + chip->combo_temp != batt_temp) { + mmi_changed = true; + chip->combo_health = batt_health; + chip->combo_temp = batt_temp; + } + if (mmi_changed) { power_supply_changed(chip->mmi_psy); - mmi_info(chip, "Combo status: soc:%d, status:%d," - " age:%d, cycles:%d, rate:%s\n", + mmi_info(chip, "Combo status: soc:%d, status:%d, temp:%d," + " health:%d, age:%d, cycles:%d, rate:%s\n", chip->combo_soc, chip->combo_status, + chip->combo_temp, + chip->combo_health, chip->combo_age, chip->combo_cycles, charge_rate[chip->max_charger_rate]); @@ -1624,7 +1649,7 @@ static void mmi_charger_heartbeat_work(struct work_struct *work) if (chip->max_charger_rate == POWER_SUPPLY_CHARGE_RATE_NONE) pm_relax(chip->dev); - __pm_relax(chip->mmi_hb_wake_source); + PM_RELAX(chip->mmi_hb_wake_source); } const char *mmi_get_battery_serialnumber(void) @@ -1893,7 +1918,7 @@ static enum alarmtimer_restart mmi_heartbeat_alarm_cb(struct alarm *alarm, mmi_info(chip, "HB alarm fired\n"); - __pm_stay_awake(chip->mmi_hb_wake_source); + PM_STAY_AWAKE(chip->mmi_hb_wake_source); cancel_delayed_work(&chip->heartbeat_work); /* Delay by 500 ms to allow devices to resume. */ schedule_delayed_work(&chip->heartbeat_work, @@ -1962,6 +1987,8 @@ static int mmi_charger_reboot(struct notifier_block *nb, static enum power_supply_property mmi_props[] = { POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_CHARGE_FULL, @@ -1979,6 +2006,12 @@ static int mmi_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_STATUS: val->intval = chip->combo_status; break; + case POWER_SUPPLY_PROP_HEALTH: + val->intval = chip->combo_health; + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = chip->combo_temp * 10; + break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = chip->combo_soc; break; @@ -2098,7 +2131,7 @@ static int mmi_parse_dt(struct mmi_charger_chip *chip) if ((rc == -EINVAL) || !charger_ability) { mmi_warn(chip, "mmi,charger is unused\n"); } else { - mmi_info(chip, "charger ability = %s\n", charger_ability); + mmi_info(chip, "QC charger ability = %s\n", charger_ability); if (strstr(charger_ability, "15W")) chip->hvdcp_pmax = CHARGER_POWER_15W; else if (strstr(charger_ability, "18W")) @@ -2112,7 +2145,7 @@ static int mmi_parse_dt(struct mmi_charger_chip *chip) if ((rc == -EINVAL) || !charger_ability) { mmi_warn(chip, "mmi,usb_dcp is unused\n"); } else { - mmi_info(chip, "charger ability = %s\n", charger_ability); + mmi_info(chip, "DCP charger ability = %s\n", charger_ability); if (strstr(charger_ability, "1.5A")) chip->dcp_pmax = CHARGER_POWER_7P5W; else if (strstr(charger_ability, "2A")) @@ -2137,6 +2170,7 @@ static int mmi_charger_probe(struct platform_device *pdev) chip->name = "mmi_charger"; chip->dev = &pdev->dev; psy_cfg.drv_data = chip; + psy_cfg.of_node = chip->dev->of_node; chip->suspended = 0; chip->combo_status = 0; chip->combo_age = 100; @@ -2170,11 +2204,7 @@ static int mmi_charger_probe(struct platform_device *pdev) INIT_LIST_HEAD(&chip->charger_list); INIT_LIST_HEAD(&chip->battery_list); INIT_DELAYED_WORK(&chip->heartbeat_work, mmi_charger_heartbeat_work); - chip->mmi_hb_wake_source = wakeup_source_register( -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,4,00) - chip->dev, -#endif - "mmi_hb_wake"); + PM_WAKEUP_REGISTER(chip->dev, chip->mmi_hb_wake_source, "mmi_hb_wake"); alarm_init(&chip->heartbeat_alarm, ALARM_BOOTTIME, mmi_heartbeat_alarm_cb); @@ -2303,7 +2333,7 @@ static int mmi_charger_remove(struct platform_device *pdev) &power_supply_mmi_attr_group); power_supply_put(chip->batt_psy); } - wakeup_source_unregister(chip->mmi_hb_wake_source); + PM_WAKEUP_UNREGISTER(chip->mmi_hb_wake_source); ipc_log_context_destroy(chip->ipc_log); return 0; @@ -2317,7 +2347,7 @@ static void mmi_charger_shutdown(struct platform_device *pdev) kfree(chip->batt_uenvp[0]); chip->batt_uenvp[0] = NULL; } - wakeup_source_unregister(chip->mmi_hb_wake_source); + PM_WAKEUP_UNREGISTER(chip->mmi_hb_wake_source); return; } diff --git a/drivers/power/mmi_charger/mmi_charger.h b/drivers/power/mmi_charger/mmi_charger.h index 69836070c818..38d9d244cd12 100644 --- a/drivers/power/mmi_charger/mmi_charger.h +++ b/drivers/power/mmi_charger/mmi_charger.h @@ -100,7 +100,7 @@ struct mmi_charger_constraint { }; struct mmi_charger_driver { - char *name; + const char *name; struct device *dev; int (*get_batt_info)(void *data, struct mmi_battery_info *batt_info); int (*get_chg_info)(void *data, struct mmi_charger_info *chg_info);