Hello,
I can't seem to trigger an interrupt on port C pin 0. I read here,
http://tech.groups.yahoo.com/group/ts-7000/message/2496, that the IRQ5 which
pin0
is tied to is actually an ISA_IRQ, and it corresponds to IRQ22 in Linux. Is
that correct? I'm
using a TS7200. I couldn't find the diagram referred to in that post. I've
tried 5, 21, and
22. Is there another part to this I don't know about. Basically what I am
asking is what
number do I pass to the request_irq function? I'm sure it is obvious I am new
to this. All I
want to do is trigger the interrupt at this point. Any help is greatly
appreciated.
Maybe I'm triggering the IRQ wrong, I am of the understanding that if
everything else is
right, all one would have to do to trigger it is bring that pin high? Or am I
completely off
base?
Below is my code:
/* Necessary includes for device drivers */
#include <linux/kernel.h> // printk()
#include <linux/module.h>
#include <linux/types.h> // size_t
#include <linux/fs.h>
#include <linux/errno.h> // error codes
#include <linux/fcntl.h> // O_ACCMODE
#include <asm/system.h> // cli(), *_flags
//#include <asm/uaccess.h> // copy_from/to_user
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <linux/init.h>
/* Declaration of functions */
int wiegand_open(struct inode *inode, struct file *filp);
int wiegand_release(struct inode *inode, struct file *filp);
ssize_t wiegand_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t wiegand_write(struct file *filp, char *buf, size_t count, loff_t
*f_pos);
void wiegand_exit(void);
int wiegand_init(void);
unsigned char tsdio24_readReg(int offset);
void tsdio24_writeReg(int offset, unsigned char numb);
void interrupt_handler(int irq, void *dev_id, struct pt_regs *regs);
unsigned int pin0Irq = 22; //ISA_IRQ5 for input pin 0 is linux IRQ 22
//see discussion ~ http://tech.groups.yahoo.com/group/ts-7000/message/2496
/* Structure that declares the usual file access functions */
struct file_operations wiegand_fops = {
read: wiegand_read,
write: NULL,
open: wiegand_open,
release: wiegand_release
};
/* Declaration of the init and exit functions */
module_init(wiegand_init);
module_exit(wiegand_exit);
/*****************************************************************************/
//Pick the correct base depending on jumper settings
#define DIO24_BASE (0x0100) //jp1 and jp2 off
//#define DIO24_BASE (0x0108)
//#define DIO24_BASE (0x0110)
//#define DIO24_BASE (0x0118)
/* Global variables of the driver */
#define TSDIO24region 0x11E00000 //0x11e00100ul
#define TSDIO24length 8
#define TSDIO24Ident 0
#define TSDIO24irqCtr 3
#define TSDIO24DDR 4
#define TSDIO24regA 5
#define TSDIO24regB 6
#define TSDIO24regC 7
/* Major number */
int wiegand_major = 68;
DECLARE_WAIT_QUEUE_HEAD(pc104_wait);
static int data_not_ready = 1;
static int interruptcount = 0;
static volatile unsigned char * mem_virt_addr;
int wiegand_init(void) {
int result;
/*//check to see the if the memory space is available
if (check_mem_region(TSDIO24region,TSDIO24length)) {
printk(KERN_ERR "WiegandIn: Unable to acquire DIO24\n");
return -EBUSY;
}
// Map the registers
request_mem_region(TSDIO24region,TSDIO24length,"WiegandIn");*/
// must use __ioremap for physical address, see asm/io.h for more information
mem_virt_addr =
(unsigned char *) __ioremap((TSDIO24region + DIO24_BASE),TSDIO24length,0);
if(!mem_virt_addr) {
printk(KERN_ERR "WiegandIn: Failed to map memory\n");
wiegand_exit();
return -EIO;
}
if(tsdio24_readReg(TSDIO24Ident) != 0x54) { // ASCII 'T'
printk(KERN_ERR "WiegandIn: Failed to map memory\n");
wiegand_exit();
return -ENODEV;
} else {
printk(KERN_INFO "\n\nWiegandIn: TSDIO24 found!\n");
}
//set port c, pin 0 to do interupts, but keep previous settings
tsdio24_writeReg(TSDIO24irqCtr, tsdio24_readReg(TSDIO24irqCtr) | 0x01);
printk(KERN_INFO "\n\nWiegandIn: IRQ Reg=0x%02x\n",
tsdio24_readReg(TSDIO24irqCtr));
/* Registering device */
result = register_chrdev(wiegand_major, "wiegandIn", &wiegand_fops);
if (result < 0) {
printk(KERN_ERR "WiegandIn: Cannot obtain major number %d\n",
wiegand_major);
wiegand_exit();
return result;
}
if(request_irq(pin0Irq, interrupt_handler, 0, "DIO24Ca0", NULL) != 0) {
printk(KERN_ERR ": can't get irq\n");
wiegand_exit();
return -EBUSY;
}
/* Allocating wiegand */
//do something
printk(KERN_INFO "\n\nInserting wiegand module ...\n");
return 0;
}
void wiegand_exit(void) {
/* Freeing up resources */
unregister_chrdev(wiegand_major, "wiegandIn");
free_irq(pin0Irq, NULL);
//iounmap(mem_virt_addr);
//release_mem_region(TSDIO24region, TSDIO24length);
printk(KERN_INFO "Removing wiegand module\n");
}
int wiegand_open(struct inode *inode, struct file *filp) {
/* Success, do nothing */
return 0;
}
int wiegand_release(struct inode *inode, struct file *filp) {
wiegand_exit();
return 0;
}
ssize_t wiegand_read(struct file *filp, char *buf, size_t count,
loff_t *f_pos) {
while (data_not_ready) {
interruptible_sleep_on(&pc104_wait);
}
//return data code goes here
data_not_ready = 1; //we are done, reset data_not_ready
return 0; // nothing read
}
unsigned char tsdio24_readReg(int offset) {
return *(mem_virt_addr + offset);
}
void tsdio24_writeReg(int offset, unsigned char numb) {
*(mem_virt_addr + offset) = numb;
}
void interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) {
interruptcount++;
printk(KERN_INFO "\n\nDIO14: interruptcount=%d\n", interruptcount);
/* Data ready. Wake up userspace process */
data_not_ready = 0;
//wake_up_interruptible(&pc104_wait);
}
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|