</pre> <span >Odroid-XU4/3<span >提供</span><span >1</span><span >個</span><span >30</span><span >針的雙排擴展頭“</span><span >CON10</span><span >”。下面是對這些擴展引腳的說明。在擴展報頭的所有信號都只是</span><span >PWRON</span><span >信號</span><span >1.8V</span></span><span ><span >。 <img src="http://img.blog.csdn.net/20160515212753850?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></span></span></p><p><span ><span ></span></span></p><p><span > 如上圖,擴展的引腳功能分別有<span >ADC</span><span >、</span><span >UART</span><span >、</span><span >SPI</span><span >、</span><span >I2C</span><span >、</span><span >GPIO</span><span >,每個</span><span >gpio</span><span >都會有相應的擴展號在內核中標識,所以對</span><span >GPIO </span><span >的自定義設置都是通過它這個擴展號去標識。</span></span></p><p><span ><span > </span></span></p><p><span > 對於<span >GPIO</span><span >驅動的開發在官網</span><span >WIKI</span><span >中只介紹了上圖中擴展引腳和擴展號,經過筆者不斷地搜素尋找,終於在它的內核裡面找到相應的</span><span >GPIO</span><span >驅動。在</span><span >ioboard-keyled.c</span><span >中:</span></span><pre name="code" class="html">// GPIO Export Number define #define GPX2_5_EXPORT_NUM 29 #define GPX2_6_EXPORT_NUM 30 #define GPX1_6_EXPORT_NUM 22 #define GPX1_2_EXPORT_NUM 18 #define GPX2_7_EXPORT_NUM 31 #define GPX2_4_EXPORT_NUM 28 #define GPX1_3_EXPORT_NUM 19 #define GPB3_2_EXPORT_NUM 209 #define GPX2_0_EXPORT_NUM 24以上是它對GPIO引腳擴展號的聲明。
static struct { int gpio_index; // Control Index int gpio; // GPIO Number char *name; // GPIO Name == sysfs attr name (must) bool output; // 1 = Output, 0 = Input int value; // Default Value(only for output) int pud; // Pull up/down register setting : S3C_GPIO_PULL_DOWN, UP, NONE } sControlGpios[] = { { IOBOARD_SW1, GPX2_5_EXPORT_NUM, "sw1", 0, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_SW2, GPX2_6_EXPORT_NUM, "sw2", 0, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_SW3, GPX1_6_EXPORT_NUM, "sw3", 0, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_SW4, GPX1_2_EXPORT_NUM, "sw4", 0, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_LED1, GPX2_7_EXPORT_NUM, "led1", 1, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_LED2, GPX2_4_EXPORT_NUM, "led2", 1, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_LED3, GPX1_3_EXPORT_NUM, "led3", 1, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_LED4, GPB3_2_EXPORT_NUM, "led4", 1, 0, S3C_GPIO_PULL_NONE }, { IOBOARD_LED5, GPX2_0_EXPORT_NUM, "led5", 1, 1, S3C_GPIO_PULL_NONE }, };這是GPIO的結構體聲明gpio_index是一個枚舉的標識,gpio是該GPIO對應的擴展號,name及是一個名字,output是對該引腳設置輸入還是輸出,
value是設置輸出的情況下的值,0還是1
此外該文件代碼裡的探測函數ioboard_keyled_probe對引腳作了相應的初始化設置,主體代碼如下:
// Control GPIO Init for (i = 0; i < ARRAY_SIZE(sControlGpios); i++) { if(sControlGpios[i].gpio) { if(gpio_request(sControlGpios[i].gpio, sControlGpios[i].name)) { printk("%s : %s gpio reqest err!\n", __FUNCTION__, sControlGpios[i].name); } else { if(sControlGpios[i].output) gpio_direction_output (sControlGpios[i].gpio, sControlGpios[i].value); else gpio_direction_input (sControlGpios[i].gpio); s3c_gpio_setpull (sControlGpios[i].gpio, sControlGpios[i].pud); } } }代碼中還有設置gpio的函數,都很簡單,就不做詳細介紹,代碼如下所示:
static ssize_t set_gpio (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned int val, i; if(!(sscanf(buf, "%d\n", &val))) return -EINVAL; for (i = 0; i < ARRAY_SIZE(sControlGpios); i++) { if(sControlGpios[i].gpio) { if(!strcmp(sControlGpios[i].name, attr->attr.name)) { if(sControlGpios[i].output) gpio_set_value(sControlGpios[i].gpio, ((val != 0) ? 1 : 0)); else printk("This GPIO Configuration is INPUT!!\n"); return count; } } } printk("%s[%d] : undefined gpio!\n", __func__,__LINE__); return count; }通過以上內核的代碼,我們就可以模仿的寫我們自己的GPIO驅動了,我們只需要知道我們所要設置的GPIO的擴展號即可,不需要對設備樹等做什麼更改。