系统自带了gpio_keys_polled.c驱动文件,硬件资源是通过设备树获取,在不修改设备树的情况下,可以直接在驱动文件中对相关的结构体进行赋值。
1、定义当前使用的IO按钮数组
static struct gpio_keys_button buttons[]={
{
.gpio = 41,//IO引脚号,根据实际情况修改
.code = KEY_1,
.desc = "KEY1",
.active_low = 1,
},
{
.gpio = 120,
.code = KEY_2,
.desc = "KEY2",
.active_low = 1,
},
{
.gpio = 121,
.code = KEY_3,
.desc = "KEY3",
.active_low = 1,
},
{
.gpio = 5,
.code = KEY_4,
.desc = "KEY4",
.active_low = 1,
},
{
.gpio = 226,
.code = KEY_5,
.desc = "KEY5",
.active_low = 1,
},
};
2、修改gpio_keys_polled_probe()函数
具体硬件资源与驱动匹配的函数为 gpio_keys_polled_get_devtree_pdata(),需要注释掉“if(!pdata)这行,否则会出现pdata->poll_interval未赋值的情况。
3、修改gpio_keys_polled_get_devtree_pdata()函数
static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev)
{
struct device_node *node, *pp;
struct gpio_keys_platform_data *pdata;
struct gpio_keys_button *button;
int error;
int nbuttons;
int i;
//不使用设备树,与之相关的代码均可注释掉
//node = dev->of_node;
//if (!node)
// return NULL;
//按键数
nbuttons = ARRAY_SIZE(buttons);//nbuttons = of_get_child_count(node);
//if (nbuttons == 0)
// return NULL;
pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button),
GFP_KERNEL);
if (!pdata) {
error = -ENOMEM;
goto err_out;
}
pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
pdata->nbuttons = nbuttons;
//扫描间隔手动赋值,注释掉从设备树获取代码
//pdata->rep = !!of_get_property(node, "autorepeat", NULL);
//of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
pdata->poll_interval = 50;//50ms
i = 0;
#if 0 //注释掉从设备树获取相关按键代码
for_each_child_of_node(node, pp) {
int gpio;
enum of_gpio_flags flags;
if (!of_find_property(pp, "gpios", NULL)) {
pdata->nbuttons--;
dev_warn(dev, "Found button without gpios\n");
continue;
}
gpio = of_get_gpio_flags(pp, 0, &flags);
if (gpio < 0) {
error = gpio;
if (error != -EPROBE_DEFER)
dev_err(dev,
"Failed to get gpio flags, error: %d\n",
error);
goto err_free_pdata;
}
button = &pdata->buttons[i++];
button->gpio = gpio;
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
if (of_property_read_u32(pp, "linux,code", &button->code)) {
dev_err(dev, "Button without keycode: 0x%x\n",
button->gpio);
error = -EINVAL;
goto err_free_pdata;
}
button->desc = of_get_property(pp, "label", NULL);
if (of_property_read_u32(pp, "linux,input-type", &button->type))
button->type = EV_KEY;
button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
if (of_property_read_u32(pp, "debounce-interval",
&button->debounce_interval))
button->debounce_interval = 5;
}
#else //使用我们定义的按键填充相关结构体
for(i=0; ibuttons[i];
button->gpio = buttons[i].gpio;
button->active_low = buttons[i].active_low;
button->type = EV_KEY;
button->code = buttons[i].code;
}
#endif
if (pdata->nbuttons == 0) {
error = -EINVAL;
goto err_free_pdata;
}
return pdata;
err_free_pdata:
kfree(pdata);
err_out:
return ERR_PTR(error);
}
static struct of_device_id gpio_keys_polled_of_match[] = {
{ .compatible = "gpio-keys-polled", },
{ },
};
4、添加platform device 注册相关代码
static struct gpio_keys_platform_data button_data={
.buttons = buttons,
.nbuttons = ARRAY_SIZE(buttons),
};
static struct platform_device button_device={
.name = "gpio-keys-polled",//此名字需与platform driver名字一致
.id = -1,
.dev = {
.platform_data = &button_data,
},
};
static int keys_dev_init(void)
{
platform_device_register(&button_device);
return 0;
}
static void keys_dev_exit(void)
{
platform_device_unregister(&button_device);
}
module_init(keys_dev_init);
module_exit(keys_dev_exit);
到此修改完毕,编译下载运行。
5、终端输入cat /proc/bus/input/devices
6、终端输入 hexdump /dev/input/event1 查看运行情况