mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2025-01-24 13:41:05 +02:00
163 lines
4.4 KiB
C
Executable File
163 lines
4.4 KiB
C
Executable File
/*
|
|
* Driver preliminar y de pruebas de teclado ps2 kbps2
|
|
*
|
|
* Author: Ari Andrés Bejarano H.
|
|
*
|
|
*/
|
|
|
|
#include <linux/module.h> /* Needed by all modules */
|
|
#include <linux/kernel.h> /* Needed for KERN_INFO, printk() */
|
|
#include <linux/ioport.h>
|
|
#include <linux/device.h>
|
|
#include <linux/interrupt.h> /* We want an interrupt */
|
|
#include <linux/irq.h> /* We want an interrupt */
|
|
#include <linux/platform_device.h>
|
|
#include <linux/fs.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/io.h> /*ioremap ioremap_nocache iounmap iowriteXX ioreadXX*/
|
|
#include <linux/gpio.h>
|
|
#include <asm/mach-jz4740/gpio.h>
|
|
#include<asm/system.h> /*rmb*/
|
|
|
|
#define FPGA_IRQ_PIN JZ_GPIO_PORTC(15)
|
|
#define FPGA_CS JZ_GPIO_PORTB(26)
|
|
#define FPGA_BASE_BEGIN 0x15000000
|
|
#define FPGA_BASE_END 0x17FFFFFF
|
|
#define SUCCESS 0
|
|
#define DEVICE_NAME "kbps2" /* Dev name as it appears in /proc/devices */
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_AUTHOR("Ari");
|
|
MODULE_DESCRIPTION("Keyboard ps2");
|
|
MODULE_VERSION("1.0");
|
|
|
|
/* Declaration of kbps2.c functions */
|
|
static irqreturn_t irq_handler(int irq, void *dev_id);
|
|
static int kbps2_open(struct inode *, struct file *);
|
|
static int kbps2_release(struct inode *, struct file *);
|
|
static ssize_t kbps2_read(struct file *, char *, size_t, loff_t *);
|
|
static ssize_t kbps2_write(struct file *, const char *, size_t, loff_t *);
|
|
static int __init kbps2_init(void);
|
|
static void __exit kbps2_exit(void);
|
|
|
|
/* Structure that declares the usual file */
|
|
/* access functions */
|
|
struct file_operations fops = {
|
|
.owner = THIS_MODULE,
|
|
.read = kbps2_read,
|
|
.write = kbps2_write,
|
|
.open = kbps2_open,
|
|
.release = kbps2_release
|
|
};
|
|
|
|
/* Declaration of the init and exit functions */
|
|
module_init(kbps2_init);
|
|
module_exit(kbps2_exit);
|
|
|
|
/* Global variables of the driver */
|
|
static int irq_enabled = 0;
|
|
static int is_device_open = 0; /* Is device open? Used to prevent multiple access to device */
|
|
static int Major=65; /* Major number */
|
|
static DECLARE_WAIT_QUEUE_HEAD(wq);
|
|
static void __iomem *ioaddress;
|
|
static unsigned int interrupt_counter = 0;
|
|
|
|
static int __init kbps2_init(void)
|
|
{
|
|
int res, irq, result;
|
|
|
|
barrier();
|
|
|
|
printk(KERN_INFO "FPGA module is Up.\n");
|
|
interrupt_counter = 0;
|
|
|
|
/* Registering device */
|
|
result = register_chrdev(Major, DEVICE_NAME, &fops);
|
|
if (result < 0) {
|
|
printk("<1>memory: cannot obtain major number %d\n", Major);
|
|
return result;
|
|
}
|
|
|
|
/* Set up the FGPA irq line */
|
|
irq = gpio_to_irq(FPGA_IRQ_PIN);
|
|
res = request_irq(irq, irq_handler, IRQF_DISABLED | IRQF_TRIGGER_RISING, "FPGA - IRQ", NULL); // IRQF_TRIGGER_FALLING
|
|
irq_enabled = 1;
|
|
printk(KERN_INFO "FPGA irq_enabled...\n");
|
|
|
|
/* Set GPIOB26 as part of External Memory Controller*/
|
|
jz_gpio_set_function (FPGA_CS, JZ_GPIO_FUNC_NONE);
|
|
/* Use ioremap to get a handle on our region */
|
|
ioaddress = __ioremap(FPGA_BASE_BEGIN, FPGA_BASE_END - FPGA_BASE_BEGIN, _CACHE_UNCACHED);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void __exit kbps2_exit(void)
|
|
{
|
|
// int ret;
|
|
/*Tho order for free_irq, iounmap & unregister is very important */
|
|
free_irq(FPGA_IRQ_PIN, NULL);
|
|
__iounmap(ioaddress);
|
|
unregister_chrdev(Major, DEVICE_NAME);
|
|
printk(KERN_INFO "FPGA driver is down...\n");
|
|
}
|
|
|
|
static irqreturn_t irq_handler(int irq, void *dev_id)
|
|
{
|
|
unsigned int red;
|
|
if(irq_enabled)
|
|
{
|
|
interrupt_counter++;
|
|
printk(KERN_INFO "interrupt_counter=%d\n",interrupt_counter);
|
|
red=ioread32(ioaddress)& 0XFF;
|
|
rmb();
|
|
printk("%X \n", red);
|
|
wake_up_interruptible(&wq);
|
|
}
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
static int kbps2_open(struct inode *inode, struct file *file)
|
|
{
|
|
if (is_device_open)
|
|
return -EBUSY;
|
|
|
|
is_device_open = 1;
|
|
|
|
try_module_get(THIS_MODULE);
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static int kbps2_release(struct inode *inode, struct file *file)
|
|
{
|
|
is_device_open = 0;
|
|
|
|
module_put(THIS_MODULE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static ssize_t kbps2_read(struct file *filp, char *buffer, size_t count, loff_t *offset)
|
|
{
|
|
unsigned int red;
|
|
|
|
printk(KERN_INFO "read______-_-\n");
|
|
red=ioread32(ioaddress)& 0XFF;
|
|
rmb();
|
|
printk("%X\n", red);
|
|
return 0;
|
|
}
|
|
|
|
static ssize_t kbps2_write(struct file *filp, const char *buff, size_t count, loff_t * off)
|
|
{
|
|
|
|
printk(KERN_INFO "write______-_-\n");
|
|
printk("%X\n", buff[0]);
|
|
iowrite32(buff[0],ioaddress);
|
|
wmb();
|
|
|
|
return 1;
|
|
}
|