Having only 2 buttons is a little bit of a constraining in some
instances. To provide an extra button, I've modified the I2C to send
MENU_KEY when the power button is pressed and released within a second
and POWER_KEY when held past 1 second. It would be nice to do the same
for the other key, but I'm not certain how to accomplish that. I'd
assume I need a timer.
Sean
diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
index 09d5cfd..cf30877 100644
--- a/drivers/i2c/chips/pcf50633.c
+++ b/drivers/i2c/chips/pcf50633.c
@@ -53,7 +53,7 @@
#include "pcf50633.h"
-#if 1
+#if 0
#define DEBUGP(x, args ...) printk("%s: " x, __FUNCTION__, ## args)
#define DEBUGPC(x, args ...) printk(x, ## args)
#else
@@ -77,6 +77,7 @@ I2C_CLIENT_INSMOD_1(pcf50633);
#define PCF50633_FIDX_PWR_PRESSED 8
#define PCF50633_FIDX_RTC_SECOND 9
#define PCF50633_FIDX_USB_PRESENT 10
+#define PCF50633_FIDX_PWR_HELD 11
#define PCF50633_F_CHG_ENABLED (1 << PCF50633_FIDX_CHG_ENABLED)
#define PCF50633_F_CHG_PRESENT (1 << PCF50633_FIDX_CHG_PRESENT)
@@ -89,6 +90,7 @@ I2C_CLIENT_INSMOD_1(pcf50633);
#define PCF50633_F_PWR_PRESSED (1 << PCF50633_FIDX_PWR_PRESSED)
#define PCF50633_F_RTC_SECOND (1 << PCF50633_FIDX_RTC_SECOND)
#define PCF50633_F_USB_PRESENT (1 << PCF50633_FIDX_USB_PRESENT)
+#define PCF50633_F_PWR_HELD (1 << PCF50633_FIDX_PWR_HELD)
enum close_state {
CLOSE_STATE_NOT,
@@ -726,15 +728,18 @@ static void pcf50633_work(struct work_struct *work)
if (pcfirq[1] & PCF50633_INT2_ONKEYF) {
/* ONKEY falling edge (start of button press) */
DEBUGPC("ONKEYF ");
+ input_report_key(pcf->input_dev, KEY_MENU, 1);
pcf->flags |= PCF50633_F_PWR_PRESSED;
- input_report_key(pcf->input_dev, KEY_POWER, 1);
}
if (pcfirq[1] & PCF50633_INT2_ONKEYR) {
/* ONKEY rising edge (end of button press) */
DEBUGPC("ONKEYR ");
- pcf->flags &= ~PCF50633_F_PWR_PRESSED;
+ if (pcf->flags & PCF50633_F_PWR_HELD)
+ input_report_key(pcf->input_dev, KEY_POWER, 0);
+ else
+ input_report_key(pcf->input_dev, KEY_MENU, 0);
+ pcf->flags &= ~(PCF50633_F_PWR_PRESSED|PCF50633_F_PWR_HELD);
pcf->onkey_seconds = -1;
- input_report_key(pcf->input_dev, KEY_POWER, 0);
/* disable SECOND interrupt in case RTC didn't
* request it */
if (!(pcf->flags & PCF50633_F_RTC_SECOND))
@@ -800,8 +805,12 @@ static void pcf50633_work(struct work_struct *work)
}
if (pcfirq[2] & PCF50633_INT3_ONKEY1S) {
/* ONKEY pressed for more than 1 second */
- pcf->onkey_seconds = 0;
DEBUGPC("ONKEY1S ");
+ pcf->onkey_seconds = 0;
+ if (pcf->flags & PCF50633_F_PWR_PRESSED) {
+ pcf->flags |= PCF50633_F_PWR_HELD;
+ input_report_key(pcf->input_dev, KEY_POWER, 1);
+ }
/* Tell PMU we are taking care of this */
reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN,
PCF50633_OOCSHDWN_TOTRST,
@@ -1735,6 +1744,7 @@ static int pcf50633_detect(struct i2c_adapter *adapter, int address, int kind)
data->input_dev->cdev.dev = &new_client->dev;
data->input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
+ set_bit(KEY_MENU, data->input_dev->keybit);
set_bit(KEY_POWER, data->input_dev->keybit);
set_bit(KEY_POWER2, data->input_dev->keybit);
set_bit(KEY_BATTERY, data->input_dev->keybit);