1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Fujitsu serial touchscreen driver 4 * 5 * Copyright (c) Dmitry Torokhov <dtor@mail.ru> 6 */ 7 8 9 #include <linux/errno.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/slab.h> 13 #include <linux/input.h> 14 #include <linux/serio.h> 15 16 #define DRIVER_DESC "Fujitsu serial touchscreen driver" 17 18 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); 19 MODULE_DESCRIPTION(DRIVER_DESC); 20 MODULE_LICENSE("GPL"); 21 22 #define FUJITSU_LENGTH 5 23 24 /* 25 * Per-touchscreen data. 26 */ 27 struct fujitsu { 28 struct input_dev *dev; 29 struct serio *serio; 30 int idx; 31 unsigned char data[FUJITSU_LENGTH]; 32 char phys[32]; 33 }; 34 35 /* 36 * Decode serial data (5 bytes per packet) 37 * First byte 38 * 1 C 0 0 R S S S 39 * Where C is 1 while in calibration mode (which we don't use) 40 * R is 1 when no coordinate corection was done. 41 * S are button state 42 */ 43 static irqreturn_t fujitsu_interrupt(struct serio *serio, 44 unsigned char data, unsigned int flags) 45 { 46 struct fujitsu *fujitsu = serio_get_drvdata(serio); 47 struct input_dev *dev = fujitsu->dev; 48 49 if (fujitsu->idx == 0) { 50 /* resync skip until start of frame */ 51 if ((data & 0xf0) != 0x80) 52 return IRQ_HANDLED; 53 } else { 54 /* resync skip garbage */ 55 if (data & 0x80) { 56 fujitsu->idx = 0; 57 return IRQ_HANDLED; 58 } 59 } 60 61 fujitsu->data[fujitsu->idx++] = data; 62 if (fujitsu->idx == FUJITSU_LENGTH) { 63 input_report_abs(dev, ABS_X, 64 (fujitsu->data[2] << 7) | fujitsu->data[1]); 65 input_report_abs(dev, ABS_Y, 66 (fujitsu->data[4] << 7) | fujitsu->data[3]); 67 input_report_key(dev, BTN_TOUCH, 68 (fujitsu->data[0] & 0x03) != 2); 69 input_sync(dev); 70 fujitsu->idx = 0; 71 } 72 73 return IRQ_HANDLED; 74 } 75 76 /* 77 * fujitsu_disconnect() is the opposite of fujitsu_connect() 78 */ 79 static void fujitsu_disconnect(struct serio *serio) 80 { 81 struct fujitsu *fujitsu = serio_get_drvdata(serio); 82 83 input_get_device(fujitsu->dev); 84 input_unregister_device(fujitsu->dev); 85 serio_close(serio); 86 serio_set_drvdata(serio, NULL); 87 input_put_device(fujitsu->dev); 88 kfree(fujitsu); 89 } 90 91 /* 92 * fujitsu_connect() is the routine that is called when someone adds a 93 * new serio device that supports the Fujitsu protocol and registers it 94 * as input device. 95 */ 96 static int fujitsu_connect(struct serio *serio, struct serio_driver *drv) 97 { 98 struct fujitsu *fujitsu; 99 struct input_dev *input_dev; 100 int err; 101 102 fujitsu = kzalloc(sizeof(struct fujitsu), GFP_KERNEL); 103 input_dev = input_allocate_device(); 104 if (!fujitsu || !input_dev) { 105 err = -ENOMEM; 106 goto fail1; 107 } 108 109 fujitsu->serio = serio; 110 fujitsu->dev = input_dev; 111 snprintf(fujitsu->phys, sizeof(fujitsu->phys), 112 "%s/input0", serio->phys); 113 114 input_dev->name = "Fujitsu Serial Touchscreen"; 115 input_dev->phys = fujitsu->phys; 116 input_dev->id.bustype = BUS_RS232; 117 input_dev->id.vendor = SERIO_FUJITSU; 118 input_dev->id.product = 0; 119 input_dev->id.version = 0x0100; 120 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 121 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 122 123 input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0); 124 input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0); 125 serio_set_drvdata(serio, fujitsu); 126 127 err = serio_open(serio, drv); 128 if (err) 129 goto fail2; 130 131 err = input_register_device(fujitsu->dev); 132 if (err) 133 goto fail3; 134 135 return 0; 136 137 fail3: 138 serio_close(serio); 139 fail2: 140 serio_set_drvdata(serio, NULL); 141 fail1: 142 input_free_device(input_dev); 143 kfree(fujitsu); 144 return err; 145 } 146 147 /* 148 * The serio driver structure. 149 */ 150 static const struct serio_device_id fujitsu_serio_ids[] = { 151 { 152 .type = SERIO_RS232, 153 .proto = SERIO_FUJITSU, 154 .id = SERIO_ANY, 155 .extra = SERIO_ANY, 156 }, 157 { 0 } 158 }; 159 160 MODULE_DEVICE_TABLE(serio, fujitsu_serio_ids); 161 162 static struct serio_driver fujitsu_drv = { 163 .driver = { 164 .name = "fujitsu_ts", 165 }, 166 .description = DRIVER_DESC, 167 .id_table = fujitsu_serio_ids, 168 .interrupt = fujitsu_interrupt, 169 .connect = fujitsu_connect, 170 .disconnect = fujitsu_disconnect, 171 }; 172 173 module_serio_driver(fujitsu_drv); 174