diff options
Diffstat (limited to 'drivers/input/keyboard/bf54x-keys.c')
| -rw-r--r-- | drivers/input/keyboard/bf54x-keys.c | 110 |
1 files changed, 65 insertions, 45 deletions
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 05e3494cf8b..e6d46c5994d 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -8,7 +8,7 @@ * * * Modified: - * Copyright 2007 Analog Devices Inc. + * Copyright 2007-2008 Analog Devices Inc. * * Bugs: Enter bugs at http://blackfin.uclinux.org/ * @@ -29,12 +29,11 @@ */ #include <linux/module.h> -#include <linux/version.h> -#include <linux/init.h> #include <linux/fs.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/pm.h> #include <linux/sysctl.h> @@ -44,7 +43,7 @@ #include <linux/input.h> #include <asm/portmux.h> -#include <asm/mach/bf54x_keys.h> +#include <mach/bf54x_keys.h> #define DRV_NAME "bf54x-keys" #define TIME_SCALE 100 /* 100 ns */ @@ -82,6 +81,9 @@ struct bf54x_kpad { unsigned short *keycode; struct timer_list timer; unsigned int keyup_test_jiffies; + unsigned short kpad_msel; + unsigned short kpad_prescale; + unsigned short kpad_ctl; }; static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad, @@ -160,7 +162,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) input_sync(input); if (bfin_kpad_get_keypressed(bf54x_kpad)) { - disable_irq(bf54x_kpad->irq); + disable_irq_nosync(bf54x_kpad->irq); bf54x_kpad->lastkey = key; mod_timer(&bf54x_kpad->timer, jiffies + bf54x_kpad->keyup_test_jiffies); @@ -174,22 +176,21 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit bfin_kpad_probe(struct platform_device *pdev) +static int bfin_kpad_probe(struct platform_device *pdev) { struct bf54x_kpad *bf54x_kpad; - struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; + struct bfin_kpad_platform_data *pdata = dev_get_platdata(&pdev->dev); struct input_dev *input; int i, error; if (!pdata->rows || !pdata->cols || !pdata->keymap) { - printk(KERN_ERR DRV_NAME - ": No rows, cols or keymap from pdata\n"); + dev_err(&pdev->dev, "no rows, cols or keymap from pdata\n"); return -EINVAL; } if (!pdata->keymapsize || pdata->keymapsize > (pdata->rows * pdata->cols)) { - printk(KERN_ERR DRV_NAME ": Invalid keymapsize\n"); + dev_err(&pdev->dev, "invalid keymapsize\n"); return -EINVAL; } @@ -207,10 +208,10 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) goto out; } - if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT || - !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) { - printk(KERN_ERR DRV_NAME - ": Invalid Debounce/Columdrive Time from pdata\n"); + if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || + !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { + dev_warn(&pdev->dev, + "invalid platform debounce/columndrive time\n"); bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ } else { bfin_write_KPAD_MSEL( @@ -229,16 +230,14 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) if (peripheral_request_list((u16 *)&per_rows[MAX_RC - pdata->rows], DRV_NAME)) { - printk(KERN_ERR DRV_NAME - ": Requesting Peripherals failed\n"); + dev_err(&pdev->dev, "requesting peripherals failed\n"); error = -EFAULT; goto out0; } if (peripheral_request_list((u16 *)&per_cols[MAX_RC - pdata->cols], DRV_NAME)) { - printk(KERN_ERR DRV_NAME - ": Requesting Peripherals failed\n"); + dev_err(&pdev->dev, "requesting peripherals failed\n"); error = -EFAULT; goto out1; } @@ -250,11 +249,10 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) } error = request_irq(bf54x_kpad->irq, bfin_kpad_isr, - IRQF_SAMPLE_RANDOM, DRV_NAME, pdev); + 0, DRV_NAME, pdev); if (error) { - printk(KERN_ERR DRV_NAME - ": unable to claim irq %d; error %d\n", - bf54x_kpad->irq, error); + dev_err(&pdev->dev, "unable to claim irq %d\n", + bf54x_kpad->irq); goto out2; } @@ -290,13 +288,13 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) __set_bit(EV_REP, input->evbit); for (i = 0; i < input->keycodemax; i++) - __set_bit(bf54x_kpad->keycode[i] & KEY_MAX, input->keybit); + if (bf54x_kpad->keycode[i] <= KEY_MAX) + __set_bit(bf54x_kpad->keycode[i], input->keybit); __clear_bit(KEY_RESERVED, input->keybit); error = input_register_device(input); if (error) { - printk(KERN_ERR DRV_NAME - ": Unable to register input device (%d)\n", error); + dev_err(&pdev->dev, "unable to register input device\n"); goto out4; } @@ -312,8 +310,7 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) bfin_write_KPAD_CTL(bfin_read_KPAD_CTL() | KPAD_EN); - printk(KERN_ERR DRV_NAME - ": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq); + device_init_wakeup(&pdev->dev, 1); return 0; @@ -329,14 +326,13 @@ out0: kfree(bf54x_kpad->keycode); out: kfree(bf54x_kpad); - platform_set_drvdata(pdev, NULL); return error; } -static int __devexit bfin_kpad_remove(struct platform_device *pdev) +static int bfin_kpad_remove(struct platform_device *pdev) { - struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; + struct bfin_kpad_platform_data *pdata = dev_get_platdata(&pdev->dev); struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); del_timer_sync(&bf54x_kpad->timer); @@ -349,32 +345,56 @@ static int __devexit bfin_kpad_remove(struct platform_device *pdev) kfree(bf54x_kpad->keycode); kfree(bf54x_kpad); - platform_set_drvdata(pdev, NULL); return 0; } -struct platform_driver bfin_kpad_device_driver = { - .probe = bfin_kpad_probe, - .remove = __devexit_p(bfin_kpad_remove), - .driver = { - .name = DRV_NAME, - } -}; - -static int __init bfin_kpad_init(void) +#ifdef CONFIG_PM +static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state) { - return platform_driver_register(&bfin_kpad_device_driver); + struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); + + bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL(); + bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE(); + bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL(); + + if (device_may_wakeup(&pdev->dev)) + enable_irq_wake(bf54x_kpad->irq); + + return 0; } -static void __exit bfin_kpad_exit(void) +static int bfin_kpad_resume(struct platform_device *pdev) { - platform_driver_unregister(&bfin_kpad_device_driver); + struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); + + bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel); + bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale); + bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl); + + if (device_may_wakeup(&pdev->dev)) + disable_irq_wake(bf54x_kpad->irq); + + return 0; } +#else +# define bfin_kpad_suspend NULL +# define bfin_kpad_resume NULL +#endif -module_init(bfin_kpad_init); -module_exit(bfin_kpad_exit); +static struct platform_driver bfin_kpad_device_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = bfin_kpad_probe, + .remove = bfin_kpad_remove, + .suspend = bfin_kpad_suspend, + .resume = bfin_kpad_resume, +}; +module_platform_driver(bfin_kpad_device_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_DESCRIPTION("Keypad driver for BF54x Processors"); +MODULE_ALIAS("platform:bf54x-keys"); |
