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");