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