在项目中我们时常遇到需要特殊控制的GPIO,需要在UBOOT中就将IO控制起来,所以针对这个问题我写了这篇博文来分享我在项目中是怎么在uboot中添加我们自己的驱动的,并且通过驱动去获取我们在设备树中添加的设备属性,获取IO属性,并且操控我们的GPIO
我的设备树配置如下:
sbc_rk3568_misc {
compatible="sbc_rk3568,misc";
pinctrl-names = "default";
pinctrl-0 = <&eeprom_wp_pin>;
eeprom-wp = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>; /*GPIO0_A0 tms-eesprom*/
status = "okay";
};
而今天我们的猪脚就是上面的这个节点,我们要去控制eeprom_wp中的这个IO,通过控制这个IO展开分享。
下面是我最开始添加的驱动为了验证是否添加成功的:
#include <common.h>
#include <asm/gpio.h>
#include <misc.h>
#include <dm.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <command.h>
static int misc_vantron_probe(struct udevice *dev)
{
printf("%s---------------------\r\n", __func__);
return 0;
}
static int misc_vantron_remove(struct udevice *dev)
{
printf("%s---------------------\r\n", __func__);
return 0;
}
static const struct udevice_id misc_vantron_ids[] = {
{ .compatible = "sbc_rk3568,misc" },
{ }
};
U_BOOT_DRIVER(misc_vantron) = {
.name = "sbc_rk3568,misc",
.id = UCLASS_MISC,
.of_match = misc_vantron_ids,
.probe = misc_vantron_probe,
.remove = misc_vantron_remove,
};
我的文件名字(misc-vantron.c)修改文件所在目录的Makefile:
obj-y += misc-vantron.o
在u-boot/arch/arm/mach-rockchip/board.c中添加一个函数并且添加uclass_get_device_by_driver函数调用获取驱动
static void vantron_misc_func(void)
{
struct udevice *dev2;
uclass_get_device_by_driver(UCLASS_MISC,
DM_GET_DRIVER(misc_vantron), &dev2); //
}
然后将该函数添加到:
int board_late_init(void)
{
...
vantron_misc_func();
...
}
这样在启动的时候就会去调用我们自己创建的函数了
编译后下载到我们的板子上就可以看到我们函数运行的打印了:
U-Boot 2017.09-g8f70544d59-220124-dirty #vtlk (Jul 22 2022 - 17:29:16 +0800)
Model: Rockchip RK3568 Evaluation Board
PreSerial: 2, raw, 0xfe660000
DRAM: 4 GiB
Sysmem: init
Relocation Offset: ed348000
Relocation fdt: eb9f8c08 - eb9fece0
CR: M/C/I
Using default environment
dwmmc@fe2b0000: 1, dwmmc@fe2c0000: 2, sdhci@fe310000: 0
Bootdev(atags): mmc 0
MMC0: HS200, 200Mhz
PartType: EFI
DM: v1
boot mode: recovery (misc)
boot mode: normal
Android 11.0, Build 2021.8, v2
Found DTB in boot part
DTB: rk-kernel.dtb
HASH(c): OK
ANDROID: fdt overlay OK
I2c0 speed: 100000Hz
vsel-gpios- not found! Error: -2
vdd_cpu init 900000 uV
PMIC: RK8090 (on=0x10, off=0x00)
vdd_logic init 900000 uV
vdd_gpu init 900000 uV
vdd_npu init 900000 uV
io-domain: OK
Warn: can't find connect driver
Model: sbc_rk3568
misc_vantron_probe-------------------
2.注意:
我发现先前放在drivers/misc/目录下,不能调用gpio_request_by_name,所以我把他移动到drivers/i2c/misc-vantron.c目录下:
更改如下:
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm-generic/gpio.h>
#include <dm/lists.h>
#include <misc.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <command.h>
#include <dm/of_access.h>
#include <dm/ofnode.h>
static int misc_vantron_probe(struct udevice *dev)
{
struct gpio_desc gpio_eeprom_wp;
struct device_node *np;
int ret;
np = of_find_compatible_node(NULL,NULL,"sbc_rk3568,misc");
if(np == NULL)
{
printf("%s :can not get sbc_rk3568,misc node\r\n",__func__);
}
else
{
printf("%s : get sbc_rk3568,misc node successed : -->%s\r\n",__func__,np->name);
}
ret = gpio_request_by_name(dev, "eeprom-wp", 0, &gpio_eeprom_wp,
GPIOD_IS_OUT);
if(ret)
{
printf("%s :can not get eepro_wp gpio\r\n",__func__);
}
else
{
printf("%s :get eepro_wp gpio \r\n",__func__);
}
printf("%s---------------------\r\n", __func__);
return 0;
}
static int misc_vantron_remove(struct udevice *dev)
{
printf("%s---------------------\r\n", __func__);
return 0;
}
static const struct udevice_id misc_vantron_ids[] = {
{ .compatible = "sbc_rk3568,misc" },
{ }
};
U_BOOT_DRIVER(misc_vantron) = {
.name = "sbc_rk3568,misc",
.id = UCLASS_GPIO,
.of_match = misc_vantron_ids,
.probe = misc_vantron_probe,
.remove = misc_vantron_remove,
};
在这里我把这类型该成了UCLASS_GPIO类型
相应的在u-boot/arch/arm/mach-rockchip/board.c修改:
static void vantron_misc_func(void)
{
struct udevice *dev2;
uclass_get_device_by_driver(UCLASS_GPIO,DM_GET_DRIVER(misc_vantron), &dev2); //
}
然后就可以在我们驱动中调用下面这两个函数去控制我们的IO口了
int dm_gpio_get_value(const struct gpio_desc *desc);
int dm_gpio_set_value(const struct gpio_desc *desc, int value);
最后成功打印:
Using display timing dts
dsi@fe060000: detailed mode clock 132000 kHz, flags[8000000a]
H: 1080 1095 1097 1127
V: 1920 1935 1937 1952
bus_format: 100e
VOP update mode to: 1080x1920p0, type: MIPI0 for VP1
rockchip_vop2_init:No hdmiphypll clk0 found, use system clk
rockchip_vop2_init:No hdmiphypll clk1 found, use system clk
VOP VP1 enable Smart0[654x270->654x270@213x825] fmt[2] addr[0xedf04000]
final DSI-Link bandwidth: 876 Mbps x 4
CLK: (sync kernel. arm: enter 816000 KHz, init 816000 KHz, kernel 0N/A)
apll 1416000 KHz
dpll 780000 KHz
gpll 1188000 KHz
cpll 1000000 KHz
npll 1200000 KHz
vpll 660000 KHz
hpll 24000 KHz
ppll 200000 KHz
armclk 1416000 KHz
aclk_bus 150000 KHz
pclk_bus 100000 KHz
aclk_top_high 500000 KHz
aclk_top_low 400000 KHz
hclk_top 150000 KHz
pclk_top 100000 KHz
aclk_perimid 300000 KHz
hclk_perimid 150000 KHz
pclk_pmu 100000 KHz
misc_vantron_probe : get sbc_rk3568,misc node successed : -->sbc_rk3568_misc
misc_vantron_probe :get eepro_wp gpio
misc_vantron_probe---------------------