From 453ca3dcbdd04e0bd881291bb3819a6fc05fe547 Mon Sep 17 00:00:00 2001 From: wutao Date: Sat, 18 Dec 2021 20:34:43 +0800 Subject: [PATCH] QC3P:detection and iio sys support Add QC3P detection and iio sys support. Change-Id: I7459889d1c7fc35b0913ba908b3ef9cf00c5729e Signed-off-by: wutao Reviewed-on: https://gerrit.mot.com/2148672 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- drivers/power/bq2589x_chg_mmi/Android.mk | 3 + drivers/power/bq2589x_chg_mmi/Kbuild | 4 + .../power/bq2589x_chg_mmi/bq2589x_charger.c | 194 +++++++++++++++++- drivers/power/bq2589x_chg_mmi/bq2589x_reg.h | 31 +++ 4 files changed, 230 insertions(+), 2 deletions(-) diff --git a/drivers/power/bq2589x_chg_mmi/Android.mk b/drivers/power/bq2589x_chg_mmi/Android.mk index 74064053300c..f1741a0e7660 100644 --- a/drivers/power/bq2589x_chg_mmi/Android.mk +++ b/drivers/power/bq2589x_chg_mmi/Android.mk @@ -5,6 +5,9 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := bq2589x_charger.ko +ifeq ($(MMI_QC3P_TURBO_CHARGER),true) + KERNEL_CFLAGS += CONFIG_MMI_QC3P_TURBO_CHARGER=y +endif LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) diff --git a/drivers/power/bq2589x_chg_mmi/Kbuild b/drivers/power/bq2589x_chg_mmi/Kbuild index 13244a6befca..a5aa81a0ed7e 100644 --- a/drivers/power/bq2589x_chg_mmi/Kbuild +++ b/drivers/power/bq2589x_chg_mmi/Kbuild @@ -5,4 +5,8 @@ EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include \ obj-m += bq2589x_charger.o +ifneq ($(filter m y,$(CONFIG_MMI_QC3P_TURBO_CHARGER)),) + EXTRA_CFLAGS += -DCONFIG_MMI_QC3P_TURBO_CHARGER +endif + KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../mmi_discrete_charger/$(GKI_OBJ_MODULE_DIR)/Module.symvers diff --git a/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c b/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c index f355037fa12f..2f104699e882 100644 --- a/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c +++ b/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c @@ -43,7 +43,10 @@ static struct bq2589x *g_bq; static DEFINE_MUTEX(bq2589x_i2c_lock); - +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER +static bool g_qc3p_detected = false; +bool qc3p_update_policy(struct bq2589x *chip); +#endif #define MMI_HVDCP2_VOLTAGE_STANDARD 8000000 #define MMI_HVDCP3_VOLTAGE_STANDARD 7500000 #define MMI_HVDCP_DETECT_ICL_LIMIT 500 @@ -173,6 +176,9 @@ struct bq2589x { u32 input_current_cache; int pulse_cnt; struct bq2589x_iio iio; +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER + struct iio_channel **ext_iio_chans; +#endif }; struct pe_ctrl { @@ -629,6 +635,22 @@ int bq2589x_get_hiz_mode(struct bq2589x *bq, u8 *state) return 0; } +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER +int bq2589x_is_enabled_charging(struct charger_device *chg_dev, bool *en) +{ + u8 val; + int ret; + struct bq2589x *bq = dev_get_drvdata(&chg_dev->dev); + + ret = bq2589x_read_byte(bq, &val, BQ2589X_REG_03); + if (ret) + return ret; + *en = ((val & BQ2589X_CHG_CONFIG_MASK) >> BQ2589X_CHG_CONFIG_SHIFT)? true:false; + + return 0; +} +#endif + int bq2589x_pumpx_enable(struct bq2589x *bq, int enable) { u8 val; @@ -1514,6 +1536,7 @@ static void bq2589x_adjust_absolute_vindpm(struct bq2589x *bq) } +#ifndef CONFIG_MMI_QC3P_TURBO_CHARGER static int mmi_adjust_qc20_hvdcp_5v(struct bq2589x *bq) { int ret; @@ -1599,6 +1622,7 @@ static int mmi_detected_qc20_hvdcp(struct bq2589x *bq, int *charger_type) return ret; } +#endif // Must enter 3.0 mode to call ,otherwise cannot step correctly. static int mmi_qc30_step_up_vbus(struct bq2589x *bq) @@ -1646,6 +1670,7 @@ static int mmi_qc30_step_down_vbus(struct bq2589x *bq) return ret; } +#ifndef CONFIG_MMI_QC3P_TURBO_CHARGER static int mmi_detected_qc30_hvdcp(struct bq2589x *bq, int *charger_type) { int ret = 0; @@ -1694,6 +1719,129 @@ static int mmi_detected_qc30_hvdcp(struct bq2589x *bq, int *charger_type) return ret; } +#endif + +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER +bool is_chan_valid(struct bq2589x *chip, + enum mmi_qc3p_ext_iio_channels chan) +{ + int rc; + + if (IS_ERR(chip->ext_iio_chans[chan])) + return false; + + if (!chip->ext_iio_chans[chan]) { + chip->ext_iio_chans[chan] = iio_channel_get(chip->dev, + mmi_qc3p_ext_iio_chan_name[chan]); + if (IS_ERR(chip->ext_iio_chans[chan])) { + rc = PTR_ERR(chip->ext_iio_chans[chan]); + if (rc == -EPROBE_DEFER) + chip->ext_iio_chans[chan] = NULL; + + dev_info(chip->dev, "Failed to get IIO channel %s, rc=%d\n", + mmi_qc3p_ext_iio_chan_name[chan], rc); + return false; + } + } + + return true; +} + +int mmi_charger_read_iio_chan(struct bq2589x *chip, + enum mmi_qc3p_ext_iio_channels chan, int *val) +{ + int rc; + + if (is_chan_valid(chip, chan)) { + rc = iio_read_channel_processed( + chip->ext_iio_chans[chan], val); + return (rc < 0) ? rc : 0; + } + + return -EINVAL; +} + +int mmi_charger_write_iio_chan(struct bq2589x *chip, + enum mmi_qc3p_ext_iio_channels chan, int val) +{ + if (is_chan_valid(chip, chan)) + return iio_write_channel_raw(chip->ext_iio_chans[chan], + val); + + return -EINVAL; +} + +static int mmi_init_iio_psy(struct bq2589x *chip, + struct device *dev) +{ + chip->ext_iio_chans = devm_kcalloc(chip->dev, + ARRAY_SIZE(mmi_qc3p_ext_iio_chan_name), + sizeof(*chip->ext_iio_chans), + GFP_KERNEL); + if (!chip->ext_iio_chans) + return -ENOMEM; + + return 0; +} + +int qc3p_start_detection(struct bq2589x *chip) +{ + int ret = 0; + ret = mmi_charger_write_iio_chan(chip, SMB5_QC3P_START_DETECT, true); + if(ret ) + dev_err(chip->dev, "Cann't write SMB5_QC3P_START_DETECT IIO\n"); + + dev_info(chip->dev, "write SMB5_QC3P_START_DETECT IIO success\n"); + return 0; +} + +bool qc3p_detection_done(struct bq2589x *chip) +{ + int ret = 0; + int val = 0; + int delay_count =0; + + do { + ret = mmi_charger_read_iio_chan(chip, SMB5_QC3P_DETECTION_READY, &val); + if(ret ) + dev_err(chip->dev, "Cann't read SMB5_QC3P_DETECTION_READY IIO\n"); + + dev_info(chip->dev, "read SMB5_QC3P_DETECTION_READY IIO :%d\n",val); + + msleep(100); + delay_count ++; + }while(val == false && delay_count <= 35); + + dev_info(chip->dev, "read SMB5_QC3P_DETECTION_READY IIO :%d\n",val); + return val; +} + +int qc3p_read_charger_type(struct bq2589x *chip) +{ + int ret = 0; + int val = 0; + + ret = mmi_charger_read_iio_chan(chip, SMB5_USB_REAL_TYPE, &val); + if(ret ) + dev_err(chip->dev, "Cann't read SMB5_USB_REAL_TYPE IIO\n"); + + dev_info(chip->dev, "read SMB5_USB_REAL_TYPE IIO :%d\n",val); + return val; +} + +bool qc3p_update_policy(struct bq2589x *chip ) +{ + int ret = 0; + int val = 0; + + ret = mmi_charger_write_iio_chan(chip, SMB5_QC3P_START_POLICY, val); + if(ret ) + dev_err(chip->dev, "Cann't write SMB5_QC3P_START_POLICY IIO\n"); + + dev_info(chip->dev, "write SMB5_QC3P_START_POLICY IIO :%d\n",val); + return val; +} +#endif static int mmi_hvdcp_detect_kthread(void *param) { @@ -1716,6 +1864,7 @@ static int mmi_hvdcp_detect_kthread(void *param) bq->mmi_is_qc3_authen = true; bq2589x_set_input_current_limit(bq, MMI_HVDCP_DETECT_ICL_LIMIT); +#ifndef CONFIG_MMI_QC3P_TURBO_CHARGER //do qc2.0 detected ret = mmi_detected_qc20_hvdcp(bq, &charger_type); if (ret) { @@ -1731,7 +1880,31 @@ static int mmi_hvdcp_detect_kthread(void *param) if (ret) { dev_err(bq->dev, "Cann't detected qc30 hvdcp\n"); } +#else + qc3p_start_detection(bq); + qc3p_detection_done(bq); + ret = qc3p_read_charger_type(bq); + switch(ret) { + case WT_CHG_TYPE_QC2: + charger_type = POWER_SUPPLY_TYPE_USB_HVDCP; + dev_info(bq->dev, "HDVCP 2.0 detected\n"); + break; + case WT_CHG_TYPE_QC3: + case WT_CHG_TYPE_QC3P_18W: + charger_type = POWER_SUPPLY_TYPE_USB_HVDCP_3; + dev_info(bq->dev, "HDVCP 3.0 or qc3p 18W detected\n"); + break; + case WT_CHG_TYPE_QC3P_27W: + dev_err(bq->dev, "QC3P 27W have been detected !\n"); + qc3p_update_policy(bq); + g_qc3p_detected = true; + break; + default: + dev_info(bq->dev, "No HDVCP detected\n"); + goto out; + } +#endif bq2589x_get_usb_present(bq); if (!bq->state.vbus_gd) goto out; @@ -1795,6 +1968,9 @@ static void bq2589x_adapter_in_func(struct bq2589x *bq) case BQ2589X_VBUS_USB_DCP: dev_info(bq->dev, "%s:DCP adapter plugged in\n", __func__); bq->real_charger_type = POWER_SUPPLY_TYPE_USB_DCP; +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER + if(g_qc3p_detected == false) +#endif mmi_start_hvdcp_detect(bq); schedule_delayed_work(&bq->check_pe_tuneup_work, 0); break; @@ -1847,6 +2023,10 @@ static void bq2589x_adapter_out_func(struct bq2589x *bq) cancel_delayed_work_sync(&bq->monitor_work); +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER + g_qc3p_detected = false; + qc3p_update_policy(bq); +#endif bq->pulse_cnt = 0; bq->typec_apsd_rerun_done = false; bq->chg_dev->noti.apsd_done = false; @@ -2344,7 +2524,9 @@ static struct charger_ops bq2589x_chg_ops = { .is_charge_halted = bq2589x_is_charging_halted, .dump_registers = bq2589x_dump_registers, - +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER + .is_enabled_charging = bq2589x_is_enabled_charging, +#endif }; static int bq2589x_charger_probe(struct i2c_client *client, @@ -2446,6 +2628,14 @@ static int bq2589x_charger_probe(struct i2c_client *client, dev_info(dev, "%s:irq = %d\n", __func__, client->irq); } +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER + ret = mmi_init_iio_psy(bq, dev); + if (ret) { + dev_err(dev, + "mmi iio psy init failed\n"); + } +#endif + pe.enable = false; bq2589x_rerun_apsd_if_required(bq); diff --git a/drivers/power/bq2589x_chg_mmi/bq2589x_reg.h b/drivers/power/bq2589x_chg_mmi/bq2589x_reg.h index 0f7bca2dd0b8..d522a764ec7f 100644 --- a/drivers/power/bq2589x_chg_mmi/bq2589x_reg.h +++ b/drivers/power/bq2589x_chg_mmi/bq2589x_reg.h @@ -354,6 +354,37 @@ #define BQ2589X_DEV_REV_SHIFT 0 +#ifdef CONFIG_MMI_QC3P_TURBO_CHARGER +enum WT_charger_type{ + WT_CHG_TYPE_BEGIN = 0, + WT_CHG_TYPE_FC, + WT_CHG_TYPE_SDP, + WT_CHG_TYPE_CDP, + WT_CHG_TYPE_DCP, + WT_CHG_TYPE_QC2, + WT_CHG_TYPE_QC3, + WT_CHG_TYPE_OCP, + WT_CHG_TYPE_QC3P_18W,//0x8 + WT_CHG_TYPE_QC3P_27W, + WT6670_CHG_TYPE_UNKNOWN, +}; +enum mmi_qc3p_ext_iio_channels { + /*qc3p*/ + SMB5_USB_REAL_TYPE, + SMB5_QC3P_POWER, + SMB5_QC3P_START_DETECT, + SMB5_QC3P_DETECTION_READY, + SMB5_QC3P_START_POLICY, +}; +static const char * const mmi_qc3p_ext_iio_chan_name[] = { + /*qc3p*/ + [SMB5_USB_REAL_TYPE] = "wt6670_usb_real_type", + [SMB5_QC3P_POWER] = "wt6670_usb_qc3p_power", + [SMB5_QC3P_START_DETECT] = "wt6670_start_detection", + [SMB5_QC3P_DETECTION_READY] "wt6670_detection_ready", + [SMB5_QC3P_START_POLICY] "qc3p_start_policy", +}; +#endif #endif