]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/input/keyboard/mpr121_touchkey.c
Input: mpr121 - handle multiple bits change of status register
[karo-tx-linux.git] / drivers / input / keyboard / mpr121_touchkey.c
index 2558c602f09903dd1b9acb52d7982e68cf596947..83dd5616e470358ba68cbc4b084923e4221201dc 100644 (file)
@@ -86,7 +86,8 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
        struct mpr121_touchkey *mpr121 = dev_id;
        struct i2c_client *client = mpr121->client;
        struct input_dev *input = mpr121->input_dev;
-       unsigned int key_num, key_val, pressed;
+       unsigned long bit_changed;
+       unsigned int key_num;
        int reg;
 
        reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR);
@@ -104,18 +105,22 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
 
        reg &= TOUCH_STATUS_MASK;
        /* use old press bit to figure out which bit changed */
-       key_num = ffs(reg ^ mpr121->statusbits) - 1;
-       pressed = reg & (1 << key_num);
+       bit_changed = reg ^ mpr121->statusbits;
        mpr121->statusbits = reg;
+       for_each_set_bit(key_num, &bit_changed, mpr121->keycount) {
+               unsigned int key_val, pressed;
 
-       key_val = mpr121->keycodes[key_num];
+               pressed = reg & BIT(key_num);
+               key_val = mpr121->keycodes[key_num];
 
-       input_event(input, EV_MSC, MSC_SCAN, key_num);
-       input_report_key(input, key_val, pressed);
-       input_sync(input);
+               input_event(input, EV_MSC, MSC_SCAN, key_num);
+               input_report_key(input, key_val, pressed);
+
+               dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val,
+                       pressed ? "pressed" : "released");
 
-       dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val,
-               pressed ? "pressed" : "released");
+       }
+       input_sync(input);
 
 out:
        return IRQ_HANDLED;