aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-s5pv210.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-s5pv210.c')
-rw-r--r--drivers/gpio/gpio-s5pv210.c345
1 files changed, 343 insertions, 2 deletions
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c
index 1ba20a7..955a0f5 100644
--- a/drivers/gpio/gpio-s5pv210.c
+++ b/drivers/gpio/gpio-s5pv210.c
@@ -14,6 +14,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/module.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
@@ -222,6 +223,174 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
.label = "MP05",
},
}, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP06(0),
+ .ngpio = S5PV210_GPIO_MP06_NR,
+ .label = "MP06",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP07(0),
+ .ngpio = S5PV210_GPIO_MP07_NR,
+ .label = "MP07",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP10(0),
+ .ngpio = S5PV210_GPIO_MP10_NR,
+ .label = "MP10",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP11(0),
+ .ngpio = S5PV210_GPIO_MP11_NR,
+ .label = "MP11",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP12(0),
+ .ngpio = S5PV210_GPIO_MP12_NR,
+ .label = "MP12",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP13(0),
+ .ngpio = S5PV210_GPIO_MP13_NR,
+ .label = "MP13",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP14(0),
+ .ngpio = S5PV210_GPIO_MP14_NR,
+ .label = "MP14",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP15(0),
+ .ngpio = S5PV210_GPIO_MP15_NR,
+ .label = "MP15",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP16(0),
+ .ngpio = S5PV210_GPIO_MP16_NR,
+ .label = "MP16",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP17(0),
+ .ngpio = S5PV210_GPIO_MP17_NR,
+ .label = "MP17",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP18(0),
+ .ngpio = S5PV210_GPIO_MP18_NR,
+ .label = "MP18",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP20(0),
+ .ngpio = S5PV210_GPIO_MP20_NR,
+ .label = "MP20",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP21(0),
+ .ngpio = S5PV210_GPIO_MP21_NR,
+ .label = "MP21",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP22(0),
+ .ngpio = S5PV210_GPIO_MP22_NR,
+ .label = "MP22",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP23(0),
+ .ngpio = S5PV210_GPIO_MP23_NR,
+ .label = "MP23",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP24(0),
+ .ngpio = S5PV210_GPIO_MP24_NR,
+ .label = "MP24",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP25(0),
+ .ngpio = S5PV210_GPIO_MP25_NR,
+ .label = "MP25",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP26(0),
+ .ngpio = S5PV210_GPIO_MP26_NR,
+ .label = "MP26",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP27(0),
+ .ngpio = S5PV210_GPIO_MP27_NR,
+ .label = "MP27",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP28(0),
+ .ngpio = S5PV210_GPIO_MP28_NR,
+ .label = "MP28",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC0(0),
+ .ngpio = S5PV210_GPIO_ETC0_NR,
+ .label = "ETC0",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC1(0),
+ .ngpio = S5PV210_GPIO_ETC1_NR,
+ .label = "ETC1",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC2(0),
+ .ngpio = S5PV210_GPIO_ETC2_NR,
+ .label = "ETC2",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_ETC4(0),
+ .ngpio = S5PV210_GPIO_ETC4_NR,
+ .label = "ETC4",
+ },
+ }, {
.base = (S5P_VA_GPIO + 0xC00),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(0),
@@ -264,7 +433,180 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
},
};
-static __init int s5pv210_gpiolib_init(void)
+/* S5PV210 machine dependent GPIO help function */
+int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if ((pin <= S5PV210_GPH3(7)) && (pin >= S5PV210_GPH0(0)))
+ return -EINVAL;
+
+ if (config > S3C_GPIO_SLP_PREV)
+ return -EINVAL;
+
+ reg = chip->base + 0x10;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(3 << shift);
+ con |= config << shift;
+ __raw_writel(con, reg);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_get_slp_cfgpin(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if ((pin <= S5PV210_GPH3(7)) && (pin >= S5PV210_GPH0(0)))
+ return -EINVAL;
+
+ reg = chip->base + 0x10;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con >>= shift;
+ con &= 0x3;
+
+ local_irq_restore(flags);
+
+ return (__force s3c_gpio_pull_t)con;
+}
+
+int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if ((pin <= S5PV210_GPH3(7)) && (pin >= S5PV210_GPH0(0)))
+ return -EINVAL;
+
+ if (config > S3C_GPIO_PULL_UP)
+ return -EINVAL;
+ reg = chip->base + 0x14;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(3 << shift);
+ con |= config << shift;
+ __raw_writel(con, reg);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c_gpio_slp_setpull_updown);
+
+int s3c_gpio_set_drvstrength(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if (config > S3C_GPIO_DRVSTR_4X)
+ return -EINVAL;
+
+ reg = chip->base + 0x0c;
+
+ offset = pin - chip->chip.base;
+ shift = offset * 2;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(3 << shift);
+ con |= config << shift;
+
+ __raw_writel(con, reg);
+#ifdef S5PC11X_ALIVEGPIO_STORE
+ con = __raw_readl(reg);
+#endif
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+int s3c_gpio_set_slewrate(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ void __iomem *reg;
+ unsigned long flags;
+ int offset;
+ u32 con;
+ int shift;
+
+ if (!chip)
+ return -EINVAL;
+
+ if (config > S3C_GPIO_SLEWRATE_SLOW)
+ return -EINVAL;
+
+ reg = chip->base + 0x0c;
+
+ offset = pin - chip->chip.base;
+ shift = offset;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(reg);
+ con &= ~(1 << shift);
+ con |= config << shift;
+
+ __raw_writel(con, reg);
+#ifdef S5PC11X_ALIVEGPIO_STORE
+ con = __raw_readl(reg);
+#endif
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+__init int s5pv210_gpiolib_init(void)
{
struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
@@ -285,4 +627,3 @@ static __init int s5pv210_gpiolib_init(void)
return 0;
}
-core_initcall(s5pv210_gpiolib_init);