1*4feacbc2SBenjamin Tissoires /* 2*4feacbc2SBenjamin Tissoires * Driver for Ntrig/Microsoft Touchscreens over SPI 3*4feacbc2SBenjamin Tissoires * 4*4feacbc2SBenjamin Tissoires * Copyright (c) 2016 Red Hat Inc. 5*4feacbc2SBenjamin Tissoires */ 6*4feacbc2SBenjamin Tissoires 7*4feacbc2SBenjamin Tissoires /* 8*4feacbc2SBenjamin Tissoires * This program is free software; you can redistribute it and/or modify it 9*4feacbc2SBenjamin Tissoires * under the terms of the GNU General Public License as published by the Free 10*4feacbc2SBenjamin Tissoires * Software Foundation; version 2 of the License. 11*4feacbc2SBenjamin Tissoires */ 12*4feacbc2SBenjamin Tissoires 13*4feacbc2SBenjamin Tissoires #include <linux/kernel.h> 14*4feacbc2SBenjamin Tissoires 15*4feacbc2SBenjamin Tissoires #include <linux/delay.h> 16*4feacbc2SBenjamin Tissoires #include <linux/gpio/consumer.h> 17*4feacbc2SBenjamin Tissoires #include <linux/input.h> 18*4feacbc2SBenjamin Tissoires #include <linux/input/mt.h> 19*4feacbc2SBenjamin Tissoires #include <linux/interrupt.h> 20*4feacbc2SBenjamin Tissoires #include <linux/module.h> 21*4feacbc2SBenjamin Tissoires #include <linux/slab.h> 22*4feacbc2SBenjamin Tissoires #include <linux/spi/spi.h> 23*4feacbc2SBenjamin Tissoires #include <linux/acpi.h> 24*4feacbc2SBenjamin Tissoires 25*4feacbc2SBenjamin Tissoires #include <asm/unaligned.h> 26*4feacbc2SBenjamin Tissoires 27*4feacbc2SBenjamin Tissoires #define SURFACE3_PACKET_SIZE 264 28*4feacbc2SBenjamin Tissoires 29*4feacbc2SBenjamin Tissoires struct surface3_ts_data { 30*4feacbc2SBenjamin Tissoires struct spi_device *spi; 31*4feacbc2SBenjamin Tissoires struct gpio_desc *gpiod_rst[2]; 32*4feacbc2SBenjamin Tissoires struct input_dev *input_dev; 33*4feacbc2SBenjamin Tissoires 34*4feacbc2SBenjamin Tissoires u8 rd_buf[SURFACE3_PACKET_SIZE] ____cacheline_aligned; 35*4feacbc2SBenjamin Tissoires }; 36*4feacbc2SBenjamin Tissoires 37*4feacbc2SBenjamin Tissoires struct surface3_ts_data_finger { 38*4feacbc2SBenjamin Tissoires u8 status; 39*4feacbc2SBenjamin Tissoires __le16 tracking_id; 40*4feacbc2SBenjamin Tissoires __le16 x; 41*4feacbc2SBenjamin Tissoires __le16 cx; 42*4feacbc2SBenjamin Tissoires __le16 y; 43*4feacbc2SBenjamin Tissoires __le16 cy; 44*4feacbc2SBenjamin Tissoires __le16 width; 45*4feacbc2SBenjamin Tissoires __le16 height; 46*4feacbc2SBenjamin Tissoires u32 padding; 47*4feacbc2SBenjamin Tissoires } __packed; 48*4feacbc2SBenjamin Tissoires 49*4feacbc2SBenjamin Tissoires static int surface3_spi_read(struct surface3_ts_data *ts_data) 50*4feacbc2SBenjamin Tissoires { 51*4feacbc2SBenjamin Tissoires struct spi_device *spi = ts_data->spi; 52*4feacbc2SBenjamin Tissoires 53*4feacbc2SBenjamin Tissoires memset(ts_data->rd_buf, 0, sizeof(ts_data->rd_buf)); 54*4feacbc2SBenjamin Tissoires return spi_read(spi, ts_data->rd_buf, sizeof(ts_data->rd_buf)); 55*4feacbc2SBenjamin Tissoires } 56*4feacbc2SBenjamin Tissoires 57*4feacbc2SBenjamin Tissoires static void surface3_spi_report_touch(struct surface3_ts_data *ts_data, 58*4feacbc2SBenjamin Tissoires struct surface3_ts_data_finger *finger) 59*4feacbc2SBenjamin Tissoires { 60*4feacbc2SBenjamin Tissoires int st = finger->status & 0x01; 61*4feacbc2SBenjamin Tissoires int slot; 62*4feacbc2SBenjamin Tissoires 63*4feacbc2SBenjamin Tissoires slot = input_mt_get_slot_by_key(ts_data->input_dev, 64*4feacbc2SBenjamin Tissoires get_unaligned_le16(&finger->tracking_id)); 65*4feacbc2SBenjamin Tissoires if (slot < 0) 66*4feacbc2SBenjamin Tissoires return; 67*4feacbc2SBenjamin Tissoires 68*4feacbc2SBenjamin Tissoires input_mt_slot(ts_data->input_dev, slot); 69*4feacbc2SBenjamin Tissoires input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, st); 70*4feacbc2SBenjamin Tissoires if (st) { 71*4feacbc2SBenjamin Tissoires input_report_abs(ts_data->input_dev, 72*4feacbc2SBenjamin Tissoires ABS_MT_POSITION_X, 73*4feacbc2SBenjamin Tissoires get_unaligned_le16(&finger->x)); 74*4feacbc2SBenjamin Tissoires input_report_abs(ts_data->input_dev, 75*4feacbc2SBenjamin Tissoires ABS_MT_POSITION_Y, 76*4feacbc2SBenjamin Tissoires get_unaligned_le16(&finger->y)); 77*4feacbc2SBenjamin Tissoires input_report_abs(ts_data->input_dev, 78*4feacbc2SBenjamin Tissoires ABS_MT_WIDTH_MAJOR, 79*4feacbc2SBenjamin Tissoires get_unaligned_le16(&finger->width)); 80*4feacbc2SBenjamin Tissoires input_report_abs(ts_data->input_dev, 81*4feacbc2SBenjamin Tissoires ABS_MT_WIDTH_MINOR, 82*4feacbc2SBenjamin Tissoires get_unaligned_le16(&finger->height)); 83*4feacbc2SBenjamin Tissoires } 84*4feacbc2SBenjamin Tissoires } 85*4feacbc2SBenjamin Tissoires 86*4feacbc2SBenjamin Tissoires static void surface3_spi_process(struct surface3_ts_data *ts_data) 87*4feacbc2SBenjamin Tissoires { 88*4feacbc2SBenjamin Tissoires const char header[] = {0xff, 0xff, 0xff, 0xff, 0xa5, 0x5a, 0xe7, 0x7e, 89*4feacbc2SBenjamin Tissoires 0x01, 0xd2, 0x00, 0x80, 0x01, 0x03, 0x03}; 90*4feacbc2SBenjamin Tissoires u8 *data = ts_data->rd_buf; 91*4feacbc2SBenjamin Tissoires u16 timestamp; 92*4feacbc2SBenjamin Tissoires unsigned int i; 93*4feacbc2SBenjamin Tissoires 94*4feacbc2SBenjamin Tissoires if (memcmp(header, data, sizeof(header))) 95*4feacbc2SBenjamin Tissoires dev_err(&ts_data->spi->dev, 96*4feacbc2SBenjamin Tissoires "%s header error: %*ph, ignoring...\n", 97*4feacbc2SBenjamin Tissoires __func__, (int)sizeof(header), data); 98*4feacbc2SBenjamin Tissoires 99*4feacbc2SBenjamin Tissoires timestamp = get_unaligned_le16(&data[15]); 100*4feacbc2SBenjamin Tissoires 101*4feacbc2SBenjamin Tissoires for (i = 0; i < 13; i++) { 102*4feacbc2SBenjamin Tissoires struct surface3_ts_data_finger *finger; 103*4feacbc2SBenjamin Tissoires 104*4feacbc2SBenjamin Tissoires finger = (struct surface3_ts_data_finger *)&data[17 + 105*4feacbc2SBenjamin Tissoires i * sizeof(struct surface3_ts_data_finger)]; 106*4feacbc2SBenjamin Tissoires 107*4feacbc2SBenjamin Tissoires /* 108*4feacbc2SBenjamin Tissoires * When bit 5 of status is 1, it marks the end of the report: 109*4feacbc2SBenjamin Tissoires * - touch present: 0xe7 110*4feacbc2SBenjamin Tissoires * - touch released: 0xe4 111*4feacbc2SBenjamin Tissoires * - nothing valuable: 0xff 112*4feacbc2SBenjamin Tissoires */ 113*4feacbc2SBenjamin Tissoires if (finger->status & 0x10) 114*4feacbc2SBenjamin Tissoires break; 115*4feacbc2SBenjamin Tissoires 116*4feacbc2SBenjamin Tissoires surface3_spi_report_touch(ts_data, finger); 117*4feacbc2SBenjamin Tissoires } 118*4feacbc2SBenjamin Tissoires 119*4feacbc2SBenjamin Tissoires input_mt_sync_frame(ts_data->input_dev); 120*4feacbc2SBenjamin Tissoires input_sync(ts_data->input_dev); 121*4feacbc2SBenjamin Tissoires } 122*4feacbc2SBenjamin Tissoires 123*4feacbc2SBenjamin Tissoires static irqreturn_t surface3_spi_irq_handler(int irq, void *dev_id) 124*4feacbc2SBenjamin Tissoires { 125*4feacbc2SBenjamin Tissoires struct surface3_ts_data *data = dev_id; 126*4feacbc2SBenjamin Tissoires 127*4feacbc2SBenjamin Tissoires if (surface3_spi_read(data)) 128*4feacbc2SBenjamin Tissoires return IRQ_HANDLED; 129*4feacbc2SBenjamin Tissoires 130*4feacbc2SBenjamin Tissoires dev_dbg(&data->spi->dev, "%s received -> %*ph\n", 131*4feacbc2SBenjamin Tissoires __func__, SURFACE3_PACKET_SIZE, data->rd_buf); 132*4feacbc2SBenjamin Tissoires surface3_spi_process(data); 133*4feacbc2SBenjamin Tissoires 134*4feacbc2SBenjamin Tissoires return IRQ_HANDLED; 135*4feacbc2SBenjamin Tissoires } 136*4feacbc2SBenjamin Tissoires 137*4feacbc2SBenjamin Tissoires static void surface3_spi_power(struct surface3_ts_data *data, bool on) 138*4feacbc2SBenjamin Tissoires { 139*4feacbc2SBenjamin Tissoires gpiod_set_value(data->gpiod_rst[0], on); 140*4feacbc2SBenjamin Tissoires gpiod_set_value(data->gpiod_rst[1], on); 141*4feacbc2SBenjamin Tissoires /* let the device settle a little */ 142*4feacbc2SBenjamin Tissoires msleep(20); 143*4feacbc2SBenjamin Tissoires } 144*4feacbc2SBenjamin Tissoires 145*4feacbc2SBenjamin Tissoires /** 146*4feacbc2SBenjamin Tissoires * surface3_spi_get_gpio_config - Get GPIO config from ACPI/DT 147*4feacbc2SBenjamin Tissoires * 148*4feacbc2SBenjamin Tissoires * @ts: surface3_spi_ts_data pointer 149*4feacbc2SBenjamin Tissoires */ 150*4feacbc2SBenjamin Tissoires static int surface3_spi_get_gpio_config(struct surface3_ts_data *data) 151*4feacbc2SBenjamin Tissoires { 152*4feacbc2SBenjamin Tissoires int error; 153*4feacbc2SBenjamin Tissoires struct device *dev; 154*4feacbc2SBenjamin Tissoires struct gpio_desc *gpiod; 155*4feacbc2SBenjamin Tissoires int i; 156*4feacbc2SBenjamin Tissoires 157*4feacbc2SBenjamin Tissoires dev = &data->spi->dev; 158*4feacbc2SBenjamin Tissoires 159*4feacbc2SBenjamin Tissoires /* Get the reset lines GPIO pin number */ 160*4feacbc2SBenjamin Tissoires for (i = 0; i < 2; i++) { 161*4feacbc2SBenjamin Tissoires gpiod = devm_gpiod_get_index(dev, NULL, i, GPIOD_OUT_LOW); 162*4feacbc2SBenjamin Tissoires if (IS_ERR(gpiod)) { 163*4feacbc2SBenjamin Tissoires error = PTR_ERR(gpiod); 164*4feacbc2SBenjamin Tissoires if (error != -EPROBE_DEFER) 165*4feacbc2SBenjamin Tissoires dev_err(dev, 166*4feacbc2SBenjamin Tissoires "Failed to get power GPIO %d: %d\n", 167*4feacbc2SBenjamin Tissoires i, 168*4feacbc2SBenjamin Tissoires error); 169*4feacbc2SBenjamin Tissoires return error; 170*4feacbc2SBenjamin Tissoires } 171*4feacbc2SBenjamin Tissoires 172*4feacbc2SBenjamin Tissoires data->gpiod_rst[i] = gpiod; 173*4feacbc2SBenjamin Tissoires } 174*4feacbc2SBenjamin Tissoires 175*4feacbc2SBenjamin Tissoires return 0; 176*4feacbc2SBenjamin Tissoires } 177*4feacbc2SBenjamin Tissoires 178*4feacbc2SBenjamin Tissoires static int surface3_spi_create_input(struct surface3_ts_data *data) 179*4feacbc2SBenjamin Tissoires { 180*4feacbc2SBenjamin Tissoires struct input_dev *input; 181*4feacbc2SBenjamin Tissoires int error; 182*4feacbc2SBenjamin Tissoires 183*4feacbc2SBenjamin Tissoires input = devm_input_allocate_device(&data->spi->dev); 184*4feacbc2SBenjamin Tissoires if (!input) 185*4feacbc2SBenjamin Tissoires return -ENOMEM; 186*4feacbc2SBenjamin Tissoires 187*4feacbc2SBenjamin Tissoires data->input_dev = input; 188*4feacbc2SBenjamin Tissoires 189*4feacbc2SBenjamin Tissoires input_set_abs_params(input, ABS_MT_POSITION_X, 0, 9600, 0, 0); 190*4feacbc2SBenjamin Tissoires input_abs_set_res(input, ABS_MT_POSITION_X, 40); 191*4feacbc2SBenjamin Tissoires input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 7200, 0, 0); 192*4feacbc2SBenjamin Tissoires input_abs_set_res(input, ABS_MT_POSITION_Y, 48); 193*4feacbc2SBenjamin Tissoires input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 1024, 0, 0); 194*4feacbc2SBenjamin Tissoires input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 1024, 0, 0); 195*4feacbc2SBenjamin Tissoires input_mt_init_slots(input, 10, INPUT_MT_DIRECT); 196*4feacbc2SBenjamin Tissoires 197*4feacbc2SBenjamin Tissoires input->name = "Surface3 SPI Capacitive TouchScreen"; 198*4feacbc2SBenjamin Tissoires input->phys = "input/ts"; 199*4feacbc2SBenjamin Tissoires input->id.bustype = BUS_SPI; 200*4feacbc2SBenjamin Tissoires input->id.vendor = 0x045e; /* Microsoft */ 201*4feacbc2SBenjamin Tissoires input->id.product = 0x0000; 202*4feacbc2SBenjamin Tissoires input->id.version = 0x0000; 203*4feacbc2SBenjamin Tissoires 204*4feacbc2SBenjamin Tissoires error = input_register_device(input); 205*4feacbc2SBenjamin Tissoires if (error) { 206*4feacbc2SBenjamin Tissoires dev_err(&data->spi->dev, 207*4feacbc2SBenjamin Tissoires "Failed to register input device: %d", error); 208*4feacbc2SBenjamin Tissoires return error; 209*4feacbc2SBenjamin Tissoires } 210*4feacbc2SBenjamin Tissoires 211*4feacbc2SBenjamin Tissoires return 0; 212*4feacbc2SBenjamin Tissoires } 213*4feacbc2SBenjamin Tissoires 214*4feacbc2SBenjamin Tissoires static int surface3_spi_probe(struct spi_device *spi) 215*4feacbc2SBenjamin Tissoires { 216*4feacbc2SBenjamin Tissoires struct surface3_ts_data *data; 217*4feacbc2SBenjamin Tissoires int error; 218*4feacbc2SBenjamin Tissoires 219*4feacbc2SBenjamin Tissoires /* Set up SPI*/ 220*4feacbc2SBenjamin Tissoires spi->bits_per_word = 8; 221*4feacbc2SBenjamin Tissoires spi->mode = SPI_MODE_0; 222*4feacbc2SBenjamin Tissoires error = spi_setup(spi); 223*4feacbc2SBenjamin Tissoires if (error) 224*4feacbc2SBenjamin Tissoires return error; 225*4feacbc2SBenjamin Tissoires 226*4feacbc2SBenjamin Tissoires data = devm_kzalloc(&spi->dev, sizeof(*data), GFP_KERNEL); 227*4feacbc2SBenjamin Tissoires if (!data) 228*4feacbc2SBenjamin Tissoires return -ENOMEM; 229*4feacbc2SBenjamin Tissoires 230*4feacbc2SBenjamin Tissoires data->spi = spi; 231*4feacbc2SBenjamin Tissoires spi_set_drvdata(spi, data); 232*4feacbc2SBenjamin Tissoires 233*4feacbc2SBenjamin Tissoires error = surface3_spi_get_gpio_config(data); 234*4feacbc2SBenjamin Tissoires if (error) 235*4feacbc2SBenjamin Tissoires return error; 236*4feacbc2SBenjamin Tissoires 237*4feacbc2SBenjamin Tissoires surface3_spi_power(data, true); 238*4feacbc2SBenjamin Tissoires surface3_spi_power(data, false); 239*4feacbc2SBenjamin Tissoires surface3_spi_power(data, true); 240*4feacbc2SBenjamin Tissoires 241*4feacbc2SBenjamin Tissoires error = surface3_spi_create_input(data); 242*4feacbc2SBenjamin Tissoires if (error) 243*4feacbc2SBenjamin Tissoires return error; 244*4feacbc2SBenjamin Tissoires 245*4feacbc2SBenjamin Tissoires error = devm_request_threaded_irq(&spi->dev, spi->irq, 246*4feacbc2SBenjamin Tissoires NULL, surface3_spi_irq_handler, 247*4feacbc2SBenjamin Tissoires IRQF_ONESHOT, 248*4feacbc2SBenjamin Tissoires "Surface3-irq", data); 249*4feacbc2SBenjamin Tissoires if (error) 250*4feacbc2SBenjamin Tissoires return error; 251*4feacbc2SBenjamin Tissoires 252*4feacbc2SBenjamin Tissoires return 0; 253*4feacbc2SBenjamin Tissoires } 254*4feacbc2SBenjamin Tissoires 255*4feacbc2SBenjamin Tissoires static int __maybe_unused surface3_spi_suspend(struct device *dev) 256*4feacbc2SBenjamin Tissoires { 257*4feacbc2SBenjamin Tissoires struct spi_device *spi = to_spi_device(dev); 258*4feacbc2SBenjamin Tissoires struct surface3_ts_data *data = spi_get_drvdata(spi); 259*4feacbc2SBenjamin Tissoires 260*4feacbc2SBenjamin Tissoires disable_irq(data->spi->irq); 261*4feacbc2SBenjamin Tissoires 262*4feacbc2SBenjamin Tissoires surface3_spi_power(data, false); 263*4feacbc2SBenjamin Tissoires 264*4feacbc2SBenjamin Tissoires return 0; 265*4feacbc2SBenjamin Tissoires } 266*4feacbc2SBenjamin Tissoires 267*4feacbc2SBenjamin Tissoires static int __maybe_unused surface3_spi_resume(struct device *dev) 268*4feacbc2SBenjamin Tissoires { 269*4feacbc2SBenjamin Tissoires struct spi_device *spi = to_spi_device(dev); 270*4feacbc2SBenjamin Tissoires struct surface3_ts_data *data = spi_get_drvdata(spi); 271*4feacbc2SBenjamin Tissoires 272*4feacbc2SBenjamin Tissoires surface3_spi_power(data, true); 273*4feacbc2SBenjamin Tissoires 274*4feacbc2SBenjamin Tissoires enable_irq(data->spi->irq); 275*4feacbc2SBenjamin Tissoires 276*4feacbc2SBenjamin Tissoires return 0; 277*4feacbc2SBenjamin Tissoires } 278*4feacbc2SBenjamin Tissoires 279*4feacbc2SBenjamin Tissoires static SIMPLE_DEV_PM_OPS(surface3_spi_pm_ops, 280*4feacbc2SBenjamin Tissoires surface3_spi_suspend, 281*4feacbc2SBenjamin Tissoires surface3_spi_resume); 282*4feacbc2SBenjamin Tissoires 283*4feacbc2SBenjamin Tissoires #ifdef CONFIG_ACPI 284*4feacbc2SBenjamin Tissoires static const struct acpi_device_id surface3_spi_acpi_match[] = { 285*4feacbc2SBenjamin Tissoires { "MSHW0037", 0 }, 286*4feacbc2SBenjamin Tissoires { } 287*4feacbc2SBenjamin Tissoires }; 288*4feacbc2SBenjamin Tissoires MODULE_DEVICE_TABLE(acpi, surface3_spi_acpi_match); 289*4feacbc2SBenjamin Tissoires #endif 290*4feacbc2SBenjamin Tissoires 291*4feacbc2SBenjamin Tissoires static struct spi_driver surface3_spi_driver = { 292*4feacbc2SBenjamin Tissoires .driver = { 293*4feacbc2SBenjamin Tissoires .name = "Surface3-spi", 294*4feacbc2SBenjamin Tissoires .acpi_match_table = ACPI_PTR(surface3_spi_acpi_match), 295*4feacbc2SBenjamin Tissoires .pm = &surface3_spi_pm_ops, 296*4feacbc2SBenjamin Tissoires }, 297*4feacbc2SBenjamin Tissoires .probe = surface3_spi_probe, 298*4feacbc2SBenjamin Tissoires }; 299*4feacbc2SBenjamin Tissoires 300*4feacbc2SBenjamin Tissoires module_spi_driver(surface3_spi_driver); 301*4feacbc2SBenjamin Tissoires 302*4feacbc2SBenjamin Tissoires MODULE_AUTHOR("Benjamin Tissoires <[email protected]>"); 303*4feacbc2SBenjamin Tissoires MODULE_DESCRIPTION("Surface 3 SPI touchscreen driver"); 304*4feacbc2SBenjamin Tissoires MODULE_LICENSE("GPL v2"); 305