diff options
| -rw-r--r-- | drivers/input/keyboard/omap4-keypad.c | 74 |
1 files changed, 55 insertions, 19 deletions
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 45bd0977d006..c51a3c4a7feb 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
| 30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/pm_runtime.h> | ||
| 32 | 33 | ||
| 33 | #include <plat/omap4-keypad.h> | 34 | #include <plat/omap4-keypad.h> |
| 34 | 35 | ||
| @@ -80,20 +81,6 @@ struct omap4_keypad { | |||
| 80 | unsigned short keymap[]; | 81 | unsigned short keymap[]; |
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | static void __devinit omap4_keypad_config(struct omap4_keypad *keypad_data) | ||
| 84 | { | ||
| 85 | __raw_writel(OMAP4_VAL_FUNCTIONALCFG, | ||
| 86 | keypad_data->base + OMAP4_KBD_CTRL); | ||
| 87 | __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, | ||
| 88 | keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); | ||
| 89 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
| 90 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
| 91 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
| 92 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
| 93 | __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA, | ||
| 94 | keypad_data->base + OMAP4_KBD_WAKEUPENABLE); | ||
| 95 | } | ||
| 96 | |||
| 97 | /* Interrupt handler */ | 84 | /* Interrupt handler */ |
| 98 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | 85 | static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) |
| 99 | { | 86 | { |
| @@ -144,6 +131,49 @@ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) | |||
| 144 | return IRQ_HANDLED; | 131 | return IRQ_HANDLED; |
| 145 | } | 132 | } |
| 146 | 133 | ||
| 134 | static int omap4_keypad_open(struct input_dev *input) | ||
| 135 | { | ||
| 136 | struct omap4_keypad *keypad_data = input_get_drvdata(input); | ||
| 137 | |||
| 138 | pm_runtime_get_sync(input->dev.parent); | ||
| 139 | |||
| 140 | disable_irq(keypad_data->irq); | ||
| 141 | |||
| 142 | __raw_writel(OMAP4_VAL_FUNCTIONALCFG, | ||
| 143 | keypad_data->base + OMAP4_KBD_CTRL); | ||
| 144 | __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, | ||
| 145 | keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); | ||
| 146 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
| 147 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
| 148 | __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN | OMAP4_DEF_IRQENABLE_LONGKEY, | ||
| 149 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
| 150 | __raw_writel(OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA, | ||
| 151 | keypad_data->base + OMAP4_KBD_WAKEUPENABLE); | ||
| 152 | |||
| 153 | enable_irq(keypad_data->irq); | ||
| 154 | |||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static void omap4_keypad_close(struct input_dev *input) | ||
| 159 | { | ||
| 160 | struct omap4_keypad *keypad_data = input_get_drvdata(input); | ||
| 161 | |||
| 162 | disable_irq(keypad_data->irq); | ||
| 163 | |||
| 164 | /* Disable interrupts */ | ||
| 165 | __raw_writel(OMAP4_VAL_IRQDISABLE, | ||
| 166 | keypad_data->base + OMAP4_KBD_IRQENABLE); | ||
| 167 | |||
| 168 | /* clear pending interrupts */ | ||
| 169 | __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), | ||
| 170 | keypad_data->base + OMAP4_KBD_IRQSTATUS); | ||
| 171 | |||
| 172 | enable_irq(keypad_data->irq); | ||
| 173 | |||
| 174 | pm_runtime_put_sync(input->dev.parent); | ||
| 175 | } | ||
| 176 | |||
| 147 | static int __devinit omap4_keypad_probe(struct platform_device *pdev) | 177 | static int __devinit omap4_keypad_probe(struct platform_device *pdev) |
| 148 | { | 178 | { |
| 149 | const struct omap4_keypad_platform_data *pdata; | 179 | const struct omap4_keypad_platform_data *pdata; |
| @@ -225,6 +255,9 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) | |||
| 225 | input_dev->id.product = 0x0001; | 255 | input_dev->id.product = 0x0001; |
| 226 | input_dev->id.version = 0x0001; | 256 | input_dev->id.version = 0x0001; |
| 227 | 257 | ||
| 258 | input_dev->open = omap4_keypad_open; | ||
| 259 | input_dev->close = omap4_keypad_close; | ||
| 260 | |||
| 228 | input_dev->keycode = keypad_data->keymap; | 261 | input_dev->keycode = keypad_data->keymap; |
| 229 | input_dev->keycodesize = sizeof(keypad_data->keymap[0]); | 262 | input_dev->keycodesize = sizeof(keypad_data->keymap[0]); |
| 230 | input_dev->keycodemax = max_keys; | 263 | input_dev->keycodemax = max_keys; |
| @@ -239,8 +272,6 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) | |||
| 239 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, | 272 | matrix_keypad_build_keymap(pdata->keymap_data, row_shift, |
| 240 | input_dev->keycode, input_dev->keybit); | 273 | input_dev->keycode, input_dev->keybit); |
| 241 | 274 | ||
| 242 | omap4_keypad_config(keypad_data); | ||
| 243 | |||
| 244 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, | 275 | error = request_irq(keypad_data->irq, omap4_keypad_interrupt, |
| 245 | IRQF_TRIGGER_RISING, | 276 | IRQF_TRIGGER_RISING, |
| 246 | "omap4-keypad", keypad_data); | 277 | "omap4-keypad", keypad_data); |
| @@ -249,17 +280,19 @@ static int __devinit omap4_keypad_probe(struct platform_device *pdev) | |||
| 249 | goto err_free_input; | 280 | goto err_free_input; |
| 250 | } | 281 | } |
| 251 | 282 | ||
| 283 | pm_runtime_enable(&pdev->dev); | ||
| 284 | |||
| 252 | error = input_register_device(keypad_data->input); | 285 | error = input_register_device(keypad_data->input); |
| 253 | if (error < 0) { | 286 | if (error < 0) { |
| 254 | dev_err(&pdev->dev, "failed to register input device\n"); | 287 | dev_err(&pdev->dev, "failed to register input device\n"); |
| 255 | goto err_free_irq; | 288 | goto err_pm_disable; |
| 256 | } | 289 | } |
| 257 | 290 | ||
| 258 | |||
| 259 | platform_set_drvdata(pdev, keypad_data); | 291 | platform_set_drvdata(pdev, keypad_data); |
| 260 | return 0; | 292 | return 0; |
| 261 | 293 | ||
| 262 | err_free_irq: | 294 | err_pm_disable: |
| 295 | pm_runtime_disable(&pdev->dev); | ||
| 263 | free_irq(keypad_data->irq, keypad_data); | 296 | free_irq(keypad_data->irq, keypad_data); |
| 264 | err_free_input: | 297 | err_free_input: |
| 265 | input_free_device(input_dev); | 298 | input_free_device(input_dev); |
| @@ -278,6 +311,9 @@ static int __devexit omap4_keypad_remove(struct platform_device *pdev) | |||
| 278 | struct resource *res; | 311 | struct resource *res; |
| 279 | 312 | ||
| 280 | free_irq(keypad_data->irq, keypad_data); | 313 | free_irq(keypad_data->irq, keypad_data); |
| 314 | |||
| 315 | pm_runtime_disable(&pdev->dev); | ||
| 316 | |||
| 281 | input_unregister_device(keypad_data->input); | 317 | input_unregister_device(keypad_data->input); |
| 282 | 318 | ||
| 283 | iounmap(keypad_data->base); | 319 | iounmap(keypad_data->base); |
