- Linux驱动讲究驱动分离与分层,pinctrl和gpio子系统就是驱动分离与分层思想下的产物,pinctrl子系统主要工作内容如下:
1.获取设备树中的pin信息
2.根据获取到的pin信息来设置pin的复用功能
3.根据获取到的pin信息来设置pin的电气属性,比如上下拉、速度、驱动能力等 - 设备树中添加pinctrl节点模板
- 1、添加对应的pinctrl节点
- 打开imx6ull-alientek-emmc.dts,在 iomuxc 节点的 imx6ul-evk 子节点添加pinctrl_led节点(同一个外设的pin都放到一个节点里面)
- iomuxc 节点就是 I.MX6ULL 的 IOMUXC 外设对应的节点,跟 PIN 的配置有关(复用)
- image.png
- 2、添加对应的设备device节点
- 在根节点“/”下创建 LED 灯节点,节点名为“gpioled”,节点内容如下:
- image.png
- 3、检查 PIN 是否被其他外设使用
- ①检查其他pinctrl节点内是否将GPIO1_IO03此引脚复用 : MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0(pinctrl_tsc 节点)
- ②检查其他设备节点内是否使用GPIO1_IO03此引脚 :xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
- 驱动硬件的方式不再是直接操作寄存器,不需要映射和取消映射
- image.png
- 初始化字符设备
- 初始化字符设备 也在static int __init led_init(void)
- 0、获取设备节点
-
/* 设置LED所使用的GPIO */ /* 1、获取设备节点:gpioled */ gpioled.nd = of_find_node_by_path("/gpioled"); if(gpioled.nd == NULL) { printk("gpioled node not find!\r\n"); return -EINVAL; } else { printk("gpioled node find!\r\n"); }
- 1、获取设备树中的gpio属性,得到LED所使用的GPIO编号,GPIO编号是一一对应的
-
/* 2、 获取设备树中的gpio属性,得到LED所使用的GPIO编号,GPIO编号是一一对应的 */ gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpio", 0);//index:GPIO 索引,"led-gpio"属性里面可能有多个GPIO,0表示第一个 if(gpioled.led_gpio < 0) { printk("can't get led-gpio"); return -EINVAL; } printk("led-gpio num = %d\r\n", gpioled.led_gpio);
- 2、设置GPIO1_IO03为输出,并且输出高电平,默认关闭LED灯
-
/* 3、设置GPIO1_IO03为输出,并且输出高电平,默认关闭LED灯 */ ret = gpio_direction_output(gpioled.led_gpio, 1); if(ret < 0) { printk("can't set gpio!\r\n"); }