#include struct leds { /*led描述*/
struct cdev led_dev;
char val[2];
volatile unsigned long *gpio_coun;
volatile unsigned long *gpio_data;
};
static struct leds led;
static ssize_t open_leds(struct inode *led_inode,struct file *file_led) /*打开文件*/
{
*led.gpio_coun &= (~(0x3 << 5 | 0x3 << 6 | 0x3 << 7 | 0x3 << 8));
*led.gpio_coun |= (0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8);
*led.gpio_data &= (~(0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8));
*led.gpio_data |= (0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8);
return 0;
}
static ssize_t write_leds(struct file *file_led,const char __user *bufer,size_t size,loff_t *off) /*点亮所有led*/
{
int val,ssize;
ssize = copy_from_user(&led.val,bufer,strlen(bufer)); /*将数据由用户区拷贝到内核区*/
if(ssize < 0)
return -1;
val = led.val[0] - '0';
if(!val)
*led.gpio_data &= (~(0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8));
else
*led.gpio_data |= (0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8);
return 0;
}
static ssize_t read_leds(struct file *file_led,char __user *bufer,size_t size,loff_t *off) /*读取数据*/
{
int f;
f = copy_to_user((void *)bufer,&led.val,strlen(led.val)); /*将数据由内核区拷贝到用户区*/
if(f < 0)
return -1;
return strlen(bufer);
}
static long ioctl_leds(struct file *file_led,unsigned int cmd,unsigned long arg) /*发送文件命令*/
{
if((cmd !=0 && cmd != 1) || (arg > 3 || arg < 0))
return -1;
switch(cmd){
case 0:
*led.gpio_data &= ~(0x1 << (arg + 5)); break;
case 1:
*led.gpio_data |= (0x1 << (arg + 5)); break;
}
return 0;
}
static int close_file(struct inode *inode,struct file *filep) /*关闭文件*/
{
*led.gpio_data &= (~(0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8));
*led.gpio_data |= (0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8);
return 0;
}
struct file_operations file_oper = {
.owner = THIS_MODULE,
.open = open_leds,
.write = write_leds,
.read = read_leds,
.unlocked_ioctl = ioctl_leds,
.release = close_file,
};
dev_t dev_num;
static struct class *class_file = NULL;
static int init_leds_device(void) /*加载驱动模块*/
{
alloc_chrdev_region(&dev_num,0,1,"my_leds"); /*动态分配设备号*/
led.led_dev.owner = THIS_MODULE; /*设备模板*/
cdev_init(&led.led_dev,&file_oper); /*初始化cdev*/
cdev_add(&led.led_dev,dev_num,1); /*注册设备*/
led.gpio_coun = (volatile unsigned long *)ioremap(0x56000010, 4); /*led端口映射*/
led.gpio_data = led.gpio_coun + 1;
/*自动创建设备文件l*/
class_file = class_create(THIS_MODULE,"my_leds");
device_create(class_file,NULL,dev_num,NULL,"my_leds");
return 0;
}
static void exit_leds_device(void) /*卸载驱动模块*/
{
cdev_del(&led.led_dev); /*注销设备*/
/*删除设备文件*/
device_destroy(class_file, dev_num);
class_destroy(class_file);
unregister_chrdev_region(dev_num,1); /*注销设备号*/
/*取消端口映射*/
iounmap(led.gpio_coun);
return;
}
MODULE_LICENSE("GPL");
module_init(init_leds_device); /*加载模块*/
module_exit(exit_leds_device); /*卸载模块*/