#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> #include <linux/delay.h> #include <linux/clk.h> #include <linux/miscdevice.h> #include <linux/gpio.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/uaccess.h> #include <mach/regs-clock.h> #include <plat/regs-timer.h> #include <mach/regs-gpio.h> #include <linux/cdev.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("liuchang"); #define beep_name "beep" #define DEV_NUM 5 struct class * class; struct device * devices[DEV_NUM]; #define MAGIC 'b' #define START_BEEP _IO(MAGIC,0) #define STOP_BEEP _IO(MAGIC,1) static struct cdev beep_dev; static ssize_t beep_read(struct file * fp,char __user * buffer,size_t count,loff_t * l) { return 0; } static ssize_t beep_write(struct file * fp,const char __user * buffer,size_t count,loff_t * l) { return 0; } static int beep_open(struct inode * ip,struct file *fp) { return 0; } static int beep_release(struct inode * ip,struct file *fp) { return 0; } static void start_beep() { s3c2410_gpio_cfgpin(S3C2410_GPB(0),S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPB(0),1); } static void stop_beep() { s3c2410_gpio_cfgpin(S3C2410_GPB(0),S3C2410_GPIO_OUTPUT); s3c2410_gpio_setpin(S3C2410_GPB(0),0); } static int beep_ioctl(struct inode * ip,struct file *fp,unsigned int cmd,unsigned long count) { switch(cmd) { case START_BEEP : { start_beep(); break; } case STOP_BEEP : { stop_beep(); break; } default: { return 0; } } return 0; } static struct file_operations fo = { .owner = THIS_MODULE, .read = beep_read, .write = beep_write, .ioctl = beep_ioctl, .open = beep_open, .release = beep_release, }; static int beep_major = 0; module_param(beep_major,int,0444); static int __init beep_init() { int i = 0; char dev_name[10]; //alloc dev_t dev_t dev = MKDEV(beep_major,0); if(beep_major){ register_chrdev_region(dev,DEV_NUM,beep_name); } else { alloc_chrdev_region(&dev,0,DEV_NUM,beep_name); beep_major = MAJOR(dev); } printk(KERN_EMERG"major is %d\n",beep_major); //init cdev cdev_init(&beep_dev,&fo); beep_dev.owner = THIS_MODULE; cdev_add(&beep_dev,dev,DEV_NUM); // class is like a container of devices-------------- // class相当于一个容器,可以存放多个类型相同的device class = class_create( THIS_MODULE,"beep_class"); for( i=0;i<DEV_NUM;i++ ) { dev = MKDEV( beep_major,i ); sprintf( dev_name,"beep%d",i); devices[i] = device_create( class,NULL,dev,NULL,dev_name); } //then /sys/class/beep_class/beepN directories created return 0; } static void __exit beep_exit() { int i = 0; dev_t dev = 0; cdev_del(&beep_dev); for( i=0;i<DEV_NUM;i++) { dev = MKDEV( beep_major,DEV_NUM); device_destroy( class,dev); } class_destroy( class); unregister_chrdev_region(dev,2); } module_init(beep_init); module_exit(beep_exit);