From 24ec4dbd5a59630f8d0ede2aad560d1336e31fdd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lothar=20Wa=C3=9Fmann?= Date: Thu, 30 Jun 2016 15:40:18 +0200 Subject: [PATCH] mxs_gpio: correctly use the GPIO API The GPIO API expects a linear GPIO number as parameter to the gpio_*() functions. The current implementation of the mxs_gpio driver operates on iomux_cfg_t cookies instead. Therefore the 'gpio' command cannot be used with this driver. Change the driver to implement the correct API and introduce some checks to catch users that still use the old semantics. 1. assert the most sigificant bit in the iomux_cfg_t pad definitions, so that using such a cookie in place of a GPIO number will decisively generate an invalid GPIO number and flag an error at runtime. 2. introduce a compile switch CONFIG_MXS_IOMUX_COMPILE_CHECK to make the iomux_cfg_t cookie a 64 bit variable, so that passing an iomux_cfg_t value to a gpio_*() function will generate a compile time error. --- arch/arm/include/asm/arch-mxs/gpio.h | 4 ++ arch/arm/include/asm/arch-mxs/iomux.h | 66 +++++++++++++------- board/denx/m28evk/m28evk.c | 14 ++--- board/freescale/mx23evk/mx23evk.c | 10 +-- board/freescale/mx28evk/mx28evk.c | 18 +++--- board/karo/tx28/tx28.c | 62 +++++++++++------- board/olimex/mx23_olinuxino/mx23_olinuxino.c | 5 +- drivers/gpio/mxs_gpio.c | 40 ++++++++---- include/configs/mx23_olinuxino.h | 2 +- 9 files changed, 138 insertions(+), 83 deletions(-) diff --git a/arch/arm/include/asm/arch-mxs/gpio.h b/arch/arm/include/asm/arch-mxs/gpio.h index 3bdf879b15..ac028f382c 100644 --- a/arch/arm/include/asm/arch-mxs/gpio.h +++ b/arch/arm/include/asm/arch-mxs/gpio.h @@ -16,4 +16,8 @@ void mxs_gpio_init(void); 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__ */ diff --git a/arch/arm/include/asm/arch-mxs/iomux.h b/arch/arm/include/asm/arch-mxs/iomux.h index 4a0ad73d11..a1d9016d5d 100644 --- a/arch/arm/include/asm/arch-mxs/iomux.h +++ b/arch/arm/include/asm/arch-mxs/iomux.h @@ -25,48 +25,60 @@ * 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) @@ -96,7 +108,13 @@ typedef u32 iomux_cfg_t; ((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 diff --git a/board/denx/m28evk/m28evk.c b/board/denx/m28evk/m28evk.c index 33d38cfc54..b0bb934a38 100644 --- a/board/denx/m28evk/m28evk.c +++ b/board/denx/m28evk/m28evk.c @@ -40,11 +40,11 @@ int board_early_init_f(void) 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; @@ -71,15 +71,15 @@ static int m28_mmc_wp(int id) 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); } @@ -125,9 +125,9 @@ int board_eth_init(bd_t *bis) #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 diff --git a/board/freescale/mx23evk/mx23evk.c b/board/freescale/mx23evk/mx23evk.c index 9428182064..a3fe4c175c 100644 --- a/board/freescale/mx23evk/mx23evk.c +++ b/board/freescale/mx23evk/mx23evk.c @@ -33,10 +33,10 @@ int board_early_init_f(void) 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; } @@ -62,16 +62,16 @@ static int mx23evk_mmc_wp(int id) 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); } diff --git a/board/freescale/mx28evk/mx28evk.c b/board/freescale/mx28evk/mx28evk.c index 5005fe23dd..0f23c30f48 100644 --- a/board/freescale/mx28evk/mx28evk.c +++ b/board/freescale/mx28evk/mx28evk.c @@ -45,14 +45,14 @@ int board_early_init_f(void) 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; } @@ -78,16 +78,16 @@ static int mx28evk_mmc_wp(int id) 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); } @@ -111,12 +111,12 @@ int board_eth_init(bd_t *bis) &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) { diff --git a/board/karo/tx28/tx28.c b/board/karo/tx28/tx28.c index 273463efcf..b7ece9272e 100644 --- a/board/karo/tx28/tx28.c +++ b/board/karo/tx28/tx28.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -38,21 +39,20 @@ 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) @@ -297,24 +297,38 @@ static const iomux_cfg_t tx28_fec_pads[] = { 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)); @@ -840,7 +854,7 @@ static void stk5v5_board_init(void) /* 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) diff --git a/board/olimex/mx23_olinuxino/mx23_olinuxino.c b/board/olimex/mx23_olinuxino/mx23_olinuxino.c index 65cbbf15b7..34fd8698db 100644 --- a/board/olimex/mx23_olinuxino/mx23_olinuxino.c +++ b/board/olimex/mx23_olinuxino/mx23_olinuxino.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ int board_early_init_f(void) 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; } @@ -45,7 +46,7 @@ int board_ehci_hcd_init(int port) 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 diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c index f761104571..e0e627d36c 100644 --- a/drivers/gpio/mxs_gpio.c +++ b/drivers/gpio/mxs_gpio.c @@ -49,55 +49,73 @@ void mxs_gpio_init(void) 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; } diff --git a/include/configs/mx23_olinuxino.h b/include/configs/mx23_olinuxino.h index b63097318d..eeb22900ad 100644 --- a/include/configs/mx23_olinuxino.h +++ b/include/configs/mx23_olinuxino.h @@ -45,7 +45,7 @@ #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) -- 2.39.2