僧哥叨叨叨

量变产生质变

imx287按键处理第一篇:原始版本

我在看资料的基础上加以整改,把程序记录下来以便于日后查看。

DEMO板上的按键原理图
这里写图片描述

按键对应的芯片引脚为:
GPIO2_6 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA6 MXS_PIN_ENCODE(2, 6)
以此类推
GPIO2_5 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA5 MXS_PIN_ENCODE(2, 5)
GPIO2_4 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA4 MXS_PIN_ENCODE(2, 4)
GPIO1_18对应 /* Bank1 */ 中 #define PINID_LCD_D18 MXS_PIN_ENCODE(1, 18)
GPIO1_17对应 /* Bank1 */ 中#define PINID_LCD_D17 MXS_PIN_ENCODE(1, 17)
具体可以查看内核中芯片引脚:

linux-2.6.35.3/arch/arm/mach-mx28/mx28_pins.h
/* Bank 1 */

define PINID_LCD_D00 MXS_PIN_ENCODE(1, 0)

define PINID_LCD_D01 MXS_PIN_ENCODE(1, 1)

define PINID_LCD_D02 MXS_PIN_ENCODE(1, 2)

define PINID_LCD_D03 MXS_PIN_ENCODE(1, 3)

define PINID_LCD_D04 MXS_PIN_ENCODE(1, 4)

define PINID_LCD_D05 MXS_PIN_ENCODE(1, 5)

define PINID_LCD_D06 MXS_PIN_ENCODE(1, 6)

define PINID_LCD_D07 MXS_PIN_ENCODE(1, 7)

define PINID_LCD_D08 MXS_PIN_ENCODE(1, 8)

define PINID_LCD_D09 MXS_PIN_ENCODE(1, 9)

define PINID_LCD_D10 MXS_PIN_ENCODE(1, 10)

define PINID_LCD_D11 MXS_PIN_ENCODE(1, 11)

define PINID_LCD_D12 MXS_PIN_ENCODE(1, 12)

define PINID_LCD_D13 MXS_PIN_ENCODE(1, 13)

define PINID_LCD_D14 MXS_PIN_ENCODE(1, 14)

define PINID_LCD_D15 MXS_PIN_ENCODE(1, 15)

define PINID_LCD_D16 MXS_PIN_ENCODE(1, 16)

define PINID_LCD_D17 MXS_PIN_ENCODE(1, 17)

define PINID_LCD_D18 MXS_PIN_ENCODE(1, 18)

define PINID_LCD_D19 MXS_PIN_ENCODE(1, 19)

define PINID_LCD_D20 MXS_PIN_ENCODE(1, 20)

define PINID_LCD_D21 MXS_PIN_ENCODE(1, 21)

define PINID_LCD_D22 MXS_PIN_ENCODE(1, 22)

define PINID_LCD_D23 MXS_PIN_ENCODE(1, 23)

define PINID_LCD_RD_E MXS_PIN_ENCODE(1, 24)

define PINID_LCD_WR_RWN MXS_PIN_ENCODE(1, 25)

define PINID_LCD_RS MXS_PIN_ENCODE(1, 26)

define PINID_LCD_CS MXS_PIN_ENCODE(1, 27)

define PINID_LCD_VSYNC MXS_PIN_ENCODE(1, 28)

define PINID_LCD_HSYNC MXS_PIN_ENCODE(1, 29)

define PINID_LCD_DOTCK MXS_PIN_ENCODE(1, 30)

define PINID_LCD_ENABLE MXS_PIN_ENCODE(1, 31)

/* Bank 2 */

define PINID_SSP0_DATA0 MXS_PIN_ENCODE(2, 0)

define PINID_SSP0_DATA1 MXS_PIN_ENCODE(2, 1)

define PINID_SSP0_DATA2 MXS_PIN_ENCODE(2, 2)

define PINID_SSP0_DATA3 MXS_PIN_ENCODE(2, 3)

define PINID_SSP0_DATA4 MXS_PIN_ENCODE(2, 4)

define PINID_SSP0_DATA5 MXS_PIN_ENCODE(2, 5)

define PINID_SSP0_DATA6 MXS_PIN_ENCODE(2, 6)

define PINID_SSP0_DATA7 MXS_PIN_ENCODE(2, 7)

define PINID_SSP0_CMD MXS_PIN_ENCODE(2, 8)

define PINID_SSP0_DETECT MXS_PIN_ENCODE(2, 9)

define PINID_SSP0_SCK MXS_PIN_ENCODE(2, 10)

define PINID_SSP1_SCK MXS_PIN_ENCODE(2, 12)

define PINID_SSP1_CMD MXS_PIN_ENCODE(2, 13)

define PINID_SSP1_DATA0 MXS_PIN_ENCODE(2, 14)

define PINID_SSP1_DATA3 MXS_PIN_ENCODE(2, 15)

define PINID_SSP2_SCK MXS_PIN_ENCODE(2, 16)

define PINID_SSP2_MOSI MXS_PIN_ENCODE(2, 17)

define PINID_SSP2_MISO MXS_PIN_ENCODE(2, 18)

define PINID_SSP2_SS0 MXS_PIN_ENCODE(2, 19)

define PINID_SSP2_SS1 MXS_PIN_ENCODE(2, 20)

define PINID_SSP2_SS2 MXS_PIN_ENCODE(2, 21)

define PINID_SSP3_SCK MXS_PIN_ENCODE(2, 24)

define PINID_SSP3_MOSI MXS_PIN_ENCODE(2, 25)

define PINID_SSP3_MISO MXS_PIN_ENCODE(2, 26)

define PINID_SSP3_SS0 MXS_PIN_ENCODE(2, 27)

下面直接上代码:

imx_key.c

/*

   GPIO Driver driver for EasyARM-iMX283

*/

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/types.h>

#include <linux/sched.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/ioctl.h>

#include <linux/delay.h>

#include <linux/bcd.h>

#include <linux/capability.h>

#include <linux/rtc.h>

#include <linux/cdev.h>

#include <linux/miscdevice.h>

#include <linux/gpio.h>

#include <linux/slab.h>

#include </usr/src/linux-2.6.35.3/arch/arm/mach-mx28/mx28_pins.h>

#include <linux/list.h>

#include<linux/init.h>

#include<linux/module.h>

#include<mach/gpio.h>                                                  

#include<asm/io.h>                                                 

#include"/usr/src/linux-2.6.35.3/arch/arm/mach-mx28/mx28_pins.h"

#include "/usr/src/linux-2.6.35.3/arch/arm/plat-mxs/include/mach/pinctrl.h"

#include "/usr/src/linux-2.6.35.3/arch/arm/mach-mx28/include/mach/mx28.h"

#include<linux/fs.h>

#include <linux/io.h>

#include<asm/uaccess.h>                                     

#include<linux/miscdevice.h>                          

#include<linux/irq.h>                          

#include<linux/sched.h>                   

#include<linux/interrupt.h>              

#include<linux/timer.h>

#include <linux/input.h>

#include <linux/time.h>

#include <linux/list.h>

#include <linux/irqreturn.h>

#include <linux/errno.h>


#define GPIO_1      MXS_PIN_TO_GPIO(PINID_LCD_D17)

#define GPIO_2      MXS_PIN_TO_GPIO(PINID_LCD_D18)

#define GPIO_3      MXS_PIN_TO_GPIO(PINID_SSP0_DATA4)

#define GPIO_4      MXS_PIN_TO_GPIO(PINID_SSP0_DATA5)

#define GPIO_5      MXS_PIN_TO_GPIO(PINID_SSP0_DATA6)

struct input_dev  *inputdev;

struct imx28x_key_struct 
{

    int key_code;                      /* 按键能产生的键值*/

    int gpio;                          /* 按键连接的GPIO*/

    struct work_struct work;                       /* 按键的工作队列*/

};

struct imx28x_key_struct keys_list[] ={

    {.key_code = KEY_A, .gpio = GPIO_1},

    {.key_code = KEY_B, .gpio = GPIO_2},

    {.key_code = KEY_C, .gpio = GPIO_3},

    {.key_code = KEY_D, .gpio = GPIO_4},

    {.key_code = KEY_E, .gpio = GPIO_5}
};


static void imx28x_scankeypad(struct work_struct *_work){

        struct imx28x_key_struct *key_tmp = container_of(_work, struct imx28x_key_struct, work);

        int gpio = key_tmp->gpio;

    int code= key_tmp->key_code; 

    while(!gpio_get_value(gpio)){

        mdelay(10);

    }

    input_report_key(inputdev, code, 0); 

    input_sync(inputdev);

}


static irqreturn_t imx28x_key_intnerrupt(int irq, void *dev_id){

    int i  = (int)dev_id;

    int gpio = keys_list[i].gpio;/* 获取按键的GPIO*/

    int code = keys_list[i].key_code;

    udelay(5);

    if (gpio_get_value(gpio)) {

        return IRQ_HANDLED;

    }

    input_report_key(inputdev, code, 1);/* 先报告键按下事件*/

    input_sync(inputdev);

    schedule_work(&(keys_list[i].work));/* 提交工作队列,实现中断的下半部处理*/

    printk("key down \n");  



    //return IRQ_RETVAL(IRQ_HANDLED);

       return IRQ_HANDLED;

}

static void __exit iMX28x_key_exit(void){

    int i = 0;

    int irq_no;

    for (i = 0; i < sizeof(keys_list)/sizeof(keys_list[0]); i++) {

    irq_no = gpio_to_irq(keys_list[i].gpio);/* 为每个按键释放GPIO*/

    free_irq(irq_no, (void *)i);    

    input_unregister_device(inputdev);  

    printk("EasyARM-i.MX28x key driver remove \n");

       }

}

static int __devinit iMX28x_key_init(void)

{

    int i = 0, ret = 0;

    int irq_no = 0; 

    int code, gpio;

    inputdev = input_allocate_device(); /* 为输入设备驱动对象申请内存空间*/

    if (!inputdev) {

        return -ENOMEM;

         }

    inputdev->name  = "EasyARM-i.MX28x_key";

    set_bit(EV_KEY, inputdev->evbit);   /* 设置输入设备支持按键事件*/

    for (i = 0; i < sizeof(keys_list)/sizeof(keys_list[0]); i++) {

        code = keys_list[i].key_code;

        gpio = keys_list[i].gpio; 

        INIT_WORK(&(keys_list[i].work), imx28x_scankeypad);

        set_bit(code, inputdev->keybit); 

        gpio_free(gpio);

        ret = gpio_request(gpio, "key_gpio");

        if (ret) {

            printk("request gpio failed %d \n", gpio);

            return -EBUSY;

        } 

        gpio_direction_input(gpio); 

        irq_no  = gpio_to_irq(gpio);

        set_irq_type(gpio, IRQF_TRIGGER_FALLING);    

        ret = request_irq(irq_no, imx28x_key_intnerrupt, IRQF_DISABLED, "imx28x_key", (void *)i);

        if(ret){

            printk("request irq faile  %d!\n", irq_no);

            return -EBUSY;

        }

    }

    input_register_device(inputdev);/* 注册设备驱动*/

    printk("EasyARM-i.MX28x key driver up \n");

    return 0;

}

module_init(iMX28x_key_init);

module_exit(iMX28x_key_exit);

MODULE_AUTHOR("EasyARM28xx By jiaochengliang");

MODULE_LICENSE("Dual BSD/GPL");

MODULE_DESCRIPTION("gpio button interrupt module");



编写Makefile

PWD:=$(shell pwd)
obj-m:=imx_key.o
module-objs := imx_key.o
KERNEL_SRC = /usr/src/linux-2.6.35.3/
KDIR:=$(KERNEL_SRC)
all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
    rm -rf *.ko *.order *.symvers *.cmd *.o *.mod.c *.tmp_versions .*.cmd .tmp_versions

make一下,生成的 .ko文件挂载到板子上

insmod imx_key.ko

测试下,输出
这里写图片描述

这里的问题:1、按键去抖用延时
2、处理事件在中断中
3、就是在卸载模块后,个别按键还在作用中

阅读更多
版权声明:本文为博主原创文章,转载请注明链接,jcljob@126.com,欢迎交流 https://blog.csdn.net/liboxiu/article/details/80694969
文章标签: 按键处理 imx_key.c
个人分类: linux驱动开发
想对作者说点什么? 我来说一句

图灵关于AI的第一篇论文中文版

2009年10月21日 106KB 下载

IMX287核心板

2013年03月12日 454KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭