Taita Posted September 21, 2020 Share Posted September 21, 2020 Armbianmonitor: http://ix.io/2ygy Heya, Configuration :: Friendlyarm NanoPi Neo (Allwinner H3) Matrix TFT2.8 (https://www.friendlyarm.com/index.php?route=product/product&product_id=102) Armbian Release: Bionic 5.8.y found here: https://www.armbian.com/nanopi-neo/ I have this st7789v-based display working on spi0.0 by utilising a custom overlay tft28.dts as below, but I cannot get the ads7846 touchscreen controller to use an additional gpio chip select (ie: spi0.1) because the ads7846 driver seems to be holding that additional cs line in a 'logic 0' state at zero volts. I believe the hardware is not at fault because it works correctly using the Friendlyarm provided Xenial image (linux kernel 4.14) here: https://drive.google.com/drive/folders/1Fg81ce8ucTOMDWrlT-F_zwH0-UljRMsM I can successfully register a second gpio chip select line for spi0 at the H3's gpio PA6 by using the custom cs1.dts below, which corresponds to pin12 of the Matrix 2.8TFT display's header. I can also load up a dummy 'spidev' device upon that additional chip select line which registers fine and is listed normally in dmesg as spi0.1. As long as I do not load up the ads7846 overlay, and use a dummy spidev at spi0.1 the PA6 gpio (ie: pin12 of the Matrix TFT28's header) stays logic high at 3.3volts which is expected idle operation for a spi chipselect line. But whenever I try to enable the ads7846 driver instead of spidev, that additional CS line (ie: gpio PA6 = pin12 on the header) is being held permanently low at 0volts. Thus, the XPT2046 chip (ads7846 clone) does not work properly. Any ideas on why this additional chipselect line (gpio PA6) is being held logic low at idle? Have I missed some assertion somewhere to make it idle at logic high (3.3v)? cs1.dts :: /dts-v1/; /plugin/; / { compatible = "allwinner,sun8i-h3"; fragment@0 { target = <&pio>; __overlay__ { spi0_cs1: spi0_cs1 { pins = "PA6"; function = "gpio_out"; output-high; }; }; }; fragment@1 { target = <&spi0>; __overlay__ { pinctrl-names = "default", "default"; pinctrl-1 = <&spi0_cs1>; cs-gpios = <0>, <&pio 0 6 0>; /* PA21 */ }; }; }; tft28.dts :: /dts-v1/; /plugin/; / { compatible = "allwinner,sun8i-h3"; fragment@0 { target = <&spi0>; __overlay__ { status = "okay"; }; }; fragment@1 { target = <&spi0>; __overlay__ { pitft: pitft@0{ compatible = "sitronix,st7789v"; reg = <0>; status = "okay"; spi-max-frequency = <50000000>; rotate = <90>; fps = <33>; buswidth = <8>; dc-gpios = <0x0b 0 1 0>; /* PA1 */ reset-gpios = <0x0b 6 11 0>; /* PG11 */ led-gpios = <0x0b 0 0 0>; /* PA0 */ debug = <0x0>; }; }; }; }; ads7846.dts :: /dts-v1/; /plugin/; / { compatible = "allwinner,sun4i-a10", "allwinner,sun7i-a20", "allwinner,sun8i-h3", "allwinner,sun50i-a64", "allwinner,sun50i-h5"; fragment@0 { target = <&spi0>; __overlay__ { status = "okay"; }; }; fragment@1 { target = <0x0b>; __overlay__ { ads7846_pins: ads7846_pins { pins= "PG9"; function = "irq"; }; }; }; fragment@2 { target = <&spi0>; __overlay__ { ads7846@0 { pinctrl-names = "default"; pinctrl-0 = <&ads7846_pins>; compatible = "ti,ads7846"; reg = <0x1>; status = "okay"; spi-max-frequency = <2000000>; interrupt-parent = <0x0b>; interrupts = <6 9 2>; /* PG9 / EINT9 */ pendown-gpio = <0x0b 6 9 0>; ti,swap-xy; ti,vref-delay-usecs = <1000>; ti,x-min = /bits/ 16 <100>; ti,x-max = /bits/ 16 <0xfff>; ti,y-min = /bits/ 16 <100>; ti,y-max = /bits/ 16 <0xfff>; ti,vref-mv = <3300>; ti,x-plate-ohms = /bits/ 16 <256>; ti,penirq-recheck-delay-usecs = <10>; ti,settle-delay-usec = /bits/ 16 <100>; ti,keep-vref-on = <1>; ti,pressure-max = /bits/ 16 <0xfff>; ti,debounce-max = <10>; ti,debounce-tol = <30>; ti,debounce-rep = <1>; }; }; }; }; /boot/armbianEnv.txt :: verbosity=1 bootlogo=false console=serial disp_mode=1920x1080p60 overlay_prefix=sun8i-h3 overlays=usbhost1 usbhost2 rootdev=UUID=7563442c-8c5f-41d1-ae68-eb9ab2f39452 rootfstype=ext4 user_overlays= cs1 tft28 ts #user_overlays= cs1 tft28 spidev #param_spidev_spi_bus=0 #param_spidev_spi_cs=1 usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u Output of dmesg | grep spi root@nanopineo:~# dmesg | grep spi [ 9.606195] ads7846 spi0.1: supply vcc not found, using dummy regulator [ 9.612769] fb_st7789v spi0.0: fbtft_property_value: buswidth = 8 [ 9.612786] fb_st7789v spi0.0: fbtft_property_value: debug = 0 [ 9.612794] fb_st7789v spi0.0: fbtft_property_value: rotate = 90 [ 9.612801] fb_st7789v spi0.0: fbtft_property_value: fps = 33 [ 9.628147] ads7846 spi0.1: touchscreen, irq 102 [ 9.628861] input: ADS7846 Touchscreen as /devices/platform/soc/1c68000.spi/spi_master/spi0/spi0.1/input/input1 [ 9.822379] graphics fb0: fb_st7789v frame buffer, 320x240, 150 KiB video memory, 4 KiB buffer memory, fps=35, spi0.0 at 50 MHz Link to comment Share on other sites More sharing options...
Coby Levy Posted September 26, 2020 Share Posted September 26, 2020 Hi, I'm having a similar issue with NanoPi Neo Core, in my case i I'm using ili9341 with latest debian kernel (5.8). I noticed it happens only when I start X11. if i stay in command-line - evtest command works fine. can you confirm its the same on your side? thx. Link to comment Share on other sites More sharing options...
Taita Posted September 26, 2020 Author Share Posted September 26, 2020 Hi Coby, I can't even get evtest to register any input, although the ads7846 is triggering udev to register an input device (event 1). Measuringthe spi0.1 cs GPIO pin during startup shows it goes high momentarily after UBoot kicks off the kernel, then it drops low as soon as the ads7846 kernel module is loaded. Link to comment Share on other sites More sharing options...
Taita Posted September 28, 2020 Author Share Posted September 28, 2020 Okay I have made some progress, I think. Still no data coming from /dev/input/event1 though. Working theory ATM is that the issue is here in ads7846.c :: /* leave chip selected when we're done, for quicker re-select? */ #if 0 #define CS_CHANGE(xfer) ((xfer).cs_change = 1) #else #define CS_CHANGE(xfer) ((xfer).cs_change = 0) #endif ... which made me think that the driver was keeping the CS line permanently active (ie: low). Assuming that the code authors presumed that ads7846 silicon would inhabit a spi bus all to itself. So I swapped them to make cs_change = 1 and rebuilt the module; now that CS line is now kept high when the screen is not touched, and pulses low when the system recieves interrupt (extected behaviour). No activity can be seen via evtest though. Time to get the oscilloscope out. Link to comment Share on other sites More sharing options...
Taita Posted September 28, 2020 Author Share Posted September 28, 2020 ** SOLVED ** The problem is caused by a change made somewhere upstream in mainline which causes any non-native chipselect lines (ie: assigned via GPIO) to be inverted through gpiolib. This causes such CS lines to default to the behaviour of active-high once it reaches the physical layer - at least for the ads7846 driver. I don't know exactly where this change was committed or why, but this should not be the default behaviour...it breaks drivers FFS! The solution would be to either: a) Re-write the ads7846.c driver to re-invert the CS behavior at the driver level (not gonna happen...not tonight anyways) b) Use the original ads7846.ko module (don't bother re-compiling like I tried above) and insert this 'legacy' line into the device tree fragment for the ads7846:: spi-cs-high; ...which I found referenced here in spi.c where it parses the dt for that driver and inverts the CS line: https://elixir.bootlin.com/linux/v5.8.11/source/drivers/spi/spi.c#L1900 The net effect is that the device-tree "spi-cs-high;" inverts the CS logic for that slave device, which then gets re-inverted back to normality via gpiolib. The reasons behind the upstream commit that caused this error are not clear or logical (go searching for it if you could be bothered) but CS active high is *very* rare, and problems shouldn't have to be solved by putting a 'legacy' device tree binding to fix a 'mainline' commit. Oh well, that's Linux for ya...we cannot complain whilst standing on the shoulders of giants. Happy poking Link to comment Share on other sites More sharing options...
Recommended Posts