提交 ff1b8ba0 编写于 作者: B Ben Dooks

ARM: Merge for-2635/gpio2

Merge branch 'for-2635/gpio2' into for-linus/samsung2
......@@ -6,6 +6,7 @@ config CPU_S3C2410
bool
depends on ARCH_S3C2410
select CPU_ARM920T
select S3C_GPIO_PULL_UP
select S3C2410_CLOCK
select S3C2410_GPIO
select CPU_LLSERIAL_S3C2410
......
......@@ -33,14 +33,15 @@ static void h1940bt_enable(int on)
h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
/* Reset the chip */
mdelay(10);
s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
gpio_set_value(S3C2410_GPH(1), 1);
mdelay(10);
s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
gpio_set_value(S3C2410_GPH(1), 0);
}
else {
s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
gpio_set_value(S3C2410_GPH(1), 1);
mdelay(10);
s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
gpio_set_value(S3C2410_GPH(1), 0);
mdelay(10);
h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
}
......@@ -61,15 +62,21 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
struct rfkill *rfk;
int ret = 0;
ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
if (ret) {
dev_err(&pdev->dev, "could not get GPH1\n");\
return ret;
}
/* Configures BT serial port GPIOs */
s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
s3c2410_gpio_pullup(S3C2410_GPH(0), 1);
s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_pullup(S3C2410_GPH(1), 1);
s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
s3c2410_gpio_pullup(S3C2410_GPH(2), 1);
s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
s3c2410_gpio_pullup(S3C2410_GPH(3), 1);
s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
......@@ -100,6 +107,7 @@ static int h1940bt_remove(struct platform_device *pdev)
struct rfkill *rfk = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
gpio_free(S3C2410_GPH(1));
if (rfk) {
rfkill_unregister(rfk);
......
......@@ -10,14 +10,28 @@
* published by the Free Software Foundation.
*/
#ifndef __MACH_GPIO_FNS_H
#define __MACH_GPIO_FNS_H __FILE__
/* These functions are in the to-be-removed category and it is strongly
* encouraged not to use these in new code. They will be marked deprecated
* very soon.
*
* Most of the functionality can be either replaced by the gpiocfg calls
* for the s3c platform or by the generic GPIOlib API.
*
* As of 2.6.35-rc, these will be removed, with the few drivers using them
* either replaced or given a wrapper until the calls can be removed.
*/
#include <plat/gpio-cfg.h>
static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
{
/* 1:1 mapping between cfgpin and setcfg calls at the moment */
s3c_gpio_cfgpin(pin, cfg);
}
/* external functions for GPIO support
*
* These allow various different clients to access the same GPIO
......@@ -25,17 +39,6 @@
* GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
*/
/* s3c2410_gpio_cfgpin
*
* set the configuration of the given pin to the value passed.
*
* eg:
* s3c2410_gpio_cfgpin(S3C2410_GPA(0), S3C2410_GPA0_ADDR0);
* s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
*/
extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
/* s3c2410_gpio_getirq
......@@ -71,6 +74,14 @@ extern int s3c2400_gpio_getirq(unsigned int pin);
extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
unsigned int config);
/* s3c2410_gpio_pullup
*
* This call should be replaced with s3c_gpio_setpull().
*
* As a note, there is currently no distinction between pull-up and pull-down
* in the s3c24xx series devices with only an on/off configuration.
*/
/* s3c2410_gpio_pullup
*
* configure the pull-up control on the given pin
......@@ -86,18 +97,8 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
/* s3c2410_gpio_getpull
*
* Read the state of the pull-up on a given pin
*
* return:
* < 0 => error code
* 0 => enabled
* 1 => disabled
*/
extern int s3c2410_gpio_getpull(unsigned int pin);
extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
#endif /* __MACH_GPIO_FNS_H */
......@@ -16,15 +16,28 @@
#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
#define S3C2410_GPIO_BANKA (32*0)
#define S3C2410_GPIO_BANKB (32*1)
#define S3C2410_GPIO_BANKC (32*2)
#define S3C2410_GPIO_BANKD (32*3)
#define S3C2410_GPIO_BANKE (32*4)
#define S3C2410_GPIO_BANKF (32*5)
#define S3C2410_GPIO_BANKG (32*6)
#define S3C2410_GPIO_BANKH (32*7)
/* GPIO sizes for various SoCs:
*
* 2442
* 2410 2412 2440 2443 2416
* ---- ---- ---- ---- ----
* A 23 22 25 16 25
* B 11 11 11 11 9
* C 16 15 16 16 16
* D 16 16 16 16 16
* E 16 16 16 16 16
* F 8 8 8 8 8
* G 16 16 16 16 8
* H 11 11 9 15 15
* J -- -- 13 16 --
* K -- -- -- -- 16
* L -- -- -- 15 7
* M -- -- -- 2 2
*/
/* GPIO bank sizes */
#define S3C2410_GPIO_A_NR (32)
#define S3C2410_GPIO_B_NR (32)
......@@ -34,6 +47,10 @@
#define S3C2410_GPIO_F_NR (32)
#define S3C2410_GPIO_G_NR (32)
#define S3C2410_GPIO_H_NR (32)
#define S3C2410_GPIO_J_NR (32) /* technically 16. */
#define S3C2410_GPIO_K_NR (32) /* technically 16. */
#define S3C2410_GPIO_L_NR (32) /* technically 15. */
#define S3C2410_GPIO_M_NR (32) /* technically 2. */
#if CONFIG_S3C_GPIO_SPACE != 0
#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
......@@ -53,6 +70,10 @@ enum s3c_gpio_number {
S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
};
#endif /* __ASSEMBLY__ */
......@@ -67,6 +88,10 @@ enum s3c_gpio_number {
#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr))
#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr))
#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr))
#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr))
#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr))
#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr))
#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr))
/* compatibility until drivers can be modified */
......
......@@ -23,11 +23,11 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
{
struct s3c_gpio_chip *chip;
if (pin > S3C2410_GPG(10))
if (pin > S3C_GPIO_END)
return NULL;
chip = &s3c24xx_gpios[pin/32];
return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL;
return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
}
#endif /* __ASM_ARCH_GPIO_CORE_H */
......@@ -20,10 +20,18 @@
* devices that need GPIO.
*/
#ifdef CONFIG_CPU_S3C244X
#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
#else
#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
#endif
#include <asm-generic/gpio.h>
#include <mach/gpio-nrs.h>
#include <mach/gpio-fns.h>
#ifdef CONFIG_CPU_S3C24XX
#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32)
#else
#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32)
#endif
......@@ -17,29 +17,11 @@
#include <mach/gpio-nrs.h>
#ifdef CONFIG_CPU_S3C2400
#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x)
#define S3C24XX_MISCCR S3C2400_MISCCR
#define S3C24XX_MISCCR S3C2400_MISCCR
#else
#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x)
#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
#endif /* CONFIG_CPU_S3C2400 */
/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */
#define S3C2400_BANKNUM(pin) (((pin) & ~31) / 32)
#define S3C2400_BASEA2B(pin) ((((pin) & ~31) >> 2))
#define S3C2400_BASEC2H(pin) ((S3C2400_BANKNUM(pin) * 10) + \
(2 * (S3C2400_BANKNUM(pin)-2)))
#define S3C2400_GPIO_BASE(pin) (pin < S3C2410_GPIO_BANKC ? \
S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
/* general configuration options */
#define S3C2410_GPIO_LEAVE (0xFFFFFFFF)
......@@ -639,6 +621,23 @@
* for the 2412/2413 from the 2410/2440/2442
*/
/* S3C2443 and above */
#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0)
#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4)
#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8)
#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0)
#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4)
#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8)
#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0)
#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4)
#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8)
#define S3C2443_GPMCON S3C2410_GPIOREG(0x100)
#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104)
#define S3C2443_GPMUP S3C2410_GPIOREG(0x108)
/* miscellaneous control */
#define S3C2400_MISCCR S3C2410_GPIOREG(0x54)
#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
......
......@@ -22,85 +22,49 @@
* pull up works like all other ports.
*/
#define S3C2440_GPIO_BANKJ (416)
#define S3C2440_GPJCON S3C2410_GPIOREG(0xd0)
#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4)
#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8)
#define S3C2413_GPJCON S3C2410_GPIOREG(0x80)
#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84)
#define S3C2413_GPJUP S3C2410_GPIOREG(0x88)
#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C)
#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
#define S3C2440_GPJ0_INP (0x00 << 0)
#define S3C2440_GPJ0_OUTP (0x01 << 0)
#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0)
#define S3C2440_GPJ1 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 1)
#define S3C2440_GPJ1_INP (0x00 << 2)
#define S3C2440_GPJ1_OUTP (0x01 << 2)
#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2)
#define S3C2440_GPJ2 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 2)
#define S3C2440_GPJ2_INP (0x00 << 4)
#define S3C2440_GPJ2_OUTP (0x01 << 4)
#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4)
#define S3C2440_GPJ3 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 3)
#define S3C2440_GPJ3_INP (0x00 << 6)
#define S3C2440_GPJ3_OUTP (0x01 << 6)
#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6)
#define S3C2440_GPJ4 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 4)
#define S3C2440_GPJ4_INP (0x00 << 8)
#define S3C2440_GPJ4_OUTP (0x01 << 8)
#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8)
#define S3C2440_GPJ5 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 5)
#define S3C2440_GPJ5_INP (0x00 << 10)
#define S3C2440_GPJ5_OUTP (0x01 << 10)
#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10)
#define S3C2440_GPJ6 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 6)
#define S3C2440_GPJ6_INP (0x00 << 12)
#define S3C2440_GPJ6_OUTP (0x01 << 12)
#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12)
#define S3C2440_GPJ7 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 7)
#define S3C2440_GPJ7_INP (0x00 << 14)
#define S3C2440_GPJ7_OUTP (0x01 << 14)
#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14)
#define S3C2440_GPJ8 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 8)
#define S3C2440_GPJ8_INP (0x00 << 16)
#define S3C2440_GPJ8_OUTP (0x01 << 16)
#define S3C2440_GPJ8_CAMPCLK (0x02 << 16)
#define S3C2440_GPJ9 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 9)
#define S3C2440_GPJ9_INP (0x00 << 18)
#define S3C2440_GPJ9_OUTP (0x01 << 18)
#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18)
#define S3C2440_GPJ10 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 10)
#define S3C2440_GPJ10_INP (0x00 << 20)
#define S3C2440_GPJ10_OUTP (0x01 << 20)
#define S3C2440_GPJ10_CAMHREF (0x02 << 20)
#define S3C2440_GPJ11 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 11)
#define S3C2440_GPJ11_INP (0x00 << 22)
#define S3C2440_GPJ11_OUTP (0x01 << 22)
#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
#define S3C2440_GPJ12 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12)
#define S3C2440_GPJ12_INP (0x00 << 24)
#define S3C2440_GPJ12_OUTP (0x01 << 24)
#define S3C2440_GPJ12_CAMRESET (0x02 << 24)
#define S3C2443_GPJ13 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
#define S3C2443_GPJ14 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
#define S3C2443_GPJ15 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
#endif /* __ASM_ARCH_REGS_GPIOJ_H */
......@@ -56,6 +56,7 @@
#include <plat/iic.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/gpio-cfg.h>
#ifdef CONFIG_MTD_PARTITIONS
......@@ -225,8 +226,8 @@ static void amlm5900_init_pm(void)
} else {
enable_irq_wake(IRQ_EINT9);
/* configure the suspend/resume status pin */
s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_pullup(S3C2410_GPF(2), 0);
s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
}
}
static void __init amlm5900_init(void)
......
......@@ -61,6 +61,7 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/cpu-freq.h>
#include <plat/gpio-cfg.h>
#include <plat/audio-simtec.h>
#include "usb-simtec.h"
......@@ -216,15 +217,13 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
{
/* ensure that an nRESET is not generated on resume. */
s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
gpio_direction_output(S3C2410_GPA(21), 1);
return 0;
}
static int bast_pm_resume(struct sys_device *sd)
{
s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
return 0;
}
......@@ -658,6 +657,8 @@ static void __init bast_init(void)
nor_simtec_init();
simtec_audio_add(NULL, true, &bast_audio);
WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
s3c_cpufreq_setboard(&bast_cpufreq);
}
......
......@@ -50,6 +50,7 @@
#include <plat/udc.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
......@@ -207,16 +208,16 @@ static int h1940_backlight_init(struct device *dev)
{
gpio_request(S3C2410_GPB(0), "Backlight");
s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
gpio_direction_output(S3C2410_GPB(0), 0);
s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
return 0;
}
static void h1940_backlight_exit(struct device *dev)
{
s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/);
gpio_direction_output(S3C2410_GPB(0), 1);
}
static struct platform_pwm_backlight_data backlight_data = {
......@@ -245,18 +246,18 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
if (!power) {
/* set to 3ec */
s3c2410_gpio_setpin(S3C2410_GPC(0), 0);
gpio_direction_output(S3C2410_GPC(0), 0);
/* wait for 3ac */
do {
value = s3c2410_gpio_getpin(S3C2410_GPC(6));
value = gpio_get_value(S3C2410_GPC(6));
} while (value);
/* set to 38c */
s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
gpio_direction_output(S3C2410_GPC(5), 0);
} else {
/* Set to 3ac */
s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
gpio_direction_output(S3C2410_GPC(5), 1);
/* Set to 3ad */
s3c2410_gpio_setpin(S3C2410_GPC(0), 1);
gpio_direction_output(S3C2410_GPC(0), 1);
}
}
......@@ -333,6 +334,7 @@ static void __init h1940_init(void)
gpio_request(S3C2410_GPC(5), "LCD power");
gpio_request(S3C2410_GPC(6), "LCD power");
gpio_direction_input(S3C2410_GPC(6));
platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
}
......
......@@ -596,6 +596,9 @@ static void __init n30_init(void)
platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
}
WARN_ON(gpio_request(S3C2410_GPB(3), "udc pup"));
gpio_direction_output(S3C2410_GPB(3), 0);
}
MACHINE_START(N30, "Acer-N30")
......
......@@ -58,6 +58,7 @@
#include <plat/iic.h>
#include <plat/common-smdk.h>
#include <plat/gpio-cfg.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/pm.h>
......@@ -219,10 +220,10 @@ static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
{
switch (cs) {
case BITBANG_CS_ACTIVE:
s3c2410_gpio_setpin(S3C2410_GPB(5), 0);
gpio_set_value(S3C2410_GPB(5), 0);
break;
case BITBANG_CS_INACTIVE:
s3c2410_gpio_setpin(S3C2410_GPB(5), 1);
gpio_set_value(S3C2410_GPB(5), 1);
break;
}
}
......@@ -347,13 +348,14 @@ static void __init qt2410_machine_init(void)
}
s3c24xx_fb_set_platdata(&qt2410_fb_info);
s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
s3c_i2c0_set_platdata(NULL);
s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT);
WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
gpio_direction_output(S3C2410_GPB(5), 1);
platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
s3c_pm_init();
......
......@@ -357,8 +357,7 @@ static struct clk *vr1000_clocks[] __initdata = {
static void vr1000_power_off(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(9), 1);
gpio_direction_output(S3C2410_GPB(9), 1);
}
static void __init vr1000_map_io(void)
......@@ -395,6 +394,8 @@ static void __init vr1000_init(void)
nor_simtec_init();
simtec_audio_add(NULL, true, NULL);
WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
}
MACHINE_START(VR1000, "Thorcom-VR1000")
......
......@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/sysdev.h>
#include <linux/serial_core.h>
......@@ -40,6 +41,10 @@
#include <plat/clock.h>
#include <plat/pll.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
/* Initial IO mappings */
static struct map_desc s3c2410_iodesc[] __initdata = {
......@@ -65,6 +70,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
void __init s3c2410_map_io(void)
{
s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
}
......
......@@ -16,41 +16,43 @@
#include <linux/types.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <plat/gpio-core.h>
int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
unsigned long offs = pin - chip->chip.base;
unsigned long flags;
unsigned long slpcon;
offs *= 2;
if (pin < S3C2410_GPIO_BANKB)
if (pin < S3C2410_GPB(0))
return -EINVAL;
if (pin >= S3C2410_GPIO_BANKF &&
pin <= S3C2410_GPIO_BANKG)
if (pin >= S3C2410_GPF(0) &&
pin <= S3C2410_GPG(16))
return -EINVAL;
if (pin > (S3C2410_GPIO_BANKH + 32))
if (pin > S3C2410_GPH(16))
return -EINVAL;
local_irq_save(flags);
slpcon = __raw_readl(base + 0x0C);
slpcon = __raw_readl(chip->base + 0x0C);
slpcon &= ~(3 << offs);
slpcon |= state << offs;
__raw_writel(slpcon, base + 0x0C);
__raw_writel(slpcon, chip->base + 0x0C);
local_irq_restore(flags);
......
......@@ -48,6 +48,7 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
......@@ -357,8 +358,7 @@ static void jive_lcm_reset(unsigned int set)
{
printk(KERN_DEBUG "%s(%d)\n", __func__, set);
s3c2410_gpio_setpin(S3C2410_GPG(13), set);
s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
gpio_set_value(S3C2410_GPG(13), set);
}
#undef LCD_UPPER_MARGIN
......@@ -391,7 +391,7 @@ static struct ili9320_platdata jive_lcm_config = {
static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
{
s3c2410_gpio_setpin(S3C2410_GPB(7), cs ? 0 : 1);
gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1);
}
static struct s3c2410_spigpio_info jive_lcd_spi = {
......@@ -413,7 +413,7 @@ static struct platform_device jive_device_lcdspi = {
static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
{
s3c2410_gpio_setpin(S3C2410_GPH(10), cs ? 0 : 1);
gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1);
}
static struct s3c2410_spigpio_info jive_wm8750_spi = {
......@@ -531,7 +531,7 @@ static void jive_power_off(void)
printk(KERN_INFO "powering system down...\n");
s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
}
static void __init jive_machine_init(void)
......@@ -636,22 +636,22 @@ static void __init jive_machine_init(void)
/* initialise the spi */
s3c2410_gpio_setpin(S3C2410_GPG(13), 0);
s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
gpio_request(S3C2410_GPG(13), "lcm reset");
gpio_direction_output(S3C2410_GPG(13), 0);
s3c2410_gpio_setpin(S3C2410_GPB(7), 1);
s3c2410_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT);
gpio_request(S3C2410_GPB(7), "jive spi");
gpio_direction_output(S3C2410_GPB(7), 1);
s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
s3c2410_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
/* initialise the WM8750 spi */
s3c2410_gpio_setpin(S3C2410_GPH(10), 1);
s3c2410_gpio_cfgpin(S3C2410_GPH(10), S3C2410_GPIO_OUTPUT);
gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
gpio_direction_output(S3C2410_GPH(10), 1);
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
......
......@@ -85,10 +85,10 @@ static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
switch (cmd)
{
case S3C2410_UDC_P_ENABLE :
s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
gpio_set_value(S3C2410_GPF(2), 1);
break;
case S3C2410_UDC_P_DISABLE :
s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
gpio_set_value(S3C2410_GPF(2), 0);
break;
case S3C2410_UDC_P_RESET :
break;
......@@ -134,8 +134,8 @@ static void __init smdk2413_machine_init(void)
{ /* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
WARN_ON(gpio_request(S3C2410_GPF(2), "udc pull"));
gpio_direction_output(S3C2410_GPF(2), 0);
s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
S3C2410_MISCCR_USBSUSPND0 |
......
......@@ -6,6 +6,7 @@ config CPU_S3C2440
bool
depends on ARCH_S3C2410
select CPU_ARM920T
select S3C_GPIO_PULL_UP
select S3C2410_CLOCK
select S3C2410_PM if PM
select S3C2410_GPIO
......
......@@ -53,6 +53,7 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
......@@ -102,10 +103,10 @@ static void mini2440_udc_pullup(enum s3c2410_udc_cmd_e cmd)
switch (cmd) {
case S3C2410_UDC_P_ENABLE :
s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
gpio_set_value(S3C2410_GPC(5), 1);
break;
case S3C2410_UDC_P_DISABLE :
s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
gpio_set_value(S3C2410_GPC(5), 0);
break;
case S3C2410_UDC_P_RESET :
break;
......@@ -632,25 +633,25 @@ static void __init mini2440_init(void)
mini2440_parse_features(&features, mini2440_features_str);
/* turn LCD on */
s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
/* Turn the backlight early on */
s3c2410_gpio_setpin(S3C2410_GPG(4), 1);
s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT);
WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
gpio_direction_output(S3C2410_GPG(4), 1);
/* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
s3c2410_gpio_pullup(S3C2410_GPB(1), 0);
s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
/* Make sure the D+ pullup pin is output */
s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup"));
gpio_direction_output(S3C2410_GPC(5), 0);
/* mark the key as input, without pullups (there is one on the board) */
for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0);
s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio,
S3C2410_GPIO_INPUT);
s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
}
if (features.lcd_index != -1) {
int li;
......
......@@ -40,6 +40,7 @@
#include <plat/regs-serial.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
#include <plat/s3c2410.h>
#include <plat/s3c244x.h>
#include <plat/clock.h>
......@@ -122,15 +123,15 @@ static void __init nexcoder_sensorboard_init(void)
{
// Initialize SCCB bus
s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
// Power up the sensor board
s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
s3c2410_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
}
static void __init nexcoder_map_io(void)
......
......@@ -49,6 +49,7 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <plat/gpio-cfg.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
......@@ -298,7 +299,7 @@ static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
/* ensure that an nRESET is not generated on resume. */
s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
return 0;
}
......@@ -310,7 +311,7 @@ static int osiris_pm_resume(struct sys_device *sd)
__raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
return 0;
}
......
......@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/sysdev.h>
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/io.h>
......@@ -33,6 +34,10 @@
#include <plat/cpu.h>
#include <plat/s3c244x.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
static struct sys_device s3c2440_sysdev = {
.cls = &s3c2440_sysclass,
};
......@@ -41,6 +46,9 @@ int __init s3c2440_init(void)
{
printk("S3C2440: Initialising architecture\n");
s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
/* change irq for watchdog */
s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
......
......@@ -51,6 +51,7 @@
static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.get_config = s3c_gpio_getcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
......@@ -58,12 +59,14 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
.cfg_eint = 7,
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.get_config = s3c_gpio_getcfg_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,
.get_config = s3c_gpio_getcfg_s3c64xx_4bit,
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
......@@ -171,6 +174,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
......@@ -178,6 +182,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
.cfg_eint = 2,
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
......@@ -185,6 +190,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
.cfg_eint = 3,
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
......
......@@ -161,12 +161,15 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
}, {
.cfg_eint = 0,
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
}, {
.cfg_eint = 2,
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
}, {
.cfg_eint = 3,
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
},
};
......@@ -279,6 +282,8 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
for (; nr_chips > 0; nr_chips--, chipcfg++) {
if (!chipcfg->set_config)
chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit;
if (!chipcfg->get_config)
chipcfg->get_config = s3c_gpio_getcfg_s3c64xx_4bit;
if (!chipcfg->set_pull)
chipcfg->set_pull = s3c_gpio_setpull_updown;
if (!chipcfg->get_pull)
......
......@@ -9,6 +9,7 @@ config PLAT_S3C24XX
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
select S3C_DEVICE_NAND
select S3C_GPIO_CFG_S3C24XX
help
Base platform code for any Samsung S3C24XX device
......
......@@ -42,6 +42,7 @@
#include <plat/nand.h>
#include <plat/common-smdk.h>
#include <plat/gpio-cfg.h>
#include <plat/devs.h>
#include <plat/pm.h>
......@@ -185,10 +186,10 @@ void __init smdk_machine_init(void)
{
/* Configure the LEDs (even if we have no LED support)*/
s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
......
/* linux/arch/arm/plat-s3c24xx/gpio.c
*
* Copyright (c) 2004-2005 Simtec Electronics
* Copyright (c) 2004-2010 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C24XX GPIO support
......@@ -20,12 +20,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <mach/hardware.h>
......@@ -34,133 +34,46 @@
#include <mach/regs-gpio.h>
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long mask;
unsigned long con;
unsigned long flags;
#include <plat/gpio-core.h>
if (pin < S3C2410_GPIO_BANKB) {
mask = 1 << S3C2410_GPIO_OFFSET(pin);
} else {
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
}
switch (function) {
case S3C2410_GPIO_LEAVE:
mask = 0;
function = 0;
break;
case S3C2410_GPIO_INPUT:
case S3C2410_GPIO_OUTPUT:
case S3C2410_GPIO_SFN2:
case S3C2410_GPIO_SFN3:
if (pin < S3C2410_GPIO_BANKB) {
function -= 1;
function &= 1;
function <<= S3C2410_GPIO_OFFSET(pin);
} else {
function &= 3;
function <<= S3C2410_GPIO_OFFSET(pin)*2;
}
}
/* modify the specified register wwith IRQs off */
local_irq_save(flags);
con = __raw_readl(base + 0x00);
con &= ~mask;
con |= function;
__raw_writel(con, base + 0x00);
local_irq_restore(flags);
}
EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
unsigned int s3c2410_gpio_getcfg(unsigned int pin)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long val = __raw_readl(base);
if (pin < S3C2410_GPIO_BANKB) {
val >>= S3C2410_GPIO_OFFSET(pin);
val &= 1;
val += 1;
} else {
val >>= S3C2410_GPIO_OFFSET(pin)*2;
val &= 3;
}
return val | S3C2410_GPIO_INPUT;
}
EXPORT_SYMBOL(s3c2410_gpio_getcfg);
/* gpiolib wrappers until these are totally eliminated */
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long up;
int ret;
if (pin < S3C2410_GPIO_BANKB)
return;
WARN_ON(to); /* should be none of these left */
local_irq_save(flags);
up = __raw_readl(base + 0x08);
up &= ~(1L << offs);
up |= to << offs;
__raw_writel(up, base + 0x08);
if (!to) {
/* if pull is enabled, try first with up, and if that
* fails, try using down */
local_irq_restore(flags);
ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
if (ret)
s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
} else {
s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
}
}
EXPORT_SYMBOL(s3c2410_gpio_pullup);
int s3c2410_gpio_getpull(unsigned int pin)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
if (pin < S3C2410_GPIO_BANKB)
return -EINVAL;
return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
}
EXPORT_SYMBOL(s3c2410_gpio_getpull);
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;
/* do this via gpiolib until all users removed */
local_irq_save(flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offs);
dat |= to << offs;
__raw_writel(dat, base + 0x04);
local_irq_restore(flags);
gpio_request(pin, "temporary");
gpio_set_value(pin, to);
gpio_free(pin);
}
EXPORT_SYMBOL(s3c2410_gpio_setpin);
unsigned int s3c2410_gpio_getpin(unsigned int pin)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
unsigned long offs = pin - chip->chip.base;
return __raw_readl(base + 0x04) & (1<< offs);
return __raw_readl(chip->base + 0x04) & (1<< offs);
}
EXPORT_SYMBOL(s3c2410_gpio_getpin);
......@@ -181,22 +94,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
}
EXPORT_SYMBOL(s3c2410_modify_misccr);
int s3c2410_gpio_getirq(unsigned int pin)
{
if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15))
return -EINVAL; /* not valid interrupts */
if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7))
return -EINVAL; /* not valid pin */
if (pin < S3C2410_GPF(4))
return (pin - S3C2410_GPF(0)) + IRQ_EINT0;
if (pin < S3C2410_GPG(0))
return (pin - S3C2410_GPF(4)) + IRQ_EINT4;
return (pin - S3C2410_GPG(0)) + IRQ_EINT8;
}
EXPORT_SYMBOL(s3c2410_gpio_getirq);
/* linux/arch/arm/plat-s3c24xx/gpiolib.c
*
* Copyright (c) 2008 Simtec Electronics
* Copyright (c) 2008-2010 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
......@@ -21,6 +21,8 @@
#include <linux/gpio.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <plat/pm.h>
......@@ -77,10 +79,21 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
return IRQ_EINT8 + offset;
}
static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
.set_config = s3c_gpio_setcfg_s3c24xx_a,
.get_config = s3c_gpio_getcfg_s3c24xx_a,
};
struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
};
struct s3c_gpio_chip s3c24xx_gpios[] = {
[0] = {
.base = S3C2410_GPACON,
.pm = __gpio_pm(&s3c_gpio_pm_1bit),
.config = &s3c24xx_gpiocfg_banka,
.chip = {
.base = S3C2410_GPA(0),
.owner = THIS_MODULE,
......@@ -161,15 +174,58 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
.ngpio = 11,
},
},
/* GPIOS for the S3C2443 and later devices. */
{
.base = S3C2440_GPJCON,
.pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPJ(0),
.owner = THIS_MODULE,
.label = "GPIOJ",
.ngpio = 16,
},
}, {
.base = S3C2443_GPKCON,
.pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPK(0),
.owner = THIS_MODULE,
.label = "GPIOK",
.ngpio = 16,
},
}, {
.base = S3C2443_GPLCON,
.pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPL(0),
.owner = THIS_MODULE,
.label = "GPIOL",
.ngpio = 15,
},
}, {
.base = S3C2443_GPMCON,
.pm = __gpio_pm(&s3c_gpio_pm_2bit),
.chip = {
.base = S3C2410_GPM(0),
.owner = THIS_MODULE,
.label = "GPIOM",
.ngpio = 2,
},
},
};
static __init int s3c24xx_gpiolib_init(void)
{
struct s3c_gpio_chip *chip = s3c24xx_gpios;
int gpn;
for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++)
for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
if (!chip->config)
chip->config = &s3c24xx_gpiocfg_default;
s3c_gpiolib_add(chip);
}
return 0;
}
......
......@@ -43,6 +43,7 @@
#include <asm/mach/time.h>
#include <plat/gpio-cfg.h>
#include <plat/pm.h>
#define PFX "s3c24xx-pm: "
......@@ -90,22 +91,22 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
{
unsigned long irqstate;
unsigned long pinstate;
int irq = s3c2410_gpio_getirq(pin);
int irq = gpio_to_irq(pin);
if (irqoffs < 4)
irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
else
irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
pinstate = s3c2410_gpio_getcfg(pin);
pinstate = s3c_gpio_getcfg(pin);
if (!irqstate) {
if (pinstate == S3C2410_GPIO_IRQ)
S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
} else {
if (pinstate == S3C2410_GPIO_IRQ) {
S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
}
}
}
......
......@@ -15,12 +15,13 @@
struct platform_device;
#include <plat/gpio-cfg.h>
#include <plat/iic.h>
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
}
......@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
int enable)
{
if (enable) {
s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
} else {
s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
s3c2410_gpio_pullup(S3C2410_GPE(11), 1);
s3c2410_gpio_pullup(S3C2410_GPE(12), 1);
s3c2410_gpio_pullup(S3C2410_GPE(13), 1);
s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
}
}
......@@ -23,16 +23,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
printk(KERN_INFO "%s(%d)\n", __func__, enable);
if (enable) {
s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
} else {
s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
s3c2410_gpio_pullup(S3C2410_GPD(10), 1);
s3c2410_gpio_pullup(S3C2410_GPD(9), 1);
s3c2410_gpio_pullup(S3C2410_GPD(8), 1);
s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
}
}
......@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
int enable)
{
if (enable) {
s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
} else {
s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
s3c2410_gpio_pullup(S3C2410_GPG(5), 1);
s3c2410_gpio_pullup(S3C2410_GPG(6), 1);
s3c2410_gpio_pullup(S3C2410_GPG(7), 1);
s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
}
}
/* linux/arch/arm/plat-s3c/gpio-config.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Copyright 2008-2010 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
......@@ -33,14 +33,34 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
offset = pin - chip->chip.base;
local_irq_save(flags);
s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_setcfg(chip, offset, config);
local_irq_restore(flags);
s3c_gpio_unlock(chip, flags);
return ret;
}
EXPORT_SYMBOL(s3c_gpio_cfgpin);
unsigned s3c_gpio_getcfg(unsigned int pin)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
unsigned long flags;
unsigned ret = 0;
int offset;
if (chip) {
offset = pin - chip->chip.base;
s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_getcfg(chip, offset);
s3c_gpio_unlock(chip, flags);
}
return ret;
}
EXPORT_SYMBOL(s3c_gpio_getcfg);
int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
......@@ -52,17 +72,17 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
offset = pin - chip->chip.base;
local_irq_save(flags);
s3c_gpio_lock(chip, flags);
ret = s3c_gpio_do_setpull(chip, offset, pull);
local_irq_restore(flags);
s3c_gpio_unlock(chip, flags);
return ret;
}
EXPORT_SYMBOL(s3c_gpio_setpull);
#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
{
void __iomem *reg = chip->base;
unsigned int shift = off;
......@@ -87,6 +107,19 @@ int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
return 0;
}
unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off)
{
u32 con;
con = __raw_readl(chip->base);
con >>= off;
con &= 1;
con++;
return S3C_GPIO_SFN(con);
}
int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
{
......@@ -109,6 +142,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
return 0;
}
unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
unsigned int off)
{
u32 con;
con = __raw_readl(chip->base);
con >>= off * 2;
con &= 3;
/* this conversion works for IN and OUT as well as special mode */
return S3C_GPIO_SPECIAL(con);
}
#endif
#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
......@@ -134,6 +180,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
return 0;
}
unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
unsigned int off)
{
void __iomem *reg = chip->base;
unsigned int shift = (off & 7) * 4;
u32 con;
if (off < 8 && chip->chip.ngpio > 8)
reg -= 4;
con = __raw_readl(reg);
con >>= shift;
con &= 0xf;
/* this conversion works for IN and OUT as well as special mode */
return S3C_GPIO_SPECIAL(con);
}
#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
......@@ -164,3 +229,35 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
return (__force s3c_gpio_pull_t)pup;
}
#endif
#ifdef CONFIG_S3C_GPIO_PULL_UP
int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
unsigned int off, s3c_gpio_pull_t pull)
{
void __iomem *reg = chip->base + 0x08;
u32 pup = __raw_readl(reg);
pup = __raw_readl(reg);
if (pup == S3C_GPIO_PULL_UP)
pup &= ~(1 << off);
else if (pup == S3C_GPIO_PULL_NONE)
pup |= (1 << off);
else
return -EINVAL;
__raw_writel(pup, reg);
return 0;
}
s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
unsigned int off)
{
void __iomem *reg = chip->base + 0x08;
u32 pup = __raw_readl(reg);
pup &= (1 << off);
return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
}
#endif /* CONFIG_S3C_GPIO_PULL_UP */
......@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/spinlock.h>
#include <plat/gpio-core.h>
......@@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
unsigned long flags;
unsigned long con;
local_irq_save(flags);
s3c_gpio_lock(ourchip, flags);
con = __raw_readl(base + 0x00);
con &= ~(3 << (offset * 2));
__raw_writel(con, base + 0x00);
local_irq_restore(flags);
s3c_gpio_unlock(ourchip, flags);
return 0;
}
......@@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
unsigned long dat;
unsigned long con;
local_irq_save(flags);
s3c_gpio_lock(ourchip, flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offset);
......@@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
__raw_writel(con, base + 0x00);
__raw_writel(dat, base + 0x04);
local_irq_restore(flags);
s3c_gpio_unlock(ourchip, flags);
return 0;
}
......@@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
unsigned long flags;
unsigned long dat;
local_irq_save(flags);
s3c_gpio_lock(ourchip, flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offset);
......@@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
dat |= 1 << offset;
__raw_writel(dat, base + 0x04);
local_irq_restore(flags);
s3c_gpio_unlock(ourchip, flags);
}
static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
......@@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
BUG_ON(!gc->label);
BUG_ON(!gc->ngpio);
spin_lock_init(&chip->lock);
if (!gc->direction_input)
gc->direction_input = s3c_gpiolib_input;
if (!gc->direction_output)
......
......@@ -30,6 +30,12 @@ static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
return (chip->config->set_config)(chip, off, config);
}
static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
unsigned int off)
{
return (chip->config->get_config)(chip, off);
}
static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
unsigned int off, s3c_gpio_pull_t pull)
{
......@@ -52,6 +58,18 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg);
/**
* s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
* @chip: The gpio chip that is being configured.
* @off: The offset for the GPIO being configured.
*
* The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
* could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
* S3C_GPIO_SPECIAL() macro.
*/
unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
unsigned int off);
/**
* s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
* @chip: The gpio chip that is being configured.
......@@ -65,6 +83,21 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg);
/**
* s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
* @chip: The gpio chip that is being configured.
* @off: The offset for the GPIO being configured.
*
* The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
* GPIO configuration value.
*
* @sa s3c_gpio_getcfg_s3c24xx
* @sa s3c_gpio_getcfg_s3c64xx_4bit
*/
extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off);
/**
* s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
* @chip: The gpio chip that is being configured.
......@@ -85,6 +118,20 @@ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg);
/**
* s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
* @chip: The gpio chip that is being configured.
* @off: The offset for the GPIO being configured.
*
* The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
* register setting into a value the software can use, such as could be passed
* to s3c_gpio_setcfg_s3c64xx_4bit().
*
* @sa s3c_gpio_getcfg_s3c24xx
*/
extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
unsigned int off);
/* Pull-{up,down} resistor controls.
*
* S3C2410,S3C2440,S3C24A0 = Pull-UP,
......@@ -145,6 +192,17 @@ extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
unsigned int off);
/**
* s3c_gpio_getpull_1up() - Get configuration for choice of up 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 resistor for the
* given GPIO in the same case as s3c_gpio_setpull_1up.
*/
extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
unsigned int off);
/**
* s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
* @chip: The gpio chip that is being configured.
......
......@@ -77,6 +77,17 @@ struct s3c_gpio_cfg {
*/
extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
/**
* s3c_gpio_getcfg - Read the current function for a GPIO pin
* @pin: The pin to read the configuration value for.
*
* Read the configuration state of the given @pin, returning a value that
* could be passed back to s3c_gpio_cfgpin().
*
* @sa s3c_gpio_cfgpin
*/
extern unsigned s3c_gpio_getcfg(unsigned int pin);
/* Define values for the pull-{up,down} available for each gpio pin.
*
* These values control the state of the weak pull-{up,down} resistors
......
......@@ -44,16 +44,26 @@ struct s3c_gpio_cfg;
* @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.
* @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support.
*
* This wrapper provides the necessary information for the Samsung
* specific gpios being registered with gpiolib.
*
* The lock protects each gpio bank from multiple access of the shared
* configuration registers, or from reading of data whilst another thread
* is writing to the register set.
*
* Each chip has its own lock to avoid any contention between different
* CPU cores trying to get one lock for different GPIO banks, where each
* bank of GPIO has its own register space and configuration registers.
*/
struct s3c_gpio_chip {
struct gpio_chip chip;
struct s3c_gpio_cfg *config;
struct s3c_gpio_pm *pm;
void __iomem *base;
spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
#endif
......@@ -108,6 +118,9 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
/* exported for core SoC support to change */
extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
#ifdef CONFIG_S3C_GPIO_TRACK
extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
......@@ -135,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
#define __gpio_pm(x) NULL
#endif /* CONFIG_PM */
/* locking wrappers to deal with multiple access to the same gpio bank */
#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
......@@ -329,7 +329,7 @@ void s3c_pm_save_gpios(void)
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip)
continue;
......@@ -367,7 +367,7 @@ void s3c_pm_restore_gpios(void)
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip)
continue;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册