主线linux f1c200s fbtft ssd1306 适配记录
主线linux f1c200s fbtft ssd1306 适配记录
menuconfig中开启staging drivers下small tft菜单中 fb ssd1306, 选择*编译进内核。
修改pio节点如下,添加 spi1 复用引脚。
pio: pinctrl@1c20800 {
compatible = "allwinner,suniv-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <38>, <39>, <40>;
clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
#gpio-cells = <3>;
spi0_pins_a: spi0-pins-pc {
pins = "PC0", "PC1", "PC2", "PC3";
function = "spi0";
};
spi1_pins_a: spi1-pins-pa {
pins = "PA0", "PA1", "PA2", "PA3";
function = "spi1";
};
lcd_rgb666_pins: lcd-rgb666-pins {
pins = "PD0", "PD1", "PD2", "PD3", "PD4",
"PD5", "PD6", "PD7", "PD8", "PD9",
"PD10", "PD11", "PD12", "PD13", "PD14",
"PD15", "PD16", "PD17", "PD18", "PD19",
"PD20", "PD21";
function = "lcd";
};
uart0_pins_a: uart-pins-pe {
pins = "PE0", "PE1";
function = "uart0";
};
mmc0_pins: mmc0-pins {
pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
function = "mmc0";
};
};
修改spi1节点如下
&spi1 {
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins_a>;
status = "okay";
spi-max-frequency = <50000000>;
ssd1306: ssd1306@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "solomon,ssd1306";
reg = <0>;
spi-max-frequency = <50000000>;
buswidth = <8>;
rotate = <0>;
fps = <30>;
spi-cpol;
spi-cpha;
reset-gpios = <&pio 4 11 GPIO_ACTIVE_HIGH>;
dc-gpios = <&pio 4 12 GPIO_ACTIVE_LOW>;
debug = <1>;
};
};
[ 1.028749] fbtft_of_value: buswidth = 8
[ 1.032829] fbtft_of_value: debug = 1
[ 1.036525] fbtft_of_value: rotate = 0
[ 1.040289] fbtft_of_value: fps = 30
[ 1.044381] fb_ssd1306 spi1.0: fbtft_request_one_gpio: 'reset-gpios' = GPIO139
[ 1.051982] fb_ssd1306 spi1.0: fbtft_request_one_gpio: 'dc-gpios' = GPIO140
[ 1.194658] Console: switching to colour frame buffer device 16x8
[ 1.202163] graphics fb0: fb_ssd1306 frame buffer, 128x64, 16 KiB video memory, 4 KiB buffer memory, fps=33, spi1.0 at 50 MHz
最后,上张效果图
技术的延伸
只是猜想,并未验证
假设有如下情况:
-
情景 1
- IO充足,Soc外接了多个fbtft显示屏,共用SPI总线
在tft设备节点中指定cs引脚,该引脚一般为Soc pinctrl复用过来的。上代码!
static int fbtft_request_gpios(struct fbtft_par *par)
{
int i;
int ret;
ret = fbtft_request_one_gpio(par, "reset", 0, &par->gpio.reset);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "dc", 0, &par->gpio.dc);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "rd", 0, &par->gpio.rd);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "wr", 0, &par->gpio.wr);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "cs", 0, &par->gpio.cs);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "latch", 0, &par->gpio.latch);
if (ret)
return ret;
for (i = 0; i < 16; i++) {
ret = fbtft_request_one_gpio(par, "db", i,
&par->gpio.db[i]);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "led", i,
&par->gpio.led[i]);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "aux", i,
&par->gpio.aux[i]);
if (ret)
return ret;
}
return 0;
}
可以看到通过fbtft_request_one_gpio
了名为cs
的引脚,来看看fbtft_request_one_gpio
函数
static int fbtft_request_one_gpio(struct fbtft_par *par,
const char *name, int index,
struct gpio_desc **gpiop)
{
struct device *dev = par->info->device;
*gpiop = devm_gpiod_get_index_optional(dev, name, index,
GPIOD_OUT_LOW);
if (IS_ERR(*gpiop))
return dev_err_probe(dev, PTR_ERR(*gpiop), "Failed to request %s GPIO\n", name);
fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n",
__func__, name);
return 0;
}
确实如此
-
情景 2
- IO不足,使用了IO拓展芯片,Soc同样外接了多个fbtft显示屏,共用SPI总线
在tft设备节点中中指定cs引脚,该引脚为IO拓展芯片某一脚,因为GPIO子系统初始化较早,所以猜测可以像
引用pinctrl子系统一样,引用该IO拓展的某一脚。因为手头上有一个使用了PCA9536的项目,记得主线中有这个芯片的驱动,倒也省了麻烦,不过暂未验证。
本文来自博客园,作者:IotaHydrae,转载请注明原文链接:https://www.cnblogs.com/hfwz/p/15983371.html
分类:
linux_drivers
, linux_display
标签:
linux
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App