1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for Ntrig/Microsoft Touchscreens over SPI
5 * Copyright (c) 2016 Red Hat Inc.
9 #include <linux/kernel.h>
11 #include <linux/delay.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/input.h>
14 #include <linux/input/mt.h>
15 #include <linux/interrupt.h>
16 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/spi/spi.h>
19 #include <linux/acpi.h>
21 #include <asm/unaligned.h>
23 #define SURFACE3_PACKET_SIZE 264
25 #define SURFACE3_REPORT_TOUCH 0xd2
26 #define SURFACE3_REPORT_PEN 0x16
28 struct surface3_ts_data
{
29 struct spi_device
*spi
;
30 struct gpio_desc
*gpiod_rst
[2];
31 struct input_dev
*input_dev
;
32 struct input_dev
*pen_input_dev
;
35 u8 rd_buf
[SURFACE3_PACKET_SIZE
] ____cacheline_aligned
;
38 struct surface3_ts_data_finger
{
50 struct surface3_ts_data_pen
{
58 static int surface3_spi_read(struct surface3_ts_data
*ts_data
)
60 struct spi_device
*spi
= ts_data
->spi
;
62 memset(ts_data
->rd_buf
, 0, sizeof(ts_data
->rd_buf
));
63 return spi_read(spi
, ts_data
->rd_buf
, sizeof(ts_data
->rd_buf
));
66 static void surface3_spi_report_touch(struct surface3_ts_data
*ts_data
,
67 struct surface3_ts_data_finger
*finger
)
69 int st
= finger
->status
& 0x01;
72 slot
= input_mt_get_slot_by_key(ts_data
->input_dev
,
73 get_unaligned_le16(&finger
->tracking_id
));
77 input_mt_slot(ts_data
->input_dev
, slot
);
78 input_mt_report_slot_state(ts_data
->input_dev
, MT_TOOL_FINGER
, st
);
80 input_report_abs(ts_data
->input_dev
,
82 get_unaligned_le16(&finger
->x
));
83 input_report_abs(ts_data
->input_dev
,
85 get_unaligned_le16(&finger
->y
));
86 input_report_abs(ts_data
->input_dev
,
88 get_unaligned_le16(&finger
->width
));
89 input_report_abs(ts_data
->input_dev
,
91 get_unaligned_le16(&finger
->height
));
95 static void surface3_spi_process_touch(struct surface3_ts_data
*ts_data
, u8
*data
)
99 timestamp
= get_unaligned_le16(&data
[15]);
101 for (i
= 0; i
< 13; i
++) {
102 struct surface3_ts_data_finger
*finger
;
104 finger
= (struct surface3_ts_data_finger
*)&data
[17 +
105 i
* sizeof(struct surface3_ts_data_finger
)];
108 * When bit 5 of status is 1, it marks the end of the report:
109 * - touch present: 0xe7
110 * - touch released: 0xe4
111 * - nothing valuable: 0xff
113 if (finger
->status
& 0x10)
116 surface3_spi_report_touch(ts_data
, finger
);
119 input_mt_sync_frame(ts_data
->input_dev
);
120 input_sync(ts_data
->input_dev
);
123 static void surface3_spi_report_pen(struct surface3_ts_data
*ts_data
,
124 struct surface3_ts_data_pen
*pen
)
126 struct input_dev
*dev
= ts_data
->pen_input_dev
;
127 int st
= pen
->status
;
128 int prox
= st
& 0x01;
129 int rubber
= st
& 0x18;
130 int tool
= (prox
&& rubber
) ? BTN_TOOL_RUBBER
: BTN_TOOL_PEN
;
132 /* fake proximity out to switch tools */
133 if (ts_data
->pen_tool
!= tool
) {
134 input_report_key(dev
, ts_data
->pen_tool
, 0);
136 ts_data
->pen_tool
= tool
;
139 input_report_key(dev
, BTN_TOUCH
, st
& 0x12);
141 input_report_key(dev
, ts_data
->pen_tool
, prox
);
144 input_report_key(dev
,
148 input_report_abs(dev
,
150 get_unaligned_le16(&pen
->x
));
151 input_report_abs(dev
,
153 get_unaligned_le16(&pen
->y
));
154 input_report_abs(dev
,
156 get_unaligned_le16(&pen
->pressure
));
160 static void surface3_spi_process_pen(struct surface3_ts_data
*ts_data
, u8
*data
)
162 struct surface3_ts_data_pen
*pen
;
164 pen
= (struct surface3_ts_data_pen
*)&data
[15];
166 surface3_spi_report_pen(ts_data
, pen
);
167 input_sync(ts_data
->pen_input_dev
);
170 static void surface3_spi_process(struct surface3_ts_data
*ts_data
)
172 static const char header
[] = {
173 0xff, 0xff, 0xff, 0xff, 0xa5, 0x5a, 0xe7, 0x7e, 0x01
175 u8
*data
= ts_data
->rd_buf
;
177 if (memcmp(header
, data
, sizeof(header
)))
178 dev_err(&ts_data
->spi
->dev
,
179 "%s header error: %*ph, ignoring...\n",
180 __func__
, (int)sizeof(header
), data
);
183 case SURFACE3_REPORT_TOUCH
:
184 surface3_spi_process_touch(ts_data
, data
);
186 case SURFACE3_REPORT_PEN
:
187 surface3_spi_process_pen(ts_data
, data
);
190 dev_err(&ts_data
->spi
->dev
,
191 "%s unknown packet type: %x, ignoring...\n",
197 static irqreturn_t
surface3_spi_irq_handler(int irq
, void *dev_id
)
199 struct surface3_ts_data
*data
= dev_id
;
201 if (surface3_spi_read(data
))
204 dev_dbg(&data
->spi
->dev
, "%s received -> %*ph\n",
205 __func__
, SURFACE3_PACKET_SIZE
, data
->rd_buf
);
206 surface3_spi_process(data
);
211 static void surface3_spi_power(struct surface3_ts_data
*data
, bool on
)
213 gpiod_set_value(data
->gpiod_rst
[0], on
);
214 gpiod_set_value(data
->gpiod_rst
[1], on
);
215 /* let the device settle a little */
220 * surface3_spi_get_gpio_config - Get GPIO config from ACPI/DT
222 * @ts: surface3_spi_ts_data pointer
224 static int surface3_spi_get_gpio_config(struct surface3_ts_data
*data
)
228 struct gpio_desc
*gpiod
;
231 dev
= &data
->spi
->dev
;
233 /* Get the reset lines GPIO pin number */
234 for (i
= 0; i
< 2; i
++) {
235 gpiod
= devm_gpiod_get_index(dev
, NULL
, i
, GPIOD_OUT_LOW
);
237 error
= PTR_ERR(gpiod
);
238 if (error
!= -EPROBE_DEFER
)
240 "Failed to get power GPIO %d: %d\n",
246 data
->gpiod_rst
[i
] = gpiod
;
252 static int surface3_spi_create_touch_input(struct surface3_ts_data
*data
)
254 struct input_dev
*input
;
257 input
= devm_input_allocate_device(&data
->spi
->dev
);
261 data
->input_dev
= input
;
263 input_set_abs_params(input
, ABS_MT_POSITION_X
, 0, 9600, 0, 0);
264 input_abs_set_res(input
, ABS_MT_POSITION_X
, 40);
265 input_set_abs_params(input
, ABS_MT_POSITION_Y
, 0, 7200, 0, 0);
266 input_abs_set_res(input
, ABS_MT_POSITION_Y
, 48);
267 input_set_abs_params(input
, ABS_MT_WIDTH_MAJOR
, 0, 1024, 0, 0);
268 input_set_abs_params(input
, ABS_MT_WIDTH_MINOR
, 0, 1024, 0, 0);
269 input_mt_init_slots(input
, 10, INPUT_MT_DIRECT
);
271 input
->name
= "Surface3 SPI Capacitive TouchScreen";
272 input
->phys
= "input/ts";
273 input
->id
.bustype
= BUS_SPI
;
274 input
->id
.vendor
= 0x045e; /* Microsoft */
275 input
->id
.product
= 0x0001;
276 input
->id
.version
= 0x0000;
278 error
= input_register_device(input
);
280 dev_err(&data
->spi
->dev
,
281 "Failed to register input device: %d", error
);
288 static int surface3_spi_create_pen_input(struct surface3_ts_data
*data
)
290 struct input_dev
*input
;
293 input
= devm_input_allocate_device(&data
->spi
->dev
);
297 data
->pen_input_dev
= input
;
298 data
->pen_tool
= BTN_TOOL_PEN
;
300 __set_bit(INPUT_PROP_DIRECT
, input
->propbit
);
301 __set_bit(INPUT_PROP_POINTER
, input
->propbit
);
302 input_set_abs_params(input
, ABS_X
, 0, 9600, 0, 0);
303 input_abs_set_res(input
, ABS_X
, 40);
304 input_set_abs_params(input
, ABS_Y
, 0, 7200, 0, 0);
305 input_abs_set_res(input
, ABS_Y
, 48);
306 input_set_abs_params(input
, ABS_PRESSURE
, 0, 1024, 0, 0);
307 input_set_capability(input
, EV_KEY
, BTN_TOUCH
);
308 input_set_capability(input
, EV_KEY
, BTN_STYLUS
);
309 input_set_capability(input
, EV_KEY
, BTN_TOOL_PEN
);
310 input_set_capability(input
, EV_KEY
, BTN_TOOL_RUBBER
);
312 input
->name
= "Surface3 SPI Pen Input";
313 input
->phys
= "input/ts";
314 input
->id
.bustype
= BUS_SPI
;
315 input
->id
.vendor
= 0x045e; /* Microsoft */
316 input
->id
.product
= 0x0002;
317 input
->id
.version
= 0x0000;
319 error
= input_register_device(input
);
321 dev_err(&data
->spi
->dev
,
322 "Failed to register input device: %d", error
);
329 static int surface3_spi_probe(struct spi_device
*spi
)
331 struct surface3_ts_data
*data
;
335 spi
->bits_per_word
= 8;
336 spi
->mode
= SPI_MODE_0
;
337 error
= spi_setup(spi
);
341 data
= devm_kzalloc(&spi
->dev
, sizeof(*data
), GFP_KERNEL
);
346 spi_set_drvdata(spi
, data
);
348 error
= surface3_spi_get_gpio_config(data
);
352 surface3_spi_power(data
, true);
353 surface3_spi_power(data
, false);
354 surface3_spi_power(data
, true);
356 error
= surface3_spi_create_touch_input(data
);
360 error
= surface3_spi_create_pen_input(data
);
364 error
= devm_request_threaded_irq(&spi
->dev
, spi
->irq
,
365 NULL
, surface3_spi_irq_handler
,
367 "Surface3-irq", data
);
374 static int __maybe_unused
surface3_spi_suspend(struct device
*dev
)
376 struct spi_device
*spi
= to_spi_device(dev
);
377 struct surface3_ts_data
*data
= spi_get_drvdata(spi
);
379 disable_irq(data
->spi
->irq
);
381 surface3_spi_power(data
, false);
386 static int __maybe_unused
surface3_spi_resume(struct device
*dev
)
388 struct spi_device
*spi
= to_spi_device(dev
);
389 struct surface3_ts_data
*data
= spi_get_drvdata(spi
);
391 surface3_spi_power(data
, true);
393 enable_irq(data
->spi
->irq
);
398 static SIMPLE_DEV_PM_OPS(surface3_spi_pm_ops
,
399 surface3_spi_suspend
,
400 surface3_spi_resume
);
403 static const struct acpi_device_id surface3_spi_acpi_match
[] = {
407 MODULE_DEVICE_TABLE(acpi
, surface3_spi_acpi_match
);
410 static struct spi_driver surface3_spi_driver
= {
412 .name
= "Surface3-spi",
413 .acpi_match_table
= ACPI_PTR(surface3_spi_acpi_match
),
414 .pm
= &surface3_spi_pm_ops
,
416 .probe
= surface3_spi_probe
,
419 module_spi_driver(surface3_spi_driver
);
421 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
422 MODULE_DESCRIPTION("Surface 3 SPI touchscreen driver");
423 MODULE_LICENSE("GPL v2");