ckfwq/linux-3.0.4/drivers/misc/gsc3280_gpio.c

143 lines
3.4 KiB
C

#include <linux/miscdevice.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/rcupdate.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/completion.h>
#include <asm/io.h>
#include <linux/fs.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <linux/gpio.h>
#include <gsc3280/gpio.h>
#include <gsc3280/sysctl.h>
#include <linux/time.h>
#include <linux/ioctl.h>
#define MEMDEV_IOC_MAGIC 'y'
#define IOCTRL_GPIO_IN _IO(MEMDEV_IOC_MAGIC,1)
#define IOCTRL_GPIO_OUT _IO(MEMDEV_IOC_MAGIC,2)
#define IOCTRL_GPIO_REQ _IO(MEMDEV_IOC_MAGIC,3)
#define IOCTRL_GPIO_FRE _IO(MEMDEV_IOC_MAGIC,4)
#define SYS_MOD_CTL0 0xBC04A008
#define GPIO_EN (1<<27)
#define SYS_IOMUX_CFG0 0xBC04A0B0
#define GPIO_BASE 0xBC110000
#define GPIO_SWPORTA_DR (0x0 + GPIO_BASE)
#define GPIO_SWPORTA_DDR (0x04 + GPIO_BASE)
#define GPIO_SWPORTB_DR (0x0c + GPIO_BASE)
#define GPIO_SWPORTB_DDR (0x10 + GPIO_BASE)
#define GPIO_SWPORTC_DR (0x18 + GPIO_BASE)
#define GPIO_SWPORTC_DDR (0x1C + GPIO_BASE)
struct gsc3280_gpio{
short int pin;
short int data;
};
static int special_gpio_open(struct inode *inode, struct file *file) {
return 0;
}
static int special_gpio_close(struct inode *inode, struct file *file){
return 0;
}
static ssize_t special_gpio_read(struct file *file, char __user *buf, size_t count, loff_t *ptr){
return 0;
}
static ssize_t special_gpio_write(struct file *filp, const char __user *buf, size_t count, loff_t *ptr){
return 0;
}
static long special_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg){
struct gsc3280_gpio *dev ;
dev = (struct gsc3280_gpio *)arg;
*(volatile unsigned int*)SYS_MOD_CTL0 |= GPIO_EN;
switch(cmd){
case IOCTRL_GPIO_REQ:
if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 ){
gpio_request(dev->pin,NULL);
}
break;
case IOCTRL_GPIO_OUT:
if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 )
{
if(dev->data > 0)
gpio_direction_output(dev->pin,1);
else
gpio_direction_output(dev->pin,0);
}
break;
case IOCTRL_GPIO_IN:
if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 )
{
gpio_direction_input(dev->pin);
dev->data=gpio_get_value(dev->pin);
}
break;
case IOCTRL_GPIO_FRE:
if((dev->pin > 0 || 0 == dev->pin ) && dev->pin <88 ){
gpio_free(dev->pin);
}
break;
default:
printk(KERN_INFO"cmd error!!!\n");
break;
}
return 0;
}
static const struct file_operations special_gpio_ops = {
.owner = THIS_MODULE,
.open = special_gpio_open,
.read = special_gpio_read,
.write = special_gpio_write,
.release = special_gpio_close,
.unlocked_ioctl = special_gpio_ioctl,
};
static struct miscdevice special_gpio_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "3280_GPIO",
.fops = &special_gpio_ops,
};
static int special_gpio_init(void){
printk(KERN_INFO"%s\n",__func__);
if (misc_register(&special_gpio_miscdev)){
printk(KERN_ALERT"Couldn't register device 0, %d.\n", 255);
return -EBUSY;
}
return 0;
}
static void special_gpio_exit(void){
printk(KERN_INFO"%s\n",__func__);
misc_deregister(&special_gpio_miscdev);
}
module_init(special_gpio_init);
module_exit(special_gpio_exit);
MODULE_LICENSE("GPL");