Linux驅動子系統之輸入子系統(6)-gpio-keys

來源:互聯網
上載者:User

6.Gpio-keys

6.1 概述

l  Gpio-keys是基於input子系統實現的一個通用的GPIO按鍵驅動。工程中我們常常會利用它來寫按鍵驅動。

 

l  gpio-keys驅動是基於platform來實現,platform driver(通用的部分)位於drivers/input/keyboard/gpio_keys.c,platform device通常和硬體有關,需要我們在BSP中實現。

 

6.2  通用驅動部分(platform driver)分析

l  初始化和卸載模組

static int__init gpio_keys_init(void)

{

         returnplatform_driver_register(&gpio_keys_device_driver);

}

 

static void__exit gpio_keys_exit(void)

{

         platform_driver_unregister(&gpio_keys_device_driver);

}

 

l  Platform driver結構體

static structplatform_driver gpio_keys_device_driver = {

         .probe                =gpio_keys_probe,

         .remove            = __devexit_p(gpio_keys_remove),

         .driver                ={

                   .name       ="gpio-keys", /*platform driver和platform device通過name來匹配 */

                   .owner     = THIS_MODULE,

#ifdef CONFIG_PM

                   .pm  = &gpio_keys_pm_ops,

#endif

         }

};

 

l  Gpio_key_probe函數,Probe函數在platform driver和platform device匹配上時調用

static int__devinit gpio_keys_probe(struct platform_device *pdev)

{

         input = input_allocate_device();

 

         /*設定相關屬性*/

         input->name = pdata->name ? :pdev->name;

         input->phys ="gpio-keys/input0";

         input->dev.parent =&pdev->dev;

         input->open = gpio_keys_open;

         input->close = gpio_keys_close;

 

         input->id.bustype = BUS_HOST;

         input->id.vendor = 0x0001;

         input->id.product = 0x0001;

         input->id.version = 0x0100;

 

         for (i = 0; i < pdata->nbuttons;i++) {

                   struct gpio_keys_button*button = &pdata->buttons[i];

                   struct gpio_button_data*bdata = &ddata->data[i];

                   unsigned int type =button->type ?: EV_KEY;

 

                   bdata->input = input;

                   bdata->button = button;

 

                  /*申請中斷和timer、工作隊列初始化*/

                   error = gpio_keys_setup_key(pdev, bdata, button);

 

                   input_set_capability(input, type, button->code);

         }

 

         error = sysfs_create_group(&pdev->dev.kobj,&gpio_keys_attr_group);

 

         error = input_register_device(input);

}

Probe主要完成註冊輸入裝置input_dev,在sys目錄下產生相應的檔案。

 

l  gpio_keys_isr中斷服務程式

staticirqreturn_t gpio_keys_isr(int irq, void *dev_id)

{

         struct gpio_button_data *bdata =dev_id;

         struct gpio_keys_button *button =bdata->button;

 

         if (bdata->timer_debounce)  /* 檢測是否設定了防震 */

                  /*添加一個定時器,延遲msecs_to_jiffies(button->debounce_interval)個jiffies後執行schedule_work()*/

                   mod_timer(&bdata->timer,  jiffies +msecs_to_jiffies(bdata->timer_debounce));

         else

                   schedule_work(&bdata->work);

 

         return IRQ_HANDLED;

}

中斷分為了上半部和下半部,下半部使用工作隊列來實現

 

l  中斷下半部

static voidgpio_keys_work_func(struct work_struct *work)

{

         struct gpio_button_data *bdata =

                   container_of(work, structgpio_button_data, work);

         /* 上報事件資訊 */

         gpio_keys_report_event(bdata);

}

 

6.3 與板相關的部分(platform device)

這裡以s3c2440的BSP為例,首先需要瞭解兩個結構體,用來GPIO的硬體資訊:

l  Gpio_keys_buttons

structgpio_keys_button {

         /* Configuration parameters */

         unsigned int code;   /*input event code (KEY_*, SW_*) */

         int gpio;         /* GPIO口號 */

         int active_low;    /* 低電平有效 */

         const char *desc;  /*功能描述 */

         unsigned int type;    /* input event type (EV_KEY, EV_SW, EV_ABS)*/

         int wakeup;               /* configure the button as a wake-up source */

         int debounce_interval;    /* 防震間隔*/

         bool can_disable;

         int value;           /* axis value for EV_ABS */

};

 

l  Gpio_keys_platform_data

structgpio_keys_platform_data {

         struct gpio_keys_button *buttons;  /* 指向定義好的gpio_keys_button*/

         int nbuttons;                    /* buttons成員個數 */

         unsigned int poll_interval;       /* polling interval in msecs -

                                                  for polling driver only */

         unsigned int rep:1;           /* enable input subsystem auto repeat*/

         int (*enable)(struct device *dev);

         void (*disable)(struct device *dev);

         const char *name;            /* input device name */

};

 

l  BSP中實現代碼

n  定義gpio_keys_button,填充GPIO的硬體資訊

static structgpio_keys_button mini2440_buttons[] = {

         {

                   .gpio                   = S3C2410_GPG(0),          /*K1 */

                   .code                  = KEY_F1,

                   .desc                  = "Button 1",

                   .active_low      = 1,

         },

         {

                   .gpio                   = S3C2410_GPG(3),          /*K2 */

                   .code                  = KEY_F2,

                   .desc                  = "Button 2",

                   .active_low      = 1,

         },

         {

                   .gpio                   = S3C2410_GPG(5),          /*K3 */

                   .code                  = KEY_F3,

                   .desc                  = "Button 3",

                   .active_low      = 1,

         },

         {

                   .gpio                   = S3C2410_GPG(6),          /*K4 */

                   .code                  = KEY_POWER,

                   .desc                  = "Power",

                   .active_low      = 1,

         },

         {

                   .gpio                   = S3C2410_GPG(7),          /*K5 */

                   .code                  = KEY_F5,

                   .desc                  = "Button 5",

                   .active_low      = 1,

         },

};

 

n  構造gpio_keys_platform_data

static structgpio_keys_platform_data mini2440_button_data = {

         .buttons   = mini2440_buttons,

         .nbuttons          = ARRAY_SIZE(mini2440_buttons),

};

 

n  構造platform_device

static structplatform_device mini2440_button_device = {

         .name                ="gpio-keys",

         .id              =-1,

         .dev           ={

                   .platform_data         = &mini2440_button_data,

         }

};

 

n  註冊platform_device

static structplatform_device *mini2440_devices[] __initdata = {

         ……

         &mini2440_button_device,             

};

 

static void__init mini2440_init(void)

{

         ……

         platform_add_devices(mini2440_devices,ARRAY_SIZE(mini2440_devices));

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.