Commit 8fe280f330ddfd4a9e395ca15ab4019a1a32aa1f

Authored by Ye.Li
Committed by Stefano Babic
1 parent 36255d6779

imx: mx6 sabreauto: Add board support for USB EHCI

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>

Showing 4 changed files with 116 additions and 0 deletions Side-by-side Diff

arch/arm/imx-common/iomux-v3.c
... ... @@ -77,4 +77,19 @@
77 77 p += stride;
78 78 }
79 79 }
  80 +
  81 +void imx_iomux_set_gpr_register(int group, int start_bit,
  82 + int num_bits, int value)
  83 +{
  84 + int i = 0;
  85 + u32 reg;
  86 + reg = readl(base + group * 4);
  87 + while (num_bits) {
  88 + reg &= ~(1<<(start_bit + i));
  89 + i++;
  90 + num_bits--;
  91 + }
  92 + reg |= (value << start_bit);
  93 + writel(reg, base + group * 4);
  94 +}
arch/arm/include/asm/imx-common/iomux-v3.h
... ... @@ -182,6 +182,11 @@
182 182 void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
183 183 void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
184 184 unsigned count);
  185 +/*
  186 +* Set bits for general purpose registers
  187 +*/
  188 +void imx_iomux_set_gpr_register(int group, int start_bit,
  189 + int num_bits, int value);
185 190  
186 191 /* macros for declaring and using pinmux array */
187 192 #if defined(CONFIG_MX6QDL)
board/freescale/mx6qsabreauto/mx6qsabreauto.c
... ... @@ -27,6 +27,7 @@
27 27 #include <asm/arch/mxc_hdmi.h>
28 28 #include <asm/imx-common/video.h>
29 29 #include <asm/arch/crm_regs.h>
  30 +#include <pca953x.h>
30 31  
31 32 DECLARE_GLOBAL_DATA_PTR;
32 33  
... ... @@ -116,6 +117,44 @@
116 117 MX6_PAD_SD2_DAT0__GPIO1_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
117 118 };
118 119  
  120 +/*Define for building port exp gpio, pin starts from 0*/
  121 +#define PORTEXP_IO_NR(chip, pin) \
  122 + ((chip << 5) + pin)
  123 +
  124 +/*Get the chip addr from a ioexp gpio*/
  125 +#define PORTEXP_IO_TO_CHIP(gpio_nr) \
  126 + (gpio_nr >> 5)
  127 +
  128 +/*Get the pin number from a ioexp gpio*/
  129 +#define PORTEXP_IO_TO_PIN(gpio_nr) \
  130 + (gpio_nr & 0x1f)
  131 +
  132 +static int port_exp_direction_output(unsigned gpio, int value)
  133 +{
  134 + int ret;
  135 +
  136 + i2c_set_bus_num(2);
  137 + ret = i2c_probe(PORTEXP_IO_TO_CHIP(gpio));
  138 + if (ret)
  139 + return ret;
  140 +
  141 + ret = pca953x_set_dir(PORTEXP_IO_TO_CHIP(gpio),
  142 + (1 << PORTEXP_IO_TO_PIN(gpio)),
  143 + (PCA953X_DIR_OUT << PORTEXP_IO_TO_PIN(gpio)));
  144 +
  145 + if (ret)
  146 + return ret;
  147 +
  148 + ret = pca953x_set_val(PORTEXP_IO_TO_CHIP(gpio),
  149 + (1 << PORTEXP_IO_TO_PIN(gpio)),
  150 + (value << PORTEXP_IO_TO_PIN(gpio)));
  151 +
  152 + if (ret)
  153 + return ret;
  154 +
  155 + return 0;
  156 +}
  157 +
119 158 static void setup_iomux_enet(void)
120 159 {
121 160 imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
... ... @@ -361,4 +400,58 @@
361 400  
362 401 return 0;
363 402 }
  403 +
  404 +#ifdef CONFIG_USB_EHCI_MX6
  405 +#define USB_HOST1_PWR PORTEXP_IO_NR(0x32, 7)
  406 +#define USB_OTG_PWR PORTEXP_IO_NR(0x34, 1)
  407 +
  408 +iomux_v3_cfg_t const usb_otg_pads[] = {
  409 + MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
  410 +};
  411 +
  412 +int board_ehci_hcd_init(int port)
  413 +{
  414 + switch (port) {
  415 + case 0:
  416 + imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
  417 + ARRAY_SIZE(usb_otg_pads));
  418 +
  419 + /*
  420 + * Set daisy chain for otg_pin_id on 6q.
  421 + * For 6dl, this bit is reserved.
  422 + */
  423 + imx_iomux_set_gpr_register(1, 13, 1, 0);
  424 + break;
  425 + case 1:
  426 + break;
  427 + default:
  428 + printf("MXC USB port %d not yet supported\n", port);
  429 + return -EINVAL;
  430 + }
  431 + return 0;
  432 +}
  433 +
  434 +int board_ehci_power(int port, int on)
  435 +{
  436 + switch (port) {
  437 + case 0:
  438 + if (on)
  439 + port_exp_direction_output(USB_OTG_PWR, 1);
  440 + else
  441 + port_exp_direction_output(USB_OTG_PWR, 0);
  442 + break;
  443 + case 1:
  444 + if (on)
  445 + port_exp_direction_output(USB_HOST1_PWR, 1);
  446 + else
  447 + port_exp_direction_output(USB_HOST1_PWR, 0);
  448 + break;
  449 + default:
  450 + printf("MXC USB port %d not yet supported\n", port);
  451 + return -EINVAL;
  452 + }
  453 +
  454 + return 0;
  455 +}
  456 +#endif
include/configs/mx6qsabreauto.h
... ... @@ -32,6 +32,9 @@
32 32 #define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
33 33 #define CONFIG_MXC_USB_FLAGS 0
34 34  
  35 +#define CONFIG_PCA953X
  36 +#define CONFIG_SYS_I2C_PCA953X_WIDTH { {0x30, 8}, {0x32, 8}, {0x34, 8} }
  37 +
35 38 #include "mx6sabre_common.h"
36 39  
37 40 #define CONFIG_SYS_FSL_USDHC_NUM 2