gpio matrix keypad linux driver


Linuxkernel & device driver programming

Cross-Referenced Linuxand Device DriverCode

[ source navigation ] [diffmarkup ] [ identifiersearch ] [ freetextsearch ] [ filesearch ]

Version: [ 2.6.11.8 ][ 2.6.25 ][ 2.6.25.8 ][ 2.6.31.13 ] Architecture:[ i386 ]

  1 /*
  2  *  GPIO driven matrix keyboard driver
  3  *
  4  *  Copyright (c) 2008 Marek Vasut <[email protected]>
  5  *
  6  *  Based on corgikbd.c
  7  *
  8  *  This program is free software; you can redistribute it and/or modify
  9  *  it under the terms of the GNU General Public License version 2 as
 10  *  published by the Free Software Foundation.
 11  *
 12  */
 13 
 14 #include <linux/types.h>
 15 #include <linux/delay.h>
 16 #include <linux/platform_device.h>
 17 #include <linux/init.h>
 18 #include <linux/input.h>
 19 #include <linux/irq.h>
 20 #include <linux/interrupt.h>
 21 #include <linux/jiffies.h>
 22 #include <linux/module.h>
 23 #include <linux/gpio.h>
 24 #include <linux/input/matrix_keypad.h>
 25 
 26 struct matrix_keypad {
 27         const struct matrix_keypad_platform_data *pdata;
 28         struct input_dev *input_dev;
 29         unsigned short *keycodes;
 30         unsigned int row_shift;
 31 
 32         uint32_t last_key_state[MATRIX_MAX_COLS];
 33         struct delayed_work work;
 34         bool scan_pending;
 35         bool stopped;
 36         spinlock_t lock;
 37 };
 38 
 39 /*
 40  * NOTE: normally the GPIO has to be put into HiZ when de-activated to cause
 41  * minmal side effect when scanning other columns, here it is configured to
 42  * be input, and it should work on most platforms.
 43  */
 44 static void __activate_col(const struct matrix_keypad_platform_data *pdata,
 45                            int col, bool on)
 46 {
 47         bool level_on = !pdata->active_low;
 48 
 49         if (on) {
 50                 gpio_direction_output(pdata->col_gpios[col], level_on);
 51         } else {
 52                 gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
 53                 gpio_direction_input(pdata->col_gpios[col]);
 54         }
 55 }
 56 
 57 static void activate_col(const struct matrix_keypad_platform_data *pdata,
 58                          int col, bool on)
 59 {
 60         __activate_col(pdata, col, on);
 61 
 62         if (on && pdata->col_scan_delay_us)
 63                 udelay(pdata->col_scan_delay_us);
 64 }
 65 
 66 static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
 67                               bool on)
 68 {
 69         int col;
 70 
 71         for (col = 0; col < pdata->num_col_gpios; col++)
 72                 __activate_col(pdata, col, on);
 73 }
 74 
 75 static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
 76                          int row)
 77 {
 78         return gpio_get_value_cansleep(pdata->row_gpios[row]) ?
 79                         !pdata->active_low : pdata->active_low;
 80 }
 81 
 82 static void enable_row_irqs(struct matrix_keypad *keypad)
 83 {
 84         const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 85         int i;
 86 
 87         for (i = 0; i < pdata->num_row_gpios; i++)
			//使能中断。
 88                 enable_irq(gpio_to_irq(pdata->row_gpios[i]));
 89 }
 90 
 91 static void disable_row_irqs(struct matrix_keypad *keypad)
 92 {
 93         const struct matrix_keypad_platform_data *pdata = keypad->pdata;
 94         int i;
 95 
 96         for (i = 0; i < pdata->num_row_gpios; i++)

			这个是关中断,记得以前使用disable_irq()时有时候会出错。
			所以使用disable_irq_nosync()会更好友好一些。
 97                 disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i]));
 98 }
 99 

使用input子系统的一般流程为:
input_allocate_device()申请一个input_dev设备――>
初始化该input_dev――>
input_register_device()向子系统注册该设备――>
中断时input_event()向子系 统报告事件。

100 /*
101  * This gets the keys from keyboard and reports it to input subsystem
102  */
	这就是延后的工作的函数体,依次进行列行扫描来判断哪个按键被按下,然后使用report_key()向
	input core提交按键事件。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值