diff --git a/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c b/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c index 15f7ebb43a40..f5574acd3a41 100644 --- a/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c +++ b/drivers/power/bq2589x_chg_mmi/bq2589x_charger.c @@ -179,6 +179,9 @@ struct bq2589x { bool mmi_qc3p_wa; int mmi_qc3p_power; + /*mmi PD*/ + int pd_active; + struct bq2589x_iio iio; #ifdef CONFIG_MMI_QC3P_WT6670_DETECTED struct iio_channel **ext_iio_chans; @@ -1880,7 +1883,7 @@ static int bq2589x_detected_qc3p_hvdcp(struct bq2589x *bq, int *charger_type) bq->mmi_qc3p_power = MMI_POWER_SUPPLY_QC3P_NONE; /*do qc3p rerun*/ dev_err(bq->dev, "qc3p voltage is invalid, rerun qc3p detect\n"); - if (!bq->mmi_qc3p_rerun_done) { + if (!bq->mmi_qc3p_rerun_done && !bq->pd_active) { bq->mmi_qc3p_rerun_done = true; bq->mmi_qc3p_wa = true; dp_val = 0x0<dev, "qc3p power is invalid, rerun qc3p detect\n"); //do rerun qc3p - if (!bq->mmi_qc3p_rerun_done) { + if (!bq->mmi_qc3p_rerun_done && !bq->pd_active) { bq->mmi_qc3p_rerun_done = true; bq->mmi_qc3p_wa = true; dp_val = 0x0<pd_active) goto out; //do qc3.0 detected @@ -2159,7 +2162,7 @@ static int mmi_hvdcp_detect_kthread(void *param) #ifdef CONFIG_MMI_QC3P_TURBO_CHARGER //do qc3p detected - if (charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) { + if (charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 && !bq->pd_active) { ret = bq2589x_detected_qc3p_hvdcp(bq, &charger_type); if (ret) { dev_err(bq->dev, "Cann't detected qc3p hvdcp\n"); @@ -2194,7 +2197,7 @@ static int mmi_hvdcp_detect_kthread(void *param) } #endif bq2589x_get_usb_present(bq); - if (!bq->state.vbus_gd) + if (!bq->state.vbus_gd || bq->pd_active) goto out; bq->real_charger_type = charger_type; @@ -2218,6 +2221,7 @@ static void mmi_start_hvdcp_detect(struct bq2589x *bq) { if (bq->mmi_qc3_support + && !bq->pd_active && bq->real_charger_type == POWER_SUPPLY_TYPE_USB_DCP) { //down(&bq->sem_dpdm); dev_info(bq->dev, "start hvdcp detect\n"); @@ -2611,6 +2615,15 @@ static irqreturn_t bq2589x_charger_interrupt(int irq, void *data) return IRQ_HANDLED; } +static int mmi_config_pd_active(struct charger_device *chg_dev, int val) +{ + struct bq2589x *bq = dev_get_drvdata(&chg_dev->dev); + + bq->pd_active = val; + + return 0; +} + static int mmi_get_qc3p_power(struct charger_device *chg_dev, int *qc3p_power) { struct bq2589x *bq = dev_get_drvdata(&chg_dev->dev); @@ -2877,6 +2890,7 @@ static struct charger_ops bq2589x_chg_ops = { .is_enabled_charging = bq2589x_is_enabled_charging, .enable_termination = bq2589x_enable_termination, .get_qc3p_power = mmi_get_qc3p_power, + .config_pd_active = mmi_config_pd_active, }; static int bq2589x_charger_probe(struct i2c_client *client, diff --git a/drivers/power/mmi_discrete_charger/mmi_discrete_charger_class.c b/drivers/power/mmi_discrete_charger/mmi_discrete_charger_class.c index 43db0af356da..c9fa76d27026 100644 --- a/drivers/power/mmi_discrete_charger/mmi_discrete_charger_class.c +++ b/drivers/power/mmi_discrete_charger/mmi_discrete_charger_class.c @@ -231,6 +231,16 @@ int charger_dev_get_qc3p_power(struct charger_device *chg_dev, int *qc3p_power) } EXPORT_SYMBOL(charger_dev_get_qc3p_power); +int charger_dev_config_pd_active(struct charger_device *chg_dev, int val) +{ + if (chg_dev != NULL && chg_dev->ops != NULL && + chg_dev->ops->config_pd_active) + return chg_dev->ops->config_pd_active(chg_dev, val); + + return -ENOTSUPP; +} +EXPORT_SYMBOL(charger_dev_config_pd_active); + int charger_dev_notify(struct charger_device *chg_dev) { return srcu_notifier_call_chain( diff --git a/drivers/power/mmi_discrete_charger/mmi_discrete_charger_core.c b/drivers/power/mmi_discrete_charger/mmi_discrete_charger_core.c index dcfc1b7d5481..84d469a714d3 100644 --- a/drivers/power/mmi_discrete_charger/mmi_discrete_charger_core.c +++ b/drivers/power/mmi_discrete_charger/mmi_discrete_charger_core.c @@ -2250,6 +2250,8 @@ int mmi_discrete_config_pd_active(struct mmi_discrete_charger *chip, int val) return 0; chip->pd_active = val; + + charger_dev_config_pd_active(chip->master_chg_dev, chip->pd_active); update_sw_icl_max(chip); if (chip->pd_active) { diff --git a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c index 6dcb0f65ebff..077590bfc3b8 100644 --- a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c +++ b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.c @@ -1693,7 +1693,7 @@ static int sgm4154x_detected_qc3p_hvdcp(struct sgm4154x_device *sgm, int *charge sgm->mmi_qc3p_power = MMI_POWER_SUPPLY_QC3P_NONE; /*do qc3p rerun*/ dev_err(sgm->dev, "qc3p voltage is invalid, rerun qc3p detect\n"); - if (!sgm->mmi_qc3p_rerun_done) { + if (!sgm->mmi_qc3p_rerun_done && !sgm->pd_active) { sgm->mmi_qc3p_rerun_done = true; sgm->mmi_qc3p_wa = true; dp_val = 0x0<<3; @@ -1765,7 +1765,7 @@ static int sgm4154x_detected_qc3p_hvdcp(struct sgm4154x_device *sgm, int *charge } else { dev_err(sgm->dev, "qc3p power is invalid, rerun qc3p detect\n"); //do rerun qc3p - if (!sgm->mmi_qc3p_rerun_done) { + if (!sgm->mmi_qc3p_rerun_done && !sgm->pd_active) { sgm->mmi_qc3p_rerun_done = true; sgm->mmi_qc3p_wa = true; dp_val = 0x0<<3; @@ -1999,7 +1999,7 @@ static int mmi_hvdcp_detect_kthread(void *param) goto out; } - if (charger_type != POWER_SUPPLY_TYPE_USB_HVDCP) + if (charger_type != POWER_SUPPLY_TYPE_USB_HVDCP || sgm->pd_active) goto out; //do qc3.0 detected @@ -2011,7 +2011,7 @@ static int mmi_hvdcp_detect_kthread(void *param) #ifdef CONFIG_MMI_QC3P_TURBO_CHARGER //do qc3p detected - if (charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) { + if (charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 && !sgm->pd_active) { ret = sgm4154x_detected_qc3p_hvdcp(sgm, &charger_type); if (ret) { dev_err(sgm->dev, "Cann't detected qc3p hvdcp\n"); @@ -2046,7 +2046,7 @@ static int mmi_hvdcp_detect_kthread(void *param) } #endif sgm4154x_get_usb_present(sgm); - if (!sgm->state.vbus_gd) + if (!sgm->state.vbus_gd || sgm->pd_active) goto out; sgm->real_charger_type = charger_type; @@ -2070,6 +2070,7 @@ static void mmi_start_hvdcp_detect(struct sgm4154x_device *sgm) { if (sgm->mmi_qc3_support + && (!sgm->pd_active) && (sgm->real_charger_type == POWER_SUPPLY_TYPE_USB_DCP #ifdef CONFIG_MMI_SGM41513_CHARGER || sgm->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP @@ -3093,6 +3094,15 @@ static int sgm4154x_get_real_charger_type(struct charger_device *chg_dev, int *c return 0; } +static int sgm4154x_config_pd_active(struct charger_device *chg_dev, int val) +{ + struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); + + sgm->pd_active = val; + + return 0; +} + static int sgm4154x_dump_registers(struct charger_device *chg_dev, struct seq_file *m) { struct sgm4154x_device *sgm = dev_get_drvdata(&chg_dev->dev); @@ -3132,6 +3142,7 @@ static struct charger_ops sgm4154x_chg_ops = { .is_enabled_charging = sgm4154x_is_enabled_charging, .enable_termination = sgm4154x_enable_termination, .get_qc3p_power = sgm4154x_get_qc3p_power, + .config_pd_active = sgm4154x_config_pd_active, }; static int sgm4154x_probe(struct i2c_client *client, diff --git a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h index 5a3c7d89a5ea..5fbb17dec843 100644 --- a/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h +++ b/drivers/power/sgm4154x_chg_mmi/sgm4154x_charger.h @@ -373,6 +373,9 @@ struct sgm4154x_device { bool mmi_qc3p_wa; int mmi_qc3p_power; + /*mmi PD*/ + int pd_active; + struct sgm4154x_iio iio; #ifdef CONFIG_MMI_QC3P_WT6670_DETECTED struct iio_channel **ext_iio_chans; diff --git a/include/linux/mmi_discrete_charger_class.h b/include/linux/mmi_discrete_charger_class.h index 982bc4cc7cb0..7206a17d66a2 100644 --- a/include/linux/mmi_discrete_charger_class.h +++ b/include/linux/mmi_discrete_charger_class.h @@ -48,6 +48,7 @@ struct charger_ops { int (*get_real_charger_type)(struct charger_device *dev, int *charger_type); int (*get_qc3p_power)(struct charger_device *dev, int *qc3p_power); + int (*config_pd_active)(struct charger_device *dev, int val); /* enable/disable charger */ int (*enable_charging)(struct charger_device *dev, bool en); @@ -140,6 +141,8 @@ extern int charger_dev_get_real_charger_type(struct charger_device *chg_dev, int extern int charger_dev_get_qc3p_power(struct charger_device *chg_dev, int *qc3p_power); +extern int charger_dev_config_pd_active(struct charger_device *chg_dev, int val); + extern int register_charger_device_notifier( struct charger_device *charger_dev, struct notifier_block *nb);