0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/i2c.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/delay.h>
0015 #include <linux/input.h>
0016 #include <linux/slab.h>
0017 #include <linux/bitops.h>
0018
0019 struct dir685_touchkeys {
0020 struct device *dev;
0021 struct i2c_client *client;
0022 struct input_dev *input;
0023 unsigned long cur_key;
0024 u16 codes[7];
0025 };
0026
0027 static irqreturn_t dir685_tk_irq_thread(int irq, void *data)
0028 {
0029 struct dir685_touchkeys *tk = data;
0030 const int num_bits = min_t(int, ARRAY_SIZE(tk->codes), 16);
0031 unsigned long changed;
0032 u8 buf[6];
0033 unsigned long key;
0034 int i;
0035 int err;
0036
0037 memset(buf, 0, sizeof(buf));
0038 err = i2c_master_recv(tk->client, buf, sizeof(buf));
0039 if (err != sizeof(buf)) {
0040 dev_err(tk->dev, "short read %d\n", err);
0041 return IRQ_HANDLED;
0042 }
0043
0044 dev_dbg(tk->dev, "IN: %*ph\n", (int)sizeof(buf), buf);
0045 key = be16_to_cpup((__be16 *) &buf[4]);
0046
0047
0048 changed = tk->cur_key ^ key;
0049 for_each_set_bit(i, &changed, num_bits) {
0050 dev_dbg(tk->dev, "key %d is %s\n", i,
0051 test_bit(i, &key) ? "down" : "up");
0052 input_report_key(tk->input, tk->codes[i], test_bit(i, &key));
0053 }
0054
0055
0056 tk->cur_key = key;
0057 input_sync(tk->input);
0058
0059 return IRQ_HANDLED;
0060 }
0061
0062 static int dir685_tk_probe(struct i2c_client *client,
0063 const struct i2c_device_id *id)
0064 {
0065 struct dir685_touchkeys *tk;
0066 struct device *dev = &client->dev;
0067 u8 bl_data[] = { 0xa7, 0x40 };
0068 int err;
0069 int i;
0070
0071 tk = devm_kzalloc(&client->dev, sizeof(*tk), GFP_KERNEL);
0072 if (!tk)
0073 return -ENOMEM;
0074
0075 tk->input = devm_input_allocate_device(dev);
0076 if (!tk->input)
0077 return -ENOMEM;
0078
0079 tk->client = client;
0080 tk->dev = dev;
0081
0082 tk->input->keycodesize = sizeof(u16);
0083 tk->input->keycodemax = ARRAY_SIZE(tk->codes);
0084 tk->input->keycode = tk->codes;
0085 tk->codes[0] = KEY_UP;
0086 tk->codes[1] = KEY_DOWN;
0087 tk->codes[2] = KEY_LEFT;
0088 tk->codes[3] = KEY_RIGHT;
0089 tk->codes[4] = KEY_ENTER;
0090 tk->codes[5] = KEY_WPS_BUTTON;
0091
0092
0093
0094
0095 tk->codes[6] = KEY_RESERVED;
0096
0097 __set_bit(EV_KEY, tk->input->evbit);
0098 for (i = 0; i < ARRAY_SIZE(tk->codes); i++)
0099 __set_bit(tk->codes[i], tk->input->keybit);
0100 __clear_bit(KEY_RESERVED, tk->input->keybit);
0101
0102 tk->input->name = "D-Link DIR-685 touchkeys";
0103 tk->input->id.bustype = BUS_I2C;
0104
0105 err = input_register_device(tk->input);
0106 if (err)
0107 return err;
0108
0109
0110 err = i2c_master_send(client, bl_data, sizeof(bl_data));
0111 if (err != sizeof(bl_data))
0112 dev_warn(tk->dev, "error setting brightness level\n");
0113
0114 if (!client->irq) {
0115 dev_err(dev, "no IRQ on the I2C device\n");
0116 return -ENODEV;
0117 }
0118 err = devm_request_threaded_irq(dev, client->irq,
0119 NULL, dir685_tk_irq_thread,
0120 IRQF_ONESHOT,
0121 "dir685-tk", tk);
0122 if (err) {
0123 dev_err(dev, "can't request IRQ\n");
0124 return err;
0125 }
0126
0127 return 0;
0128 }
0129
0130 static const struct i2c_device_id dir685_tk_id[] = {
0131 { "dir685tk", 0 },
0132 { }
0133 };
0134 MODULE_DEVICE_TABLE(i2c, dir685_tk_id);
0135
0136 #ifdef CONFIG_OF
0137 static const struct of_device_id dir685_tk_of_match[] = {
0138 { .compatible = "dlink,dir685-touchkeys" },
0139 {},
0140 };
0141 MODULE_DEVICE_TABLE(of, dir685_tk_of_match);
0142 #endif
0143
0144 static struct i2c_driver dir685_tk_i2c_driver = {
0145 .driver = {
0146 .name = "dlink-dir685-touchkeys",
0147 .of_match_table = of_match_ptr(dir685_tk_of_match),
0148 },
0149 .probe = dir685_tk_probe,
0150 .id_table = dir685_tk_id,
0151 };
0152 module_i2c_driver(dir685_tk_i2c_driver);
0153
0154 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
0155 MODULE_DESCRIPTION("D-Link DIR-685 touchkeys driver");
0156 MODULE_LICENSE("GPL");