GPIO是與硬體體系密切相關的,linux提供一個模型來讓驅動統一處理GPIO,即各個闆卡都有實作自己的gpio_chip控制子產品:request, free, input,output, get,set,irq...
然後把控制子產品注冊到核心中,這時會改變全局gpio數組:gpio_desc[].
當使用者請求gpio時,就會到這個數組中找到,并調用這個GPIO對應的gpio_chip的處理函數。
gpio實作為一組可用的 gpio_chip, 由驅動傳入對應 gpio的全局序号 去 request, dataout ,datain, free. 這時會調用gpio_chip中具體的實作。
寄存器讀寫函數: __raw_writel() __raw_writeb() __raw_readl() __raw_readb()
gpio是一組可控件的腳,由多個寄存器同時控制。通過設定對應的寄存器可以達到設定GPIO口對應狀态與功能。 資料狀态,輸入輸出方向,清零,中斷(那個邊沿觸發), 一般是一組(bank)一組的。
// 注冊方法: 1:struct gpio_chip: 表示一個gpio controller.通過這個結構抽象化所有的 GPIO源,而讓闆上其它的子產品可以用相同的接口調用使用這些GPIO。 2: struct gpio_desc: 表示一個gpio口,含對應的 gpio_chip. 3: ARCH_NR_GPIOS: 與闆相關的GPIO口數量,即是全局GPIO數組:static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; 4: 注冊 gpio_chip時,就是根據 chip 的資料 修改全局 GPIO數組中 gpio_desc 字段(chip, flags)。
arch/arm/mach-sc8810/gpio.c
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/bug.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <mach/regs_global.h>
#include <mach/regs_gpio.h>
#include <mach/regs_ana.h>
#include <mach/board.h>
#include "gpio_phy.h"
static struct gpio_chip sprd_gpio_chip = {
.label = "sc8810-gpio",
.direction_input = sprd_gpio_direction_input,
.direction_output = sprd_gpio_direction_output,
.get = sprd_gpio_get,
.set = sprd_gpio_set,
.request = sprd_gpio_request,
.free = sprd_gpio_free,
.to_irq = sprd_gpio_to_irq,
.base = 0,
.ngpio = GPIO_MAX_PIN_NUM,
};
static u8 sprd_gpio_logic[GPIO_MAX_PIN_NUM];
arch/arm/mach-sc8810/gpio_phy.h
取得基位址,其中用到了 實體位址轉虛拟位址的函數__adi_phy_to_virt 。
static __inline u32 __get_base_addr (u32 gpio_id)
{
if (gpio_id > NR_D_DIE_GPIOS)
{
if (gpio_id < 176 + 16)
return __adi_phy_to_virt(0x82000480);
return __adi_phy_to_virt(0x820004c0);
}
return ((gpio_id>>4) -1) * 0x80 + (u32) GPIO_BASE;
}
customize/customer_cfg/sp8810ga/kernel/pinmap/pinmap_cfg.c
17506(b) 2012-07-30 15:23 ./customize/customer_cfg/sp8810ga/kernel/pinmap/pinmap_cfg.c
22519(b) 2012-07-30 13:14 ./kernel/arch/arm/mach-sc8810/board-sp8810w/pinmap_cfg.c
kernel/arch/arm/mach-sc8810/board-sp8810/pinmap_cfg.c