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

匿名 (未验证) 提交于 2019-12-03 00:27:02

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

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、就是在卸载模块后,个别按键还在作用中

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!