diff options
author | Patrick Delaunay | 2019-03-29 15:42:24 +0100 |
---|---|---|
committer | Marek Vasut | 2019-04-21 10:26:52 +0200 |
commit | 6fe7dd3327d552bacf4266d7f1ed074bf98ffb92 (patch) | |
tree | b4ddd4665a26df7617120e110682954e532571d5 /board | |
parent | c31000c534c6d62dd3a3ae58f30eae3ed572d856 (diff) |
stm32mp1: add stusb1600 support for DK1 and DK2 board
The DK1 and DK2 boards use the USB Type-C controller STUSB1600.
This patch updates:
- the device tree to add the I2C node in the DT
- the board stm32mp1 to probe this I2C device and use this controller
to check cable detection.
- the DWC2 driver to support a new dt property
"u-boot,force-b-session-valid" which forces B session and
device mode; it is a workaround because the VBUS sensing and
ID detection isn't available with stusb1600.
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Lukasz Majewski <lukma@denx.de>
Diffstat (limited to 'board')
-rw-r--r-- | board/st/stm32mp1/stm32mp1.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index b369b7a54b6..76917b022ed 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -9,15 +9,18 @@ #include <dm.h> #include <g_dnl.h> #include <generic-phy.h> +#include <i2c.h> #include <led.h> #include <misc.h> #include <phy.h> #include <reset.h> #include <syscon.h> +#include <usb.h> #include <asm/io.h> #include <asm/gpio.h> #include <asm/arch/stm32.h> #include <power/regulator.h> +#include <usb/dwc2_udc.h> /* SYSCFG registers */ #define SYSCFG_BOOTR 0x00 @@ -151,11 +154,64 @@ static void board_key_check(void) #if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) +/* STMicroelectronics STUSB1600 Type-C controller */ +#define STUSB1600_CC_CONNECTION_STATUS 0x0E + +/* STUSB1600_CC_CONNECTION_STATUS bitfields */ +#define STUSB1600_CC_ATTACH BIT(0) + +static int stusb1600_init(struct udevice **dev_stusb1600) +{ + ofnode node; + struct udevice *dev, *bus; + int ret; + u32 chip_addr; + + *dev_stusb1600 = NULL; + + /* if node stusb1600 is present, means DK1 or DK2 board */ + node = ofnode_by_compatible(ofnode_null(), "st,stusb1600"); + if (!ofnode_valid(node)) + return -ENODEV; + + ret = ofnode_read_u32(node, "reg", &chip_addr); + if (ret) + return -EINVAL; + + ret = uclass_get_device_by_ofnode(UCLASS_I2C, ofnode_get_parent(node), + &bus); + if (ret) { + printf("bus for stusb1600 not found\n"); + return -ENODEV; + } + + ret = dm_i2c_probe(bus, chip_addr, 0, &dev); + if (!ret) + *dev_stusb1600 = dev; + + return ret; +} + +static int stusb1600_cable_connected(struct udevice *dev) +{ + u8 status; + + if (dm_i2c_read(dev, STUSB1600_CC_CONNECTION_STATUS, &status, 1)) + return 0; + + return status & STUSB1600_CC_ATTACH; +} + +#include <usb/dwc2_udc.h> int g_dnl_board_usb_cable_connected(void) { + struct udevice *stusb1600; struct udevice *dwc2_udc_otg; int ret; + if (!stusb1600_init(&stusb1600)) + return stusb1600_cable_connected(stusb1600); + ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC, DM_GET_DRIVER(dwc2_udc_otg), &dwc2_udc_otg); |