[1 of 2][10277827]modify charging driver
###%%%comment:[1 of 2]modify charging driver
###%%%bug number:10277827
###%%%product name:n10
###%%%root cause:Coding
###%%%Bug category:T2M
###%%%regression response:NO
###%%%regression comments:
###%%%Module_Impact:kernel
###%%%Test_Suggestion:device can be charged
###%%%Solution:porting tct common charge driver
###%%%Test_Report:ok
###%%%VAL Can Test:No
Change-Id: I47330b3d1bda501eea0bf39ce89b563f20412609
diff --git a/arch/arm64/configs/vendor/n10-perf_defconfig b/arch/arm64/configs/vendor/n10-perf_defconfig
index 6ae0769..58e095e 100644
--- a/arch/arm64/configs/vendor/n10-perf_defconfig
+++ b/arch/arm64/configs/vendor/n10-perf_defconfig
@@ -376,8 +376,8 @@
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_SMB5=y
-CONFIG_SMB1390_CHARGE_PUMP_PSY=y
-CONFIG_SMB1355_SLAVE_CHARGER=y
+CONFIG_SMB1390_CHARGE_PUMP_PSY=n
+CONFIG_SMB1355_SLAVE_CHARGER=n
CONFIG_QPNP_QG=y
CONFIG_SMB1398_CHARGER=y
CONFIG_THERMAL=y
@@ -452,22 +452,22 @@
CONFIG_USB_HIDDEV=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD=n
+CONFIG_USB_EHCI_HCD_PLATFORM=n
+CONFIG_USB_OHCI_HCD=n
+CONFIG_USB_OHCI_HCD_PLATFORM=n
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_MSM=y
-CONFIG_USB_ISP1760=y
-CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_ISP1760=n
+CONFIG_USB_ISP1760_HOST_ROLE=n
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_NOP_USB_XCEIV=y
-CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_USB_MSM_SSPHY_QMP=n
CONFIG_MSM_QUSB_PHY=y
-CONFIG_MSM_HSUSB_PHY=y
-CONFIG_USB_QCOM_EMU_PHY=y
+CONFIG_MSM_HSUSB_PHY=n
+CONFIG_USB_QCOM_EMU_PHY=n
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=900
CONFIG_USB_CONFIGFS=y
@@ -590,7 +590,7 @@
CONFIG_MSM_PIL_SSR_GENERIC=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_QCOM_DCC_V2=y
-CONFIG_QCOM_EUD=y
+CONFIG_QCOM_EUD=n
CONFIG_QCOM_MINIDUMP=y
CONFIG_QCOM_FSA4480_I2C=y
CONFIG_QCOM_WATCHDOG_V2=y
@@ -715,4 +715,8 @@
CONFIG_T2M_SND_MBHC=y
CONFIG_T2M_SND_HPH_SWITCH=y
CONFIG_T2M_SND_N10=y
-#[T2MNB_BSP] audio end
\ No newline at end of file
+#[T2MNB_BSP] audio end
+CONFIG_TCT_CHG_AUTOTEST=y
+CONFIG_TCT_PM7250_COMMON=y
+CONFIG_USB_PD_LOG_LVL=1
+
diff --git a/arch/arm64/configs/vendor/n10_defconfig b/arch/arm64/configs/vendor/n10_defconfig
index 8858d86..5338249 100644
--- a/arch/arm64/configs/vendor/n10_defconfig
+++ b/arch/arm64/configs/vendor/n10_defconfig
@@ -384,8 +384,8 @@
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_QPNP_SMB5=y
-CONFIG_SMB1390_CHARGE_PUMP_PSY=y
-CONFIG_SMB1355_SLAVE_CHARGER=y
+CONFIG_SMB1390_CHARGE_PUMP_PSY=n
+CONFIG_SMB1355_SLAVE_CHARGER=n
CONFIG_QPNP_QG=y
CONFIG_SMB1398_CHARGER=y
CONFIG_THERMAL=y
@@ -460,22 +460,22 @@
CONFIG_USB_HIDDEV=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD=n
+CONFIG_USB_EHCI_HCD_PLATFORM=n
+CONFIG_USB_OHCI_HCD=n
+CONFIG_USB_OHCI_HCD_PLATFORM=n
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_MSM=y
-CONFIG_USB_ISP1760=y
-CONFIG_USB_ISP1760_HOST_ROLE=y
+CONFIG_USB_ISP1760=n
+CONFIG_USB_ISP1760_HOST_ROLE=n
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_NOP_USB_XCEIV=y
-CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_USB_MSM_SSPHY_QMP=n
CONFIG_MSM_QUSB_PHY=y
-CONFIG_MSM_HSUSB_PHY=y
-CONFIG_USB_QCOM_EMU_PHY=y
+CONFIG_MSM_HSUSB_PHY=n
+CONFIG_USB_QCOM_EMU_PHY=n
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VBUS_DRAW=900
CONFIG_USB_CONFIGFS=y
@@ -608,7 +608,7 @@
CONFIG_MSM_PIL_SSR_GENERIC=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_QCOM_DCC_V2=y
-CONFIG_QCOM_EUD=y
+CONFIG_QCOM_EUD=n
CONFIG_QCOM_MINIDUMP=y
CONFIG_MSM_CORE_HANG_DETECT=y
CONFIG_MSM_GLADIATOR_HANG_DETECT=y
@@ -784,3 +784,6 @@
CONFIG_T2M_SND_N10=y
#[T2MNB_BSP] audio end
+CONFIG_TCT_CHG_AUTOTEST=y
+CONFIG_TCT_PM7250_COMMON=y
+CONFIG_USB_PD_LOG_LVL=1
diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c
index 8467d0f..04c3107 100644
--- a/drivers/iio/adc/qcom-vadc-common.c
+++ b/drivers/iio/adc/qcom-vadc-common.c
@@ -247,6 +247,78 @@
* Alium.
*/
static const struct vadc_map_pt adcmap_batt_therm_30k[] = {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ {1673, -400},
+ {1649, -380},
+ {1623, -360},
+ {1596, -340},
+ {1566, -320},
+ {1535, -300},
+ {1502, -280},
+ {1467, -260},
+ {1430, -240},
+ {1392, -220},
+ {1352, -200},
+ {1311, -180},
+ {1269, -160},
+ {1226, -140},
+ {1182, -120},
+ {1138, -100},
+ {1093, -80},
+ {1049, -60},
+ {1004, -40},
+ {960, -20},
+ {917, 0},
+ {874, 20},
+ {832, 40},
+ {791, 60},
+ {752, 80},
+ {713, 100},
+ {676, 120},
+ {640, 140},
+ {606, 160},
+ {573, 180},
+ {541, 200},
+ {511, 220},
+ {483, 240},
+ {455, 260},
+ {430, 280},
+ {405, 300},
+ {382, 320},
+ {360, 340},
+ {340, 360},
+ {320, 380},
+ {302, 400},
+ {285, 420},
+ {269, 440},
+ {253, 460},
+ {239, 480},
+ {225, 500},
+ {213, 520},
+ {201, 540},
+ {190, 560},
+ {179, 580},
+ {169, 600},
+ {160, 620},
+ {152, 640},
+ {143, 660},
+ {136, 680},
+ {128, 700},
+ {122, 720},
+ {115, 740},
+ {109, 760},
+ {104, 780},
+ {98, 800},
+ {93, 820},
+ {89, 840},
+ {84, 860},
+ {80, 880},
+ {76, 900},
+ {73, 920},
+ {69, 940},
+ {66, 960},
+ {63, 980}
+#else
{1864, -400},
{1863, -380},
{1861, -360},
@@ -317,6 +389,7 @@
{349, 940},
{332, 960},
{315, 980}
+#endif
};
/*
@@ -1113,6 +1186,7 @@
/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
+
voltage = div64_s64(voltage, (data->full_scale_code_volt
* 1000));
diff --git a/drivers/of/of_batterydata.c b/drivers/of/of_batterydata.c
index 0a6ad38..e033ea3 100644
--- a/drivers/of/of_batterydata.c
+++ b/drivers/of/of_batterydata.c
@@ -371,6 +371,16 @@
if (best_node == NULL) {
pr_err("No battery data found\n");
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ for_each_child_of_node(batterydata_container_node, node)
+ {
+ if(of_property_read_bool(node,"qcom,default-battery-type"))
+ {
+ best_node = node;
+ break;
+ }
+ }
+#endif
return best_node;
}
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index 633e006..4edfe51 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -122,7 +122,12 @@
psy->changed = true;
pm_stay_awake(&psy->dev);
spin_unlock_irqrestore(&psy->changed_lock, flags);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_work(private_chg_wq, &psy->changed_work);
+#else
schedule_work(&psy->changed_work);
+#endif
}
EXPORT_SYMBOL_GPL(power_supply_changed);
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index a8ad746..896e536 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -81,6 +81,17 @@
"Unknown", "System", "Device"
};
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static const char * const power_supply_usbc_text[] = {
+ "Nothing attached", "Sink attached", "Powered cable w/ sink",
+ "Debug Accessory", "Audio Adapter", "Powered cable w/o sink",
+ "Source Debug Accessory (FMB)",
+ "Source attached (default current)",
+ "Source attached (medium current)",
+ "Source attached (high current)",
+ "Non compliant",
+};
+#else
static const char * const power_supply_usbc_text[] = {
"Nothing attached", "Sink attached", "Powered cable w/ sink",
"Debug Accessory", "Audio Adapter", "Powered cable w/o sink",
@@ -89,6 +100,7 @@
"Source attached (high current)",
"Non compliant",
};
+#endif
static const char * const power_supply_usbc_pr_text[] = {
"none", "dual power role", "sink", "source"
@@ -383,7 +395,11 @@
POWER_SUPPLY_ATTR(esr_count),
POWER_SUPPLY_ATTR(buck_freq),
POWER_SUPPLY_ATTR(boost_current),
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ POWER_SUPPLY_ATTR(safety_timer_enable),
+#else
POWER_SUPPLY_ATTR(safety_timer_enabled),
+#endif
POWER_SUPPLY_ATTR(charge_done),
POWER_SUPPLY_ATTR(flash_active),
POWER_SUPPLY_ATTR(flash_trigger),
@@ -479,6 +495,9 @@
POWER_SUPPLY_ATTR(cp_toggle_switcher),
POWER_SUPPLY_ATTR(cp_irq_status),
POWER_SUPPLY_ATTR(cp_ilim),
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ POWER_SUPPLY_ATTR(tcl_fixtemp),
+#endif
POWER_SUPPLY_ATTR(irq_status),
POWER_SUPPLY_ATTR(parallel_output_mode),
POWER_SUPPLY_ATTR(cc_toggle_enable),
diff --git a/drivers/power/supply/qcom/Kconfig b/drivers/power/supply/qcom/Kconfig
index 9581455..4cb8876 100644
--- a/drivers/power/supply/qcom/Kconfig
+++ b/drivers/power/supply/qcom/Kconfig
@@ -162,6 +162,15 @@
sizes. The HL6111R has voltage, current and temperature
protection mechanisms, an I2C interface, and a PSNS output.
+# [start] dis-/enable chg common patches based on pm7250b chipset.
+config TCT_PM7250_COMMON
+ bool "Enable common chg patches for pm7250&pm7250B platform"
+ default n
+ select TCT_INIT_SPEED_UP
+ help
+ Say Y here to enable common chg patches.
+ Say N to disable these chg patches.
+# [ended]
config SMB1398_CHARGER
tristate "SMB1398 power supply framework based driver"
depends on MFD_I2C_PMIC
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index ec45b7d..5cb56c4 100644
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -103,6 +103,9 @@
enum power_supply_type charger_type;
/* debugfs directory */
struct dentry *dfs_root;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ bool last_input_present;
+#endif
u32 float_voltage_uv;
};
@@ -119,6 +122,15 @@
static int debug_mask;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define pl_dbg(chip, reason, fmt, ...) \
+ do { \
+ if (debug_mask & (reason)) \
+ pr_err_ratelimited(fmt, ##__VA_ARGS__); \
+ else \
+ pr_debug(fmt, ##__VA_ARGS__); \
+ } while (0)
+#else
#define pl_dbg(chip, reason, fmt, ...) \
do { \
if (debug_mask & (reason)) \
@@ -126,6 +138,7 @@
else \
pr_debug(fmt, ##__VA_ARGS__); \
} while (0)
+#endif
#define IS_USBIN(mode) ((mode == POWER_SUPPLY_PL_USBIN_USBIN) \
|| (mode == POWER_SUPPLY_PL_USBIN_USBIN_EXT))
@@ -153,6 +166,20 @@
return !!chip->usb_psy;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static bool is_dc_available(struct pl_data *chip)
+{
+ if (chip->dc_psy)
+ return true;
+
+ chip->dc_psy = power_supply_get_by_name("dc");
+ if (!chip->dc_psy)
+ return false;
+
+ return true;
+}
+#endif
+
static bool is_cp_available(struct pl_data *chip)
{
if (!chip->cp_master_psy)
@@ -269,9 +296,11 @@
if (!is_cp_available(chip))
return;
+#if !defined(CONFIG_TCT_PM7250_COMMON)
if (cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE)
== POWER_SUPPLY_PL_OUTPUT_VPH)
return;
+#endif
target_icl = get_adapter_icl_based_ilim(chip);
ilim = (target_icl > 0) ? min(ilim, target_icl) : ilim;
@@ -286,6 +315,10 @@
if (chip->cp_ilim_votable) {
fcc = get_effective_result_locked(chip->fcc_votable);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote(chip->cp_ilim_votable, voter, true, ilim);
+#else
/*
* If FCC >= (2 * MIN_ICL) then it is safe to enable CP
* with MIN_ICL.
@@ -297,6 +330,7 @@
vote(chip->cp_ilim_votable, voter, true, pval.intval);
else
vote(chip->cp_ilim_votable, voter, true, ilim);
+#endif
/*
* Rerun FCC votable to ensure offset for ILIM compensation is
@@ -938,6 +972,64 @@
&pval);
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static int pl_fcc_vote_callback(struct votable *votable, void *data,
+ int total_fcc_ua, const char *client)
+{
+ struct pl_data *chip = data;
+ int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0;
+ int cp_output_mode = POWER_SUPPLY_PL_OUTPUT_NONE;
+ union power_supply_propval pval = {0, };
+ int rc = 0;
+
+ if (total_fcc_ua < 0)
+ return 0;
+
+ if (!chip->main_psy)
+ return 0;
+
+ if (!chip->cp_disable_votable)
+ chip->cp_disable_votable = find_votable("CP_DISABLE");
+
+ if (chip->cp_disable_votable) {
+ cp_output_mode = cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE);
+ if (cp_output_mode == POWER_SUPPLY_PL_OUTPUT_VBAT
+ || cp_output_mode == POWER_SUPPLY_PL_OUTPUT_VPH) {
+ rc = power_supply_get_property(chip->cp_master_psy,
+ POWER_SUPPLY_PROP_MIN_ICL, &pval);
+ if (!rc) {
+ /*
+ * With VPH output configuration ILIM is configured
+ * independent of battery FCC, disable CP here if FCC/2
+ * falls below MIN_ICL supported by CP.
+ */
+ if (total_fcc_ua <= (pval.intval << 1))
+ vote(chip->cp_disable_votable, FCC_VOTER,
+ true, 0);
+ else
+ vote(chip->cp_disable_votable, FCC_VOTER,
+ false, 0);
+ }
+ }
+ }
+
+ if (chip->pl_mode != POWER_SUPPLY_PL_NONE) {
+ get_fcc_split(chip, total_fcc_ua, &master_fcc_ua,
+ &slave_fcc_ua);
+
+ if (slave_fcc_ua > MINIMUM_PARALLEL_FCC_UA) {
+ vote(chip->pl_disable_votable, PL_FCC_LOW_VOTER,
+ false, 0);
+ } else {
+ vote(chip->pl_disable_votable, PL_FCC_LOW_VOTER,
+ true, 0);
+ }
+ }
+
+ rerun_election(chip->pl_disable_votable);
+ return 0;
+}
+#else
static int pl_fcc_vote_callback(struct votable *votable, void *data,
int total_fcc_ua, const char *client)
{
@@ -1022,6 +1114,7 @@
return 0;
}
+#endif
static void fcc_stepper_work(struct work_struct *work)
{
@@ -1185,8 +1278,13 @@
cp_configure_ilim(chip, FCC_VOTER, chip->slave_fcc_ua / 2);
if (reschedule_ms) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chip->fcc_stepper_work,
+ msecs_to_jiffies(reschedule_ms));
+#else
schedule_delayed_work(&chip->fcc_stepper_work,
msecs_to_jiffies(reschedule_ms));
+#endif
pr_debug("Rescheduling FCC_STEPPER work\n");
return;
}
@@ -1206,6 +1304,80 @@
return true;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static bool is_usb_present(struct pl_data *chip)
+{
+ union power_supply_propval pval = {0, };
+
+ if (is_usb_available(chip))
+ power_supply_get_property(chip->usb_psy,
+ POWER_SUPPLY_PROP_PRESENT, &pval);
+
+ return pval.intval ? true : false;
+}
+
+static bool is_dc_present(struct pl_data *chip)
+{
+ union power_supply_propval pval = {0, };
+
+ if (is_dc_available(chip))
+ power_supply_get_property(chip->dc_psy,
+ POWER_SUPPLY_PROP_PRESENT, &pval);
+
+ return pval.intval ? true : false;
+}
+
+static bool is_input_present(struct pl_data *chip)
+{
+ return is_usb_present(chip) || is_dc_present(chip);
+}
+
+static void handle_safety_timer(struct pl_data *chip)
+{
+ int rc = 0;
+ union power_supply_propval pval = {1, };
+
+ if (!chip->batt_psy || !chip->last_input_present) {
+ pl_dbg(chip, PR_PARALLEL, "skip, input:%d\n",
+ chip->last_input_present);
+ return;
+ }
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE, &pval);
+ if (rc < 0 || pval.intval) {
+ pl_dbg(chip, PR_PARALLEL, "skip, rc=%d, val=%d\n",
+ rc, pval.intval);
+ return;
+ }
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_HEALTH, &pval);
+ if (rc < 0
+ || pval.intval != POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE) {
+ pl_dbg(chip, PR_PARALLEL, "skip, rc=%d, health=%d\n",
+ rc, pval.intval);
+ return;
+ }
+
+ pval.intval = 0;
+ rc = power_supply_set_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_CHARGING_ENABLED, &pval);
+ if (rc < 0) {
+ pl_dbg(chip, PR_PARALLEL, "failed to set chg disabled\n");
+ return;
+ }
+
+ pval.intval = 1;
+ rc = power_supply_set_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_CHARGING_ENABLED, &pval);
+ if (rc < 0) {
+ pl_dbg(chip, PR_PARALLEL, "failed to set chg enabled\n");
+ return;
+ }
+}
+#endif
+
#define PARALLEL_FLOAT_VOLTAGE_DELTA_UV 50000
static int pl_fv_vote_callback(struct votable *votable, void *data,
int fv_uv, const char *client)
@@ -1229,7 +1401,11 @@
return rc;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chip->pl_psy && chip->pl_mode != POWER_SUPPLY_PL_NONE) {
+#else
if (chip->pl_mode != POWER_SUPPLY_PL_NONE) {
+#endif
pval.intval += PARALLEL_FLOAT_VOLTAGE_DELTA_UV;
rc = power_supply_set_property(chip->pl_psy,
POWER_SUPPLY_PROP_VOLTAGE_MAX, &pval);
@@ -1283,6 +1459,7 @@
if (client == NULL)
icl_ua = INT_MAX;
+#if !defined(CONFIG_TCT_PM7250_COMMON)
/*
* Disable parallel for new ICL vote - the call to split_settled will
* ensure that all the input current limit gets assigned to the main
@@ -1304,6 +1481,7 @@
else
schedule_delayed_work(&chip->status_change_work,
msecs_to_jiffies(PL_DELAY_MS));
+#endif
/* rerun AICL */
/* get the settled current */
@@ -1333,7 +1511,9 @@
POWER_SUPPLY_PROP_CURRENT_MAX,
&pval);
+#if !defined(CONFIG_TCT_PM7250_COMMON)
vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0);
+#endif
/* Configure ILIM based on AICL result only if input mode is USBMID */
if (cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE)
@@ -1352,10 +1532,10 @@
if (!dc_present)
cp_configure_ilim(chip, ICL_CHANGE_VOTER, icl_ua);
}
-
- return 0;
+ return 0;//zxzcheck
}
+
static void pl_disable_forever_work(struct work_struct *work)
{
struct pl_data *chip = container_of(work,
@@ -1416,8 +1596,19 @@
}
total_fcc_ua = get_effective_result_locked(chip->fcc_votable);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (total_fcc_ua < 0) {
+ pr_err("skip, Invalid FCC:%d\n", total_fcc_ua);
+ return -EINVAL;
+ }
+#endif
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chip->pl_psy && chip->pl_mode != POWER_SUPPLY_PL_NONE
+ && !pl_disable) {
+#else
if (chip->pl_mode != POWER_SUPPLY_PL_NONE && !pl_disable) {
+#endif
rc = validate_parallel_icl(chip, &disable);
if (rc < 0)
return rc;
@@ -1452,8 +1643,13 @@
if (chip->step_fcc) {
vote(chip->pl_awake_votable, FCC_STEPPER_VOTER,
true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chip->fcc_stepper_work,
+ 0);
+#else
schedule_delayed_work(&chip->fcc_stepper_work,
0);
+#endif
}
} else {
/*
@@ -1555,8 +1751,13 @@
/* main psy gets all share */
vote(chip->fcc_main_votable, MAIN_FCC_VOTER, true,
total_fcc_ua);
+//#if defined(CONFIG_TCT_PM7250_COMMON) && !defined(CONFIG_TCT_OTTAWA_CHG_PATCH)
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ cp_ilim = total_fcc_ua;
+#else
cp_ilim = total_fcc_ua - get_effective_result_locked(
chip->fcc_main_votable);
+#endif
if (cp_ilim > 0)
cp_configure_ilim(chip, FCC_VOTER, cp_ilim / 2);
@@ -1569,8 +1770,13 @@
if (chip->step_fcc) {
vote(chip->pl_awake_votable, FCC_STEPPER_VOTER,
true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chip->fcc_stepper_work,
+ 0);
+#else
schedule_delayed_work(&chip->fcc_stepper_work,
0);
+#endif
}
}
@@ -1584,8 +1790,10 @@
chip->pl_disable = (bool)pl_disable;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
pl_dbg(chip, PR_PARALLEL, "parallel charging %s\n",
pl_disable ? "disabled" : "enabled");
+#endif
return 0;
}
@@ -1593,9 +1801,11 @@
static int pl_enable_indirect_vote_callback(struct votable *votable,
void *data, int pl_enable, const char *client)
{
+#if !defined(CONFIG_TCT_PM7250_COMMON)
struct pl_data *chip = data;
vote(chip->pl_disable_votable, PL_INDIRECT_VOTER, !pl_enable, 0);
+#endif
return 0;
}
@@ -1614,6 +1824,7 @@
return 0;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
static bool is_parallel_available(struct pl_data *chip)
{
union power_supply_propval pval = {0, };
@@ -1678,7 +1889,9 @@
return true;
}
+#endif
+#if !defined(CONFIG_TCT_PM7250_COMMON)
static void handle_main_charge_type(struct pl_data *chip)
{
union power_supply_propval pval = {0, };
@@ -1733,10 +1946,12 @@
/* remember the new state only if it isn't any of the above */
chip->charge_type = pval.intval;
}
+#endif
#define MIN_ICL_CHANGE_DELTA_UA 300000
static void handle_settled_icl_change(struct pl_data *chip)
{
+#if !defined(CONFIG_TCT_PM7250_COMMON)
union power_supply_propval pval = {0, };
int new_total_settled_ua;
int rc;
@@ -1776,9 +1991,11 @@
vote(chip->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0);
else
vote(chip->pl_enable_votable_indirect, USBIN_I_VOTER, true, 0);
+#endif
rerun_election(chip->fcc_votable);
+#if !defined(CONFIG_TCT_PM7250_COMMON)
if (IS_USBIN(chip->pl_mode)) {
/*
* call aicl split only when USBIN_USBIN and enabled
@@ -1805,8 +2022,10 @@
split_settled(chip);
}
}
+#endif
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
static void handle_parallel_in_taper(struct pl_data *chip)
{
union power_supply_propval pval = {0, };
@@ -1835,7 +2054,9 @@
return;
}
}
+#endif
+#if !defined(CONFIG_TCT_PM7250_COMMON)
static void handle_usb_change(struct pl_data *chip)
{
int rc;
@@ -1873,12 +2094,25 @@
chip->charger_type = pval.intval;
}
}
+#endif
static void status_change_work(struct work_struct *work)
{
struct pl_data *chip = container_of(work,
struct pl_data, status_change_work.work);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ bool input_present = false;
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (!is_batt_available(chip)) {
+ pl_dbg(chip, PR_PARALLEL, "skip for batt_psy is NULL\n");
+ __pm_relax(chip->pl_ws);
+ return;
+ }
+#endif
+
if (!chip->main_psy && is_main_available(chip)) {
/*
* re-run election for FCC/FV/ICL once main_psy
@@ -1890,18 +2124,58 @@
rerun_election(chip->fv_votable);
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (!chip->main_psy) {
+ pl_dbg(chip, PR_PARALLEL, "skip for main_psy is NULL\n");
+ __pm_relax(chip->pl_ws);
+ return;
+ }
+#else
if (!chip->main_psy)
return;
+#endif
+#if !defined(CONFIG_TCT_PM7250_COMMON)
if (!is_batt_available(chip))
return;
+#endif
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ input_present = is_input_present(chip);
+ if (!input_present && !chip->last_input_present) {
+ pl_dbg(chip, PR_PARALLEL, "skip for input_present=%d\n",
+ input_present);
+ __pm_relax(chip->pl_ws);
+ return;
+ }
+ chip->last_input_present = input_present;
+#endif
+
+#if !defined(CONFIG_TCT_PM7250_COMMON)
is_parallel_available(chip);
+#endif
+#if !defined(CONFIG_TCT_PM7250_COMMON)
handle_usb_change(chip);
+#endif
+
+#if !defined(CONFIG_TCT_PM7250_COMMON)
handle_main_charge_type(chip);
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ handle_safety_timer(chip);
+#endif
+
handle_settled_icl_change(chip);
+
+#if !defined(CONFIG_TCT_PM7250_COMMON)
handle_parallel_in_taper(chip);
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ __pm_relax(chip->pl_ws);
+#endif
}
static int pl_notifier_call(struct notifier_block *nb,
@@ -1913,10 +2187,25 @@
if (ev != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (delayed_work_pending(&chip->status_change_work)) {
+ pr_debug("status_change_work pending now, skip\n");
+ return NOTIFY_OK;
+ }
+#endif
+
if ((strcmp(psy->desc->name, "parallel") == 0)
|| (strcmp(psy->desc->name, "battery") == 0)
|| (strcmp(psy->desc->name, "main") == 0))
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ {
+ __pm_stay_awake(chip->pl_ws);
+ queue_delayed_work(private_chg_wq,
+ &chip->status_change_work, 0);
+ }
+#else
schedule_delayed_work(&chip->status_change_work, 0);
+#endif
return NOTIFY_OK;
}
@@ -1937,7 +2226,12 @@
static int pl_determine_initial_status(struct pl_data *chip)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ __pm_stay_awake(chip->pl_ws);
status_change_work(&chip->status_change_work.work);
+#else
+ status_change_work(&chip->status_change_work.work);
+#endif
return 0;
}
@@ -2052,6 +2346,11 @@
chip->pl_disable_votable = NULL;
goto destroy_votable;
}
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chip->pl_psy = NULL;
+#endif
+
vote(chip->pl_disable_votable, CHG_STATE_VOTER, true, 0);
vote(chip->pl_disable_votable, TAPER_END_VOTER, false, 0);
vote(chip->pl_disable_votable, PARALLEL_PSY_VOTER, true, 0);
diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h
index 6b74327..bc3982f 100644
--- a/drivers/power/supply/qcom/qg-core.h
+++ b/drivers/power/supply/qcom/qg-core.h
@@ -69,6 +69,9 @@
bool qg_ext_sense;
bool use_cp_iin_sns;
bool use_s7_ocv;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ bool tt_enabled;
+#endif
bool qg_sleep_config;
bool qg_fast_chg_cfg;
bool fvss_enable;
@@ -108,6 +111,11 @@
struct mutex data_lock;
struct mutex soc_lock;
wait_queue_head_t qg_wait_q;
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ struct wakeup_source *qg_ws;
+#endif
+
struct votable *awake_votable;
struct votable *vbatt_irq_disable_votable;
struct votable *fifo_irq_disable_votable;
diff --git a/drivers/power/supply/qcom/qg-defs.h b/drivers/power/supply/qcom/qg-defs.h
index 5caeb49..2fa3fcb 100644
--- a/drivers/power/supply/qcom/qg-defs.h
+++ b/drivers/power/supply/qcom/qg-defs.h
@@ -6,6 +6,15 @@
#ifndef __QG_DEFS_H__
#define __QG_DEFS_H__
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define qg_dbg(chip, reason, fmt, ...) \
+ do { \
+ if (*chip->debug_mask & (reason)) \
+ pr_err(fmt, ##__VA_ARGS__); \
+ else \
+ pr_debug(fmt, ##__VA_ARGS__); \
+ } while (0)
+#else
#define qg_dbg(chip, reason, fmt, ...) \
do { \
if (*chip->debug_mask & (reason)) \
@@ -13,6 +22,7 @@
else \
pr_debug(fmt, ##__VA_ARGS__); \
} while (0)
+#endif
#define is_between(left, right, value) \
(((left) >= (right) && (left) >= (value) \
diff --git a/drivers/power/supply/qcom/qg-soc.c b/drivers/power/supply/qcom/qg-soc.c
index 5b6a70b..010a4e1 100644
--- a/drivers/power/supply/qcom/qg-soc.c
+++ b/drivers/power/supply/qcom/qg-soc.c
@@ -629,7 +629,12 @@
/* timer callback runs in atomic context, cannot use voter */
pm_stay_awake(chip->dev);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_work(private_chg_wq, &chip->scale_soc_work);
+#else
schedule_work(&chip->scale_soc_work);
+#endif
return ALARMTIMER_NORESTART;
}
diff --git a/drivers/power/supply/qcom/qg-util.c b/drivers/power/supply/qcom/qg-util.c
index 9359d7c..6b738b6 100644
--- a/drivers/power/supply/qcom/qg-util.c
+++ b/drivers/power/supply/qcom/qg-util.c
@@ -374,12 +374,13 @@
pr_err("Failed reading BAT_TEMP over ADC rc=%d\n", rc);
return rc;
}
-/*zxzadd just for power on, should remove below code when device power on !!! begin */
- pr_err("batt_temp11 = %d\n", *temp);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#if defined(DISABLE_TEMPERATURE_DETECTION_AND_THERMAL_POLICY)
+ pr_debug("temperature fixed at 25 degree! The real temp is=%d\n", *temp);
*temp = 250;
- pr_err("fix batt_temp22 = %d\n", *temp);
-/*zxzadd just for power on, should remove below code when device power on !!! end */
+#endif
+#endif
return 0;
}
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index 0032df4..aabe3f1 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -120,6 +120,34 @@
return present;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#if defined(CONFIG_TCT_GCF) || \
+ defined(CONFIG_TCT_IEEE1725) || \
+ defined(CONFIG_TCT_CB)
+#define VALID_BATT_ID_82K_LOW (69700)
+#define VALID_BATT_ID_82K_HIGH (94300)
+
+#define VALID_BATT_ID_18K_LOW (15300)
+#define VALID_BATT_ID_18K_HIGH (20700)
+static bool is_debug_batt_id(struct qpnp_qg *chip)
+{
+ if (is_between(VALID_BATT_ID_82K_LOW, VALID_BATT_ID_82K_HIGH,
+ chip->batt_id_ohm))
+ return false;
+
+ if (is_between(VALID_BATT_ID_18K_LOW, VALID_BATT_ID_18K_HIGH,
+ chip->batt_id_ohm))
+ return false;
+
+ return true;
+}
+#else
+static bool is_debug_batt_id(struct qpnp_qg *chip)
+{
+ return false;
+}
+#endif
+#else
#define DEBUG_BATT_ID_LOW 6000
#define DEBUG_BATT_ID_HIGH 8500
static bool is_debug_batt_id(struct qpnp_qg *chip)
@@ -130,6 +158,7 @@
return false;
}
+#endif
static int qg_read_ocv(struct qpnp_qg *chip, u32 *ocv_uv, u32 *ocv_raw, u8 type)
{
@@ -836,6 +865,12 @@
rc = qg_sdam_read(SDAM_ESR_CHARGE_DELTA, &data);
if (!rc && data) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (abs((int)data) > 10) {
+ pr_err("abnormal chg esr: 0x%x\n", data);
+ data = 0;
+ }
+#endif
chip->kdata.param[QG_ESR_CHARGE_DELTA].data = data;
chip->kdata.param[QG_ESR_CHARGE_DELTA].valid = true;
qg_dbg(chip, QG_DEBUG_ESR,
@@ -846,6 +881,12 @@
rc = qg_sdam_read(SDAM_ESR_DISCHARGE_DELTA, &data);
if (!rc && data) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (abs((int)data) > 10) {
+ pr_err("abnormal dischg esr: 0x%x\n", data);
+ data = 0;
+ }
+#endif
chip->kdata.param[QG_ESR_DISCHARGE_DELTA].data = data;
chip->kdata.param[QG_ESR_DISCHARGE_DELTA].valid = true;
qg_dbg(chip, QG_DEBUG_ESR,
@@ -883,16 +924,34 @@
if (chip->udata.param[QG_ESR_CHARGE_DELTA].valid) {
esr = chip->udata.param[QG_ESR_CHARGE_DELTA].data;
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (abs((int)esr) < 10) {
+ qg_sdam_write(SDAM_ESR_CHARGE_DELTA, esr);
+ qg_dbg(chip, QG_DEBUG_ESR,
+ "SDAM store ESR_CHARGE_DELTA=0x%x\n", esr);
+ }
+#else
qg_sdam_write(SDAM_ESR_CHARGE_DELTA, esr);
qg_dbg(chip, QG_DEBUG_ESR,
"SDAM store ESR_CHARGE_DELTA=%d\n", esr);
+#endif
}
if (chip->udata.param[QG_ESR_DISCHARGE_DELTA].valid) {
esr = chip->udata.param[QG_ESR_DISCHARGE_DELTA].data;
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (abs((int)esr) < 10) {
+ qg_sdam_write(SDAM_ESR_DISCHARGE_DELTA, esr);
+ qg_dbg(chip, QG_DEBUG_ESR,
+ "SDAM store ESR_DISCHARGE_DELTA=0x%x\n", esr);
+ }
+#else
qg_sdam_write(SDAM_ESR_DISCHARGE_DELTA, esr);
qg_dbg(chip, QG_DEBUG_ESR,
"SDAM store ESR_DISCHARGE_DELTA=%d\n", esr);
+#endif
}
if (chip->udata.param[QG_ESR_CHARGE_SF].valid) {
@@ -1208,6 +1267,10 @@
struct qpnp_qg, udata_work);
int rc;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ mutex_lock(&chip->data_lock);
+#endif
+
if (chip->udata.param[QG_CC_SOC].valid)
chip->cc_soc = chip->udata.param[QG_CC_SOC].data;
@@ -1240,6 +1303,18 @@
chip->catch_up_soc = chip->udata.param[QG_SOC].data;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chip->catch_up_soc == 0) {
+ int vbat_uv = 0;
+ int vcutoff_uv = chip->dt.vbatt_cutoff_mv * 1000;
+ qg_get_battery_voltage(chip, &vbat_uv);
+ if (vbat_uv >= vcutoff_uv) {
+ pr_debug("%d >= %d, keep report soc=1\n", vbat_uv, vcutoff_uv);
+ chip->catch_up_soc = 1;
+ }
+ }
+#endif
+
qg_scale_soc(chip, chip->force_soc);
chip->force_soc = false;
@@ -1259,6 +1334,12 @@
if (chip->udata.param[QG_ESR].valid)
chip->esr_last = chip->udata.param[QG_ESR].data;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ pr_err_ratelimited("userspace write rbat=%d, esr=%d\n",
+ chip->sdam_data[SDAM_RBAT_MOHM],
+ chip->esr_last);
+#endif
+
if (chip->esr_actual != -EINVAL && chip->udata.param[QG_ESR].valid) {
chip->esr_nominal = chip->udata.param[QG_ESR].data;
if (chip->qg_psy)
@@ -1272,6 +1353,11 @@
(chip->batt_soc != INT_MIN) ? chip->batt_soc : -EINVAL,
(chip->cc_soc != INT_MIN) ? chip->cc_soc : -EINVAL,
chip->full_soc, chip->esr_last);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ mutex_unlock(&chip->data_lock);
+#endif
+
vote(chip->awake_votable, UDATA_READY_VOTER, false, 0);
}
@@ -1397,9 +1483,19 @@
pr_warn("VBATT EMPTY SOC = 0\n");
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ mutex_lock(&chip->soc_lock);
+#endif
chip->catch_up_soc = 0;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ mutex_unlock(&chip->soc_lock);
+#endif
qg_scale_soc(chip, true);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ mutex_lock(&chip->data_lock);
+#endif
+
qg_sdam_read(SDAM_OCV_UV, &ocv_uv);
chip->sdam_data[SDAM_SOC] = 0;
chip->sdam_data[SDAM_OCV_UV] = ocv_uv;
@@ -1407,6 +1503,10 @@
qg_store_soc_params(chip);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ mutex_unlock(&chip->data_lock);
+#endif
+
if (chip->qg_psy)
power_supply_changed(chip->qg_psy);
@@ -1487,6 +1587,21 @@
},
};
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static int qg_awake_cb(struct votable *votable, void *data, int awake,
+ const char *client)
+{
+ struct qpnp_qg *chip = data;
+
+ if (awake)
+ __pm_stay_awake(chip->qg_ws);
+ else
+ __pm_relax(chip->qg_ws);
+
+ pr_debug("client: %s awake: %d\n", client, awake);
+ return 0;
+}
+#else
static int qg_awake_cb(struct votable *votable, void *data, int awake,
const char *client)
{
@@ -1504,6 +1619,7 @@
pr_debug("client: %s awake: %d\n", client, awake);
return 0;
}
+#endif
static int qg_fifo_irq_disable_cb(struct votable *votable, void *data,
int disable, const char *client)
@@ -2238,13 +2354,27 @@
rc = get_cycle_count(chip->counter, &pval->intval);
break;
case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chip->dt.tt_enabled)
+ rc = ttf_get_time_to_full(chip->ttf, &pval->intval);
+ else
+ rc = -ENODATA;
+#else
rc = ttf_get_time_to_full(chip->ttf, &pval->intval);
+#endif
break;
case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
rc = ttf_get_time_to_full(chip->ttf, &pval->intval);
break;
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chip->dt.tt_enabled)
+ rc = ttf_get_time_to_empty(chip->ttf, &pval->intval);
+ else
+ rc = -ENODATA;
+#else
rc = ttf_get_time_to_empty(chip->ttf, &pval->intval);
+#endif
break;
case POWER_SUPPLY_PROP_ESR_ACTUAL:
pval->intval = (chip->esr_actual == -EINVAL) ? -EINVAL :
@@ -2286,9 +2416,17 @@
break;
default:
pr_debug("Unsupported property %d\n", psp);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ rc = -EINVAL;
+#endif
break;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (rc < 0)
+ rc = -ENODATA;
+#endif
+
return rc;
}
@@ -2718,7 +2856,13 @@
if (rc < 0)
pr_err("Failed in charge_full_update, rc=%d\n", rc);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chip->dt.tt_enabled)
+ ttf_update(chip->ttf, input_present);
+#else
ttf_update(chip->ttf, input_present);
+#endif
+
out:
pm_relax(chip->dev);
}
@@ -2732,8 +2876,15 @@
if (event != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (work_pending(&chip->qg_status_change_work)) {
+ pr_debug("qg_status_change_work pending now, skip\n");
+ return NOTIFY_OK;
+ }
+#else
if (work_pending(&chip->qg_status_change_work))
return NOTIFY_OK;
+#endif
if ((strcmp(psy->desc->name, "battery") == 0)
|| (strcmp(psy->desc->name, "parallel") == 0)
@@ -2745,7 +2896,12 @@
* a mutex lock and this is executed in an atomic context.
*/
pm_stay_awake(chip->dev);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_work(private_chg_wq, &chip->qg_status_change_work);
+#else
schedule_work(&chip->qg_status_change_work);
+#endif
}
return NOTIFY_OK;
@@ -2809,6 +2965,17 @@
goto fail_read;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if ((chip->sdam_data[SDAM_RBAT_MOHM] != 0) &&
+ (chip->sdam_data[SDAM_RBAT_MOHM] > 170 ||
+ chip->sdam_data[SDAM_RBAT_MOHM] < 80)) {
+ chip->kdata.param[QG_CLEAR_LEARNT_DATA].data = 1;
+ chip->kdata.param[QG_CLEAR_LEARNT_DATA].valid = true;
+ qg_dbg(chip, QG_DEBUG_ESR,
+ "fg rbatt(%d) abnormal, reset hvdcp_opti data\n",
+ chip->sdam_data[SDAM_RBAT_MOHM]);
+ }
+#endif
if (copy_to_user(buf, &chip->kdata, data_size)) {
pr_err("Failed in copy_to_user\n");
@@ -2866,8 +3033,16 @@
rc = data_size;
vote(chip->awake_votable, UDATA_READY_VOTER, true, 0);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ mutex_unlock(&chip->data_lock);
+ qg_dbg(chip, QG_DEBUG_DEVICE, "QG write complete size=%d\n", rc);
+ queue_work(private_chg_wq, &chip->udata_work);
+ return rc;
+#else
schedule_work(&chip->udata_work);
qg_dbg(chip, QG_DEBUG_DEVICE, "QG write complete size=%d\n", rc);
+#endif
fail:
mutex_unlock(&chip->data_lock);
return rc;
@@ -3231,6 +3406,20 @@
pr_err("Failed to read shutdown params rc=%d\n", rc);
goto use_pon_ocv;
}
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (abs((int)shutdown[SDAM_ESR_CHARGE_DELTA]) > 10) {
+ pr_err("found abnormal esr chg delta(0x%x)\n",
+ shutdown[SDAM_ESR_CHARGE_DELTA]);
+ qg_sdam_write(SDAM_ESR_CHARGE_DELTA, 0);
+ }
+ if (abs((int)shutdown[SDAM_ESR_DISCHARGE_DELTA]) > 10) {
+ pr_err("found abnormal esr dischg delta(0x%x)\n",
+ shutdown[SDAM_ESR_DISCHARGE_DELTA]);
+ qg_sdam_write(SDAM_ESR_DISCHARGE_DELTA, 0);
+ }
+#endif
+
shutdown_temp = sign_extend32(shutdown[SDAM_TEMP], 15);
rc = lookup_soc_ocv(&pon_soc, ocv[S7_PON_OCV].ocv_uv, batt_temp, false);
@@ -3253,6 +3442,38 @@
* 2. The device was powered off for < ignore_shutdown_time
* 2. Batt temp has not changed more than shutdown_temp_diff
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (!shutdown[SDAM_VALID]) {
+ pr_err("WARNING: sdram data invalid\n");
+ goto use_pon_ocv;
+ }
+
+ if (!is_between(0, chip->dt.ignore_shutdown_soc_secs,
+ abs(rtc_sec - shutdown[SDAM_TIME_SEC]))) {
+ pr_err("WARNING: too long time interval(%ld,%d,%d)\n",
+ rtc_sec, shutdown[SDAM_TIME_SEC],
+ chip->dt.ignore_shutdown_soc_secs);
+ goto use_pon_ocv;
+ }
+
+ if (!is_between(0, chip->dt.shutdown_temp_diff,
+ abs(shutdown_temp - batt_temp)) &&
+ (shutdown_temp < 0 || batt_temp < 0)) {
+ pr_err("WARNING: too big gaps of temperature(%d,%d,%d)\n",
+ shutdown_temp, batt_temp,
+ chip->dt.shutdown_temp_diff);
+ goto use_pon_ocv;
+ }
+
+ if ((chip->dt.shutdown_soc_threshold != -EINVAL) &&
+ !is_between(0, chip->dt.shutdown_soc_threshold,
+ abs(pon_soc - shutdown[SDAM_SOC]))) {
+ pr_err("WARNING: too big gaps of soc(%d,%d,%d)\n",
+ pon_soc, shutdown[SDAM_SOC],
+ chip->dt.shutdown_soc_threshold);
+ goto use_pon_ocv;
+ }
+#else
if (!shutdown[SDAM_VALID])
goto use_pon_ocv;
@@ -3269,6 +3490,7 @@
!is_between(0, chip->dt.shutdown_soc_threshold,
abs(pon_soc - shutdown[SDAM_SOC])))
goto use_pon_ocv;
+#endif
use_pon_ocv = false;
ocv_uv = shutdown[SDAM_OCV_UV];
@@ -4605,7 +4827,9 @@
chip->suspend_data = false;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
schedule_delayed_work(&chip->ttf->ttf_work, 0);
+#endif
return rc;
}
@@ -4821,7 +5045,9 @@
pr_err("Error in restoring cycle_count, rc=%d\n", rc);
return rc;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
schedule_delayed_work(&chip->ttf->ttf_work, 10000);
+#endif
}
rc = qg_determine_pon_soc(chip);
@@ -4830,6 +5056,12 @@
goto fail_device;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chip->qg_ws = wakeup_source_register(&pdev->dev, "qg_voted_ws");
+ if (!chip->qg_ws)
+ goto fail_device;
+#endif
+
chip->awake_votable = create_votable("QG_WS", VOTE_SET_ANY,
qg_awake_cb, chip);
if (IS_ERR(chip->awake_votable)) {
@@ -4902,6 +5134,11 @@
device_destroy(chip->qg_class, chip->dev_no);
cdev_del(&chip->qg_cdev);
unregister_chrdev_region(chip->dev_no, 1);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ wakeup_source_unregister(chip->qg_ws);
+ pr_err("QG probe failed with err:%d\n", rc);
+#endif
return rc;
}
@@ -4925,6 +5162,9 @@
mutex_destroy(&chip->soc_lock);
if (chip->awake_votable)
destroy_votable(chip->awake_votable);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ wakeup_source_unregister(chip->qg_ws);
+#endif
return 0;
}
diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c
index ce5a63d..5b5bc097 100644
--- a/drivers/power/supply/qcom/qpnp-smb5.c
+++ b/drivers/power/supply/qcom/qpnp-smb5.c
@@ -3,6 +3,9 @@
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define pr_fmt(fmt) "[SMB5]: %s: " fmt, __func__
+#endif
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -227,6 +230,46 @@
struct smb_dt_props dt;
};
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static int thermal_disable = 0;
+module_param_named(
+ thermal_disable, thermal_disable,
+ int, S_IRUSR | S_IWUSR
+);
+
+static int fixtemp = 0;
+static int fixtemp_val = 250;
+module_param_named(
+ fixtemp_val, fixtemp_val,
+ int, S_IRUSR | S_IWUSR
+);
+
+static int stopchg_en = 1;
+module_param_named(
+ stopchg_en, stopchg_en,
+ int, S_IRUSR | S_IWUSR
+);
+static int safety_timer_en = 1;
+module_param_named(
+ safety_timer_en, safety_timer_en,
+ int, S_IRUSR | S_IWUSR
+);
+#endif
+
+#if defined(CONFIG_TCT_OTTAWA_CHG_PATCH)
+static int force_icl = -1;
+module_param_named(
+ force_icl, force_icl,
+ int, S_IRUSR | S_IWUSR
+);
+
+static int force_fcc = -1;
+module_param_named(
+ force_fcc, force_fcc,
+ int, S_IRUSR | S_IWUSR
+);
+#endif
+
static int __debug_mask;
static ssize_t pd_disabled_show(struct device *dev, struct device_attribute
@@ -335,8 +378,15 @@
chip->chg.chg_param.smb_version = PM7250B_SUBTYPE;
chg->param = smb5_pm8150b_params;
chg->name = "pm7250b_charger";
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->hw_max_icl_ua = HW_ICL_MAX;
+ chg->uusb_moisture_protection_capable = false;
+ chg->main_fcc_max = PM6150_MAX_FCC_UA;
+ chg->wa_flags |= SW_THERM_REGULATION_WA | CHG_TERMINATION_WA;
+#else
chg->wa_flags |= CHG_TERMINATION_WA;
chg->uusb_moisture_protection_capable = true;
+#endif
break;
case PM6150_SUBTYPE:
chip->chg.chg_param.smb_version = PM6150_SUBTYPE;
@@ -504,6 +554,43 @@
}
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (of_find_property(node, "qcom,thermal-mitigation-lcdon", &byte_len)) {
+ chg->thermal_mitigation_lcdon = devm_kzalloc(chg->dev, byte_len,
+ GFP_KERNEL);
+
+ if (chg->thermal_mitigation_lcdon == NULL) {
+ dev_err(chg->dev, "thermal_mitigation_lcdon NULL\n");
+ chg->thermal_levels = 0;
+ return -ENOMEM;
+ }
+
+ if (chg->thermal_levels != (byte_len / sizeof(u32))) {
+ dev_err(chg->dev, "thermal on-off levels %d not equal\n",
+ chg->thermal_levels);
+ chg->thermal_levels = 0;
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32_array(node,
+ "qcom,thermal-mitigation-lcdon",
+ chg->thermal_mitigation_lcdon,
+ chg->thermal_levels);
+ if (rc < 0) {
+ dev_err(chg->dev,
+ "Couldn't read thermal-lcdon limits rc = %d\n", rc);
+ chg->thermal_levels = 0;
+ return rc;
+ }
+ } else if (chg->thermal_levels) {
+ /* if qcom,thermal-mitigation defined but not this one. */
+ dev_err(chg->dev,
+ "ERROR: thermal-lcdon must defined!\n");
+ chg->thermal_levels = 0;
+ //return -EINVAL; // let boot up with debug later.
+ }
+#endif
+
rc = of_property_read_u32(node, "qcom,charger-temp-max",
&chg->charger_temp_max);
if (rc < 0)
@@ -575,6 +662,9 @@
chip->dt.disable_suspend_on_collapse = of_property_read_bool(node,
"qcom,disable-suspend-on-collapse");
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->disable_suspend_on_collapse = chip->dt.disable_suspend_on_collapse;
+#endif
chg->smb_pull_up = -EINVAL;
of_property_read_u32(node, "qcom,smb-internal-pull-kohm",
&chg->smb_pull_up);
@@ -906,6 +996,9 @@
switch (psp) {
case POWER_SUPPLY_PROP_PRESENT:
rc = smblib_get_prop_usb_present(chg, val);
+#if defined(CONFIG_TCT_CHG_AUTOTEST)
+ pr_err_ratelimited("TCTNB_PRESENT:%d\n", val->intval);
+#endif
break;
case POWER_SUPPLY_PROP_ONLINE:
rc = smblib_get_usb_online(chg, val);
@@ -936,6 +1029,9 @@
break;
case POWER_SUPPLY_PROP_REAL_TYPE:
val->intval = chg->real_charger_type;
+#if defined(CONFIG_TCT_CHG_AUTOTEST)
+ pr_err_ratelimited("TCTNB_REALTYPE:%d\n", val->intval);
+#endif
break;
case POWER_SUPPLY_PROP_TYPEC_MODE:
rc = smblib_get_usb_prop_typec_mode(chg, val);
@@ -1028,6 +1124,9 @@
case POWER_SUPPLY_PROP_THERM_ICL_LIMIT:
val->intval = get_client_vote(chg->usb_icl_votable,
THERMAL_THROTTLE_VOTER);
+#if defined(CONFIG_TCT_CHG_AUTOTEST)
+ pr_err_ratelimited("TCTNB_THRO_ICL:%d\n", val->intval);
+#endif
break;
case POWER_SUPPLY_PROP_ADAPTER_CC_MODE:
val->intval = chg->adapter_cc_mode;
@@ -1099,14 +1198,22 @@
rc = smblib_set_prop_pd_in_hard_reset(chg, val);
break;
case POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->system_suspend_supported = false;
+#else
chg->system_suspend_supported = val->intval;
+#endif
break;
case POWER_SUPPLY_PROP_BOOST_CURRENT:
rc = smblib_set_prop_boost_current(chg, val);
break;
case POWER_SUPPLY_PROP_CTM_CURRENT_MAX:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ rc = -EINVAL;
+#else
rc = vote(chg->usb_icl_votable, CTM_VOTER,
val->intval >= 0, val->intval);
+#endif
break;
case POWER_SUPPLY_PROP_PR_SWAP:
rc = smblib_set_prop_pr_swap_in_progress(chg, val);
@@ -1125,6 +1232,12 @@
power_supply_changed(chg->usb_psy);
break;
case POWER_SUPPLY_PROP_THERM_ICL_LIMIT:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ return 0;
+#endif
+
+
+
if (!is_client_vote_enabled(chg->usb_icl_votable,
THERMAL_THROTTLE_VOTER)) {
chg->init_thermal_ua = get_effective_result(
@@ -1235,9 +1348,13 @@
if (!val->intval)
break;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
+#else
if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) ||
(chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB))
&& (chg->real_charger_type == POWER_SUPPLY_TYPE_USB))
+#endif
val->intval = 1;
else
val->intval = 0;
@@ -1402,10 +1519,19 @@
rc = -EINVAL;
break;
}
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (rc < 0) {
+ pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
+ return -ENODATA;
+ }
+ return 0;
+#else
if (rc < 0)
pr_debug("Couldn't get prop %d rc = %d\n", psp, rc);
return rc;
+#endif
}
static int smb5_usb_main_set_prop(struct power_supply *psy,
@@ -1473,6 +1599,9 @@
rerun_election(chg->fcc_votable);
break;
case POWER_SUPPLY_PROP_FORCE_MAIN_FCC:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ return -EINVAL;
+#endif
vote_override(chg->fcc_main_votable, CC_MODE_VOTER,
(val->intval < 0) ? false : true, val->intval);
if (val->intval >= 0)
@@ -1488,6 +1617,9 @@
rerun_election(chg->fcc_votable);
break;
case POWER_SUPPLY_PROP_FORCE_MAIN_ICL:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ return -EINVAL;
+#endif
vote_override(chg->usb_icl_votable, CC_MODE_VOTER,
(val->intval < 0) ? false : true, val->intval);
/* Main ICL updated re-calculate ILIM */
@@ -1738,6 +1870,11 @@
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE,
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ POWER_SUPPLY_PROP_TCL_FIXTEMP,
+ POWER_SUPPLY_PROP_CHARGING_ENABLED,
+ POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE,
+#endif
};
#define DEBUG_ACCESSORY_TEMP_DECIDEGC 250
@@ -1766,6 +1903,9 @@
break;
case POWER_SUPPLY_PROP_CAPACITY:
rc = smblib_get_prop_batt_capacity(chg, val);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->real_soc = val->intval;
+#endif
break;
case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
rc = smblib_get_prop_system_temp_level(chg, val);
@@ -1821,11 +1961,21 @@
rc = smblib_get_prop_batt_iterm(chg, val);
break;
case POWER_SUPPLY_PROP_TEMP:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ rc = smblib_get_prop_from_bms(chg,
+ POWER_SUPPLY_PROP_TEMP, val);
+#else
if (chg->typec_mode == POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY)
val->intval = DEBUG_ACCESSORY_TEMP_DECIDEGC;
else
rc = smblib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_TEMP, val);
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if(fixtemp == 1)
+ val->intval = fixtemp_val;
+#endif
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
@@ -1890,9 +2040,25 @@
case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE:
val->intval = chg->fcc_stepper_enable;
break;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ case POWER_SUPPLY_PROP_TCL_FIXTEMP:
+ val->intval = fixtemp;
+ break;
+ case POWER_SUPPLY_PROP_CHARGING_ENABLED:
+ val->intval = !get_client_vote(chg->chg_disable_votable,
+ USER_VOTER);
+ break;
+ case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
+ val->intval = safety_timer_en;
+ break;
+#endif
default:
pr_err("batt power supply prop %d not supported\n", psp);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ return -ENODATA;
+#else
return -EINVAL;
+#endif
}
if (rc < 0) {
@@ -1914,10 +2080,37 @@
case POWER_SUPPLY_PROP_STATUS:
rc = smblib_set_prop_batt_status(chg, val);
break;
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ case POWER_SUPPLY_PROP_CHARGING_ENABLED:
+ if (!stopchg_en) {
+ pr_emerg("stop battery chg not allowed\n");
+ return -EINVAL;
+ }
+ vote(chg->chg_disable_votable, USER_VOTER,
+ (val->intval > 0) ? false : true, 0);
+ pr_emerg("WARNING: userspace %s battery chg function!\n",
+ (val->intval > 0) ? "enable" : "disable");
+ break;
+#endif
+
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (!stopchg_en) {
+ pr_emerg("stop chg not allowed\n");
+ return -EINVAL;
+ }
+#endif
rc = smblib_set_prop_input_suspend(chg, val);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ pr_emerg("WARNING: userspace disabled charge function! \n");
+#endif
break;
case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (thermal_disable)
+ break;
+#endif
rc = smblib_set_prop_system_temp_level(chg, val);
break;
case POWER_SUPPLY_PROP_CAPACITY:
@@ -1972,8 +2165,20 @@
rc = smblib_run_aicl(chg, RERUN_AICL);
break;
case POWER_SUPPLY_PROP_DP_DM:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (val->intval == POWER_SUPPLY_DP_DM_FORCE_12V) {
+ return -EINVAL;
+ } else if((chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP)
+ && (val->intval == POWER_SUPPLY_DP_DM_FORCE_9V)
+ && (chg->real_soc > 90)) {
+ return -EINVAL;
+ } else if (!chg->flash_active) {
+ rc = smblib_dp_dm(chg, val->intval);
+ }
+#else
if (!chg->flash_active)
rc = smblib_dp_dm(chg, val->intval);
+#endif
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
rc = smblib_set_prop_input_current_limited(chg, val);
@@ -1997,6 +2202,15 @@
case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE:
chg->fcc_stepper_enable = val->intval;
break;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ case POWER_SUPPLY_PROP_TCL_FIXTEMP:
+ fixtemp = val->intval;
+ break;
+ case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
+ safety_timer_en = val->intval;
+ pr_err("set safety timer %d done\n", safety_timer_en);
+ break;
+#endif
default:
rc = -EINVAL;
}
@@ -2010,7 +2224,9 @@
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
+#if !defined(CONFIG_TCT_PM7250_COMMON)
case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
+#endif
case POWER_SUPPLY_PROP_CAPACITY:
case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
case POWER_SUPPLY_PROP_DP_DM:
@@ -2018,6 +2234,16 @@
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED:
case POWER_SUPPLY_PROP_DIE_HEALTH:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ case POWER_SUPPLY_PROP_TCL_FIXTEMP:
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+ case POWER_SUPPLY_PROP_FCC_STEPPER_ENABLE:
+ case POWER_SUPPLY_PROP_FORCE_RECHARGE:
+ case POWER_SUPPLY_PROP_SET_SHIP_MODE:
+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
+ case POWER_SUPPLY_PROP_CHARGING_ENABLED:
+ case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
+#endif
return 1;
default:
break;
@@ -2183,6 +2409,14 @@
smblib_apsd_enable(chg, true);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ rc = smblib_masked_write(chg, TYPE_C_CFG_REG,
+ BC1P2_START_ON_CC_BIT, 0);
+ if (rc < 0) {
+ dev_err(chg->dev, "failed to write TYPE_C_CFG_REG rc=%d\n", rc);
+ return rc;
+ }
+#else
rc = smblib_read(chg, TYPE_C_SNK_STATUS_REG, &val);
if (rc < 0) {
dev_err(chg->dev, "failed to read TYPE_C_SNK_STATUS_REG rc=%d\n",
@@ -2201,6 +2435,7 @@
return rc;
}
}
+#endif
/* Use simple write to clear interrupts */
rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_1_REG, 0);
@@ -2696,9 +2931,13 @@
smblib_get_charge_param(chg, &chg->param.fcc,
&chg->batt_profile_fcc_ua);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->batt_profile_fv_uv = 4400000;
+#else
if (chip->dt.batt_profile_fv_uv < 0)
smblib_get_charge_param(chg, &chg->param.fv,
&chg->batt_profile_fv_uv);
+#endif
smblib_get_charge_param(chg, &chg->param.usb_icl,
&chg->default_icl_ua);
@@ -2821,7 +3060,11 @@
}
rc = smblib_write(chg, AICL_RERUN_TIME_CFG_REG,
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ AICL_RERUN_TIME_3MIN_VAL);
+#else
AICL_RERUN_TIME_12S_VAL);
+#endif
if (rc < 0) {
dev_err(chg->dev,
"Couldn't configure AICL rerun interval rc=%d\n", rc);
@@ -2917,7 +3160,15 @@
}
rc = smblib_write(chg, CHGR_FAST_CHARGE_SAFETY_TIMER_CFG_REG,
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#if defined(CONFIG_TCT_IEEE1725)
+ FAST_CHARGE_SAFETY_TIMER_192_MIN);
+#else
+ FAST_CHARGE_SAFETY_TIMER_1536_MIN);
+#endif
+#else
FAST_CHARGE_SAFETY_TIMER_768_MIN);
+#endif
if (rc < 0) {
dev_err(chg->dev, "Couldn't set CHGR_FAST_CHARGE_SAFETY_TIMER_CFG_REG rc=%d\n",
rc);
@@ -2953,6 +3204,16 @@
}
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->qc2_unsupported_voltage = QC2_NON_COMPLIANT_12V;
+ rc = smblib_masked_write(chg, HVDCP_PULSE_COUNT_MAX_REG,
+ HVDCP_PULSE_COUNT_MAX_QC2_MASK,
+ HVDCP_PULSE_COUNT_MAX_QC2_9V);
+ if (rc < 0)
+ dev_err(chg->dev, "Couldn't write max pulses rc=%d\n",
+ rc);
+#endif
+
if (chg->smb_pull_up != -EINVAL) {
rc = smb5_configure_internal_pull(chg, SMB_THERM,
get_valid_pullup(chg->smb_pull_up));
@@ -3084,7 +3345,9 @@
},
[INPUT_CURRENT_LIMITING_IRQ] = {
.name = "input-current-limiting",
+#if !defined(CONFIG_TCT_PM7250_COMMON)
.handler = default_irq_handler,
+#endif
},
[CONCURRENT_MODE_DISABLE_IRQ] = {
.name = "concurrent-mode-disable",
@@ -3337,7 +3600,9 @@
irq_data->storm_data = smb5_irqs[irq_index].storm_data;
mutex_init(&irq_data->storm_data.storm_lock);
+#if !defined(CONFIG_TCT_PM7250_COMMON)
smb5_irqs[irq_index].enabled = true;
+#endif
rc = devm_request_threaded_irq(chg->dev, irq, NULL,
smb5_irqs[irq_index].handler,
IRQF_ONESHOT, irq_name, irq_data);
@@ -3346,6 +3611,9 @@
return rc;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ smb5_irqs[irq_index].enabled = true;
+#endif
smb5_irqs[irq_index].irq = irq;
smb5_irqs[irq_index].irq_data = irq_data;
if (smb5_irqs[irq_index].wake)
@@ -3671,7 +3939,9 @@
switch (chg->chg_param.smb_version) {
case PM8150B_SUBTYPE:
case PM6150_SUBTYPE:
+#if defined(CONFIG_TCT_PM7250_COMMON)
case PM7250B_SUBTYPE:
+#endif
rc = smb5_init_dc_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize dc psy rc=%d\n", rc);
@@ -3731,6 +4001,10 @@
goto free_irq;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ recheck_unknown_typec(chg);
+#endif
+
smb5_create_debugfs(chip);
rc = sysfs_create_groups(&chg->dev->kobj, smb5_groups);
diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c
index 086f2d9..cedc3f0 100644
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -3,6 +3,10 @@
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define pr_fmt(fmt) "[SMBLIB5]: " fmt
+#endif
+
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/delay.h>
@@ -21,6 +25,20 @@
#include "storm-watch.h"
#include "schgm-flash.h"
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define smblib_err(chg, fmt, ...) \
+ pr_err_ratelimited("%s: " fmt, \
+ __func__, ##__VA_ARGS__)
+#define smblib_dbg(chg, reason, fmt, ...) \
+ do { \
+ if (*chg->debug_mask & (reason)) \
+ pr_err_ratelimited("%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ else \
+ pr_debug_ratelimited("%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ } while (0)
+#else
#define smblib_err(chg, fmt, ...) \
pr_err("%s: %s: " fmt, chg->name, \
__func__, ##__VA_ARGS__) \
@@ -34,6 +52,7 @@
pr_debug("%s: %s: " fmt, chg->name, \
__func__, ##__VA_ARGS__); \
} while (0)
+#endif
#define typec_rp_med_high(chg, typec_mode) \
((typec_mode == POWER_SUPPLY_TYPEC_SOURCE_MEDIUM \
@@ -174,7 +193,11 @@
break;
case SW_OVERRIDE_HC_MODE:
usb51_mode = USBIN_MODE_CHG_BIT;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ icl_override = ICL_OVERRIDE_BIT;
+#else
icl_override = 0;
+#endif
apsd_override = ICL_OVERRIDE_AFTER_APSD_BIT;
break;
case HW_AUTO_MODE:
@@ -323,7 +346,12 @@
val.intval = ((prop_val.intval == 2) ? 1 : 0);
extcon_set_property(chg->extcon, id,
EXTCON_PROP_USB_TYPEC_POLARITY, val);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val.intval = false;
+#else
val.intval = true;
+#endif
extcon_set_property(chg->extcon, id,
EXTCON_PROP_USB_SS, val);
} else if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) {
@@ -982,8 +1010,14 @@
static void smblib_hvdcp_detect_try_enable(struct smb_charger *chg, bool enable)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->hvdcp_disable)
+ return;
+#else
if (chg->hvdcp_disable || chg->pd_not_supported)
return;
+#endif
+
smblib_hvdcp_detect_enable(chg, enable);
}
@@ -1115,11 +1149,21 @@
if (!chg->bms_psy)
chg->bms_psy = psy;
if (ev == PSY_EVENT_PROP_CHANGED)
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_work(private_chg_wq, &chg->bms_update_work);
+#else
schedule_work(&chg->bms_update_work);
+#endif
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if ((!chg->sw_jeita_enabled) &&
+ (chg->jeita_configured == JEITA_CFG_NONE))
+ schedule_work(&chg->jeita_update_work);
+#else
if (chg->jeita_configured == JEITA_CFG_NONE)
schedule_work(&chg->jeita_update_work);
+#endif
if (chg->sec_pl_present && !chg->pl.psy
&& !strcmp(psy->desc->name, "parallel")) {
@@ -1230,6 +1274,9 @@
vote(chg->usb_icl_votable, SW_THERM_REGULATION_VOTER, false, 0);
vote(chg->pl_disable_votable, SW_THERM_REGULATION_VOTER, false, 0);
vote(chg->dc_suspend_votable, SW_THERM_REGULATION_VOTER, false, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->apsd_rerun_done = false;
+#endif
if (chg->cp_disable_votable)
vote(chg->cp_disable_votable, SW_THERM_REGULATION_VOTER,
false, 0);
@@ -1280,14 +1327,25 @@
smblib_err(chg, "Couldn't restore max pulses rc=%d\n",
rc);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->disable_suspend_on_collapse) {
+ rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
+ SUSPEND_ON_COLLAPSE_USBIN_BIT,
+ SUSPEND_ON_COLLAPSE_USBIN_BIT);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't turn on SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
+ rc);
+ }
+ chg->qc2_unsupported_voltage = QC2_NON_COMPLIANT_12V;
+#else
rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
SUSPEND_ON_COLLAPSE_USBIN_BIT,
SUSPEND_ON_COLLAPSE_USBIN_BIT);
if (rc < 0)
smblib_err(chg, "Couldn't turn on SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
rc);
-
chg->qc2_unsupported_voltage = QC2_COMPLIANT;
+#endif
}
chg->qc3p5_detected = false;
@@ -1434,15 +1492,22 @@
goto set_mode;
/* configure current */
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB) {
+#else
if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB
&& (chg->typec_legacy
|| chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
|| chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)) {
+#endif
rc = set_sdp_current(chg, icl_ua);
if (rc < 0) {
smblib_err(chg, "Couldn't set SDP ICL rc=%d\n", rc);
goto out;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ icl_override = SW_OVERRIDE_USB51_MODE;
+#endif
} else {
/*
* Try USB 2.0/3,0 option first on USB path when maximum input
@@ -1912,9 +1977,22 @@
int smblib_get_prop_input_suspend(struct smb_charger *chg,
union power_supply_propval *val)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int rc = 0;
+ u8 stat=0;
+
+ rc = smblib_read(chg, USBIN_CMD_IL_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read USBIN_CMD_IL rc=%d\n", rc);
+ val->intval = 0;
+ return rc;
+ }
+ val->intval = (bool)(stat & USBIN_SUSPEND_BIT);
+#else
val->intval
= (get_client_vote(chg->usb_icl_votable, USER_VOTER) == 0)
&& get_client_vote(chg->dc_suspend_votable, USER_VOTER);
+#endif
return 0;
}
@@ -1972,7 +2050,11 @@
union power_supply_propval pval = {0, };
bool usb_online, dc_online;
u8 stat;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int rc, suspend = 0;
+#else
int rc, suspend = 0, input_present = 0;
+#endif
if (chg->fake_chg_status_on_debug_batt) {
rc = smblib_get_prop_from_bms(chg,
@@ -1986,6 +2068,7 @@
}
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
rc = smblib_get_prop_batt_health(chg, &pval);
if (rc < 0) {
smblib_err(chg, "Couldn't get batt health rc=%d\n", rc);
@@ -2001,7 +2084,9 @@
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
return 0;
}
+#endif
+#if !defined(CONFIG_TCT_PM7250_COMMON)
/*
* If SOC = 0 and we are discharging with input connected, report
* the battery status as DISCHARGING.
@@ -2023,6 +2108,7 @@
} else {
chg->cutoff_count = 0;
}
+#endif
if (chg->dbc_usbov) {
rc = smblib_get_prop_usb_present(chg, &pval);
@@ -2159,6 +2245,21 @@
return rc;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ switch (stat & BATTERY_CHARGER_STATUS_MASK) {
+ case TRICKLE_CHARGE:
+ case PRE_CHARGE:
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ break;
+ case FULLON_CHARGE:
+ case TAPER_CHARGE:
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ break;
+ default:
+ val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ break;
+ }
+#else
switch (stat & BATTERY_CHARGER_STATUS_MASK) {
case TRICKLE_CHARGE:
case PRE_CHARGE:
@@ -2173,6 +2274,7 @@
default:
val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
}
+#endif
return rc;
}
@@ -2194,6 +2296,14 @@
smblib_dbg(chg, PR_REGISTER, "BATTERY_CHARGER_STATUS_2 = 0x%02x\n",
stat);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (stat & CHARGER_ERROR_STATUS_SFT_EXPIRE_BIT) {
+ val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
+ smblib_err(chg, "safety timer expired: 0x%02x\n", stat);
+ return 0;
+ }
+#endif
+
if (stat & CHARGER_ERROR_STATUS_BAT_OV_BIT) {
rc = smblib_get_prop_from_bms(chg,
POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
@@ -2230,6 +2340,29 @@
else
val->intval = POWER_SUPPLY_HEALTH_GOOD;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define JEITA_HARD_COLD_TEMP (0)
+#define JEITA_SOFT_COLD_TEMP (100)
+#define JEITA_SOFT_HOT_TEMP (450)
+#define JEITA_HARD_HOT_TEMP (550)
+
+ rc = smblib_get_prop_from_bms(chg,
+ POWER_SUPPLY_PROP_TEMP, &pval);
+ if (!rc) {
+
+ if (pval.intval < JEITA_HARD_COLD_TEMP)
+ val->intval = POWER_SUPPLY_HEALTH_COLD;
+ else if (pval.intval < JEITA_SOFT_COLD_TEMP)
+ val->intval = POWER_SUPPLY_HEALTH_COOL;
+ else if (pval.intval < JEITA_SOFT_HOT_TEMP)
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+ else if (pval.intval < JEITA_HARD_HOT_TEMP)
+ val->intval = POWER_SUPPLY_HEALTH_WARM;
+ else
+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ }
+#endif
+
done:
return rc;
}
@@ -2397,6 +2530,46 @@
return 0;
}
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+extern int g_lcd_on;
+int smblib_set_prop_system_temp_level(struct smb_charger *chg,
+ const union power_supply_propval *val)
+{
+ int *thermal_array = NULL;
+ /* MODIFIED-END by jin.wang,BUG-9172506*/
+
+ if (val->intval < 0)
+ return -EINVAL;
+
+ if (chg->thermal_levels <= 0)
+ return -EINVAL;
+
+ if (val->intval > chg->thermal_levels)
+ return -EINVAL;
+
+ /* MODIFIED-BEGIN by jin.wang, 2020-04-07,BUG-9172506*/
+ /* 1: LCD on ; 0: LCD off */
+ thermal_array = g_lcd_on ?
+ chg->thermal_mitigation_lcdon :
+ chg->thermal_mitigation;
+
+ pr_err("[%d]level: %d -> %d\n", g_lcd_on,
+ chg->system_temp_level, val->intval);
+
+ chg->system_temp_level = val->intval;
+ if (chg->system_temp_level == chg->thermal_levels)
+ return vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, true,
+ thermal_array[chg->thermal_levels-1]);
+
+ if (chg->system_temp_level == 0)
+ return vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, false, 0);
+
+ vote(chg->fcc_votable, THERMAL_DAEMON_VOTER, true,
+ thermal_array[chg->system_temp_level]);
+ return 0;
+}
+#else
int smblib_set_prop_system_temp_level(struct smb_charger *chg,
const union power_supply_propval *val)
{
@@ -2423,6 +2596,7 @@
chg->thermal_mitigation[chg->system_temp_level]);
return 0;
}
+#endif // MODIFIED by jin.wang, 2020-04-07,BUG-9172506
int smblib_set_prop_input_current_limited(struct smb_charger *chg,
const union power_supply_propval *val)
@@ -2541,6 +2715,11 @@
#define QC3_PULSES_FOR_6V 5
#define QC3_PULSES_FOR_9V 20
#define QC3_PULSES_FOR_12V 35
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define QC3P5_PULSES_FOR_6V 50
+#define QC3P5_PULSES_FOR_9V 200
+#define QC3P5_PULSES_FOR_12V 350
+#endif
static int smblib_hvdcp3_set_fsw(struct smb_charger *chg)
{
int pulse_count, rc;
@@ -2551,6 +2730,25 @@
return rc;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) {
+ if (pulse_count < QC3P5_PULSES_FOR_6V)
+ smblib_set_opt_switcher_freq(chg,
+ chg->chg_freq.freq_5V);
+ else if (pulse_count < QC3P5_PULSES_FOR_9V)
+ smblib_set_opt_switcher_freq(chg,
+ chg->chg_freq.freq_6V_8V);
+ else if (pulse_count < QC3P5_PULSES_FOR_12V)
+ smblib_set_opt_switcher_freq(chg,
+ chg->chg_freq.freq_9V);
+ else
+ smblib_set_opt_switcher_freq(chg,
+ chg->chg_freq.freq_12V);
+ return 0;
+ }
+#endif
+
+
if (pulse_count < QC3_PULSES_FOR_6V)
smblib_set_opt_switcher_freq(chg,
chg->chg_freq.freq_5V);
@@ -2602,6 +2800,21 @@
switch (val) {
case POWER_SUPPLY_DP_DM_DP_PULSE:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) {
+ if (QC3P5_PULSES_FOR_12V <= chg->pulse_cnt) {
+ smblib_err(chg, "QC3.5 pulse_cnt %d too large, skipped\n",
+ chg->pulse_cnt);
+ rc = -EINVAL;
+ break;
+ }
+ } else if (QC3_PULSES_FOR_12V <= chg->pulse_cnt) {
+ smblib_err(chg, "QC3.0 pulse_cnt %d too large, skipped\n",
+ chg->pulse_cnt);
+ rc = -EINVAL;
+ break;
+ }
+#endif
/*
* Pre-emptively increment pulse count to enable the setting
* of FSW prior to increasing voltage.
@@ -2627,9 +2840,23 @@
rc, chg->pulse_cnt);
break;
case POWER_SUPPLY_DP_DM_DM_PULSE:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->pulse_cnt <= 0) {
+ smblib_dbg(chg, PR_INTERRUPT, "pulse_cnt(%d), skip down\n",
+ chg->pulse_cnt);
+ return -EINVAL;
+ }
+#endif
rc = smblib_dm_pulse(chg);
if (!rc && chg->pulse_cnt)
chg->pulse_cnt--;
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (smblib_hvdcp3_set_fsw(chg) < 0) {
+ smblib_err(chg, "dm:Couldn't set QC3.0 Fsw\n");
+ }
+#endif
+
smblib_dbg(chg, PR_PARALLEL, "DP_DM_DM_PULSE rc=%d cnt=%d\n",
rc, chg->pulse_cnt);
break;
@@ -2664,6 +2891,10 @@
target_icl_ua, chg->usb_icl_delta_ua);
break;
case POWER_SUPPLY_DP_DM_FORCE_5V:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->pulse_cnt = 0;
+ smblib_hvdcp_set_fsw(chg, QC_5V_BIT);
+#endif
rc = smblib_force_vbus_voltage(chg, FORCE_5V_BIT);
if (rc < 0)
pr_err("Failed to force 5V\n");
@@ -2789,7 +3020,11 @@
SW_THERM_REGULATION_VOTER)) {
vote(chg->awake_votable, SW_THERM_REGULATION_VOTER,
true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->thermal_regulation_work, 0);
+#else
schedule_delayed_work(&chg->thermal_regulation_work, 0);
+#endif
}
} else {
cancel_delayed_work_sync(&chg->thermal_regulation_work);
@@ -2836,8 +3071,13 @@
rc = power_supply_get_property(chg->cp_psy,
POWER_SUPPLY_PROP_CP_DIE_TEMP, &pval);
if (rc < 0) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ smblib_dbg(chg, PR_MISC, "Couldn't get smb charger temp, rc=%d\n",
+ rc);
+#else
smblib_err(chg, "Couldn't get smb1390 charger temp, rc=%d\n",
rc);
+#endif
return rc;
}
chg->smb_temp = pval.intval;
@@ -2937,7 +3177,11 @@
chg->smb_temp > SMB_TEMP_REG_H_THRESH ||
chg->die_temp > DIE_TEMP_REG_H_THRESH) {
thermal_status = TEMP_ABOVE_RANGE;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ wdog_timeout = SNARL_WDOG_TMOUT_8S;
+#else
wdog_timeout = SNARL_WDOG_TMOUT_1S;
+#endif
goto out;
}
@@ -3004,8 +3248,13 @@
*/
if (is_client_vote_enabled(chg->usb_icl_votable,
SW_THERM_REGULATION_VOTER)) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->thermal_regulation_work,
+ msecs_to_jiffies(THERM_REG_RECHECK_DELAY_1S));
+#else
schedule_delayed_work(&chg->thermal_regulation_work,
msecs_to_jiffies(THERM_REG_RECHECK_DELAY_1S));
+#endif
return 0;
}
@@ -3312,9 +3561,13 @@
if (!val->intval)
goto exit;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
+#else
if (((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) ||
(chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB))
&& (chg->real_charger_type == POWER_SUPPLY_TYPE_USB))
+#endif
val->intval = 0;
else
val->intval = 1;
@@ -3347,6 +3600,9 @@
val->intval = MICRO_9V;
else
val->intval = MICRO_12V;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val->intval = MICRO_9V;
+#endif
break;
default:
val->intval = MICRO_5V;
@@ -3376,6 +3632,9 @@
val->intval = MICRO_9V;
else
val->intval = MICRO_12V;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val->intval = MICRO_9V;
+#endif
break;
case POWER_SUPPLY_TYPE_USB_PD:
val->intval = chg->voltage_max_uv;
@@ -3397,7 +3656,11 @@
switch (chg->real_charger_type) {
case POWER_SUPPLY_TYPE_USB_HVDCP:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val->intval = MICRO_9V;
+#else
val->intval = MICRO_12V;
+#endif
break;
case POWER_SUPPLY_TYPE_USB_HVDCP_3P5:
step_uv = HVDCP3P5_STEP_UV;
@@ -3499,6 +3762,9 @@
* OTG mode.
*/
if (!pval.intval) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val->intval = 0;
+#endif
rc = smblib_read(chg, DCDC_CMD_OTG_REG, ®);
if (rc < 0) {
smblib_err(chg, "Couldn't read CMD_OTG rc=%d", rc);
@@ -3679,6 +3945,9 @@
[POWER_SUPPLY_TYPEC_SOURCE_DEFAULT] = "SOURCE_DEFAULT",
[POWER_SUPPLY_TYPEC_SOURCE_MEDIUM] = "SOURCE_MEDIUM",
[POWER_SUPPLY_TYPEC_SOURCE_HIGH] = "SOURCE_HIGH",
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ [POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY] = "SOURCE_DEBUG_ACCESSORY",
+#endif
[POWER_SUPPLY_TYPEC_NON_COMPLIANT] = "NON_COMPLIANT",
[POWER_SUPPLY_TYPEC_SINK] = "SINK",
[POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE] = "SINK_POWERED_CABLE",
@@ -3711,7 +3980,11 @@
case SNK_DAM_500MA_BIT:
case SNK_DAM_1500MA_BIT:
case SNK_DAM_3000MA_BIT:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ return POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY;
+#else
return POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY;
+#endif
default:
break;
}
@@ -3834,8 +4107,13 @@
static inline bool typec_in_src_mode(struct smb_charger *chg)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ return (chg->typec_mode > POWER_SUPPLY_TYPEC_NONE &&
+ chg->typec_mode < POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY);
+#else
return (chg->typec_mode > POWER_SUPPLY_TYPEC_NONE &&
chg->typec_mode < POWER_SUPPLY_TYPEC_SOURCE_DEFAULT);
+#endif
}
int smblib_get_prop_typec_select_rp(struct smb_charger *chg,
@@ -4224,6 +4502,7 @@
return POWER_SUPPLY_HEALTH_COOL;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
static int get_rp_based_dcp_current(struct smb_charger *chg, int typec_mode)
{
int rp_ua;
@@ -4241,6 +4520,7 @@
return rp_ua;
}
+#endif
/*******************
* USB PSY SETTERS *
@@ -4266,7 +4546,11 @@
static int smblib_handle_usb_current(struct smb_charger *chg,
int usb_current)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int rc = 0;
+#else
int rc = 0, rp_ua, typec_mode;
+#endif
union power_supply_propval val = {0, };
if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_FLOAT) {
@@ -4286,6 +4570,12 @@
return rc;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ rc = vote(chg->usb_icl_votable,
+ SW_ICL_MAX_VOTER, true, USBIN_500MA);
+ if (rc < 0)
+ return rc;
+#else
if (chg->connector_type ==
POWER_SUPPLY_CONNECTOR_TYPEC) {
/*
@@ -4305,6 +4595,7 @@
if (rc < 0)
return rc;
}
+#endif
} else {
/*
* FLOAT charger detected as SDP by USB driver,
@@ -4312,6 +4603,12 @@
* real_charger_type
*/
chg->real_charger_type = POWER_SUPPLY_TYPE_USB;
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (usb_current < SDP_CURRENT_UA)
+ usb_current = SDP_CURRENT_UA;
+#endif
+
rc = vote(chg->usb_icl_votable, USB_PSY_VOTER,
true, usb_current);
if (rc < 0)
@@ -4475,10 +4772,15 @@
if (typec_mode >= POWER_SUPPLY_TYPEC_SINK &&
typec_mode <= POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER)
snk_attached = true;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ else if (typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY &&
+ typec_mode <= POWER_SUPPLY_TYPEC_SOURCE_HIGH)
+ src_attached = true;
+#else
else if (typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT &&
typec_mode <= POWER_SUPPLY_TYPEC_SOURCE_HIGH)
src_attached = true;
-
+#endif
/*
* If current power role is in DRP, and type-c is already in the
* mode (source or sink) that's being requested, it means this is
@@ -4623,7 +4925,11 @@
const struct apsd_result *apsd = smblib_get_apsd_result(chg);
int rc = 0;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int sec_charger;
+#else
int sec_charger, typec_mode;
+#endif
/*
* Ignore repetitive notification while PD is active, which
@@ -4696,9 +5002,13 @@
if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB &&
!chg->ok_to_pd) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote(chg->usb_icl_votable, USB_PSY_VOTER, true, SDP_CURRENT_UA);
+#else
typec_mode = smblib_get_prop_typec_mode(chg);
if (typec_rp_med_high(chg, typec_mode))
vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
+#endif
}
power_supply_changed(chg->usb_psy);
@@ -4933,10 +5243,20 @@
typec_source_rd = smblib_get_prop_ufp_mode(chg);
/* QC 2.0/3.0 adapter */
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (apsd_result->bit & (QC_3P0_BIT)) {
+ *total_current_ua = QC3_ICL_MAX;
+ return 0;
+ } else if (apsd_result->bit & (QC_2P0_BIT)) {
+ *total_current_ua = QC2_ICL_MAX;
+ return 0;
+ }
+#else
if (apsd_result->bit & (QC_3P0_BIT | QC_2P0_BIT)) {
*total_current_ua = HVDCP_CURRENT_UA;
return 0;
}
+#endif
if (non_compliant && !chg->typec_legacy_use_rp_icl) {
switch (apsd_result->bit) {
@@ -4945,12 +5265,21 @@
break;
case DCP_CHARGER_BIT:
case OCP_CHARGER_BIT:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ current_ua = DCP_CURRENT_UA;
+ break;
+ case FLOAT_CHARGER_BIT:
+ default:
+ current_ua = SDP_CURRENT_UA;
+ break;
+#else
case FLOAT_CHARGER_BIT:
current_ua = DCP_CURRENT_UA;
break;
default:
current_ua = 0;
break;
+#endif
}
*total_current_ua = max(current_ua, val.intval);
@@ -4958,6 +5287,9 @@
}
switch (typec_source_rd) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ case POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY:
+#endif
case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT:
switch (apsd_result->bit) {
case CDP_CHARGER_BIT:
@@ -4965,19 +5297,60 @@
break;
case DCP_CHARGER_BIT:
case OCP_CHARGER_BIT:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ current_ua = DCP_CURRENT_UA;
+ break;
+ case FLOAT_CHARGER_BIT:
+ default:
+ current_ua = SDP_CURRENT_UA;
+ break;
+#else
case FLOAT_CHARGER_BIT:
current_ua = chg->default_icl_ua;
break;
default:
current_ua = 0;
break;
+#endif
}
break;
case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ switch (apsd_result->bit) {
+ case CDP_CHARGER_BIT:
+ current_ua = CDP_CURRENT_UA;
+ break;
+ case DCP_CHARGER_BIT:
+ case OCP_CHARGER_BIT:
+ current_ua = DCP_CURRENT_UA;
+ break;
+ case FLOAT_CHARGER_BIT:
+ default:
+ current_ua = SDP_CURRENT_UA;
+ break;
+ }
+#else
current_ua = TYPEC_MEDIUM_CURRENT_UA;
+#endif
break;
case POWER_SUPPLY_TYPEC_SOURCE_HIGH:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ switch (apsd_result->bit) {
+ case CDP_CHARGER_BIT:
+ current_ua = CDP_CURRENT_UA;
+ break;
+ case DCP_CHARGER_BIT:
+ case OCP_CHARGER_BIT:
+ current_ua = DCP_CURRENT_UA;
+ break;
+ case FLOAT_CHARGER_BIT:
+ default:
+ current_ua = SDP_CURRENT_UA;
+ break;
+ }
+#else
current_ua = TYPEC_HIGH_CURRENT_UA;
+#endif
break;
case POWER_SUPPLY_TYPEC_NON_COMPLIANT:
case POWER_SUPPLY_TYPEC_NONE:
@@ -5154,6 +5527,15 @@
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->sw_jeita_enabled) {
+ if (chg->batt_psy)
+ power_supply_changed(chg->batt_psy);
+
+ return IRQ_HANDLED;
+ }
+#endif
+
if (chg->jeita_configured != JEITA_CFG_COMPLETE)
return IRQ_HANDLED;
@@ -5253,15 +5635,29 @@
reset_storm_count(wdata);
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->wa_flags & BOOST_BACK_WA) {
+ if (!chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data)
+ return IRQ_HANDLED;
+
+ wdata = &chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data->storm_data;
+ reset_storm_count(wdata);
+ }
+#else
if (!chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data)
return IRQ_HANDLED;
wdata = &chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data->storm_data;
reset_storm_count(wdata);
+#endif
/* Workaround for non-QC2.0-compliant chargers follows */
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (apsd->pst == POWER_SUPPLY_TYPE_USB_HVDCP) {
+#else
if (!chg->qc2_unsupported_voltage &&
apsd->pst == POWER_SUPPLY_TYPE_USB_HVDCP) {
+#endif
rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat);
if (rc < 0)
smblib_err(chg,
@@ -5298,21 +5694,41 @@
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->disable_suspend_on_collapse) {
+ rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
+ SUSPEND_ON_COLLAPSE_USBIN_BIT,
+ 0);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't turn off SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
+ rc);
+ }
+#else
rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
SUSPEND_ON_COLLAPSE_USBIN_BIT,
0);
if (rc < 0)
smblib_err(chg, "Couldn't turn off SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
rc);
+#endif
smblib_rerun_apsd(chg);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ smblib_run_aicl(chg, RERUN_AICL_BIT);
+#endif
}
return IRQ_HANDLED;
}
#define USB_WEAK_INPUT_UA 1400000
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define ICL_CHANGE_DELAY_MS 3000
+#else
#define ICL_CHANGE_DELAY_MS 1000
+#endif
irqreturn_t icl_change_irq_handler(int irq, void *data)
{
u8 stat;
@@ -5353,13 +5769,20 @@
return IRQ_HANDLED;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
/* If AICL settled then schedule work now */
if (settled_ua == get_effective_result(chg->usb_icl_votable))
delay = 0;
+#endif
cancel_delayed_work_sync(&chg->icl_change_work);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->icl_change_work,
+ msecs_to_jiffies(delay));
+#else
schedule_delayed_work(&chg->icl_change_work,
msecs_to_jiffies(delay));
+#endif
}
return IRQ_HANDLED;
@@ -5543,6 +5966,15 @@
if (vbus_rising) {
cancel_delayed_work_sync(&chg->pr_swap_detach_work);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->disable_suspend_on_collapse) {
+ rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
+ SUSPEND_ON_COLLAPSE_USBIN_BIT, 0);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't turn off SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
+ rc);
+ }
+#endif
vote(chg->awake_votable, DETACH_DETECT_VOTER, false, 0);
rc = smblib_request_dpdm(chg, true);
if (rc < 0)
@@ -5558,10 +5990,12 @@
if (chg->fcc_stepper_enable)
vote(chg->fcc_votable, FCC_STEPPER_VOTER, false, 0);
+#if !defined(CONFIG_TCT_PM7250_COMMON)
/* Schedule work to enable parallel charger */
vote(chg->awake_votable, PL_DELAY_VOTER, true, 0);
schedule_delayed_work(&chg->pl_enable_work,
msecs_to_jiffies(PL_DELAY_MS));
+#endif
} else {
/* Disable SW Thermal Regulation */
rc = smblib_set_sw_thermal_regulation(chg, false);
@@ -5618,18 +6052,58 @@
if (rc < 0)
smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->real_charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
+#else
smblib_update_usb_type(chg);
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0);
+ vote(chg->pl_disable_votable, PL_FCC_LOW_VOTER, false, 0);
+ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, SDP_100_MA);
+ vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0);
+ chg->adapter_cc_mode = 0;
+ chg->thermal_overheat = 0;
+ chg->pd_active = 0;
+ vote_override(chg->fcc_main_votable, CC_MODE_VOTER, false, 0);
+ vote_override(chg->usb_icl_votable, CC_MODE_VOTER, false, 0);
+ vote(chg->cp_disable_votable, OVERHEAT_LIMIT_VOTER, false, 0);
+ vote(chg->usb_icl_votable, OVERHEAT_LIMIT_VOTER, false, 0);
+ if (chg->disable_suspend_on_collapse) {
+ rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
+ SUSPEND_ON_COLLAPSE_USBIN_BIT, SUSPEND_ON_COLLAPSE_USBIN_BIT);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't turn on SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
+ rc);
+ }
+ vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);
+#endif
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (unlikely(chg->connector_type ==
+ POWER_SUPPLY_CONNECTOR_MICRO_USB)) {
+ smblib_micro_usb_plugin(chg, vbus_rising);
+ } else if (!vbus_rising) {
+ smblib_notify_device_mode(chg, false);
+ }
+#else
if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
smblib_micro_usb_plugin(chg, vbus_rising);
+#endif
vote(chg->temp_change_irq_disable_votable, DEFAULT_VOTER,
!vbus_rising, 0);
power_supply_changed(chg->usb_psy);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ smblib_err(chg, "IRQ: usbin-plugin %s\n",
+ vbus_rising ? "attached" : "detached");
+#else
smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n",
vbus_rising ? "attached" : "detached");
+#endif
}
irqreturn_t usb_plugin_irq_handler(int irq, void *data)
@@ -5645,6 +6119,7 @@
return IRQ_HANDLED;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
static void smblib_handle_slow_plugin_timeout(struct smb_charger *chg,
bool rising)
{
@@ -5658,6 +6133,7 @@
smblib_dbg(chg, PR_INTERRUPT, "IRQ: sdp-enumeration-done %s\n",
rising ? "rising" : "falling");
}
+#endif
#define APSD_EXTENDED_TIMEOUT_MS 400
/* triggers when HVDCP 3.0 authentication has finished */
@@ -5677,6 +6153,10 @@
apsd_result = smblib_get_apsd_result(chg);
if (apsd_result->bit & QC_3P0_BIT) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER,
+ true, QC3_ICL_MAX);
+#endif
/* for QC3, switch to CP if present */
if (chg->sec_cp_present) {
rc = smblib_select_sec_charger(chg,
@@ -5722,8 +6202,14 @@
CHARGER_TYPE_VOTER, false, 0);
vote(chg->hdc_irq_disable_votable,
CHARGER_TYPE_VOTER, false, 0);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true,
- hvdcp_ua);
+ QC2_ICL_MAX);
+#else
+ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true,
+ HVDCP_CURRENT_UA);
+#endif
} else {
/* A plain DCP, enforce DCP ICL if specified */
vote(chg->usb_icl_votable, DCP_VOTER,
@@ -5735,6 +6221,7 @@
rising ? "rising" : "falling");
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
/* triggers when HVDCP is detected */
static void smblib_handle_hvdcp_detect_done(struct smb_charger *chg,
bool rising)
@@ -5742,11 +6229,14 @@
smblib_dbg(chg, PR_INTERRUPT, "IRQ: hvdcp-detect-done %s\n",
rising ? "rising" : "falling");
}
+#endif
static void update_sw_icl_max(struct smb_charger *chg, int pst)
{
+#if !defined(CONFIG_TCT_PM7250_COMMON)
int typec_mode;
int rp_ua;
+#endif
/* while PD is active it should have complete ICL control */
if (chg->pd_active)
@@ -5764,6 +6254,7 @@
|| pst == POWER_SUPPLY_TYPE_USB_HVDCP_3)
return;
+#if !defined(CONFIG_TCT_PM7250_COMMON)
/* TypeC rp med or high, use rp value */
typec_mode = smblib_get_prop_typec_mode(chg);
if (typec_rp_med_high(chg, typec_mode)) {
@@ -5771,6 +6262,7 @@
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, rp_ua);
return;
}
+#endif
/* rp-std or legacy, USB BC 1.2 */
switch (pst) {
@@ -5782,9 +6274,14 @@
if (!is_client_vote_enabled(chg->usb_icl_votable,
USB_PSY_VOTER)) {
/* if flash is active force 500mA */
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote(chg->usb_icl_votable, USB_PSY_VOTER, true,
+ SDP_CURRENT_UA);
+#else
vote(chg->usb_icl_votable, USB_PSY_VOTER, true,
is_flash_active(chg) ?
SDP_CURRENT_UA : SDP_100_MA);
+#endif
}
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, false, 0);
break;
@@ -5793,16 +6290,27 @@
CDP_CURRENT_UA);
break;
case POWER_SUPPLY_TYPE_USB_DCP:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true,
+ DCP_CURRENT_UA);
+ vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
+#else
rp_ua = get_rp_based_dcp_current(chg, typec_mode);
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, rp_ua);
+#endif
break;
case POWER_SUPPLY_TYPE_USB_FLOAT:
/*
* limit ICL to 100mA, the USB driver will enumerate to check
* if this is a SDP and appropriately set the current
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true,
+ SDP_CURRENT_UA);
+#else
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true,
SDP_100_MA);
+#endif
break;
case POWER_SUPPLY_TYPE_UNKNOWN:
default:
@@ -5826,10 +6334,19 @@
switch (apsd_result->bit) {
case SDP_CHARGER_BIT:
case CDP_CHARGER_BIT:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->use_extcon ||
+ (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY)) {
+ smblib_notify_device_mode(chg, true);
+ }
+ break;
+ case FLOAT_CHARGER_BIT:
+#else
case FLOAT_CHARGER_BIT:
if (chg->use_extcon)
smblib_notify_device_mode(chg, true);
break;
+#endif
case OCP_CHARGER_BIT:
case DCP_CHARGER_BIT:
break;
@@ -5841,6 +6358,75 @@
apsd_result->name);
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define PLUGIN_DELAY_MS (60000)
+irqreturn_t usb_source_change_irq_handler(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+ struct smb_charger *chg = irq_data->parent_data;
+ int rc = 0;
+ u8 stat;
+
+ /* PD session is ongoing, ignore BC1.2 and QC detection */
+ if (chg->pd_active)
+ goto out2;
+
+ rc = smblib_read(chg, APSD_STATUS_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read APSD_STATUS rc=%d\n", rc);
+ goto out2;
+ }
+
+ /* skip for no necessary actions. */
+ if (!(stat & APSD_DTC_STATUS_DONE_BIT)
+ || (stat & VADP_CHANGE_DONE_AFTER_AUTH_BIT)
+ || (stat & APSD_STATUS_7_BIT)) {
+ smblib_dbg(chg, PR_MISC, "skip with 0x%02x\n", stat);
+ goto out1;
+ }
+
+ /* if this's the first time detect as float/ocp/unknown type,
+ we can recheck this type via rerun apsd. */
+ if (!chg->apsd_rerun_done) {
+ const struct apsd_result *first_type = smblib_get_apsd_result(chg);
+ if ((first_type->bit == FLOAT_CHARGER_BIT)
+ || (first_type->bit == OCP_CHARGER_BIT)
+ || (!first_type->bit)
+ || (stat == 0x21 && first_type->bit == SDP_CHARGER_BIT)) {
+ smblib_err(chg, "type:'%s', stat:0x%x, rerun apsd now.\n",
+ first_type->name, stat);
+ chg->apsd_rerun_done = true;
+ smblib_rerun_apsd(chg);
+ goto out2;
+ }
+ }
+
+ smblib_err(chg, "IRQ: APSD_STATUS_REG=0x%02x\n", stat);
+ cancel_delayed_work_sync(&chg->pl_enable_work);
+ vote(chg->awake_votable, PL_DELAY_VOTER, true, 0);
+
+ smblib_handle_apsd_done(chg,
+ (bool)(stat & APSD_DTC_STATUS_DONE_BIT));
+
+ smblib_handle_hvdcp_check_timeout(chg,
+ (bool)(stat & HVDCP_CHECK_TIMEOUT_BIT),
+ (bool)(stat & QC_CHARGER_BIT));
+
+ smblib_handle_hvdcp_3p0_auth_done(chg,
+ (bool)(stat & QC_AUTH_DONE_STATUS_BIT));
+
+ queue_delayed_work(private_chg_wq, &chg->pl_enable_work,
+ msecs_to_jiffies(PLUGIN_DELAY_MS));
+ smblib_err(chg, "sleeping with psy:%d\n",
+ chg->real_charger_type);
+
+out1:
+ power_supply_changed(chg->usb_psy);
+ smblib_hvdcp_adaptive_voltage_change(chg);
+out2:
+ return IRQ_HANDLED;
+}
+#else
irqreturn_t usb_source_change_irq_handler(int irq, void *data)
{
struct smb_irq_data *irq_data = data;
@@ -5903,6 +6489,7 @@
return IRQ_HANDLED;
}
+#endif
enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm,
ktime_t time)
@@ -6026,6 +6613,9 @@
{
int rc = 0;
u8 stat;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int typec_mode = POWER_SUPPLY_TYPEC_NONE;
+#endif
if (chg->pr_swap_in_progress) {
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, false, 0);
@@ -6043,6 +6633,17 @@
chg->ok_to_pd = (!(chg->typec_legacy || chg->pd_disabled)
|| chg->early_usb_attach) && !chg->pd_not_supported;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ typec_mode = smblib_get_prop_ufp_mode(chg);
+ if (typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY) {
+ chg->ok_to_pd = false;
+ }
+
+ pr_err("ok_to_pd=%d {%d,%d,%d,0x%02x}\n", chg->ok_to_pd,
+ typec_mode, chg->typec_legacy,
+ chg->early_usb_attach, stat);
+#endif
+
/* allow apsd proceed to detect QC2/3 */
if (!chg->ok_to_pd)
smblib_hvdcp_detect_try_enable(chg, true);
@@ -6231,7 +6832,13 @@
chg->qc3p5_detected = false;
typec_src_fault_condition_cfg(chg, false);
smblib_hvdcp_detect_try_enable(chg, false);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->pd_active = 0;
+ chg->real_charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
+#else
smblib_update_usb_type(chg);
+#endif
if (chg->wa_flags & BOOST_BACK_WA) {
data = chg->irq_info[SWITCHER_POWER_OK_IRQ].irq_data;
@@ -6297,7 +6904,11 @@
vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0);
chg->adapter_cc_mode = 0;
chg->thermal_overheat = 0;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ vote_override(chg->fcc_main_votable, CC_MODE_VOTER, false, 0);
+#else
vote_override(chg->fcc_votable, CC_MODE_VOTER, false, 0);
+#endif
vote_override(chg->usb_icl_votable, CC_MODE_VOTER, false, 0);
vote(chg->cp_disable_votable, OVERHEAT_LIMIT_VOTER, false, 0);
vote(chg->usb_icl_votable, OVERHEAT_LIMIT_VOTER, false, 0);
@@ -6345,14 +6956,25 @@
smblib_err(chg, "Couldn't restore max pulses rc=%d\n",
rc);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chg->disable_suspend_on_collapse) {
+ rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
+ SUSPEND_ON_COLLAPSE_USBIN_BIT,
+ SUSPEND_ON_COLLAPSE_USBIN_BIT);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't turn on SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
+ rc);
+ }
+ chg->qc2_unsupported_voltage = QC2_NON_COMPLIANT_12V;
+#else
rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
SUSPEND_ON_COLLAPSE_USBIN_BIT,
SUSPEND_ON_COLLAPSE_USBIN_BIT);
if (rc < 0)
smblib_err(chg, "Couldn't turn on SUSPEND_ON_COLLAPSE_USBIN_BIT rc=%d\n",
rc);
-
chg->qc2_unsupported_voltage = QC2_COMPLIANT;
+#endif
}
if (chg->use_extcon)
@@ -6360,6 +6982,10 @@
chg->typec_legacy = false;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chg->apsd_rerun_done = false;
+#endif
+
del_timer_sync(&chg->apsd_timer);
chg->apsd_ext_timeout = false;
}
@@ -6414,8 +7040,13 @@
chg->lpd_stage = LPD_STAGE_FLOAT;
cancel_delayed_work_sync(&chg->lpd_ra_open_work);
vote(chg->awake_votable, LPD_VOTER, true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->lpd_ra_open_work,
+ msecs_to_jiffies(300));
+#else
schedule_delayed_work(&chg->lpd_ra_open_work,
msecs_to_jiffies(300));
+#endif
}
}
@@ -6481,8 +7112,13 @@
smblib_handle_rp_change(chg, typec_mode);
chg->typec_mode = typec_mode;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ smblib_err(chg, "IRQ: Type-C %s detected\n",
+ smblib_typec_mode_name[chg->typec_mode]);
+#else
smblib_dbg(chg, PR_INTERRUPT, "IRQ: cc-state-change; Type-C %s detected\n",
smblib_typec_mode_name[chg->typec_mode]);
+#endif
power_supply_changed(chg->usb_psy);
@@ -6513,7 +7149,9 @@
if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
return IRQ_HANDLED;
+#if !defined(CONFIG_TCT_PM7250_COMMON)
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name);
+#endif
rc = smblib_read(chg, TYPE_C_STATE_MACHINE_STATUS_REG, &stat);
if (rc < 0) {
@@ -6522,6 +7160,10 @@
return IRQ_HANDLED;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ smblib_err(chg, "IRQ: 0x%02x\n", stat);
+#endif
+
attached = !!(stat & TYPEC_ATTACH_DETACH_STATE_BIT);
if (attached) {
@@ -6604,8 +7246,13 @@
mutex_unlock(&chg->typec_lock);
if (chg->lpd_stage == LPD_STAGE_FLOAT_CANCEL)
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->lpd_detach_work,
+ msecs_to_jiffies(1000));
+#else
schedule_delayed_work(&chg->lpd_detach_work,
msecs_to_jiffies(1000));
+#endif
}
rc = smblib_masked_write(chg, USB_CMD_PULLDOWN_REG,
@@ -6720,7 +7367,9 @@
smblib_dbg(chg, PR_WLS, "rerunning DCIN AICL\n");
+#if !defined(CONFIG_TCT_PM7250_COMMON)
pm_stay_awake(chg->dev);
+#endif
schedule_work(&chg->dcin_aicl_work);
return ALARMTIMER_NORESTART;
@@ -6737,7 +7386,11 @@
return;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (icl <= DCIN_ICL_MIN_UA) {
+#else
if (icl == DCIN_ICL_MIN_UA) {
+#endif
/* Cannot possibly decrease ICL any further - do nothing */
smblib_dbg(chg, PR_WLS, "hit min ICL: stop\n");
return;
@@ -6918,7 +7571,12 @@
*/
vote(chg->hdc_irq_disable_votable, HDC_IRQ_VOTER, true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->clear_hdc_work,
+ msecs_to_jiffies(60));
+#else
schedule_delayed_work(&chg->clear_hdc_work, msecs_to_jiffies(60));
+#endif
return IRQ_HANDLED;
}
@@ -7002,7 +7660,11 @@
if (chg->wa_flags & SW_THERM_REGULATION_WA) {
cancel_delayed_work_sync(&chg->thermal_regulation_work);
vote(chg->awake_votable, SW_THERM_REGULATION_VOTER, true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->thermal_regulation_work, 0);
+#else
schedule_delayed_work(&chg->thermal_regulation_work, 0);
+#endif
}
power_supply_changed(chg->batt_psy);
@@ -7094,8 +7756,13 @@
if (stat & USBIN_OV_RT_STS_BIT) {
chg->dbc_usbov = true;
vote(chg->awake_votable, USBOV_DBC_VOTER, true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->usbov_dbc_work,
+ msecs_to_jiffies(USB_OV_DBC_PERIOD_MS));
+#else
schedule_delayed_work(&chg->usbov_dbc_work,
msecs_to_jiffies(USB_OV_DBC_PERIOD_MS));
+#endif
} else {
cancel_delayed_work_sync(&chg->usbov_dbc_work);
chg->dbc_usbov = false;
@@ -7133,8 +7800,13 @@
if (!chg->pr_swap_in_progress) {
cancel_delayed_work_sync(&chg->pr_swap_detach_work);
vote(chg->awake_votable, DETACH_DETECT_VOTER, true, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_delayed_work(private_chg_wq, &chg->pr_swap_detach_work,
+ msecs_to_jiffies(DETACH_DETECT_DELAY_MS));
+#else
schedule_delayed_work(&chg->pr_swap_detach_work,
msecs_to_jiffies(DETACH_DETECT_DELAY_MS));
+#endif
}
rc = smblib_masked_write(chg, TYPE_C_DEBOUNCE_OPTION_REG,
@@ -7365,7 +8037,10 @@
pl_enable_work.work);
smblib_dbg(chg, PR_PARALLEL, "timer expired, enabling parallel\n");
+
+#if !defined(CONFIG_TCT_PM7250_COMMON)
vote(chg->pl_disable_votable, PL_DELAY_VOTER, false, 0);
+#endif
vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);
}
@@ -7376,9 +8051,15 @@
int rc;
rc = smblib_update_thermal_readings(chg);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (rc < 0)
+ smblib_dbg(chg, PR_MISC, "Couldn't read current thermal values %d\n",
+ rc);
+#else
if (rc < 0)
smblib_err(chg, "Couldn't read current thermal values %d\n",
rc);
+#endif
rc = smblib_process_thermal_readings(chg);
if (rc < 0)
@@ -7622,6 +8303,9 @@
alarm_start_relative(&chg->chg_termination_alarm, ms_to_ktime(delay));
out:
vote(chg->awake_votable, CHG_TERMINATION_VOTER, false, 0);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ pm_relax(chg->dev);
+#endif
}
static enum alarmtimer_restart chg_termination_alarm_cb(struct alarm *alarm,
@@ -7635,7 +8319,12 @@
/* Atomic context, cannot use voter */
pm_stay_awake(chg->dev);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ queue_work(private_chg_wq, &chg->chg_termination_work);
+#else
schedule_work(&chg->chg_termination_work);
+#endif
return ALARMTIMER_NORESTART;
}
@@ -7941,6 +8630,37 @@
pm_relax(chg->dev);
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+int recheck_unknown_typec(struct smb_charger *chg)
+{
+ int rc;
+ u8 stat = 0;
+
+ if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
+ return -1;
+
+ if(chg->typec_mode != POWER_SUPPLY_TYPEC_NONE)
+ return -1;
+
+ if(chg->real_charger_type != POWER_SUPPLY_TYPE_UNKNOWN)
+ return -1;
+
+ rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read USBIN_RT_STS rc=%d\n", rc);
+ return rc;
+ }
+ if (!(stat & USBIN_PLUGIN_RT_STS_BIT)) {
+ return -1;
+ }
+ pr_err("detected non-compliant cc line\n");
+ vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, USBIN_500MA);
+ smblib_request_dpdm(chg, true);
+ smblib_rerun_apsd(chg);
+ return 0;
+}
+#endif
+
static int smblib_create_votables(struct smb_charger *chg)
{
int rc = 0;
diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h
index 6294edc..5d67ec2 100644
--- a/drivers/power/supply/qcom/smb5-lib.h
+++ b/drivers/power/supply/qcom/smb5-lib.h
@@ -95,7 +95,13 @@
#define SDP_100_MA 100000
#define SDP_CURRENT_UA 500000
#define CDP_CURRENT_UA 1500000
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define DCP_CURRENT_UA 2000000
+#else
#define DCP_CURRENT_UA 1500000
+#endif
+
#define HVDCP_CURRENT_UA 3000000
#define TYPEC_DEFAULT_CURRENT_UA 900000
#define TYPEC_MEDIUM_CURRENT_UA 1500000
@@ -105,6 +111,14 @@
#define DCIN_ICL_STEP_UA 100000
#define ROLE_REVERSAL_DELAY_MS 500
+#if defined(CONFIG_TCT_PM7250_COMMON)
+
+#define QC3_ICL_MAX 2000000
+#define QC2_ICL_MAX 1500000
+#define HW_ICL_MAX 2050000
+#endif
+
+
enum smb_mode {
PARALLEL_MASTER = 0,
PARALLEL_SLAVE,
@@ -399,6 +413,11 @@
struct mutex dpdm_lock;
struct mutex typec_lock;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ bool apsd_rerun_done;
+ bool disable_suspend_on_collapse;
+#endif
+
/* power supplies */
struct power_supply *batt_psy;
struct power_supply *usb_psy;
@@ -506,9 +525,15 @@
int system_temp_level;
int thermal_levels;
int *thermal_mitigation;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int *thermal_mitigation_lcdon;
+#endif
int dcp_icl_ua;
int fake_capacity;
int fake_batt_status;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int real_soc;
+#endif
bool step_chg_enabled;
bool sw_jeita_enabled;
bool jeita_arb_enable;
@@ -676,6 +701,11 @@
irqreturn_t temp_change_irq_handler(int irq, void *data);
irqreturn_t usbin_ov_irq_handler(int irq, void *data);
irqreturn_t sdam_sts_change_irq_handler(int irq, void *data);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+int recheck_unknown_typec(struct smb_charger *chg);
+#endif
+
int smblib_get_prop_input_suspend(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_present(struct smb_charger *chg,
diff --git a/drivers/power/supply/qcom/smb5-reg.h b/drivers/power/supply/qcom/smb5-reg.h
index 311e810..1d0d082 100644
--- a/drivers/power/supply/qcom/smb5-reg.h
+++ b/drivers/power/supply/qcom/smb5-reg.h
@@ -42,6 +42,9 @@
#define BATTERY_CHARGER_STATUS_2_REG (CHGR_BASE + 0x07)
#define CHARGER_ERROR_STATUS_BAT_OV_BIT BIT(1)
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define CHARGER_ERROR_STATUS_SFT_EXPIRE_BIT BIT(2)
+#endif
#define BATTERY_CHARGER_STATUS_5_REG (CHGR_BASE + 0x0B)
#define ENABLE_TRICKLE_BIT BIT(2)
@@ -526,6 +529,9 @@
#define AICL_RERUN_TIME_CFG_REG (MISC_BASE + 0x61)
#define AICL_RERUN_TIME_12S_VAL 0x01
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define AICL_RERUN_TIME_3MIN_VAL 0x03
+#endif
#define MISC_THERMREG_SRC_CFG_REG (MISC_BASE + 0x70)
#define THERMREG_SW_ICL_ADJUST_BIT BIT(7)
diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c
index 369fc66..8ce966d 100644
--- a/drivers/power/supply/qcom/step-chg-jeita.c
+++ b/drivers/power/supply/qcom/step-chg-jeita.c
@@ -18,6 +18,11 @@
#define JEITA_VOTER "JEITA_VOTER"
#define JEITA_FCC_SCALE_VOTER "JEITA_FCC_SCALE_VOTER"
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define CHG_CTL_VOTER "CHG_CTL_VOTER"
+#define VBAT_LMT_VOTER "VBAT_LMT_VOTER"
+#endif
+
#define is_between(left, right, value) \
(((left) >= (right) && (left) >= (value) \
&& (value) >= (right)) \
@@ -64,6 +69,11 @@
long jeita_max_fcc_ua;
long jeita_fcc_step_size;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ int max_fv_uv;
+ bool last_input_present;
+#endif
+
struct step_chg_cfg *step_chg_config;
struct jeita_fcc_cfg *jeita_fcc_config;
struct jeita_fv_cfg *jeita_fv_config;
@@ -83,6 +93,10 @@
static struct step_chg_info *the_chip;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define STEP_CHG_HYSTERISIS_DELAY_MS 10000
+#endif
+
#define STEP_CHG_HYSTERISIS_DELAY_US 5000000 /* 5 secs */
#define BATT_HOT_DECIDEGREE_MAX 600
@@ -112,6 +126,7 @@
return true;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
static bool is_usb_available(struct step_chg_info *chip)
{
if (!chip->usb_psy)
@@ -122,6 +137,7 @@
return true;
}
+#endif
static bool is_input_present(struct step_chg_info *chip)
{
@@ -289,6 +305,10 @@
return rc;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chip->max_fv_uv = max_fv_uv;
+#endif
+
rc = of_property_read_u32(profile_node, "qcom,fastchg-current-ma",
&max_fcc_ma);
if (rc < 0) {
@@ -312,11 +332,23 @@
chip->ocv_based_step_chg =
of_property_read_bool(profile_node, "qcom,ocv-based-step-chg");
if (chip->ocv_based_step_chg) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chip->step_chg_config->param.psy_prop =
+ POWER_SUPPLY_PROP_VOLTAGE_NOW;
+#else
chip->step_chg_config->param.psy_prop =
POWER_SUPPLY_PROP_VOLTAGE_OCV;
+#endif
chip->step_chg_config->param.prop_name = "OCV";
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+
+ chip->step_chg_config->param.rise_hys = 50000;
+ chip->step_chg_config->param.fall_hys = 50000;
+#else
chip->step_chg_config->param.rise_hys = 0;
chip->step_chg_config->param.fall_hys = 0;
+#endif
chip->step_chg_config->param.use_bms = true;
}
@@ -476,8 +508,16 @@
* If the threshold is lesser than the minimum allowed range,
* return -ENODATA.
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (threshold < 0 || threshold < range[0].low_threshold) {
+ pr_debug("invalid lowest value: %d < %d\n",
+ threshold, range[0].low_threshold);
+ return -ENODATA;
+ }
+#else
if (threshold < range[0].low_threshold)
return -ENODATA;
+#endif
/* First try to find the matching index without hysteresis */
for (i = 0; i < MAX_STEP_CHG_ENTRIES; i++) {
@@ -485,6 +525,12 @@
/* First invalid table entry; exit loop */
break;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (range[i].high_threshold == range[i].low_threshold) {
+ /* invalid table entry; exit loop */
+ break;
+ }
+#endif
if (is_between(range[i].low_threshold,
range[i].high_threshold, threshold)) {
@@ -504,7 +550,11 @@
if (*new_index == -EINVAL) {
if (i == 0) {
/* Battery profile data array is completely invalid */
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ return -EINVAL;
+#else
return -ENODATA;
+#endif
}
*new_index = (i - 1);
@@ -547,6 +597,7 @@
return 0;
}
+#if !defined(CONFIG_TCT_PM7250_COMMON)
#define TAPERED_STEP_CHG_FCC_REDUCTION_STEP_MA 50000 /* 50 mA */
static void taper_fcc_step_chg(struct step_chg_info *chip, int index,
int current_voltage)
@@ -589,7 +640,176 @@
current_fcc - TAPERED_STEP_CHG_FCC_REDUCTION_STEP_MA));
}
}
+#endif
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define OV_VOTER "OV_VOTER"
+#define SOC_VOTER "SOC_VOTER"
+#define VBATT_VOTER "VBATT_VOTER"
+
+#define LIMIT_VBAT_OV (4430000)
+#define LIMIT_VBAT_MAX (4400000)
+#define LIMIT_VBAT_MIN (4300000)
+#define LIMIT_VBAT_CV (4350000)
+#define CV_DOWN_DELTA_UA (100000)
+#define CV_UP_DELTA_UA (50000)
+#define MIN_FCC_UA (500000)
+#define MAX_FCC_UA (2000000)
+static int handle_vbatt_ov(struct step_chg_info *chip)
+{
+ union power_supply_propval pval = {0, };
+ int rc = 0;
+
+ if (!chip->fcc_votable)
+ chip->fcc_votable = find_votable("FCC");
+ if (!chip->fcc_votable) {
+ pr_err("fcc voter NULL\n");
+ return -EINVAL;
+ }
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
+ if (rc < 0 || (pval.intval <= LIMIT_VBAT_MAX)) {
+ pr_debug("vbatt-%d lower or rc-%d, restored\n",
+ pval.intval, rc);
+ vote(chip->fcc_votable, OV_VOTER, false, 0);
+ return rc;
+ }
+
+ if (pval.intval >= LIMIT_VBAT_OV) {
+ pr_err("OV-%d, disabled chg\n", pval.intval);
+ vote(chip->fcc_votable, OV_VOTER, true, 0);
+ }
+
+ return 0;
+}
+
+static int handle_vbatt_limit(struct step_chg_info *chip)
+{
+ union power_supply_propval pval = {0, };
+ int rc = 0;
+ int fcc_val_uA = 500000;
+
+ if (!chip->fcc_votable)
+ chip->fcc_votable = find_votable("FCC");
+ if (!chip->fcc_votable) {
+ pr_err("fcc voter NULL\n");
+ return -EINVAL;
+ }
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_CAPACITY, &pval);
+ if (rc < 0 || pval.intval < 80) {
+ vote(chip->fcc_votable, SOC_VOTER, false, 0);
+ } else if (pval.intval >= 90) {
+ vote(chip->fcc_votable, SOC_VOTER, true, 1500000);
+ } else if (pval.intval >= 85) {
+ vote(chip->fcc_votable, SOC_VOTER, true, 1800000);
+ }
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
+ if (rc < 0 || (pval.intval < LIMIT_VBAT_MIN)) {
+ pr_err_ratelimited("vbatt-%d lower or rc-%d, restored\n",
+ pval.intval, rc);
+ vote(chip->fcc_votable, VBATT_VOTER, false, 0);
+ return rc;
+ }
+
+ fcc_val_uA = get_effective_result(chip->fcc_votable);
+ pr_err_ratelimited("f=%d, v=%d\n", fcc_val_uA, pval.intval);
+
+ if (pval.intval > LIMIT_VBAT_MAX) {
+ if (fcc_val_uA >= (MIN_FCC_UA + CV_DOWN_DELTA_UA)) {
+ fcc_val_uA -= CV_DOWN_DELTA_UA;
+ vote(chip->fcc_votable, VBATT_VOTER, true, fcc_val_uA);
+ pr_err_ratelimited("down FCC to %d\n", fcc_val_uA);
+ }
+ } else if (pval.intval < LIMIT_VBAT_CV) {
+ if ((fcc_val_uA > 0) &&
+ (fcc_val_uA <= (MAX_FCC_UA - CV_UP_DELTA_UA))) {
+ fcc_val_uA += CV_UP_DELTA_UA;
+ vote(chip->fcc_votable, VBATT_VOTER, true, fcc_val_uA);
+ pr_err_ratelimited("up FCC to %d\n", fcc_val_uA);
+ }
+ }
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static int handle_step_chg_config(struct step_chg_info *chip)
+{
+ union power_supply_propval pval = {0, };
+ int rc = 0, fcc_ua = 0;
+ u64 elapsed_ms;
+
+ if (!chip->step_chg_enable || !chip->step_chg_cfg_valid) {
+ pr_debug("step_chg disabled or invalid, %d, %d\n",
+ chip->step_chg_enable, chip->step_chg_cfg_valid);
+ return 0;
+ }
+
+ if (!chip->fcc_votable)
+ chip->fcc_votable = find_votable("FCC");
+ if (!chip->fcc_votable)
+ /* changing FCC is a must */
+ return -EINVAL;
+
+ elapsed_ms = ktime_ms_delta(ktime_get(), chip->step_last_update_time);
+ /* skip processing, event too early */
+ if (elapsed_ms < STEP_CHG_HYSTERISIS_DELAY_MS)
+ return 0;
+
+ rc = handle_vbatt_ov(chip);
+ if (rc < 0)
+ pr_err("Couldn't limit ov rc = %d\n", rc);
+
+ rc = handle_vbatt_limit(chip);
+ if (rc < 0)
+ pr_err("Couldn't limit vbat rc = %d\n", rc);
+
+ if (chip->step_chg_config->param.use_bms)
+ rc = power_supply_get_property(chip->bms_psy,
+ chip->step_chg_config->param.psy_prop, &pval);
+ else
+ rc = power_supply_get_property(chip->batt_psy,
+ chip->step_chg_config->param.psy_prop, &pval);
+
+ if (rc < 0) {
+ pr_debug("Couldn't read %s property rc=%d\n",
+ chip->step_chg_config->param.prop_name, rc);
+ vote(chip->fcc_votable, STEP_CHG_VOTER, false, 0);
+ return rc;
+ }
+
+ rc = get_val(chip->step_chg_config->fcc_cfg,
+ chip->step_chg_config->param.rise_hys,
+ chip->step_chg_config->param.fall_hys,
+ chip->step_index,
+ pval.intval,
+ &chip->step_index,
+ &fcc_ua);
+ if (rc < 0) {
+ pr_debug("Couldn't get_val:%d from step_chg_config, rc=%d\n",
+ pval.intval, rc);
+ vote(chip->fcc_votable, STEP_CHG_VOTER, false, 0);
+ goto update_time;
+ }
+
+ fcc_ua = chip->step_chg_config->fcc_cfg[chip->step_index].value;
+ vote(chip->fcc_votable, STEP_CHG_VOTER, true, fcc_ua);
+
+ pr_debug("%s=%d, Step-FCC=%duA, index=%d\n",
+ chip->step_chg_config->param.prop_name,
+ pval.intval,
+ get_client_vote(chip->fcc_votable, STEP_CHG_VOTER),
+ chip->step_index);
+update_time:
+ chip->step_last_update_time = ktime_get();
+ return 0;
+}
+#else
static int handle_step_chg_config(struct step_chg_info *chip)
{
union power_supply_propval pval = {0, };
@@ -671,6 +891,7 @@
chip->step_last_update_time = ktime_get();
return 0;
}
+#endif
static void handle_jeita_fcc_scaling(struct step_chg_info *chip)
{
@@ -742,6 +963,116 @@
}
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define FV_LVL_1 (300000)
+#define FV_LVL_2 (200000)
+#define FV_LVL_3 (100000)
+#define FV_LVL_4 (50000)
+#define FCC_LVL_1 (1500000)
+#define FCC_LVL_2 (1000000)
+#define FCC_LVL_3 (500000)
+static int handle_jeita(struct step_chg_info *chip)
+{
+ union power_supply_propval pval = {0, };
+ int rc = 0, fcc_ua = 0, fv_uv = 0;
+ u64 elapsed_ms = 0;
+
+ if (!chip->sw_jeita_enable || !chip->sw_jeita_cfg_valid) {
+ pr_debug("sw_jeita disabled or invalid, %d, %d\n",
+ chip->sw_jeita_enable, chip->sw_jeita_cfg_valid);
+ return 0;
+ }
+
+ if (!chip->fcc_votable)
+ chip->fcc_votable = find_votable("FCC");
+ if (!chip->fcc_votable)
+ /* changing FCC is a must */
+ return -EINVAL;
+
+ elapsed_ms = ktime_ms_delta(ktime_get(), chip->jeita_last_update_time);
+ /* skip processing, event too early */
+ if (elapsed_ms < STEP_CHG_HYSTERISIS_DELAY_MS)
+ return 0;
+
+ if (chip->jeita_fcc_config->param.use_bms)
+ rc = power_supply_get_property(chip->bms_psy,
+ chip->jeita_fcc_config->param.psy_prop, &pval);
+ else
+ rc = power_supply_get_property(chip->batt_psy,
+ chip->jeita_fcc_config->param.psy_prop, &pval);
+
+ if (rc < 0) {
+ pr_debug("Couldn't read %s property rc=%d\n",
+ chip->jeita_fcc_config->param.prop_name, rc);
+ vote(chip->fcc_votable, JEITA_VOTER, false, 0);
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, false, 0);
+ vote(chip->fcc_votable, CHG_CTL_VOTER, false, 0);
+ return rc;
+ }
+
+ rc = get_val(chip->jeita_fcc_config->fcc_cfg,
+ chip->jeita_fcc_config->param.rise_hys,
+ chip->jeita_fcc_config->param.fall_hys,
+ chip->jeita_fcc_index,
+ pval.intval,
+ &chip->jeita_fcc_index,
+ &fcc_ua);
+ if (rc < 0) {
+ pr_debug("Couldn't get_val:%d from jeita_fcc_config, rc=%d\n",
+ pval.intval, rc);
+ if (rc == -ENODATA)
+ fcc_ua = 0;
+ else
+ fcc_ua = -EINVAL;
+ }
+ vote(chip->fcc_votable, JEITA_VOTER, (fcc_ua>=0) ? true : false, fcc_ua);
+
+ rc = get_val(chip->jeita_fv_config->fv_cfg,
+ chip->jeita_fv_config->param.rise_hys,
+ chip->jeita_fv_config->param.fall_hys,
+ chip->jeita_fv_index,
+ pval.intval,
+ &chip->jeita_fv_index,
+ &fv_uv);
+ if (rc < 0)
+ fv_uv = 0;
+
+ if (fv_uv > 3600000 && fv_uv < chip->max_fv_uv) {
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
+ if(rc < 0) {
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, false, 0);
+ vote(chip->fcc_votable, CHG_CTL_VOTER, false, 0);
+ } else {
+ if (pval.intval > fv_uv) {
+ vote(chip->fcc_votable, CHG_CTL_VOTER, true, 0);
+ } else if ((pval.intval+FV_LVL_4) < fv_uv) {
+ if ((pval.intval+FV_LVL_3) >= fv_uv) {
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, true, FCC_LVL_3);
+ } else if ((pval.intval+FV_LVL_2) >= fv_uv) {
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, true, FCC_LVL_2);
+ } else if ((pval.intval+FV_LVL_1) >= fv_uv) {
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, true, FCC_LVL_1);
+ } else {
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, false, 0);
+ }
+ vote(chip->fcc_votable, CHG_CTL_VOTER, false, 0);
+ }
+ }
+ } else {
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, false, 0);
+ vote(chip->fcc_votable, CHG_CTL_VOTER, false, 0);
+ }
+
+ pr_debug("current FV=%d, Jeita-FV-FCC=%d,%d, index=%d\n",
+ pval.intval, fv_uv,
+ get_effective_result(chip->fcc_votable),
+ chip->jeita_fv_index);
+
+ chip->jeita_last_update_time = ktime_get();
+ return 0;
+}
+#else
#define JEITA_SUSPEND_HYST_UV 50000
static int handle_jeita(struct step_chg_info *chip)
{
@@ -858,6 +1189,7 @@
return 0;
}
+#endif
static int handle_battery_insertion(struct step_chg_info *chip)
{
@@ -892,18 +1224,91 @@
return rc;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#if defined(CONFIG_TCT_IEEE1725)
+#define IEEE_VOTER "IEEE_VOTER"
+#define LIMIT_LOWER_TEMP_LVL (30)
+#define LIMIT_UPPER_TEMP_LVL (50)
+static int handle_ieee_limit(struct step_chg_info *chip)
+{
+ union power_supply_propval pval = {0, };
+ int rc = 0;
+
+ if (!chip->fcc_votable)
+ chip->fcc_votable = find_votable("FCC");
+ if (!chip->fcc_votable)
+ return -EINVAL;
+
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_TEMP, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't read batt temp, rc=%d\n", rc);
+ vote(chip->fcc_votable, IEEE_VOTER, false, 0);
+ return rc;
+ }
+
+ if (pval.intval < LIMIT_LOWER_TEMP_LVL) {
+ vote(chip->fcc_votable, IEEE_VOTER, true, 0);
+ } else if (pval.intval > LIMIT_UPPER_TEMP_LVL) {
+ vote(chip->fcc_votable, IEEE_VOTER, false, 0);
+ }
+ return 0;
+}
+#endif
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static void step_chg_status_change_work(struct work_struct *work)
+#else
static void status_change_work(struct work_struct *work)
+#endif
{
struct step_chg_info *chip = container_of(work,
struct step_chg_info, status_change_work.work);
int rc = 0;
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ bool input_present = false;
+#endif
+#if !defined(CONFIG_TCT_PM7250_COMMON)
union power_supply_propval prop = {0, };
+#endif
if (!is_batt_available(chip) || !is_bms_available(chip))
goto exit_work;
handle_battery_insertion(chip);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ input_present = is_input_present(chip);
+ if (!input_present && !chip->last_input_present) {
+ pr_debug("skip for input_present=%d\n",
+ input_present);
+ goto exit_work;
+ }
+ chip->last_input_present = input_present;
+ if (!input_present) {
+ if (chip->fcc_votable) {
+ vote(chip->fcc_votable, VBAT_LMT_VOTER, false, 0);
+ vote(chip->fcc_votable, CHG_CTL_VOTER, false, 0);
+ vote(chip->fcc_votable, JEITA_VOTER, false, 0);
+ vote(chip->fcc_votable, STEP_CHG_VOTER, false, 0);
+ chip->step_index = -EINVAL;
+ chip->jeita_fcc_index = -EINVAL;
+ chip->jeita_fv_index = -EINVAL;
+ }
+ goto exit_work;
+ }
+#endif
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#if defined(CONFIG_TCT_IEEE1725)
+ rc = handle_ieee_limit(chip);
+ if (rc < 0)
+ pr_err("Couldn't limit ieee rc = %d\n", rc);
+#endif
+#endif
+
/* skip elapsed_us debounce for handling battery temperature */
rc = handle_jeita(chip);
if (rc < 0)
@@ -913,6 +1318,7 @@
if (rc < 0)
pr_err("Couldn't handle step rc = %d\n", rc);
+#if !defined(CONFIG_TCT_PM7250_COMMON)
/* Remove stale votes on USB removal */
if (is_usb_available(chip)) {
prop.intval = 0;
@@ -924,6 +1330,7 @@
false, 0);
}
}
+#endif
exit_work:
__pm_relax(chip->step_chg_ws);
@@ -938,10 +1345,25 @@
if (ev != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (delayed_work_pending(&chip->status_change_work)) {
+ pr_debug("step_chg_status_change_work pending now, skip\n");
+ return NOTIFY_OK;
+ }
+#endif
+
if ((strcmp(psy->desc->name, "battery") == 0)
|| (strcmp(psy->desc->name, "usb") == 0)) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (chip->config_is_read) {
+ __pm_stay_awake(chip->step_chg_ws);
+ queue_delayed_work(private_chg_wq,
+ &chip->status_change_work, 0);
+ }
+#else
__pm_stay_awake(chip->step_chg_ws);
schedule_delayed_work(&chip->status_change_work, 0);
+#endif
}
if ((strcmp(psy->desc->name, "bms") == 0)) {
@@ -995,6 +1417,10 @@
chip->jeita_fcc_index = -EINVAL;
chip->jeita_fv_index = -EINVAL;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chip->max_fv_uv = -EINVAL;
+#endif
+
chip->step_chg_config = devm_kzalloc(dev,
sizeof(struct step_chg_cfg), GFP_KERNEL);
if (!chip->step_chg_config)
@@ -1014,14 +1440,29 @@
chip->jeita_fcc_config->param.psy_prop = POWER_SUPPLY_PROP_TEMP;
chip->jeita_fcc_config->param.prop_name = "BATT_TEMP";
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chip->jeita_fcc_config->param.rise_hys = 10;
+ chip->jeita_fcc_config->param.fall_hys = 30;
+#else
chip->jeita_fcc_config->param.rise_hys = 10;
chip->jeita_fcc_config->param.fall_hys = 10;
+#endif
+
chip->jeita_fv_config->param.psy_prop = POWER_SUPPLY_PROP_TEMP;
chip->jeita_fv_config->param.prop_name = "BATT_TEMP";
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ chip->jeita_fv_config->param.rise_hys = 10;
+ chip->jeita_fv_config->param.fall_hys = 30;
+#else
chip->jeita_fv_config->param.rise_hys = 10;
chip->jeita_fv_config->param.fall_hys = 10;
+#endif
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ INIT_DELAYED_WORK(&chip->status_change_work, step_chg_status_change_work);
+#else
INIT_DELAYED_WORK(&chip->status_change_work, status_change_work);
+#endif
INIT_DELAYED_WORK(&chip->get_config_work, get_config_work);
rc = step_chg_register_notifier(chip);
diff --git a/drivers/power/supply/qcom/tct-customized-fr.c b/drivers/power/supply/qcom/tct-customized-fr.c
new file mode 100644
index 0000000..1743e7b
--- /dev/null
+++ b/drivers/power/supply/qcom/tct-customized-fr.c
@@ -0,0 +1,376 @@
+#define pr_fmt(fmt) "[SMBLIB5]: " fmt
+
+#include <linux/init.h>
+#include <linux/power_supply.h>
+#include "smb5-lib.h"
+#if defined(CONFIG_DRM)
+#include <linux/msm_drm_notify.h>
+#if defined(CONFIG_DRM_PANEL)
+#include <drm/drm_panel.h>
+#endif
+#elif defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#endif
+#include <linux/platform_device.h>
+#include <linux/iio/consumer.h>
+
+#define smblib_err(chg, fmt, ...) \
+ pr_err_ratelimited("%s: " fmt, \
+ __func__, ##__VA_ARGS__)
+#define smblib_dbg(chg, reason, fmt, ...) \
+ do { \
+ if (*chg->debug_mask & (reason)) \
+ pr_err_ratelimited("%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ else \
+ pr_debug_ratelimited("%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ } while (0)
+
+/************** battery current thermal for screen on or off ******************/
+/* smb5-lib.h qpnp-smb5.c add some patch */
+#if defined(CONFIG_DRM)
+#if defined(CONFIG_DRM_PANEL)
+static int smblib_check_panel_dt(struct smb_charger *chg)
+{
+ int i;
+ int count;
+ struct device_node *node, *np;
+ struct drm_panel *panel;
+
+ np = of_find_compatible_node(NULL, NULL, "qcom,msm-notifier");
+ if (!np) {
+ smblib_err(chg, "failed to find qcom,msm-notifier node\n");
+ return -ENODEV;
+ }
+ count = of_count_phandle_with_args(np, "panel", NULL);
+ if (count <= 0)
+ return 0;
+
+ for (i = 0; i < count; i++) {
+ node = of_parse_phandle(np, "panel", i);
+ panel = of_drm_find_panel(node);
+ of_node_put(node);
+ if (!IS_ERR(panel)) {
+ chg->active_panel = panel;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+#endif
+static int smblib_drm_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct msm_drm_notifier *evdata = data;
+ int *blank = NULL;
+ union power_supply_propval pval;
+ struct smb_charger *chg = container_of(self, struct smb_charger, fb_nb);
+
+ if (!evdata) {
+ smblib_err(chg, "evdata is null\n");
+ return 0;
+ }
+
+ if (event != MSM_DRM_EVENT_BLANK) {
+ smblib_dbg(chg, PR_MISC, "DRM event(%lu) do not need process\n", event);
+ return 0;
+ }
+
+ if (evdata->data && event == MSM_DRM_EVENT_BLANK && chg) {
+ blank = evdata->data;
+ pval.intval = chg->system_temp_level;
+ switch (*blank) {
+ case MSM_DRM_BLANK_UNBLANK:
+ chg->is_screen_on = true;
+ smblib_set_prop_system_temp_level(chg, &pval);
+ break;
+ case MSM_DRM_BLANK_POWERDOWN:
+ chg->is_screen_on = false;
+ smblib_set_prop_system_temp_level(chg, &pval);
+ break;
+ default:
+ smblib_dbg(chg, PR_MISC, "DRM blank(%d) do not need process\n", *blank);
+ break;
+ }
+ }
+
+ return 0;
+
+}
+
+#elif defined(CONFIG_FB)
+static int smblib_fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank = NULL;
+ union power_supply_propval pval;
+ struct smb_charger *chg = container_of(self, struct smb_charger, fb_nb);
+
+ if (!evdata) {
+ smblib_err(chg, "evdata is null\n");
+ return 0;
+ }
+
+ if (event != FB_EVENT_BLANK) {
+ smblib_dbg(chg, PR_MISC, "FB event(%lu) do not need process\n", event);
+ return 0;
+ }
+
+ if (evdata->data && event == FB_EVENT_BLANK && chg) {
+ blank = evdata->data;
+ pval.intval = chg->system_temp_level;
+ switch (*blank) {
+ case FB_BLANK_UNBLANK:
+ chg->is_screen_on = true;
+ smblib_set_prop_system_temp_level(chg, &pval);
+ break;
+ case FB_BLANK_POWERDOWN:
+ chg->is_screen_on = false;
+ smblib_set_prop_system_temp_level(chg, &pval);
+ break;
+ default:
+ smblib_dbg(chg, PR_MISC, "FB blank(%d) do not need process\n", *blank);
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static int __init tct_thermal_init(void)
+{
+ struct power_supply *batt_psy = NULL;
+ struct smb_charger *chg = NULL;
+ int rc = 0;
+ batt_psy = power_supply_get_by_name("battery");
+ if (!batt_psy)
+ return -ENODEV;
+
+ chg = power_supply_get_drvdata(batt_psy);
+ if (chg) {
+ chg->is_screen_on = true;
+#if defined(CONFIG_DRM)
+ chg->fb_nb.notifier_call = smblib_drm_notifier_callback;
+#if defined(CONFIG_DRM_PANEL)
+ smblib_check_panel_dt(chg);
+ if (chg->active_panel) {
+ smblib_err(chg, "find active_panel\n");
+ rc = drm_panel_notifier_register(chg->active_panel, &chg->fb_nb);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't register DRM_PANEL notifier rc = %d\n", rc);
+ goto err_notifier_register;
+ }
+ } else {
+ smblib_err(chg, "Couldn't find active_panel\n");
+ goto err_notifier_register;
+ }
+#else
+ rc = msm_drm_register_client(&chg->fb_nb);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't register DRM notifier rc = %d\n", rc);
+ goto err_notifier_register;
+ }
+#endif
+#elif defined(CONFIG_FB)
+ chg->fb_nb.notifier_call = smblib_fb_notifier_callback;
+ rc = fb_register_client(&chg->fb_nb);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't register FB notifier rc = %d\n", rc);
+ goto err_notifier_register;
+ }
+#endif
+ } else {
+ pr_err("[%s]chg is null\n", __func__);
+ return -ENODATA;
+ }
+
+ return 0;
+err_notifier_register:
+ chg->is_screen_on = false;
+ return rc;
+}
+late_initcall(tct_thermal_init);
+
+/************ print charger and battery log for hw test every 10s *************/
+static int g_log_en = 0;
+static unsigned int g_alarm_time = 10;
+static struct delayed_work print_tct_charge_worker;
+static struct alarm fg_log_thread_alarm;
+static struct smb_charger *g_qcom_chg;
+
+static const char * const power_supply_status_text[] = {
+ "Unknown", "Charging", "Discharging", "Not charging", "Full"
+};
+
+static const char * const power_supply_charge_type_text[] = {
+ "Unknown", "N/A", "Trickle", "Fast", "Taper"
+};
+
+static const char * const power_supply_health_text[] = {
+ "Unknown", "Good", "Overheat", "Dead", "Over voltage",
+ "Unspecified failure", "Cold", "Watchdog timer expire",
+ "Safety timer expire",
+ "Warm", "Cool", "Hot"
+};
+
+void print_log_for_fg(void)
+{
+ union power_supply_propval Vbat = {0,}, Ibat = {0,}, batt_temp = {0,}, soc = {0,};
+ union power_supply_propval Vbus = {0,}, status = {0,}, health = {0,}, Vph = {0,}, thermal_icl = {0,};
+ union power_supply_propval charging_type = {0,}, Ibus = {0,}, Isns = {0,};
+ union power_supply_propval cp_temp = {0,};
+ int v_int_ext = 0, i_int_ext = 0;
+
+ if (g_qcom_chg->batt_psy) {
+ power_supply_get_property(g_qcom_chg->batt_psy, POWER_SUPPLY_PROP_STATUS, &status);
+ power_supply_get_property(g_qcom_chg->batt_psy, POWER_SUPPLY_PROP_HEALTH, &health);
+ power_supply_get_property(g_qcom_chg->batt_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &Vbat);
+ power_supply_get_property(g_qcom_chg->batt_psy, POWER_SUPPLY_PROP_CAPACITY, &soc);
+ power_supply_get_property(g_qcom_chg->batt_psy, POWER_SUPPLY_PROP_CURRENT_NOW, &Ibat);
+ power_supply_get_property(g_qcom_chg->batt_psy, POWER_SUPPLY_PROP_TEMP, &batt_temp);
+ power_supply_get_property(g_qcom_chg->batt_psy, POWER_SUPPLY_PROP_CHARGE_TYPE, &charging_type);
+ }
+
+ if (g_qcom_chg->usb_psy) {
+ power_supply_get_property(g_qcom_chg->usb_psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &Vbus);
+ power_supply_get_property(g_qcom_chg->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_NOW, &Ibus);
+ power_supply_get_property(g_qcom_chg->usb_psy, POWER_SUPPLY_PROP_VOLTAGE_VPH, &Vph);
+ power_supply_get_property(g_qcom_chg->usb_psy, POWER_SUPPLY_PROP_THERM_ICL_LIMIT, &thermal_icl);
+ }
+
+ if (g_qcom_chg->cp_psy) {
+ power_supply_get_property(g_qcom_chg->cp_psy, POWER_SUPPLY_PROP_CP_ISNS, &Isns);
+ power_supply_get_property(g_qcom_chg->cp_psy, POWER_SUPPLY_PROP_CP_DIE_TEMP, &cp_temp);
+ }
+
+ if (g_qcom_chg->iio.v_i_int_ext_chan) {
+ iio_read_channel_processed_two(g_qcom_chg->iio.v_i_int_ext_chan, &v_int_ext, &i_int_ext);
+ }
+
+ printk(KERN_ERR "%s: status:%s,health:%s,voltage:%dmV,capacity:%d,current:%dmA,temperature:%d,chgvoltage:%dmV,charging_type:%s,Ibus:%d,Thermal_icl:%d,VPH:%d,Isns:%d,cp_temp:%d,die_temp:%d,connector_temp:%d,skin_temp=%d,I_pmic=%d,I_smb=%d\n",
+ __func__, power_supply_status_text[status.intval],
+ power_supply_health_text[health.intval],
+ Vbat.intval/1000, soc.intval, Ibat.intval/1000, batt_temp.intval,
+ Vbus.intval/1000, power_supply_charge_type_text[charging_type.intval],
+ Ibus.intval/1000, thermal_icl.intval/1000, Vph.intval/1000, Isns.intval/1000,
+ cp_temp.intval, g_qcom_chg->die_temp, g_qcom_chg->connector_temp, g_qcom_chg->skin_temp,
+ -i_int_ext/1000, Ibat.intval/1000 + i_int_ext/1000);
+}
+
+static void print_tct_charge_work(struct work_struct *work)
+{
+ print_log_for_fg();
+}
+
+static ssize_t enable_show(struct device *dev, struct device_attribute
+ *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", g_log_en);
+}
+
+static ssize_t enable_store(struct device *dev, struct device_attribute
+ *attr, const char *buf, size_t count)
+{
+ int val;
+ if (kstrtos32(buf, 0, &val))
+ return -EINVAL;
+
+ g_log_en = val;
+ if (g_log_en)
+ alarm_start_relative(&fg_log_thread_alarm,
+ ns_to_ktime((unsigned long long)(g_alarm_time) * NSEC_PER_SEC));
+ else
+ alarm_cancel(&fg_log_thread_alarm);
+
+ return count;
+}
+static DEVICE_ATTR_RW(enable);
+
+static ssize_t alarm_time_show(struct device *dev, struct device_attribute
+ *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", g_alarm_time);
+}
+
+static ssize_t alarm_time_store(struct device *dev, struct device_attribute
+ *attr, const char *buf, size_t count)
+{
+ int val;
+ if (kstrtos32(buf, 0, &val))
+ return -EINVAL;
+
+ g_alarm_time = val;
+
+ return count;
+}
+static DEVICE_ATTR_RW(alarm_time);
+
+static struct attribute *log_attrs[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_alarm_time.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(log);
+
+static enum alarmtimer_restart fg_log_thread_func(struct alarm *alarm, ktime_t now)
+{
+ queue_delayed_work(private_chg_wq, &print_tct_charge_worker, 0);
+ alarm_forward_now(&fg_log_thread_alarm,
+ ns_to_ktime((unsigned long long)(g_alarm_time) * NSEC_PER_SEC));
+ return ALARMTIMER_RESTART;
+}
+
+static void fg_log_thread_init(void)
+{
+ alarm_init(&fg_log_thread_alarm, ALARM_REALTIME, fg_log_thread_func);
+}
+
+static int __init tct_charger_battery_log_init(void)
+{
+ int rc = 0;
+ struct platform_device *log_pdev = NULL;
+ struct power_supply *batt_psy = NULL;
+ struct smb_charger *chg = NULL;
+ batt_psy = power_supply_get_by_name("battery");
+ if (!batt_psy)
+ return -ENODEV;
+ chg = power_supply_get_drvdata(batt_psy);
+ if (!chg) {
+ pr_err("[%s]chg is null\n", __func__);
+ return -ENODATA;
+ }
+ g_qcom_chg = chg;
+
+ log_pdev = platform_device_register_data(NULL, "tct_charge_log",
+ PLATFORM_DEVID_NONE, chg, sizeof(*chg));
+ if (IS_ERR(log_pdev)) {
+ pr_err("Failed to register tct_charge_log platform device\n");
+ rc = PTR_ERR(log_pdev);
+ goto err_pdev_register;
+ }
+
+ rc = sysfs_create_groups(&log_pdev->dev.kobj, log_groups);
+ if (rc < 0) {
+ pr_err("Couldn't create sysfs files rc=%d\n", rc);
+ goto err_group;
+ }
+
+ fg_log_thread_init();
+
+ INIT_DELAYED_WORK(&print_tct_charge_worker, print_tct_charge_work);
+ if (g_log_en)
+ alarm_start_relative(&fg_log_thread_alarm,
+ ns_to_ktime((unsigned long long)(g_alarm_time) * NSEC_PER_SEC));
+
+ return 0;
+err_group:
+ platform_device_unregister(log_pdev);
+err_pdev_register:
+ return rc;
+}
+late_initcall(tct_charger_battery_log_init);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 9dfe4b3..691b14a 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -3374,15 +3374,13 @@
mdwc->vbus_active = event;
}
- /*
- * Drive a pulse on DP to ensure proper CDP detection
- * and only when the vbus connect event is a valid one.
- */
+#if !defined(CONFIG_TCT_PM7250_COMMON)
if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_CDP &&
- mdwc->vbus_active && !mdwc->check_eud_state) {
+ mdwc->vbus_active) {
dev_dbg(mdwc->dev, "Connected to CDP, pull DP up\n");
usb_phy_drive_dp_pulse(mdwc->hs_phy, DP_PULSE_WIDTH_MSEC);
}
+#endif
if (dwc3_is_otg_or_drd(dwc) && !mdwc->in_restart)
queue_work(mdwc->dwc3_wq, &mdwc->resume_work);
@@ -3695,6 +3693,23 @@
int ret = 0, size = 0, i;
u32 val;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (dev && node && of_property_read_bool(node, "extcon")) {
+ struct extcon_dev *edev=NULL;
+ edev = extcon_get_edev_by_phandle(dev, 0);
+ if (IS_ERR(edev)) {
+ if (PTR_ERR(edev) == -EPROBE_DEFER) {
+ pr_err("Could not get extcon, deferring dwc3-msm probe\n");
+ return -EPROBE_DEFER;
+ } else {
+ pr_err("Could not get extcon(%ld), stop dwc3-msm probe\n",
+ PTR_ERR(edev));
+ return PTR_ERR(edev);
+ }
+ }
+ }
+#endif
+
mdwc = devm_kzalloc(&pdev->dev, sizeof(*mdwc), GFP_KERNEL);
if (!mdwc)
return -ENOMEM;
@@ -4280,8 +4295,11 @@
}
if (on) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ dev_err(mdwc->dev, "%s: turn on host\n", __func__);
+#else
dev_dbg(mdwc->dev, "%s: turn on host\n", __func__);
-
+#endif
mdwc->hs_phy->flags |= PHY_HOST_MODE;
pm_runtime_get_sync(mdwc->dev);
dbg_event(0xFF, "StrtHost gync",
@@ -4364,7 +4382,11 @@
schedule_delayed_work(&mdwc->perf_vote_work,
msecs_to_jiffies(1000 * PM_QOS_SAMPLE_SEC));
} else {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ dev_err(mdwc->dev, "%s: turn off host\n", __func__);
+#else
dev_dbg(mdwc->dev, "%s: turn off host\n", __func__);
+#endif
usb_unregister_atomic_notify(&mdwc->usbdev_nb);
if (!IS_ERR_OR_NULL(mdwc->vbus_reg))
@@ -4440,8 +4462,13 @@
atomic_read(&mdwc->dev->power.usage_count));
if (on) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ dev_err(mdwc->dev, "%s: turn on gadget %s\n",
+ __func__, dwc->gadget.name);
+#else
dev_dbg(mdwc->dev, "%s: turn on gadget %s\n",
__func__, dwc->gadget.name);
+#endif
dwc3_override_vbus_status(mdwc, true);
usb_phy_notify_connect(mdwc->hs_phy, USB_SPEED_HIGH);
@@ -4483,8 +4510,13 @@
schedule_delayed_work(&mdwc->perf_vote_work,
msecs_to_jiffies(1000 * PM_QOS_SAMPLE_SEC));
} else {
+ #if defined(CONFIG_TCT_PM7250_COMMON)
+ dev_err(mdwc->dev, "%s: turn off gadget %s\n",
+ __func__, dwc->gadget.name);
+ #else
dev_dbg(mdwc->dev, "%s: turn off gadget %s\n",
__func__, dwc->gadget.name);
+ #endif
cancel_delayed_work_sync(&mdwc->perf_vote_work);
msm_dwc3_perf_vote_update(mdwc, false);
pm_qos_remove_request(&mdwc->pm_qos_req_dma);
diff --git a/drivers/usb/pd/Kconfig b/drivers/usb/pd/Kconfig
index 19b5228..6c15e0b 100644
--- a/drivers/usb/pd/Kconfig
+++ b/drivers/usb/pd/Kconfig
@@ -28,4 +28,15 @@
The is used to handle the PHY layer communication of the
Power Delivery stack.
+# Jin.wang added here to enable different usbpd logs level
+config USB_PD_LOG_LVL
+ int "USBPD Log level(0,3)"
+ range 0 3
+ default 1
+ help
+ enable different log level for usbpd debug. 0 for no logs,
+ 1 for error logs only, 2 for debug logs only(no error log),
+ 3 for all logs.
+# Jin.wang added done.
+
endmenu
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 6dca69d..3d423a8 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -3,6 +3,10 @@
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define pr_fmt(fmt) "[PE]:" fmt
+#endif
+
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
@@ -193,6 +197,36 @@
};
static void *usbpd_ipc_log;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+enum {
+ LOG_LEVEL_ERR = BIT(0),
+ LOG_LEVEL_DEBUG = BIT(1),
+ LOG_LEVEL_ALL = 0xFF,
+};
+
+static int pdlog = CONFIG_USB_PD_LOG_LVL;
+module_param(pdlog, int, S_IRUGO|S_IWUSR);
+
+#define usbpd_err(dev, fmt, ...) \
+ do { \
+ if (pdlog & LOG_LEVEL_ERR) { \
+ ipc_log_string(usbpd_ipc_log, "%s(): " fmt, __func__, \
+ ##__VA_ARGS__); \
+ pr_err_ratelimited("%s: " fmt, __func__, ##__VA_ARGS__); \
+ } \
+ } while (0)
+
+#define usbpd_dbg(dev, fmt, ...) \
+ do { \
+ if (pdlog & LOG_LEVEL_DEBUG) \
+ ipc_log_string(usbpd_ipc_log, "%s(): " fmt, __func__, \
+ ##__VA_ARGS__); \
+ pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define usbpd_info usbpd_err
+#define usbpd_warn usbpd_dbg
+#else
#define usbpd_dbg(dev, fmt, ...) do { \
ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
##__VA_ARGS__); \
@@ -216,8 +250,13 @@
##__VA_ARGS__); \
dev_err(dev, fmt, ##__VA_ARGS__); \
} while (0)
+#endif
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define NUM_LOG_PAGES (30)
+#else
#define NUM_LOG_PAGES 10
+#endif
/* Timeouts (in ms) */
#define ERROR_RECOVERY_TIME 25
@@ -351,9 +390,18 @@
#define STOP_USB_HOST 0
#define START_USB_HOST 1
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define PD_MIN_SINK_CURRENT 500
+#else
#define PD_MIN_SINK_CURRENT 900
+#endif
+#if defined(CONFIG_TCT_PM7250_COMMON)
+static const u32 default_src_caps[] = { 0x26019032 }; /* VSafe5V @ 0.5A */
+#else
static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */
+#endif
+
static const u32 default_snk_caps[] = { 0x2601912C }; /* VSafe5V @ 3A */
struct vdm_tx {
@@ -541,6 +589,10 @@
static inline void stop_usb_host(struct usbpd *pd)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ usbpd_info(&pd->dev, "stop usb host \n");
+#endif
+
extcon_set_state_sync(pd->extcon, EXTCON_USB_HOST, 0);
}
@@ -550,11 +602,19 @@
union extcon_property_value val;
int ret = 0;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ usbpd_info(&pd->dev, "start usb host with ss:%d, cc=%d\n", ss, cc);
+#endif
+
val.intval = (cc == ORIENTATION_CC2);
extcon_set_property(pd->extcon, EXTCON_USB_HOST,
EXTCON_PROP_USB_TYPEC_POLARITY, val);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val.intval = 0;
+#else
val.intval = ss;
+#endif
extcon_set_property(pd->extcon, EXTCON_USB_HOST,
EXTCON_PROP_USB_SS, val);
@@ -570,6 +630,10 @@
static inline void stop_usb_peripheral(struct usbpd *pd)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ usbpd_info(&pd->dev, "stop usb peripheral \n");
+#endif
+
extcon_set_state_sync(pd->extcon, EXTCON_USB, 0);
}
@@ -578,14 +642,26 @@
enum plug_orientation cc = usbpd_get_plug_orientation(pd);
union extcon_property_value val;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ usbpd_info(&pd->dev, "start usb peripheral with cc=%d\n", cc);
+#endif
+
val.intval = (cc == ORIENTATION_CC2);
extcon_set_property(pd->extcon, EXTCON_USB,
EXTCON_PROP_USB_TYPEC_POLARITY, val);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val.intval = 0;
+#else
val.intval = 1;
+#endif
extcon_set_property(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_SS, val);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ val.intval = 0;
+#else
val.intval = pd->typec_mode > POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ? 1 : 0;
+#endif
extcon_set_property(pd->extcon, EXTCON_USB,
EXTCON_PROP_USB_TYPEC_MED_HIGH_CURRENT, val);
@@ -2022,15 +2098,30 @@
if (!pd->vbus) {
pd->vbus = devm_regulator_get(pd->dev.parent, "vbus");
if (IS_ERR(pd->vbus)) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ pd->vbus = NULL;
+#endif
usbpd_err(&pd->dev, "Unable to get vbus\n");
return -EAGAIN;
}
}
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (!pd->vbus_enabled) {
+ usbpd_err(&pd->dev, "[Enable]:otg_vbus\n");
+ ret = regulator_enable(pd->vbus);
+ if (ret)
+ usbpd_err(&pd->dev, "Unable to enable vbus (%d)\n", ret);
+
+ pd->vbus_enabled = true;
+ }
+#else
ret = regulator_enable(pd->vbus);
if (ret)
usbpd_err(&pd->dev, "Unable to enable vbus (%d)\n", ret);
else
pd->vbus_enabled = true;
+#endif
count = 10;
/*
@@ -3405,12 +3496,23 @@
/* Enters new state and executes actions on entry */
static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
{
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ usbpd_dbg(&pd->dev, "cs: %d->%d\n",
+ pd->current_state, next_state);
+ usbpd_dbg(&pd->dev, "pr:%d, dr:%d, tm:%d, ips:%d, hrr:%d\n",
+ pd->current_pr, pd->current_dr,
+ pd->typec_mode, pd->in_pr_swap,
+ pd->hard_reset_recvd);
+#endif
+
if (pd->hard_reset_recvd) /* let usbpd_sm handle it */
return;
+#if !defined(CONFIG_TCT_PM7250_COMMON)
usbpd_dbg(&pd->dev, "%s -> %s\n",
usbpd_state_strings[pd->current_state],
usbpd_state_strings[next_state]);
+#endif
pd->current_state = next_state;
@@ -3515,15 +3617,23 @@
POWER_SUPPLY_PROP_PD_ACTIVE, &val);
if (pd->vbus_enabled) {
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ usbpd_err(&pd->dev, "[Disable]:otg_vbus\n");
+#endif
regulator_disable(pd->vbus);
pd->vbus_enabled = false;
}
reset_vdm_state(pd);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ stop_usb_host(pd);
+ stop_usb_peripheral(pd);
+#else
if (pd->current_dr == DR_UFP)
stop_usb_peripheral(pd);
else if (pd->current_dr == DR_DFP)
stop_usb_host(pd);
+#endif
pd->current_dr = DR_NONE;
@@ -3637,6 +3747,12 @@
}
spin_unlock_irqrestore(&pd->rx_lock, flags);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if(rx_msg)
+ usbpd_dbg(&pd->dev, "rx_msg={%04x,%04x}\n",
+ rx_msg->hdr, rx_msg->data_len);
+#endif
+
/* Disconnect? */
if (pd->current_pr == PR_NONE) {
if (pd->current_state == PE_UNKNOWN &&
@@ -3754,8 +3870,12 @@
pd->current_pr = PR_SINK;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ eval.intval = 0;
+#else
eval.intval = typec_mode > POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ?
1 : 0;
+#endif
extcon_set_property(pd->extcon, EXTCON_USB,
EXTCON_PROP_USB_TYPEC_MED_HIGH_CURRENT, eval);
break;
@@ -3774,8 +3894,17 @@
break;
case POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY:
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ usbpd_info(&pd->dev, "Type-C Sink Debug Accessory connected\n");
+#else
usbpd_info(&pd->dev, "Type-C Debug Accessory connected\n");
+#endif
break;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ case POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY:
+ usbpd_info(&pd->dev, "Type-C Source Debug Accessory connected\n");
+ break;
+#endif
case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER:
usbpd_info(&pd->dev, "Type-C Analog Audio Adapter connected\n");
break;
@@ -3826,9 +3955,14 @@
return ret;
}
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (val.intval == POWER_SUPPLY_TYPE_USB ||
+ val.intval == POWER_SUPPLY_TYPE_USB_CDP) {
+#else
if (val.intval == POWER_SUPPLY_TYPE_USB ||
val.intval == POWER_SUPPLY_TYPE_USB_CDP ||
val.intval == POWER_SUPPLY_TYPE_USB_FLOAT) {
+#endif
usbpd_dbg(&pd->dev, "typec mode:%d type:%d\n",
typec_mode, val.intval);
pd->typec_mode = typec_mode;
@@ -3927,6 +4061,13 @@
bool do_swap = false;
int ret;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (1) {
+ pr_err("Not support dr set\n");
+ return -ENOTSUPP;
+ }
+#endif
+
usbpd_dbg(&pd->dev, "Setting data role to %d\n", role);
if (role == TYPEC_HOST) {
@@ -3964,6 +4105,13 @@
bool do_swap = false;
int ret;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (1) {
+ pr_err("Not support pr set\n");
+ return -ENOTSUPP;
+ }
+#endif
+
usbpd_dbg(&pd->dev, "Setting power role to %d\n", role);
if (role == TYPEC_SOURCE) {
@@ -4001,6 +4149,13 @@
union power_supply_propval value;
int wait_count = 5;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (1) {
+ pr_err("Not support mode set\n");
+ return -ENOTSUPP;
+ }
+#endif
+
usbpd_dbg(&pd->dev, "Setting mode to %d\n", type);
if (type == TYPEC_PORT_DRP)
@@ -4114,7 +4269,11 @@
struct usbpd *pd = dev_get_drvdata(dev);
const char *pr = "none";
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY)
+#else
if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT)
+#endif
pr = "sink";
else if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SINK)
pr = "source";
@@ -4144,7 +4303,11 @@
struct usbpd *pd = dev_get_drvdata(dev);
const char *dr = "none";
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY)
+#else
if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT)
+#endif
dr = "ufp";
else if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SINK)
dr = "dfp";
diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c
index fd79892..0ffc8d9 100644
--- a/drivers/usb/pd/qpnp-pdphy.c
+++ b/drivers/usb/pd/qpnp-pdphy.c
@@ -3,6 +3,10 @@
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define pr_fmt(fmt) "[PDPHY]: %s: " fmt, __func__
+#endif
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -20,6 +24,11 @@
#include <linux/wait.h>
#include "usbpd.h"
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#include <linux/power_supply.h>
+#endif
+
+
#define USB_PDPHY_MAX_DATA_OBJ_LEN 28
#define USB_PDPHY_MSG_HDR_LEN 2
@@ -790,6 +799,13 @@
unsigned int base;
struct usb_pdphy *pdphy;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ if (!power_supply_get_by_name("usb")) {
+ pr_err("Could not get USB power_supply, deferring pdphy probe\n");
+ return -EPROBE_DEFER;
+ }
+#endif
+
pdphy = devm_kzalloc(&pdev->dev, sizeof(*pdphy), GFP_KERNEL);
if (!pdphy)
return -ENOMEM;
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 47d49c9..cbaef5a 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -3,6 +3,9 @@
* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define pr_fmt(fmt) "[USB2_PHY]: %s: " fmt, __func__
+#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
diff --git a/drivers/usb/phy/phy-msm-ssusb-qmp.c b/drivers/usb/phy/phy-msm-ssusb-qmp.c
index 33a4718..e387f2d 100644
--- a/drivers/usb/phy/phy-msm-ssusb-qmp.c
+++ b/drivers/usb/phy/phy-msm-ssusb-qmp.c
@@ -3,6 +3,10 @@
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
*/
+#if defined(CONFIG_TCT_PM7250_COMMON)
+#define pr_fmt(fmt) "[USB3_PHY]: %s: " fmt, __func__
+#endif
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/err.h>
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 72fe67b..bc29616 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -361,6 +361,9 @@
POWER_SUPPLY_PROP_CP_TOGGLE_SWITCHER,
POWER_SUPPLY_PROP_CP_IRQ_STATUS,
POWER_SUPPLY_PROP_CP_ILIM,
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ POWER_SUPPLY_PROP_TCL_FIXTEMP,
+#endif
POWER_SUPPLY_PROP_IRQ_STATUS,
POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE,
POWER_SUPPLY_PROP_CC_TOGGLE_ENABLE,
@@ -432,6 +435,9 @@
POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY, /* Ra only */
/* Acting as sink */
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ POWER_SUPPLY_TYPEC_SOURCE_DEBUG_ACCESSORY,/* Rd/Rd */
+#endif
POWER_SUPPLY_TYPEC_SOURCE_DEFAULT, /* Rp default */
POWER_SUPPLY_TYPEC_SOURCE_MEDIUM, /* Rp 1.5A */
POWER_SUPPLY_TYPEC_SOURCE_HIGH, /* Rp 3A */
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 342f374..94ff046 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -396,6 +396,10 @@
extern struct workqueue_struct *system_power_efficient_wq;
extern struct workqueue_struct *system_freezable_power_efficient_wq;
+#if defined(CONFIG_TCT_PM7250_COMMON)
+extern struct workqueue_struct *private_chg_wq;
+#endif
+
extern struct workqueue_struct *
__alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active,
struct lock_class_key *key, const char *lock_name, ...) __printf(1, 6);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index f3ca7e0..75158d3 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -352,6 +352,10 @@
struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly;
EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq);
+#if defined(CONFIG_TCT_PM7250_COMMON)
+struct workqueue_struct *private_chg_wq __read_mostly;
+EXPORT_SYMBOL_GPL(private_chg_wq);
+#endif
static int worker_thread(void *__worker);
static void workqueue_sysfs_unregister(struct workqueue_struct *wq);
@@ -5817,6 +5821,13 @@
system_freezable_power_efficient_wq = alloc_workqueue("events_freezable_power_efficient",
WQ_FREEZABLE | WQ_POWER_EFFICIENT,
0);
+
+#if defined(CONFIG_TCT_PM7250_COMMON)
+ private_chg_wq = alloc_workqueue("private_chg_wq",
+ WQ_FREEZABLE, 0);
+ BUG_ON(!private_chg_wq);
+#endif
+
BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq ||
!system_unbound_wq || !system_freezable_wq ||
!system_power_efficient_wq ||