2008-05-17 04:10:08 sw4 driver problem
hong li (CHINA)
Message: 55957
Hi everyone
I write a driver about sw4 on ezkit 533 , the sw4 connects to PF8 and the ezkit 533 has install uclinux , according to the driver , when i press sw4 ,is will enter interrupt service programme and the led will turn off, however, when i test the driver , there is no any reaction, and it can not enter the interrupt service programme
what is the problem? how to slove the problem?
Thanks
Hong
the driver as follows:
/*
File: key.c
Author: LiHong
Created: 2008.04.30
Discription: bf533 ezkit key driver
Version: V0.1
Modified:
License: GPL
*/
#include<linux/module.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/errno.h>
#include<linux/mm.h>
#include<linux/sched.h>
#include<linux/init.h>
#include<linux/cdev.h>
#include<linux/major.h>
#include<linux/kernel.h>
#include<linux/interrupt.h>
#include<asm/uaccess.h>
#include<asm/blackfin.h>
#include<asm/io.h>
#include<asm/irq.h>
#define KEY_MAJOR 210
#define BF_FIO_FLAG_D 0xFFC00700 /* Flag Mask to directly specify state of pins */
#define pFlashA_PortB_Data 0x20270005 /*the physical address of data register*/
#define INT_CTL_BASE_ADD 0xFFC00100
#define IRQ_NUMBER 41
static void __iomem *key_base;
static void __iomem *led_base;
static void __iomem *int_base;
static int key_major = KEY_MAJOR;
struct key_dev
{
struct cdev cdev;
wait_queue_head_t wq;
unsigned int tmp_value;
};
struct key_dev *key_devp;
static irqreturn_t key_irq_service(int irq,void *id,struct pt_regs *r);
int key_open(struct inode *inode,struct file *filp)
{
int ret=0;
init_waitqueue_head(&key_devp->wq);
key_devp->tmp_value = 0;
/*address mapping and setting the register*/
key_base = ioremap(BF_FIO_FLAG_D,64);
led_base = ioremap((unsigned long)pFlashA_PortB_Data,3);
int_base = ioremap(INT_CTL_BASE_ADD,36);
disable_irq(IRQ_NUMBER);
iowrite16(0x0000,key_base+48);/*set direction is input*/
iowrite16(0x0100,key_base+64);/*input buffer enable*/
iowrite16(0x0100,key_base+56);/*set edge is rising */
iowrite16(0x0100,key_base+16);/*maskA*/
enable_irq(IRQ_NUMBER);
ret = request_irq(IRQ_NUMBER,key_irq_service,SA_INTERRUPT,"key irq",NULL);
if(ret)
{ printk(KERN_ERR "IRQ%d already in use \n",IRQ_NUMBER);
goto key_error;
}
iowrite8(0x3f,led_base+2); /*set the led port is output*/
iowrite8(0x3f,led_base); /*the led is turn on */
return ret;
key_error:free_irq(IRQ_NUMBER,NULL);
return ret;
}
int key_release(struct inode *inode,struct file *filp)
{
iounmap(key_base);
iounmap(led_base);
free_irq(IRQ_NUMBER,NULL);
return 0;
}
static ssize_t key_read(struct file *filp,char *buf,ssize_t count,loff_t *ppos)
{
retry:if(key_devp->tmp_value != 0)
{
copy_to_user(buf,key_devp->tmp_value,count);
return count;
}
else
{
if(filp->f_flags & O_NONBLOCK)
{
return - EAGAIN;
}
interruptible_sleep_on(&(key_devp->wq));
goto retry;
}
return 0;
}
static irqreturn_t key_irq_service(int irq,void *id,struct pt_regs *r)
{
iowrite8(0x00,led_base); /*the led is turn off*/
key_devp->tmp_value = 4;
wake_up_interruptible(&key_devp->wq);
return IRQ_HANDLED;
}
static const struct file_operations key_fops =
{
.owner = THIS_MODULE,
.open = key_open,
.release = key_release,
.read = key_read,
};
int key_init( void )
{
int result;
dev_t devno = MKDEV(key_major,0);
if(key_major)
result = register_chrdev_region(devno,1,"pf8");
else
{
result = alloc_chrdev_region(&devno,0,1,"pf8");
key_major = MAJOR(devno);
}
if(result<0)
return result;
key_devp = kmalloc(sizeof(struct key_dev),GFP_KERNEL);
if(!key_devp)
{
result = - ENOMEM;
goto fail_malloc;
}
memset(key_devp,0,sizeof(struct key_dev));
cdev_init(&key_devp->cdev,&key_fops);
key_devp->cdev.owner = THIS_MODULE;
key_devp->cdev.ops = &key_fops;
cdev_add(&key_devp->cdev,devno,1);
return 0;
fail_malloc:unregister_chrdev_region(devno,1);
return result;
}
void key_exit( void )
{
cdev_del(&key_devp->cdev);
kfree(key_devp);
unregister_chrdev_region(MKDEV(key_major,0),1);
}
module_init(key_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");
QuoteReplyEditDelete
2008-05-17 10:16:00 Re: sw4 driver problem
Mike Frysinger (UNITED STATES)
Message: 55979
your code is very weird. i dont know why you're doing all of that ioremap/iowrite/ioread stuff, or where you get this magic "41" number from. none of that is how you're supposed to utilize GPIOs.
please read the documentation:
http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:interrupts
http://docs.blackfin.uclinux.org/doku.php?id=gpio
http://docs.blackfin.uclinux.org/doku.php?id=gpio_input_device_driver
http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:simple-gpio
QuoteReplyEditDelete
2008-05-17 11:21:24 Re: sw4 driver problem
hong li (CHINA)
Message: 55981
Thanks Mike
I am a beginner , i will rewrite the driver according to your documents
Hong
QuoteReplyEditDelete
2008-05-18 02:49:11 Re: sw4 driver problem
hong li (CHINA)
Message: 55988
Mike
Thanks your help sincerely, t have sloved the problem
Hong