Commit e3579303 authored by Ye Li's avatar Ye Li

MLK-18289-2 imx8mm_evk: Add codes to setup typec PD charging

On iMX8MM EVK, the USB2 port is the primary power supply, when USB2 is charging,
the 3483_EN_SNK1 is not enabled. In the board, we init the tcpc of USB2 first with
PD enabled. If it is charging, when init the tcpc of USB1 we disable the PD,
otherwise we enable PD on USB1.

The USB PD switch NX20P3438 needs to exit dead battery mode before
enable EN_SINK, otherwise the OVP is fixed at 6.8V. Also the OVP threshold needs set to
23V, when we switch to use 20V VBUS input.

Due to HW issue, after we switched to 9V/20V, set on/off button to off then set back it to
on, the board can't power up. In this patch we limit the voltage to 5V, will change back
to 9V/20V when HW fixes the issue.
Signed-off-by: 's avatarYe Li <ye.li@nxp.com>
Acked-by: 's avatarPeng Fan <peng.fan@nxp.com>
parent 867b0263
......@@ -23,6 +23,7 @@
#include <asm/imx-common/dma.h>
#include <power/pmic.h>
#include <power/bd71837.h>
#include "../common/tcpc.h"
DECLARE_GLOBAL_DATA_PTR;
......@@ -189,8 +190,117 @@ int board_phy_config(struct phy_device *phydev)
}
#endif
#ifdef CONFIG_USB_TCPC
struct tcpc_port port1;
struct tcpc_port port2;
struct tcpc_port_config port1_config = {
.i2c_bus = 1, /*i2c2*/
.addr = 0x50,
.port_type = TYPEC_PORT_UFP,
.max_snk_mv = 5000,
.max_snk_ma = 3000,
.max_snk_mw = 40000,
.op_snk_mv = 9000,
};
struct tcpc_port_config port2_config = {
.i2c_bus = 1, /*i2c2*/
.addr = 0x52,
.port_type = TYPEC_PORT_UFP,
.max_snk_mv = 5000,
.max_snk_ma = 3000,
.max_snk_mw = 40000,
.op_snk_mv = 9000,
};
static int setup_pd_switch(uint8_t i2c_bus, uint8_t addr)
{
struct udevice *bus;
struct udevice *i2c_dev = NULL;
int ret;
uint8_t valb;
ret = uclass_get_device_by_seq(UCLASS_I2C, i2c_bus, &bus);
if (ret) {
printf("%s: Can't find bus\n", __func__);
return -EINVAL;
}
ret = dm_i2c_probe(bus, addr, 0, &i2c_dev);
if (ret) {
printf("%s: Can't find device id=0x%x\n",
__func__, addr);
return -ENODEV;
}
ret = dm_i2c_read(i2c_dev, 0xB, &valb, 1);
if (ret) {
printf("%s dm_i2c_read failed, err %d\n", __func__, ret);
return -EIO;
}
valb |= 0x4; /* Set DB_EXIT to exit dead battery mode */
ret = dm_i2c_write(i2c_dev, 0xB, (const uint8_t *)&valb, 1);
if (ret) {
printf("%s dm_i2c_write failed, err %d\n", __func__, ret);
return -EIO;
}
/* Set OVP threshold to 23V */
valb = 0x6;
ret = dm_i2c_write(i2c_dev, 0x8, (const uint8_t *)&valb, 1);
if (ret) {
printf("%s dm_i2c_write failed, err %d\n", __func__, ret);
return -EIO;
}
return 0;
}
static int setup_typec(void)
{
int ret;
ret = setup_pd_switch(1, 0x73);
if (ret)
printf("%s: NX20P3484 setup 0x%x failed, err=%d\n",
__func__, 0x73, ret);
ret = setup_pd_switch(1, 0x72);
if (ret)
printf("%s: NX20P3484 setup 0x%x failed, err=%d\n",
__func__, 0x72, ret);
ret = tcpc_init(&port2, port2_config, NULL);
if (ret) {
printf("%s: tcpc port2 init failed, err=%d\n",
__func__, ret);
} else if (tcpc_pd_sink_check_charging(&port2)) {
/* Disable PD for USB1, since USB2 has priority */
port1_config.disable_pd = true;
printf("Power supply on USB2\n");
}
ret = tcpc_init(&port1, port1_config, NULL);
if (ret) {
printf("%s: tcpc port1 init failed, err=%d\n",
__func__, ret);
} else {
if (!port1_config.disable_pd)
printf("Power supply on USB1\n");
return ret;
}
return ret;
}
#endif
int board_init(void)
{
#ifdef CONFIG_USB_TCPC
setup_typec();
#endif
#ifdef CONFIG_MXC_SPI
setup_spi();
#endif
......
......@@ -39,3 +39,4 @@ CONFIG_DM_SPI=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_USB_TCPC=y
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment