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