From eda91f0bc520a44f3645451bfe5ee6beb67d34be Mon Sep 17 00:00:00 2001 From: luowei Date: Tue, 12 Apr 2011 09:30:11 +0800 Subject: [PATCH] add power off support for a22 --- arch/arm/mach-rk29/board-rk29-a22-key.c | 21 ++++++---- arch/arm/mach-rk29/board-rk29-a22.c | 2 + drivers/input/keyboard/rk29_keys.c | 17 ++++++--- drivers/mfd/wm831x-spi-a22.c | 51 ++++++++++++++++++++----- 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-rk29/board-rk29-a22-key.c b/arch/arm/mach-rk29/board-rk29-a22-key.c index 59d7f762c291..42acf145e88b 100755 --- a/arch/arm/mach-rk29/board-rk29-a22-key.c +++ b/arch/arm/mach-rk29/board-rk29-a22-key.c @@ -9,8 +9,8 @@ static struct rk29_keys_button key_button[] = { { - .desc = "menu", - .code = EV_MENU, + .desc = "esc", + .code = KEY_BACK, .gpio = RK29_PIN6_PA0, .active_low = PRESS_LEV_LOW, }, @@ -27,29 +27,33 @@ static struct rk29_keys_button key_button[] = { .active_low = PRESS_LEV_LOW, }, { - .desc = "home", - .code = KEY_HOME, + .desc = "menu", + .code = KEY_MENU, .gpio = RK29_PIN6_PA3, .active_low = PRESS_LEV_LOW, }, + { - .desc = "search", - .code = KEY_SEARCH, + .desc = "home", + .code = KEY_HOME, .gpio = RK29_PIN6_PA4, .active_low = PRESS_LEV_LOW, }, + { - .desc = "esc", - .code = KEY_BACK, + .desc = "play", + .code = KEY_POWER, .gpio = RK29_PIN6_PA5, .active_low = PRESS_LEV_LOW, }, + { .desc = "sensor", .code = KEY_CAMERA, .gpio = RK29_PIN6_PA6, .active_low = PRESS_LEV_LOW, }, +#if 0 { .desc = "play", .code = KEY_POWER, @@ -57,6 +61,7 @@ static struct rk29_keys_button key_button[] = { .active_low = PRESS_LEV_LOW, .wakeup = 1, }, +#endif #if 0 { .desc = "vol+", diff --git a/arch/arm/mach-rk29/board-rk29-a22.c b/arch/arm/mach-rk29/board-rk29-a22.c index e9207c8d3e39..3be113532186 100755 --- a/arch/arm/mach-rk29/board-rk29-a22.c +++ b/arch/arm/mach-rk29/board-rk29-a22.c @@ -2949,9 +2949,11 @@ static void __init machine_rk29_init_irq(void) } #define POWER_ON_PIN RK29_PIN4_PA4 +extern void wm831x_power_off(void); static void rk29_pm_power_off(void) { printk(KERN_ERR "rk29_pm_power_off start...\n"); + wm831x_power_off(); gpio_direction_output(POWER_ON_PIN, GPIO_LOW); while (1); } diff --git a/drivers/input/keyboard/rk29_keys.c b/drivers/input/keyboard/rk29_keys.c index cc5ac6b84a0b..771e64dd01a6 100755 --- a/drivers/input/keyboard/rk29_keys.c +++ b/drivers/input/keyboard/rk29_keys.c @@ -59,15 +59,20 @@ struct rk29_keys_drvdata { static struct input_dev *input_dev; -void rk29_send_power_key(void) +void rk29_send_power_key(int state) { if (!input_dev) return; - - input_report_key(input_dev, KEY_POWER, 1); - input_sync(input_dev); - input_report_key(input_dev, KEY_POWER, 0); - input_sync(input_dev); + if(state) + { + input_report_key(input_dev, KEY_POWER, 1); + input_sync(input_dev); + } + else + { + input_report_key(input_dev, KEY_POWER, 0); + input_sync(input_dev); + } } void rk28_send_wakeup_key(void) diff --git a/drivers/mfd/wm831x-spi-a22.c b/drivers/mfd/wm831x-spi-a22.c index 0a4921f46dd3..392faf002fff 100755 --- a/drivers/mfd/wm831x-spi-a22.c +++ b/drivers/mfd/wm831x-spi-a22.c @@ -532,20 +532,47 @@ static int wm831x_init(struct wm831x *wm831x) } -extern void rk29_send_power_key(void); -static int gNumInt = 0; +extern void rk29_send_power_key(int state); +static int gNumInt = 0, gNumTimer = 0; +static struct timer_list irq_timer; +static struct wm831x *gwm831x; -static void wm831x_irq_worker(struct work_struct *work) +void wm831x_power_off(void) { - struct wm831x *wm831x = container_of(work, struct wm831x, irq_work); - wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1, 0xffff);//clear all intterupt + wm831x_reg_write(gwm831x, WM831X_POWER_STATE, 0);//power off +} - if(++ gNumInt >= 2) +static void wm831x_irq_timer(unsigned long data) +{ + struct wm831x *wm831x = (struct wm831x *)data; + int pin = irq_to_gpio(wm831x->irq); + + if(gNumInt >0) { - rk29_send_power_key(); - //wake_lock_timeout(&wm831x->irq_wake,msecs_to_jiffies(2000)); - gNumInt = 0; + if(gpio_get_value(pin) > 0) + gNumTimer++; + else + gNumTimer = 0; + + if(gNumTimer >20) + { + rk29_send_power_key(0); + gNumTimer = 0; + gNumInt = 0; + } } + + irq_timer.expires = jiffies + msecs_to_jiffies(20); + add_timer(&irq_timer); + +} + +static void wm831x_irq_worker(struct work_struct *work) +{ + struct wm831x *wm831x = container_of(work, struct wm831x, irq_work); + wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1, 0xffff);//clear all intterupt + gNumInt++; + rk29_send_power_key(1); enable_irq(wm831x->irq); wake_unlock(&wm831x->irq_wake); //printk("%s,irq=%d\n",__FUNCTION__,wm831x->irq); @@ -611,7 +638,7 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi) wm831x->control_data = spi; wm831x->read_dev = wm831x_spi_read_device; wm831x->write_dev = wm831x_spi_write_device; - + gwm831x = wm831x; mutex_init(&wm831x->io_lock); wm831x_init(wm831x); @@ -639,6 +666,10 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi) wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0xefff); wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK, 0xefff); + setup_timer(&irq_timer, wm831x_irq_timer, (unsigned long)wm831x); + irq_timer.expires = jiffies+2000; + add_timer(&irq_timer); + return 0; //return wm831x_device_init(wm831x, type, irq); } -- 2.34.1