以下适用于android、linux驱动。
1、把行扫IO设为常规按键模式,用来触发动作。此时设定初始的按键上报值。把列扫作为IO输出。这里在dtsi里设定:
&soc {
gpio_keys {
compatible = "gpio-keys";
input-name = "gpio-keys";
pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
pinctrl-0 = <&gpio_key_active>;
pinctrl-1 = <&gpio_key_suspend>;
//列扫5个
qcom,keyboard_c0 = <&tlmm 1 0>;
qcom,keyboard_c1 = <&tlmm 2 0>;
qcom,keyboard_c2 = <&tlmm 3 0>;
qcom,keyboard_c3 = <&tlmm 4 0>;
qcom,keyboard_c4 = <&tlmm 5 0>;
vol_up {
label = "volume_up";
gpios = <&tlmm 91 0x1>;
linux,input-type = <1>;
linux,code = <115>;
debounce-interval = <15>;
};
//行扫6个
r0 {
label = "r0";
gpios = <&tlmm 6 0x1>;
linux,input-type = <1>;
linux,code = <70>;
//gpio-key,wakeup;
debounce-interval = <15>;
};
r1 {
label = "r1";
gpios = <&tlmm 7 0x1>;
linux,input-type = <1>;
linux,code = <75>;
//gpio-key,wakeup;
debounce-interval = <15>;
};
r2 {
label = "r2";
gpios = <&tlmm 8 0x1>;
linux,input-type = <1>;
linux,code = <80>;
//gpio-key,wakeup;
debounce-interval = <15>;
};
r3 {
label = "r3";
gpios = <&tlmm 9 0x1>;
linux,input-type = <1>;
linux,code = <85>;
// gpio-key,wakeup;
debounce-interval = <15>;
};
r4 {
label = "r4";
gpios = <&tlmm 10 0x1>;
linux,input-type = <1>;
linux,code = <90>;
gpio-key,wakeup;
debounce-interval = <15>;
};
r5 {
label = "r5";
gpios = <&tlmm 11 0x1>;
linux,input-type = <1>;
linux,code = <95>;
//gpio-key,wakeup;
debounce-interval = <15>;
};
};
};
2、设计一个矩阵扫描程序,得到一个按键值。
3、用步聚2得到的按键值去替换步聚1设定的那个初始的按键值,以达到区分同一列不同行按键的上报值。
以上两步在gpio-key.c的gpio_keys_gpio_report_event增加以下修改代码:
static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
{
const struct gpio_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = button->type ?: EV_KEY;
int state,code;
state = (__gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
code = button->code;
if(code>=70 && code<=100)
{
stop_flag1 = 0 ;
disable_irq(button->gpio);
if(code_flag1)
{
gpio_set_value_cansleep(1, 0);
gpio_set_value_cansleep(2, 1);
gpio_set_value_cansleep(3, 1);
gpio_set_value_cansleep(4, 1);
gpio_set_value_cansleep(5, 1);
mdelay(1);
if(!gpio_get_value_cansleep(button->gpio)){
mdelay(10);
if(!gpio_get_value_cansleep(button->gpio))
{
keycode_save = code;
code_flag2 = 0;
code_flag3 = 0;
code_flag4 = 0;
code_flag5 = 0;
stop_flag1 = 0 ;
}
}
}
if(code_flag2)
{
gpio_set_value_cansleep(1,1);
gpio_set_value_cansleep(2, 0);
gpio_set_value_cansleep(3, 1);
gpio_set_value_cansleep(4, 1);
gpio_set_value_cansleep(5, 1);
mdelay(1);
if(!gpio_get_value_cansleep(button->gpio)){
mdelay(10);
if(!gpio_get_value_cansleep(button->gpio))
{
code = code + 1 ;
keycode_save = code;
code_flag1 = 0;
code_flag3 = 0;
code_flag4 = 0;
code_flag5 = 0;
stop_flag1 = 0 ;
}
}
}
if(code_flag3)
{
gpio_set_value_cansleep(1,1);
gpio_set_value_cansleep(2, 1);
gpio_set_value_cansleep(3, 0);
gpio_set_value_cansleep(4, 1);
gpio_set_value_cansleep(5, 1);
mdelay(1);
if(!gpio_get_value_cansleep(button->gpio)){
mdelay(10);
if(!gpio_get_value_cansleep(button->gpio))
{
code = code + 2 ;
keycode_save = code;
code_flag1 = 0;
code_flag2 = 0;
code_flag4 = 0;
code_flag5 = 0;
stop_flag1 = 0 ;
}
}
}
if(code_flag4)
{
gpio_set_value_cansleep(1,1);
gpio_set_value_cansleep(2, 1);
gpio_set_value_cansleep(3, 1);
gpio_set_value_cansleep(4, 0);
gpio_set_value_cansleep(5, 1);
mdelay(1);
if(!gpio_get_value_cansleep(button->gpio)){
mdelay(10);
if(!gpio_get_value_cansleep(button->gpio))
{
code = code + 3 ;
keycode_save = code;
code_flag1 = 0;
code_flag2 = 0;
code_flag3 = 0;
code_flag5 = 0;
stop_flag1 = 0 ;
}
}
}
if(code_flag5)
{
gpio_set_value_cansleep(1,1);
gpio_set_value_cansleep(2, 1);
gpio_set_value_cansleep(3, 1);
gpio_set_value_cansleep(4, 1);
gpio_set_value_cansleep(5, 0);
mdelay(1);
if(!gpio_get_value_cansleep(button->gpio)){
mdelay(10);
if(!gpio_get_value_cansleep(button->gpio))
{
code = code + 4 ;
keycode_save = code;
code_flag1 = 0;
code_flag2 = 0;
code_flag3 = 0;
code_flag4 = 0;
stop_flag1 = 0 ;
}
}
}
if(stop_flag2 == 0)
{
stop_flag2=2;
if (type == EV_ABS) {
if (state)
input_event(input, type, code, button->value);
} else {
input_event(input, type, code, !!state);
}
input_sync(input);
}
if(gpio_get_value_cansleep(button->gpio)){
mdelay(10);
if(gpio_get_value_cansleep(button->gpio))
{
gpio_set_value_cansleep(1,0);
gpio_set_value_cansleep(2, 0);
gpio_set_value_cansleep(3, 0);
gpio_set_value_cansleep(4, 0);
gpio_set_value_cansleep(5, 0);
mdelay(1);
code = keycode_save ;
stop_flag1 = 1 ;
stop_flag2 =0 ;
}
}
}
if(stop_flag1 == 1)
{
if (type == EV_ABS) {
if (state)
input_event(input, type, code, button->value);
} else {
input_event(input, type, code, !!state);
}
input_sync(input);
code_flag1 = 1;
code_flag2 = 1;
code_flag3 = 1;
code_flag4 = 1;
code_flag5 = 1;
}
}
4、查看getevent;
130|msm8937_64:/ # getevent
add device 1: /dev/input/event5
name: "msm8917-sku5-snd-card Button Jack"
add device 2: /dev/input/event4
name: "msm8917-sku5-snd-card Headset Jack"
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 3: /dev/input/event2
name: "hbtp_vm"
add device 4: /dev/input/event1
name: "goodix-ts"
add device 5: /dev/input/event0
name: "qpnp_pon"
could not get driver version for /dev/input/mice, Not a typewriter
add device 6: /dev/input/event3
name: "gpio-keys"
/dev/input/event3: 0001 004b 00000001
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 004b 00000000
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0053 00000001
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0053 00000000
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0053 00000001
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0053 00000000
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0055 00000001
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 0055 00000000
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 005f 00000001
/dev/input/event3: 0000 0000 00000000
/dev/input/event3: 0001 005f 00000000
/dev/input/event3: 0000 0000 00000000
5、在gpio-keys.kl建立按键映射表。搞定!