Commit c3deb0c5d60c4d1da71c0e0d3daa57f3eb5b9c8d

Authored by Ye Li
1 parent 2ce6011258

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: Ye Li <ye.li@nxp.com>
Acked-by: Peng Fan <peng.fan@nxp.com>
(cherry picked from commit e3579303f0e050aeeee938584492f76840e4bb97)

Showing 2 changed files with 111 additions and 0 deletions Side-by-side Diff

board/freescale/imx8mm_evk/imx8mm_evk.c
... ... @@ -23,6 +23,7 @@
23 23 #include <asm/mach-imx/dma.h>
24 24 #include <power/pmic.h>
25 25 #include <power/bd71837.h>
  26 +#include "../common/tcpc.h"
26 27  
27 28 DECLARE_GLOBAL_DATA_PTR;
28 29  
29 30  
... ... @@ -192,8 +193,117 @@
192 193 }
193 194 #endif
194 195  
  196 +#ifdef CONFIG_USB_TCPC
  197 +struct tcpc_port port1;
  198 +struct tcpc_port port2;
  199 +
  200 +struct tcpc_port_config port1_config = {
  201 + .i2c_bus = 1, /*i2c2*/
  202 + .addr = 0x50,
  203 + .port_type = TYPEC_PORT_UFP,
  204 + .max_snk_mv = 5000,
  205 + .max_snk_ma = 3000,
  206 + .max_snk_mw = 40000,
  207 + .op_snk_mv = 9000,
  208 +};
  209 +
  210 +struct tcpc_port_config port2_config = {
  211 + .i2c_bus = 1, /*i2c2*/
  212 + .addr = 0x52,
  213 + .port_type = TYPEC_PORT_UFP,
  214 + .max_snk_mv = 5000,
  215 + .max_snk_ma = 3000,
  216 + .max_snk_mw = 40000,
  217 + .op_snk_mv = 9000,
  218 +};
  219 +
  220 +static int setup_pd_switch(uint8_t i2c_bus, uint8_t addr)
  221 +{
  222 + struct udevice *bus;
  223 + struct udevice *i2c_dev = NULL;
  224 + int ret;
  225 + uint8_t valb;
  226 +
  227 + ret = uclass_get_device_by_seq(UCLASS_I2C, i2c_bus, &bus);
  228 + if (ret) {
  229 + printf("%s: Can't find bus\n", __func__);
  230 + return -EINVAL;
  231 + }
  232 +
  233 + ret = dm_i2c_probe(bus, addr, 0, &i2c_dev);
  234 + if (ret) {
  235 + printf("%s: Can't find device id=0x%x\n",
  236 + __func__, addr);
  237 + return -ENODEV;
  238 + }
  239 +
  240 + ret = dm_i2c_read(i2c_dev, 0xB, &valb, 1);
  241 + if (ret) {
  242 + printf("%s dm_i2c_read failed, err %d\n", __func__, ret);
  243 + return -EIO;
  244 + }
  245 + valb |= 0x4; /* Set DB_EXIT to exit dead battery mode */
  246 + ret = dm_i2c_write(i2c_dev, 0xB, (const uint8_t *)&valb, 1);
  247 + if (ret) {
  248 + printf("%s dm_i2c_write failed, err %d\n", __func__, ret);
  249 + return -EIO;
  250 + }
  251 +
  252 + /* Set OVP threshold to 23V */
  253 + valb = 0x6;
  254 + ret = dm_i2c_write(i2c_dev, 0x8, (const uint8_t *)&valb, 1);
  255 + if (ret) {
  256 + printf("%s dm_i2c_write failed, err %d\n", __func__, ret);
  257 + return -EIO;
  258 + }
  259 +
  260 + return 0;
  261 +}
  262 +
  263 +static int setup_typec(void)
  264 +{
  265 + int ret;
  266 +
  267 + ret = setup_pd_switch(1, 0x73);
  268 + if (ret)
  269 + printf("%s: NX20P3484 setup 0x%x failed, err=%d\n",
  270 + __func__, 0x73, ret);
  271 +
  272 + ret = setup_pd_switch(1, 0x72);
  273 + if (ret)
  274 + printf("%s: NX20P3484 setup 0x%x failed, err=%d\n",
  275 + __func__, 0x72, ret);
  276 +
  277 + ret = tcpc_init(&port2, port2_config, NULL);
  278 + if (ret) {
  279 + printf("%s: tcpc port2 init failed, err=%d\n",
  280 + __func__, ret);
  281 + } else if (tcpc_pd_sink_check_charging(&port2)) {
  282 + /* Disable PD for USB1, since USB2 has priority */
  283 + port1_config.disable_pd = true;
  284 + printf("Power supply on USB2\n");
  285 + }
  286 +
  287 + ret = tcpc_init(&port1, port1_config, NULL);
  288 + if (ret) {
  289 + printf("%s: tcpc port1 init failed, err=%d\n",
  290 + __func__, ret);
  291 + } else {
  292 + if (!port1_config.disable_pd)
  293 + printf("Power supply on USB1\n");
  294 + return ret;
  295 + }
  296 +
  297 + return ret;
  298 +}
  299 +#endif
  300 +
195 301 int board_init(void)
196 302 {
  303 +#ifdef CONFIG_USB_TCPC
  304 + setup_typec();
  305 +#endif
  306 +
197 307 #ifdef CONFIG_MXC_SPI
198 308 setup_spi();
199 309 #endif
configs/imx8mm_evk_defconfig
... ... @@ -45,4 +45,5 @@
45 45 CONFIG_DM_SPI_FLASH=y
46 46 CONFIG_SPI_FLASH=y
47 47 CONFIG_SPI_FLASH_STMICRO=y
  48 +CONFIG_USB_TCPC=y