背景 根據orangepi zero2用戶手冊說明,linux5.13內核不能使用 modprobe fbtft_device 驅動spi lcd 查看linux內核源碼提交記錄,發現在v5.4-rc3中刪除了fbtft_device.c文件 commit如下 staging/fbtft: Remo ...
背景
根據orangepi zero2用戶手冊說明,linux5.13內核不能使用 modprobe fbtft_device
驅動spi lcd
查看linux內核源碼提交記錄,發現在v5.4-rc3中刪除了fbtft_device.c文件
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 <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
“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了
spi1在26PIN引出,並且cs0和cs1都有,不過cs0復用在了i2c3的TWI3-SDA引腳上,所以我們使用spi1驅動lcd,並且使用cs1
硬體接線如下,實際上就是用戶手冊推薦的連接
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
關於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>;
};
};