From 5b323c7beb1b10b137f9e21981050319d89d55dd Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 31 Oct 2008 16:14:28 +0000 Subject: [ARM] S3C: Move HSMMC device definition to plat-s3ec Move the definition for the hsmmc device to plat-s3c to be shared between the s3c24xx and s3c64xx platforms. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm/plat-s3c/Kconfig') diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 6fa261a3d405..0deb1054975f 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -102,3 +102,11 @@ config S3C_LOWLEVEL_UART_PORT such as the `Uncompressing...` at start time. The value of this configuration should be between zero and two. The port must have been initialised by the boot-loader before use. + +# device definitions to compile in + +config S3C_DEV_HSMMC + bool + depends on PLAT_S3C + help + Compile in platform device definitions for HSMMC code -- cgit v1.2.3 From efd3a8eb150e383305c36eedc78c29cab910158e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 31 Oct 2008 16:14:30 +0000 Subject: [ARM] S3C64XX: Add gpio bank numbering Define the gpio numbers for the S3C64XX GPIO banks available on the S3C6400 and S3C6410. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c6400/include/mach/gpio.h | 72 ++++++++++++++++++++++++++++++- arch/arm/plat-s3c/Kconfig | 11 +++++ 2 files changed, 82 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-s3c/Kconfig') diff --git a/arch/arm/mach-s3c6400/include/mach/gpio.h b/arch/arm/mach-s3c6400/include/mach/gpio.h index 8b4254a23d9a..8600c818a46f 100644 --- a/arch/arm/mach-s3c6400/include/mach/gpio.h +++ b/arch/arm/mach-s3c6400/include/mach/gpio.h @@ -17,6 +17,76 @@ #define gpio_cansleep __gpio_cansleep #define gpio_to_irq __gpio_to_irq -#define ARCH_NR_GPIOS 188 +/* GPIO bank sizes */ +#define S3C64XX_GPIO_A_NR (8) +#define S3C64XX_GPIO_B_NR (7) +#define S3C64XX_GPIO_C_NR (8) +#define S3C64XX_GPIO_D_NR (5) +#define S3C64XX_GPIO_E_NR (5) +#define S3C64XX_GPIO_F_NR (16) +#define S3C64XX_GPIO_G_NR (7) +#define S3C64XX_GPIO_H_NR (10) +#define S3C64XX_GPIO_I_NR (16) +#define S3C64XX_GPIO_J_NR (12) +#define S3C64XX_GPIO_K_NR (16) +#define S3C64XX_GPIO_L_NR (15) +#define S3C64XX_GPIO_M_NR (6) +#define S3C64XX_GPIO_N_NR (16) +#define S3C64XX_GPIO_O_NR (16) +#define S3C64XX_GPIO_P_NR (15) +#define S3C64XX_GPIO_Q_NR (9) + +/* GPIO bank numbes */ + +/* CONFIG_S3C_GPIO_SPACE allows the user to select extra + * space for debugging purposes so that any accidental + * change from one gpio bank to another can be caught. +*/ + +#define S3C64XX_GPIO_NEXT(__gpio) \ + ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) + +enum s3c_gpio_number { + S3C64XX_GPIO_A_START = 0, + S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A), + S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B), + S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C), + S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D), + S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E), + S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F), + S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G), + S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H), + S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I), + S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J), + S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K), + S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L), + S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M), + S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N), + S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O), + S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P), +}; + +/* S3C64XX GPIO number definitions. */ + +#define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr)) +#define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr)) +#define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr)) +#define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr)) +#define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr)) +#define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr)) +#define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr)) +#define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr)) +#define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr)) +#define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr)) +#define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr)) +#define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr)) +#define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr)) +#define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr)) +#define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr)) +#define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr)) +#define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr)) + +/* define the number of gpios we need to the one after the GPQ() range */ +#define ARCH_NR_GPIOS (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) #include diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 0deb1054975f..d7767e0305d0 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -103,6 +103,17 @@ config S3C_LOWLEVEL_UART_PORT this configuration should be between zero and two. The port must have been initialised by the boot-loader before use. +# options for gpiolib support + +config S3C_GPIO_SPACE + int "Space between gpio banks" + default 0 + help + Add a number of spare GPIO entries between each bank for debugging + purposes. This allows any problems where an counter overflows from + one bank to another to be caught, at the expense of using a little + more memory. + # device definitions to compile in config S3C_DEV_HSMMC -- cgit v1.2.3 From 8a53bdb907cb924ed30f79bcfe7f4f15ff7de15e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 31 Oct 2008 16:14:32 +0000 Subject: [ARM] S3C: Add GPIO chip tracking The gpiolib driver keeps its chip array to itself and having a separate array for s3c-only gpios stops any non-s3c gpio being used in one of the s3c specific configuration calls. Signed-off-by: Ben Dooks --- arch/arm/plat-s3c/Kconfig | 6 ++++++ arch/arm/plat-s3c/gpio.c | 21 ++++++++++++++++++++- arch/arm/plat-s3c/include/plat/gpio-core.h | 23 +++++++++++++++++++++++ arch/arm/plat-s3c64xx/Kconfig | 1 + 4 files changed, 50 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-s3c/Kconfig') diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index d7767e0305d0..77fc38f51874 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -114,6 +114,12 @@ config S3C_GPIO_SPACE one bank to another to be caught, at the expense of using a little more memory. +config S3C_GPIO_TRACK + bool + help + Internal configuration option to enable the s3c specific gpio + chip tracking if the platform requires it. + # device definitions to compile in config S3C_DEV_HSMMC diff --git a/arch/arm/plat-s3c/gpio.c b/arch/arm/plat-s3c/gpio.c index f035d4550c43..d71dd6d9ce5c 100644 --- a/arch/arm/plat-s3c/gpio.c +++ b/arch/arm/plat-s3c/gpio.c @@ -18,6 +18,22 @@ #include +#ifdef CONFIG_S3C_GPIO_TRACK +struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; + +static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip) +{ + unsigned int gpn; + int i; + + gpn = chip->chip.base; + for (i = 0; i < chip->chip.ngpio; i++, gpn++) { + BUG_ON(gpn > ARRAY_SIZE(s3c_gpios)); + s3c_gpios[gpn] = chip; + } +} +#endif /* CONFIG_S3C_GPIO_TRACK */ + /* Default routines for controlling GPIO, based on the original S3C24XX * GPIO functions which deal with the case where each gpio bank of the * chip is as following: @@ -109,6 +125,7 @@ static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset) __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) { struct gpio_chip *gc = &chip->chip; + int ret; BUG_ON(!chip->base); BUG_ON(!gc->label); @@ -124,5 +141,7 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) gc->get = s3c_gpiolib_get; /* gpiochip_add() prints own failure message on error. */ - gpiochip_add(gc); + ret = gpiochip_add(gc); + if (ret >= 0) + s3c_gpiolib_track(chip); } diff --git a/arch/arm/plat-s3c/include/plat/gpio-core.h b/arch/arm/plat-s3c/include/plat/gpio-core.h index 3cb9105c4811..ad68b32a7f9d 100644 --- a/arch/arm/plat-s3c/include/plat/gpio-core.h +++ b/arch/arm/plat-s3c/include/plat/gpio-core.h @@ -47,3 +47,26 @@ static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc) * other parts of the system. */ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip); + + +/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios + * for use with the configuration calls, and other parts of the s3c gpiolib + * support code. + * + * Not all s3c support code will need this, as some configurations of cpu + * may only support one or two different configuration options and have an + * easy gpio to s3c_gpio_chip mapping function. If this is the case, then + * the machine support file should provide its own s3c_gpiolib_getchip() + * and any other necessary functions. + */ + +#ifdef CONFIG_S3C_GPIO_TRACK +extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; + +static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) +{ + return s3c_gpios[chip]; +} +#else +static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } +#endif diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig index bd832ba0cf77..3df2ec19d08a 100644 --- a/arch/arm/plat-s3c64xx/Kconfig +++ b/arch/arm/plat-s3c64xx/Kconfig @@ -14,6 +14,7 @@ config PLAT_S3C64XX default y select NO_IOPORT select ARCH_REQUIRE_GPIOLIB + select S3C_GPIO_TRACK help Base platform code for any Samsung S3C64XX device -- cgit v1.2.3 From 21b23664b9354c5449841e401efb9ad523fb898b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 31 Oct 2008 16:14:34 +0000 Subject: [ARM] S3C: Add new GPIO configuration calls Add new GPIO configuration calls that mesh with the new gpiolib support. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2410/include/mach/gpio-core.h | 34 +++++ arch/arm/mach-s3c6400/include/mach/gpio-core.h | 21 +++ arch/arm/plat-s3c/Kconfig | 27 ++++ arch/arm/plat-s3c/Makefile | 1 + arch/arm/plat-s3c/gpio-config.c | 163 ++++++++++++++++++++ arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h | 176 ++++++++++++++++++++++ arch/arm/plat-s3c/include/plat/gpio-cfg.h | 110 ++++++++++++++ arch/arm/plat-s3c/include/plat/gpio-core.h | 9 +- arch/arm/plat-s3c24xx/gpiolib.c | 6 +- arch/arm/plat-s3c64xx/Kconfig | 3 + arch/arm/plat-s3c64xx/gpiolib.c | 75 ++++++++- 11 files changed, 619 insertions(+), 6 deletions(-) create mode 100644 arch/arm/mach-s3c2410/include/mach/gpio-core.h create mode 100644 arch/arm/mach-s3c6400/include/mach/gpio-core.h create mode 100644 arch/arm/plat-s3c/gpio-config.c create mode 100644 arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h create mode 100644 arch/arm/plat-s3c/include/plat/gpio-cfg.h (limited to 'arch/arm/plat-s3c/Kconfig') diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-core.h b/arch/arm/mach-s3c2410/include/mach/gpio-core.h new file mode 100644 index 000000000000..6c9fbb99ef14 --- /dev/null +++ b/arch/arm/mach-s3c2410/include/mach/gpio-core.h @@ -0,0 +1,34 @@ +/* arch/arm/mach-s3c24100/include/mach/gpio-core.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C2410 - GPIO core 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. +*/ + +#ifndef __ASM_ARCH_GPIO_CORE_H +#define __ASM_ARCH_GPIO_CORE_H __FILE__ + +#include +#include + +extern struct s3c_gpio_chip s3c24xx_gpios[]; + +static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin) +{ + struct s3c_gpio_chip *chip; + + if (pin > S3C2410_GPG10) + return NULL; + + chip = &s3c24xx_gpios[pin/32]; + return (S3C2410_GPIO_OFFSET(pin) > chip->chip.ngpio) ? chip : NULL; +} + +#endif /* __ASM_ARCH_GPIO_CORE_H */ diff --git a/arch/arm/mach-s3c6400/include/mach/gpio-core.h b/arch/arm/mach-s3c6400/include/mach/gpio-core.h new file mode 100644 index 000000000000..d89aae68b0a5 --- /dev/null +++ b/arch/arm/mach-s3c6400/include/mach/gpio-core.h @@ -0,0 +1,21 @@ +/* arch/arm/mach-s3c6400/include/mach/gpio-core.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C64XX - GPIO core 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. +*/ + +#ifndef __ASM_ARCH_GPIO_CORE_H +#define __ASM_ARCH_GPIO_CORE_H __FILE__ + +/* currently we just include the platform support */ +#include + +#endif /* __ASM_ARCH_GPIO_CORE_H */ diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 77fc38f51874..45e62cba595c 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -120,6 +120,33 @@ config S3C_GPIO_TRACK Internal configuration option to enable the s3c specific gpio chip tracking if the platform requires it. +config S3C_GPIO_PULL_UPDOWN + bool + help + Internal configuration to enable the correct GPIO pull helper + +config S3C_GPIO_PULL_DOWN + bool + help + Internal configuration to enable the correct GPIO pull helper + +config S3C_GPIO_PULL_UP + bool + help + Internal configuration to enable the correct GPIO pull helper + +config S3C_GPIO_CFG_S3C24XX + bool + help + Internal configuration to enable S3C24XX style GPIO configuration + functions. + +config S3C_GPIO_CFG_S3C64XX + bool + help + Internal configuration to enable S3C64XX style GPIO configuration + functions. + # device definitions to compile in config S3C_DEV_HSMMC diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index 4d0299aef7ca..68a3451a2d9d 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile @@ -16,6 +16,7 @@ obj-y += time.o obj-y += clock.o obj-y += pwm-clock.o obj-y += gpio.o +obj-y += gpio-config.o # devices diff --git a/arch/arm/plat-s3c/gpio-config.c b/arch/arm/plat-s3c/gpio-config.c new file mode 100644 index 000000000000..7642b975a998 --- /dev/null +++ b/arch/arm/plat-s3c/gpio-config.c @@ -0,0 +1,163 @@ +/* linux/arch/arm/plat-s3c/gpio-config.c + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C series GPIO configuration core + * + * 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 + +int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) +{ + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); + unsigned long flags; + int offset; + int ret; + + if (!chip) + return -EINVAL; + + offset = pin - chip->chip.base; + + local_irq_save(flags); + ret = s3c_gpio_do_setcfg(chip, offset, config); + local_irq_restore(flags); + + return ret; +} + +int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) +{ + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); + unsigned long flags; + int offset, ret; + + if (!chip) + return -EINVAL; + + offset = pin - chip->chip.base; + + local_irq_save(flags); + ret = s3c_gpio_do_setpull(chip, offset, pull); + local_irq_restore(flags); + + return ret; +} + +#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX +int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg) +{ + void __iomem *reg = chip->base; + unsigned int shift = off; + u32 con; + + if (s3c_gpio_is_cfg_special(cfg)) { + cfg &= 0xf; + + /* Map output to 0, and SFN2 to 1 */ + cfg -= 1; + if (cfg > 1) + return -EINVAL; + + cfg <<= shift; + } + + con = __raw_readl(reg); + con &= ~(0x1 << shift); + con |= cfg; + __raw_writel(con, reg); + + return 0; +} + +int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg) +{ + void __iomem *reg = chip->base; + unsigned int shift = off * 2; + u32 con; + + if (s3c_gpio_is_cfg_special(cfg)) { + cfg &= 0xf; + if (cfg > 3) + return -EINVAL; + + cfg <<= shift; + } + + con = __raw_readl(reg); + con &= ~(0x3 << shift); + con |= cfg; + __raw_writel(con, reg); + + return 0; +} +#endif + +#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX +int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg) +{ + void __iomem *reg = chip->base; + unsigned int shift = (off & 7) * 4; + u32 con; + + if (off < 8 && chip->chip.ngpio >= 8) + reg -= 4; + + if (s3c_gpio_is_cfg_special(cfg)) { + cfg &= 0xf; + cfg <<= shift; + } + + con = __raw_readl(reg); + con &= ~(0xf << shift); + con |= cfg; + __raw_writel(con, reg); + + return 0; +} +#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ + +#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN +int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull) +{ + void __iomem *reg = chip->base + 0x08; + int shift = off * 2; + u32 pup; + + pup = __raw_readl(reg); + pup &= ~(3 << shift); + pup |= pull << shift; + __raw_writel(pup, reg); + + return 0; +} + +s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, + unsigned int off) +{ + void __iomem *reg = chip->base + 0x08; + int shift = off * 2; + u32 pup = __raw_readl(reg); + + pup >>= shift; + pup &= 0x3; + return (__force s3c_gpio_pull_t)pup; +} +#endif diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h new file mode 100644 index 000000000000..652e2bbdaa20 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/gpio-cfg-helpers.h @@ -0,0 +1,176 @@ +/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C Platform - GPIO pin configuration helper definitions + * + * 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. +*/ + +/* This is meant for core cpu support, machine or other driver files + * should not be including this header. + */ + +#ifndef __PLAT_GPIO_CFG_HELPERS_H +#define __PLAT_GPIO_CFG_HELPERS_H __FILE__ + +/* As a note, all gpio configuration functions are entered exclusively, either + * with the relevant lock held or the system prevented from doing anything else + * by disabling interrupts. +*/ + +static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int config) +{ + return (chip->config->set_config)(chip, off, config); +} + +static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull) +{ + return (chip->config->set_pull)(chip, off, pull); +} + +/** + * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @cfg: The configuration value to set. + * + * This helper deal with the GPIO cases where the control register + * has two bits of configuration per gpio, which have the following + * functions: + * 00 = input + * 01 = output + * 1x = special function +*/ +extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg); + +/** + * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A) + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @cfg: The configuration value to set. + * + * This helper deal with the GPIO cases where the control register + * has one bit of configuration for the gpio, where setting the bit + * means the pin is in special function mode and unset means output. +*/ +extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg); + +/** + * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @cfg: The configuration value to set. + * + * This helper deal with the GPIO cases where the control register has 4 bits + * of control per GPIO, generally in the form of: + * 0000 = Input + * 0001 = Output + * others = Special functions (dependant on bank) + * + * Note, since the code to deal with the case where there are two control + * registers instead of one, we do not have a seperate set of functions for + * each case. +*/ +extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, + unsigned int off, unsigned int cfg); + + +/* Pull-{up,down} resistor controls. + * + * S3C2410,S3C2440,S3C24A0 = Pull-UP, + * S3C2412,S3C2413 = Pull-Down + * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef] + * S3C2443 = Pull-Both [not same as S3C6400] + */ + +/** + * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @param: pull: The pull mode being requested. + * + * This is a helper function for the case where we have GPIOs with one + * bit configuring the presence of a pull-up resistor. + */ +extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull); + +/** + * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none + * @chip: The gpio chip that is being configured + * @off: The offset for the GPIO being configured + * @param: pull: The pull mode being requested + * + * This is a helper function for the case where we have GPIOs with one + * bit configuring the presence of a pull-down resistor. + */ +extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull); + +/** + * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @param: pull: The pull mode being requested. + * + * This is a helper function for the case where we have GPIOs with two + * bits configuring the presence of a pull resistor, in the following + * order: + * 00 = No pull resistor connected + * 01 = Pull-up resistor connected + * 10 = Pull-down resistor connected + */ +extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull); + + +/** + * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none + * @chip: The gpio chip that the GPIO pin belongs to + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-{up,down} resistor for the + * given GPIO in the same case as s3c_gpio_setpull_upown. +*/ +extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, + unsigned int off); + +/** + * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. + * @chip: The gpio chip that is being configured. + * @off: The offset for the GPIO being configured. + * @param: pull: The pull mode being requested. + * + * This is a helper function for the case where we have GPIOs with two + * bits configuring the presence of a pull resistor, in the following + * order: + * 00 = Pull-up resistor connected + * 10 = Pull-down resistor connected + * x1 = No pull up resistor + */ +extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull); + +/** + * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors + * @chip: The gpio chip that the GPIO pin belongs to. + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-{up,down} resistor for the + * given GPIO in the same case as s3c_gpio_setpull_upown. +*/ +extern s3c_gpio_pull_t s3c_gpio_getpull_s3c24xx(struct s3c_gpio_chip *chip, + unsigned int off); + +#endif /* __PLAT_GPIO_CFG_HELPERS_H */ + diff --git a/arch/arm/plat-s3c/include/plat/gpio-cfg.h b/arch/arm/plat-s3c/include/plat/gpio-cfg.h new file mode 100644 index 000000000000..29cd6a86cade --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/gpio-cfg.h @@ -0,0 +1,110 @@ +/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C Platform - GPIO pin configuration + * + * 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. +*/ + +/* This file contains the necessary definitions to get the basic gpio + * pin configuration done such as setting a pin to input or output or + * changing the pull-{up,down} configurations. + */ + +/* Note, this interface is being added to the s3c64xx arch first and will + * be added to the s3c24xx systems later. + */ + +#ifndef __PLAT_GPIO_CFG_H +#define __PLAT_GPIO_CFG_H __FILE__ + +typedef unsigned int __bitwise__ s3c_gpio_pull_t; + +/* forward declaration if gpio-core.h hasn't been included */ +struct s3c_gpio_chip; + +/** + * struct s3c_gpio_cfg GPIO configuration + * @cfg_eint: Configuration setting when used for external interrupt source + * @get_pull: Read the current pull configuration for the GPIO + * @set_pull: Set the current pull configuraiton for the GPIO + * @set_config: Set the current configuration for the GPIO + * @get_config: Read the current configuration for the GPIO + * + * Each chip can have more than one type of GPIO bank available and some + * have different capabilites even when they have the same control register + * layouts. Provide an point to vector control routine and provide any + * per-bank configuration information that other systems such as the + * external interrupt code will need. + */ +struct s3c_gpio_cfg { + unsigned int cfg_eint; + + s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs); + int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs, + s3c_gpio_pull_t pull); + + unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs); + int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs, + unsigned config); +}; + +#define S3C_GPIO_SPECIAL_MARK (0xfffffff0) +#define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x)) + +/* Defines for generic pin configurations */ +#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0)) +#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) +#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) + +#define s3c_gpio_is_cfg_special(_cfg) \ + (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK) + +/** + * s3c_gpio_cfgpin() - Change the GPIO function of a pin. + * @pin pin The pin number to configure. + * @pin to The configuration for the pin's function. + * + * Configure which function is actually connected to the external + * pin, such as an gpio input, output or some form of special function + * connected to an internal peripheral block. + */ +extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); + +/* Define values for the pull-{up,down} available for each gpio pin. + * + * These values control the state of the weak pull-{up,down} resistors + * available on most pins on the S3C series. Not all chips support both + * up or down settings, and it may be dependant on the chip that is being + * used to whether the particular mode is available. + */ +#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) +#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) +#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) + +/** + * s3c_gpio_setpull() - set the state of a gpio pin pull resistor + * @pin: The pin number to configure the pull resistor. + * @pull: The configuration for the pull resistor. + * + * This function sets the state of the pull-{up,down} resistor for the + * specified pin. It will return 0 if successfull, or a negative error + * code if the pin cannot support the requested pull setting. +*/ +extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); + +/** + * s3c_gpio_getpull() - get the pull resistor state of a gpio pin + * @pin: The pin number to get the settings for + * + * Read the pull resistor value for the specified pin. +*/ +extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); + +#endif /* __PLAT_GPIO_CFG_H */ diff --git a/arch/arm/plat-s3c/include/plat/gpio-core.h b/arch/arm/plat-s3c/include/plat/gpio-core.h index ad68b32a7f9d..2fc60a580ac8 100644 --- a/arch/arm/plat-s3c/include/plat/gpio-core.h +++ b/arch/arm/plat-s3c/include/plat/gpio-core.h @@ -20,16 +20,20 @@ * specific code. */ +struct s3c_gpio_cfg; + /** * struct s3c_gpio_chip - wrapper for specific implementation of gpio * @chip: The chip structure to be exported via gpiolib. * @base: The base pointer to the gpio configuration registers. + * @config: special function and pull-resistor control information. * * This wrapper provides the necessary information for the Samsung * specific gpios being registered with gpiolib. */ struct s3c_gpio_chip { struct gpio_chip chip; + struct s3c_gpio_cfg *config; void __iomem *base; }; @@ -48,7 +52,6 @@ static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc) */ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip); - /* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios * for use with the configuration calls, and other parts of the s3c gpiolib * support code. @@ -65,8 +68,10 @@ extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END]; static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) { - return s3c_gpios[chip]; + return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL; } #else +/* machine specific code should provide s3c_gpiolib_getchip */ + static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } #endif diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 9785a8fb4809..f95c6c9d9f1a 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -59,7 +59,7 @@ static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, return 0; } -static struct s3c_gpio_chip gpios[] = { +struct s3c_gpio_chip s3c24xx_gpios[] = { [0] = { .base = S3C24XX_GPIO_BASE(S3C2410_GPA0), .chip = { @@ -129,10 +129,10 @@ static struct s3c_gpio_chip gpios[] = { static __init int s3c24xx_gpiolib_init(void) { - struct s3c_gpio_chip *chip = gpios; + struct s3c_gpio_chip *chip = s3c24xx_gpios; int gpn; - for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++) + for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) s3c_gpiolib_add(chip); return 0; diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig index 3df2ec19d08a..842200abeb36 100644 --- a/arch/arm/plat-s3c64xx/Kconfig +++ b/arch/arm/plat-s3c64xx/Kconfig @@ -15,6 +15,9 @@ config PLAT_S3C64XX select NO_IOPORT select ARCH_REQUIRE_GPIOLIB select S3C_GPIO_TRACK + select S3C_GPIO_PULL_UPDOWN + select S3C_GPIO_CFG_S3C24XX + select S3C_GPIO_CFG_S3C64XX help Base platform code for any Samsung S3C64XX device diff --git a/arch/arm/plat-s3c64xx/gpiolib.c b/arch/arm/plat-s3c64xx/gpiolib.c index 28ba23502bce..cc62941d7b5c 100644 --- a/arch/arm/plat-s3c64xx/gpiolib.c +++ b/arch/arm/plat-s3c64xx/gpiolib.c @@ -18,8 +18,10 @@ #include #include +#include -#include +#include +#include #include /* GPIO bank summary: @@ -52,6 +54,12 @@ #define con_4bit_shift(__off) ((__off) * 4) +#if 1 +#define gpio_dbg(x...) do { } while(0) +#else +#define gpio_dbg(x...) printk(KERN_DEBUG ## x) +#endif + /* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the * following example: @@ -77,6 +85,8 @@ static int s3c64xx_gpiolib_4bit_input(struct gpio_chip *chip, unsigned offset) con &= ~(0xf << con_4bit_shift(offset)); __raw_writel(con, base + OFF_GPCON); + gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); + return 0; } @@ -102,6 +112,8 @@ static int s3c64xx_gpiolib_4bit_output(struct gpio_chip *chip, __raw_writel(con, base + OFF_GPCON); __raw_writel(dat, base + OFF_GPDAT); + gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); + return 0; } @@ -142,6 +154,8 @@ static int s3c64xx_gpiolib_4bit2_input(struct gpio_chip *chip, unsigned offset) con &= ~(0xf << con_4bit_shift(offset)); __raw_writel(con, regcon); + gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); + return 0; } @@ -174,12 +188,35 @@ static int s3c64xx_gpiolib_4bit2_output(struct gpio_chip *chip, __raw_writel(con, regcon); __raw_writel(dat, base + OFF_GPDAT); + gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); + return 0; } +static struct s3c_gpio_cfg gpio_4bit_cfg_noint = { + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = { + .cfg_eint = 7, + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = { + .cfg_eint = 3, + .set_config = s3c_gpio_setcfg_s3c64xx_4bit, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + static struct s3c_gpio_chip gpio_4bit[] = { { .base = S3C64XX_GPA_BASE, + .config = &gpio_4bit_cfg_eint0111, .chip = { .base = S3C64XX_GPA(0), .ngpio = S3C64XX_GPIO_A_NR, @@ -187,6 +224,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { }, }, { .base = S3C64XX_GPB_BASE, + .config = &gpio_4bit_cfg_eint0111, .chip = { .base = S3C64XX_GPB(0), .ngpio = S3C64XX_GPIO_B_NR, @@ -194,6 +232,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { }, }, { .base = S3C64XX_GPC_BASE, + .config = &gpio_4bit_cfg_eint0111, .chip = { .base = S3C64XX_GPC(0), .ngpio = S3C64XX_GPIO_C_NR, @@ -201,6 +240,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { }, }, { .base = S3C64XX_GPD_BASE, + .config = &gpio_4bit_cfg_eint0111, .chip = { .base = S3C64XX_GPD(0), .ngpio = S3C64XX_GPIO_D_NR, @@ -208,6 +248,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { }, }, { .base = S3C64XX_GPE_BASE, + .config = &gpio_4bit_cfg_noint, .chip = { .base = S3C64XX_GPE(0), .ngpio = S3C64XX_GPIO_E_NR, @@ -215,6 +256,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { }, }, { .base = S3C64XX_GPG_BASE, + .config = &gpio_4bit_cfg_eint0111, .chip = { .base = S3C64XX_GPG(0), .ngpio = S3C64XX_GPIO_G_NR, @@ -222,6 +264,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { }, }, { .base = S3C64XX_GPM_BASE, + .config = &gpio_4bit_cfg_eint0011, .chip = { .base = S3C64XX_GPM(0), .ngpio = S3C64XX_GPIO_M_NR, @@ -233,6 +276,7 @@ static struct s3c_gpio_chip gpio_4bit[] = { static struct s3c_gpio_chip gpio_4bit2[] = { { .base = S3C64XX_GPH_BASE + 0x4, + .config = &gpio_4bit_cfg_eint0111, .chip = { .base = S3C64XX_GPH(0), .ngpio = S3C64XX_GPIO_H_NR, @@ -240,6 +284,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = { }, }, { .base = S3C64XX_GPK_BASE + 0x4, + .config = &gpio_4bit_cfg_noint, .chip = { .base = S3C64XX_GPK(0), .ngpio = S3C64XX_GPIO_K_NR, @@ -247,6 +292,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = { }, }, { .base = S3C64XX_GPL_BASE + 0x4, + .config = &gpio_4bit_cfg_eint0011, .chip = { .base = S3C64XX_GPL(0), .ngpio = S3C64XX_GPIO_L_NR, @@ -255,9 +301,30 @@ static struct s3c_gpio_chip gpio_4bit2[] = { }, }; +static struct s3c_gpio_cfg gpio_2bit_cfg_noint = { + .set_config = s3c_gpio_setcfg_s3c24xx, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = { + .cfg_eint = 2, + .set_config = s3c_gpio_setcfg_s3c24xx, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + +static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = { + .cfg_eint = 3, + .set_config = s3c_gpio_setcfg_s3c24xx, + .set_pull = s3c_gpio_setpull_updown, + .get_pull = s3c_gpio_getpull_updown, +}; + static struct s3c_gpio_chip gpio_2bit[] = { { .base = S3C64XX_GPF_BASE, + .config = &gpio_2bit_cfg_eint11, .chip = { .base = S3C64XX_GPF(0), .ngpio = S3C64XX_GPIO_F_NR, @@ -265,6 +332,7 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }, { .base = S3C64XX_GPI_BASE, + .config = &gpio_2bit_cfg_noint, .chip = { .base = S3C64XX_GPI(0), .ngpio = S3C64XX_GPIO_I_NR, @@ -272,6 +340,7 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }, { .base = S3C64XX_GPJ_BASE, + .config = &gpio_2bit_cfg_noint, .chip = { .base = S3C64XX_GPJ(0), .ngpio = S3C64XX_GPIO_J_NR, @@ -279,6 +348,7 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }, { .base = S3C64XX_GPN_BASE, + .config = &gpio_2bit_cfg_eint10, .chip = { .base = S3C64XX_GPN(0), .ngpio = S3C64XX_GPIO_N_NR, @@ -286,6 +356,7 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }, { .base = S3C64XX_GPO_BASE, + .config = &gpio_2bit_cfg_eint11, .chip = { .base = S3C64XX_GPO(0), .ngpio = S3C64XX_GPIO_O_NR, @@ -293,6 +364,7 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }, { .base = S3C64XX_GPP_BASE, + .config = &gpio_2bit_cfg_eint11, .chip = { .base = S3C64XX_GPP(0), .ngpio = S3C64XX_GPIO_P_NR, @@ -300,6 +372,7 @@ static struct s3c_gpio_chip gpio_2bit[] = { }, }, { .base = S3C64XX_GPQ_BASE, + .config = &gpio_2bit_cfg_eint11, .chip = { .base = S3C64XX_GPQ(0), .ngpio = S3C64XX_GPIO_Q_NR, -- cgit v1.2.3 From a2205cd2cbfb8fb217e6036f08773a09d1b6d75e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 31 Oct 2008 16:14:39 +0000 Subject: [ARM] S3C: Add SDHCI (HSMMC) channel 1 device definition Add device definition and support code for the Samsung HSMMC channel 1 device. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c6410/cpu.c | 1 + arch/arm/plat-s3c/Kconfig | 6 +++ arch/arm/plat-s3c/Makefile | 1 + arch/arm/plat-s3c/dev-hsmmc1.c | 68 ++++++++++++++++++++++++++++++++++ arch/arm/plat-s3c/include/plat/sdhci.h | 14 ++++++- 5 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-s3c/dev-hsmmc1.c (limited to 'arch/arm/plat-s3c/Kconfig') diff --git a/arch/arm/mach-s3c6410/cpu.c b/arch/arm/mach-s3c6410/cpu.c index 84fb65b59999..137918e7711f 100644 --- a/arch/arm/mach-s3c6410/cpu.c +++ b/arch/arm/mach-s3c6410/cpu.c @@ -55,6 +55,7 @@ void __init s3c6410_map_io(void) /* initialise device information early */ s3c6410_default_sdhci0(); + s3c6410_default_sdhci1(); } void __init s3c6410_init_clocks(int xtal) diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 45e62cba595c..e6e64968a611 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -154,3 +154,9 @@ config S3C_DEV_HSMMC depends on PLAT_S3C help Compile in platform device definitions for HSMMC code + +config S3C_DEV_HSMMC1 + bool + depends on PLAT_S3C + help + Compile in platform device definitions for HSMMC channel 1 diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index 68a3451a2d9d..3f6544a95fe8 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile @@ -21,3 +21,4 @@ obj-y += gpio-config.o # devices obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o +obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o diff --git a/arch/arm/plat-s3c/dev-hsmmc1.c b/arch/arm/plat-s3c/dev-hsmmc1.c new file mode 100644 index 000000000000..e49bc4cd0ee6 --- /dev/null +++ b/arch/arm/plat-s3c/dev-hsmmc1.c @@ -0,0 +1,68 @@ +/* linux/arch/arm/plat-s3c/dev-hsmmc1.c + * + * Copyright (c) 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C series device definition for hsmmc device 1 + * + * 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 + +#define S3C_SZ_HSMMC (0x1000) + +static struct resource s3c_hsmmc1_resource[] = { + [0] = { + .start = S3C_PA_HSMMC1, + .end = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_HSMMC1, + .end = IRQ_HSMMC1, + .flags = IORESOURCE_IRQ, + } +}; + +static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL; + +struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { + .max_width = 4, + .host_caps = (MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +}; + +struct platform_device s3c_device_hsmmc1 = { + .name = "s3c-sdhci", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), + .resource = s3c_hsmmc1_resource, + .dev = { + .dma_mask = &s3c_device_hsmmc1_dmamask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &s3c_hsmmc1_def_platdata, + }, +}; + +void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) +{ + struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; + + set->max_width = pd->max_width; + + if (pd->cfg_gpio) + set->cfg_gpio = pd->cfg_gpio; + if (pd->cfg_card) + set->cfg_card = pd->cfg_card; +} diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-s3c/include/plat/sdhci.h index c9999121b4bb..5aeebeb70dc2 100644 --- a/arch/arm/plat-s3c/include/plat/sdhci.h +++ b/arch/arm/plat-s3c/include/plat/sdhci.h @@ -56,12 +56,14 @@ struct s3c_sdhci_platdata { * make the structure itself __initdata. */ extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd); +extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd); /* Default platform data, exported so that per-cpu initialisation can * set the correct one when there are more than one cpu type selected. */ -extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platata; +extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata; +extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata; /* Helper function availablity */ @@ -69,6 +71,8 @@ extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platata; extern char *s3c6410_hsmmc_clksrcs[4]; extern void s3c6410_setup_sdhci0_cfg_gpio(struct platform_device *, int w); +extern void s3c6410_setup_sdhci1_cfg_gpio(struct platform_device *, int w); + extern void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev, void __iomem *r, struct mmc_ios *ios, @@ -80,8 +84,16 @@ static inline void s3c6410_default_sdhci0(void) s3c_hsmmc0_def_platdata.cfg_gpio = s3c6410_setup_sdhci0_cfg_gpio; s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card; } + +static inline void s3c6410_default_sdhci1(void) +{ + s3c_hsmmc1_def_platdata.clocks = s3c6410_hsmmc_clksrcs; + s3c_hsmmc1_def_platdata.cfg_gpio = s3c6410_setup_sdhci0_cfg_gpio; + s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card; +} #else static inline void s3c6410_default_sdhci0(void) { } +static inline void s3c6410_default_sdhci1(void) { } #endif /* CONFIG_S3C6410_SETUP_SDHCI */ #endif /* __PLAT_S3C_SDHCI_H */ -- cgit v1.2.3 From 1aba834da12989bb769d1dcbf6b0ea29f730c92c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 31 Oct 2008 16:14:55 +0000 Subject: [ARM] S3C: Add i2c1 device definition Add device definition and support functions for the second i2c device (i2c1). If this is selected, the first i2c bus will become index 0 instead of index -1. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c6400/include/mach/map.h | 2 + arch/arm/plat-s3c/Kconfig | 6 +++ arch/arm/plat-s3c/Makefile | 1 + arch/arm/plat-s3c/dev-i2c0.c | 8 +++- arch/arm/plat-s3c/dev-i2c1.c | 68 +++++++++++++++++++++++++++++++ arch/arm/plat-s3c/include/plat/devs.h | 1 + arch/arm/plat-s3c/include/plat/iic.h | 2 + arch/arm/plat-s3c64xx/include/plat/irqs.h | 5 +++ 8 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 arch/arm/plat-s3c/dev-i2c1.c (limited to 'arch/arm/plat-s3c/Kconfig') diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h index f0d6fa616b6c..4d5cd7ee8c15 100644 --- a/arch/arm/mach-s3c6400/include/mach/map.h +++ b/arch/arm/mach-s3c6400/include/mach/map.h @@ -41,6 +41,7 @@ #define S3C64XX_PA_SYSCON (0x7E00F000) #define S3C64XX_PA_TIMER (0x7F006000) #define S3C64XX_PA_IIC0 (0x7F004000) +#define S3C64XX_PA_IIC1 (0x7F00F000) #define S3C64XX_PA_GPIO (0x7F008000) #define S3C64XX_VA_GPIO S3C_ADDR(0x00500000) @@ -60,5 +61,6 @@ #define S3C_PA_HSMMC1 S3C64XX_PA_HSMMC1 #define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2 #define S3C_PA_IIC S3C64XX_PA_IIC0 +#define S3C_PA_IIC1 S3C64XX_PA_IIC1 #endif /* __ASM_ARCH_6400_MAP_H */ diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index e6e64968a611..d7a6e487f218 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -160,3 +160,9 @@ config S3C_DEV_HSMMC1 depends on PLAT_S3C help Compile in platform device definitions for HSMMC channel 1 + +config S3C_DEV_I2C1 + bool + depends on PLAT_S3C + help + Compile in platform device definitions for I2C channel 1 diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index 187fa95b87d5..3fcee0c44e18 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile @@ -23,3 +23,4 @@ obj-y += gpio-config.o obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o obj-y += dev-i2c0.o +obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o diff --git a/arch/arm/plat-s3c/dev-i2c0.c b/arch/arm/plat-s3c/dev-i2c0.c index 21870fd2ec98..2c0128c77c6e 100644 --- a/arch/arm/plat-s3c/dev-i2c0.c +++ b/arch/arm/plat-s3c/dev-i2c0.c @@ -37,12 +37,16 @@ static struct resource s3c_i2c_resource[] = { struct platform_device s3c_device_i2c0 = { .name = "s3c2410-i2c", +#ifdef CONFIG_S3C_DEV_I2C1 + .id = 0, +#else .id = -1, +#endif .num_resources = ARRAY_SIZE(s3c_i2c_resource), .resource = s3c_i2c_resource, }; -struct s3c2410_platform_i2c default_i2c_data __initdata = { +static struct s3c2410_platform_i2c default_i2c_data0 __initdata = { .flags = 0, .slave_addr = 0x10, .bus_freq = 100*1000, @@ -55,7 +59,7 @@ void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) struct s3c2410_platform_i2c *npd; if (!pd) - pd = &default_i2c_data; + pd = &default_i2c_data0; npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); if (!npd) diff --git a/arch/arm/plat-s3c/dev-i2c1.c b/arch/arm/plat-s3c/dev-i2c1.c new file mode 100644 index 000000000000..9658fb0aec95 --- /dev/null +++ b/arch/arm/plat-s3c/dev-i2c1.c @@ -0,0 +1,68 @@ +/* linux/arch/arm/plat-s3c/dev-i2c1.c + * + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C series device definition for i2c device 1 + * + * 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 + +static struct resource s3c_i2c_resource[] = { + [0] = { + .start = S3C_PA_IIC1, + .end = S3C_PA_IIC1 + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IIC1, + .end = IRQ_IIC1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_i2c1 = { + .name = "s3c2410-i2c", + .id = 1, + .num_resources = ARRAY_SIZE(s3c_i2c_resource), + .resource = s3c_i2c_resource, +}; + +static struct s3c2410_platform_i2c default_i2c_data1 __initdata = { + .flags = 0, + .bus_num = 1, + .slave_addr = 0x10, + .bus_freq = 100*1000, + .max_freq = 400*1000, + .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON, +}; + +void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) +{ + struct s3c2410_platform_i2c *npd; + + if (!pd) + pd = &default_i2c_data1; + + npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + else if (!npd->cfg_gpio) + npd->cfg_gpio = s3c_i2c1_cfg_gpio; + + s3c_device_i2c1.dev.platform_data = npd; +} diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h index d9e0c543ebd6..0e342d1fafbb 100644 --- a/arch/arm/plat-s3c/include/plat/devs.h +++ b/arch/arm/plat-s3c/include/plat/devs.h @@ -28,6 +28,7 @@ extern struct platform_device s3c_device_usb; extern struct platform_device s3c_device_lcd; extern struct platform_device s3c_device_wdt; extern struct platform_device s3c_device_i2c0; +extern struct platform_device s3c_device_i2c1; extern struct platform_device s3c_device_iis; extern struct platform_device s3c_device_rtc; extern struct platform_device s3c_device_adc; diff --git a/arch/arm/plat-s3c/include/plat/iic.h b/arch/arm/plat-s3c/include/plat/iic.h index 5073b1e74ee8..dc1dfcb9bc6c 100644 --- a/arch/arm/plat-s3c/include/plat/iic.h +++ b/arch/arm/plat-s3c/include/plat/iic.h @@ -48,8 +48,10 @@ struct s3c2410_platform_i2c { * as the driver will no longer carry defaults. */ extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); +extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); /* defined by architecture to configure gpio */ extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); +extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); #endif /* __ASM_ARCH_IIC_H */ diff --git a/arch/arm/plat-s3c64xx/include/plat/irqs.h b/arch/arm/plat-s3c64xx/include/plat/irqs.h index bc25689c3f83..02e8dd4c97d5 100644 --- a/arch/arm/plat-s3c64xx/include/plat/irqs.h +++ b/arch/arm/plat-s3c64xx/include/plat/irqs.h @@ -70,6 +70,7 @@ #define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3) #define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4) #define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5) +#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5) #define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6) #define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6) #define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7) @@ -144,6 +145,10 @@ #define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3) #define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4) +/* compatibility for device defines */ + +#define IRQ_IIC1 IRQ_S3C6410_IIC1 + /* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE * which we place after the pair of VICs. */ -- cgit v1.2.3 From 58435f7b2d1aa1ca1b08a2eecc36e13291342cfc Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 19 Nov 2008 15:41:31 +0000 Subject: [ARM] S3C: Add new FB device definition Add a device definition for the new S3C framebuffer driver. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c6400/include/mach/map.h | 2 + arch/arm/plat-s3c/Kconfig | 6 +++ arch/arm/plat-s3c/Makefile | 1 + arch/arm/plat-s3c/dev-fb.c | 72 ++++++++++++++++++++++++++++++++ arch/arm/plat-s3c/include/plat/devs.h | 1 + 5 files changed, 82 insertions(+) create mode 100644 arch/arm/plat-s3c/dev-fb.c (limited to 'arch/arm/plat-s3c/Kconfig') diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h index 4d5cd7ee8c15..cff27d813fc6 100644 --- a/arch/arm/mach-s3c6400/include/mach/map.h +++ b/arch/arm/mach-s3c6400/include/mach/map.h @@ -38,6 +38,7 @@ #define S3C_VA_UART2 S3C_VA_UARTx(2) #define S3C_VA_UART3 S3C_VA_UARTx(3) +#define S3C64XX_PA_FB (0x77100000) #define S3C64XX_PA_SYSCON (0x7E00F000) #define S3C64XX_PA_TIMER (0x7F006000) #define S3C64XX_PA_IIC0 (0x7F004000) @@ -62,5 +63,6 @@ #define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2 #define S3C_PA_IIC S3C64XX_PA_IIC0 #define S3C_PA_IIC1 S3C64XX_PA_IIC1 +#define S3C_PA_FB S3C64XX_PA_FB #endif /* __ASM_ARCH_6400_MAP_H */ diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index d7a6e487f218..e80a32822d88 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -166,3 +166,9 @@ config S3C_DEV_I2C1 depends on PLAT_S3C help Compile in platform device definitions for I2C channel 1 + +config S3C_DEV_FB + bool + depends on PLAT_S3C + help + Compile in platform device definition for framebuffer diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index 3fcee0c44e18..39195f972d5e 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o obj-y += dev-i2c0.o obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o +obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o diff --git a/arch/arm/plat-s3c/dev-fb.c b/arch/arm/plat-s3c/dev-fb.c new file mode 100644 index 000000000000..0454b8ec02e2 --- /dev/null +++ b/arch/arm/plat-s3c/dev-fb.c @@ -0,0 +1,72 @@ +/* linux/arch/arm/plat-s3c/dev-fb.c + * + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C series device definition for framebuffer device + * + * 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 + +static struct resource s3c_fb_resource[] = { + [0] = { + .start = S3C_PA_FB, + .end = S3C_PA_FB + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD_VSYNC, + .end = IRQ_LCD_VSYNC, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_LCD_FIFO, + .end = IRQ_LCD_FIFO, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_LCD_SYSTEM, + .end = IRQ_LCD_SYSTEM, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device s3c_device_fb = { + .name = "s3c-fb", + .id = -1, + .num_resources = ARRAY_SIZE(s3c_fb_resource), + .resource = s3c_fb_resource, + .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask, + .dev.coherent_dma_mask = 0xffffffffUL, +}; + +void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) +{ + struct s3c_fb_platdata *npd; + + if (!pd) { + printk(KERN_ERR "%s: no platform data\n", __func__); + return; + } + + npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL); + if (!npd) + printk(KERN_ERR "%s: no memory for platform data\n", __func__); + + s3c_device_fb.dev.platform_data = npd; +} diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h index 0e342d1fafbb..6b1b5231511c 100644 --- a/arch/arm/plat-s3c/include/plat/devs.h +++ b/arch/arm/plat-s3c/include/plat/devs.h @@ -24,6 +24,7 @@ extern struct platform_device *s3c24xx_uart_src[]; extern struct platform_device s3c_device_timer[]; +extern struct platform_device s3c_device_fb; extern struct platform_device s3c_device_usb; extern struct platform_device s3c_device_lcd; extern struct platform_device s3c_device_wdt; -- cgit v1.2.3