展讯8810的GPIO物理地址与虚拟地址的变换,小例÷

转帖:

./mach-sc8810/board-sp8810/gpio_cfg.c  gpio配置规划

kernel/arch/arm/mach-sc8810/include/mach/regs_gpio.h:
#define GPIO_BASE                            SPRD_GPIO_BASE
#define GPIO_PG_BASE                    GPIO_BASE
#define GPI_PG0_BASE                GPIO_BASE
kernel/arch/arm/mach-sc8810/include/mach/hardware.h:
#define SPRD_GPIO_BASE           0xE0031000

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

kernel/arch/arm/mach-sc8810/include/mach/adi_hal_internal.h  定义了GPIO的物理地址和虚拟地址之间的转换函数

#define ADI_PHYS    SPRD_MISC_PHYS//0x82000000
#define __adi_virt_to_phys(x) ((x) - SPRD_ADI_BASE + ADI_PHYS)
#define __adi_phy_to_virt(x) ((x)-ADI_PHYS + SPRD_ADI_BASE) // x-0x82000000+0xE0037000; 就是x+0x5E037000,也就是 虚拟地址到物理地址的偏移是 0x5E037000, 与 函数中的不符!!!

SC8810 Device Spec.pdf 的p102页 表5-1 SC8810重启之后的内存地址映射表 中 指明了 
0x80000000~0x8fffffff 为外设地址空间,其中0x82000480为GPIO(模拟控制功能段)的基地址(在0x820005ff结束); 0x8A000000为剩下的一段 GPIO的基地址。

kernel/arch/arm/mach-sc8810/include/mach/regs_adi.h
./mach-sc8810/include/mach/hardware.h 中定义了硬件物理地址和虚拟地址的映射关系,及硬件地址相关的宏
特别重要的一个宏是 #define SPRD_MISC_BASE          0xE0037000,其他很多宏都是在这个宏的基础上进行偏移的。
/* GPIO */
#define SPRD_GPIO_BASE           0xE0031000 //虚拟地址
#define SPRD_GPIO_PHYS           0x8a000000 //物理地址
#define SPRD_GPIO_SIZE           SZ_4K

/* registers for watchdog ,RTC, touch panel, aux adc, analog die... */
#define SPRD_MISC_BASE          0xE0037000  //MISC类 模块的虚拟地址
#define SPRD_MISC_PHYS          0x82000000  //MISC类 模块的物理地址
#define SPRD_MISC_SIZE          SZ_4K    //那么物理地址到虚拟地址的偏移为:
                                        //0xE0037000-0x82000000 =0x5E037000
                                        //正好是 __adi_phy_to_virt 的转换偏移;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

./mach-sc8810/include/mach/regs_adi.h: #define SPRD_ADI_BASE SPRD_MISC_BASE//0xE0037000
./mach-sc8810/include/mach/regs_adi.h: #define  ADI_BASE   SPRD_ADI_BASE  //0x82000000
./mach-sc8810/include/mach/regs_gpio.h: #define GPIO_BASE   SPRD_GPIO_BASE

/mach-sc8810/include/mach/board.h  
 定义了gpio的某些struct和一些全局变量( int sprd_3rdparty_gpio_tp_rst; int sprd_3rdparty_gpio_tp_irq; )

./mach-sc8810/include/mach/board.h :
 /* platform device data structures */
 struct sprd_platform_data
 {
  void (*panel_power)(int on);
  unsigned has_vsync_irq:1;
 };
 //这个是gpio_cfg.c文件中用到的结构,定义了一个gpio_initdata结构数组。
 struct gpio_initdata {
  int* gpio;
  int io;
 };

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

kernel/arch/arm/mach-sc8810/gpio.c  
 gpio各种操作函数的定义

mach-sc8810/include/mach/gpio.h
 //定义了一些GPIO相关的宏,比如gpio号的最大值、最小值

 #include <linux/init.h>

 #define GPIO_MIN_PIN_NUM  16
 #define GPIO_MAX_PIN_NUM      (205 + 16)
 //定义充电探测口
 #define CHARGER_DETECT_GPIO 162
 //定义USB的口
 #define USB_DM_GPIO 145
 #define USB_DP_GPIO 146

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

kernel/arch/arm/mach-sc8810/gpio_phy.h 中的 __get_base_addr 函数说明:

 #define NR_D_DIE_GPIOS 147

 static __inline u32 __get_base_addr (u32 gpio_id)
 {
  if (gpio_id > NR_D_DIE_GPIOS) //148~159保留
  {
   if (gpio_id < 176 + 16) //手册上 (176+16)号gpio之前的基地址都是0x80的step,
    return __adi_phy_to_virt(0x82000480);//GPIO(模拟控制)的基地址;另外还有小于这个区段的GPIO号的基地址是0x8A000000;
   return __adi_phy_to_virt(0x820004c0);//超过192号GPIO其基地址就是0x820004c0,中间没有步进0x80
  }

  return ((gpio_id>>4) -1) * 0x80 + (u32) GPIO_BASE;//<=147号的GPIO口的基地址//GPIO_BASE:0xE0031000; 
 //可以假定,0x8a0000000 的虚拟地址是 0xE0031000, 
 //那么虚拟地址到物理地址的偏移是:0x56031000 ,
 //这个值与 __adi_phy_to_virt 这个宏转换机制不一样。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~····
文中内容来自链接:http://blog.csdn.net/duanlove/article/details/7978790

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值