詳解內核驅動操作GPIO引腳API函數

詳解內核驅動操作GPIO引腳API函數

函數原型:
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
unsigned int s3c2410_gpio_getcfg(unsigned int pin)
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
unsigned int s3c2410_gpio_getpin(unsigned int pin)
unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
int s3c2410_gpio_getirq(unsigned int pin)
關於函數中用到的虛擬地址到物理地址轉換的變量及算法可以參考
http://blog.163.com/hefeng330467115@126/blog/static/782058422010620511659/
http://blog.chinaunix.net/u3/102836/showart_2065945.html
看簡單led驅動程序是用到的文件及頭文件可能有:
linux/include/asm-arm/arch-s3c2410/map.h
linux/include/asm-arm/arch-s3c2410/regs-gpio.h
linux/arch/arm/plat-s3c24xx/gpio.c
linux/include/asm-arm/io.h
Source Insight 打開這些文件,然後再看驅動程序,可以隨意跳轉到定義處,很是方便
pin參數:
gpio引腳及特殊功能寄存器助記符都在linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定義:
eg:
S3C2410_GPACON 
S3C2410_GPADAT
S3C2410_GPA0 - S3C2410_GPA22 //引腳
S3C2410_GPA0_OUT - S3C2410_GPA22_OUT //設置引腳爲輸出
用到哪個不清楚的可以直接到這個文件去查找
還有中斷和GSTATUS
S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23
……
function參數:
指定引腳功能:輸出、輸入還是特殊功能,也在linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定義。
函數功能:
1 原型:void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
作用:配置GPIO引腳功能,即是配置相應的CON
eg 
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP)//設置B5腳爲輸出功能
函數原代碼及註釋:
這個函數註釋的比較詳細,後面類似的不再重複註釋
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin); 
//引腳基地址即是:GPA0GPB0 …… 的虛擬基地址
unsigned long mask; 
unsigned long con;
unsigned long flags;
if (pin < S3C2410_GPIO_BANKB) {
mask = 1 << S3C2410_GPIO_OFFSET(pin);
//用於查找對應的引腳位(端口A一位控制一個引腳
} else {
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
//除端口A外其他端口都是兩位控制一個引腳
}
//根據function值具體確定怎麼來調整function
switch (function) { 
case S3C2410_GPIO_LEAVE:
mask = 0;
function = 0;
break;
case S3C2410_GPIO_INPUT:
case S3C2410_GPIO_OUTPUT:
case S3C2410_GPIO_SFN2:
case S3C2410_GPIO_SFN3:
if (pin < S3C2410_GPIO_BANKB) 
{ // 當某位被設爲0時,相應引腳爲輸出,此時可
function -= 1; //以在GPADAT中相應位寫入10;當某位被
function &= 1; //設爲1時,相應引腳爲地址線或用於地址控制。
function <<= S3C2410_GPIO_OFFSET(pin); //偏移量即是相應的引腳
} else {
function &= 3;
function <<= S3C2410_GPIO_OFFSET(pin)*2; //A端口以外的其他端口都是 
} //兩位控制一個引腳
}
/* modify the specified register wwith IRQs off */
local_irq_save(flags); //調用該宏函數來保存IRQ 中斷使能狀態,並禁止IRQ 中斷
con = __raw_readl(base + 0x00);
// 基地址加偏移量得到相應端口的控制寄存器(GPxCON)地址,然後讀取該寄存器的值 
con &= ~mask; // 找到需要修改的引腳的控制位 
con |= function; // 使對應的引腳的功能爲function
__raw_writel(con, base + 0x00); // 重寫控制寄存器的值,實現引腳功能修改
local_irq_restore(flags); //恢復IRQ 和FIQ 的中斷使能狀態
}

2 原型:unsigned int s3c2410_gpio_getcfg(unsigned int pin)
作用:該函數根據引腳獲得指定引腳配置的功能值
eg 
s3c2410_gpio_getcfg (S3C2410_GPB5)//讀取B5腳爲的配置功能 輸入00、輸出01、特殊功能02 ……
函數原代碼及註釋:
unsigned int s3c2410_gpio_getcfg(unsigned int pin)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long val = __raw_readl(base);
if (pin < S3C2410_GPIO_BANKB) { //此判斷操作主要是針對A端口,原因前面已解釋
val >>= S3C2410_GPIO_OFFSET(pin);
val &= 1;
val += 1;
} else {
val >>= S3C2410_GPIO_OFFSET(pin)*2;
val &= 3;
}
return val | S3C2410_GPIO_INPUT;
}

原型:void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
作用:設置相應GPIO口的上拉電阻
eg 
s3c2410_gpio_pullupS3C2410_GPB50//設置S3C2410_GPB5不要上拉電阻
s3c2410_gpio_pullupS3C2410_GPB51//設置S3C2410_GPB5要上拉電阻
函數原代碼及註釋:
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long up;
if (pin < S3C2410_GPIO_BANKB)
return;
local_irq_save(flags);
up = __raw_readl(base + 0x08); // //0x08GPxUP寄存器的物理偏移量
up &= ~(1L << offs); //1L是什麼東西,暫時沒看明白,可能是錯誤,感覺應該是1
up |= to << offs;
__raw_writel(up, base + 0x08);
local_irq_restore(flags);
}
4原型:void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
作用:該函數給指定的引腳位寫入01,即是配置相應的DAT位。
eg
s3c2410_gpio_setpin (S3C2410_GPB5 ,0)//設置S3C2410_GPB5的輸出值爲0
s3c2410_gpio_setpin (S3C2410_GPB5 ,1)//設置S3C2410_GPB5的輸出值爲1
函數原代碼及註釋:
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;
local_irq_save(flags);
dat = __raw_readl(base + 0x04); //0x04GPxDAT寄存器的物理偏移量
dat &= ~(1 << offs);
dat |= to << offs;
__raw_writel(dat, base + 0x04);
local_irq_restore(flags);
}
5原型:void s3c2410_gpio_getpin(unsigned int pin)
作用:該函數讀取指定引腳的狀態 返回0 1,即是讀取相應的DAT位。
eg
s3c2410_gpio_setpin (S3C2410_GPB5 )// 讀取S3C2410_GPB5位的狀態。
函數原代碼及註釋:
unsigned int s3c2410_gpio_getpin(unsigned int pin)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);

return __raw_readl(base + 0x04) & (1<< offs);
}
6原型:unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
作用: 主要是設置混雜控制寄存器(Miscellaneous control :物理地址0x56000080), 此寄存器控制數據口上拉寄存器,hi-z 狀態,USB塊和CLKOUT選擇
7原型:int s3c2410_gpio_getirq(unsigned int pin)
作用: 讀取中斷引腳的狀態 GPF0-GPF7、GPG0-GPG7
eg
s3c2410_gpio_ getirq (S3C2410_GPF0 )// 讀取S3C2410_GPF0位的狀態,看是否產生EINT8中斷。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章