Commit c3deb0c5d60c4d1da71c0e0d3daa57f3eb5b9c8d
1 parent
2ce6011258
Exists in
smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga
and in
5 other branches
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