天天看點

linux的GPIO平台适配模型(結合8810講解)

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

繼續閱讀