#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-fns.h>
#include <asm/uaccess.h>
#define ALARM_MAJOR 250
#define ALARM_NAME "alarm"
/*high is bell,lower is quit*/
static long alarm_table [] = {
S3C2410_GPB(0),
};
static int alarm_cfg [] = {
S3C2410_GPIO_OUTPUT,
};
struct alarm_dev
{
struct cdev cdev;
spinlock_t lock;
};
int alarm_major = ALARM_MAJOR;
struct alarm_dev *devp;
static int alarm_open(struct inode *inode, struct file *filp)
{
filp->private_data = devp;
return 0;
}
static int alarm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
{
switch(cmd){
case 0:
case 1:
if(arg){
return -EINVAL;
}
spin_lock(&devp->lock);
s3c2410_gpio_setpin(alarm_table[arg], cmd);
spin_unlock(&devp->lock);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations alarm_fops = {
.owner = THIS_MODULE,
.open = alarm_open,
.ioctl = alarm_ioctl,
};
static void alarm_setup(struct alarm_dev *dev, int index)
{
int err;
int devno = MKDEV(alarm_major, 0);
cdev_init(&dev->cdev, &alarm_fops);
dev->cdev.owner = THIS_MODULE;
err = cdev_add(&dev->cdev, devno, 1);
if(err)
printk(KERN_NOTICE "Error %d adding globalmem %d", err, index);
}
int __init alarm_init(void)
{
int result;
dev_t devno = MKDEV(alarm_major, 0);
if(alarm_major)
result = register_chrdev_region(devno, 1, ALARM_NAME);
else{
result = alloc_chrdev_region(&devno, 0, 1, ALARM_NAME);
alarm_major = MAJOR(devno);
}
if(result < 0)
return result;
devp = kmalloc(sizeof(struct alarm_dev), GFP_KERNEL);
if(!devp)
{
result = -ENOMEM;
goto fail_malloc;
}
memset(devp, 0, sizeof(struct alarm_dev));
alarm_setup(devp, 0);
spin_lock_init(&devp->lock);
s3c2410_gpio_cfgpin(alarm_table[0], alarm_cfg[0]);
s3c2410_gpio_setpin(alarm_table[0], 0);
return 0;
fail_malloc:
unregister_chrdev_region(devno, 1);
return result;
}
void __exit alarm_exit(void)
{
cdev_del(&devp->cdev);
kfree(devp);
unregister_chrdev_region(MKDEV(alarm_major, 0), 1);
}
module_init(alarm_init);
module_exit(alarm_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("emperor");
MODULE_DESCRIPTION("alarm module");
测试代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
void main(void)
{
int fd;
fd = open("/dev/alarm", 0);
if(fd < 0){
perror("open is failure");
exit(-1);
}
ioctl(fd, 1, 0); //响
}