1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Driver for Hynitron cstxxx Touchscreen
4  *
5  *  Copyright (c) 2022 Chris Morgan <macromorgan@hotmail.com>
6  *
7  *  This code is based on hynitron_core.c authored by Hynitron.
8  *  Note that no datasheet was available, so much of these registers
9  *  are undocumented. This is essentially a cleaned-up version of the
10  *  vendor driver with support removed for hardware I cannot test and
11  *  device-specific functions replated with generic functions wherever
12  *  possible.
13  */
14 
15 #include <linux/delay.h>
16 #include <linux/err.h>
17 #include <linux/gpio/consumer.h>
18 #include <linux/i2c.h>
19 #include <linux/input.h>
20 #include <linux/input/mt.h>
21 #include <linux/input/touchscreen.h>
22 #include <linux/mod_devicetable.h>
23 #include <linux/module.h>
24 #include <linux/property.h>
25 #include <asm/unaligned.h>
26 
27 /* Per chip data */
28 struct hynitron_ts_chip_data {
29 	unsigned int max_touch_num;
30 	u32 ic_chkcode;
31 	int (*firmware_info)(struct i2c_client *client);
32 	int (*bootloader_enter)(struct i2c_client *client);
33 	int (*init_input)(struct i2c_client *client);
34 	void (*report_touch)(struct i2c_client *client);
35 };
36 
37 /* Data generic to all (supported and non-supported) controllers. */
38 struct hynitron_ts_data {
39 	const struct hynitron_ts_chip_data *chip;
40 	struct i2c_client *client;
41 	struct input_dev *input_dev;
42 	struct touchscreen_properties prop;
43 	struct gpio_desc *reset_gpio;
44 };
45 
46 /*
47  * Since I have no datasheet, these values are guessed and/or assumed
48  * based on observation and testing.
49  */
50 #define CST3XX_FIRMWARE_INFO_START_CMD		0x01d1
51 #define CST3XX_FIRMWARE_INFO_END_CMD		0x09d1
52 #define CST3XX_FIRMWARE_CHK_CODE_REG		0xfcd1
53 #define CST3XX_FIRMWARE_VERSION_REG		0x08d2
54 #define CST3XX_FIRMWARE_VER_INVALID_VAL		0xa5a5a5a5
55 
56 #define CST3XX_BOOTLDR_PROG_CMD			0xaa01a0
57 #define CST3XX_BOOTLDR_PROG_CHK_REG		0x02a0
58 #define CST3XX_BOOTLDR_CHK_VAL			0xac
59 
60 #define CST3XX_TOUCH_DATA_PART_REG		0x00d0
61 #define CST3XX_TOUCH_DATA_FULL_REG		0x07d0
62 #define CST3XX_TOUCH_DATA_CHK_VAL		0xab
63 #define CST3XX_TOUCH_DATA_TOUCH_VAL		0x03
64 #define CST3XX_TOUCH_DATA_STOP_CMD		0xab00d0
65 #define CST3XX_TOUCH_COUNT_MASK			GENMASK(6, 0)
66 
67 
68 /*
69  * Hard coded reset delay value of 20ms not IC dependent in
70  * vendor driver.
71  */
72 static void hyn_reset_proc(struct i2c_client *client, int delay)
73 {
74 	struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
75 
76 	gpiod_set_value_cansleep(ts_data->reset_gpio, 1);
77 	msleep(20);
78 	gpiod_set_value_cansleep(ts_data->reset_gpio, 0);
79 	if (delay)
80 		fsleep(delay * 1000);
81 }
82 
83 static irqreturn_t hyn_interrupt_handler(int irq, void *dev_id)
84 {
85 	struct i2c_client *client = dev_id;
86 	struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
87 
88 	ts_data->chip->report_touch(client);
89 
90 	return IRQ_HANDLED;
91 }
92 
93 /*
94  * The vendor driver would retry twice before failing to read or write
95  * to the i2c device.
96  */
97 
98 static int cst3xx_i2c_write(struct i2c_client *client,
99 			    unsigned char *buf, int len)
100 {
101 	int ret;
102 	int retries = 0;
103 
104 	while (retries < 2) {
105 		ret = i2c_master_send(client, buf, len);
106 		if (ret == len)
107 			return 0;
108 		if (ret <= 0)
109 			retries++;
110 		else
111 			break;
112 	}
113 
114 	return ret < 0 ? ret : -EIO;
115 }
116 
117 static int cst3xx_i2c_read_register(struct i2c_client *client, u16 reg,
118 				    u8 *val, u16 len)
119 {
120 	__le16 buf = cpu_to_le16(reg);
121 	struct i2c_msg msgs[] = {
122 		{
123 			.addr = client->addr,
124 			.flags = 0,
125 			.len = 2,
126 			.buf = (u8 *)&buf,
127 		},
128 		{
129 			.addr = client->addr,
130 			.flags = I2C_M_RD,
131 			.len = len,
132 			.buf = val,
133 		}
134 	};
135 	int err;
136 	int ret;
137 
138 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
139 	if (ret == ARRAY_SIZE(msgs))
140 		return 0;
141 
142 	err = ret < 0 ? ret : -EIO;
143 	dev_err(&client->dev, "Error reading %d bytes from 0x%04x: %d (%d)\n",
144 		len, reg, err, ret);
145 
146 	return err;
147 }
148 
149 static int cst3xx_firmware_info(struct i2c_client *client)
150 {
151 	struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
152 	int err;
153 	u32 tmp;
154 	unsigned char buf[4];
155 
156 	/*
157 	 * Tests suggest this command needed to read firmware regs.
158 	 */
159 	put_unaligned_le16(CST3XX_FIRMWARE_INFO_START_CMD, buf);
160 	err = cst3xx_i2c_write(client, buf, 2);
161 	if (err)
162 		return err;
163 
164 	usleep_range(10000, 11000);
165 
166 	/*
167 	 * Read register for check-code to determine if device detected
168 	 * correctly.
169 	 */
170 	err = cst3xx_i2c_read_register(client, CST3XX_FIRMWARE_CHK_CODE_REG,
171 				       buf, 4);
172 	if (err)
173 		return err;
174 
175 	tmp = get_unaligned_le32(buf);
176 	if ((tmp & 0xffff0000) != ts_data->chip->ic_chkcode) {
177 		dev_err(&client->dev, "%s ic mismatch, chkcode is %u\n",
178 			__func__, tmp);
179 		return -ENODEV;
180 	}
181 
182 	usleep_range(10000, 11000);
183 
184 	/* Read firmware version and test if firmware missing. */
185 	err = cst3xx_i2c_read_register(client, CST3XX_FIRMWARE_VERSION_REG,
186 				       buf, 4);
187 	if (err)
188 		return err;
189 
190 	tmp = get_unaligned_le32(buf);
191 	if (tmp == CST3XX_FIRMWARE_VER_INVALID_VAL) {
192 		dev_err(&client->dev, "Device firmware missing\n");
193 		return -ENODEV;
194 	}
195 
196 	/*
197 	 * Tests suggest cmd required to exit reading firmware regs.
198 	 */
199 	put_unaligned_le16(CST3XX_FIRMWARE_INFO_END_CMD, buf);
200 	err = cst3xx_i2c_write(client, buf, 2);
201 	if (err)
202 		return err;
203 
204 	usleep_range(5000, 6000);
205 
206 	return 0;
207 }
208 
209 static int cst3xx_bootloader_enter(struct i2c_client *client)
210 {
211 	int err;
212 	u8 retry;
213 	u32 tmp = 0;
214 	unsigned char buf[3];
215 
216 	for (retry = 0; retry < 5; retry++) {
217 		hyn_reset_proc(client, (7 + retry));
218 		/* set cmd to enter program mode */
219 		put_unaligned_le24(CST3XX_BOOTLDR_PROG_CMD, buf);
220 		err = cst3xx_i2c_write(client, buf, 3);
221 		if (err)
222 			continue;
223 
224 		usleep_range(2000, 2500);
225 
226 		/* check whether in program mode */
227 		err = cst3xx_i2c_read_register(client,
228 					       CST3XX_BOOTLDR_PROG_CHK_REG,
229 					       buf, 1);
230 		if (err)
231 			continue;
232 
233 		tmp = get_unaligned(buf);
234 		if (tmp == CST3XX_BOOTLDR_CHK_VAL)
235 			break;
236 	}
237 
238 	if (tmp != CST3XX_BOOTLDR_CHK_VAL) {
239 		dev_err(&client->dev, "%s unable to enter bootloader mode\n",
240 			__func__);
241 		return -ENODEV;
242 	}
243 
244 	hyn_reset_proc(client, 40);
245 
246 	return 0;
247 }
248 
249 static void cst3xx_report_contact(struct hynitron_ts_data *ts_data,
250 				  u8 id, unsigned int x, unsigned int y, u8 w)
251 {
252 	input_mt_slot(ts_data->input_dev, id);
253 	input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, 1);
254 	touchscreen_report_pos(ts_data->input_dev, &ts_data->prop, x, y, true);
255 	input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR, w);
256 }
257 
258 static int cst3xx_finish_touch_read(struct i2c_client *client)
259 {
260 	unsigned char buf[3];
261 	int err;
262 
263 	put_unaligned_le24(CST3XX_TOUCH_DATA_STOP_CMD, buf);
264 	err = cst3xx_i2c_write(client, buf, 3);
265 	if (err) {
266 		dev_err(&client->dev,
267 			"send read touch info ending failed: %d\n", err);
268 		return err;
269 	}
270 
271 	return 0;
272 }
273 
274 /*
275  * Handle events from IRQ. Note that for cst3xx it appears that IRQ
276  * fires continuously while touched, otherwise once every 1500ms
277  * when not touched (assume touchscreen waking up periodically).
278  * Note buffer is sized for 5 fingers, if more needed buffer must
279  * be increased. The buffer contains 5 bytes for each touch point,
280  * a touch count byte, a check byte, and then a second check byte after
281  * all other touch points.
282  *
283  * For example 1 touch would look like this:
284  * touch1[5]:touch_count[1]:chk_byte[1]
285  *
286  * 3 touches would look like this:
287  * touch1[5]:touch_count[1]:chk_byte[1]:touch2[5]:touch3[5]:chk_byte[1]
288  */
289 static void cst3xx_touch_report(struct i2c_client *client)
290 {
291 	struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
292 	u8 buf[28];
293 	u8 finger_id, sw, w;
294 	unsigned int x, y;
295 	unsigned int touch_cnt, end_byte;
296 	unsigned int idx = 0;
297 	unsigned int i;
298 	int err;
299 
300 	/* Read and validate the first bits of input data. */
301 	err = cst3xx_i2c_read_register(client, CST3XX_TOUCH_DATA_PART_REG,
302 				       buf, 28);
303 	if (err ||
304 	    buf[6] != CST3XX_TOUCH_DATA_CHK_VAL ||
305 	    buf[0] == CST3XX_TOUCH_DATA_CHK_VAL) {
306 		dev_err(&client->dev, "cst3xx touch read failure\n");
307 		return;
308 	}
309 
310 	/* Report to the device we're done reading the touch data. */
311 	err = cst3xx_finish_touch_read(client);
312 	if (err)
313 		return;
314 
315 	touch_cnt = buf[5] & CST3XX_TOUCH_COUNT_MASK;
316 	/*
317 	 * Check the check bit of the last touch slot. The check bit is
318 	 * always present after touch point 1 for valid data, and then
319 	 * appears as the last byte after all other touch data.
320 	 */
321 	if (touch_cnt > 1) {
322 		end_byte = touch_cnt * 5 + 2;
323 		if (buf[end_byte] != CST3XX_TOUCH_DATA_CHK_VAL) {
324 			dev_err(&client->dev, "cst3xx touch read failure\n");
325 			return;
326 		}
327 	}
328 
329 	/* Parse through the buffer to capture touch data. */
330 	for (i = 0; i < touch_cnt; i++) {
331 		x = ((buf[idx + 1] << 4) | ((buf[idx + 3] >> 4) & 0x0f));
332 		y = ((buf[idx + 2] << 4) | (buf[idx + 3] & 0x0f));
333 		w = (buf[idx + 4] >> 3);
334 		sw = (buf[idx] & 0x0f) >> 1;
335 		finger_id = (buf[idx] >> 4) & 0x0f;
336 
337 		/* Sanity check we don't have more fingers than we expect */
338 		if (ts_data->chip->max_touch_num < finger_id) {
339 			dev_err(&client->dev, "cst3xx touch read failure\n");
340 			break;
341 		}
342 
343 		/* sw value of 0 means no touch, 0x03 means touch */
344 		if (sw == CST3XX_TOUCH_DATA_TOUCH_VAL)
345 			cst3xx_report_contact(ts_data, finger_id, x, y, w);
346 
347 		idx += 5;
348 
349 		/* Skip the 2 bytes between point 1 and point 2 */
350 		if (i == 0)
351 			idx += 2;
352 	}
353 
354 	input_mt_sync_frame(ts_data->input_dev);
355 	input_sync(ts_data->input_dev);
356 }
357 
358 static int cst3xx_input_dev_int(struct i2c_client *client)
359 {
360 	struct hynitron_ts_data *ts_data = i2c_get_clientdata(client);
361 	int err;
362 
363 	ts_data->input_dev = devm_input_allocate_device(&client->dev);
364 	if (!ts_data->input_dev) {
365 		dev_err(&client->dev, "Failed to allocate input device\n");
366 		return -ENOMEM;
367 	}
368 
369 	ts_data->input_dev->name = "Hynitron cst3xx Touchscreen";
370 	ts_data->input_dev->phys = "input/ts";
371 	ts_data->input_dev->id.bustype = BUS_I2C;
372 
373 	input_set_drvdata(ts_data->input_dev, ts_data);
374 
375 	input_set_capability(ts_data->input_dev, EV_ABS, ABS_MT_POSITION_X);
376 	input_set_capability(ts_data->input_dev, EV_ABS, ABS_MT_POSITION_Y);
377 	input_set_abs_params(ts_data->input_dev, ABS_MT_TOUCH_MAJOR,
378 			     0, 255, 0, 0);
379 
380 	touchscreen_parse_properties(ts_data->input_dev, true, &ts_data->prop);
381 
382 	if (!ts_data->prop.max_x || !ts_data->prop.max_y) {
383 		dev_err(&client->dev,
384 			"Invalid x/y (%d, %d), using defaults\n",
385 			ts_data->prop.max_x, ts_data->prop.max_y);
386 		ts_data->prop.max_x = 1152;
387 		ts_data->prop.max_y = 1920;
388 		input_abs_set_max(ts_data->input_dev,
389 				  ABS_MT_POSITION_X, ts_data->prop.max_x);
390 		input_abs_set_max(ts_data->input_dev,
391 				  ABS_MT_POSITION_Y, ts_data->prop.max_y);
392 	}
393 
394 	err = input_mt_init_slots(ts_data->input_dev,
395 				  ts_data->chip->max_touch_num,
396 				  INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
397 	if (err) {
398 		dev_err(&client->dev,
399 			"Failed to initialize input slots: %d\n", err);
400 		return err;
401 	}
402 
403 	err = input_register_device(ts_data->input_dev);
404 	if (err) {
405 		dev_err(&client->dev,
406 			"Input device registration failed: %d\n", err);
407 		return err;
408 	}
409 
410 	return 0;
411 }
412 
413 static int hyn_probe(struct i2c_client *client)
414 {
415 	struct hynitron_ts_data *ts_data;
416 	int err;
417 
418 	ts_data = devm_kzalloc(&client->dev, sizeof(*ts_data), GFP_KERNEL);
419 	if (!ts_data)
420 		return -ENOMEM;
421 
422 	ts_data->client = client;
423 	i2c_set_clientdata(client, ts_data);
424 
425 	ts_data->chip = device_get_match_data(&client->dev);
426 	if (!ts_data->chip)
427 		return -EINVAL;
428 
429 	ts_data->reset_gpio = devm_gpiod_get(&client->dev,
430 					     "reset", GPIOD_OUT_LOW);
431 	err = PTR_ERR_OR_ZERO(ts_data->reset_gpio);
432 	if (err) {
433 		dev_err(&client->dev, "request reset gpio failed: %d\n", err);
434 		return err;
435 	}
436 
437 	hyn_reset_proc(client, 60);
438 
439 	err = ts_data->chip->bootloader_enter(client);
440 	if (err < 0)
441 		return err;
442 
443 	err = ts_data->chip->init_input(client);
444 	if (err < 0)
445 		return err;
446 
447 	err = ts_data->chip->firmware_info(client);
448 	if (err < 0)
449 		return err;
450 
451 	err = devm_request_threaded_irq(&client->dev, client->irq,
452 					NULL, hyn_interrupt_handler,
453 					IRQF_ONESHOT,
454 					"Hynitron Touch Int", client);
455 	if (err) {
456 		dev_err(&client->dev, "failed to request IRQ: %d\n", err);
457 		return err;
458 	}
459 
460 	return 0;
461 }
462 
463 static const struct hynitron_ts_chip_data cst3xx_data = {
464 	.max_touch_num		= 5,
465 	.ic_chkcode		= 0xcaca0000,
466 	.firmware_info		= &cst3xx_firmware_info,
467 	.bootloader_enter	= &cst3xx_bootloader_enter,
468 	.init_input		= &cst3xx_input_dev_int,
469 	.report_touch		= &cst3xx_touch_report,
470 };
471 
472 static const struct i2c_device_id hyn_tpd_id[] = {
473 	{ .name = "hynitron_ts", 0 },
474 	{ /* sentinel */ },
475 };
476 MODULE_DEVICE_TABLE(i2c, hyn_tpd_id);
477 
478 static const struct of_device_id hyn_dt_match[] = {
479 	{ .compatible = "hynitron,cst340", .data = &cst3xx_data },
480 	{ /* sentinel */ },
481 };
482 MODULE_DEVICE_TABLE(of, hyn_dt_match);
483 
484 static struct i2c_driver hynitron_i2c_driver = {
485 	.driver = {
486 		.name = "Hynitron-TS",
487 		.of_match_table = hyn_dt_match,
488 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
489 	},
490 	.id_table = hyn_tpd_id,
491 	.probe_new = hyn_probe,
492 };
493 
494 module_i2c_driver(hynitron_i2c_driver);
495 
496 MODULE_AUTHOR("Chris Morgan");
497 MODULE_DESCRIPTION("Hynitron Touchscreen Driver");
498 MODULE_LICENSE("GPL");
499