X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/fe8a4ad530831ef7b897a9617b30a6d280fd2814..HEAD:/target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/mach-gta02.c?ds=sidebyside diff --git a/target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/mach-gta02.c b/target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/mach-gta02.c index b5a9fa621..49ab6c43b 100644 --- a/target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/mach-gta02.c +++ b/target/linux/s3c24xx/files-2.6.30/arch/arm/mach-s3c2442/mach-gta02.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -90,6 +91,7 @@ #include #include #include +#include #include #include @@ -1273,40 +1275,38 @@ struct platform_device gta02_led_dev = { }, }; -static struct resource gta02_button_resources[] = { - [0] = { - .start = GTA02_GPIO_AUX_KEY, - .end = GTA02_GPIO_AUX_KEY, - }, - [1] = { - .start = GTA02_GPIO_HOLD_KEY, - .end = GTA02_GPIO_HOLD_KEY, - }, - [2] = { - .start = GTA02_GPIO_JACK_INSERT, - .end = GTA02_GPIO_JACK_INSERT, - }, - [3] = { - .start = 0, - .end = 0, +static struct gpio_keys_button gta02_buttons[] = { + { + .gpio = GTA02_GPIO_AUX_KEY, + .code = KEY_PHONE, + .desc = "Aux", + .type = EV_KEY, }, - [4] = { - .start = 0, - .end = 0, + { + .gpio = GTA02_GPIO_HOLD_KEY, + .code = KEY_PAUSE, + .desc = "Hold", + .type = EV_KEY, }, }; +static struct gpio_keys_platform_data gta02_buttons_pdata = { + .buttons = gta02_buttons, + .nbuttons = ARRAY_SIZE(gta02_buttons), +}; + static struct platform_device gta02_button_dev = { - .name = "gta02-button", - .num_resources = ARRAY_SIZE(gta02_button_resources), - .resource = gta02_button_resources, + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = >a02_buttons_pdata, + }, }; static struct platform_device gta02_pm_usbhost_dev = { .name = "gta02-pm-host", }; - /* USB */ static struct s3c2410_hcd_info gta02_usb_info = { .port[0] = { @@ -1637,6 +1637,57 @@ static void gta02_poweroff(void) PCF50633_OOCSHDWN_GOSTDBY, PCF50633_OOCSHDWN_GOSTDBY); } + +/* On hardware rev 5 and earlier the leds are missing a resistor and reading + * from their gpio pins will always return 0, so we have to shadow the + * led states software */ +static unsigned long gpb_shadow; +extern struct s3c_gpio_chip s3c24xx_gpios[]; + +static void gta02_gpb_set(struct gpio_chip *chip, + unsigned offset, int value) +{ + void __iomem *base = S3C24XX_GPIO_BASE(S3C2410_GPB0); + unsigned long flags; + unsigned long dat; + + local_irq_save(flags); + + dat = __raw_readl(base + 0x04) | gpb_shadow; + dat &= ~(1 << offset); + gpb_shadow &= ~(1 << offset); + if (value) { + dat |= 1 << offset; + switch (offset) { + case 0 ... 2: + gpb_shadow |= 1 << offset; + break; + default: + break; + } + } + __raw_writel(dat, base + 0x04); + + local_irq_restore(flags); +} + +static int gta02_gpb_get(struct gpio_chip *chip, unsigned offset) +{ + void __iomem *base = S3C24XX_GPIO_BASE(S3C2410_GPB0); + unsigned long val; + + val = __raw_readl(base + 0x04) | gpb_shadow; + val >>= offset; + val &= 1; + + return val; +} + +static void gta02_hijack_gpb(void) { + s3c24xx_gpios[1].chip.set = gta02_gpb_set; + s3c24xx_gpios[1].chip.get = gta02_gpb_get; +} + static void __init gta02_machine_init(void) { int rc; @@ -1653,6 +1704,8 @@ static void __init gta02_machine_init(void) default: break; } + if (S3C_SYSTEM_REV_ATAG <= GTA02v5_SYSTEM_REV) + gta02_hijack_gpb(); spin_lock_init(&motion_irq_lock);