/*
**************************************************************************
uril driver interface for Linux on NUC970
**************************************************************************
*/
#include <linux/module.h> //
#include <linux/init.h> //
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <mach/hardware.h>
#include "util.h"
#define MODULE_NAME "util_gpio"
static struct platform_device* io_devices = NULL;
static int util_major=0;
static struct cdev util_chrdev;
static struct class* util_class;
static struct device * util_dev;
ssize_t driver_read(struct file * file, char *buf, size_t count, loff_t * ppos)
{
printk(KERN_INFO "driver_read!\n");
return 0;
}
ssize_t driver_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
{
printk(KERN_INFO "driver_write!\n");
return 0;
}
static int driver_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "driver_open!\n");
return 0;
}
static int driver_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
printk(KERN_INFO "driver_ioctl!\n");
return 0;
}
static int driver_release (struct inode* inode,struct file* file)
{
//printk(KERN_INFO "driver_release!\n");
//return 0;
}
struct file_operations util_driver_fops = {
.owner = THIS_MODULE,
.write = driver_write,
.read = driver_read,
.open = driver_open,
.unlocked_ioctl = driver_ioctl,
//.release = driver_release,
};
static int io_probe(struct platform_device *pdev) //__devinit
{
int ret;
dev_t dev_id;
dev_id = MKDEV(util_major, 0);
cdev_init(&util_chrdev, &util_driver_fops);
util_chrdev.owner = THIS_MODULE;
ret = cdev_add(&util_chrdev, dev_id, 1);
if(ret)
{
printk(KERN_ERR "cdev_add error!\n");
return -ENOMEM;
}
//create class
util_class = class_create(THIS_MODULE, MODULE_NAME);
if (IS_ERR(util_class))
return PTR_ERR(util_class);
util_dev = device_create(util_class, NULL, dev_id, NULL, MODULE_NAME);
if (IS_ERR(util_dev))
return PTR_ERR(util_dev);
printk("driver for "MODULE_NAME".%d (%d.%d) registered\n", 0, MAJOR(dev_id), MINOR(dev_id));
return ret;
}
static int io_remove(struct platform_device *pdev) //__devexit
{
return 0;
}
static struct platform_driver io_driver =
{
.probe = io_probe,
.remove = io_remove,
.driver =
{
.name = MODULE_NAME,
.owner = THIS_MODULE,
},
};
static int __init util_init(void)
{
int ret=1;
dev_t dev = MKDEV(util_major, 0);
//printk(KERN_INFO "hello world.\n");
io_devices = platform_device_alloc(MODULE_NAME, 0);
if(io_devices == NULL)
{
printk(KERN_ERR "get platform_device error!\n");
ret = -ENOMEM;
}
ret = platform_device_add(io_devices);
if (ret)
goto put_dev;
/* Figure out our device number. */
if (util_major)
ret = register_chrdev_region(dev, 1, MODULE_NAME);
else
{
ret = alloc_chrdev_region(&dev, 0, 1, MODULE_NAME);
if (ret)
{
printk(KERN_WARNING "FPGA_MODULE_NAME: unable to get major %d\n", util_major);
return ret;
}
util_major = MAJOR(dev);
}
ret = platform_driver_register(&io_driver);
if (ret == 0)
goto out;
platform_device_del(io_devices);
put_dev:
platform_device_put(io_devices);
out:
return 0;
}
static void __exit util_exit(void)
{
//printk(KERN_INFO "hello exit!\n");
device_destroy(util_class, MKDEV(util_major, 0));
cdev_del(&util_chrdev);
//
class_destroy(util_class);
platform_driver_unregister(&io_driver);
unregister_chrdev_region(MKDEV(util_major, 0), 1);
platform_device_unregister(io_devices);
}
module_init(util_init);
module_exit(util_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wlj");
MODULE_DESCRIPTION("util module");
MODULE_ALIAS("platform:wq3300");