notro / fbtft

Linux Framebuffer drivers for small TFT LCD display modules. Development has moved to https://git.kernel.org/cgit/linux/kernel/git/gregkh/staging.git/tree/drivers/staging/fbtft?h=staging-testing
1.84k stars 495 forks source link

Waveshare 3.5 "pico" device tree #580

Closed g0ierli closed 2 years ago

g0ierli commented 2 years ago

Hello,

I'm using a Waveshare 3.5 "pico" display (https://www.waveshare.com/wiki/Pico-ResTouch-LCD-3.5) which has an ILI9488 driver. However, before Kernel 5.4, i had no problem using the device by overriding the init option of the ILI9481:

/etc/modprobe.d/fbtft.conf:

options fbtft_device name=ili9481 init=-1,0x21,-1,0xC2,0x33,-1,0XC5,0x00,0x1e,0x80,-1,0xB1,0xB0,-1,0x36,0x28,-1,0XE0,0x0,0x13,0x18,0x04,0x0F,0x06,0x3a,0x56,0x4d,0x03,0x0a,0x06,0x30,0x3e,0x0f,-1,0XE1,0x0,0x13,0x18,0x01,0x11,0x06,0x38,0x34,0x4d,0x06,0x0d,0x0b,0x31,0x37,0x0f,-1,0X3A,0x55,-1,0x11,-2,120,-1,0x29,-3 gpios=reset:19,dc:13,cs:8,led:6 speed=20000000 bgr=1 fps=60 height=320 width=480 rotate=90

I tried to experiment with the following dts and messing around with width, height and rotate:

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835";

    // Enable the SPI controller
    fragment@0 {
        target = <&spi0>;
        __overlay__ {
            status = "okay";
        };
    };

    // Enabling the SPI controller also enables spidev on cs0, so we have disable it
    fragment@1 {
        target = <&spidev0>;
        __overlay__ {
            status = "disabled";
        };
    };

    fragment@2 {
        target = <&spi0>;
        __overlay__ {
            /* needed to avoid dtc warning */
            #address-cells = <1>;
            #size-cells = <0>;

            display: display@0{
                compatible = "ilitek,ili9481";
                reg = <0>; // Chip Select 0

                spi-max-frequency = <20000000>; // 20MHz

                reset-gpios = <&gpio 19 1>; // reset is active low hence the 1
                dc-gpios = <&gpio 13 0>;
                led-gpios = <&gpio 6 0>;

                width = <480>;
                height = <320>;
                buswidth = <8>; // Most controllers use this value
                rotate = <90>;

                init = <0x1000021
                    0x10000c2 0x33
                    0x10000c5 0x00 0x1e 0x80
                    0x10000B1 0xB0
                    0x1000036 0x28
                    0x10000E0 0x00 0x13 0x18 0x04 0x0F 0x06 0x3a 0x56 0x4d 0x03 0x0a 0x06 0x30 0x3e 0x0f
                    0x10000E1 0x00 0x13 0x18 0x01 0x11 0x06 0x38 0x34 0x4d 0x06 0x0d 0x0b 0x31 0x37 0x0f
                    0x100003A 0x55
                    0x1000011
                    0x2000078
                    0x1000029>;

                debug = <0x4000000>; // print init commands to the kernel log
            };
        };
    };
};

Although the correct init sequence is shown in dmesg:

[   35.542882] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /soc/spi@7e204000/status
[   35.542904] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /soc/spi@7e204000/spidev@0/status
[   35.642945] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[   35.644873] fb_ili9481: module is from the staging directory, the quality is unknown, you have been warned.
[   35.645247] fb_ili9481 spi0.0: fbtft_property_value: width = 480
[   35.645255] fb_ili9481 spi0.0: fbtft_property_value: height = 320
[   35.645263] fb_ili9481 spi0.0: fbtft_property_value: buswidth = 8
[   35.645272] fb_ili9481 spi0.0: fbtft_property_value: debug = 67108864
[   35.645279] fb_ili9481 spi0.0: fbtft_property_value: rotate = 90
[   35.785906] fb_ili9481 spi0.0: init: write_register:
[   35.785914] fb_ili9481 spi0.0: buf[0] = 21
[   35.785943] fb_ili9481 spi0.0: init: write_register:
[   35.785949] fb_ili9481 spi0.0: buf[0] = C2
[   35.785955] fb_ili9481 spi0.0: buf[1] = 33
[   35.785990] fb_ili9481 spi0.0: init: write_register:
[   35.785996] fb_ili9481 spi0.0: buf[0] = C5
[   35.786002] fb_ili9481 spi0.0: buf[1] = 00
[   35.786008] fb_ili9481 spi0.0: buf[2] = 1E
[   35.786013] fb_ili9481 spi0.0: buf[3] = 80
[   35.786048] fb_ili9481 spi0.0: init: write_register:
[   35.786054] fb_ili9481 spi0.0: buf[0] = B1
[   35.786059] fb_ili9481 spi0.0: buf[1] = B0
[   35.786093] fb_ili9481 spi0.0: init: write_register:
[   35.786099] fb_ili9481 spi0.0: buf[0] = 36
[   35.786104] fb_ili9481 spi0.0: buf[1] = 28
[   35.786138] fb_ili9481 spi0.0: init: write_register:
[   35.786144] fb_ili9481 spi0.0: buf[0] = E0
[   35.786149] fb_ili9481 spi0.0: buf[1] = 00
[   35.786155] fb_ili9481 spi0.0: buf[2] = 13
[   35.786160] fb_ili9481 spi0.0: buf[3] = 18
[   35.786166] fb_ili9481 spi0.0: buf[4] = 04
[   35.786171] fb_ili9481 spi0.0: buf[5] = 0F
[   35.786177] fb_ili9481 spi0.0: buf[6] = 06
[   35.786183] fb_ili9481 spi0.0: buf[7] = 3A
[   35.786188] fb_ili9481 spi0.0: buf[8] = 56
[   35.786194] fb_ili9481 spi0.0: buf[9] = 4D
[   35.786200] fb_ili9481 spi0.0: buf[10] = 03
[   35.786205] fb_ili9481 spi0.0: buf[11] = 0A
[   35.786211] fb_ili9481 spi0.0: buf[12] = 06
[   35.786216] fb_ili9481 spi0.0: buf[13] = 30
[   35.786222] fb_ili9481 spi0.0: buf[14] = 3E
[   35.786228] fb_ili9481 spi0.0: buf[15] = 0F
[   35.786268] fb_ili9481 spi0.0: init: write_register:
[   35.786274] fb_ili9481 spi0.0: buf[0] = E1
[   35.786279] fb_ili9481 spi0.0: buf[1] = 00
[   35.786285] fb_ili9481 spi0.0: buf[2] = 13
[   35.786290] fb_ili9481 spi0.0: buf[3] = 18
[   35.786296] fb_ili9481 spi0.0: buf[4] = 01
[   35.786302] fb_ili9481 spi0.0: buf[5] = 11
[   35.786307] fb_ili9481 spi0.0: buf[6] = 06
[   35.786313] fb_ili9481 spi0.0: buf[7] = 38
[   35.786318] fb_ili9481 spi0.0: buf[8] = 34
[   35.786324] fb_ili9481 spi0.0: buf[9] = 4D
[   35.786329] fb_ili9481 spi0.0: buf[10] = 06
[   35.786335] fb_ili9481 spi0.0: buf[11] = 0D
[   35.786340] fb_ili9481 spi0.0: buf[12] = 0B
[   35.786346] fb_ili9481 spi0.0: buf[13] = 31
[   35.786352] fb_ili9481 spi0.0: buf[14] = 37
[   35.786357] fb_ili9481 spi0.0: buf[15] = 0F
[   35.786397] fb_ili9481 spi0.0: init: write_register:
[   35.786403] fb_ili9481 spi0.0: buf[0] = 3A
[   35.786409] fb_ili9481 spi0.0: buf[1] = 55
[   35.786442] fb_ili9481 spi0.0: init: write_register:
[   35.786448] fb_ili9481 spi0.0: buf[0] = 11
[   35.786468] fb_ili9481 spi0.0: init: msleep(120)
[   35.925908] fb_ili9481 spi0.0: init: write_register:
[   35.925916] fb_ili9481 spi0.0: buf[0] = 29
[   36.058947] Console: switching to colour frame buffer device 40x30
[   36.059349] graphics fb0: fb_ili9481 frame buffer, 320x480, 300 KiB video memory, 4 KiB buffer memory, fps=20, spi0.0 at 20 MHz

the display output is very errornous. Switching width/height doesn't give me any useful image:

tmp_raspi

Any idea, how to debug this or how to implement my own driver or override an existing driver without much effort? Any help is appreciated!

notro commented 2 years ago

I looked at the fbtft_device entry:

        .name = "ili9481",
        .spi = &(struct spi_board_info) {
            .modalias = "fb_ili9481",
            .max_speed_hz = 32000000,
            .mode = SPI_MODE_0,
            .platform_data = &(struct fbtft_platform_data) {
                .display = {
                    .regwidth = 16,
                    .buswidth = 8,
                    .backlight = 1,
                },
                .bgr = true,
                .gpios = (const struct fbtft_gpio []) {
                    { "reset", 25 },
                    { "dc", 24 },
                    { "led", 22 },
                    {},
                },
            }
        }

It says regwidth=16. So I looked at the display schematics and yes it has a 16-bit shift register. Try adding regwidth = <16>; to the device tree.

g0ierli commented 2 years ago

Thank you very much. The behavior of the display changed, and the text seems to be wrapped now and some lines are missing, but the cursor is blinking in the very last line under the word 'distribution': tmp_raspi2

Subsequently, I also tried to switch width/height: tmp_raspi3

And it's working now. Thank you very much for your help.