1 /* 2 * Wacom Penabled Driver for I2C 3 * 4 * Copyright (c) 2011 - 2013 Tatsunosuke Tobita, Wacom. 5 * <tobita.tatsunosuke@wacom.co.jp> 6 * 7 * This program is free software; you can redistribute it 8 * and/or modify it under the terms of the GNU General 9 * Public License as published by the Free Software 10 * Foundation; either version of 2 of the License, 11 * or (at your option) any later version. 12 */ 13 14 #include <linux/module.h> 15 #include <linux/input.h> 16 #include <linux/i2c.h> 17 #include <linux/slab.h> 18 #include <linux/irq.h> 19 #include <linux/interrupt.h> 20 #include <linux/gpio.h> 21 #include <asm/unaligned.h> 22 23 #define WACOM_CMD_QUERY0 0x04 24 #define WACOM_CMD_QUERY1 0x00 25 #define WACOM_CMD_QUERY2 0x33 26 #define WACOM_CMD_QUERY3 0x02 27 #define WACOM_CMD_THROW0 0x05 28 #define WACOM_CMD_THROW1 0x00 29 #define WACOM_QUERY_SIZE 19 30 31 struct wacom_features { 32 int x_max; 33 int y_max; 34 int pressure_max; 35 char fw_version; 36 }; 37 38 struct wacom_i2c { 39 struct i2c_client *client; 40 struct input_dev *input; 41 u8 data[WACOM_QUERY_SIZE]; 42 bool prox; 43 int tool; 44 }; 45 46 static int wacom_query_device(struct i2c_client *client, 47 struct wacom_features *features) 48 { 49 int ret; 50 u8 cmd1[] = { WACOM_CMD_QUERY0, WACOM_CMD_QUERY1, 51 WACOM_CMD_QUERY2, WACOM_CMD_QUERY3 }; 52 u8 cmd2[] = { WACOM_CMD_THROW0, WACOM_CMD_THROW1 }; 53 u8 data[WACOM_QUERY_SIZE]; 54 struct i2c_msg msgs[] = { 55 { 56 .addr = client->addr, 57 .flags = 0, 58 .len = sizeof(cmd1), 59 .buf = cmd1, 60 }, 61 { 62 .addr = client->addr, 63 .flags = 0, 64 .len = sizeof(cmd2), 65 .buf = cmd2, 66 }, 67 { 68 .addr = client->addr, 69 .flags = I2C_M_RD, 70 .len = sizeof(data), 71 .buf = data, 72 }, 73 }; 74 75 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 76 if (ret < 0) 77 return ret; 78 if (ret != ARRAY_SIZE(msgs)) 79 return -EIO; 80 81 features->x_max = get_unaligned_le16(&data[3]); 82 features->y_max = get_unaligned_le16(&data[5]); 83 features->pressure_max = get_unaligned_le16(&data[11]); 84 features->fw_version = get_unaligned_le16(&data[13]); 85 86 dev_dbg(&client->dev, 87 "x_max:%d, y_max:%d, pressure:%d, fw:%d\n", 88 features->x_max, features->y_max, 89 features->pressure_max, features->fw_version); 90 91 return 0; 92 } 93 94 static irqreturn_t wacom_i2c_irq(int irq, void *dev_id) 95 { 96 struct wacom_i2c *wac_i2c = dev_id; 97 struct input_dev *input = wac_i2c->input; 98 u8 *data = wac_i2c->data; 99 unsigned int x, y, pressure; 100 unsigned char tsw, f1, f2, ers; 101 int error; 102 103 error = i2c_master_recv(wac_i2c->client, 104 wac_i2c->data, sizeof(wac_i2c->data)); 105 if (error < 0) 106 goto out; 107 108 tsw = data[3] & 0x01; 109 ers = data[3] & 0x04; 110 f1 = data[3] & 0x02; 111 f2 = data[3] & 0x10; 112 x = le16_to_cpup((__le16 *)&data[4]); 113 y = le16_to_cpup((__le16 *)&data[6]); 114 pressure = le16_to_cpup((__le16 *)&data[8]); 115 116 if (!wac_i2c->prox) 117 wac_i2c->tool = (data[3] & 0x0c) ? 118 BTN_TOOL_RUBBER : BTN_TOOL_PEN; 119 120 wac_i2c->prox = data[3] & 0x20; 121 122 input_report_key(input, BTN_TOUCH, tsw || ers); 123 input_report_key(input, wac_i2c->tool, wac_i2c->prox); 124 input_report_key(input, BTN_STYLUS, f1); 125 input_report_key(input, BTN_STYLUS2, f2); 126 input_report_abs(input, ABS_X, x); 127 input_report_abs(input, ABS_Y, y); 128 input_report_abs(input, ABS_PRESSURE, pressure); 129 input_sync(input); 130 131 out: 132 return IRQ_HANDLED; 133 } 134 135 static int wacom_i2c_open(struct input_dev *dev) 136 { 137 struct wacom_i2c *wac_i2c = input_get_drvdata(dev); 138 struct i2c_client *client = wac_i2c->client; 139 140 enable_irq(client->irq); 141 142 return 0; 143 } 144 145 static void wacom_i2c_close(struct input_dev *dev) 146 { 147 struct wacom_i2c *wac_i2c = input_get_drvdata(dev); 148 struct i2c_client *client = wac_i2c->client; 149 150 disable_irq(client->irq); 151 } 152 153 static int wacom_i2c_probe(struct i2c_client *client, 154 const struct i2c_device_id *id) 155 { 156 struct wacom_i2c *wac_i2c; 157 struct input_dev *input; 158 struct wacom_features features = { 0 }; 159 int error; 160 161 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 162 dev_err(&client->dev, "i2c_check_functionality error\n"); 163 return -EIO; 164 } 165 166 error = wacom_query_device(client, &features); 167 if (error) 168 return error; 169 170 wac_i2c = kzalloc(sizeof(*wac_i2c), GFP_KERNEL); 171 input = input_allocate_device(); 172 if (!wac_i2c || !input) { 173 error = -ENOMEM; 174 goto err_free_mem; 175 } 176 177 wac_i2c->client = client; 178 wac_i2c->input = input; 179 180 input->name = "Wacom I2C Digitizer"; 181 input->id.bustype = BUS_I2C; 182 input->id.vendor = 0x56a; 183 input->id.version = features.fw_version; 184 input->dev.parent = &client->dev; 185 input->open = wacom_i2c_open; 186 input->close = wacom_i2c_close; 187 188 input->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 189 190 __set_bit(BTN_TOOL_PEN, input->keybit); 191 __set_bit(BTN_TOOL_RUBBER, input->keybit); 192 __set_bit(BTN_STYLUS, input->keybit); 193 __set_bit(BTN_STYLUS2, input->keybit); 194 __set_bit(BTN_TOUCH, input->keybit); 195 196 input_set_abs_params(input, ABS_X, 0, features.x_max, 0, 0); 197 input_set_abs_params(input, ABS_Y, 0, features.y_max, 0, 0); 198 input_set_abs_params(input, ABS_PRESSURE, 199 0, features.pressure_max, 0, 0); 200 201 input_set_drvdata(input, wac_i2c); 202 203 error = request_threaded_irq(client->irq, NULL, wacom_i2c_irq, 204 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 205 "wacom_i2c", wac_i2c); 206 if (error) { 207 dev_err(&client->dev, 208 "Failed to enable IRQ, error: %d\n", error); 209 goto err_free_mem; 210 } 211 212 /* Disable the IRQ, we'll enable it in wac_i2c_open() */ 213 disable_irq(client->irq); 214 215 error = input_register_device(wac_i2c->input); 216 if (error) { 217 dev_err(&client->dev, 218 "Failed to register input device, error: %d\n", error); 219 goto err_free_irq; 220 } 221 222 i2c_set_clientdata(client, wac_i2c); 223 return 0; 224 225 err_free_irq: 226 free_irq(client->irq, wac_i2c); 227 err_free_mem: 228 input_free_device(input); 229 kfree(wac_i2c); 230 231 return error; 232 } 233 234 static int wacom_i2c_remove(struct i2c_client *client) 235 { 236 struct wacom_i2c *wac_i2c = i2c_get_clientdata(client); 237 238 free_irq(client->irq, wac_i2c); 239 input_unregister_device(wac_i2c->input); 240 kfree(wac_i2c); 241 242 return 0; 243 } 244 245 static int __maybe_unused wacom_i2c_suspend(struct device *dev) 246 { 247 struct i2c_client *client = to_i2c_client(dev); 248 249 disable_irq(client->irq); 250 251 return 0; 252 } 253 254 static int __maybe_unused wacom_i2c_resume(struct device *dev) 255 { 256 struct i2c_client *client = to_i2c_client(dev); 257 258 enable_irq(client->irq); 259 260 return 0; 261 } 262 263 static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume); 264 265 static const struct i2c_device_id wacom_i2c_id[] = { 266 { "WAC_I2C_EMR", 0 }, 267 { }, 268 }; 269 MODULE_DEVICE_TABLE(i2c, wacom_i2c_id); 270 271 static struct i2c_driver wacom_i2c_driver = { 272 .driver = { 273 .name = "wacom_i2c", 274 .owner = THIS_MODULE, 275 .pm = &wacom_i2c_pm, 276 }, 277 278 .probe = wacom_i2c_probe, 279 .remove = wacom_i2c_remove, 280 .id_table = wacom_i2c_id, 281 }; 282 module_i2c_driver(wacom_i2c_driver); 283 284 MODULE_AUTHOR("Tatsunosuke Tobita <tobita.tatsunosuke@wacom.co.jp>"); 285 MODULE_DESCRIPTION("WACOM EMR I2C Driver"); 286 MODULE_LICENSE("GPL"); 287