GPIO常用系统调用函数:位于include/linux/gpio.h
1,申请GPIO
static inline int gpio_request(unsigned gpio,consr char *label)
2,设置GPIO电平
static inline void gpio_set_value(unsigned ine gpio,int value)
3,获取GPIO电平
static inline int gpio_get_value(unsigned gpio)
4,设置GPIO为输出,并设置电平
static inline int gpio_direction_output(unsigned gpio,int value)
5,设置GPIO为输入
static inline int gpio_direction_input(unsigned gpio)
6、设备树下添加自己的节点
hello-gpio{
compatible= "rockchip,drv_gpio";led =<&gpio8 GPIO_A1 GPIO_ACTIVE_LOW>;
led1 =<&gpio5 GPIO_C3 GPIO_ACTIVE_LOW>;
led2 =<&gpio0 GPIO_C1 GPIO_ACTIVE_LOW>;
led3 =<&gpio1 GPIO_D2 GPIO_ACTIVE_LOW>;
status ="okay";
};
7 驱动代码:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#define LED_GPIO 258 //没用到
#define GPIO_LOW 0
#define GPIO_HIGH 1
static struct class *drv_gpio_class; //创建一个类
static struct class_device *drv_gpio_class_dev; //创建设备节点
static int major; //主设备号
static int gpio,gpio5_c3,gpio0_c1,gpio1_d2; //定义几个io口
static int drv_gpio_open(struct inode *inode, struct file *file) //应用层调用
{
printk(KERN_INFO "drv_gpio_drv_open\n");
/* 配置为输出 */
int i;
for(i=0;i<=4;i++)
{
// gpio_set_value(gpio,GPIO_LOW);
mdelay(500);
// gpio_set_value(gpio,GPIO_HIGH);
mdelay(500);
}
return 0;
}
static ssize_t drv_gpio_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)//应用层调用
{
//int val;
printk(KERN_INFO "drv_gpio_drv_write\n");
/* copy_from_user(&val, buf, count); // copy_to_user();
if (val == 1)
{
// 点灯
*gpio_dat &= ~(1<<pin);
}
else
{
// 灭灯
*gpio_dat |= (1<<pin);
}*/
return 0;
}
static struct file_operations drv_gpio_fops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = drv_gpio_open,
.write = drv_gpio_write,
};
static int drv_gpio_probe(struct platform_device *pdev) //驱动和设备树匹配成功时会第一个调用的入口函数
{
int ret =-1;
int i;
int flag;
struct device_node *drv_gpio_node =pdev->dev.of_node;
printk(KERN_INFO "%s-%d: enter\n",__FUNCTION__,__LINE__);
//gpio=of_get_named_gpio_flags(drv_gpio_node,"led", 0, & flag);
gpio5_c3=of_get_named_gpio_flags(drv_gpio_node,"led1", 0, & flag); //获取设备树的资源
// gpio0_c1=of_get_named_gpio_flags(drv_gpio_node,"led2", 0, & flag);
// gpio1_d2=of_get_named_gpio_flags(drv_gpio_node,"led3", 0, & flag);
// if(!gpio_is_valid(gpio)){
//
// printk(KERN_INFO "invalid gpio : %d\n",gpio);
// return -1;
// }
if(!gpio_is_valid(gpio5_c3)){
printk(KERN_INFO "invalid gpio : %d\n",gpio5_c3);
return -1;
}
/* if(!gpio_is_valid(gpio0_c1)){
printk(KERN_INFO "invalid gpio : %d\n",gpio5_c3);
return -1;
}
if(!gpio_is_valid(gpio1_d2)){
printk(KERN_INFO "invalid gpio : %d\n",gpio1_d2);
return -1;
}
ret =gpio_request(gpio,"drv_gpio");
if(ret!=0){
gpio_free(gpio);
return -EIO;
}*/
ret =gpio_request(gpio5_c3,"drv_gpio");
if(ret!=0){
gpio_free(gpio5_c3);
return -EIO;
}
/*ret =gpio_request(gpio0_c1,"drv_gpio");
if(ret!=0){
gpio_free(gpio0_c1);
return -EIO;
}
ret =gpio_request(gpio1_d2,"drv_gpio");
if(ret!=0){
gpio_free(gpio1_d2);
return -EIO;
}*/
//gpio_direction_output(gpio,GPIO_HIGH);
gpio_direction_output(gpio5_c3,GPIO_HIGH); //配置gpio为输出 且为高
//gpio_direction_output(gpio0_c1,GPIO_HIGH);
//gpio_direction_output(gpio1_d2,GPIO_LOW);
/*for(i=0;i<=4;i++)
{
gpio_set_value(gpio,GPIO_LOW);
//gpio_set_value(gpio5_c3,GPIO_LOW);
mdelay(500);
gpio_set_value(gpio,GPIO_HIGH);
//gpio_set_value(gpio5_c3,GPIO_HIGH);
mdelay(500);
}*/
printk(KERN_INFO "%s-%d: enter\n",__FUNCTION__,__LINE__);
major = register_chrdev(0, "rockchip_hello", &drv_gpio_fops); //创建设备节点
drv_gpio_class = class_create(THIS_MODULE, "rockchip_hello");
drv_gpio_class_dev = device_create(drv_gpio_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */
return 0;
}
static int drv_gpio_remove(struct platform_device *pdev)
{
printk("drv_gpio_remove, remove led\n");
device_destroy(drv_gpio_class, MKDEV(major, 0));
class_destroy(drv_gpio_class);
unregister_chrdev(major, "rockchip_hello");
return 0;
}
static const struct of_device_id of_rockchip_gpio_match[]={
{.compatible ="rockchip,drv_gpio"},
{/*Sentinel*/}
};
static struct platform_driver rockchip_gpio_driver={
.probe =drv_gpio_probe,
.remove =drv_gpio_remove,
.driver ={
.name ="rockchip_hello",
.owner =THIS_MODULE,
.of_match_table =of_rockchip_gpio_match,
},
};
static int __init drv_gpio_init(void)
{
printk(KERN_INFO "Enter %s\n", __FUNCTION__);
platform_driver_register(&rockchip_gpio_driver);
/*int i;
for (i=0;i<=4;i++)
{
printk(KERN_INFO "gpio_blink:%d\n",i);
gpio_set_value(LED_GPIO,GPIO_LOW);
mdelay(500);
gpio_set_value(LED_GPIO,GPIO_HIGH);
mdelay(500);
// printk(KERN_INFO"~~~~~~~~~~~~~~~~~~~~this is first_drv for my qt!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
mdelay(1000);
}*/
return 0;
}
static void __exit drv_gpio_exit(void)
{
platform_driver_unregister(&rockchip_gpio_driver);
printk(KERN_INFO "~~~~~~~~~~~~~~~~~~~~exit first_drv!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
subsys_initcall(drv_gpio_init);
module_exit(drv_gpio_exit);
MODULE_LICENSE("GPL");