GPIO的初始化

在内核源码目录下 ls drivers/gpio/*.o, 可以看到“gpioexynos4”被编译进了内核

 

– 生成.o文件代表最终被编译进了内核

 

– 除了menuconfig配置文件,还可以通过.o文件来判定该文件是否编译进了

内核

 

在 gpio-exynos4.c 文件最下面一行

 

– core_initcall(exynos4_gpiolib_init);

– core_initcall代表在linux初始化过程中会调用

– 初始化函数是在源码目录下“include/linux/init.h”文件中定义的,该头文件

中定义了一系列的初始化函数,在linux启动的过程中会按等级

 

初始化函数调用了“exynos4_gpiolib_init”

static __init int exynos4_gpiolib_init(void)
{
	struct s3c_gpio_chip *chip;
	int i;
	int nr_chips;

	/* GPIO common part  */

	chip = exynos4_gpio_common_4bit;
	nr_chips = ARRAY_SIZE(exynos4_gpio_common_4bit);

	for (i = 0; i < nr_chips; i++, chip++) {
		if (chip->config == NULL)
			chip->config = &gpio_cfg;
		if (chip->base == NULL)
			pr_err("No allocation of base address for [common gpio]");
	}

	samsung_gpiolib_add_4bit_chips(exynos4_gpio_common_4bit, nr_chips);

	/* Only 4210 GPIO  part */
	if (soc_is_exynos4210()) {
		chip = exynos4210_gpio_4bit;
		nr_chips = ARRAY_SIZE(exynos4210_gpio_4bit);

		for (i = 0; i < nr_chips; i++, chip++) {
			if (chip->config == NULL)
				chip->config = &gpio_cfg;
			if (chip->base == NULL)
				pr_err("No allocation of base address [4210 gpio]");
		}

		samsung_gpiolib_add_4bit_chips(exynos4210_gpio_4bit, nr_chips);
	} else {
	/* Only 4212/4412 GPIO part */
		chip = exynos4212_gpio_4bit;
		nr_chips = ARRAY_SIZE(exynos4212_gpio_4bit);

		for (i = 0; i < nr_chips; i++, chip++) {
			if (chip->config == NULL)
				chip->config = &gpio_cfg;
			if (chip->base == NULL)
				pr_err("No allocation of base address [4212 gpio]");
		}

		samsung_gpiolib_add_4bit_chips(exynos4212_gpio_4bit, nr_chips);
	}

	s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
	s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);

	return 0;
}

 

• 在该函数中引用了chip = exynos4_gpio_common_4bit结构体

 

• 查找到结构体exynos4_gpio_common_4bit

• 可以看到结构体中有S5P_VA_XXXX的基地址定义,VA一般用来代表虚

拟地址。

 

 

.base = (S5P_VA_GPIO2 + 0x100)

– 表示偏移地址和虚拟地址相加

 

• .eint_offset = 0x20

– 表示中断部分,介绍中断的时候再讲(IO口可以配置为中断模式)

 

• .group = 22

– 给GPIO分组

 

• chip.base = EXYNOS4_GPL2(0),

– 宏定义EXYNOS4_GPL2(0)赋值给初始化函数

 

• chip.ngpio = EXYNOS4_GPIO_L2_NR

– 表示这一小组中有几个GPIO

 

• chip.label = "GPL2",

– 程序员需要关心的标志

 

 

宏定义EXYNOS4_GPL2(0)分析

 

– EXYNOS4_GPL2(_nr) (EXYNOS4_GPIO_L2_START + (_nr))

– 枚举GPIO

– EXYNOS4_GPIO_L2_START= EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1)

– EXYNOS4_GPIO_NEXT宏定义

– #define EXYNOS4_GPIO_NEXT(__gpio) \ ((__gpio##_START) + (__gpio##_NR)

+ CONFIG_S3C_GPIO_SPACE + 1)

• GPIO的数量EXYNOS4_GPIO_L2_NR

– 可以通过手册查到

 

 

S5P_VA_GPIO2

 

– 虚拟地址

• 查找S5P_VA_GPIO2宏定义,可以看到所有的GPIO被分为4个bank,这

个和datasheet上面是一致的。

– S5P_VA_GPIO1

– S5P_VA_GPIO2 S3C_ADDR(0x02240000)

– S5P_VA_GPIO3

– S5P_VA_GPIO4

• 查找到S3C_ADDR宏定义

– #define S3C_ADDR(x) (S3C_ADDR_BASE + (x))

• 查找到S3C_ADDR_BASE宏定义,这是一个虚拟地址,可以看出,地址

范围超出了1G或者2G内存的范围

– #define S3C_ADDR_BASE 0xF6000000

 

 

 

GPIO的调用函数

 

• 例如头文件gpio-cfg.h中s3c_gpio_cfgpin函数。这个函数是给GPIO做配

置,第一个参数是宏EXYNOS4_GPL2(0),第二个是配置的状态参数

– 配置头文件在arm/arm/plat-samsung/include/plat/gpio-cfg.h

• 查找该函数,可以看到进入函数就会调用chip结构体

– s3c_gpiolib_getchip,这个函数通过pin调用之后,会返回s3c_gpios[chip] 的

参数

– exynos4_gpio_common_4bit[]和s3c_gpios都是结构体s3c_gpio_chip类型的

数据

– 然后计算偏移地址等等一系列操作,这一部分是linux内核以及三星平台完

成的,具体细节不用管。

 

控制GPIO时,可以通过GPIO的一些处理函数加上类似EXYNOS4_GPL2(0)的宏定义,就可以操作GPIO。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值