143 lines
3.4 KiB
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");
|
|
|