主线linux f1c200s fbtft ssd1306 适配记录

主线linux f1c200s fbtft ssd1306 适配记录

menuconfig中开启staging drivers下small tft菜单中 fb ssd1306, 选择*编译进内核。

image

修改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

最后,上张效果图

image

技术的延伸

只是猜想,并未验证
假设有如下情况:

  • 情景 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的项目,记得主线中有这个芯片的驱动,倒也省了麻烦,不过暂未验证。

posted @   IotaHydrae  阅读(818)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示