#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#define DEV_NAME "myled"
#define ledd_major 0
//定义LED控制引脚配置
static unsigned long ledd_table[]={
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};
static unsigned int ledd_cfg_table[]={
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};
struct ledd_dev_t
{
struct cdev cdev;
//unsigned int mem;
}ledd_dev;
int ledd_open(struct inode *inode, struct file *filp)
{
int i,ret;
for(i=0;i<4;i++)
{
printk("setting pin%d configuration now/n",i);
s3c2410_gpio_cfgpin(ledd_table[i],ledd_cfg_table[i]);
}
ret=nonseekable_open(inode,filp);
printk("the open function in driver return %d/n",ret);
return ret;
}
int ledd_release(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t ledd_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops)
{
int ret;
int number;
int power;
unsigned char mem;
printk("run the function copy_from_user()/n");
printk("buf value is %d/n",*buf);
if(copy_from_user(&mem,buf,1))
ret= -EFAULT;
else
{
number=(((mem)&0x0f0)>>4);//取传入实参的二进制的4到7位作为LED序号
power=((mem)&0x01);//取传入实参的二进制的0到3位作为LED开关位,0:亮,1:灭
printk("number is %d/n",number);
printk("power is %d/n",power);
s3c2410_gpio_setpin(ledd_table[number],power);
}
return 0;
}
static const struct file_operations ledd_fops=
{
.owner=THIS_MODULE,
.open= ledd_open,
.release=ledd_release,
.write=ledd_write,
};
static int __init ledd_init(void)
{
int ret;
int ma,mi;
cdev_init(&ledd_dev.cdev, &ledd_fops);
ledd_dev.cdev.owner=THIS_MODULE;
ledd_dev.cdev.dev=MKDEV(ledd_major, 0);
if (ledd_major)
{
register_chrdev_region(ledd_dev.cdev.dev,1,DEV_NAME);
}
else
{
alloc_chrdev_region(&ledd_dev.cdev.dev,0,1,DEV_NAME);
}
ma=MAJOR(ledd_dev.cdev.dev);
mi=MINOR(ledd_dev.cdev.dev);
printk("%d/n",ma);
printk("%d/n",mi);
printk("this is my led driver/n");
ret=cdev_add(&ledd_dev.cdev,ledd_dev.cdev.dev,1);
return ret;
}
static void __exit ledd_exit(void)
{
printk("bye");
unregister_chrdev_region(ledd_dev.cdev.dev,1);
cdev_del(&ledd_dev.cdev);
}
module_init(ledd_init);
module_exit(ledd_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YH Inc.");