#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <asm/io.h>
struct cdev dev0;
struct cdev dev1;
struct cdev dev2;
struct cdev dev3;
dev_t dev_id;
char *name="atxb_led";
unsigned base_minor=0;
struct class *cls;
#define GPMCON (0x7f008820)
#define GPMDAT (0x7f008824)
unsigned int *gpmdat;
//========================================
//led0
//========================================
ssize_t led0_read(struct file *file, char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat &= ~(1 << 0);
return 0;
}
ssize_t led0_write(struct file *file, const char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat |= (1 << 0);
return 0;
}
int led0_open(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
int led0_release(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
struct file_operations ops0 =
{
.owner = THIS_MODULE,
.read = led0_read,
.write = led0_write,
.open = led0_open,
.release= led0_release,
};
//========================================
//led1
//========================================
ssize_t led1_read(struct file *file, char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat &= ~(1 << 1);
return 0;
}
ssize_t led1_write(struct file *file, const char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat |= (1 << 1);
return 0;
}
int led1_open(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
int led1_release(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
struct file_operations ops1 =
{
.owner = THIS_MODULE,
.read = led1_read,
.write = led1_write,
.open = led1_open,
.release= led1_release,
};
//========================================
//led2
//========================================
ssize_t led2_read(struct file *file, char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat &= ~(1 << 2);
return 0;
}
ssize_t led2_write(struct file *file, const char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat |= (1 << 2);
return 0;
}
int led2_open(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
int led2_release(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
struct file_operations ops2 =
{
.owner = THIS_MODULE,
.read = led2_read,
.write = led2_write,
.open = led2_open,
.release= led2_release,
};
//========================================
//led3
//========================================
ssize_t led3_read(struct file *file, char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat &= ~(1 << 3);
return 0;
}
ssize_t led3_write(struct file *file, const char __user *user, size_t size, loff_t *offset)
{
printk("%s\n",__func__);
*gpmdat |= (1 << 3);
return 0;
}
int led3_open(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
int led3_release(struct inode *inode, struct file *file)
{
printk("%s\n",__func__);
return 0;
}
struct file_operations ops3 =
{
.owner = THIS_MODULE,
.read = led3_read,
.write = led3_write,
.open = led3_open,
.release= led3_release,
};
void init_gpm(void)
{
unsigned int *gpmcon;
printk("%s\n",__func__);
gpmcon = (unsigned int *)ioremap(GPMCON, 4);
*gpmcon &= ~0xffff;
*gpmcon |= 0x1111;
iounmap(gpmcon);
gpmdat = (unsigned int *)ioremap(GPMDAT, 4);
}
void exit_gpm(void)
{
printk("%s\n",__func__);
iounmap(gpmdat);
}
int __init led_init(void)
{
int ret;
ret = alloc_chrdev_region(&dev_id, base_minor, 4, name);
if(ret)
{
printk("alloc_chrdev_region error\n");
goto err;
}
cdev_init(&dev0, &ops0);
cdev_init(&dev1, &ops1);
cdev_init(&dev2, &ops2);
cdev_init(&dev3, &ops3);
cdev_add(&dev0, MKDEV(MAJOR(dev_id), 0), 1);
cdev_add(&dev1, MKDEV(MAJOR(dev_id), 1), 1);
cdev_add(&dev2, MKDEV(MAJOR(dev_id), 2), 1);
cdev_add(&dev3, MKDEV(MAJOR(dev_id), 3), 1);
cls = class_create(THIS_MODULE, name);
device_create(cls, NULL, MKDEV(MAJOR(dev_id), 0), &dev0, "ATXB_LED0");
device_create(cls, NULL, MKDEV(MAJOR(dev_id), 1), &dev1, "ATXB_LED1");
device_create(cls, NULL, MKDEV(MAJOR(dev_id), 2), &dev2, "ATXB_LED2");
device_create(cls, NULL, MKDEV(MAJOR(dev_id), 3), &dev3, "ATXB_LED3");
init_gpm();
err:
return 0;
}
void __exit led_exit(void)
{
exit_gpm();
device_destroy(cls, MKDEV(MAJOR(dev_id), 0));
device_destroy(cls, MKDEV(MAJOR(dev_id), 1));
device_destroy(cls, MKDEV(MAJOR(dev_id), 2));
device_destroy(cls, MKDEV(MAJOR(dev_id), 3));
class_destroy(cls);
cdev_del(&dev0);
cdev_del(&dev1);
cdev_del(&dev2);
cdev_del(&dev3);
unregister_chrdev_region(MKDEV(MAJOR(dev_id), 0), 4);
}
MODULE_LICENSE("GPL");
module_init(led_init);
module_exit(led_exit);
kernel_char_driver.tar.gz_operation
版权申诉
52 浏览量
2022-09-19
19:53:29
上传
评论
收藏 2KB GZ 举报
weixin_42653672
- 粉丝: 94
- 资源: 1万+