Microchip AR1100 touchscreen driver with Mainline kernel 4.14.y

I am trying to add Microchip AR1100 touchscreen device to mainline kernel build. The AR1100 is not a traditional I2C or SPI device. Instead, it provides a simple UART interface. Smart | Connected | Secure | Microchip Technology

I realize this is not supported, but I am hoping for a nudge in the correct direction. The device and open source code driver are old (probably linux 3.x kernel). I am not sure if this driver is compatible with mainline kernel. I created a patch (attached) for the kernel. That builds into the kernel without errors. I created the userspace portion of the driver as a recipe attached.

When I run the userspace application: “inputactivate -ar1xxx /dev/ttyS3”, the kernel crashes:

[   24.084043] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[   24.095600] pgd = f5560000
[   24.100498] [00000000] *pgd=baab4831
[   24.106250] Internal error: Oops: 80000007 [#1] PREEMPT SMP ARM
[   24.114363] Modules linked in:
[   24.119565] CPU: 2 PID: 123 Comm: inputactivate Not tainted 4.14.72-2.8.4 #8
[   24.128818] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[   24.137312] task: f608c700 task.stack: f683c000
[   24.144037] PC is at 0x0
[   24.148699] LR is at serial8250_do_set_ldisc+0x64/0x98
[   24.155929] pc : [<00000000>]    lr : [<c049a074>]    psr: 60000093
[   24.164294] sp : f683de78  ip : 00000000  fp : 00000000
[   24.171627] r10: f6094080  r9 : 00000000  r8 : f54eec80
[   24.178959] r7 : f54eec80  r6 : f6094000  r5 : f60adb0c  r4 : c140ead0
[   24.187612] r3 : 00000000  r2 : 00000000  r1 : 00000001  r0 : c140ead0
[   24.196297] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   24.205721] Control: 10c5387d  Table: b556004a  DAC: 00000051
[   24.213642] Process inputactivate (pid: 123, stack limit = 0xf683c210)
[   24.222365] Stack: (0xf683de78 to 0xf683e000)
[   24.228882] de60:                                                       f60adba4 c04933cc
[   24.239259] de80: f6094000 00000000 00000002 c0480410 00005423 f6094000 f6af79c0 00000000
[   24.249613] dea0: bef94dac f6094000 00000000 c04798dc f6ada6b8 f6af76c8 00000002 00000002
[   24.259918] dec0: c0478258 00000002 00000000 c024e560 00000000 00000000 00000000 f6af76c0
[   24.270165] dee0: 00000000 f683df08 f6af76c0 00000002 f683df08 c024e6a8 f683df04 f683df08
[   24.280365] df00: 00000000 00000000 00000001 00000000 00000000 bef94dac f6ada1d8 f6af79c0
[   24.290564] df20: 00000003 bef94dac f683c000 c0260cc8 f6890518 f60cd000 c024c9e0 a0000013
[   24.300789] df40: 00000020 f6af79c8 f6ada1d8 00000000 00000000 c0245e90 00000003 f6af79c0
[   24.311048] df60: f60cd000 f6af76c0 f6af76c0 00000000 f6af79c0 f6af79c0 00000003 00005423
[   24.321352] df80: bef94dac f683c000 00000000 c0261528 00022700 00000003 0000001c 00000036
[   24.331722] dfa0: c0108a84 c01088a0 00022700 00000003 00000003 00005423 bef94dac bef94d98
[   24.342153] dfc0: 00022700 00000003 0000001c 00000036 b6f910b0 bef94dac 00000002 00000000
[   24.352651] dfe0: 00022010 bef94d80 00010a28 b6f28c8c 60000010 00000003 00000000 00000000
[   24.363138] [<c049a074>] (serial8250_do_set_ldisc) from [<c04933cc>] (uart_set_ldisc+0x3c/0x48)
[   24.374160] [<c04933cc>] (uart_set_ldisc) from [<c0480410>] (tty_set_ldisc+0x140/0x1c8)
[   24.384523] [<c0480410>] (tty_set_ldisc) from [<c04798dc>] (tty_ioctl+0x220/0xabc)
[   24.394467] [<c04798dc>] (tty_ioctl) from [<c0260cc8>] (do_vfs_ioctl+0x9c/0x8c8)
[   24.404237] [<c0260cc8>] (do_vfs_ioctl) from [<c0261528>] (SyS_ioctl+0x34/0x58)
[   24.413914] [<c0261528>] (SyS_ioctl) from [<c01088a0>] (ret_fast_syscall+0x0/0x54)
[   24.423834] Code: bad PC value
[   24.429201] ---[ end trace e3b0440d1cf81d3d ]---
[   24.436210] note: inputactivate[123] exited with preempt_count 1
[   32.199915] random: crng init done
[   38.889663] NOHZ: local_softirq_pending 08

I’ve narrowed down the crash to this section of inputactivate.c

fprintf(stderr, "c\n");
	id = input_types[type].id;
	extra = input_types[type].extra;
fprintf(stderr, "d\n");
	if (input_types[type].init && input_types[type].init(fd, &id, &extra)) {
		fprintf(stderr, "inputattach: device initialization failed\n");
		return 1;
	}
fprintf(stderr, "e\n");
	ldisc = N_MOUSE;
	if(ioctl(fd, TIOCSETD, &ldisc)) {
		fprintf(stderr, "inputattach: can't set line discipline\n"); 
		return 1;
	}
fprintf(stderr, "f\n");
	devt = /*SERIO_RS232 | */input_types[type].type | (id << 8) | (extra << 16);

	**if(ioctl(fd, SPIOCSTYPE, &devt))** {
		fprintf(stderr, "inputattach: can't set device type\n");
		return 1;
	}

The line: if(ioctl(fd, TIOCSETD, &ldisc)) with ldisc=N_MOUSE is where it is crashing. I am unsure if this driver is compatible with mainline, as it is old. I am also not sure if perhaps there is just something missing that it is trying to attach too. From what I understand, once enabled, the touchscreen just outputs touch x,y corrdinates over a UART and connects much like a traditional mouse. There is a PDF in the source package. attached. In the documentation PDF, they talk about alternately using the “hampshire” kernel module. I’m not sure, but maybe that is another option? Any thoughts much appreciated.

It looks like inputactivate.c is just a custom inputattach method. I’m going to try adding a new line lidscipline number to tty.h and see if that helps?

This might be related to similar issues described here.

I was using the wrong UART mapping for Apalis T30.

If I use inputattach -ar1xxx /dev/ttyTHS2, it no longer crashes.

Perfect that it works. Thanks for the letting us know.