免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1526 | 回复: 1
打印 上一主题 下一主题

2.6.16下控制键盘灯的设备驱动代码 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-17 11:55 |只看该作者 |倒序浏览
大家看看有什么改进的地方
#include<linux/module.h>
#include<linux/config.h>
#include<linux/init.h>
#include<linux/tty.h>
#include<linux/kd.h>
#include<linux/console_struct.h>
#include<linux/interrupt.h>

MODULE_LICENSE("GPL");

struct timer_list my_timer;
struct tty_driver *my_driver;
struct cdev *char_dev;
unsigned long led_seq = 1;

#define BLINK_DELAY HZ/5
#define LED_FIRST 0x02
#define LED_SECOND 0x04
#define LED_THIRD 0x01
#define LED_ALL 0x07

#define RESTORE_LEDS 0xFF
#define LED_LIGHT 0x01
#define LED_DARK 0x02

static void my_timer_func(unsigned long ptr)
{
        if(ptr == 1){
                (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,RESTORE_LEDS);
                (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,LED_FIRST);
               
          led_seq = 2;
          my_timer.data = led_seq;
          my_timer.expires = jiffies + BLINK_DELAY;
          add_timer(&my_timer);
        }
        if(ptr == 2){
                (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,RESTORE_LEDS);
                (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,LED_SECOND);
               
          led_seq = 3;
          my_timer.data = led_seq;
          my_timer.expires = jiffies + BLINK_DELAY;
          add_timer(&my_timer);
        }
        if(ptr == 3)
        {
                (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,RESTORE_LEDS);
                (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,LED_SECOND);
               
          led_seq = 1;
          my_timer.data = led_seq;
          my_timer.expires = jiffies + BLINK_DELAY;
          add_timer(&my_timer);
        }
}

static int device_open(struct inode *inode,struct file *file)
{
        int i;
        for(i=0; i<MAX_NR_CONSOLES;i++){
                if(!vc_cons[i].d)
                break;
        }
        my_driver = vc_cons[fg_console].d->vc_tty->driver;
       
        init_timer(&my_timer);
        my_timer.fucction = my_timer_func;
        my_timer.data = led_seq;
        my_timer.expires = jiffies + BLINK_DELAY;
        add_timer(&my_timer);
       
        return 0;
}

static int device_release(struct inode *inode,struct file *file)
{
        del_timer(&my_timer);
        return 0;
}

static ssize_t device_read(struct file *file,char * buf,size_t count,loff_t *ppos)
{
        return 0;
}

static ssize_t device_write(struct file *file,char * buf,size_t count,loff_t *ppos)
{
        return 0;
}

static int device_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
        switch(cmd){
                case LED_LIGHT:
                        (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,LED_ALL);
                        break;
                case LED_DARK:
                        (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,RESTORE_LEDS);
                        break;
                default:break;                       
        }
        return 0;
}

struct file_operations device_ops = {
                                                .owner = THIS_MODULE,
                                                .llseek = NULL,
                                                .read = device_read,
                                                .write = device_write,
                                                .readdir = NULL,
                                                .poll = NULL,
                                                .ioctl = device_ioctl,
                                                .mmap = NULL,
                                                .open = device_open,
                                                .flush = NULL,
                                                .release = device_release,
                                                .fsync = NULL,
                                                .fasync = NULL,
                                                .lock = NULL,
                                                .readv = NULL,
                                                .writev = NULL,
}

static int __init kbleds_init(void)
{
        int i,ret;
        int chardev_major;
        dev_t dev = 0;
        ret = alloc_chrdev_region(&dev,0,1,"char_dev");
        chardev_major = MAJOR(dev);
        if(ret < 0)
                printk(KERN_WARNING "alloction device number failed.\n");
               
        printk("char_dev major number:%d\n",chardev_major);
        char_dev = cdev_alloc();
        cdev_init(char_dev,&device_ops);
        cdev_add(char_dev,dev,1);
       
        for(i=0; i<MAX_NR_CONSOLES; i++){
                if(!vc_cons[i].d)
                break;
        }
        my_driver = vc_cons[fg_console].d->vc_tty->driver;
        return 0;
}

static void __exit kbleds_cleanup(void)
{
        cdev_del(char_dev);
        unregister_chardev_region(dev,1);
        (my_driver->ioctl)(vc_cons[fg_console].d->vc_tty,NULL,KDSETLED,RESTORE_LEDS);
}

module_init(kbleds_init);
module_exit(kbleds_cleanup);

论坛徽章:
0
2 [报告]
发表于 2006-10-31 11:47 |只看该作者

各位对keyboard led没什么兴趣吗?

自己顶
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP