diff mbox

[3/3] input: keyboard: MCS5080: support led blink when it's touched.

Message ID 4CE0B81A.9030501@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kim, HeungJun Nov. 15, 2010, 4:33 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c
index 931b28c..e3fd31f 100644
--- a/drivers/input/keyboard/mcs_touchkey.c
+++ b/drivers/input/keyboard/mcs_touchkey.c
@@ -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) {