2008-03-21 06:23:27 gpio interrupt
Bastien Briec (FRANCE)
Message: 52882 hi all
i work on a cm-bf537e, and i would like to run an application when a button is pressed, i look at the interrupt wiki, so i wrote a driver :
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <stdio.h>
#define CONFIG_YOURDRIVERS_IRQ_PFX IRQ_PG10
static irqreturn_t your_irq_handler (int irq, void *dev_id)
{
printk(KERN_INFO"your_irq_handler \n");
return IRQ_HANDLED;
}
static int __init your_drivers_init_function(void)
{
if (request_irq(CONFIG_YOURDRIVERS_IRQ_PFX, your_irq_handler, IRQT_RISING, "PG10",NULL))
{
printk(KERN_WARNING "IRQ %d is not free.\n", CONFIG_YOURDRIVERS_IRQ_PFX);
return -EBUSY;
}
disable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);
printf("driver test pg10");
enable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);
}
void __exit your_drivers_exit_function(void)
{
free_irq (CONFIG_YOURDRIVERS_IRQ_PFX, NULL);
}
i add it like explained in the driver developpemnt but nothing when I push the pg10 button. can someone explain me how to do.
regards Bastien
TranslateQuoteReplyEditDelete
2008-03-21 07:07:58 Re: gpio interrupt
Jian Ju (HONG KONG)
Message: 52885 I'm unfamiliar with bf537 board, however, you need to setup the gpio (int mask, edge/level, polarity, etc) in the init function so that the interrupt can be generated as you expected.
TranslateQuoteReplyEditDelete
2008-03-21 08:53:40 Re: gpio interrupt
Mike Frysinger (UNITED STATES)
Message: 52888 all of those things are done for you with the GPIO framework ... you need need to mess with any masks
QuoteReplyEditDelete
2008-03-21 08:55:10 Re: gpio interrupt
Mike Frysinger (UNITED STATES)
Message: 52889 you called request_irq() with "IRQT_RISING" ... that is an invalid flag
please read the start of the wiki page where it lists valid flags
QuoteReplyEditDelete
2008-03-21 10:00:18 Re: gpio interrupt
Bastien Briec (FRANCE)
Message: 52891 I try to replace it by "IRQF_TRIGGER_LOW" but there is nothing when i push the button, what i would like to begin is just to display a message when the button is pressed.
regards Bastien
TranslateQuoteReplyEditDelete
2008-03-21 11:15:17 Re: gpio interrupt
Mike Frysinger (UNITED STATES)
Message: 52894 try using a rising or falling trigger ... otherwise, you'll have to verify with the hardware schematics what you're actually pushing
we've used the gpio keys driver on the BF537-STAMP just fine ... you could probably adapt it to the cm-bf537 pretty easily by just migrating over the board resources
QuoteReplyEditDelete
2008-03-25 05:32:31 Re: gpio interrupt
Bastien Briec (FRANCE)
Message: 53001 I try with a rising and a falling trigger but in all case i get nothing, i verify in the hardware schematics the button is pg14 and it works with the pflags_test program, is my driver correct or may be it's another problem?
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <stdio.h>
#define CONFIG_YOURDRIVERS_IRQ_PFX PG14
static irqreturn_t your_irq_handler (int irq, void *dev_id)
{
printk(KERN_INFO"your_irq_handler \n");
return IRQ_HANDLED;
}
static int __init your_drivers_init_function(void)
{
if (request_irq(CONFIG_YOURDRIVERS_IRQ_PFX, your_irq_handler, IRQF_RISING_RISING, "PG14",NULL))
{
printk(KERN_WARNING "IRQ %d is not free.\n", CONFIG_YOURDRIVERS_IRQ_PFX);
return -EBUSY;
}
disable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);
printf("driver test pg14");
enable_irq(CONFIG_YOURDRIVERS_IRQ_PFX);
}
void __exit your_drivers_exit_function(void)
{
free_irq (CONFIG_YOURDRIVERS_IRQ_PFX, NULL);
}
module_init(your_drivers_init_function)
module_exit(your_drivers_exit_function);
TranslateQuoteReplyEditDelete
2008-03-25 08:19:02 Re: gpio interrupt
Mike Frysinger (UNITED STATES)
Message: 53013 your driver is incorrect ... you use IRQ_PG14, not PG14
QuoteReplyEditDelete
2008-03-25 08:51:00 Re: gpio interrupt
Bastien Briec (FRANCE)
Message: 53015 I also try to use IRQ_PG14 instead of PG14 but the driver does not seems to work
TranslateQuoteReplyEditDelete
2008-03-26 05:19:49 Re: gpio interrupt
roger froysaa (NORWAY)
Message: 53041
Hi, here is an old test I did on the CM-BF537 to test IRQs. It worked for me when I was playing with it...
Please note that this was only a dumb test and is seriously crappy code
Ignore the SPI-related names, I was reusing test code from other stuff...
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <asm-blackfin/mach-bf537/irq.h>
#include <linux/interrupt.h>
// GLOBAL SETTINGS AND INIT
int rf_major = 0;
int rf_minor = 0;
int rf_nr_devs = 1;
MODULE_LICENSE("GPL");
// Our local (internal) SPI device representation
struct rf_device_t
{
int opened;
struct cdev cdev;
};
struct rf_device_t rf_info; // One global instance - only one user at a time...
static DEFINE_SPINLOCK(rf_global_lock);
// =============================================================================
// Char device functions
// =============================================================================
static int rf_spi_open (struct inode * inode, struct file * filp)
{
//printk(KERN_WARNING "rf: open() called\n");
spin_lock(&rf_global_lock);
if (rf_info.opened)
{
printk(KERN_WARNING "rf: Driver already opened - exiting.\n");
spin_unlock(&rf_global_lock);
return -EBUSY;
}
rf_info.opened++;
spin_unlock(&rf_global_lock);
return 0;
}
static int rf_spi_release (struct inode * inode, struct file * filp)
{
//printk(KERN_WARNING "rf: release() called on close\n");
spin_lock(&rf_global_lock);
rf_info.opened--;
spin_unlock(&rf_global_lock);
return 0;
}
// Character device specific function map.
struct file_operations rf_fops = {
.owner = THIS_MODULE,
.open = rf_spi_open,
.release = rf_spi_release,
};
irqreturn_t rf_spi_irq (int irq, void *dev_id, struct pt_regs *regs)
{
printk(KERN_WARNING "rf: IRQ handler: Button pressed!!!\n");
return IRQ_HANDLED;
}
// =============================================================================
// MODULE RELATED STUFF
// =============================================================================
static int rf_spi_init (void)
{
int result;
dev_t devno = 0;
// -------------------------------------------------------------------------
// Allocate device number
if (rf_major)
{
devno = MKDEV(rf_major, rf_minor);
result = register_chrdev_region(devno, rf_nr_devs, "rf_spi");
}
else
{
// Normal case - have device nr given to us by kernel
result = alloc_chrdev_region(&devno, rf_minor, rf_nr_devs, "rf_spi");
rf_major = MAJOR(devno);
printk(KERN_WARNING "rf: Device number allocated: major: %d, minor: %d\n", MAJOR(devno), MINOR(devno));
}
if (result < 0)
{
printk(KERN_WARNING "rf: can't get major %d\n", rf_major);
return result;
}
// -------------------------------------------------------------------------
// Char device registration
// Initialize device...
cdev_init(&rf_info.cdev, &rf_fops);
rf_info.cdev.owner = THIS_MODULE;
rf_info.cdev.ops = &rf_fops;
result = cdev_add (&rf_info.cdev, devno, 1);
if (result)
{
printk(KERN_NOTICE "Error %d adding rf_spi\n", result);
goto cleanup_chrdev_region;
}
// -------------------------------------------------------------------------
// Register GPIO IRQ
result = request_irq (IRQ_PG14, rf_spi_irq, IRQF_TRIGGER_LOW, "rf_spi", NULL);
if (result)
{
printk(KERN_NOTICE "Error %d requesting IRQ\n", result);
goto cleanup_cdev;
}
// -------------------------------------------------------------------------
printk(KERN_ALERT "rf loaded ok\n");
return 0;
// Error "catch" handlers
cleanup_cdev:
cdev_del(&rf_info.cdev);
cleanup_chrdev_region:
unregister_chrdev_region(devno, rf_nr_devs);
return result;
}
static void rf_spi_cleanup (void)
{
/* cleanup_module is never called if registering failed */
dev_t devno = MKDEV(rf_major, rf_minor);
free_irq (IRQ_PG14, NULL);
cdev_del(&rf_info.cdev);
unregister_chrdev_region(devno, rf_nr_devs);
printk(KERN_ALERT "rf module cleanup done\n");
}
module_init(rf_spi_init);
module_exit(rf_spi_cleanup);
QuoteReplyEditDelete
2008-03-26 06:30:21 Re: gpio interrupt
Bastien Briec (FRANCE)
Message: 53046 Thanks Roger, it works, i'll try to understand all now.