1、修改设备树文件
1.1 添加pinctrl节点
pinctrl
子系统主要工作内容如下:
①、获取设备树中
pin
信息。
②、根据获取到的
pin
信息来设置
pin
的复用功能
③、根据获取到的
pin
信息来设置
pin
的电气特性,比如上
/
下拉、速度、驱动能力等。
根据数据手册和绑定文档添加pinctrl节点。
在 iomuxc 节点的 imx6ul-evk 子节点下创建一个名为“ pinctrl_led ”的子节点
在 iomuxc 节点的 imx6ul-evk 子节点下创建一个名为“ pinctrl_led ”的子节点
1 pinctrl_led: ledgrp {
2 fsl,pins = <
3 MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */
4 >;
5 };
1.2 添加 LED 设备节点
gpio
子系统顾名思义,就是用于初始化
GPIO
并且提供相应的
API
函数,比如设置
GPIO为输入输出,读取 GPIO 的值等。
在根节点“/”下创建
LED
灯节点,节点名为“
gpioled
”
gpioled {
#address-cells = <1>;
#size-cells = <1>;
compatible = "alientek-gpioled";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_led>;
led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
status = "okay";
};
1.3检查 PIN 是否被其他外设使用
①、检查 pinctrl 设置。
②、如果这个
PIN
配置为
GPIO
的话,检查这个
GPIO
有没有被别的外设使用。
2 LED
灯驱动程序框架
#define GPIOLED_CNT 1
#define GPIOLED_NAME "gpioled"
#define LEDOFF 0
#define LEDON 1
/*gpioled 设备结构体*/
struct gpioled_dev
{
dev_t devid;
int major;
int minor;
struct cdev cdev;
struct class *class;
struct device *device;
struct device_node *nd;
int led_gpio;
};
struct gpioled_dev gpioled; /*LED*/
static int led_open(struct inode *inode, struct file *filp)
{
filp->private_data = &gpioled;
return 0;
}
static int led_release(struct inode *inode, struct file *filp)
{
struct gpioled_dev *dev = filp->private_data;
return 0;
}
static ssize_t led_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
int ret;
struct gpioled_dev *dev = filp->private_data;
return 0;
}
/*操作集*/
static const struct file_operations led_fops = {
.owner = THIS_MODULE,
.write = led_write,
.open = led_open,
.release = led_release,
};
/*驱动入口函数*/
static int __init led_init(void)
{
int ret = 0;
/********注册字符设备驱动*********/
/* 1.创建设备号*/
...code...
/* 2初始化cdev*/
...code...
/* 3添加cdev*/
...code...
/* 4创建类*/
...code...
/* 5创建设备*/
...code...
/********GPIO相关操作*********/
/*1,获取设备节点*/
gpioled.nd = of_find_node_by_path("/gpioled");
if (gpioled.nd == NULL)
{
}
/*2,获取LED设备所对应的GPIO编号*/
gpioled.led_gpio = of_get_named_gpio(gpioled.nd, "led-gpios", 0);
if (gpioled.led_gpio < 0)
{
}
/*3,申请GPIO引脚*/
ret = gpio_request(gpioled.led_gpio, "led-gpio");
if (ret)
{
}
/*4,设置 GPIO1_IO03 为输出,并且输出高电平,默认关闭 LED 灯*/
ret = gpio_direction_output(gpioled.led_gpio, 1);
if (ret)
{
}
/*5,输出低电平,点亮led灯*/
gpio_set_value(gpioled.led_gpio, 0);
return ret;
}
/*驱动出口函数*/
static void __exit led_exit(void)
{
/*关灯*/
gpio_set_value(gpioled.led_gpio, 1);
/*注销字符设备驱动*/
...code...
/*释放IO*/
gpio_free(gpioled.led_gpio);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("supersmart");