pd: bring up sc2150a

pd/sc2150a
add sc2150a driver

Change-Id: I81ae4c312571ca19fa92ae7dcc842e3a67551a6a
Reviewed-on: https://gerrit.mot.com/2138697
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
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:
chailu1 2021-12-08 17:50:12 +08:00 • committed by Lu Chai
commit 0f3e28cdb1
6 changed files with 87 additions and 19 deletions

View file

@ -37,6 +37,8 @@
#include "pd_core.h"
#endif /* CONFIG_USB_POWER_DELIVERY */
#define SC2150A_DID 0x0000
#define PE_STATE_FULL_NAME 0
#define TCPC_LOW_RP_DUTY (100) /* 10 % */
@ -72,6 +74,7 @@ static inline int tcpci_check_vbus_valid(struct tcpc_device *tcpc)
int tcpci_check_vbus_valid_from_ic(struct tcpc_device *tcpc);
int tcpci_check_vsafe0v(struct tcpc_device *tcpc, bool detect_en);
int tcpci_get_chip_id(struct tcpc_device *tcpc, uint32_t *chip_id);
int tcpci_alert_status_clear(struct tcpc_device *tcpc, uint32_t mask);
int tcpci_fault_status_clear(struct tcpc_device *tcpc, uint8_t status);
int tcpci_set_alert_mask(struct tcpc_device *tcpc, uint32_t mask);

View file

@ -212,6 +212,7 @@ struct tcpc_ops {
int (*alert_status_clear)(struct tcpc_device *tcpc, uint32_t mask);
int (*fault_status_clear)(struct tcpc_device *tcpc, uint8_t status);
int (*set_alert_mask)(struct tcpc_device *tcpc, uint32_t mask);
int (*get_chip_id)(struct tcpc_device *tcpc, uint32_t *chip_id);
int (*get_alert_mask)(struct tcpc_device *tcpc, uint32_t *mask);
int (*get_alert_status)(struct tcpc_device *tcpc, uint32_t *alert);
int (*get_power_status)(struct tcpc_device *tcpc, uint16_t *pwr_status);

View file

@ -724,7 +724,9 @@ static int rt1711_tcpc_init(struct tcpc_device *tcpc, bool sw_reset)
if (chip->chip_id == RT1711H_DID_A) {
rt1711_i2c_write8(tcpc, TCPC_V10_REG_FAULT_CTRL,
TCPC_V10_REG_FAULT_CTRL_DIS_VCONN_OV);
}
} else if (chip->chip_id == SC2150A_DID)
rt1711_i2c_write8(tcpc, TCPC_V10_REG_COMMAND,
TCPM_CMD_ENABLE_VBUS_DETECT);
/*
* CC Detect Debounce : 26.7*val us
@ -793,6 +795,15 @@ int rt1711_fault_status_clear(struct tcpc_device *tcpc, uint8_t status)
return 0;
}
int rt1711_get_chip_id(struct tcpc_device *tcpc, uint32_t *chip_id)
{
struct rt1711_chip *chip = tcpc_get_dev_data(tcpc);
*chip_id = chip->chip_id;
return 0;
}
int rt1711_get_alert_mask(struct tcpc_device *tcpc, uint32_t *mask)
{
int ret;
@ -883,6 +894,7 @@ static int rt1711_get_cc(struct tcpc_device *tcpc, int *cc1, int *cc2)
{
int status, role_ctrl, cc_role;
bool act_as_sink, act_as_drp;
struct rt1711_chip *chip = tcpc_get_dev_data(tcpc);
status = rt1711_i2c_read8(tcpc, TCPC_V10_REG_CC_STATUS);
if (status < 0)
@ -920,6 +932,15 @@ static int rt1711_get_cc(struct tcpc_device *tcpc, int *cc1, int *cc2)
* If status is not open, then OR in termination to convert to
* enum tcpc_cc_voltage_status.
*/
if (chip->chip_id == SC2150A_DID && act_as_drp &&
act_as_sink) {
if ((*cc1 + *cc2) > (2 * TYPEC_CC_VOLT_RA)) {
if (*cc1 == TYPEC_CC_VOLT_RA)
*cc1 = TYPEC_CC_VOLT_OPEN;
if (*cc2 == TYPEC_CC_VOLT_RA)
*cc2 = TYPEC_CC_VOLT_OPEN;
}
}
if (*cc1 != TYPEC_CC_VOLT_OPEN)
*cc1 |= (act_as_sink << 2);
@ -953,18 +974,22 @@ static int rt1711_enable_vsafe0v_detect(
static int rt1711_set_cc(struct tcpc_device *tcpc, int pull)
{
int ret;
uint8_t data;
int ret = 0;
uint8_t data = 0;
uint8_t old_data = 0;
int rp_lvl = TYPEC_CC_PULL_GET_RP_LVL(pull), pull1, pull2;
struct rt1711_chip *chip = tcpc_get_dev_data(tcpc);
RT1711_INFO("pull = 0x%02X\n", pull);
pull = TYPEC_CC_PULL_GET_RES(pull);
if (chip->chip_id == SC2150A_DID)
old_data = rt1711_i2c_read8(tcpc, TCPC_V10_REG_ROLE_CTRL);
if (pull == TYPEC_CC_DRP) {
data = TCPC_V10_REG_ROLE_CTRL_RES_SET(
1, rp_lvl, TYPEC_CC_RD, TYPEC_CC_RD);
ret = rt1711_i2c_write8(
tcpc, TCPC_V10_REG_ROLE_CTRL, data);
if (chip->chip_id != SC2150A_DID || old_data != data)
ret = rt1711_i2c_write8(
tcpc, TCPC_V10_REG_ROLE_CTRL, data);
if (ret == 0) {
#ifdef CONFIG_TCPC_VSAFE0V_DETECT_IC
@ -980,14 +1005,17 @@ static int rt1711_set_cc(struct tcpc_device *tcpc, int pull)
pull1 = pull2 = pull;
if (pull == TYPEC_CC_RP && tcpc->typec_is_attached_src) {
if (tcpc->typec_polarity)
pull1 = TYPEC_CC_OPEN;
else
pull2 = TYPEC_CC_OPEN;
if (chip->chip_id != SC2150A_DID) {
if (pull == TYPEC_CC_RP && tcpc->typec_is_attached_src) {
if (tcpc->typec_polarity)
pull1 = TYPEC_CC_OPEN;
else
pull2 = TYPEC_CC_OPEN;
}
}
data = TCPC_V10_REG_ROLE_CTRL_RES_SET(0, rp_lvl, pull1, pull2);
ret = rt1711_i2c_write8(tcpc, TCPC_V10_REG_ROLE_CTRL, data);
if (chip->chip_id != SC2150A_DID || old_data != data)
ret = rt1711_i2c_write8(tcpc, TCPC_V10_REG_ROLE_CTRL, data);
}
return 0;
@ -1229,6 +1257,8 @@ static int rt1711_transmit(struct tcpc_device *tcpc,
if (data_cnt > 0)
memcpy(packet.data, (uint8_t *) data, data_cnt);
if (chip->chip_id == SC2150A_DID)
packet.cnt += 4;
rv = rt1711_block_write(chip->client,
TCPC_V10_REG_TX_BYTE_CNT,
@ -1262,6 +1292,7 @@ static struct tcpc_ops rt1711_tcpc_ops = {
.init = rt1711_tcpc_init,
.alert_status_clear = rt1711_alert_status_clear,
.fault_status_clear = rt1711_fault_status_clear,
.get_chip_id= rt1711_get_chip_id,
.get_alert_mask = rt1711_get_alert_mask,
.get_alert_status = rt1711_get_alert_status,
.get_power_status = rt1711_get_power_status,
@ -1462,7 +1493,7 @@ static int rt1711_tcpcdev_init(struct rt1711_chip *chip, struct device *dev)
#endif /* CONFIG_USB_PD_RETRY_CRC_DISCARD */
#ifdef CONFIG_USB_PD_REV30
if (chip->chip_id >= RT1715_DID_D)
if ((chip->chip_id >= RT1715_DID_D) || (chip->chip_id == SC2150A_DID))
chip->tcpc->tcpc_flags |= TCPC_FLAGS_PD_REV30;
if (chip->tcpc->tcpc_flags & TCPC_FLAGS_PD_REV30)
@ -1477,6 +1508,8 @@ static int rt1711_tcpcdev_init(struct rt1711_chip *chip, struct device *dev)
#define RICHTEK_1711_VID 0x29cf
#define RICHTEK_1711_PID 0x1711
#define SC2150A_VID 0x311C
#define SC2150A_PID 0x2150
static inline int rt1711h_check_revision(struct i2c_client *client)
{
@ -1490,7 +1523,7 @@ static inline int rt1711h_check_revision(struct i2c_client *client)
return -EIO;
}
if (vid != RICHTEK_1711_VID) {
if ((vid != RICHTEK_1711_VID) && (vid != SC2150A_VID)) {
pr_info("%s failed, VID=0x%04x\n", __func__, vid);
return -ENODEV;
}
@ -1501,7 +1534,7 @@ static inline int rt1711h_check_revision(struct i2c_client *client)
return -EIO;
}
if (pid != RICHTEK_1711_PID) {
if ((pid != RICHTEK_1711_PID) && (pid != SC2150A_PID)) {
pr_info("%s failed, PID=0x%04x\n", __func__, pid);
return -ENODEV;
}

View file

@ -117,6 +117,16 @@ int tcpci_check_vsafe0v(
return ret;
}
int tcpci_get_chip_id(struct tcpc_device *tcpc, uint32_t *chip_id)
{
if (tcpc->ops->get_chip_id == NULL)
return -ENOTSUPP;
else
tcpc->ops->get_chip_id(tcpc, chip_id);
return 0;
}
int tcpci_alert_status_clear(
struct tcpc_device *tcpc, uint32_t mask)
{

View file

@ -347,6 +347,7 @@ int tcpci_alert(struct tcpc_device *tcpc)
int rv = 0, i = 0;
uint32_t alert_status = 0, alert_mask = 0;
const uint8_t typec_role = tcpc->typec_role;
uint32_t chip_id;
rv = tcpci_get_alert_status(tcpc, &alert_status);
if (rv < 0)
@ -360,7 +361,9 @@ int tcpci_alert(struct tcpc_device *tcpc)
TCPC_INFO("Alert:0x%04x, Mask:0x%04x\n", alert_status, alert_mask);
#endif /* CONFIG_USB_PD_DBG_ALERT_STATUS */
alert_status &= alert_mask;
rv = tcpci_get_chip_id(tcpc,&chip_id);
if (rv || SC2150A_DID != chip_id)
alert_status &= alert_mask;
if (typec_role == TYPEC_ROLE_UNKNOWN ||
typec_role >= TYPEC_ROLE_NR) {

View file

@ -845,11 +845,18 @@ static inline bool typec_role_is_try_src(
static inline void typec_try_src_entry(struct tcpc_device *tcpc)
{
uint32_t chip_id;
int rv = 0;
TYPEC_NEW_STATE(typec_try_src);
tcpc->typec_drp_try_timeout = false;
tcpci_set_cc(tcpc, TYPEC_CC_RP);
tcpc_enable_timer(tcpc, TYPEC_TRY_TIMER_DRP_TRY);
rv = tcpci_get_chip_id(tcpc, &chip_id);
if (!rv && SC2150A_DID == chip_id) {
tcpc_typec_handle_cc_change(tcpc);
}
}
static inline void typec_trywait_snk_entry(struct tcpc_device *tcpc)
@ -904,11 +911,18 @@ static inline bool typec_role_is_try_sink(
static inline void typec_try_snk_entry(struct tcpc_device *tcpc)
{
int rv = 0;
uint32_t chip_id;
TYPEC_NEW_STATE(typec_try_snk);
tcpc->typec_drp_try_timeout = false;
tcpci_set_cc(tcpc, TYPEC_CC_RD);
tcpc_enable_timer(tcpc, TYPEC_TRY_TIMER_DRP_TRY);
rv = tcpci_get_chip_id(tcpc, &chip_id);
if (!rv && SC2150A_DID == chip_id) {
tcpc_typec_handle_cc_change(tcpc);
}
}
static inline void typec_trywait_src_entry(struct tcpc_device *tcpc)
@ -1561,6 +1575,8 @@ static inline bool typec_handle_cc_changed_entry(struct tcpc_device *tcpc)
static inline void typec_attach_wait_entry(struct tcpc_device *tcpc)
{
bool as_sink;
int rv = 0;
uint32_t chip_id;
#ifdef CONFIG_USB_POWER_DELIVERY
struct pd_port *pd_port = &tcpc->pd_port;
#endif /* CONFIG_USB_POWER_DELIVERY */
@ -1630,10 +1646,12 @@ static inline void typec_attach_wait_entry(struct tcpc_device *tcpc)
#ifdef CONFIG_TYPEC_NOTIFY_ATTACHWAIT
tcpci_notify_attachwait_state(tcpc, as_sink);
#endif /* CONFIG_TYPEC_NOTIFY_ATTACHWAIT */
if (as_sink)
rv = tcpci_get_chip_id(tcpc, &chip_id);
if (as_sink) {
TYPEC_NEW_STATE(typec_attachwait_snk);
else {
if (!rv && SC2150A_DID == chip_id)
tcpci_set_cc(tcpc, TYPEC_CC_RD);
} else {
/* Advertise Rp level before Attached.SRC Ellisys 3.1.6359 */
tcpci_set_cc(tcpc,
TYPEC_CC_PULL(tcpc->typec_local_rp_level, TYPEC_CC_RP));