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