Documentation
先從documentation消化一點介紹: A "General Purpose Input/Output" (GPIO) is a flexible software-controlled digital signal。 既然是數位訊號數位訊號在computer science,那就是只有0(low)/1(high),在embedded 平台上是常用且好用的東西。SoC上會有一堆GPIO,多達一百多根,沒有被設為alternative function (註1)的都可以拿來GPIO。從schematics上看就是一個點,從CPU拉出來,可能拉到power button設為XEINT當wakeup event,或是拉到analog codec設gpi當jack detect,或是設成gpo用來表示目前系統狀態 (1: normal; 0 suspend)。
GPIO的用途大概有以下幾種:
1. alternative function: 這是特定的function,如camera,hdmi,keypad。以hdmi為例,可以接到hdmi的hpd當hot plug detect,或是cec做進階控制,不過這些gpio都會有另外的driver來控制。以keypad為例,就可以藉由gpio的high/low來 mapping按了哪個key。
2. GPI: input/output的方向是對CPU而言,因此GPI就是從外部給CPU signal,比如說EC。舉個例好了,EC控制power button,按下後,EC就將某個GPI拉high,此時CPU收到high後,trigger wakeup source,系統就resume。
3. GPO: 對照GPI,GPO就是由CPU發出來的。同樣用EC當例子,EC也控了LED。當系統進入suspend,就把某根接到EC的GPO拉low。EC收到後,就把LED變成橘色。
GPIO怎麼用,在不同的系統,不同的應用會有不同的用法。
KERNEL
GPIO相關的API都定義在
#include
sample code:
1.為避免不同的driver同時設定同一根GPIO,所以先用gpio_request看看是否有人使用。之後再用s3c_gpio_cfgpin設為GPI,然後拉NONE。
err = gpio_request(S5PV2XX_GPH3(7),"GPH3");
if (err){
printk("gpio request error : %d\n",err);
}else{
s3c_gpio_cfgpin(S5PV2XX_GPH3(7),S3C_GPIO_INPUT);
s3c_gpio_setpull(S5PV2XX_GPH3(7), S3C_GPIO_PULL_NONE);
}
2.設為GPO,並拉low (0), high (1)
gpio_direction_output(S5PV2XX_GPH0(7), 0);
gpio_direction_output(S5PV2XX_GPH0(7), 1);
3. 設為EINT wakeup source。先設為EINT後,再投為wakeup source,掛handler。
err = gpio_request(S5PV2XX_GPH3(7),"GPH3");
if (err){
printk("gpio request error : %d\n",err);
}else{
s3c_gpio_cfgpin(S5PV2XX_GPH3(7),S5PV2XX_GPH3_7_EXT_INT33_7);
s3c_gpio_setpull(S5PV2XX_GPH3(7), S3C_GPIO_PULL_NONE);
}
set_irq_type(IRQ_EINT(31), IRQF_TRIGGER_FALLING);
setup_irq(IRQ_EINT(31), &s3c_button_irq);
set_irq_wake(IRQ_EINT(31), 1);
原著:http://kezeodsnx.pixnet.net/blog/post/30257192
GPIO(General Purpose I/O),其接腳可以供使用者由程式控制自由使用,PIN 腳依現實考量可作為GPI、GPO、GPIO。
因此,GPIO 的 PIN,我們要注意的是用途、in/out、還有電位的high/low,可以透過HW線路圖幫助了解。而這些狀態,我們可以透過 register 去了解控制。
特定 GPIO 可以發 GPIO event,像是 SCI、SMI,例如我們 notebook lid 的動作,透過 LID 的線傳到 EC,EC 再送一個 GPIO EVENT 給南橋,然後處理。
電位的改變有 edge 和 level。edge 的電會一直持續,當電位改變的時候,狀態也跟著改變,例如 high 到 low 為 1,則 low 到 high 為0。
level 則是當電位在低的時候,表 low,高的時候表 high。PIN是吃不同電的,這點我們要注意。
接下來說 routing,為什麼要 routing 呢?一個南橋下接了一大堆 device,符合 PCI 規格的 device
都有 ABCD 四根 PIN 可以發中斷(如果是 single function,就只有 int A),而我們所知的 8259,扣掉master和slave連接的一根,真的能用的只有十五根,甚至有些已經在早期分配給固定的 device,根本不夠用,為了分配剩下的 IRQ,所以我們就做了 routing 的動作。也就是說,本來要透過硬體直接連接 PIN,但是因為不夠用,INTEL 多做了幾支 PIN,PCI DEVICES就連接到這些 PIN,用軟體模擬的方式分配,解決不夠用的問題,我們把這樣的機制稱為 PIRQ Route Controller。
IRQ 的值,我們可以在 PCI SPE OFFSET 3C 的地方看到,另外我們有一根 serial IRQ,透過電位形狀來分辨不同的中斷。
在作業系統驅動程式支援 IRQ 共享的狀態下,從早期的 PIC 只支援 15 IRQ,現在的 APIC 可以支援的 215 個。
Routing 的實作方面,可以去看_PRT這個 control method。
沒有留言:
張貼留言