
On Fri, 29 Mar 2019 15:42:24 +0100 Patrick Delaunay patrick.delaunay@st.com wrote:
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
arch/arm/dts/stm32mp157-pinctrl.dtsi | 7 ++++ arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 2 +- arch/arm/dts/stm32mp157a-dk1.dts | 18 ++++++++++ board/st/stm32mp1/stm32mp1.c | 56 ++++++++++++++++++++++++++++++++ doc/device-tree-bindings/usb/dwc2.txt | 2 ++ drivers/usb/gadget/dwc2_udc_otg.c | 8 +++-- 6 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi index 867d244..1962267 100644 --- a/arch/arm/dts/stm32mp157-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi @@ -380,6 +380,13 @@ }; };
stusb1600_pins_a: stusb1600-0 {
pins {
pinmux = <STM32_PINMUX('I',
11, ANALOG)>;
bias-pull-up;
};
};
uart4_pins_a: uart4-0 { pins1 { pinmux = <STM32_PINMUX('G',
11, AF6)>; /* UART4_TX */ diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi index 7e2c5d0..0f32a38 100644 --- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi @@ -191,7 +191,7 @@ };
&usbotg_hs {
- force-b-session-valid;
- u-boot,force-b-session-valid; hnp-srp-disable;
};
diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts index b8ef820..e36773d 100644 --- a/arch/arm/dts/stm32mp157a-dk1.dts +++ b/arch/arm/dts/stm32mp157a-dk1.dts @@ -67,6 +67,24 @@ /delete-property/dmas; /delete-property/dma-names;
- typec: stusb1600@28 {
compatible = "st,stusb1600";
reg = <0x28>;
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpioi>;
pinctrl-names = "default";
pinctrl-0 = <&stusb1600_pins_a>;
status = "okay";
typec_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
power-role = "sink";
power-opmode = "default";
};
- };
- pmic: stpmic@33 { compatible = "st,stpmic1"; reg = <0x33>;
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 58b6d78..23737ce 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);
diff --git a/doc/device-tree-bindings/usb/dwc2.txt b/doc/device-tree-bindings/usb/dwc2.txt index eb60ffa..61493f7 100644 --- a/doc/device-tree-bindings/usb/dwc2.txt +++ b/doc/device-tree-bindings/usb/dwc2.txt @@ -39,6 +39,8 @@ Refer to phy/phy-bindings.txt for generic phy consumer properties
- g-tx-fifo-size: size of periodic tx fifo per endpoint (except ep0)
in gadget mode.
- usb33d-supply: external VBUS and ID sensing comparators supply, in
order to perform OTG operation, used on STM32MP1 SoCs. +- u-boot,force-b-session-valid: force B-peripheral session instead of relying on
- VBUS sensing (only valid when dr_mode = "peripheral" and for
u-boot). Deprecated properties:
- g-use-dma: gadget DMA mode is automatically detected
diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c index 3fdaa10..494ab53 100644 --- a/drivers/usb/gadget/dwc2_udc_otg.c +++ b/drivers/usb/gadget/dwc2_udc_otg.c @@ -1053,7 +1053,7 @@ static int dwc2_udc_otg_ofdata_to_platdata(struct udevice *dev) platdata->tx_fifo_sz = dev_read_u32_default(dev, "g-tx-fifo-size", 0); platdata->force_b_session_valid =
dev_read_bool(dev, "force-b-session-valid");
dev_read_bool(dev, "u-boot,force-b-session-valid");
/* force platdata according compatible */ drvdata = dev_get_driver_data(dev);
@@ -1075,6 +1075,9 @@ static void dwc2_set_stm32mp1_hsotg_params(struct dwc2_plat_otg_data *p) | 0 << 8 /* [0:SRP disable 1:SRP enable]*/ | 0 << 6 /* 0: high speed utmi+, 1: full speed serial*/ | 0x7 << 0; /* FS timeout calibration**/ +
- if (p->force_b_session_valid)
p->usb_gusbcfg |= 1 << 30; /* FDMOD: Force device
mode */ }
static int dwc2_udc_otg_reset_init(struct udevice *dev, @@ -1166,7 +1169,8 @@ static int dwc2_udc_otg_probe(struct udevice *dev) if (platdata->force_b_session_valid) /* Override B session bits : value and enable */
setbits_le32(&usbotg_reg->gotgctl, B_VALOEN |
B_VALOVAL);
setbits_le32(&usbotg_reg->gotgctl,
A_VALOEN | A_VALOVAL | B_VALOEN |
B_VALOVAL); ret = dwc2_udc_probe(platdata); if (ret)
Reviewed-by: Lukasz Majewski lukma@denx.de
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de