ckfwq/linux-3.0.4/arch/mips/loongson/gsc3280/gpiolib.c

467 lines
16 KiB
C

/* linux/arch/mips/loongson/gsc3280/gpiolib.c
*
* Copyright (c) 2010 Loongson Co., Ltd.
*
* GSC3280 - GPIOlib support <ansonn.wang@gmail.com>
*
* 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 <linux/kernel.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <gsc3280/gpio-plat.h>
#include <gsc3280/gpio.h>
#include <gsc3280/gsc3280_int.h>
#include <gsc3280/gsc3280_regs.h>
#include <gsc3280/sysctl.h>
#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);