diff --git a/arch/arm/include/asm/arch-s3c24x0/gpio.h b/arch/arm/include/asm/arch-s3c24x0/gpio.h new file mode 100644 index 0000000..76bc52c --- /dev/null +++ b/arch/arm/include/asm/arch-s3c24x0/gpio.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012. + * + * Gabriel Huau + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _S3C24X0_GPIO_H_ +#define _S3C24X0_GPIO_H_ + +enum s3c2440_gpio { + GPA0, + GPA1, + GPA2, + GPA3, + GPA4, + GPA5, + GPA6, + GPA7, + GPA8, + GPA9, + GPA10, + GPA11, + GPA12, + GPA13, + GPA14, + GPA15, + GPA16, + GPA17, + GPA18, + GPA19, + GPA20, + GPA21, + GPA22, + GPA23, + GPA24, + + GPB0 = 32, + GPB1, + GPB2, + GPB3, + GPB4, + GPB5, + GPB6, + GPB7, + GPB8, + GPB9, + GPB10, + + GPC0 = 64, + GPC1, + GPC2, + GPC3, + GPC4, + GPC5, + GPC6, + GPC7, + GPC8, + GPC9, + GPC10, + GPC11, + GPC12, + GPC13, + GPC14, + GPC15, + + GPD0 = 96, + GPD1, + GPD2, + GPD3, + GPD4, + GPD5, + GPD6, + GPD7, + GPD8, + GPD9, + GPD10, + GPD11, + GPD12, + GPD13, + GPD14, + GPD15, + + GPE0 = 128, + GPE1, + GPE2, + GPE3, + GPE4, + GPE5, + GPE6, + GPE7, + GPE8, + GPE9, + GPE10, + GPE11, + GPE12, + GPE13, + GPE14, + GPE15, + + GPF0 = 160, + GPF1, + GPF2, + GPF3, + GPF4, + GPF5, + GPF6, + GPF7, + + GPG0 = 192, + GPG1, + GPG2, + GPG3, + GPG4, + GPG5, + GPG6, + GPG7, + GPG8, + GPG9, + GPG10, + GPG11, + GPG12, + GPG13, + GPG14, + GPG15, + + GPH0 = 224, + GPH1, + GPH2, + GPH3, + GPH4, + GPH5, + GPH6, + GPH7, + GPH8, + GPH9, + GPH10, + + GPJ0 = 256, + GPJ1, + GPJ2, + GPJ3, + GPJ4, + GPJ5, + GPJ6, + GPJ7, + GPJ8, + GPJ9, + GPJ10, + GPJ11, + GPJ12, +}; + +#endif diff --git a/arch/arm/include/asm/arch-s3c24x0/iomux.h b/arch/arm/include/asm/arch-s3c24x0/iomux.h new file mode 100644 index 0000000..cc22de7 --- /dev/null +++ b/arch/arm/include/asm/arch-s3c24x0/iomux.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2012 + * + * Gabriel Huau + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _S3C24X0_IOMUX_H_ +#define _S3C24X0_IOMUX_H_ + +enum s3c2440_iomux_func { + /* PORT A */ + IOMUXA_ADDR0 = 1, + IOMUXA_ADDR16 = (1 << 1), + IOMUXA_ADDR17 = (1 << 2), + IOMUXA_ADDR18 = (1 << 3), + IOMUXA_ADDR19 = (1 << 4), + IOMUXA_ADDR20 = (1 << 5), + IOMUXA_ADDR21 = (1 << 6), + IOMUXA_ADDR22 = (1 << 7), + IOMUXA_ADDR23 = (1 << 8), + IOMUXA_ADDR24 = (1 << 9), + IOMUXA_ADDR25 = (1 << 10), + IOMUXA_ADDR26 = (1 << 11), + IOMUXA_nGCS1 = (1 << 12), + IOMUXA_nGCS2 = (1 << 13), + IOMUXA_nGCS3 = (1 << 14), + IOMUXA_nGCS4 = (1 << 15), + IOMUXA_nGCS5 = (1 << 16), + IOMUXA_CLE = (1 << 17), + IOMUXA_ALE = (1 << 18), + IOMUXA_nFWE = (1 << 19), + IOMUXA_nFRE = (1 << 20), + IOMUXA_nRSTOUT = (1 << 21), + IOMUXA_nFCE = (1 << 22), + + /* PORT B */ + IOMUXB_nXDREQ0 = (2 << 20), + IOMUXB_nXDACK0 = (2 << 18), + IOMUXB_nXDREQ1 = (2 << 16), + IOMUXB_nXDACK1 = (2 << 14), + IOMUXB_nXBREQ = (2 << 12), + IOMUXB_nXBACK = (2 << 10), + IOMUXB_TCLK0 = (2 << 8), + IOMUXB_TOUT3 = (2 << 6), + IOMUXB_TOUT2 = (2 << 4), + IOMUXB_TOUT1 = (2 << 2), + IOMUXB_TOUT0 = 2, + + /* PORT C */ + IOMUXC_VS7 = (2 << 30), + IOMUXC_VS6 = (2 << 28), + IOMUXC_VS5 = (2 << 26), + IOMUXC_VS4 = (2 << 24), + IOMUXC_VS3 = (2 << 22), + IOMUXC_VS2 = (2 << 20), + IOMUXC_VS1 = (2 << 18), + IOMUXC_VS0 = (2 << 16), + IOMUXC_LCD_LPCREVB = (2 << 14), + IOMUXC_LCD_LPCREV = (2 << 12), + IOMUXC_LCD_LPCOE = (2 << 10), + IOMUXC_VM = (2 << 8), + IOMUXC_VFRAME = (2 << 6), + IOMUXC_VLINE = (2 << 4), + IOMUXC_VCLK = (2 << 2), + IOMUXC_LEND = 2, + IOMUXC_I2SSDI = (3 << 8), + + /* PORT D */ + IOMUXD_VS23 = (2 << 30), + IOMUXD_VS22 = (2 << 28), + IOMUXD_VS21 = (2 << 26), + IOMUXD_VS20 = (2 << 24), + IOMUXD_VS19 = (2 << 22), + IOMUXD_VS18 = (2 << 20), + IOMUXD_VS17 = (2 << 18), + IOMUXD_VS16 = (2 << 16), + IOMUXD_VS15 = (2 << 14), + IOMUXD_VS14 = (2 << 12), + IOMUXD_VS13 = (2 << 10), + IOMUXD_VS12 = (2 << 8), + IOMUXD_VS11 = (2 << 6), + IOMUXD_VS10 = (2 << 4), + IOMUXD_VS9 = (2 << 2), + IOMUXD_VS8 = 2, + IOMUXD_nSS0 = (3 << 30), + IOMUXD_nSS1 = (3 << 28), + IOMUXD_SPICLK1 = (3 << 20), + IOMUXD_SPIMOSI1 = (3 << 18), + IOMUXD_SPIMISO1 = (3 << 16), + + /* PORT E */ + IOMUXE_IICSDA = (2 << 30), + IOMUXE_IICSCL = (2 << 28), + IOMUXE_SPICLK0 = (2 << 26), + IOMUXE_SPIMOSI0 = (2 << 24), + IOMUXE_SPIMISO0 = (2 << 22), + IOMUXE_SDDAT3 = (2 << 20), + IOMUXE_SDDAT2 = (2 << 18), + IOMUXE_SDDAT1 = (2 << 16), + IOMUXE_SDDAT0 = (2 << 14), + IOMUXE_SDCMD = (2 << 12), + IOMUXE_SDCLK = (2 << 10), + IOMUXE_I2SDO = (2 << 8), + IOMUXE_I2SDI = (2 << 6), + IOMUXE_CDCLK = (2 << 4), + IOMUXE_I2SSCLK = (2 << 2), + IOMUXE_I2SLRCK = 2, + IOMUXE_AC_SDATA_OUT = (3 << 8), + IOMUXE_AC_SDATA_IN = (3 << 6), + IOMUXE_AC_nRESET = (3 << 4), + IOMUXE_AC_BIT_CLK = (3 << 2), + IOMUXE_AC_SYNC = 3, + + /* PORT F */ + IOMUXF_EINT7 = (2 << 14), + IOMUXF_EINT6 = (2 << 12), + IOMUXF_EINT5 = (2 << 10), + IOMUXF_EINT4 = (2 << 8), + IOMUXF_EINT3 = (2 << 6), + IOMUXF_EINT2 = (2 << 4), + IOMUXF_EINT1 = (2 << 2), + IOMUXF_EINT0 = 2, + + /* PORT G */ + IOMUXG_EINT23 = (2 << 30), + IOMUXG_EINT22 = (2 << 28), + IOMUXG_EINT21 = (2 << 26), + IOMUXG_EINT20 = (2 << 24), + IOMUXG_EINT19 = (2 << 22), + IOMUXG_EINT18 = (2 << 20), + IOMUXG_EINT17 = (2 << 18), + IOMUXG_EINT16 = (2 << 16), + IOMUXG_EINT15 = (2 << 14), + IOMUXG_EINT14 = (2 << 12), + IOMUXG_EINT13 = (2 << 10), + IOMUXG_EINT12 = (2 << 8), + IOMUXG_EINT11 = (2 << 6), + IOMUXG_EINT10 = (2 << 4), + IOMUXG_EINT9 = (2 << 2), + IOMUXG_EINT8 = 2, + IOMUXG_TCLK1 = (3 << 22), + IOMUXG_nCTS1 = (3 << 20), + IOMUXG_nRTS1 = (3 << 18), + IOMUXG_SPICLK1 = (3 << 14), + IOMUXG_SPIMOSI1 = (3 << 12), + IOMUXG_SPIMISO1 = (3 << 10), + IOMUXG_LCD_PWRDN = (3 << 8), + IOMUXG_nSS1 = (3 << 6), + IOMUXG_nSS0 = (3 << 4), + + /* PORT H */ + IOMUXH_CLKOUT1 = (2 << 20), + IOMUXH_CLKOUT0 = (2 << 18), + IOMUXH_UEXTCLK = (2 << 16), + IOMUXH_RXD2 = (2 << 14), + IOMUXH_TXD2 = (2 << 12), + IOMUXH_RXD1 = (2 << 10), + IOMUXH_TXD1 = (2 << 8), + IOMUXH_RXD0 = (2 << 6), + IOMUXH_TXD0 = (2 << 4), + IOMUXH_nRTS0 = (2 << 2), + IOMUXH_nCTS0 = 2, + IOMUXH_nCTS1 = (3 << 14), + IOMUXH_nRTS1 = (3 << 12), + + /* PORT J */ + IOMUXJ_CAMRESET = (2 << 24), + IOMUXJ_CAMCLKOUT = (2 << 22), + IOMUXJ_CAMHREF = (2 << 20), + IOMUXJ_CAMVSYNC = (2 << 18), + IOMUXJ_CAMPCLK = (2 << 16), + IOMUXJ_CAMDATA7 = (2 << 14), + IOMUXJ_CAMDATA6 = (2 << 12), + IOMUXJ_CAMDATA5 = (2 << 10), + IOMUXJ_CAMDATA4 = (2 << 8), + IOMUXJ_CAMDATA3 = (2 << 6), + IOMUXJ_CAMDATA2 = (2 << 4), + IOMUXJ_CAMDATA1 = (2 << 2), + IOMUXJ_CAMDATA0 = 2 +}; + +#endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 17f4b73..d50ac3b 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -44,6 +44,7 @@ COBJS-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o COBJS-$(CONFIG_OMAP_GPIO) += omap_gpio.o COBJS-$(CONFIG_DB8500_GPIO) += db8500_gpio.o COBJS-$(CONFIG_BCM2835_GPIO) += bcm2835_gpio.o +COBJS-$(CONFIG_S3C2440_GPIO) += s3c2440_gpio.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/gpio/s3c2440_gpio.c b/drivers/gpio/s3c2440_gpio.c new file mode 100644 index 0000000..43bbf11 --- /dev/null +++ b/drivers/gpio/s3c2440_gpio.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2012 + * Gabriel Huau + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include + +#define GPIO_INPUT 0x0 +#define GPIO_OUTPUT 0x1 + +/* 0x4 means that we want DAT and not CON register */ +#define GPIO_PORT(x) ((((x) >> 5) & 0x3) + 0x4) +#define GPIO_BIT(x) ((x) & 0x3f) + +/* + * It's how we calculate the full port address + * We have to get the number of the port + 1 (Port A is at 0x56000001 ...) + * We move it at the second digit, and finally we add 0x4 because we want + * to modify GPIO DAT and not CON + */ +#define GPIO_FULLPORT(x) (S3C24X0_GPIO_BASE | ((GPIO_PORT(gpio) + 1) << 1)) + +int gpio_set_value(unsigned gpio, int value) +{ + unsigned l = readl(GPIO_FULLPORT(gpio)); + unsigned bit; + unsigned port = GPIO_FULLPORT(gpio); + + /* + * All GPIO Port have a configuration on + * 2 bits excepted the first GPIO (A) which + * have only 1 bit of configuration. + */ + if (!GPIO_PORT(gpio)) + bit = (0x1 << GPIO_BIT(gpio)); + else + bit = (0x3 << GPIO_BIT(gpio)); + + if (value) + l |= bit; + else + l &= ~bit; + + return writel(port, l); +} + +int gpio_get_value(unsigned gpio) +{ + unsigned l = readl(GPIO_FULLPORT(gpio)); + + if (GPIO_PORT(gpio) == 0) /* PORT A */ + return (l >> GPIO_BIT(gpio)) & 0x1; + return (l >> GPIO_BIT(gpio)) & 0x3; +} + +int gpio_request(unsigned gpio, const char *label) +{ + return 0; +} + +int gpio_free(unsigned gpio) +{ + return 0; +} + +int gpio_direction_input(unsigned gpio) +{ + return writel(GPIO_FULLPORT(gpio), GPIO_INPUT << GPIO_BIT(gpio)); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + writel(GPIO_FULLPORT(gpio), GPIO_OUTPUT << GPIO_BIT(gpio)); + return gpio_set_value(gpio, value); +}