mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 00:00:00 -04:00
charge: add qc3p driver
add qc3+ authenticate process and qqc3+ voltage control interface Change-Id: I1e944ba8d6b0d16c19c70f9d5c1385bbf9a28801 Signed-off-by: chailu1 <chailu1@lenovo.com> Reviewed-on: https://gerrit.mot.com/1971082 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Haijian Ma <mahj8@motorola.com> Reviewed-by: Huosheng Liao <liaohs@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
2469090ab0
commit
8583c761b5
7 changed files with 216 additions and 3 deletions
|
|
@ -626,6 +626,8 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node)
|
|||
&chg->chg_param.qc4_max_icl_ua);
|
||||
if (chg->chg_param.qc4_max_icl_ua <= 0)
|
||||
chg->chg_param.qc4_max_icl_ua = MICRO_4PA;
|
||||
chg->mmi_qc3p_support = of_property_read_bool(node,
|
||||
"mmi,qc3p-support");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,6 +269,9 @@ int smb5_iio_get_prop(struct smb_charger *chg, int channel, int *val)
|
|||
case PSY_IIO_CHARGING_ENABLED:
|
||||
*val = !get_effective_result(chg->chg_disable_votable);
|
||||
break;
|
||||
case PSY_IIO_MMI_QC3P_POWER:
|
||||
*val = chg->mmi_qc3p_power;
|
||||
break;
|
||||
default:
|
||||
pr_err("get prop %d is not supported\n", channel);
|
||||
rc = -EINVAL;
|
||||
|
|
@ -471,7 +474,12 @@ int smb5_iio_set_prop(struct smb_charger *chg, int channel, int val)
|
|||
rc = smblib_run_aicl(chg, RERUN_AICL);
|
||||
break;
|
||||
case PSY_IIO_DP_DM:
|
||||
if (!chg->flash_active)
|
||||
if (chg->mmi_qc3p_support) {
|
||||
if ((chg->real_charger_type == QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3P5)
|
||||
||(!chg->flash_active && !chg->mmi_is_qc3p_authen
|
||||
&& chg->real_charger_type == QTI_POWER_SUPPLY_TYPE_USB_HVDCP_3))
|
||||
rc = smblib_dp_dm(chg, val);
|
||||
} else if (!chg->flash_active)
|
||||
rc = smblib_dp_dm(chg, val);
|
||||
break;
|
||||
case PSY_IIO_INPUT_CURRENT_LIMITED:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ enum iio_type {
|
|||
QG,
|
||||
CP,
|
||||
SMB_PARALLEL,
|
||||
MMI_CP,
|
||||
};
|
||||
|
||||
/* For qpnp-smb5.c and smb5-lib.c */
|
||||
|
|
@ -34,6 +35,10 @@ enum qg_chg_iio_channels {
|
|||
SMB5_QG_TIME_TO_FULL_NOW,
|
||||
};
|
||||
|
||||
enum mmi_cp_iio_channels {
|
||||
SC8549_INPUT_VOLTAGE_NOW,
|
||||
};
|
||||
|
||||
enum cp_iio_channels {
|
||||
CP_PARALLEL_OUTPUT_MODE,
|
||||
CP_MASTER_ENABLE,
|
||||
|
|
@ -202,6 +207,7 @@ static const struct smb5_iio_prop_channels smb5_chans_pmic[] = {
|
|||
SMB5_CHAN_ACTIVITY("battery_fcc_stepper_enable", FCC_STEPPER_ENABLE)
|
||||
SMB5_CHAN_INDEX("usb_typec_accessory_mode", TYPEC_ACCESSORY_MODE)
|
||||
SMB5_CHAN_INDEX("charging_enabled", CHARGING_ENABLED)
|
||||
SMB5_CHAN_INDEX("usb_qc3p_power", MMI_QC3P_POWER)
|
||||
};
|
||||
|
||||
struct iio_channel **get_ext_channels(struct device *dev,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
#include "storm-watch.h"
|
||||
#include "smb5-iio.h"
|
||||
#include "battery-profile-loader.h"
|
||||
#include <uapi/linux/sched/types.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
|
||||
#define smblib_err(chg, fmt, ...) \
|
||||
pr_err("%s: %s: " fmt, chg->name, \
|
||||
|
|
@ -885,6 +888,10 @@ int smblib_set_aicl_cont_threshold(struct smb_chg_param *param,
|
|||
/********************
|
||||
* HELPER FUNCTIONS *
|
||||
********************/
|
||||
/* MMI CP channels */
|
||||
static const char * const smblib_mmi_cp_ext_iio_chan[] = {
|
||||
[SC8549_INPUT_VOLTAGE_NOW] = "sc8549_input_voltage_now",
|
||||
};
|
||||
|
||||
/* CP channels */
|
||||
static const char * const smblib_cp_ext_iio_chan[] = {
|
||||
|
|
@ -941,6 +948,11 @@ static int smblib_read_iio_prop(struct smb_charger *chg,
|
|||
return -ENODEV;
|
||||
iio_chan_list = chg->iio_chan_list_smb_parallel[iio_chan];
|
||||
break;
|
||||
case MMI_CP:
|
||||
if (IS_ERR_OR_NULL(chg->iio_chan_list_mmi_cp))
|
||||
return -ENODEV;
|
||||
iio_chan_list = chg->iio_chan_list_mmi_cp[iio_chan];
|
||||
break;
|
||||
default:
|
||||
pr_err_ratelimited("iio_type %d is not supported\n", type);
|
||||
return -EINVAL;
|
||||
|
|
@ -971,6 +983,11 @@ static int smblib_write_iio_prop(struct smb_charger *chg,
|
|||
return -ENODEV;
|
||||
iio_chan_list = chg->iio_chan_list_smb_parallel[iio_chan];
|
||||
break;
|
||||
case MMI_CP:
|
||||
if (IS_ERR_OR_NULL(chg->iio_chan_list_mmi_cp))
|
||||
return -ENODEV;
|
||||
iio_chan_list = chg->iio_chan_list_mmi_cp[iio_chan];
|
||||
break;
|
||||
default:
|
||||
pr_err_ratelimited("iio_type %d is not supported\n", type);
|
||||
return -EINVAL;
|
||||
|
|
@ -979,6 +996,33 @@ static int smblib_write_iio_prop(struct smb_charger *chg,
|
|||
return iio_write_channel_raw(iio_chan_list, val);
|
||||
}
|
||||
|
||||
static bool is_mmi_cp_available(struct smb_charger *chg)
|
||||
{
|
||||
int rc;
|
||||
struct iio_channel **iio_list;
|
||||
|
||||
if (IS_ERR(chg->iio_chan_list_mmi_cp))
|
||||
return false;
|
||||
|
||||
if (!chg->iio_chan_list_mmi_cp) {
|
||||
iio_list = get_ext_channels(chg->dev,
|
||||
smblib_mmi_cp_ext_iio_chan,
|
||||
ARRAY_SIZE(smblib_mmi_cp_ext_iio_chan));
|
||||
if (IS_ERR(iio_list)) {
|
||||
rc = PTR_ERR(iio_list);
|
||||
if (rc != -EPROBE_DEFER) {
|
||||
dev_err(chg->dev, "Failed to get channels, rc=%d\n",
|
||||
rc);
|
||||
chg->iio_chan_list_mmi_cp = ERR_PTR(-EINVAL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
chg->iio_chan_list_mmi_cp = iio_list;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_cp_available(struct smb_charger *chg)
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -1305,6 +1349,7 @@ static void smblib_uusb_removal(struct smb_charger *chg)
|
|||
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true,
|
||||
is_flash_active(chg) ? SDP_CURRENT_UA : SDP_100_MA);
|
||||
vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, SW_QC3P_AUTHEN_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, CHG_TERMINATION_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER, false, 0);
|
||||
|
|
@ -2869,8 +2914,10 @@ int smblib_dp_dm(struct smb_charger *chg, int val)
|
|||
pr_err("Failed to force 12V\n");
|
||||
break;
|
||||
case QTI_POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3P5:
|
||||
chg->qc3p5_detected = true;
|
||||
smblib_update_usb_type(chg);
|
||||
if (!chg->mmi_qc3p_support) {
|
||||
chg->qc3p5_detected = true;
|
||||
smblib_update_usb_type(chg);
|
||||
}
|
||||
break;
|
||||
case QTI_POWER_SUPPLY_DP_DM_ICL_UP:
|
||||
default:
|
||||
|
|
@ -5862,6 +5909,113 @@ static void smblib_handle_sdp_enumeration_done(struct smb_charger *chg,
|
|||
rising ? "rising" : "falling");
|
||||
}
|
||||
|
||||
static int mmi_get_vbus(struct smb_charger *chg)
|
||||
{
|
||||
int rc = 0, val;
|
||||
|
||||
if (!is_mmi_cp_available(chg))
|
||||
return 0;
|
||||
|
||||
rc = smblib_read_iio_prop(chg, MMI_CP, SC8549_INPUT_VOLTAGE_NOW,
|
||||
&val);
|
||||
if (!rc)
|
||||
return val;
|
||||
else {
|
||||
smblib_err(chg, "Couldn't read mmi cp vbus rc=%d\n", rc);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define QC3P_AUTHEN_LOW_THR_MV 5500
|
||||
#define QC3P_AUTHEN_HIGH_THR_MV 6500
|
||||
#define QC3P_AUTHEN_NONE_THR_MV 9500
|
||||
#define QC3P_AUTHEN_45W_THR_MV 8500
|
||||
#define QC3P_AUTHEN_27W_THR_MV 7500
|
||||
#define QC3P_AUTHEN_18W_THR_MV 6500
|
||||
static int mmi_qc3p_kthread_handler(void *param)
|
||||
{
|
||||
struct smb_charger *chg = param;
|
||||
int i;
|
||||
int v_aut,v_power;
|
||||
unsigned long j1,j2;
|
||||
struct sched_param sch_param = {.sched_priority = MAX_RT_PRIO-1};
|
||||
|
||||
sched_setscheduler(current, SCHED_FIFO, &sch_param);
|
||||
do {
|
||||
wait_event_interruptible(chg->mmi_timer_wait_que, chg->mmi_timer_trig_flag || kthread_should_stop());
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
chg->mmi_timer_trig_flag = false;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
smblib_dp_pulse(chg);
|
||||
udelay(5000);
|
||||
}
|
||||
mdelay(95);
|
||||
for (i = 0; i < 16; i++) {
|
||||
smblib_dm_pulse(chg);
|
||||
udelay(5000);
|
||||
}
|
||||
mdelay(100);
|
||||
|
||||
j1 = jiffies;
|
||||
v_aut = mmi_get_vbus(chg);
|
||||
j1 = jiffies - j1;
|
||||
if (v_aut < QC3P_AUTHEN_LOW_THR_MV || v_aut > QC3P_AUTHEN_HIGH_THR_MV) {
|
||||
chg->mmi_qc3p_power = QTI_POWER_SUPPLY_QC3P_NONE;
|
||||
smblib_err(chg, "is qc3.0 charge adatper vbus=%d\n",v_aut);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0;i < 3; i++) {
|
||||
smblib_dp_pulse(chg);
|
||||
udelay(5000);
|
||||
smblib_dm_pulse(chg);
|
||||
udelay(5000);
|
||||
}
|
||||
mdelay(30);
|
||||
|
||||
j2 = jiffies;
|
||||
v_power = mmi_get_vbus(chg);
|
||||
j2 = jiffies - j2;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
smblib_dp_pulse(chg);
|
||||
udelay(5000);
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
smblib_dm_pulse(chg);
|
||||
udelay(5000);
|
||||
}
|
||||
msleep(30);
|
||||
|
||||
if (v_power > QC3P_AUTHEN_NONE_THR_MV)
|
||||
chg->mmi_qc3p_power = QTI_POWER_SUPPLY_QC3P_NONE;
|
||||
else if (v_power > QC3P_AUTHEN_45W_THR_MV)
|
||||
chg->mmi_qc3p_power = QTI_POWER_SUPPLY_QC3P_45W;
|
||||
else if (v_power > QC3P_AUTHEN_27W_THR_MV)
|
||||
chg->mmi_qc3p_power = QTI_POWER_SUPPLY_QC3P_27W;
|
||||
else if (v_power > QC3P_AUTHEN_18W_THR_MV)
|
||||
chg->mmi_qc3p_power = QTI_POWER_SUPPLY_QC3P_18W;
|
||||
else
|
||||
chg->mmi_qc3p_power = QTI_POWER_SUPPLY_QC3P_NONE;
|
||||
|
||||
if (chg->mmi_qc3p_power != QTI_POWER_SUPPLY_QC3P_NONE)
|
||||
chg->qc3p5_detected = true;
|
||||
smblib_update_usb_type(chg);
|
||||
power_supply_changed(chg->usb_psy);
|
||||
|
||||
smblib_dbg(chg, PR_MISC, "V_aut:%dms %dmV,V_power=%dms %dmV,Power =%d\n",
|
||||
jiffies_to_msecs(j1), v_aut, jiffies_to_msecs(j2), v_power, chg->mmi_qc3p_power);
|
||||
out:
|
||||
chg->mmi_is_qc3p_authen = false;
|
||||
vote(chg->usb_icl_votable, SW_QC3P_AUTHEN_VOTER, false, 0);
|
||||
}while (!kthread_should_stop());
|
||||
|
||||
smblib_dbg(chg, PR_MISC, "qc3p kthread stop\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define APSD_EXTENDED_TIMEOUT_MS 400
|
||||
/* triggers when HVDCP 3.0 authentication has finished */
|
||||
static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg,
|
||||
|
|
@ -5898,6 +6052,13 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg,
|
|||
"APSD Extented timer started at %lld\n",
|
||||
jiffies_to_msecs(jiffies));
|
||||
|
||||
if (chg->mmi_qc3p_support) {
|
||||
chg->mmi_is_qc3p_authen = true;
|
||||
chg->qc3p5_detected = false;
|
||||
chg->mmi_qc3p_power = QTI_POWER_SUPPLY_QC3P_NONE;
|
||||
vote(chg->usb_icl_votable, SW_QC3P_AUTHEN_VOTER, true, 500000);
|
||||
}
|
||||
|
||||
mod_timer(&chg->apsd_timer,
|
||||
msecs_to_jiffies(APSD_EXTENDED_TIMEOUT_MS)
|
||||
+ jiffies);
|
||||
|
|
@ -6477,6 +6638,7 @@ static void typec_src_removal(struct smb_charger *chg)
|
|||
vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, DCP_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, SW_QC3P_AUTHEN_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, CTM_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0);
|
||||
vote(chg->usb_icl_votable, CHG_TERMINATION_VOTER, false, 0);
|
||||
|
|
@ -7985,6 +8147,11 @@ static void apsd_timer_cb(struct timer_list *tm)
|
|||
jiffies_to_msecs(jiffies));
|
||||
|
||||
chg->apsd_ext_timeout = true;
|
||||
|
||||
if (chg->mmi_qc3p_support) {
|
||||
chg->mmi_timer_trig_flag = true;
|
||||
wake_up_interruptible(&chg->mmi_timer_wait_que);
|
||||
}
|
||||
}
|
||||
|
||||
#define SOFT_JEITA_HYSTERESIS_OFFSET 0x200
|
||||
|
|
@ -8559,6 +8726,17 @@ int smblib_init(struct smb_charger *chg)
|
|||
INIT_DELAYED_WORK(&chg->pr_lock_clear_work,
|
||||
smblib_pr_lock_clear_work);
|
||||
INIT_DELAYED_WORK(&chg->pd_contract_work, smblib_pd_contract_work);
|
||||
if (chg->mmi_qc3p_support) {
|
||||
chg->mmi_qc3p_authen_task = kthread_create(mmi_qc3p_kthread_handler, chg,
|
||||
"mmi_qc3p_authen", "mmi_qc3p_authen_task", chg);
|
||||
if (IS_ERR(chg->mmi_qc3p_authen_task)) {
|
||||
rc = PTR_ERR(chg->mmi_qc3p_authen_task);
|
||||
smblib_err(chg, "Failed to create mmi_qc3p_authen_task rc = %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
init_waitqueue_head(&chg->mmi_timer_wait_que);
|
||||
wake_up_process(chg->mmi_qc3p_authen_task);
|
||||
}
|
||||
timer_setup(&chg->apsd_timer, apsd_timer_cb, 0);
|
||||
|
||||
INIT_DELAYED_WORK(&chg->role_reversal_check,
|
||||
|
|
@ -8729,6 +8907,8 @@ int smblib_deinit(struct smb_charger *chg)
|
|||
cancel_delayed_work_sync(&chg->usbov_dbc_work);
|
||||
cancel_delayed_work_sync(&chg->role_reversal_check);
|
||||
cancel_delayed_work_sync(&chg->pr_swap_detach_work);
|
||||
if (chg->mmi_qc3p_support && chg->mmi_qc3p_authen_task)
|
||||
kthread_stop(chg->mmi_qc3p_authen_task);
|
||||
power_supply_unreg_notifier(&chg->nb);
|
||||
smblib_destroy_votables(chg);
|
||||
qcom_step_chg_deinit();
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ enum print_reason {
|
|||
#define ICL_CHANGE_VOTER "ICL_CHANGE_VOTER"
|
||||
#define OVERHEAT_LIMIT_VOTER "OVERHEAT_LIMIT_VOTER"
|
||||
#define TYPEC_SWAP_VOTER "TYPEC_SWAP_VOTER"
|
||||
#define SW_QC3P_AUTHEN_VOTER "SW_QC3P_AUTHEN_VOTER"
|
||||
|
||||
#define BOOST_BACK_STORM_COUNT 3
|
||||
#define WEAK_CHG_STORM_COUNT 8
|
||||
|
|
@ -639,6 +640,15 @@ struct smb_charger {
|
|||
ktime_t dcin_uv_last_time;
|
||||
int last_wls_vout;
|
||||
int usb_dcp_curr_max;
|
||||
|
||||
/* mmi qc3p */
|
||||
struct iio_channel **iio_chan_list_mmi_cp;
|
||||
struct task_struct *mmi_qc3p_authen_task;
|
||||
wait_queue_head_t mmi_timer_wait_que;
|
||||
enum mmi_qc3p_power mmi_qc3p_power;
|
||||
bool mmi_is_qc3p_authen;
|
||||
bool mmi_qc3p_support;
|
||||
bool mmi_timer_trig_flag;
|
||||
};
|
||||
|
||||
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
|
||||
|
|
|
|||
|
|
@ -160,4 +160,5 @@
|
|||
#define PSY_IIO_MMI_CP_INPUT_VOLTAGE_NOW 0x101
|
||||
#define PSY_IIO_MMI_CP_STATUS1 0x102
|
||||
#define PSY_IIO_MMI_CP_CLEAR_ERROR 0x103
|
||||
#define PSY_IIO_MMI_QC3P_POWER 0x104
|
||||
#endif /* __QTI_POWER_SUPPLY_IIO_H__ */
|
||||
|
|
|
|||
|
|
@ -113,4 +113,10 @@ enum power_supply_typec_power_role {
|
|||
QTI_POWER_SUPPLY_TYPEC_PR_SOURCE,
|
||||
};
|
||||
|
||||
enum mmi_qc3p_power {
|
||||
QTI_POWER_SUPPLY_QC3P_NONE,
|
||||
QTI_POWER_SUPPLY_QC3P_18W,
|
||||
QTI_POWER_SUPPLY_QC3P_27W,
|
||||
QTI_POWER_SUPPLY_QC3P_45W,
|
||||
};
|
||||
#endif /* __QTI_POWER_SUPPLY_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue