inline void mxs_gpio_init(void) {}
#endif
+#define MXS_GPIO_NR(p, o) (((p) * 32) | ((o) & 0x1f))
+#define MXS_GPIO_TO_BANK(gpio) ((gpio) / 32)
+#define MXS_GPIO_TO_PIN(gpio) ((gpio) % 32)
+
#endif /* __MX28_GPIO_H__ */
* PAD_VOL_VALID: 14 (1)
* PAD_PULL: 15 (1)
* PAD_PULL_VALID: 16 (1)
- * RESERVED: 17..31 (15)
+ * RESERVED: 17..30 (14)
+ * sentinel to produce an invalid GPIO number when using an
+ * iomux_cfg_t value where a plain GPIO number is expected
+ * GPIO_SENTINEL: 31 (1)
*/
+#ifdef CONFIG_MXS_IOMUX_COMPILE_CHECK
+typedef u64 iomux_cfg_t;
+#define IOMUX_CFG_SHIFT 32
+#else
typedef u32 iomux_cfg_t;
+#define IOMUX_CFG_SHIFT 0
+#endif
-#define MXS_PAD_BANK_SHIFT 0
+#define MXS_PAD_BANK_SHIFT (IOMUX_CFG_SHIFT + 0)
#define MXS_PAD_BANK_MASK ((iomux_cfg_t)0x7 << MXS_PAD_BANK_SHIFT)
-#define MXS_PAD_PIN_SHIFT 3
+#define MXS_PAD_PIN_SHIFT (IOMUX_CFG_SHIFT + 3)
#define MXS_PAD_PIN_MASK ((iomux_cfg_t)0x1f << MXS_PAD_PIN_SHIFT)
-#define MXS_PAD_MUXSEL_SHIFT 8
+#define MXS_PAD_MUXSEL_SHIFT (IOMUX_CFG_SHIFT + 8)
#define MXS_PAD_MUXSEL_MASK ((iomux_cfg_t)0x3 << MXS_PAD_MUXSEL_SHIFT)
-#define MXS_PAD_MA_SHIFT 10
+#define MXS_PAD_MA_SHIFT (IOMUX_CFG_SHIFT + 10)
#define MXS_PAD_MA_MASK ((iomux_cfg_t)0x3 << MXS_PAD_MA_SHIFT)
-#define MXS_PAD_MA_VALID_SHIFT 12
+#define MXS_PAD_MA_VALID_SHIFT (IOMUX_CFG_SHIFT + 12)
#define MXS_PAD_MA_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_MA_VALID_SHIFT)
-#define MXS_PAD_VOL_SHIFT 13
+#define MXS_PAD_VOL_SHIFT (IOMUX_CFG_SHIFT + 13)
#define MXS_PAD_VOL_MASK ((iomux_cfg_t)0x1 << MXS_PAD_VOL_SHIFT)
-#define MXS_PAD_VOL_VALID_SHIFT 14
+#define MXS_PAD_VOL_VALID_SHIFT (IOMUX_CFG_SHIFT + 14)
#define MXS_PAD_VOL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_VOL_VALID_SHIFT)
-#define MXS_PAD_PULL_SHIFT 15
+#define MXS_PAD_PULL_SHIFT (IOMUX_CFG_SHIFT + 15)
#define MXS_PAD_PULL_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_SHIFT)
-#define MXS_PAD_PULL_VALID_SHIFT 16
+#define MXS_PAD_PULL_VALID_SHIFT (IOMUX_CFG_SHIFT + 16)
#define MXS_PAD_PULL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_VALID_SHIFT)
-#define PAD_MUXSEL_0 0
-#define PAD_MUXSEL_1 1
-#define PAD_MUXSEL_2 2
-#define PAD_MUXSEL_GPIO 3
+#define MXS_GPIO_SENTINEL_SHIFT (IOMUX_CFG_SHIFT + 31)
+#define MXS_GPIO_SENTINEL_MASK ((iomux_cfg_t)0x1 << MXS_GPIO_SENTINEL_SHIFT)
-#define PAD_4MA 0
-#define PAD_8MA 1
-#define PAD_12MA 2
-#define PAD_16MA 3
+#define PAD_MUXSEL_0 (iomux_cfg_t)0
+#define PAD_MUXSEL_1 (iomux_cfg_t)1
+#define PAD_MUXSEL_2 (iomux_cfg_t)2
+#define PAD_MUXSEL_GPIO (iomux_cfg_t)3
-#define PAD_1V8 0
+#define PAD_4MA (iomux_cfg_t)0
+#define PAD_8MA (iomux_cfg_t)1
+#define PAD_12MA (iomux_cfg_t)2
+#define PAD_16MA (iomux_cfg_t)3
+
+#define PAD_1V8 (iomux_cfg_t)0
#if defined(CONFIG_SOC_MX28)
-#define PAD_3V3 1
+#define PAD_3V3 (iomux_cfg_t)1
#else
-#define PAD_3V3 0
+#define PAD_3V3 (iomux_cfg_t)0
#endif
-#define PAD_NOPULL 0
-#define PAD_PULLUP 1
+#define PAD_NOPULL (iomux_cfg_t)0
+#define PAD_PULLUP (iomux_cfg_t)1
#define MXS_PAD_4MA ((PAD_4MA << MXS_PAD_MA_SHIFT) | \
MXS_PAD_MA_VALID_MASK)
((iomux_cfg_t)(_muxsel) << MXS_PAD_MUXSEL_SHIFT) | \
((iomux_cfg_t)(_ma) << MXS_PAD_MA_SHIFT) | \
((iomux_cfg_t)(_vol) << MXS_PAD_VOL_SHIFT) | \
- ((iomux_cfg_t)(_pull) << MXS_PAD_PULL_SHIFT))
+ ((iomux_cfg_t)(_pull) << MXS_PAD_PULL_SHIFT) | \
+ ((iomux_cfg_t)1 << 31))
+
+#define MXS_PAD_TO_GPIO(p) ((unsigned)(((((p) & MXS_PAD_BANK_MASK) >> \
+ MXS_PAD_BANK_SHIFT) << 5) | \
+ ((p) & MXS_PAD_PIN_MASK) >> \
+ MXS_PAD_PIN_SHIFT))
/*
* A pad becomes naked, when none of mA, vol or pull
mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT);
mxs_iomux_setup_pad(MX28_PAD_AUART3_TX__GPIO_3_13 |
MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
- gpio_direction_output(MX28_PAD_AUART3_TX__GPIO_3_13, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART3_TX__GPIO_3_13), 0);
mxs_iomux_setup_pad(MX28_PAD_AUART3_RX__GPIO_3_12 |
MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
- gpio_direction_output(MX28_PAD_AUART3_RX__GPIO_3_12, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART3_RX__GPIO_3_12), 0);
#endif
return 0;
return 1;
}
- return gpio_get_value(MX28_PAD_AUART2_CTS__GPIO_3_10);
+ return gpio_get_value(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_CTS__GPIO_3_10));
}
int board_mmc_init(bd_t *bis)
{
/* Configure WP as input. */
- gpio_direction_input(MX28_PAD_AUART2_CTS__GPIO_3_10);
+ gpio_direction_input(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_CTS__GPIO_3_10));
/* Turn on the power to the card. */
- gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_PWM3__GPIO_3_28), 0);
return mxsmmc_initialize(bis, 0, m28_mmc_wp, NULL);
}
#if !defined(CONFIG_DENX_M28_V11) && !defined(CONFIG_DENX_M28_V10)
/* Reset the new PHY */
- gpio_direction_output(MX28_PAD_AUART2_RTS__GPIO_3_11, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RTS__GPIO_3_11), 0);
udelay(10000);
- gpio_set_value(MX28_PAD_AUART2_RTS__GPIO_3_11, 1);
+ gpio_set_value(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RTS__GPIO_3_11), 1);
udelay(10000);
#endif
mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
/* Power on LCD */
- gpio_direction_output(MX23_PAD_LCD_RESET__GPIO_1_18, 1);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_LCD_RESET__GPIO_1_18), 1);
/* Set contrast to maximum */
- gpio_direction_output(MX23_PAD_PWM2__GPIO_1_28, 1);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_PWM2__GPIO_1_28), 1);
return 0;
}
return 1;
}
- return gpio_get_value(MX23_PAD_PWM4__GPIO_1_30);
+ return gpio_get_value(MXS_PAD_TO_GPIO(MX23_PAD_PWM4__GPIO_1_30));
}
int board_mmc_init(bd_t *bis)
{
/* Configure WP as input */
- gpio_direction_input(MX23_PAD_PWM4__GPIO_1_30);
+ gpio_direction_input(MXS_PAD_TO_GPIO(MX23_PAD_PWM4__GPIO_1_30));
/* Configure MMC0 Power Enable */
- gpio_direction_output(MX23_PAD_PWM3__GPIO_1_29, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_PWM3__GPIO_1_29), 0);
return mxsmmc_initialize(bis, 0, mx23evk_mmc_wp, NULL);
}
mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT);
mxs_iomux_setup_pad(MX28_PAD_AUART2_RX__GPIO_3_8 |
MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL);
- gpio_direction_output(MX28_PAD_AUART2_RX__GPIO_3_8, 1);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RX__GPIO_3_8), 1);
#endif
/* Power on LCD */
- gpio_direction_output(MX28_PAD_LCD_RESET__GPIO_3_30, 1);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_LCD_RESET__GPIO_3_30), 1);
/* Set contrast to maximum */
- gpio_direction_output(MX28_PAD_PWM2__GPIO_3_18, 1);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_PWM2__GPIO_3_18), 1);
return 0;
}
return 1;
}
- return gpio_get_value(MX28_PAD_SSP1_SCK__GPIO_2_12);
+ return gpio_get_value(MXS_PAD_TO_GPIO(MX28_PAD_SSP1_SCK__GPIO_2_12));
}
int board_mmc_init(bd_t *bis)
{
/* Configure WP as input */
- gpio_direction_input(MX28_PAD_SSP1_SCK__GPIO_2_12);
+ gpio_direction_input(MXS_PAD_TO_GPIO(MX28_PAD_SSP1_SCK__GPIO_2_12));
/* Configure MMC0 Power Enable */
- gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_PWM3__GPIO_3_28), 0);
return mxsmmc_initialize(bis, 0, mx28evk_mmc_wp, NULL);
}
&clkctrl_regs->hw_clkctrl_enet);
/* Power-on FECs */
- gpio_direction_output(MX28_PAD_SSP1_DATA3__GPIO_2_15, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_SSP1_DATA3__GPIO_2_15), 0);
/* Reset FEC PHYs */
- gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_CLK__GPIO_4_13), 0);
udelay(200);
- gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1);
+ gpio_set_value(MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_CLK__GPIO_4_13), 1);
ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
if (ret) {
#include <linux/fb.h>
#include <asm/io.h>
#include <asm/gpio.h>
+#include <asm/arch/iomux.h>
#include <asm/arch/iomux-mx28.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
DECLARE_GLOBAL_DATA_PTR;
-#define MXS_GPIO_NR(p, o) (((p) << 5) | (o))
+#define TX28_LCD_PWR_GPIO MXS_PAD_TO_GPIO(MX28_PAD_LCD_ENABLE__GPIO_1_31)
+#define TX28_LCD_RST_GPIO MXS_PAD_TO_GPIO(MX28_PAD_LCD_RESET__GPIO_3_30)
+#define TX28_LCD_BACKLIGHT_GPIO MXS_PAD_TO_GPIO(MX28_PAD_PWM0__GPIO_3_16)
-#define TX28_LCD_PWR_GPIO MX28_PAD_LCD_ENABLE__GPIO_1_31
-#define TX28_LCD_RST_GPIO MX28_PAD_LCD_RESET__GPIO_3_30
-#define TX28_LCD_BACKLIGHT_GPIO MX28_PAD_PWM0__GPIO_3_16
+#define TX28_USBH_VBUSEN_GPIO MXS_PAD_TO_GPIO(MX28_PAD_SPDIF__GPIO_3_27)
+#define TX28_USBH_OC_GPIO MXS_PAD_TO_GPIO(MX28_PAD_JTAG_RTCK__GPIO_4_20)
+#define TX28_USBOTG_VBUSEN_GPIO MXS_PAD_TO_GPIO(MX28_PAD_GPMI_CE2N__GPIO_0_18)
+#define TX28_USBOTG_OC_GPIO MXS_PAD_TO_GPIO(MX28_PAD_GPMI_CE3N__GPIO_0_19)
+#define TX28_USBOTG_ID_GPIO MXS_PAD_TO_GPIO(MX28_PAD_PWM2__GPIO_3_18)
-#define TX28_USBH_VBUSEN_GPIO MX28_PAD_SPDIF__GPIO_3_27
-#define TX28_USBH_OC_GPIO MX28_PAD_JTAG_RTCK__GPIO_4_20
-#define TX28_USBOTG_VBUSEN_GPIO MX28_PAD_GPMI_CE2N__GPIO_0_18
-#define TX28_USBOTG_OC_GPIO MX28_PAD_GPMI_CE3N__GPIO_0_19
-#define TX28_USBOTG_ID_GPIO MX28_PAD_PWM2__GPIO_3_18
+#define TX28_LED_GPIO MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RXD3__GPIO_4_10)
-#define TX28_LED_GPIO MX28_PAD_ENET0_RXD3__GPIO_4_10
-
-#define STK5_CAN_XCVR_GPIO MX28_PAD_LCD_D00__GPIO_1_0
+#define STK5_CAN_XCVR_PAD MX28_PAD_LCD_D00__GPIO_1_0
+#define STK5_CAN_XCVR_GPIO MXS_PAD_TO_GPIO(STK5_CAN_XCVR_PAD)
#define ENET_PAD_CTRL (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
#define GPIO_PAD_CTRL (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
MX28_PAD_ENET0_RXD1__ENET0_RXD1 | ENET_PAD_CTRL,
};
+static struct gpio tx28_fec_strap_gpios[] = {
+ /* first entry must be RESET pin */
+ { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_CLK__GPIO_4_13),
+ GPIOFLAG_OUTPUT_INIT_LOW, "PHY Reset", },
+
+ { MXS_PAD_TO_GPIO(MX28_PAD_PWM4__GPIO_3_29),
+ GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Power", },
+
+ /* Pull strap pins to high */
+ { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_EN__GPIO_4_2),
+ GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Mode0", },
+ { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RXD0__GPIO_4_3),
+ GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Mode1", },
+ { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RXD1__GPIO_4_4),
+ GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Mode2", },
+
+ { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_TX_CLK__GPIO_4_5),
+ GPIOFLAG_INPUT, "PHY INT", },
+};
+
int board_eth_init(bd_t *bis)
{
int ret;
/* Reset the external phy */
- gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0);
-
- /* Power on the external phy */
- gpio_direction_output(MX28_PAD_PWM4__GPIO_3_29, 1);
-
- /* Pull strap pins to high */
- gpio_direction_output(MX28_PAD_ENET0_RX_EN__GPIO_4_2, 1);
- gpio_direction_output(MX28_PAD_ENET0_RXD0__GPIO_4_3, 1);
- gpio_direction_output(MX28_PAD_ENET0_RXD1__GPIO_4_4, 1);
- gpio_direction_input(MX28_PAD_ENET0_TX_CLK__GPIO_4_5);
+ ret = gpio_request_array(tx28_fec_strap_gpios,
+ ARRAY_SIZE(tx28_fec_strap_gpios));
+ if (ret)
+ printf("Failed to request FEC GPIOs: %d\n", ret);
udelay(25000);
- gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1);
+ gpio_set_value(tx28_fec_strap_gpios[0].gpio, 1);
udelay(100);
mxs_iomux_setup_multiple_pads(tx28_fec_pads, ARRAY_SIZE(tx28_fec_pads));
/* init flexcan transceiver enable GPIO */
gpio_request_one(STK5_CAN_XCVR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH,
"Flexcan Transceiver");
- mxs_iomux_setup_pad(STK5_CAN_XCVR_GPIO);
+ mxs_iomux_setup_pad(STK5_CAN_XCVR_PAD);
}
int board_late_init(void)
#include <common.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#include <asm/arch/iomux.h>
#include <asm/arch/iomux-mx23.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
int board_ehci_hcd_init(int port)
{
/* Enable LAN9512 (Maxi) or GL850G (Mini) USB HUB power. */
- gpio_direction_output(MX23_PAD_GPMI_ALE__GPIO_0_17, 1);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_GPMI_ALE__GPIO_0_17), 1);
udelay(100);
return 0;
}
int board_ehci_hcd_exit(int port)
{
/* Enable LAN9512 (Maxi) or GL850G (Mini) USB HUB power. */
- gpio_direction_output(MX23_PAD_GPMI_ALE__GPIO_0_17, 0);
+ gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_GPMI_ALE__GPIO_0_17), 0);
return 0;
}
#endif
int gpio_get_value(unsigned gpio)
{
- uint32_t bank = PAD_BANK(gpio);
+ uint32_t bank = MXS_GPIO_TO_BANK(gpio);
uint32_t offset = PINCTRL_DIN(bank);
struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
- return (readl(®->reg) >> PAD_PIN(gpio)) & 1;
+ if (bank >= PINCTRL_BANKS)
+ return -EINVAL;
+
+ return (readl(®->reg) >> MXS_GPIO_TO_PIN(gpio)) & 1;
}
int gpio_set_value(unsigned gpio, int value)
{
- uint32_t bank = PAD_BANK(gpio);
+ uint32_t bank = MXS_GPIO_TO_BANK(gpio);
uint32_t offset = PINCTRL_DOUT(bank);
struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
+ if (bank >= PINCTRL_BANKS)
+ return -EINVAL;
+
if (value)
- writel(1 << PAD_PIN(gpio), ®->reg_set);
+ writel(1 << MXS_GPIO_TO_PIN(gpio), ®->reg_set);
else
- writel(1 << PAD_PIN(gpio), ®->reg_clr);
+ writel(1 << MXS_GPIO_TO_PIN(gpio), ®->reg_clr);
return 0;
}
int gpio_direction_input(unsigned gpio)
{
- uint32_t bank = PAD_BANK(gpio);
+ uint32_t bank = MXS_GPIO_TO_BANK(gpio);
uint32_t offset = PINCTRL_DOE(bank);
struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
- writel(1 << PAD_PIN(gpio), ®->reg_clr);
+ if (bank >= PINCTRL_BANKS)
+ return -EINVAL;
+
+ writel(1 << MXS_GPIO_TO_PIN(gpio), ®->reg_clr);
return 0;
}
int gpio_direction_output(unsigned gpio, int value)
{
- uint32_t bank = PAD_BANK(gpio);
+ uint32_t bank = MXS_GPIO_TO_BANK(gpio);
uint32_t offset = PINCTRL_DOE(bank);
struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
+ if (bank >= PINCTRL_BANKS)
+ return -EINVAL;
+
gpio_set_value(gpio, value);
- writel(1 << PAD_PIN(gpio), ®->reg_set);
+ writel(1 << MXS_GPIO_TO_PIN(gpio), ®->reg_set);
return 0;
}
int gpio_request(unsigned gpio, const char *label)
{
- if (PAD_BANK(gpio) >= PINCTRL_BANKS)
- return -1;
+ if (MXS_GPIO_TO_BANK(gpio) >= PINCTRL_BANKS) {
+ printf("%s(): Invalid GPIO%d (GPIO_%u_%u) requested; possibly intended: GPIO_%u_%u\n",
+ __func__, gpio, gpio / 32, gpio % 32,
+ PAD_BANK(gpio), PAD_PIN(gpio));
+ printf("Linear GPIO number required rather than iomux_cfg_t cookie!\n");
+ printf("Possibly missing MXS_PAD_TO_GPIO() in the GPIO specification.\n");
+ return -EINVAL;
+ }
return 0;
}
#define CONFIG_GPIO_LED
#define CONFIG_BOARD_SPECIFIC_LED
#define STATUS_LED_BOOT 0
-#define STATUS_LED_BIT MX23_PAD_SSP1_DETECT__GPIO_2_1
+#define STATUS_LED_BIT MXS_PAD_TO_GPIO(MX23_PAD_SSP1_DETECT__GPIO_2_1)
#define STATUS_LED_STATE STATUS_LED_ON
#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2)