Hi3531与Hi3520 GPIO口的对比及驱动的修改

http://blog.csdn.net/xiangpingli/article/details/7251734

1、GPIO口的对比:

3520:

应用:16路CIF,4路、8路D1

管脚总数:768pin

GPIO: 8组,GPIO0~GPIO7

GPIO基地址:从NAND、NOR、DDR映射GPIOX寄存器地址都是一样的:

3531:

应用:

单片:16D1+16CIF编码+4D1解码,8路D1同编同解,4路高清同编同解

         双片(+3532):16路D1同编同解,8路720P同编同解,4路1080P实时解码

 管脚总数:817pin

GPIO:19组,GPIO0~GPIO18

 

3520与3531GPIO对比总结:

1、3531有19组GPIO,3520有8组GPIO,两者GPIO0~7的地址是相同的。

2、各寄存器偏移地址不变

 

3520gpio驱动中针对3531修改:

1、首先把多出的寄存器组添加上,多了11组寄存器。

2、然后因为内核的接口变化了,修改ioctl相关的部分,记得unlocked_ioctl参数比原来的参数少了一个inode。

3、创建和初始化信号量的地方也要修改掉,DECLARE_MUTEX在linux3.0中也不存在了,取而代之的是DEFINE_SEMAPHORE

4、就是地址映射部分,哪里映射失败,要把之前映射的全部释放掉再退出:

 

hi_gpio.c:

#include <linux/module.h>
//#include <asm/hardware.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>

#include <linux/init.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>

#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include "hi_gpio.h"

#define  GPIO_0_BASE_ADDR  0x20150000
#define  GPIO_1_BASE_ADDR  0x20160000
#define  GPIO_2_BASE_ADDR  0x20170000
#define  GPIO_3_BASE_ADDR  0x20180000
#define  GPIO_4_BASE_ADDR  0x20190000
#define  GPIO_5_BASE_ADDR  0x201a0000
#define  GPIO_6_BASE_ADDR  0x201b0000
#define  GPIO_7_BASE_ADDR  0x201c0000
#define  GPIO_8_BASE_ADDR  0x201d0000
/*  changed for 3531  */
#define  GPIO_9_BASE_ADDR  0x201e0000
#define  GPIO_10_BASE_ADDR  0x201f0000
#define  GPIO_11_BASE_ADDR  0x20200000
#define  GPIO_12_BASE_ADDR  0x20210000
#define  GPIO_13_BASE_ADDR  0x20220000
#define  GPIO_14_BASE_ADDR  0x20230000
#define  GPIO_15_BASE_ADDR  0x20240000
#define  GPIO_16_BASE_ADDR  0x20250000
#define  GPIO_17_BASE_ADDR  0x20260000
#define  GPIO_18_BASE_ADDR  0x20270000


#define  GPIO_DIR_BASE   (groupbase+0x400)
#define  GPIO_INTR_MASK  (groupbase+0x410)
#define  GPIO_DATA_BASE   data_reg_base


#define WRITE_REG(Addr, Value) ((*(volatile unsigned int *)(Addr)) = (Value))
#define READ_REG(Addr)         (*(volatile unsigned int *)(Addr))


static DEFINE_SEMAPHORE(gpio_sem);  /* 根据linux3.0.y 的源码,DEFINE_SEMAPHORE取代了DECLARE_MUTEX */

//static DECLARE_MUTEX(gpio_sem);

unsigned int groupbase=-1;
unsigned int data_reg_base=0;
unsigned int gpio_0_base_addr_virtual=0;
unsigned int gpio_1_base_addr_virtual=0;
unsigned int gpio_2_base_addr_virtual=0;
unsigned int gpio_3_base_addr_virtual=0;
unsigned int gpio_4_base_addr_virtual=0;
unsigned int gpio_5_base_addr_virtual=0;
unsigned int gpio_6_base_addr_virtual=0;
unsigned int gpio_7_base_addr_virtual=0;
unsigned int gpio_8_base_addr_virtual=0;
unsigned int gpio_9_base_addr_virtual=0;
unsigned int gpio_10_base_addr_virtual=0;
unsigned int gpio_11_base_addr_virtual=0;
unsigned int gpio_12_base_addr_virtual=0;
unsigned int gpio_13_base_addr_virtual=0;
unsigned int gpio_14_base_addr_virtual=0;
unsigned int gpio_15_base_addr_virtual=0;
unsigned int gpio_16_base_addr_virtual=0;
unsigned int gpio_17_base_addr_virtual=0;
unsigned int gpio_18_base_addr_virtual=0;


static void gpio_calculate_data_groupbase(unsigned int groupnum, unsigned int bitnum)
{
    switch(groupnum)
    {
 case 0: 
      groupbase =gpio_0_base_addr_virtual;
      break;
 case 1: 
      groupbase =gpio_1_base_addr_virtual;
      break;
 case 2: 
      groupbase =gpio_2_base_addr_virtual;
      break;
 case 3: 
      groupbase =gpio_3_base_addr_virtual;
      break;
 case 4: 
      groupbase =gpio_4_base_addr_virtual;
      break;
 case 5: 
      groupbase =gpio_5_base_addr_virtual;
      break;
 case 6: 
      groupbase =gpio_6_base_addr_virtual;
      break;
 case 7: 
      groupbase =gpio_7_base_addr_virtual;
      break;
 case 8: 
      groupbase =gpio_8_base_addr_virtual;
      break;
 case 9: 
      groupbase =gpio_9_base_addr_virtual;
      break;
 case 10: 
      groupbase =gpio_10_base_addr_virtual;
      break;
 case 11: 
      groupbase =gpio_11_base_addr_virtual;
      break;
 case 12: 
      groupbase =gpio_12_base_addr_virtual;
      break;
 case 13: 
      groupbase =gpio_13_base_addr_virtual;
      break;
 case 14: 
      groupbase =gpio_14_base_addr_virtual;
      break;
 case 15: 
      groupbase =gpio_15_base_addr_virtual;
      break;
 case 16: 
      groupbase =gpio_16_base_addr_virtual;
      break;
 case 17: 
      groupbase =gpio_17_base_addr_virtual;
      break;
 case 18: 
      groupbase =gpio_18_base_addr_virtual;
      break;


   
 default:
      break;
    }

//    printk("groupbase:%x !\n",groupbase);
    data_reg_base=groupbase+(1<<(bitnum+2));
//    printk("data_reg_base:%x !\n",data_reg_base);
}

 

static int gpio_open(struct inode *inode, struct file *filp)
{
   return 0;  
}

static int gpio_release(struct inode *inode, struct file *filp)
{
 return 0; 
}


//static int gpio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
static int gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{         

    //这里代码没改

    return 0;

}


static struct file_operations gpio_fops = {
  owner:THIS_MODULE,
  open:gpio_open,
 // ioctl:gpio_ioctl,
  unlocked_ioctl:gpio_ioctl,  /* linux3.0.y 不再使用ioctl,采用unlocked_ioctl */
  release:gpio_release,
};

static struct miscdevice gpio_dev = {
    MISC_DYNAMIC_MINOR,
    "hi_gpio",
    &gpio_fops,
};

 

//gpio的复用关系要放在uboot下面;
static int __init hi_gpio_init(void)
{
 signed int  ret=0;

        ret = misc_register(&gpio_dev);
        if (ret)
        {
                printk(KERN_ERR "register misc dev for hi_gpio fail!\n");
  return ret;
 }
 
 gpio_0_base_addr_virtual=(unsigned int)ioremap_nocache(GPIO_0_BASE_ADDR,0x40000);
 if(!gpio_0_base_addr_virtual)
 {
     printk("ioremap gpio group0 failed!\n");
     return -1;
 }
 gpio_1_base_addr_virtual=gpio_0_base_addr_virtual+0x10000;
 gpio_2_base_addr_virtual=gpio_0_base_addr_virtual+0x20000;
 gpio_3_base_addr_virtual=gpio_0_base_addr_virtual+0x30000;
 gpio_4_base_addr_virtual=(unsigned int) ioremap_nocache(GPIO_4_BASE_ADDR,0x40000);
 if(!gpio_4_base_addr_virtual)
 {
     printk("ioremap gpio group0 failed!\n");
  /*说明gpio_0 映射成功了,但gpio_4没成功,所以要把gpio_0的释放掉*/
     iounmap((void*)gpio_0_base_addr_virtual);
     return -1;
 }

 gpio_5_base_addr_virtual=gpio_4_base_addr_virtual+0x10000;
 gpio_6_base_addr_virtual=gpio_4_base_addr_virtual+0x20000;
 gpio_7_base_addr_virtual=gpio_4_base_addr_virtual+0x30000;

 gpio_8_base_addr_virtual=(unsigned int) ioremap_nocache(GPIO_8_BASE_ADDR,0x40000);
 if(!gpio_8_base_addr_virtual)
 {
     printk("ioremap gpio group0 failed!\n");
  /*说明gpio_0 和gpio_4都映射成功了,但gpio_8没映射成功,所以将之前映射的释放*/
     iounmap((void*)gpio_0_base_addr_virtual);
     iounmap((void*)gpio_4_base_addr_virtual);   
     return -1;
 }

 gpio_9_base_addr_virtual   = gpio_8_base_addr_virtual + 0x10000;
 gpio_10_base_addr_virtual = gpio_8_base_addr_virtual + 0x20000;
 gpio_11_base_addr_virtual = gpio_8_base_addr_virtual + 0x30000;

 gpio_12_base_addr_virtual=(unsigned int) ioremap_nocache(GPIO_12_BASE_ADDR,0x40000);
 if(!gpio_12_base_addr_virtual)
 {
     printk("ioremap gpio group0 failed!\n");
     iounmap((void*)gpio_0_base_addr_virtual);   
     iounmap((void*)gpio_4_base_addr_virtual); 
     iounmap((void*)gpio_8_base_addr_virtual); 
     return -1;
 }

 gpio_13_base_addr_virtual   = gpio_12_base_addr_virtual + 0x10000;
 gpio_14_base_addr_virtual = gpio_12_base_addr_virtual + 0x20000;
 gpio_15_base_addr_virtual = gpio_12_base_addr_virtual + 0x30000;

 gpio_16_base_addr_virtual=(unsigned int) ioremap_nocache(GPIO_16_BASE_ADDR,0x30000); /* 注意:这里不能再是0x40000了*/
 if(!gpio_16_base_addr_virtual)
 {
     printk("ioremap gpio group0 failed!\n");    

     iounmap((void*)gpio_0_base_addr_virtual);   
     iounmap((void*)gpio_4_base_addr_virtual); 
     iounmap((void*)gpio_8_base_addr_virtual); 
     iounmap((void*)gpio_12_base_addr_virtual); 
     return -1;
 }

 gpio_17_base_addr_virtual   = gpio_16_base_addr_virtual + 0x10000;
 gpio_18_base_addr_virtual = gpio_16_base_addr_virtual + 0x20000;

 

 return 0;         
}


static void __exit hi_gpio_exit(void)
{
    misc_deregister(&gpio_dev);
    iounmap((void*)gpio_0_base_addr_virtual);
    iounmap((void*)gpio_4_base_addr_virtual);
    iounmap((void*)gpio_8_base_addr_virtual);
    iounmap((void*)gpio_12_base_addr_virtual);
    iounmap((void*)gpio_16_base_addr_virtual); 

}

module_init(hi_gpio_init);
module_exit(hi_gpio_exit);

MODULE_AUTHOR("Digital Media Team ,Hisilicon crop ");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Real Time Clock interface for HI3511"); 


 


你可能感兴趣的:(Hi3531与Hi3520 GPIO口的对比及驱动的修改)