@@ -19,6 +19,7 @@
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/slab.h>
+#include <linux/workqueue.h>
/* MCS5000 Touchkey */
#define MCS5000_TOUCHKEY_STATUS 0x04
@@ -32,6 +33,8 @@
#define MCS5080_TOUCHKEY_FW 0x01
#define MCS5080_TOUCHKEY_BASE_VAL 0x1
+#define LED_TIME 500
+
enum mcs_touchkey_type {
MCS5000_TOUCHKEY,
MCS5080_TOUCHKEY,
@@ -46,6 +49,8 @@ struct mcs_touchkey_chip {
struct mcs_touchkey_data {
void (*poweron)(int);
+ struct delayed_work work;
+ int suspended;
struct i2c_client *client;
struct input_dev *input_dev;
@@ -55,6 +60,30 @@ struct mcs_touchkey_data {
unsigned short keycodes[];
};
+static void mcs_touchkey_led(struct mcs_touchkey_data *data, int on)
+{
+ unsigned char buf;
+
+ if (data->suspended)
+ return;
+
+ if (on)
+ buf = 0x1;
+ else
+ buf = 0x2;
+ i2c_master_send(data->client, &buf, 1);
+}
+
+static void mcs_touchkey_work(struct work_struct *work)
+{
+ struct delayed_work *dw = to_delayed_work(work);
+ struct mcs_touchkey_data *data;
+
+ data = container_of(dw, struct mcs_touchkey_data, work);
+
+ mcs_touchkey_led(data, 0);
+}
+
static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id)
{
struct mcs_touchkey_data *data = dev_id;
@@ -89,6 +118,14 @@ static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id)
input_report_key(input, data->key_code, pressed);
input_sync(input);
+ if (pressed) {
+ cancel_work_sync(&data->work.work);
+ mcs_touchkey_led(data, 1);
+ } else {
+ if (!delayed_work_pending(&data->work))
+ schedule_delayed_work(&data->work, msecs_to_jiffies(LED_TIME));
+ }
+
dev_dbg(&client->dev, "key %d %d %s\n", data->key_val, data->key_code,
pressed ? "pressed" : "released");
@@ -173,6 +210,8 @@ static int __devinit mcs_touchkey_probe(struct i2c_client *client,
if (pdata->poweron)
data->poweron = pdata->poweron;
+ INIT_DELAYED_WORK(&data->work, mcs_touchkey_work);
+
error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt,
IRQF_TRIGGER_FALLING, client->dev.driver->name, data);
if (error) {