diff options
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/Kconfig | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/imx_keypad.c | 3 | ||||
-rw-r--r-- | drivers/input/keyboard/omap-keypad.c | 154 |
3 files changed, 38 insertions, 121 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index c50fa75416f8..b4b65af8612a 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -533,7 +533,7 @@ config KEYBOARD_DAVINCI | |||
533 | 533 | ||
534 | config KEYBOARD_OMAP | 534 | config KEYBOARD_OMAP |
535 | tristate "TI OMAP keypad support" | 535 | tristate "TI OMAP keypad support" |
536 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 536 | depends on ARCH_OMAP1 |
537 | select INPUT_MATRIXKMAP | 537 | select INPUT_MATRIXKMAP |
538 | help | 538 | help |
539 | Say Y here if you want to use the OMAP keypad. | 539 | Say Y here if you want to use the OMAP keypad. |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index ff4c0a87a25f..ce68e361558c 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -358,6 +358,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad) | |||
358 | /* Inhibit KDI and KRI interrupts. */ | 358 | /* Inhibit KDI and KRI interrupts. */ |
359 | reg_val = readw(keypad->mmio_base + KPSR); | 359 | reg_val = readw(keypad->mmio_base + KPSR); |
360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | 360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); |
361 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
361 | writew(reg_val, keypad->mmio_base + KPSR); | 362 | writew(reg_val, keypad->mmio_base + KPSR); |
362 | 363 | ||
363 | /* Colums as open drain and disable all rows */ | 364 | /* Colums as open drain and disable all rows */ |
@@ -515,7 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev) | |||
515 | input_set_drvdata(input_dev, keypad); | 516 | input_set_drvdata(input_dev, keypad); |
516 | 517 | ||
517 | /* Ensure that the keypad will stay dormant until opened */ | 518 | /* Ensure that the keypad will stay dormant until opened */ |
519 | clk_enable(keypad->clk); | ||
518 | imx_keypad_inhibit(keypad); | 520 | imx_keypad_inhibit(keypad); |
521 | clk_disable(keypad->clk); | ||
519 | 522 | ||
520 | error = request_irq(irq, imx_keypad_irq_handler, 0, | 523 | error = request_irq(irq, imx_keypad_irq_handler, 0, |
521 | pdev->name, keypad); | 524 | pdev->name, keypad); |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index a0222db4dc86..2bda5f0b9c6e 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -35,13 +35,9 @@ | |||
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <asm/gpio.h> | 38 | #include <linux/gpio.h> |
39 | #include <linux/platform_data/gpio-omap.h> | ||
39 | #include <plat/keypad.h> | 40 | #include <plat/keypad.h> |
40 | #include <plat/menelaus.h> | ||
41 | #include <asm/irq.h> | ||
42 | #include <mach/hardware.h> | ||
43 | #include <asm/io.h> | ||
44 | #include <plat/mux.h> | ||
45 | 41 | ||
46 | #undef NEW_BOARD_LEARNING_MODE | 42 | #undef NEW_BOARD_LEARNING_MODE |
47 | 43 | ||
@@ -96,28 +92,8 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp) | |||
96 | 92 | ||
97 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) | 93 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) |
98 | { | 94 | { |
99 | struct omap_kp *omap_kp = dev_id; | ||
100 | |||
101 | /* disable keyboard interrupt and schedule for handling */ | 95 | /* disable keyboard interrupt and schedule for handling */ |
102 | if (cpu_is_omap24xx()) { | 96 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
103 | int i; | ||
104 | |||
105 | for (i = 0; i < omap_kp->rows; i++) { | ||
106 | int gpio_irq = gpio_to_irq(row_gpios[i]); | ||
107 | /* | ||
108 | * The interrupt which we're currently handling should | ||
109 | * be disabled _nosync() to avoid deadlocks waiting | ||
110 | * for this handler to complete. All others should | ||
111 | * be disabled the regular way for SMP safety. | ||
112 | */ | ||
113 | if (gpio_irq == irq) | ||
114 | disable_irq_nosync(gpio_irq); | ||
115 | else | ||
116 | disable_irq(gpio_irq); | ||
117 | } | ||
118 | } else | ||
119 | /* disable keyboard interrupt and schedule for handling */ | ||
120 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
121 | 97 | ||
122 | tasklet_schedule(&kp_tasklet); | 98 | tasklet_schedule(&kp_tasklet); |
123 | 99 | ||
@@ -133,33 +109,22 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state) | |||
133 | { | 109 | { |
134 | int col = 0; | 110 | int col = 0; |
135 | 111 | ||
136 | /* read the keypad status */ | 112 | /* disable keyboard interrupt and schedule for handling */ |
137 | if (cpu_is_omap24xx()) { | 113 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
138 | /* read the keypad status */ | ||
139 | for (col = 0; col < omap_kp->cols; col++) { | ||
140 | set_col_gpio_val(omap_kp, ~(1 << col)); | ||
141 | state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff; | ||
142 | } | ||
143 | set_col_gpio_val(omap_kp, 0); | ||
144 | |||
145 | } else { | ||
146 | /* disable keyboard interrupt and schedule for handling */ | ||
147 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
148 | 114 | ||
149 | /* read the keypad status */ | 115 | /* read the keypad status */ |
150 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 116 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); |
151 | for (col = 0; col < omap_kp->cols; col++) { | 117 | for (col = 0; col < omap_kp->cols; col++) { |
152 | omap_writew(~(1 << col) & 0xff, | 118 | omap_writew(~(1 << col) & 0xff, |
153 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 119 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); |
154 | 120 | ||
155 | udelay(omap_kp->delay); | 121 | udelay(omap_kp->delay); |
156 | 122 | ||
157 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + | 123 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + |
158 | OMAP_MPUIO_KBR_LATCH) & 0xff; | 124 | OMAP_MPUIO_KBR_LATCH) & 0xff; |
159 | } | ||
160 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
161 | udelay(2); | ||
162 | } | 125 | } |
126 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
127 | udelay(2); | ||
163 | } | 128 | } |
164 | 129 | ||
165 | static void omap_kp_tasklet(unsigned long data) | 130 | static void omap_kp_tasklet(unsigned long data) |
@@ -222,14 +187,8 @@ static void omap_kp_tasklet(unsigned long data) | |||
222 | mod_timer(&omap_kp_data->timer, jiffies + delay); | 187 | mod_timer(&omap_kp_data->timer, jiffies + delay); |
223 | } else { | 188 | } else { |
224 | /* enable interrupts */ | 189 | /* enable interrupts */ |
225 | if (cpu_is_omap24xx()) { | 190 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
226 | int i; | 191 | kp_cur_group = -1; |
227 | for (i = 0; i < omap_kp_data->rows; i++) | ||
228 | enable_irq(gpio_to_irq(row_gpios[i])); | ||
229 | } else { | ||
230 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
231 | kp_cur_group = -1; | ||
232 | } | ||
233 | } | 192 | } |
234 | } | 193 | } |
235 | 194 | ||
@@ -242,6 +201,7 @@ static ssize_t omap_kp_enable_show(struct device *dev, | |||
242 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, | 201 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, |
243 | const char *buf, size_t count) | 202 | const char *buf, size_t count) |
244 | { | 203 | { |
204 | struct omap_kp *omap_kp = dev_get_drvdata(dev); | ||
245 | int state; | 205 | int state; |
246 | 206 | ||
247 | if (sscanf(buf, "%u", &state) != 1) | 207 | if (sscanf(buf, "%u", &state) != 1) |
@@ -253,9 +213,9 @@ static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute | |||
253 | mutex_lock(&kp_enable_mutex); | 213 | mutex_lock(&kp_enable_mutex); |
254 | if (state != kp_enable) { | 214 | if (state != kp_enable) { |
255 | if (state) | 215 | if (state) |
256 | enable_irq(INT_KEYBOARD); | 216 | enable_irq(omap_kp->irq); |
257 | else | 217 | else |
258 | disable_irq(INT_KEYBOARD); | 218 | disable_irq(omap_kp->irq); |
259 | kp_enable = state; | 219 | kp_enable = state; |
260 | } | 220 | } |
261 | mutex_unlock(&kp_enable_mutex); | 221 | mutex_unlock(&kp_enable_mutex); |
@@ -289,7 +249,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
289 | struct omap_kp *omap_kp; | 249 | struct omap_kp *omap_kp; |
290 | struct input_dev *input_dev; | 250 | struct input_dev *input_dev; |
291 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; | 251 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; |
292 | int i, col_idx, row_idx, irq_idx, ret; | 252 | int i, col_idx, row_idx, ret; |
293 | unsigned int row_shift, keycodemax; | 253 | unsigned int row_shift, keycodemax; |
294 | 254 | ||
295 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { | 255 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { |
@@ -314,8 +274,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
314 | omap_kp->input = input_dev; | 274 | omap_kp->input = input_dev; |
315 | 275 | ||
316 | /* Disable the interrupt for the MPUIO keyboard */ | 276 | /* Disable the interrupt for the MPUIO keyboard */ |
317 | if (!cpu_is_omap24xx()) | 277 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
318 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
319 | 278 | ||
320 | if (pdata->delay) | 279 | if (pdata->delay) |
321 | omap_kp->delay = pdata->delay; | 280 | omap_kp->delay = pdata->delay; |
@@ -328,31 +287,8 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
328 | omap_kp->rows = pdata->rows; | 287 | omap_kp->rows = pdata->rows; |
329 | omap_kp->cols = pdata->cols; | 288 | omap_kp->cols = pdata->cols; |
330 | 289 | ||
331 | if (cpu_is_omap24xx()) { | 290 | col_idx = 0; |
332 | /* Cols: outputs */ | 291 | row_idx = 0; |
333 | for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { | ||
334 | if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) { | ||
335 | printk(KERN_ERR "Failed to request" | ||
336 | "GPIO%d for keypad\n", | ||
337 | col_gpios[col_idx]); | ||
338 | goto err1; | ||
339 | } | ||
340 | gpio_direction_output(col_gpios[col_idx], 0); | ||
341 | } | ||
342 | /* Rows: inputs */ | ||
343 | for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { | ||
344 | if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) { | ||
345 | printk(KERN_ERR "Failed to request" | ||
346 | "GPIO%d for keypad\n", | ||
347 | row_gpios[row_idx]); | ||
348 | goto err2; | ||
349 | } | ||
350 | gpio_direction_input(row_gpios[row_idx]); | ||
351 | } | ||
352 | } else { | ||
353 | col_idx = 0; | ||
354 | row_idx = 0; | ||
355 | } | ||
356 | 292 | ||
357 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); | 293 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); |
358 | 294 | ||
@@ -394,27 +330,16 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
394 | 330 | ||
395 | /* scan current status and enable interrupt */ | 331 | /* scan current status and enable interrupt */ |
396 | omap_kp_scan_keypad(omap_kp, keypad_state); | 332 | omap_kp_scan_keypad(omap_kp, keypad_state); |
397 | if (!cpu_is_omap24xx()) { | 333 | omap_kp->irq = platform_get_irq(pdev, 0); |
398 | omap_kp->irq = platform_get_irq(pdev, 0); | 334 | if (omap_kp->irq >= 0) { |
399 | if (omap_kp->irq >= 0) { | 335 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, |
400 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, | 336 | "omap-keypad", omap_kp) < 0) |
401 | "omap-keypad", omap_kp) < 0) | 337 | goto err4; |
402 | goto err4; | ||
403 | } | ||
404 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
405 | } else { | ||
406 | for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) { | ||
407 | if (request_irq(gpio_to_irq(row_gpios[irq_idx]), | ||
408 | omap_kp_interrupt, | ||
409 | IRQF_TRIGGER_FALLING, | ||
410 | "omap-keypad", omap_kp) < 0) | ||
411 | goto err5; | ||
412 | } | ||
413 | } | 338 | } |
339 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
340 | |||
414 | return 0; | 341 | return 0; |
415 | err5: | 342 | |
416 | for (i = irq_idx - 1; i >=0; i--) | ||
417 | free_irq(row_gpios[i], omap_kp); | ||
418 | err4: | 343 | err4: |
419 | input_unregister_device(omap_kp->input); | 344 | input_unregister_device(omap_kp->input); |
420 | input_dev = NULL; | 345 | input_dev = NULL; |
@@ -423,7 +348,6 @@ err3: | |||
423 | err2: | 348 | err2: |
424 | for (i = row_idx - 1; i >=0; i--) | 349 | for (i = row_idx - 1; i >=0; i--) |
425 | gpio_free(row_gpios[i]); | 350 | gpio_free(row_gpios[i]); |
426 | err1: | ||
427 | for (i = col_idx - 1; i >=0; i--) | 351 | for (i = col_idx - 1; i >=0; i--) |
428 | gpio_free(col_gpios[i]); | 352 | gpio_free(col_gpios[i]); |
429 | 353 | ||
@@ -439,18 +363,8 @@ static int __devexit omap_kp_remove(struct platform_device *pdev) | |||
439 | 363 | ||
440 | /* disable keypad interrupt handling */ | 364 | /* disable keypad interrupt handling */ |
441 | tasklet_disable(&kp_tasklet); | 365 | tasklet_disable(&kp_tasklet); |
442 | if (cpu_is_omap24xx()) { | 366 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
443 | int i; | 367 | free_irq(omap_kp->irq, omap_kp); |
444 | for (i = 0; i < omap_kp->cols; i++) | ||
445 | gpio_free(col_gpios[i]); | ||
446 | for (i = 0; i < omap_kp->rows; i++) { | ||
447 | gpio_free(row_gpios[i]); | ||
448 | free_irq(gpio_to_irq(row_gpios[i]), omap_kp); | ||
449 | } | ||
450 | } else { | ||
451 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
452 | free_irq(omap_kp->irq, omap_kp); | ||
453 | } | ||
454 | 368 | ||
455 | del_timer_sync(&omap_kp->timer); | 369 | del_timer_sync(&omap_kp->timer); |
456 | tasklet_kill(&kp_tasklet); | 370 | tasklet_kill(&kp_tasklet); |