/* linux/arch/mips/loongson/gsc3280/gpiolib.c * * Copyright (c) 2010 Loongson Co., Ltd. * * GSC3280 - GPIOlib support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #define GPIO_MAX_CONFLICT_MOD 4 #define GSC3280_MAX_MODULES 34 static char *gsc3280_modules_name[GSC3280_MAX_MODULES] = { "CLKOUT", "SDIO", "NFC", "UART0", "UART1", "UART2", "UART3_0", "UART3_1", "UART4_0", "UART4_1", "UART5", "UART5_TXE0", "UART5_TXE1", "UART6", "UART7", "CAN_0", "CAN_1", "SCI0", "SCI1_0", "SCI1_1", "LCDC", "MAC_MII", "MAC_RMII", "KEYPAD", "I2C", "I2S", "PS2_0", "PS2_1", "PWM", "SPI0", "SPI1", "EMI", "JTAG", "USB" }; /* table */ #ifdef CONFIG_BLX_GSC3280A static int gsc3280_gpio_conflict_table[GSC3280_GPIO_END][GPIO_MAX_CONFLICT_MOD] = { {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART3_0,-1},//GPIO0 {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART4_0,-1},//GPIO1 {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART4_0,-1},//GPIO2 {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART4_0,-1}, {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_CAN_0,-1}, {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_CAN_0,-1}, {SYSCTL_IOMUX_UART5,SYSCTL_IOMUX_SCI1_0,-1,-1}, {SYSCTL_IOMUX_UART5,SYSCTL_IOMUX_SCI1_0,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI,-1},//GPIO10 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_SCI1_0,-1,-1,-1}, {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_UART3_0,-1}, {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_UART4_1,-1}, {SYSCTL_IOMUX_PWM,SYSCTL_IOMUX_PS2_1,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_PWM,SYSCTL_IOMUX_PS2_1,SYSCTL_IOMUX_EMI,-1},//GPIO20 {SYSCTL_IOMUX_PWM,SYSCTL_IOMUX_PS2_0,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_PWM,SYSCTL_IOMUX_PS2_0,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_PWM,SYSCTL_IOMUX_I2S,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_SPI0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_SPI0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_SPI0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI,-1}, {SYSCTL_IOMUX_JTAG,-1,-1,-1}, {-1,-1,-1,-1}, {-1,-1,-1,-1}, {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI,-1},//GPIO30 {SYSCTL_IOMUX_EMI,-1,-1,-1}, {SYSCTL_IOMUX_NFC,-1,-1,-1},//GPIO32 {SYSCTL_IOMUX_NFC,-1,-1,-1}, {SYSCTL_IOMUX_NFC,-1,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1},//GPIO40 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART3_0,-1}, {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART3_0,-1}, {SYSCTL_IOMUX_UART0,SYSCTL_IOMUX_CAN_1,SYSCTL_IOMUX_UART5_TXE0,-1}, {SYSCTL_IOMUX_UART0,SYSCTL_IOMUX_CAN_1,SYSCTL_IOMUX_SCI1_0,-1}, {SYSCTL_IOMUX_UART2,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO50 {SYSCTL_IOMUX_UART2,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_UART3_1,-1,-1},//GPIO52 {SYSCTL_IOMUX_UART3_1,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_UART4_1,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_UART4_1,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_UART7,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_UART7,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_SCI1_1,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_SCI1_1,SYSCTL_IOMUX_LCDC,-1,-1}, {SYSCTL_IOMUX_SCI1_1,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO60 {SYSCTL_IOMUX_SPI1,-1,-1,-1}, {SYSCTL_IOMUX_LCDC,-1,-1,-1}, {SYSCTL_IOMUX_CLKOUT,-1,-1,-1}, {SYSCTL_IOMUX_SPI1,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_SPI1,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_SPI1,SYSCTL_IOMUX_EMI,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO67 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO70 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1}, {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1}, {SYSCTL_IOMUX_I2C,-1,-1,-1}, {SYSCTL_IOMUX_I2C,-1,-1,-1}, {SYSCTL_IOMUX_EMI,SYSCTL_IOMUX_I2S,-1,-1}, {SYSCTL_IOMUX_KEYPAD,-1,-1,-1}, {SYSCTL_IOMUX_KEYPAD,-1,-1,-1}, {SYSCTL_IOMUX_JTAG,SYSCTL_IOMUX_UART1,SYSCTL_IOMUX_PWM,-1}, {SYSCTL_IOMUX_JTAG,SYSCTL_IOMUX_UART1,SYSCTL_IOMUX_PWM,-1}, {SYSCTL_IOMUX_EMI,SYSCTL_IOMUX_I2S,SYSCTL_IOMUX_PWM,-1}, {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_SCI1_1,-1,-1}, {SYSCTL_IOMUX_EMI,SYSCTL_IOMUX_UART5,SYSCTL_IOMUX_USB,-1}, {SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_PWM,-1,-1}, {-1,-1,-1,-1}, {-1,-1,-1,-1} }; #else static int gsc3280_gpio_conflict_table[GSC3280_GPIO_END][GPIO_MAX_CONFLICT_MOD] = { {SYSCTL_IOMUX_UART6_4W,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART3_0,-1},//GPIO0 {SYSCTL_IOMUX_UART6_4W,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART4_0,-1},//GPIO1 {SYSCTL_IOMUX_UART6_FULL,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART4_0,-1},//GPIO2 {SYSCTL_IOMUX_UART6_FULL,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART4_0,-1}, {SYSCTL_IOMUX_UART6_FULL,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_CAN_0,-1}, {SYSCTL_IOMUX_UART6_FULL,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_CAN_0,-1}, {SYSCTL_IOMUX_UART5,SYSCTL_IOMUX_SCI1_0,-1,-1}, //GPIO6 {SYSCTL_IOMUX_UART5,SYSCTL_IOMUX_SCI1_0,-1,-1}, //GPIO7 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,-1,-1}, //GPIO8 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI_A39,-1},//GPIO9 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI_A39,-1},//GPIO10 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI_A39,-1},//GPIO11 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI_A39,-1},//GPIO12 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI_A39,-1},//GPIO13 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI_A39,-1},//GPIO14 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_EMI_A39,-1},//GPIO15 {SYSCTL_IOMUX_SCI1_0,-1,-1,-1},//GPIO16 {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_UART3_1,-1},//GPIO17 {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_UART4_1,-1},//GPIO18 {SYSCTL_IOMUX_PWM_ABCAP0,SYSCTL_IOMUX_PS2_1,SYSCTL_IOMUX_EMI_A1519,-1},//GPIO19 {SYSCTL_IOMUX_PWM_ABCAP0,SYSCTL_IOMUX_PS2_1,SYSCTL_IOMUX_EMI_A1519,-1},//GPIO20 {SYSCTL_IOMUX_PWM_OUT23,SYSCTL_IOMUX_PS2_0,SYSCTL_IOMUX_EMI_A1519,-1},//GPIO21 {SYSCTL_IOMUX_PWM_OUT45,SYSCTL_IOMUX_PS2_0,SYSCTL_IOMUX_EMI_A10,-1},//GPIO22 {SYSCTL_IOMUX_PWM_OUT45,SYSCTL_IOMUX_I2S,SYSCTL_IOMUX_EMI_A11,-1},//GPIO23 {SYSCTL_IOMUX_SPI0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI_A1519,-1},//GPIO24 {SYSCTL_IOMUX_SPI0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI_A1519,-1},//GPIO25 {SYSCTL_IOMUX_SPI0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI_A02,-1},//GPIO26 {SYSCTL_IOMUX_JTAG,-1,-1,-1},//GPIO27 {SYSCTL_IOMUX_JTAG,-1,-1,-1},//GPIO28 {SYSCTL_IOMUX_JTAG,-1,SYSCTL_IOMUX_PWM_CAP2,-1},//GPIO29 modify me {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_KEYPAD,SYSCTL_IOMUX_EMI_A02,-1},//GPIO30 {SYSCTL_IOMUX_EMI_A02,-1,-1,-1},//GPIO31 {SYSCTL_IOMUX_NFC,-1,-1,-1},//GPIO32 GPIOB0 {SYSCTL_IOMUX_NFC,-1,-1,-1},//GPIO33 GPIOB1 {SYSCTL_IOMUX_NFC,-1,-1,-1},//GPIO34 GPIOB2 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO35 GPIOB3 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO36 GPIOB4 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO37 GPIOB5 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO38 GPIOB6 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO39 GPIOB7 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO40 GPIOB8 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO41 GPIOB9 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO42 GPIOB10 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO43 GPIOB11 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO44 GPIOB12 {SYSCTL_IOMUX_NFC,SYSCTL_IOMUX_EMI_WRD,-1,-1},//GPIO45 GPIOB13 {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART3_0,-1},//GPIO46 GPIOB14 {SYSCTL_IOMUX_UART6,SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_UART3_0,-1},//GPIO47 GPIOB15 {SYSCTL_IOMUX_UART0,SYSCTL_IOMUX_CAN_1,SYSCTL_IOMUX_UART5_TXE0,-1},//GPIO48 GPIOB16 {SYSCTL_IOMUX_UART0,SYSCTL_IOMUX_CAN_1,SYSCTL_IOMUX_SCI1_0,-1},//GPIO49 GPIOB17 {SYSCTL_IOMUX_UART2,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO50 GPIOB18 {SYSCTL_IOMUX_UART2,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO51 GPIOB19 {SYSCTL_IOMUX_LCDC,SYSCTL_IOMUX_UART3_1,-1,-1},//GPIO52 GPIOB20 {SYSCTL_IOMUX_UART3_1,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO53 GPIOB21 {SYSCTL_IOMUX_UART4_1,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO54 GPIOB22 {SYSCTL_IOMUX_UART4_1,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO55 GPIOB23 {SYSCTL_IOMUX_UART7,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO56 GPIOB24 {SYSCTL_IOMUX_UART7,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO57 GPIOB25 {SYSCTL_IOMUX_SCI1_1,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO58 GPIOB26 {SYSCTL_IOMUX_SCI1_1,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO59 GPIOB27 {SYSCTL_IOMUX_SCI1_1,SYSCTL_IOMUX_LCDC,-1,-1},//GPIO60 GPIOB28 {SYSCTL_IOMUX_SPI1,-1,-1,-1},//GPIO61 GPIOB29 {SYSCTL_IOMUX_LCDC,-1,-1,-1},//GPIO62 GPIOB30 {SYSCTL_IOMUX_CLKOUT,-1,-1,-1},//GPIO63 GPIOB31 {SYSCTL_IOMUX_SPI1,SYSCTL_IOMUX_EMI_A1214,-1,-1}, //GPIO64 GPIOC0 {SYSCTL_IOMUX_SPI1,SYSCTL_IOMUX_EMI_A1214,-1,-1}, //GPIO65 GPIOC1 {SYSCTL_IOMUX_SPI1,SYSCTL_IOMUX_EMI_A1214,-1,-1}, //GPIO66 GPIOC2 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO67 GPIOC3 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO68 GPIOC4 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO69 GPIOC5 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO70 GPIOC6 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO71 GPIOC7 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO72 GPIOC8 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO73 GPIOC9 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO74 GPIOC10 {SYSCTL_IOMUX_MAC_MII,SYSCTL_IOMUX_MAC_RMII,-1,-1},//GPIO75 GPIOC11 {SYSCTL_IOMUX_I2C,-1,-1,-1}, //GPIO78?? GPIOC12 {SYSCTL_IOMUX_I2C,-1,-1,-1}, //GPIO79?? GPIOC13 {SYSCTL_IOMUX_EMI_CSN0,SYSCTL_IOMUX_I2S,-1,-1},//GPIO78 GPIOC14 {SYSCTL_IOMUX_KEYPAD,-1,-1,-1},//GPIO79 GPIOC15 {SYSCTL_IOMUX_KEYPAD,-1,-1,-1},//GPIO80 GPIOC16 {SYSCTL_IOMUX_JTAG,SYSCTL_IOMUX_UART1,SYSCTL_IOMUX_PWM_CAP1,-1},//GPIO81 GPIOC17 {SYSCTL_IOMUX_JTAG,SYSCTL_IOMUX_UART1,SYSCTL_IOMUX_PWM_OUT23,-1},//GPIO82 GPIOC18 {SYSCTL_IOMUX_EMI_CSN1,SYSCTL_IOMUX_I2S,SYSCTL_IOMUX_PWM_OUT01,-1},//GPIO83 GPIOC19 {SYSCTL_IOMUX_SCI1_0,SYSCTL_IOMUX_SCI1_1,-1,-1}, //GPIO84 GPIOC20 {SYSCTL_IOMUX_EMI_CSN2,SYSCTL_IOMUX_UART5_TXE1,SYSCTL_IOMUX_USB,-1}, //GPIO85 GPIOC21 {SYSCTL_IOMUX_SDIO,SYSCTL_IOMUX_PWM_OUT01,-1,-1}, //GPIO86 GPIOC22 {-1,-1,-1,-1}, //GPIO87 GPIOC23 {-1,-1,-1,-1} }; #endif /* return gsc3280 gpio irq number */ static int gsc3280_gpiolib_gpioint_to_irq(struct gpio_chip *chip, unsigned offset) { return EXT_GSC3280_GPIO_IRQ; } /* request an gpio port, process modules conflict */ static int gsc3280_gpiolib_request(struct gpio_chip *chip, unsigned offset) { int i; int pin_number; pin_number = chip->base + offset; if (pin_number < 0 || pin_number >= GSC3280_GPIO_END) return -1; for (i = 0; i < GPIO_MAX_CONFLICT_MOD; i++) { int iomux_mod = gsc3280_gpio_conflict_table[pin_number][i]; if (-1 == iomux_mod) continue; if (sysctl_iomux_is_enabled(iomux_mod)) { if (iomux_mod < GSC3280_MAX_MODULES) printk(KERN_ERR "Module[%s] conflict with gpio%d, request failed\n", gsc3280_modules_name[iomux_mod], pin_number); return -1; } } return 0; } /* set gpio pin, input mode */ static int gsc3280_gpiolib_input(struct gpio_chip *chip, unsigned offset) { unsigned long flags; unsigned long con; struct gsc3280_gpio_chip *ourchip = to_gsc3280_gpio(chip); void __iomem *base = ourchip->base; gsc3280_gpio_lock(ourchip, flags); con = __raw_readl(base + 0x04); con &= ~(0x01 << offset); __raw_writel(con, base + 0x04); gsc3280_gpio_unlock(ourchip, flags); return 0; } /* set gpio pin, output mode */ static int gsc3280_gpiolib_output(struct gpio_chip *chip, unsigned offset, int value) { unsigned long flags; unsigned long dat; unsigned long con; struct gsc3280_gpio_chip *ourchip = to_gsc3280_gpio(chip); void __iomem *base = ourchip->base; gsc3280_gpio_lock(ourchip, flags); dat = __raw_readl(base + 0x00); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x00); con = __raw_readl(base + 0x04); con |= (1 << offset); __raw_writel(con, base + 0x04); __raw_writel(dat, base + 0x00); gsc3280_gpio_unlock(ourchip, flags); return 0; } /* set gpio pin output value */ static void gsc3280_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value) { unsigned long flags; unsigned long dat; struct gsc3280_gpio_chip *ourchip = to_gsc3280_gpio(chip); void __iomem *base = ourchip->base; gsc3280_gpio_lock(ourchip, flags); dat = __raw_readl(base + 0x00); dat &= ~(1 << offset); if (value) dat |= 1 << offset; __raw_writel(dat, base + 0x00); gsc3280_gpio_unlock(ourchip, flags); } /* get gpio pin value */ static int gsc3280_gpiolib_get(struct gpio_chip *chip, unsigned offset) { unsigned int val; struct gsc3280_gpio_chip *ourchip = to_gsc3280_gpio(chip); switch (chip->base) { case GSC3280_GPA(0): val = __raw_readl(ourchip->base + 0x50); break; case GSC3280_GPB(0): val = __raw_readl(ourchip->base + 0x48); break; case GSC3280_GPC(0): val = __raw_readl(ourchip->base + 0x40); break; default: val = 0; } val >>= offset; val &= 1; return val; } #ifdef CONFIG_PM struct gsc3280_gpio_pm gsc3280_gpio_pm_default = { .save = gsc3280_gpio_pm_save, .resume = gsc3280_gpio_pm_resume, }; #endif static struct gsc3280_gpio_chip gsc3280_gpio[] = { { .base = (__iomem void *)GSC3280_REGADDR_GPIO_SWPORTA_DR, .chip = { .base = GSC3280_GPA(0), .ngpio = GSC3280_GPIO_A_NR, .label = "GPIOA", .request = gsc3280_gpiolib_request, .to_irq = gsc3280_gpiolib_gpioint_to_irq, }, #ifdef CONFIG_PM .pm = &gsc3280_gpioa_pm, #endif }, { .base = (__iomem void *)GSC3280_REGADDR_GPIO_SWPORTB_DR, .chip = { .base = GSC3280_GPB(0), .ngpio = GSC3280_GPIO_B_NR, .label = "GPIOB", .request = gsc3280_gpiolib_request, .to_irq = NULL, }, #ifdef CONFIG_PM .pm = &GSC3280_gpio_pm_default, #endif }, { .base = (__iomem void *)GSC3280_REGADDR_GPIO_SWPORTC_DR, .chip = { .base = GSC3280_GPC(0), .ngpio = GSC3280_GPIO_C_NR, .label = "GPIOC", .request = gsc3280_gpiolib_request, .to_irq = NULL, }, #ifdef CONFIG_PM .pm = &gsc3280_gpio_pm_default, #endif }, }; /* add gpio port to gpiolib ** gsc3280 have PORTA, PORTB, PORTC */ void __init gsc3280_gpiolib_add_chips(struct gsc3280_gpio_chip *chip) { struct gpio_chip *gc = &chip->chip; BUG_ON(!chip->base); BUG_ON(!gc->label); BUG_ON(!gc->ngpio); spin_lock_init(&chip->lock); if (!gc->direction_input) gc->direction_input = gsc3280_gpiolib_input; if (!gc->direction_output) gc->direction_output = gsc3280_gpiolib_output; if (!gc->set) gc->set = gsc3280_gpiolib_set; if (!gc->get) gc->get = gsc3280_gpiolib_get; #ifdef CONFIG_PM if (chip->pm != NULL) { if (!chip->pm->save || !chip->pm->resume) printk(KERN_ERR "gpio: %s has missing PM functions\n", gc->label); } else printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); #endif gpiochip_add(gc); } /* gpiolib modules for gsc3280 platform */ int __init gsc3280_gpiolib_init(void) { int i = 0; struct gsc3280_gpio_chip *ourchip = gsc3280_gpio; int nr_chips = ARRAY_SIZE(gsc3280_gpio); /* enable GPIO SysCtrl */ sysctl_mod_enable(SYSCTL_MOD_GPIO); for (i = 0; i < nr_chips; i++, ourchip++) { gsc3280_gpiolib_add_chips(ourchip); } return 0; } /* modules init */ core_initcall(gsc3280_gpiolib_init);