]> git.sur5r.net Git - u-boot/commitdiff
imx: mx6 sabreauto: Add board support for USB EHCI
authorYe.Li <B37916@freescale.com>
Thu, 30 Oct 2014 10:53:49 +0000 (18:53 +0800)
committerStefano Babic <sbabic@denx.de>
Mon, 3 Nov 2014 10:21:49 +0000 (11:21 +0100)
On mx6 sabreauto board, there are two USB ports:
0: OTG
1: HOST
The EHCI driver is enabled for this board, but the IOMUX and VBUS power
control is not implemented, which cause both USB port failed to work.
This patch fix the problem by adding the board support codes.

Since the power control uses the GPIO pin from port expander MAX7310,
the PCA953X driver is enabled for accessing the MAX7310.

The ID pin of OTG Port needs to configure the GPR1 bit 13 for selecting
its daisy chain. Add a new function "imx_iomux_set_gpr_register" to
handle GPR register setting.

Signed-off-by: Ye.Li <B37916@freescale.com>
arch/arm/imx-common/iomux-v3.c
arch/arm/include/asm/imx-common/iomux-v3.h
board/freescale/mx6qsabreauto/mx6qsabreauto.c
include/configs/mx6qsabreauto.h

index 22cd11aa04867c47c8d7356683889324d8ad6a25..e88e6e2a9881d0dcd00af5477453afe219ed79b1 100644 (file)
@@ -77,3 +77,18 @@ void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
                p += stride;
        }
 }
+
+void imx_iomux_set_gpr_register(int group, int start_bit,
+                                       int num_bits, int value)
+{
+       int i = 0;
+       u32 reg;
+       reg = readl(base + group * 4);
+       while (num_bits) {
+               reg &= ~(1<<(start_bit + i));
+               i++;
+               num_bits--;
+       }
+       reg |= (value << start_bit);
+       writel(reg, base + group * 4);
+}
index a8ca49c343f8984d0b227963f203a2e9acc9ea38..e0a49be4ff79de66abdb22e420a94b354a83e89f 100644 (file)
@@ -182,6 +182,11 @@ typedef u64 iomux_v3_cfg_t;
 void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
 void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
                                     unsigned count);
+/*
+* Set bits for general purpose registers
+*/
+void imx_iomux_set_gpr_register(int group, int start_bit,
+                                        int num_bits, int value);
 
 /* macros for declaring and using pinmux array */
 #if defined(CONFIG_MX6QDL)
index 0dc0160e19fe9e70510d66668bc2cdef1b341090..42ae6fac5e2a258d64550be1eedbd12a1ed931f8 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/arch/mxc_hdmi.h>
 #include <asm/imx-common/video.h>
 #include <asm/arch/crm_regs.h>
+#include <pca953x.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -116,6 +117,44 @@ static iomux_v3_cfg_t const port_exp[] = {
        MX6_PAD_SD2_DAT0__GPIO1_IO15            | MUX_PAD_CTRL(NO_PAD_CTRL),
 };
 
+/*Define for building port exp gpio, pin starts from 0*/
+#define PORTEXP_IO_NR(chip, pin) \
+       ((chip << 5) + pin)
+
+/*Get the chip addr from a ioexp gpio*/
+#define PORTEXP_IO_TO_CHIP(gpio_nr) \
+       (gpio_nr >> 5)
+
+/*Get the pin number from a ioexp gpio*/
+#define PORTEXP_IO_TO_PIN(gpio_nr) \
+       (gpio_nr & 0x1f)
+
+static int port_exp_direction_output(unsigned gpio, int value)
+{
+       int ret;
+
+       i2c_set_bus_num(2);
+       ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
+       if (ret)
+               return ret;
+
+       ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
+               (1 << PORTEXP_IO_TO_PIN(gpio)),
+               (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
+
+       if (ret)
+               return ret;
+
+       ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
+               (1 << PORTEXP_IO_TO_PIN(gpio)),
+               (value << PORTEXP_IO_TO_PIN(gpio)));
+
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static void setup_iomux_enet(void)
 {
        imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
@@ -361,3 +400,57 @@ int checkboard(void)
 
        return 0;
 }
+
+#ifdef CONFIG_USB_EHCI_MX6
+#define USB_HOST1_PWR     PORTEXP_IO_NR(0x32, 7)
+#define USB_OTG_PWR       PORTEXP_IO_NR(0x34, 1)
+
+iomux_v3_cfg_t const usb_otg_pads[] = {
+       MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+int board_ehci_hcd_init(int port)
+{
+       switch (port) {
+       case 0:
+               imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
+                       ARRAY_SIZE(usb_otg_pads));
+
+               /*
+                 * Set daisy chain for otg_pin_id on 6q.
+                *  For 6dl, this bit is reserved.
+                */
+               imx_iomux_set_gpr_register(1, 13, 1, 0);
+               break;
+       case 1:
+               break;
+       default:
+               printf("MXC USB port %d not yet supported\n", port);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int board_ehci_power(int port, int on)
+{
+       switch (port) {
+       case 0:
+               if (on)
+                       port_exp_direction_output(USB_OTG_PWR, 1);
+               else
+                       port_exp_direction_output(USB_OTG_PWR, 0);
+               break;
+       case 1:
+               if (on)
+                       port_exp_direction_output(USB_HOST1_PWR, 1);
+               else
+                       port_exp_direction_output(USB_HOST1_PWR, 0);
+               break;
+       default:
+               printf("MXC USB port %d not yet supported\n", port);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+#endif
index 0ab31279ccd6e5888ddfa28153ffcc13e5b834fd..235dd6d33fdf9d9018a5ba9cd2e76f40162ad1b2 100644 (file)
@@ -32,6 +32,9 @@
 #define CONFIG_MXC_USB_PORTSC  (PORT_PTS_UTMI | PORT_PTS_PTW)
 #define CONFIG_MXC_USB_FLAGS   0
 
+#define CONFIG_PCA953X
+#define CONFIG_SYS_I2C_PCA953X_WIDTH   { {0x30, 8}, {0x32, 8}, {0x34, 8} }
+
 #include "mx6sabre_common.h"
 
 #define CONFIG_SYS_FSL_USDHC_NUM       2