您的位置:首页 > 其它

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

2017-12-06 09:32 846 查看
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"); 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ubuntu