altera cyclone gpio export driver

平台:altera cycloneV

功能:设备树添加gpio,驱动设置gpio状态以及是否导出

设备树添加节点:

        gpios {
            compatible = "cyclone_gpio_export";
            status     = "okay";
    
            /* input */
            gpio44{
                label = "1";
                gpios = <&hps_0_gpio1_porta 15 0>;
                default-direction = "in";
            };
            /* output */
            gpio54{
                label = "2";
                gpios = <&hps_0_gpio1_porta 25 1>;
                default-direction = "out";
            };   
        };

 

驱动:

#include <linux/gpio.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/module.h>

struct gpio_user_data{
    const char *label;
    bool           input;
    unsigned int gpio;
    unsigned int default_value;
};

struct gpio_info{
    struct gpio_user_data *data;
    int gpio_count;
};


static struct gpio_info *cyclone_gpio_info;

static void gpio_user_init_default(void)
{
        int i,ret;
        struct gpio_user_data *data;
        data = cyclone_gpio_info->data;

        for(i = 0;i < cyclone_gpio_info->gpio_count;i++) {

                if(!gpio_is_valid(data[i].gpio)) {
                        continue;
                }
                
                ret = gpio_request(data[i].gpio,data[i].label);
                if(ret < 0) {
                        continue;
                }
                
                if(data[i].input) {
                        gpio_direction_input(data[i].gpio);
                }
                else {
                    gpio_direction_output(data[i].gpio,data[i].default_value);
                }
                
          if(gpio_export(data[i].gpio, true))
              printk("export gpio error\n");
        }
}


int cyclone_gpio_export_probe(struct platform_device *pdev)
{
    struct device_node *node = pdev->dev.of_node, *child;
    int index = 0;
    
    cyclone_gpio_info = kzalloc(sizeof(struct gpio_info), GFP_KERNEL);
    if(!cyclone_gpio_info)
    {
        printk("alloc gpio info error!\n");
        return -ENOMEM;
    }

    cyclone_gpio_info->gpio_count = of_get_child_count(node);
    if(!cyclone_gpio_info->gpio_count)
    {
        printk("get none gpio!\n");
        return -EIO;
    }
    printk("get %d gpios\n",cyclone_gpio_info->gpio_count);

    cyclone_gpio_info->data = kzalloc(sizeof(struct gpio_user_data)*cyclone_gpio_info->gpio_count, GFP_KERNEL);
    if(!cyclone_gpio_info->data)
    {
        printk("alloc gpio user data error!\n");
        return -ENOMEM;
    }
    
       for_each_available_child_of_node(node,child){
            const char *input;
            struct gpio_user_data *data = &cyclone_gpio_info->data[index++];        
            data->label = of_get_property(child,"label",NULL) ? : child->name;
            input = of_get_property(child,"default-direction",NULL) ? : "in";
            if(strcmp(input,"in") == 0)
                data->input = true;
            data->gpio = of_get_gpio_flags(child,0,&data->default_value);
    printk("gpio name = %s, direction = %d, num = %d\n",data->label,data->input,data->gpio);
       }
    
    gpio_user_init_default();

    return 0;
}

static int cyclone_gpio_export_remove(struct platform_device *pdev)
{
    kfree(cyclone_gpio_info->data);
    kfree(cyclone_gpio_info);

    return 0;
}

static struct of_device_id cyclone_gpio_export_match[] = {
    { .compatible = "cyclone_gpio_export", },
    {},
};

static struct platform_driver cyclone_gpio_export_driver = {
    .driver = {
        .name    = "cyclone_gpio",
        .owner    = THIS_MODULE,
        .of_match_table = of_match_ptr(cyclone_gpio_export_match),
    },
    .probe        = cyclone_gpio_export_probe,
    .remove        = cyclone_gpio_export_remove,
};

static int __init cyclone_gpio_export_init(void)
{
    return platform_driver_register(&cyclone_gpio_export_driver);
}

static void __exit cyclone_gpio_export_exit(void)
{
    platform_driver_unregister(&cyclone_gpio_export_driver);
}

MODULE_LICENSE("GPL");

module_init(cyclone_gpio_export_init);
module_exit(cyclone_gpio_export_exit);


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值