linux gpio按键驱动程序,Linux GPIO Key 驱动的加载
gpio-keys是基于input子系統(tǒng)實現(xiàn)的一個通用的GPIO按鍵驅(qū)動,基于platform來實現(xiàn),位于drivers/input/keyboard/gpio_keys.c,這個文件是硬件無關(guān)的,而硬件有關(guān)的需要我們自己來注冊.進(jìn)入這個gpio_keys.c這個函數(shù),第一步就是初始化.
static int __init gpio_keys_init(void)
{
return platform_driver_register(&gpio_keys_device_driver);
}
然后加載這個結(jié)構(gòu)體:
static struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
.remove = __devexit_p(gpio_keys_remove),
.driver = {
.name = "gpio-keys",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &gpio_keys_pm_ops,
#endif
}
};
進(jìn)入后會執(zhí)行probe函數(shù),進(jìn)行設(shè)備的probe.當(dāng)然只是注冊設(shè)備,沒什么必要看.還比如gpio_keys_isr就是去抖動檢測,這是上半部分函數(shù).
static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{
struct gpio_button_data *bdata = dev_id;
struct gpio_keys_button *button = bdata->button;
BUG_ON(irq != gpio_to_irq(button->gpio));
if (button->debounce_interval)
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(button->debounce_interval));
else
schedule_work(&bdata->work);
return IRQ_HANDLED;
}
然后由定時器在超時時候,觸發(fā)的下半部分.
static void gpio_keys_work_func(struct work_struct *work)
{
struct gpio_button_data *bdata =
container_of(work, struct gpio_button_data, work);
gpio_keys_report_event(bdata);
}
既然gpio_keys這么簡單,那么看看我們?nèi)绾谓壎?在此之前,先打開相應(yīng)的頭文件.
#ifndef _GPIO_KEYS_H
#define _GPIO_KEYS_H
struct gpio_keys_button {
/* Configuration parameters */
int code; /* input event code (KEY_*, SW_*) */
int gpio;
int active_low;
char *desc;
int type; /* input event type (EV_KEY, EV_SW) */
int wakeup; /* configure the button as a wake-up source */
int debounce_interval; /* debounce ticks interval in msecs */
bool can_disable;
};
struct gpio_keys_platform_data {
struct gpio_keys_button *buttons;
int nbuttons;
unsigned int rep:1; /* enable input subsystem auto repeat */
};
#endif
其中g(shù)pio_keys_button就是我們要引用到板級相關(guān)文件的一個重要的結(jié)構(gòu)體,他的每個字段的意義,挑重點的說一說.
code字段,意思就是對應(yīng)Linux的按鍵事件,gpio要對應(yīng)gpio號,active_low是低電平有效,desc是功能描述,debounce_interval是消抖間隔.當(dāng)然這個gpio_keys_button最終要關(guān)聯(lián)到gpio_keys_platform_data里,其中nbuttons就是有的按鍵總數(shù).在板級文件中要聲明.比如做2個引腳,一個是F1,一個是F2的功能.
static struct gpio_keys_button mx28evk_buttons[] =
{
{
.gpio = MXS_PIN_TO_GPIO(MXS_PIN_ENCODE(2, 4)), /*K1 */
.code = KEY_F1,
.desc = "Button 1",
.active_low = 1,
},
{
.gpio = MXS_PIN_TO_GPIO(MXS_PIN_ENCODE(2, 6)), /*K2 */
.code = KEY_F2,
.desc = "Button 2",
.active_low = 1,
},
};
然后聲明一個組合起來的platform結(jié)構(gòu).
static struct gpio_keys_platform_data mx28evk_button_data =
{
.buttons = mx28evk_buttons,
.nbuttons = ARRAY_SIZE(mx28evk_button_data),
};
最后構(gòu)建device,因為所有初始化都只識別device.
static struct platform_device mx28evk_button_device =
{
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &mx28evk_button_data,
}
};
最后只需要注冊設(shè)備,就可以順利使用了.
static struct platform_device *mx28evk_button_device_p[] __initdata = {
&mx28evk_button_device,
};
platform_add_devices(mx28evk_button_device_p,ARRAY_SIZE(mx28evk_button_device_p));
但是,GPIO的驅(qū)動有些BUG,下次再說.可能會導(dǎo)致加載失敗,只針對MX28平臺才錯誤吧.關(guān)鍵加載如圖:
總結(jié)
以上是生活随笔為你收集整理的linux gpio按键驱动程序,Linux GPIO Key 驱动的加载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: thymeleaf There was
- 下一篇: 深度解析| 揭开中国紫砂壶背后惊人的大内