0730_驱动2 gpiod子系统

一、为什么引入gpiod子系统

  • 在新版本内核中引入gpiod子系统
  • gpiod子系统和gpio子系统的功能框架实现是一致,只不过封装的接口不一样
  • gpiod子系统功能框架会更为强大

二、gpiod子系统API接口

void gpiod_set_value(struct gpio_desc *desc, int value); //设置gpio引脚输出高低电平
int gpiod_get_value(const struct gpio_desc *desc); //读取gpio引脚值
int gpiod_direction_input(struct gpio_desc *desc); //设置gpio引脚为输入模式
int gpiod_direction_output(struct gpio_desc *desc, int value); //设置gpio引脚输出高低电平
void gpiod_put(struct gpio_desc *desc); //释放gpio引脚


//如何从设备树中,直接获取到gpio_desc结构体指针
struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
                     const char *propname, int index,
                     enum gpiod_flags dflags,
                     const char *label);
函数功能:直接从设备树中获取到gpio_desc结构体指针
参数:
    node:节点结构体指针
    propname:属性的名称
    index:索引号
    dflags:
        GPIOD_OUT_LOW:gpio引脚输出低电平
        GPIOD_OUT_HIGH:gpio引脚输出高电平
    label:NULL
返回值:
    成功返回gpio_desc结构体指针
    失败 借助IS_ERR

三、gpiod子系统示例 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>

/*
myled{//基于gpio子系统设备树节点
    core-led{ //核心板设备树子节点
        led = <&gpioz 5 0>,<&gpioz 6 0>,<&gpioz 7 0>; //led1 PZ5 led2 PZ6 led3 PZ7
    };
    extend-led{ //扩展板设备树子节点
        led1 = <&gpioe 10 0>; //led1 PE10                                                                     
        led2 = <&gpiof 10 0>; //led2 PF10
        led3 = <&gpioe 8 0>; //led3 PE8
    };
};
*/
struct device_node* node;
struct device_node* enode;
struct device_node* cnode;
struct gpio_desc* cdesc[3];
struct gpio_desc* edesc[3];
char* name[3] = {"led1","led2","led3"};

static int __init demo_init(void)
{
    int i = 0;
    //获取myled节点
    node = of_find_node_by_path("/myled");
    if(node == NULL){
        printk("of find node by path is error\n");
        return -EIO;
    }
    //获取核心板设备树子节点
    cnode = of_get_child_by_name(node,"core-led");
    if(cnode == NULL){
        printk("of get cchild by name is error\n");
        return -EIO;
    }
    //获取扩展板设备树子节点
    enode = of_get_child_by_name(node,"extend-led");
    if(enode == NULL){
        printk("of get echild by name is error\n");
        return -EIO;
    }

    for(i=0;i<3;i++)
    {
        //直接从设备树中获取到核心板gpio_desc结构体指针
        cdesc[i] = gpiod_get_from_of_node(cnode,"led",i,GPIOD_OUT_LOW,NULL);
        if(IS_ERR(cdesc[i])){ //将错误码转换为地址,判断地址是否在4K空间
            printk("gpiod get from of cnode is error\n");
            return PTR_ERR(cdesc[i]); //将地址转换为错误码
        }
        //设置gpio核心板引脚输出高电平
        gpiod_direction_output(cdesc[i],1);

        //直接从设备树中获取到扩展板gpio_desc结构体指针
        edesc[i] = gpiod_get_from_of_node(enode,name[i],0,GPIOD_OUT_LOW,NULL);
        if(IS_ERR(edesc[i])){ //将错误码转换为地址,判断地址是否在4K空间
            printk("gpiod get from of enode is error\n");
            return PTR_ERR(edesc[i]); //将地址转换为错误码
        }
        //设置gpio扩展板引脚输出高电平
        gpiod_direction_output(edesc[i],1);
    }
    return 0;
}

static void __exit demo_exit(void)
{
    int i = 0;
    for(i=0;i<3;i++)
    {
        //设置gpio引脚输出低电平
        gpiod_direction_output(cdesc[i],0);
        gpiod_direction_output(edesc[i],0);
        //释放gpio编号
        gpiod_put(cdesc[i]);
        gpiod_put(edesc[i]);
    }
}

module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值