2008-05-17 04:10:08     sw4 driver problem

Document created by Aaronwu Employee on Aug 6, 2013
Version 1Show Document
  • View in full screen mode

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

Attachments

    Outcomes