mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
QC3P:detection and iio sys support
Add QC3P detection and iio sys support. Change-Id: I7459889d1c7fc35b0913ba908b3ef9cf00c5729e Signed-off-by: wutao <huaqin89@motorola.com> Reviewed-on: https://gerrit.mot.com/2148672 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Huosheng Liao <liaohs@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
f2d6f6fa98
commit
453ca3dcbd
4 changed files with 233 additions and 5 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue