^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for Ntrig/Microsoft Touchscreens over SPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2016 Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define SURFACE3_PACKET_SIZE 264
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define SURFACE3_REPORT_TOUCH 0xd2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define SURFACE3_REPORT_PEN 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct surface3_ts_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct spi_device *spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct gpio_desc *gpiod_rst[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct input_dev *pen_input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int pen_tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u8 rd_buf[SURFACE3_PACKET_SIZE] ____cacheline_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct surface3_ts_data_finger {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) __le16 tracking_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) __le16 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) __le16 cx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __le16 y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __le16 cy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) __le16 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __le16 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u32 padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct surface3_ts_data_pen {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __le16 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) __le16 y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) __le16 pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int surface3_spi_read(struct surface3_ts_data *ts_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct spi_device *spi = ts_data->spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) memset(ts_data->rd_buf, 0, sizeof(ts_data->rd_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return spi_read(spi, ts_data->rd_buf, sizeof(ts_data->rd_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void surface3_spi_report_touch(struct surface3_ts_data *ts_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct surface3_ts_data_finger *finger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int st = finger->status & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) slot = input_mt_get_slot_by_key(ts_data->input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) get_unaligned_le16(&finger->tracking_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (slot < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) input_mt_slot(ts_data->input_dev, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (st) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) input_report_abs(ts_data->input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ABS_MT_POSITION_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) get_unaligned_le16(&finger->x));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) input_report_abs(ts_data->input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ABS_MT_POSITION_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) get_unaligned_le16(&finger->y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) input_report_abs(ts_data->input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ABS_MT_WIDTH_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) get_unaligned_le16(&finger->width));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) input_report_abs(ts_data->input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ABS_MT_WIDTH_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) get_unaligned_le16(&finger->height));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void surface3_spi_process_touch(struct surface3_ts_data *ts_data, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u16 timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) timestamp = get_unaligned_le16(&data[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) for (i = 0; i < 13; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct surface3_ts_data_finger *finger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) finger = (struct surface3_ts_data_finger *)&data[17 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) i * sizeof(struct surface3_ts_data_finger)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * When bit 5 of status is 1, it marks the end of the report:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * - touch present: 0xe7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * - touch released: 0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * - nothing valuable: 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (finger->status & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) surface3_spi_report_touch(ts_data, finger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) input_mt_sync_frame(ts_data->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) input_sync(ts_data->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void surface3_spi_report_pen(struct surface3_ts_data *ts_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct surface3_ts_data_pen *pen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct input_dev *dev = ts_data->pen_input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int st = pen->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int prox = st & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int rubber = st & 0x18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int tool = (prox && rubber) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* fake proximity out to switch tools */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ts_data->pen_tool != tool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) input_report_key(dev, ts_data->pen_tool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) input_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ts_data->pen_tool = tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) input_report_key(dev, BTN_TOUCH, st & 0x12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) input_report_key(dev, ts_data->pen_tool, prox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (st) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) input_report_key(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) BTN_STYLUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) st & 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) input_report_abs(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ABS_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) get_unaligned_le16(&pen->x));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) input_report_abs(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ABS_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) get_unaligned_le16(&pen->y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) input_report_abs(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ABS_PRESSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) get_unaligned_le16(&pen->pressure));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static void surface3_spi_process_pen(struct surface3_ts_data *ts_data, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct surface3_ts_data_pen *pen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pen = (struct surface3_ts_data_pen *)&data[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) surface3_spi_report_pen(ts_data, pen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) input_sync(ts_data->pen_input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void surface3_spi_process(struct surface3_ts_data *ts_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static const char header[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 0xff, 0xff, 0xff, 0xff, 0xa5, 0x5a, 0xe7, 0x7e, 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 *data = ts_data->rd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (memcmp(header, data, sizeof(header)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) dev_err(&ts_data->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) "%s header error: %*ph, ignoring...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) __func__, (int)sizeof(header), data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) switch (data[9]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case SURFACE3_REPORT_TOUCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) surface3_spi_process_touch(ts_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case SURFACE3_REPORT_PEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) surface3_spi_process_pen(ts_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev_err(&ts_data->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "%s unknown packet type: %x, ignoring...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) __func__, data[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static irqreturn_t surface3_spi_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct surface3_ts_data *data = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (surface3_spi_read(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) dev_dbg(&data->spi->dev, "%s received -> %*ph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) __func__, SURFACE3_PACKET_SIZE, data->rd_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) surface3_spi_process(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void surface3_spi_power(struct surface3_ts_data *data, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) gpiod_set_value(data->gpiod_rst[0], on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) gpiod_set_value(data->gpiod_rst[1], on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* let the device settle a little */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * surface3_spi_get_gpio_config - Get GPIO config from ACPI/DT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * @ts: surface3_spi_ts_data pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int surface3_spi_get_gpio_config(struct surface3_ts_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct gpio_desc *gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev = &data->spi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Get the reset lines GPIO pin number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) gpiod = devm_gpiod_get_index(dev, NULL, i, GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (IS_ERR(gpiod)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) error = PTR_ERR(gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (error != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) "Failed to get power GPIO %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) data->gpiod_rst[i] = gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int surface3_spi_create_touch_input(struct surface3_ts_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) input = devm_input_allocate_device(&data->spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) data->input_dev = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) input_set_abs_params(input, ABS_MT_POSITION_X, 0, 9600, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) input_abs_set_res(input, ABS_MT_POSITION_X, 40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 7200, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) input_abs_set_res(input, ABS_MT_POSITION_Y, 48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 1024, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 1024, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) input_mt_init_slots(input, 10, INPUT_MT_DIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) input->name = "Surface3 SPI Capacitive TouchScreen";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) input->phys = "input/ts";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) input->id.bustype = BUS_SPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) input->id.vendor = 0x045e; /* Microsoft */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) input->id.product = 0x0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) input->id.version = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dev_err(&data->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) "Failed to register input device: %d", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int surface3_spi_create_pen_input(struct surface3_ts_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) input = devm_input_allocate_device(&data->spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) data->pen_input_dev = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) data->pen_tool = BTN_TOOL_PEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) __set_bit(INPUT_PROP_DIRECT, input->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) __set_bit(INPUT_PROP_POINTER, input->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) input_set_abs_params(input, ABS_X, 0, 9600, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) input_abs_set_res(input, ABS_X, 40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) input_set_abs_params(input, ABS_Y, 0, 7200, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) input_abs_set_res(input, ABS_Y, 48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) input_set_abs_params(input, ABS_PRESSURE, 0, 1024, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) input_set_capability(input, EV_KEY, BTN_TOUCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) input_set_capability(input, EV_KEY, BTN_STYLUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) input_set_capability(input, EV_KEY, BTN_TOOL_PEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) input_set_capability(input, EV_KEY, BTN_TOOL_RUBBER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) input->name = "Surface3 SPI Pen Input";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) input->phys = "input/ts";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) input->id.bustype = BUS_SPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) input->id.vendor = 0x045e; /* Microsoft */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) input->id.product = 0x0002;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) input->id.version = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) dev_err(&data->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) "Failed to register input device: %d", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int surface3_spi_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct surface3_ts_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Set up SPI*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) spi->bits_per_word = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) spi->mode = SPI_MODE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) error = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) data = devm_kzalloc(&spi->dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) data->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) spi_set_drvdata(spi, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) error = surface3_spi_get_gpio_config(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) surface3_spi_power(data, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) surface3_spi_power(data, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) surface3_spi_power(data, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) error = surface3_spi_create_touch_input(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) error = surface3_spi_create_pen_input(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) error = devm_request_threaded_irq(&spi->dev, spi->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) NULL, surface3_spi_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) "Surface3-irq", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static int __maybe_unused surface3_spi_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct spi_device *spi = to_spi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct surface3_ts_data *data = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) disable_irq(data->spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) surface3_spi_power(data, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static int __maybe_unused surface3_spi_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct spi_device *spi = to_spi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct surface3_ts_data *data = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) surface3_spi_power(data, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) enable_irq(data->spi->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static SIMPLE_DEV_PM_OPS(surface3_spi_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) surface3_spi_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) surface3_spi_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static const struct acpi_device_id surface3_spi_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { "MSHW0037", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) MODULE_DEVICE_TABLE(acpi, surface3_spi_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static struct spi_driver surface3_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .name = "Surface3-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .acpi_match_table = ACPI_PTR(surface3_spi_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .pm = &surface3_spi_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .probe = surface3_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) module_spi_driver(surface3_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) MODULE_DESCRIPTION("Surface 3 SPI touchscreen driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) MODULE_LICENSE("GPL v2");