1. 程式人生 > >uboot中獲取dts資源並操作gpio口

uboot中獲取dts資源並操作gpio口

裝置樹(DTS)的引入減少了核心為支援新硬體而需要的改變,提高程式碼重用,使得單個核心映象能支援多個系統。
    DTS作為U-Boot 和Linux 核心之間的動態介面,能夠有效減少重複配置,共享於U-Boot 和Linux之間本文將簡單介紹U-Boot使用DTS控制LED的例子:    
    1.在kernel/arch/arm/boot/dts/rk3288-box.dts中新增LED配置:

------------------- kernel/arch/arm/boot/dts/rk3288-box.dts -------------------
index e102714..80928ba 100755
@@ -137,6 +136,16 @@
rockchip,remote_wakeup;
rockchip,usb_irq_wakeup;
};
+
+ leds {
+ compatible = "gpio-leds";
+ power {
+ label = "tchip:blue:power";
+ default-state = "on";
+ gpios = <&gpio8 GPIO_A3 GPIO_ACTIVE_LOW>;
+ };
+ };
};

&gmac {

 

    以上是linux標準的GPIO-LED配置,直接配置上核心就可使用LED。

    2.修改U-Boot,以支援讀取DTS配置並操作LED燈,修改u-boot/board/rockchip/rk32xx/rk32xx.c:

 

-------------------- u-boot/board/rockchip/rk32xx/rk32xx.c --------------------
index bfdcf0e..29fff0f 100755
@@ -61,12 +61,34 @@ void board_lmb_reserve(struct lmb *lmb) {
//reserve 48M for kernel & 8M for nand api.
lmb_reserve(lmb, gd->bd->bi_dram[0].start, CONFIG_LMB_RESERVE_SIZE);
}
+
+static struct fdt_gpio_state power_led_gpio;
+int power_led_parse_dt(const void *blob)
+{
+ int led_node = 0;
+ int node = 0;
+
+ node = fdt_node_offset_by_compatible(blob,
+ 0, "gpio-leds");
+ if (node < 0) {
+ printf("can't find dts node for led\n");
+ return -ENODEV;
+ }
+ led_node = fdt_subnode_offset(blob, node, "power");
+ fdtdec_decode_gpio(blob, led_node, "gpios", &power_led_gpio);
+ power_led_gpio.gpio = rk_gpio_base_to_bank(power_led_gpio.gpio & RK_GPIO_BANK_MASK) | (power_led_gpio.gpio & RK_GPIO_PIN_MASK);
+ power_led_gpio.flags = !(power_led_gpio.flags & OF_GPIO_ACTIVE_LOW);
+ debug("power_led_gpio: %s,%d-%d\n", power_led_gpio.name, power_led_gpio.gpio, power_led_gpio.flags);
+
+ return 0;
+}
#endif /* CONFIG_OF_LIBFDT */


#ifdef CONFIG_RK_FB

#ifdef CONFIG_OF_LIBFDT
+
static struct fdt_gpio_state lcd_en_gpio, lcd_cs_gpio;
static int lcd_en_delay, lcd_cs_delay;
static int lcd_node = 0;
@@ -114,7 +136,6 @@ void rk_backlight_ctrl(int brightness)

void rk_fb_init(unsigned int onoff)
{
-
#ifdef CONFIG_OF_LIBFDT
if (lcd_node == 0) rk_lcd_parse_dt(gd->fdt_blob);

@@ -178,6 +199,17 @@ void init_panel_info(vidinfo_t *vid)
vid->logo_rgb_mode = RGB565;
}

+void power_led_init(void)
+{
+ printf("Enter power_led_init\n");
+#ifdef CONFIG_OF_LIBFDT
+ power_led_parse_dt(gd->fdt_blob);
+ if (power_led_gpio.name!=NULL)
+ {
+ gpio_direction_output(power_led_gpio.gpio, power_led_gpio.flags);
+ }
+#endif
+}

#ifdef CONFIG_RK616
int rk616_power_on(void)
@@ -259,6 +291,9 @@ int board_late_init(void)
load_disk_partitions();
prepare_fdt();
key_init();
+
+ power_led_init();
+
#ifdef CONFIG_POWER_RK
pmic_init(0);
fg_init(0); /*fuel gauge init*/

 

    3.編譯核心,參考Wiki<http://wiki.t-firefly.com/index.php/Firefly-RK3288/Build_kernel>中的編譯核心映像部分

    4.編譯U-Boot,參考SDK下的“RKDocs/common/uboot/RockChip_Uboot開發文件V1.0.pdf”文件,編譯生成RK3288Loader_uboot_V2.15.bin

    5.燒寫resource.img和RK3288Loader_uboot_V2.15.bin,開機。有沒有發現LED燈比原來的快差不多兩秒點亮呢

原文連結https://linux.cn/thread-13866-1-7.html