linux led 总线驱动下载,单总线led驱动芯片WS2811在linux下的驱动

#include #include "ralink_gpio.h"

static dev_t sys_led_dev;

static struct class* sys_led_class = 0;

static struct cdev* sys_led_cdev = 0;

#define SYS_LED_NAME"sys_led"

union _rgb

{

unsigned int color;

struct

{

unsigned char r;

unsigned char g;

unsigned char b;

}u_s;

};

#define set_led_hight()*(volatile u32*)(RALINK_REG_PIOSET1) = (1 << (44 - 32))

#define set_led_low()*(volatile u32*)(RALINK_REG_PIORESET1) = (1 << (44 - 32))

inline void set_out()//设置GPIO为输出以便控制WS2811

{

unsigned long tmp;

tmp = *(volatile u32 *)(RALINK_REG_GPIOMODE2);

tmp |= 1;

*(volatile u32 *)(RALINK_REG_GPIOMODE2) = tmp;

tmp = *(volatile u32*)(RALINK_REG_PIODIR1);

tmp |= (1 << (44 - 32));

*(volatile u32*)(RALINK_REG_PIODIR1) = tmp;

}

static void set_led_1(void)//发出二进制1

{

set_led_hight();

ndelay(678);

set_led_low();

ndelay(278);

}

static void set_led_0(void)//发出二进制0

{

set_led_hight();

ndelay(278);

set_led_low();

ndelay(678);

}

// >= 50us

static void reset_op(void)//发出Reset信号

{

set_led_hight();//首先将总线拉高ndelay

ndelay(300);//保持一段时间

set_led_low();//拉低

udelay(50);//至少保持50us,之后芯片等待接收新的数据

}

static int sys_led_open(struct inode* in, struct file* fi)

{

set_out();

return 0;

}

static int sys_led_ioctl(struct file* fi, unsigned int cmd, unsigned long data)

{

union _rgb rgb;

int i;

unsigned int fl;

switch (cmd)

{

case 0:

if (copy_from_user((char*)&rgb, (char*)data, sizeof(rgb)))//从用户空间获得颜色值

{

return -1;

}

set_out();

reset_op();

local_irq_save(fl);//把当前中断状态保存到flags中,然后禁用当前处理器上的中断发送

for (i = 0; i < 24; ++i)//发出24bit的颜色值

{

if (1 & rgb.color)

set_led_1();

else

set_led_0();

rgb.color >>= 1;

}

local_irq_restore(fl);//中断恢复

break;

case 1:

reset_op();

break;

}

return 0;

}

static ssize_t sys_led_write(struct file* fi, char* __user buf, size_t len, loff_t* ff)

{

union _rgb rgb;

unsigned int fl;

int i;

if (copy_from_user((char*)&rgb, (char*)buf, sizeof(rgb)))

{

return -1;

}

set_out();

reset_op();

local_irq_save(fl);

for (i = 0; i < 24; ++i)

{

if (1 & rgb.color)

set_led_1();

else

set_led_0();

rgb.color >>= 1;

}

local_irq_restore(fl);

return sizeof(union _rgb);

}

static struct file_operations led_file =

{

.owner = THIS_MODULE,

.open = sys_led_open,

.unlocked_ioctl = sys_led_ioctl,

.write = sys_led_write,

};

static void __exit sys_led_exit(void);

static int __init sys_led_init(void)

{

int ret;

sys_led_class = class_create(THIS_MODULE, "sys_led_class");

if (IS_ERR(sys_led_class))

{

printk("error : sys led class create failed

");

return -1;

}

ret = alloc_chrdev_region(&sys_led_dev, 0, 1, SYS_LED_NAME);

if (ret < 0)

{

printk("error : get dev number failed

");

goto error_exit;

}

device_create(sys_led_class, NULL, sys_led_dev, NULL, "%s", SYS_LED_NAME);

sys_led_cdev = cdev_alloc();

if (!sys_led_cdev)

{

printk("new memory cdev failed

");

goto error_exit;

}

cdev_init(sys_led_cdev, &led_file);

sys_led_cdev->owner = THIS_MODULE;

ret = cdev_add(sys_led_cdev, sys_led_dev, 1);

if (ret < 0)

{

printk("sys led cdev add failed

");

goto error_exit;

}

return 0;

error_exit:

sys_led_exit();

return -1;

}

static void __exit sys_led_exit(void)

{

if (sys_led_cdev)

{

cdev_del(sys_led_cdev);

}

if (sys_led_class)

{

device_destroy(sys_led_class, sys_led_dev);

class_destroy(sys_led_class);

}

unregister_chrdev_region(sys_led_dev, 1);

}

module_init(sys_led_init);

module_exit(sys_led_exit);

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("system status led control");

MODULE_AUTHOR("system led");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值