按键驱动insmode时gpio_keys_probe没有被调用,是什么原因?

java_hero 2010-12-17 10:31:20
/**
* hello.c
* ------Test for kernel module
*/
#include <linux/module.h>
#include <linux/version.h>

#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/random.h>

#define GPIO_KEY1 (32 * 2 + 20)
#define GPIO_KEY2 (32 * 5 + 20)

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");

struct gpio_keys_button {
/* Configuration parameters */
int code; /* input event code (KEY_*, SW_*) */
int gpio;
int active_low;
char *desc;
int type; /* input event type (EV_KEY, EV_SW) */
int wakeup; /* configure the button as a wake-up source */
};

struct gpio_keys_platform_data {
struct gpio_keys_button *buttons;
int nbuttons;
};

static struct gpio_keys_button the_buttons[] = {
{
.gpio = GPIO_KEY1,
.code = KEY_1,
.desc = "Button 0",
.active_low = 1,
},
{
.gpio = GPIO_KEY2,
.code = KEY_2,
.desc = "Button 1",
.active_low = 1,
},
};

static struct gpio_keys_platform_data the_button_data = {
.buttons = the_buttons,
.nbuttons = ARRAY_SIZE(the_buttons),
};

static struct platform_device the_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &the_button_data,
}
};

static int gpio_get_value(int gpio)
{
int rand;
get_random_bytes(&rand,sizeof(rand));
return (rand % 2);
}

static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{
int i;
struct platform_device *pdev = dev_id;
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input = platform_get_drvdata(pdev);

for (i = 0; i < pdata->nbuttons; i++)
{
struct gpio_keys_button *button = &pdata->buttons[i];
int gpio = button->gpio;

//if (irq == gpio_to_irq(gpio))
{//判断哪个键被按了?
unsigned int type = button->type ?: EV_KEY;
int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low;//记录按键状态
input_event(input, type, button->code, !!state);//汇报输入事件
input_sync(input);//等待输入事件处理完成
}
}
return IRQ_HANDLED;
}


static void gpiodev_init(void)
{
int error;
//this function will init gpio
//printk(KERN_INFO "Java gpiodev_init begin!...\n");
error = platform_device_register(&the_button_device);
printk(KERN_INFO "gpiodev_init: error = %d \n",error);
//printk(KERN_INFO "Java gpiodev_init end!...\n");
}

static int __devinit gpio_keys_probe(struct platform_device *pdev)
{
int error;
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input;
int i;

printk(KERN_INFO "Java gpio_keys_probe begin!...\n");

input = input_allocate_device();
if (!input)
{
printk(KERN_INFO "gpio_keys_probe input == NULL!...\n");
return -ENOMEM;
}

platform_set_drvdata(pdev, input);
input->name = pdev->name;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x01;
input->id.product = 0x01;
input->id.version = 0x0100;
input->evbit[0] = BIT(EV_KEY)| BIT(EV_SYN) | BIT(EV_REP);
for(i = 0;i < pdata->nbuttons;i++)
{
struct gpio_keys_button *button = &pdata->buttons[i];
int irq = button->gpio;
error = request_irq(irq,gpio_keys_isr,IRQF_SAMPLE_RANDOM | IRQF_DISABLED, button->desc ? button->desc : "gpio_keys",pdev);
if(error)
{
printk(KERN_INFO "gpio_keys_probe: request_irq Failed!...\n");
goto FAILED;
}
}
error = input_register_device(input);//注册输入设备,并和对应的handler处理函数挂钩
if (error)
{
printk(KERN_ERR "Unable to register gpio-keys input device\n");
goto FAILED;
}

printk(KERN_INFO "Java gpio_keys_probe end!...\n");
return error;

FAILED:
while (--i >= 0)
{
free_irq(pdata->buttons[i].gpio, pdev);
}
platform_set_drvdata(pdev, NULL);
input_free_device(input);
return -1;
}

static int __devexit gpio_keys_remove(struct platform_device *pdev)
{
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input = platform_get_drvdata(pdev);
int i;

device_init_wakeup(&pdev->dev, 0);

for (i = 0; i < pdata->nbuttons; i++) {
int irq = pdata->buttons[i].gpio ;//+ IRQ_GPIO_0;
free_irq(irq, pdev);
}

input_unregister_device(input);

return 0;
return 0;
}

static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
{
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
int i;

if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->nbuttons; i++) {
struct gpio_keys_button *button = &pdata->buttons[i];
if (button->wakeup) {
int irq = button->gpio;// + IRQ_GPIO_0;
enable_irq_wake(irq);
}
}
}
return 0;
}

static int gpio_keys_resume(struct platform_device *pdev)
{
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
int i;

if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->nbuttons; i++) {
struct gpio_keys_button *button = &pdata->buttons[i];
if (button->wakeup) {
int irq = button->gpio;// + IRQ_GPIO_0;
disable_irq_wake(irq);
}
}
}
return 0;
}

struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
.remove = __devexit_p(gpio_keys_remove),
.suspend = gpio_keys_suspend,
.resume = gpio_keys_resume,
.driver = {
.name = "gpiokeys",
}
};

static int gpiokeys_init(void)//(2)
{
int error;
gpiodev_init();
error = platform_driver_register(&gpio_keys_device_driver);
printk(KERN_INFO "gpiokeys_init,error = %d\n",error); //(3)
return error;
}

static void gpiokeys_exit(void)
{
printk(KERN_INFO "Goodbye, cruel world\n");
platform_device_unregister(&the_button_device);
platform_driver_unregister(&gpio_keys_device_driver);

}

module_init(gpiokeys_init);
module_exit(gpiokeys_exit);
...全文
216 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
谭海燕 2010-12-17
  • 打赏
  • 举报
回复
发帖给点建议:

LZ,贴这么大篇幅的代码,不用[code]括起来,代码是没人看的。我遇到这种直接跳过。



按键驱动,加载是否成功。。

调试下。

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧