背景
根据orangepi zero2用户手册说明,linux5.13内核不能使用 modprobe fbtft_device 驱动spi lcd
[img=50%,50%]https://img2024.cnblogs.com/blog/2965756/202405/2965756-20240523231053747-777004804.png[/img] 查看linux内核源码提交记录,发现在v5.4-rc3中删除了fbtft_device.c文件
[img=50%,50%]https://img2024.cnblogs.com/blog/2965756/202405/2965756-20240523231305036-1773607823.png[/img] commit如下- staging/fbtft: Remove fbtft_device
- Commit c440eee ("Staging: fbtft: Switch to the gpio descriptor
- interface") removed the gpio code from fbtft_device rendering it useless.
- fbtft_device is a module that was used on the Raspberry Pi to dynamically
- add fbtft devices when the Pi didn't have Device Tree support.
- Just remove the module since it's the responsibility of Device Tree, ACPI
- or platform code to add devices.
- Fixes: c440eee ("Staging: fbtft: Switch to the gpio descriptor interface")
- Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
- Link: https://lore.kernel.org/r/20190917171843.10334-2-noralf@tronnes.org
- Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
复制代码 “fbtft_device用来在树莓派没有设备树时,自动添加fbtft设备,删除这个模块因为添加设备是设备树、ACPI或者平台代码的责任”
所以是因为原来的代码不符合设备和驱动分离的原则,所以给删除了,但其实驱动程序依然在,理论上只需要将设备硬件信息注册到内核,就可以正常运行了,可以通过设备树或者模块
dts
下面看下orangepi官方修改后的内核源码中的设备树,分支orange-pi-6.1-sun50iw9
https://github.com/orangepi-xunlong/linux-orangepi
sun50i-h616.dtsi
从芯片级(h616)的dts可以看到spi有spi0和spi1,spi0有一个cs0,spi1有cs0和cs1- /omit-if-no-ref/
- spi0_pins: spi0-pins {
- pins = "PC0", "PC2", "PC4";
- function = "spi0";
- };
- /omit-if-no-ref/
- spi0_cs0_pin: spi0-cs0-pin {
- pins = "PC3";
- function = "spi0";
- };
- /omit-if-no-ref/
- spi1_pins: spi1-pins {
- pins = "PH6", "PH7", "PH8";
- function = "spi1";
- };
- /omit-if-no-ref/
- spi1_cs0_pin: spi1-cs0-pin {
- pins = "PH5";
- function = "spi1";
- };
- /omit-if-no-ref/
- spi1_cs1_pin: spi1-cs1-pin {
- pins = "PH9";
- function = "spi1";
- };
复制代码 spi1设备只添加了cs1,cs0引脚没有用在spi1上,而是复用在了i2c3- spi0: spi@5010000 {
- compatible = "allwinner,sun50i-h616-spi",
- "allwinner,sun8i-h3-spi";
- reg = <0x05010000 0x1000>;
- interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
- clock-names = "ahb", "mod";
- resets = <&ccu RST_BUS_SPI0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_pins>;
- dmas = <&dma 22>, <&dma 22>;
- dma-names = "rx", "tx";
- status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
- };
- spi1: spi@5011000 {
- compatible = "allwinner,sun50i-h616-spi",
- "allwinner,sun8i-h3-spi";
- reg = <0x05011000 0x1000>;
- interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
- clock-names = "ahb", "mod";
- resets = <&ccu RST_BUS_SPI1>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>, <&spi1_cs1_pin>;
- dmas = <&dma 23>, <&dma 23>;
- dma-names = "rx", "tx";
- status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
- };
复制代码 sun50i-h616-orangepi-zero2.dts
从板级(orangepi zero2)dts可以看到添加了一个spidev@1设备,但是默认未启用- &spi1 {
- status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>, <&spi1_cs1_pin>;
- spidev@1 {
- compatible = "rohm,dh2228fv";
- status = "disabled";
- reg = <1>;
- spi-max-frequency = <1000000>;
- };
- };
复制代码 硬件
可以看到spi0用来连接NOR FLASH,所以肯定不可以再用来连接lcd了
[img=50%,50%]https://img2024.cnblogs.com/blog/2965756/202405/2965756-20240523233253874-1044312203.png[/img] spi1在26PIN引出,并且cs0和cs1都有,不过cs0复用在了i2c3的TWI3-SDA引脚上,所以我们使用spi1驱动lcd,并且使用cs1
[img=50%,50%]https://img2024.cnblogs.com/blog/2965756/202405/2965756-20240523233534817-1937686464.png[/img] [img=50%,50%]https://img2024.cnblogs.com/blog/2965756/202405/2965756-20240523233418560-1909467696.png[/img] 硬件接线如下,实际上就是用户手册推荐的连接
[img=50%,50%]https://img2024.cnblogs.com/blog/2965756/202405/2965756-20240523234811319-663639227.png[/img] dts替换
新建ili9341.dts文件
vim ili9341.dts- /dts-v1/;
- /plugin/;
- / {
- fragment@0 {
- target = <&spi1>;
- __overlay__ {
- status = "okay";
- ili9341: ili9341@0 {
- compatible = "ilitek,ili9341";
- reg = <1>;
- spi-max-frequency = <40000000>;
- rotate = <0>;
- bgr;
- fps = <30>;
- buswidth = <8>;
- reset-gpios = <&pio 2 9 1>;
- dc-gpios = <&pio 2 6 0>;
- led-gpios = <&pio 2 5 0>;
- debug = <0>;
- };
- };
- };
- };
复制代码 替换设备树,执行后reboot
orangepi-add-overlay ili9341.dts
不出意外的话,console默认会显示在lcd上,可以使用fbi指令测试- su root
- apt update
- apt install fbi
- fbi -vt 1 -noverbose -d /dev/fb0 /boot/boot.bmp
复制代码[img=30%,30%]https://img2024.cnblogs.com/blog/2965756/202405/2965756-20240523235205693-44829006.jpg[/img] 关于pinctrl-0和cs-gpios
使用cs-gpios定义片选信号使用的引脚,来自ChatGPT3.5- spi@40013000 {
- compatible = "some-vendor,spi-bus";
- reg = <0x40013000>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "okay";
- cs-gpios = <&gpio1 10 0>, <&gpio1 11 0>; // 定义两个片选 GPIO
- spidev0: spidev@0 {
- compatible = "some-vendor,spidev";
- reg = <0>; // 对应 cs-gpios 的第一个 GPIO (gpio1 10)
- spi-max-frequency = <10000000>;
- status = "okay";
- };
- spidev1: spidev@1 {
- compatible = "some-vendor,spidev";
- reg = <1>; // 对应 cs-gpios 的第二个 GPIO (gpio1 11)
- spi-max-frequency = <10000000>;
- status = "okay";
- };
- };
复制代码 pinctrl-0已经包含了spi1_cs1_pin,所以spidev的reg直接使用1也可以找到,就不需要cs-gpios了- &spi1 {
- status = "disabled";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>, <&spi1_cs1_pin>;
- spidev@1 {
- compatible = "rohm,dh2228fv";
- status = "disabled";
- reg = <1>;
- spi-max-frequency = <1000000>;
- };
- };
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |