BenWhite
Posts: 4
Joined: Tue Sep 13, 2016 11:14 am

AR1021 Touch Controller Overlay/Driver Issues

Tue Sep 13, 2016 11:34 am

Hi,
I've spent the past few days going round in circles trying to get the Microchip AR1021 I2C touchscreen controller working in the carrier board which I've designed for the CM. So far I've been unable to get the kernel module (ar1021_i2c from the raspberrypi/linux Github) to successfully load. I seem to always end up with one of the two following problems as reported in dmesg.
Most of the many variations on the overlays I've tried end up as in scenario 1, below. I haven't been able to find what error: -22 actually indicates, which might point in the right direction.
Scenario 1:

Code: Select all

[   94.008787] ------------[ cut here ]------------
[   94.008857] WARNING: CPU: 0 PID: 936 at drivers/irqchip/irq-bcm2835.c:182 armctrl_xlate+0x98/0xb8()
[   94.008873] Modules linked in: ar1021_i2c(+) bnep bluetooth rndis_host cdc_ether cfg80211 rfkill evdev rtc_pcf8523 hid_ortek i2c_bcm2708 bcm2835_gpiomem bcm2835_wdt uio_pdrv_genirq uio sg i2c_dev fuse ipv6
[   94.008977] CPU: 0 PID: 936 Comm: modprobe Not tainted 4.4.13+ #894
[   94.008990] Hardware name: BCM2708
[   94.009052] [<c0016c9c>] (unwind_backtrace) from [<c0013c20>] (show_stack+0x20/0x24)
[   94.009086] [<c0013c20>] (show_stack) from [<c02e347c>] (dump_stack+0x20/0x28)
[   94.009122] [<c02e347c>] (dump_stack) from [<c0021e54>] (warn_slowpath_common+0x8c/0xc4)
[   94.009149] [<c0021e54>] (warn_slowpath_common) from [<c0021f48>] (warn_slowpath_null+0x2c/0x34)
[   94.009177] [<c0021f48>] (warn_slowpath_null) from [<c0307484>] (armctrl_xlate+0x98/0xb8)
[   94.009220] [<c0307484>] (armctrl_xlate) from [<c005f9b8>] (irq_create_fwspec_mapping+0x88/0x150)
[   94.009253] [<c005f9b8>] (irq_create_fwspec_mapping) from [<c005fae4>] (irq_create_of_mapping+0x64/0x6c)
[   94.009391] [<c005fae4>] (irq_create_of_mapping) from [<c046b8fc>] (of_irq_get+0x4c/0x5c)
[   94.009474] [<c046b8fc>] (of_irq_get) from [<c041a95c>] (i2c_device_probe+0x208/0x224)
[   94.009522] [<c041a95c>] (i2c_device_probe) from [<c0369ffc>] (driver_probe_device+0x200/0x304)
[   94.009552] [<c0369ffc>] (driver_probe_device) from [<c036a19c>] (__driver_attach+0x9c/0xa0)
[   94.009579] [<c036a19c>] (__driver_attach) from [<c036827c>] (bus_for_each_dev+0x7c/0xb0)
[   94.009605] [<c036827c>] (bus_for_each_dev) from [<c0369a28>] (driver_attach+0x28/0x30)
[   94.009632] [<c0369a28>] (driver_attach) from [<c0369638>] (bus_add_driver+0x19c/0x224)
[   94.009658] [<c0369638>] (bus_add_driver) from [<c036a824>] (driver_register+0x88/0x108)
[   94.009687] [<c036a824>] (driver_register) from [<c041b694>] (i2c_register_driver+0x3c/0x90)
[   94.009728] [<c041b694>] (i2c_register_driver) from [<bf206018>] (ar1021_i2c_driver_init+0x18/0x24 [ar1021_i2c])
[   94.009780] [<bf206018>] (ar1021_i2c_driver_init [ar1021_i2c]) from [<c00095b8>] (do_one_initcall+0x90/0x1f0)
[   94.009814] [<c00095b8>] (do_one_initcall) from [<c00d7378>] (do_init_module+0x6c/0x1d0)
[   94.009848] [<c00d7378>] (do_init_module) from [<c007e44c>] (load_module+0x19c0/0x1ef4)
[   94.009877] [<c007e44c>] (load_module) from [<c007eb28>] (SyS_finit_module+0x74/0x84)
[   94.009906] [<c007eb28>] (SyS_finit_module) from [<c000f820>] (ret_fast_syscall+0x0/0x1c)
[   94.009922] ---[ end trace e82f9e3d2b8bf3ba ]---
[   94.010002] ar1021_i2c 0-004d: Failed to enable IRQ, error: -22
[   94.010056] ar1021_i2c: probe of 0-004d failed with error -22
This happens when using the device tree suggested in viewtopic.php?f=66&t=124727&p=862834&hi ... 21#p862834 which I have as follows:

Code: Select all

// Enable the AR1021 touchscreen controller
/dts-v1/;
/plugin/;

/ {
	compatible = "brcm,bcm2708";
	
	fragment@0 {
		target = <&i2c0>;
		
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			ar1021: ar1021@4d {
				compatible = "microchip,ar1021-i2c";
				reg = <0x4d>;
				
				interupt-parent = <&gpio>;
				interrupts = <35 0x8>;

				gpios = <&gpio 35 2>;			

				status = "okay";
			};
		};
	};
};
Or when I use something like from here viewtopic.php?f=107&t=153424

Code: Select all

// Enable the AR1021 touchscreen controller
/dts-v1/;
/plugin/;

/ {
	compatible = "brcm,brcm2835","brcm,bcm2708","brcm,brcm2709";

	fragment@0 {
		target = <&i2c0>;
		
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			ar1021: ar1021@4d {
				compatible = "microchip,ar1021-i2c";
				reg = <0x4d>;

				pinctrl-names = "default";
				//pinctrl-0 = <&ar1021_pins>;
				
				interupt-parent = <&gpio>;
				interrupts = <35 0x1>;		// rising edge		

				status = "okay";
			};
		};
	};

	fragment@1 {
		target = <&gpio>;

		__overlay__ {
			ar1021_pins: ar1021_pins {
				brcm,pins = <35>;
				brcm,function = <0>;		// input
				brcm,pull = <1>; 		// down
			};
		};
	};
};
Scenario 2:
If I uncomment the pinctrl-0 line in the above overlay I simply get

Code: Select all

[  111.367731] ar1021_i2c 0-004d: could not find pctldev for node /soc/interrupt-controller@7e00b200, deferring probe
Any help greatly appreciated!

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4740
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: AR1021 Touch Controller Overlay/Driver Issues

Tue Sep 13, 2016 2:26 pm

22 is EINVAL (Invalid argument). Notice that the kernel WARNING is coming from the irq-bcm2835 driver, but your overlay is trying to use the GPIO driver as a source of interrupts. This would be fine, if you had typed "interrupt-parent" correctly.

The error is presumably because the interrupt controller can't make sense of the interrupt descriptor - the GPIO driver wants "<gpio> <flags>", whereas irq-bcm2835 wants "<bank> <index>", and 35 is too high for a bank number.

Fix that and try again.

BenWhite
Posts: 4
Joined: Tue Sep 13, 2016 11:14 am

Re: AR1021 Touch Controller Overlay/Driver Issues

Tue Sep 13, 2016 4:37 pm

Thanks so much - that was embarrassingly simple! Demonstrates the value of a second opinion. Fixed the typo in the first overlay and now it's working.

Only remaining problem is that the module ar1021_i2c is not automatically loaded. I seem to remember reading something about i2c devices adding prefixes to the compatible string?

Could you shed any light on getting this working? It's not too important though: can always load the module with modprobe on startup.

May be of some use:

Code: Select all

pi@raspberrypi:~ $ grep ar1021 /lib/modules/`uname -r`/modules.alias
alias i2c:MICROCHIP_AR1021_I2C ar1021_i2c
alias of:N*T*Cmicrochip,ar1021-i2c* ar1021_i2c

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4740
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: AR1021 Touch Controller Overlay/Driver Issues

Tue Sep 13, 2016 4:43 pm

The I2C framework seems to match the part of the DT alias after the comma with the I2C alias - try using "microchip,ar1021_i2c" (note the underscore) instead. If that doesn't work, I'll have to test it myself.

BenWhite
Posts: 4
Joined: Tue Sep 13, 2016 11:14 am

Re: AR1021 Touch Controller Overlay/Driver Issues

Wed Sep 14, 2016 9:56 am

No luck: changing to an underscore stops it working entirely.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4740
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: AR1021 Touch Controller Overlay/Driver Issues

Wed Sep 14, 2016 10:37 am

Let's make use of the Dynamic Device Tree feature to help us debug the problem.

1) Remove the dtoverlay line from config.txt and reboot.
2) Start a udev monitor logging udev traffic to a file:

Code: Select all

udevadm monitor --kernel --property > udevlog.txt &
3) Load the overlay:

Code: Select all

sudo dtoverlay ar1021.dtbo  # Or whatever you called it
Note that with the suffix the string will be treated as a file path, otherwise it is treated as a name and searched for in /boot/overlays.
4) You can now kill off the udev monitor:

Code: Select all

killall -HUP udevadm
5) Now search the log for module aliases:

Code: Select all

grep ALIAS udevlog.txt
In my case I was using an audio card I had to hand and got the following output:

Code: Select all

MODALIAS=of:Ndacpro_oscT<NULL>Chifiberry,dacpro-clk
MODALIAS=of:Ni2sT<NULL>Cbrcm,bcm2835-i2s
MODALIAS=of:Ni2cT<NULL>Cbrcm,bcm2708-i2c
OF_ALIAS_0=i2c1
MODALIAS=of:NsoundT<NULL>Chifiberry,hifiberry-dacplus
OF_ALIAS_0=i2c1
MODALIAS=i2c:pcm5122
MODALIAS=platform:snd-soc-dummy
6) Search the list of known module aliases for a match:

Code: Select all

pi@raspberrypi ~ $ grep pcm5122 /lib/modules/`uname -r`/modules.alias
alias i2c:pcm5122 snd_soc_pcm512x_i2c
alias of:N*T*Cti,pcm5122* snd_soc_pcm512x_2c
You will have to substitute ar1021 as a pattern string.

Let me know what you find.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4740
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: AR1021 Touch Controller Overlay/Driver Issues

Wed Sep 14, 2016 11:09 am

Code: Select all

sound/soc/codecs/pcm512x-i2c.c-static const struct i2c_device_id pcm512x_i2c_id[] = {
sound/soc/codecs/pcm512x-i2c.c-	{ "pcm5121", },
sound/soc/codecs/pcm512x-i2c.c-	{ "pcm5122", },
sound/soc/codecs/pcm512x-i2c.c-	{ "pcm5141", },
sound/soc/codecs/pcm512x-i2c.c-	{ "pcm5142", },
sound/soc/codecs/pcm512x-i2c.c-	{ }
sound/soc/codecs/pcm512x-i2c.c-};
sound/soc/codecs/pcm512x-i2c.c:MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);

Code: Select all

drivers/input/touchscreen/ar1021_i2c.c-static const struct i2c_device_id ar1021_i2c_id[] = {
drivers/input/touchscreen/ar1021_i2c.c-	{ "MICROCHIP_AR1021_I2C", 0 },
drivers/input/touchscreen/ar1021_i2c.c-	{ },
drivers/input/touchscreen/ar1021_i2c.c-};
drivers/input/touchscreen/ar1021_i2c.c:MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id);
Looking at fragments of the two drivers above - my DAC, your touchscreen controller - by analogy I think the compatible string you need is:

Code: Select all

microchip,MICROCHIP_AR1021_I2C
where only the part after the comma is significant. I'm not happy with how I2C handles its module aliases - is this really the best we can do? - but this may provide a workaround for now. For now, it might be safest if you include both compatible strings in the overlay:

Code: Select all

compatible = "microchip,ar1021-i2c", "microchip,MICROCHIP_AR1021_I2C";

BenWhite
Posts: 4
Joined: Tue Sep 13, 2016 11:14 am

Re: AR1021 Touch Controller Overlay/Driver Issues

Wed Sep 14, 2016 12:03 pm

Still not loading.

Before adding the new compatible string you suggested the udevadm log is as follows

Code: Select all

KERNEL[678.407333] add      /devices/platform/soc/20205000.i2c/i2c-0/0-004d (i2c)
ACTION=add
DEVPATH=/devices/platform/soc/20205000.i2c/i2c-0/0-004d
MODALIAS=i2c:ar1021-i2c
OF_COMPATIBLE_0=microchip,ar1021-i2c
OF_COMPATIBLE_N=1
OF_FULLNAME=/soc/i2c@7e205000/ar1021@4d
OF_NAME=ar1021
SEQNUM=1067
SUBSYSTEM=i2c
Searching the aliases:

Code: Select all

pi@raspberrypi:~ $ grep ar1021-i2c /lib/modules/`uname -r`/modules.alias
alias of:N*T*Cmicrochip,ar1021-i2c* ar1021_i2c
Then with the addition of your compatible string:

Code: Select all

KERNEL[883.929106] add      /devices/platform/soc/20205000.i2c/i2c-0/0-004d (i2c)
ACTION=add
DEVPATH=/devices/platform/soc/20205000.i2c/i2c-0/0-004d
MODALIAS=i2c:ar1021-i2c
OF_COMPATIBLE_0=microchip,ar1021-i2c
OF_COMPATIBLE_1=microchip,MICROCHIP_AR1021_I2C
OF_COMPATIBLE_N=2
OF_FULLNAME=/soc/i2c@7e205000/ar1021@4d
OF_NAME=ar1021
SEQNUM=1069
SUBSYSTEM=i2c
But still the module doesn't load automatically.

Interestingly (maybe) this is what happens if I just use the new compatible string that you suggested:

Code: Select all

KERNEL[1328.492161] add      /devices/platform/soc/20205000.i2c/i2c-0/0-004d (i2c)
ACTION=add
DEVPATH=/devices/platform/soc/20205000.i2c/i2c-0/0-004d
MODALIAS=i2c:MICROCHIP_AR1021_I2
OF_COMPATIBLE_0=microchip,MICROCHIP_AR1021_I2C
OF_COMPATIBLE_N=1
OF_FULLNAME=/soc/i2c@7e205000/ar1021@4d
OF_NAME=ar1021
SEQNUM=1071
SUBSYSTEM=i2c
Note the MODALIAS line is missing the final character - I assume this is significant. Also, in this case, the driver is not working when loading the module with modprobe.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4740
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: AR1021 Touch Controller Overlay/Driver Issues

Thu Sep 15, 2016 1:33 pm

I have a fix, but it took a while to get there. I first thought I could get the kernel to advertise the OF/DT modaliases to udev, to the extent of writing a patch to do it - this was the commit message:

Code: Select all

i2c: Also locate modules using compatible strings
    
    I2C driver modules typically define two different aliases - an I2C alias
    of the form "i2c:<name>", and a DT alias based on the compatible string
    of the device - but the I2C subsystem only generates uevents for the I2C
    alias using the second half of the compatible string found in the device
    node.
    
    e.g. compatible = "microchip,ar1021-i2c";
    
    results in a uevent containing "MODALIAS=i2c:ar1021-i2c".
    
    This can be confusing for users since using the synthesised i2c alias
    may not match the i2c: alias registered for the driver module. In the
    case of the ar1021 touchscreen driver the I2C device ID is
    "MICROCHIP_AR1021_I2C" which translates to an I2C alias of
    "i2c:MICROCHIP_AR1021_I2C", but the compatible string is as shown
    above, with the consequence that using the obvious compatible string
    in a DT will not cause the module to be loaded.
    
    To remove this confusion, modify the I2C subsystem to also generate
    uevents containing the DT alias.
Unfortunately, each device can only have one MODALIAS, so the patch was replacing rather than augmenting the i2c modalias with the DT modalias - a change that would almost certainly break some use cases.

In the end I found that a custom udev rule for i2c devices provides an easy solution. Put this in /etc/udev/rules.d/10-local.rules:

Code: Select all

SUBSYSTEM=="i2c", ENV{MODALIAS}=="?*", ENV{OF_NAME}=="?*", ENV{OF_COMPATIBLE_0}=="?*", RUN+="/usr/bin/i2cprobe"
and this in /usr/bin/i2cprobe:

Code: Select all

#!/bin/sh
modprobe ${MODALIAS} || modprobe "of:N${OF_NAME}T<NULL>C${OF_COMPATIBLE_0}"
Make sure i2cprobe is executable.

Now when you run the dtoverlay command (sudo dtoverlay ar1021) udev will invoke i2cprobe which will try to probe "i2c:ar1021_i2c" and fail, then probe "of:Nar1021T<NULL>Cmicrochip,ar1021-i2c" and succeed.

I'll investigate making this a standard part of Raspbian.

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 4740
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: AR1021 Touch Controller Overlay/Driver Issues

Tue Sep 20, 2016 9:28 am

If you run

Code: Select all

sudo apt-get update && sudo apt-get install raspberrypi-sys-mods
you'll get an updated raspberrypi-sys-mods package that includes the new i2c module probing rule. Provided your kernel includes the ar1021 module, it will be loaded automatically when you load the overlay.

Thanks @ShiftPlusOne.

Return to “Device Tree”