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 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,246);"> //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口的对比及驱动的修改的更多相关文章

  1. 树莓派2 GPIO 和 SwiftyGPIO

    自从苹果去年开源Swift编程语言以来,热心人们已经创建了Ubuntu安装包,移植到ARM设备上如RaspberryPi2,创建了网页开发框架,而现在UmbertoRaimondi发布了SwiftyGPIO,一个Swift库,能够和ARM设备上的GPIO接口进行交互。SwiftyGPIOREADME详细解释了如何使用模块。这次我们在RaspBerryPi2上用Swift语言再实现一次。SwiftGPIO为比较流行的板子提供了封装好的GPIO。setLedColor方法通过一个元组和一个数组[GPIO]把一

  2. ubuntu-10.04 – 在内核模式和用户模式之间使用ioctl通信

    我想使用ioctl与我的内核模块进行通信。我已经为内核模块和其他用户模式编写了两个c程序。编译内核模块时我收到这个错误:error:在初始化程序中指定的未知字段’ioctl’在这一行:任何想法为什么会发生这种情况。谢谢在较新的内核中,首选方法是使用.unlocked_ioctl或.compat_ioctl字段。Thisdiscussion可能会澄清发生了什么,如何处理。

  3. ubuntu – mdadm重启,阵列丢失了吗?不能组装?

    不知道我的Array发生了什么.我重新启动ubuntu12.04.1并在启动时遇到错误,fstab无法挂载我的mdadm数组的文件系统UUID.在运行了一些我在谷歌找到mdadm的命令之后,我完全糊涂了……看来我的数组刚刚消失了?无法获取有关Array的任何详细信息.mdadm–examine显示两个相同的数组?p=12416893#post12416893并尝试使用旧快照做一个mdadm–create.RAID现在出现了,但我无法安装它.这就是我基于以上链接/帖子所做的和谢谢大家花时间看这个,因为这超出

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

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

  5. 如何在ubuntu下使用nasm(程序集)从键盘读取单个字符输入?

    我在ubuntu下使用nasm.顺便说一下,我需要从用户的键盘上获取单个输入字符(比如一个程序要求你输入y/n?

  6. Ubuntu 14.04 编译最新版本strace

    strace一直使用很多年前的版本,会有一个问题是,新版本加添了ioctl命令不支持,那么就会显示一个纯数字,看起来就比较恼火。所以会考虑到要编译最新版本的strace来调试。

  7. 在Windows中直接发送ATA命令到设备?

    我试图在Windows中将ATA命令发送到物理磁盘,并从设备获取响应。所以我相信我必须使用一些“原始”的发送命令的方法。另外,如果您有一个基于nForce的MB与nvidia驱动程序,您的SATA驱动器将显示为SCSI,您不能使用此通过。在某些情况下,SMARTIOCTL将适用于nForce驱动程序。IDENTIFY需要一个512字节的数据缓冲区:根据ATA规范设置IDE寄存器。

  8. jquery – 创建HTML按钮以运行Python脚本

    所以我一直在寻找这个答案,而且我发现的大多数答案要么含糊不清,要么超出我对编程的了解.我想要做的是在网页quad_relay.html上创建一个按钮单击该按钮时,我希望它运行python脚本set_gpio.py该网页位于运行Django的lighttpd服务器上.我安装了jQuery和AJAX,我知道它们是我需要采取的路线才能实现这一点,但每次我尝试它都不起作用.有人能帮助我吗?解决方法你必须做一些修改:在您的HTML文件中:在urls.py中在views.py中:

  9. c – 英特尔Galileo裸机UART

    我想在Intelgalileo板上编写一个“helloworld”裸机应用程序.当然,使用UEFI打印文本效果很好,但我想“手动”访问UART,而无需UEFI的任何帮助.在QEMU,我的代码效果很好:.h文件.c文件主要这些规格对我没什么帮助.我猜英特尔galileo板上的UART不使用/模拟普通/传统COM端口3F8h,2F8h,3E8h或2E8h.谁能告诉我我做错了什么,甚至发布了一个最小的裸机世界示例?

  10. c – 如何在Linux GPIO中使用boost :: asio

    我有一个使用boost::asio进行异步输入/输出的单线程Linux应用程序.现在我需要扩展此应用程序以读取/sys/class/gpio/gpioXX/value上的GPIO输入.在边沿触发的GPIO输入上使用boost::asio::posix::stream_descriptor可以做到这一点吗?我配置了GPIO输入,如下所示:我设法写了一个基于epoll的测试应用程序,它阻止GPIO文件

随机推荐

  1. crontab发送一个月份的电子邮件

    ubuntu14.04邮件服务器:Postfixroot收到来自crontab的十几封电子邮件.这些邮件包含PHP警告.>我已经解决了这些警告的原因.>我已修复每个cronjobs不发送电子邮件(输出发送到>/dev/null2>&1)>我删除了之前的所有电子邮件/var/mail/root/var/spool/mail/root但我仍然每小时收到十几封电子邮件.这些电子邮件来自cronjobs,

  2. 模拟两个ubuntu服务器计算机之间的慢速连接

    我想模拟以下场景:假设我有4台ubuntu服务器机器A,B,C和D.我想在机器A和机器C之间减少20%的网络带宽,在A和B之间减少10%.使用网络模拟/限制工具来做到这一点?

  3. ubuntu-12.04 – 如何在ubuntu 12.04中卸载从源安装的redis?

    我从源代码在Ubuntu12.04上安装了redis-server.但在某些时候它无法完全安装,最后一次makeinstallcmd失败.然后我刚刚通过apt包安装.现在我很困惑哪个安装正在运行哪个conf文件?实际上我想卸载/删除通过源安装的所有内容,只是想安装一个包.转到源代码树并尝试以下命令:如果这不起作用,您可以列出软件自行安装所需的步骤:

  4. ubuntu – “apt-get source”无法找到包但“apt-get install”和“apt-get cache”可以找到它

    我正在尝试下载软件包的源代码,但是当我运行时它无法找到.但是当我运行apt-cache搜索squid3时,它会找到它.它也适用于apt-getinstallsquid3.我使用的是Ubuntu11.04服务器,这是我的/etc/apt/sources.list我已经多次更新了.我尝试了很多不同的debs,并没有发现任何其他地方的错误.这里的问题是你的二进制包(deb)与你的源包(deb-src)不

  5. ubuntu – 有没有办法检测nginx何时完成正常关闭?

    &&touchrestarted),因为即使Nginx没有完成其关闭,touch命令也会立即执行.有没有好办法呢?这样的事情怎么样?因此,pgrep将查找任何Nginx进程,而while循环将让它坐在那里直到它们全部消失.你可以改变一些有用的东西,比如睡1;/etc/init.d/Nginx停止,以便它会休眠一秒钟,然后尝试使用init.d脚本停止Nginx.你也可以在某处放置一个计数器,这样你就可以在需要太长时间时发出轰击信号.

  6. ubuntu – 如何将所有外发电子邮件从postfix重定向到单个地址进行测试

    我正在为基于Web的应用程序设置测试服务器,该应用程序发送一些电子邮件通知.有时候测试是使用真实的客户数据进行的,因此我需要保证服务器在我们测试时无法向真实客户发送电子邮件.我想要的是配置postfix,以便它接收任何外发电子邮件并将其重定向到一个电子邮件地址,而不是传递到真正的目的地.我正在运行ubuntu服务器9.10.先感谢您设置本地用户以接收所有被困邮件:你需要在main.cf中添加:然后

  7. ubuntu – vagrant无法连接到虚拟框

    当我使用基本的Vagrantfile,只配置了两条线:我看到我的虚拟框打开,但是我的流氓日志多次显示此行直到超时:然后,超时后的一段时间,虚拟框框终于要求我登录,但是太久了!所以我用流氓/流氓记录.然后在我的物理机器上,如果我“流氓ssh”.没有事情发生,直到:怎么了?

  8. ubuntu – Nginx – 转发HTTP AUTH – 用户?

    我和Nginx和Jenkins有些麻烦.我尝试使用Nginx作为Jenkins实例的反向代理,使用HTTP基本身份验证.它到目前为止工作,但我不知道如何传递带有AUTH用户名的标头?}尝试将此指令添加到您的位置块

  9. Debian / Ubuntu – 删除后如何恢复/ var / cache / apt结构?

    我在ubuntu服务器上的空间不足,所以我做了这个命令以节省空间但是现在在尝试使用apt时,我会收到以下错误:等等显然我删除了一些目录结构.有没有办法做apt-getrebuild-var-tree或类似的?

  10. 检查ubuntu上安装的rubygems版本?

    如何查看我的ubuntu盒子上安装的rubygems版本?只是一个想法,列出已安装的软件包和grep为ruby或宝石或其他:)dpkg–get-selections

返回
顶部