diff options
Diffstat (limited to 'drivers/input/keyboard/pxa27x_keypad.c')
-rw-r--r-- | drivers/input/keyboard/pxa27x_keypad.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 29fe1b2be1c1..7f7b72464a37 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -311,7 +311,15 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) | |||
311 | if (pdata->enable_rotary0 || pdata->enable_rotary1) | 311 | if (pdata->enable_rotary0 || pdata->enable_rotary1) |
312 | pxa27x_keypad_scan_rotary(keypad); | 312 | pxa27x_keypad_scan_rotary(keypad); |
313 | 313 | ||
314 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; | 314 | /* |
315 | * The KPDR_DK only output the key pin level, so it relates to board, | ||
316 | * and low level may be active. | ||
317 | */ | ||
318 | if (pdata->direct_key_low_active) | ||
319 | new_state = ~KPDK_DK(kpdk) & keypad->direct_key_mask; | ||
320 | else | ||
321 | new_state = KPDK_DK(kpdk) & keypad->direct_key_mask; | ||
322 | |||
315 | bits_changed = keypad->direct_key_state ^ new_state; | 323 | bits_changed = keypad->direct_key_state ^ new_state; |
316 | 324 | ||
317 | if (bits_changed == 0) | 325 | if (bits_changed == 0) |
@@ -383,7 +391,14 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) | |||
383 | if (pdata->direct_key_num > direct_key_num) | 391 | if (pdata->direct_key_num > direct_key_num) |
384 | direct_key_num = pdata->direct_key_num; | 392 | direct_key_num = pdata->direct_key_num; |
385 | 393 | ||
386 | keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask; | 394 | /* |
395 | * Direct keys usage may not start from KP_DKIN0, check the platfrom | ||
396 | * mask data to config the specific. | ||
397 | */ | ||
398 | if (pdata->direct_key_mask) | ||
399 | keypad->direct_key_mask = pdata->direct_key_mask; | ||
400 | else | ||
401 | keypad->direct_key_mask = ((1 << direct_key_num) - 1) & ~mask; | ||
387 | 402 | ||
388 | /* enable direct key */ | 403 | /* enable direct key */ |
389 | if (direct_key_num) | 404 | if (direct_key_num) |
@@ -399,7 +414,7 @@ static int pxa27x_keypad_open(struct input_dev *dev) | |||
399 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); | 414 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); |
400 | 415 | ||
401 | /* Enable unit clock */ | 416 | /* Enable unit clock */ |
402 | clk_enable(keypad->clk); | 417 | clk_prepare_enable(keypad->clk); |
403 | pxa27x_keypad_config(keypad); | 418 | pxa27x_keypad_config(keypad); |
404 | 419 | ||
405 | return 0; | 420 | return 0; |
@@ -410,7 +425,7 @@ static void pxa27x_keypad_close(struct input_dev *dev) | |||
410 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); | 425 | struct pxa27x_keypad *keypad = input_get_drvdata(dev); |
411 | 426 | ||
412 | /* Disable clock unit */ | 427 | /* Disable clock unit */ |
413 | clk_disable(keypad->clk); | 428 | clk_disable_unprepare(keypad->clk); |
414 | } | 429 | } |
415 | 430 | ||
416 | #ifdef CONFIG_PM | 431 | #ifdef CONFIG_PM |
@@ -419,10 +434,14 @@ static int pxa27x_keypad_suspend(struct device *dev) | |||
419 | struct platform_device *pdev = to_platform_device(dev); | 434 | struct platform_device *pdev = to_platform_device(dev); |
420 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 435 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
421 | 436 | ||
422 | clk_disable(keypad->clk); | 437 | /* |
423 | 438 | * If the keypad is used a wake up source, clock can not be disabled. | |
439 | * Or it can not detect the key pressing. | ||
440 | */ | ||
424 | if (device_may_wakeup(&pdev->dev)) | 441 | if (device_may_wakeup(&pdev->dev)) |
425 | enable_irq_wake(keypad->irq); | 442 | enable_irq_wake(keypad->irq); |
443 | else | ||
444 | clk_disable_unprepare(keypad->clk); | ||
426 | 445 | ||
427 | return 0; | 446 | return 0; |
428 | } | 447 | } |
@@ -433,19 +452,24 @@ static int pxa27x_keypad_resume(struct device *dev) | |||
433 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); | 452 | struct pxa27x_keypad *keypad = platform_get_drvdata(pdev); |
434 | struct input_dev *input_dev = keypad->input_dev; | 453 | struct input_dev *input_dev = keypad->input_dev; |
435 | 454 | ||
436 | if (device_may_wakeup(&pdev->dev)) | 455 | /* |
456 | * If the keypad is used as wake up source, the clock is not turned | ||
457 | * off. So do not need configure it again. | ||
458 | */ | ||
459 | if (device_may_wakeup(&pdev->dev)) { | ||
437 | disable_irq_wake(keypad->irq); | 460 | disable_irq_wake(keypad->irq); |
461 | } else { | ||
462 | mutex_lock(&input_dev->mutex); | ||
438 | 463 | ||
439 | mutex_lock(&input_dev->mutex); | 464 | if (input_dev->users) { |
465 | /* Enable unit clock */ | ||
466 | clk_prepare_enable(keypad->clk); | ||
467 | pxa27x_keypad_config(keypad); | ||
468 | } | ||
440 | 469 | ||
441 | if (input_dev->users) { | 470 | mutex_unlock(&input_dev->mutex); |
442 | /* Enable unit clock */ | ||
443 | clk_enable(keypad->clk); | ||
444 | pxa27x_keypad_config(keypad); | ||
445 | } | 471 | } |
446 | 472 | ||
447 | mutex_unlock(&input_dev->mutex); | ||
448 | |||
449 | return 0; | 473 | return 0; |
450 | } | 474 | } |
451 | 475 | ||