全志linux led驱动程序,芯灵思Sinlinx A64 linux通过设备树写LED驱动(附参考代码,未测试)...

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MY_DEVICE_NAME "my_LED_device"

// 获取到设备树中到节点

static int gpio = -1;

int get_irqno_from_node(void)

{

struct gpio_config config;

struct device_node *np = of_find_node_by_path("/leds");

IF(np){

printk("find node ok\n");

}

else{

printk("find node failed\n");

}

gpio = of_get_named_gpio_flags(nd, "gpios", i, (enum of_gpio_flags *)&config);// 从设备树中读取gpios的GPIO配置编号和标志

if(!gpio_is_valid(gpio)){

//判断该 GPIO 编号是否有效,有效gpio_request 则申请占用该 GPIO。如果初始化过程出错,需要调用 gpio_free 来释放之前申请过且成功的 GPIO

printk("gpio isn't valid\n");

return -1;

}

if(gpio_request(gpio, "leds") < 0)

printk("gpio request failed %d\n", gpio);

gpio_direction_output(gpio, 1); //关灯

return 0;

}

static int my_open (struct inode *node, struct file *filp)

{

if(gpio)

{

printk("open ok\n");

}

else

{

return -EINVAL;

}

return 0;

}

static ssize_t my_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)

{

unsigned char val;

copy_from_user(&val, buf, 1);

printk(" gpl_dat address   0x%x\n",gpl_dat);

if (val)

{

gpio_direction_output(gpio, 0); //关灯

printk("led on\n");

}

else

{

gpio_direction_output(gpio, 1); //关灯

printk("led off\n");

}

return 1;

}

static const struct file_operations my_led_fops = {

//step 1 :定义file_operations结构体

.open = my_open,

.write = my_write,

};

//step 1 :

static struct class *led_class;

static struct cdev *pcdev;      //定义一个cdev指针

static dev_t n_dev;            //第一个设备号(包含了主和次)

static int __init led_device_init(void)

{//step 2 :注册

int ret = -1;

pcdev = cdev_alloc();//分配cdev结构空间

if(pcdev == NULL) {

printk(KERN_EMERG" cdev_alloc  error\n");

ret = -ENOMEM;   /* 分配失败 */

return ret;

}

//2. 动态申请设备号

ret = alloc_chrdev_region(&n_dev, 0 , 2, MY_DEVICE_NAME);

if(ret < 0 ) {

//释放前面成功的资源

kfree(pcdev);                              /*释放cdev结构空间 */

printk(KERN_EMERG"alloc_chrdev_region  error\n");

return ret;

}

cdev_init(pcdev, &my_led_fops);     //初始化cdev结构           /* 建立cdev和file_operations之间的连接 */

/*

或这样初始化cdev结构

pcdev->owner = THIS_MODULE;

pcdev->ops = &my_led_fops;

*/

ret = cdev_add(pcdev, n_dev, 2) ;// 向内核里面添加一个驱动,注册驱动

if(ret < 0 ) {

//释放前面成功的资源

unregister_chrdev_region(n_dev,  2);       /*  释放前面申请的调和号*/

kfree(pcdev);                               /* 释放cdev结构空间 */

printk(KERN_EMERG"alloc_chrdev_region  error\n");

return ret;

}

/*自动创建设备节点/dev/SinlinxA64_LED*/

led_class = class_create(THIS_MODULE, "myled");

device_create(led_class, NULL, n_dev, NULL, "SinlinxA64_LED");

get_irqno_from_node();

printk(KERN_EMERG"cdev ok\n");

return 0;

}

static void __exit led_device_exit(void)

{    //step 2 :注销

//注销cdev结构

cdev_del(pcdev);

//释放设备号

unregister_chrdev_region(n_dev, 2); /*起始设备号(主、次) 连续的次设备号数量*/

//释放cdev结构空间

kfree(pcdev);

device_destroy(led_class, n_dev);

class_destroy(led_class);

gpio_free(gpio);

printk(KERN_EMERG"cdev_del ok\n");

}

module_init(led_device_init);

module_exit(led_device_exit);

MODULE_LICENSE("GPL");

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值