2 * Wacom Penabled Driver for I2C
4 * Copyright (c) 2011 - 2013 Tatsunosuke Tobita, Wacom.
5 * <tobita.tatsunosuke@wacom.co.jp>
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.
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>
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
31 struct wacom_features
{
39 struct i2c_client
*client
;
40 struct input_dev
*input
;
41 u8 data
[WACOM_QUERY_SIZE
];
46 static int wacom_query_device(struct i2c_client
*client
,
47 struct wacom_features
*features
)
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
[] = {
75 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
78 if (ret
!= ARRAY_SIZE(msgs
))
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]);
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
);
94 static irqreturn_t
wacom_i2c_irq(int irq
, void *dev_id
)
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
;
103 error
= i2c_master_recv(wac_i2c
->client
,
104 wac_i2c
->data
, sizeof(wac_i2c
->data
));
108 tsw
= data
[3] & 0x01;
109 ers
= data
[3] & 0x04;
112 x
= le16_to_cpup((__le16
*)&data
[4]);
113 y
= le16_to_cpup((__le16
*)&data
[6]);
114 pressure
= le16_to_cpup((__le16
*)&data
[8]);
117 wac_i2c
->tool
= (data
[3] & 0x0c) ?
118 BTN_TOOL_RUBBER
: BTN_TOOL_PEN
;
120 wac_i2c
->prox
= data
[3] & 0x20;
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
);
135 static int wacom_i2c_open(struct input_dev
*dev
)
137 struct wacom_i2c
*wac_i2c
= input_get_drvdata(dev
);
138 struct i2c_client
*client
= wac_i2c
->client
;
140 enable_irq(client
->irq
);
145 static void wacom_i2c_close(struct input_dev
*dev
)
147 struct wacom_i2c
*wac_i2c
= input_get_drvdata(dev
);
148 struct i2c_client
*client
= wac_i2c
->client
;
150 disable_irq(client
->irq
);
153 static int wacom_i2c_probe(struct i2c_client
*client
,
154 const struct i2c_device_id
*id
)
156 struct wacom_i2c
*wac_i2c
;
157 struct input_dev
*input
;
158 struct wacom_features features
= { 0 };
161 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
)) {
162 dev_err(&client
->dev
, "i2c_check_functionality error\n");
166 error
= wacom_query_device(client
, &features
);
170 wac_i2c
= kzalloc(sizeof(*wac_i2c
), GFP_KERNEL
);
171 input
= input_allocate_device();
172 if (!wac_i2c
|| !input
) {
177 wac_i2c
->client
= client
;
178 wac_i2c
->input
= input
;
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
;
188 input
->evbit
[0] |= BIT_MASK(EV_KEY
) | BIT_MASK(EV_ABS
);
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
);
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);
201 input_set_drvdata(input
, wac_i2c
);
203 error
= request_threaded_irq(client
->irq
, NULL
, wacom_i2c_irq
,
204 IRQF_TRIGGER_LOW
| IRQF_ONESHOT
,
205 "wacom_i2c", wac_i2c
);
207 dev_err(&client
->dev
,
208 "Failed to enable IRQ, error: %d\n", error
);
212 /* Disable the IRQ, we'll enable it in wac_i2c_open() */
213 disable_irq(client
->irq
);
215 error
= input_register_device(wac_i2c
->input
);
217 dev_err(&client
->dev
,
218 "Failed to register input device, error: %d\n", error
);
222 i2c_set_clientdata(client
, wac_i2c
);
226 free_irq(client
->irq
, wac_i2c
);
228 input_free_device(input
);
234 static int wacom_i2c_remove(struct i2c_client
*client
)
236 struct wacom_i2c
*wac_i2c
= i2c_get_clientdata(client
);
238 free_irq(client
->irq
, wac_i2c
);
239 input_unregister_device(wac_i2c
->input
);
245 static int __maybe_unused
wacom_i2c_suspend(struct device
*dev
)
247 struct i2c_client
*client
= to_i2c_client(dev
);
249 disable_irq(client
->irq
);
254 static int __maybe_unused
wacom_i2c_resume(struct device
*dev
)
256 struct i2c_client
*client
= to_i2c_client(dev
);
258 enable_irq(client
->irq
);
263 static SIMPLE_DEV_PM_OPS(wacom_i2c_pm
, wacom_i2c_suspend
, wacom_i2c_resume
);
265 static const struct i2c_device_id wacom_i2c_id
[] = {
266 { "WAC_I2C_EMR", 0 },
269 MODULE_DEVICE_TABLE(i2c
, wacom_i2c_id
);
271 static struct i2c_driver wacom_i2c_driver
= {
277 .probe
= wacom_i2c_probe
,
278 .remove
= wacom_i2c_remove
,
279 .id_table
= wacom_i2c_id
,
281 module_i2c_driver(wacom_i2c_driver
);
283 MODULE_AUTHOR("Tatsunosuke Tobita <tobita.tatsunosuke@wacom.co.jp>");
284 MODULE_DESCRIPTION("WACOM EMR I2C Driver");
285 MODULE_LICENSE("GPL");