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