Loading drivers/input/keyboard/gpio_keys.c +69 −20 Original line number Diff line number Diff line Loading @@ -26,23 +26,54 @@ #include <asm/gpio.h> struct gpio_button_data { struct gpio_keys_button *button; struct input_dev *input; struct timer_list timer; }; struct gpio_keys_drvdata { struct input_dev *input; struct gpio_button_data data[0]; }; static void gpio_keys_report_event(struct gpio_keys_button *button, struct input_dev *input) { unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; input_event(input, type, button->code, !!state); input_sync(input); } static void gpio_check_button(unsigned long _data) { struct gpio_button_data *data = (struct gpio_button_data *)_data; gpio_keys_report_event(data->button, data->input); } 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); struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); int i; 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; if (irq == gpio_to_irq(button->gpio)) { struct gpio_button_data *bdata = &ddata->data[i]; if (button->debounce_interval) mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(button->debounce_interval)); else gpio_keys_report_event(button, bdata->input); input_event(input, type, button->code, !!state); input_sync(input); return IRQ_HANDLED; } } Loading @@ -53,17 +84,21 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) static int __devinit gpio_keys_probe(struct platform_device *pdev) { struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct gpio_keys_drvdata *ddata; struct input_dev *input; int i, error; int wakeup = 0; ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + pdata->nbuttons * sizeof(struct gpio_button_data), GFP_KERNEL); input = input_allocate_device(); if (!input) return -ENOMEM; platform_set_drvdata(pdev, input); if (!ddata || !input) { error = -ENOMEM; goto fail1; } input->evbit[0] = BIT_MASK(EV_KEY); platform_set_drvdata(pdev, ddata); input->name = pdev->name; input->phys = "gpio-keys/input0"; Loading @@ -74,16 +109,23 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input->id.product = 0x0001; input->id.version = 0x0100; ddata->input = input; for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_button_data *bdata = &ddata->data[i]; int irq; unsigned int type = button->type ?: EV_KEY; bdata->input = input; setup_timer(&bdata->timer, gpio_check_button, (unsigned long)bdata); error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); if (error < 0) { pr_err("gpio-keys: failed to request GPIO %d," " error %d\n", button->gpio, error); goto fail; goto fail2; } error = gpio_direction_input(button->gpio); Loading @@ -92,7 +134,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) " direction for GPIO %d, error %d\n", button->gpio, error); gpio_free(button->gpio); goto fail; goto fail2; } irq = gpio_to_irq(button->gpio); Loading @@ -102,7 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) " for GPIO %d, error %d\n", button->gpio, error); gpio_free(button->gpio); goto fail; goto fail2; } error = request_irq(irq, gpio_keys_isr, Loading @@ -114,7 +156,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) pr_err("gpio-keys: Unable to claim irq %d; error %d\n", irq, error); gpio_free(button->gpio); goto fail; goto fail2; } if (button->wakeup) Loading @@ -127,21 +169,25 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) if (error) { pr_err("gpio-keys: Unable to register input device, " "error: %d\n", error); goto fail; goto fail2; } device_init_wakeup(&pdev->dev, wakeup); return 0; fail: fail2: while (--i >= 0) { free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); if (pdata->buttons[i].debounce_interval) del_timer_sync(&ddata->data[i].timer); gpio_free(pdata->buttons[i].gpio); } platform_set_drvdata(pdev, NULL); fail1: input_free_device(input); kfree(ddata); return error; } Loading @@ -149,7 +195,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) 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); struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); struct input_dev *input = ddata->input; int i; device_init_wakeup(&pdev->dev, 0); Loading @@ -157,6 +204,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) for (i = 0; i < pdata->nbuttons; i++) { int irq = gpio_to_irq(pdata->buttons[i].gpio); free_irq(irq, pdev); if (pdata->buttons[i].debounce_interval) del_timer_sync(&ddata->data[i].timer); gpio_free(pdata->buttons[i].gpio); } Loading include/linux/gpio_keys.h +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ struct gpio_keys_button { char *desc; int type; /* input event type (EV_KEY, EV_SW) */ int wakeup; /* configure the button as a wake-up source */ int debounce_interval; /* debounce ticks interval in msecs */ }; struct gpio_keys_platform_data { Loading Loading
drivers/input/keyboard/gpio_keys.c +69 −20 Original line number Diff line number Diff line Loading @@ -26,23 +26,54 @@ #include <asm/gpio.h> struct gpio_button_data { struct gpio_keys_button *button; struct input_dev *input; struct timer_list timer; }; struct gpio_keys_drvdata { struct input_dev *input; struct gpio_button_data data[0]; }; static void gpio_keys_report_event(struct gpio_keys_button *button, struct input_dev *input) { unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; input_event(input, type, button->code, !!state); input_sync(input); } static void gpio_check_button(unsigned long _data) { struct gpio_button_data *data = (struct gpio_button_data *)_data; gpio_keys_report_event(data->button, data->input); } 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); struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); int i; 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; if (irq == gpio_to_irq(button->gpio)) { struct gpio_button_data *bdata = &ddata->data[i]; if (button->debounce_interval) mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(button->debounce_interval)); else gpio_keys_report_event(button, bdata->input); input_event(input, type, button->code, !!state); input_sync(input); return IRQ_HANDLED; } } Loading @@ -53,17 +84,21 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) static int __devinit gpio_keys_probe(struct platform_device *pdev) { struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct gpio_keys_drvdata *ddata; struct input_dev *input; int i, error; int wakeup = 0; ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + pdata->nbuttons * sizeof(struct gpio_button_data), GFP_KERNEL); input = input_allocate_device(); if (!input) return -ENOMEM; platform_set_drvdata(pdev, input); if (!ddata || !input) { error = -ENOMEM; goto fail1; } input->evbit[0] = BIT_MASK(EV_KEY); platform_set_drvdata(pdev, ddata); input->name = pdev->name; input->phys = "gpio-keys/input0"; Loading @@ -74,16 +109,23 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input->id.product = 0x0001; input->id.version = 0x0100; ddata->input = input; for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_button_data *bdata = &ddata->data[i]; int irq; unsigned int type = button->type ?: EV_KEY; bdata->input = input; setup_timer(&bdata->timer, gpio_check_button, (unsigned long)bdata); error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); if (error < 0) { pr_err("gpio-keys: failed to request GPIO %d," " error %d\n", button->gpio, error); goto fail; goto fail2; } error = gpio_direction_input(button->gpio); Loading @@ -92,7 +134,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) " direction for GPIO %d, error %d\n", button->gpio, error); gpio_free(button->gpio); goto fail; goto fail2; } irq = gpio_to_irq(button->gpio); Loading @@ -102,7 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) " for GPIO %d, error %d\n", button->gpio, error); gpio_free(button->gpio); goto fail; goto fail2; } error = request_irq(irq, gpio_keys_isr, Loading @@ -114,7 +156,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) pr_err("gpio-keys: Unable to claim irq %d; error %d\n", irq, error); gpio_free(button->gpio); goto fail; goto fail2; } if (button->wakeup) Loading @@ -127,21 +169,25 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) if (error) { pr_err("gpio-keys: Unable to register input device, " "error: %d\n", error); goto fail; goto fail2; } device_init_wakeup(&pdev->dev, wakeup); return 0; fail: fail2: while (--i >= 0) { free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev); if (pdata->buttons[i].debounce_interval) del_timer_sync(&ddata->data[i].timer); gpio_free(pdata->buttons[i].gpio); } platform_set_drvdata(pdev, NULL); fail1: input_free_device(input); kfree(ddata); return error; } Loading @@ -149,7 +195,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) 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); struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); struct input_dev *input = ddata->input; int i; device_init_wakeup(&pdev->dev, 0); Loading @@ -157,6 +204,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) for (i = 0; i < pdata->nbuttons; i++) { int irq = gpio_to_irq(pdata->buttons[i].gpio); free_irq(irq, pdev); if (pdata->buttons[i].debounce_interval) del_timer_sync(&ddata->data[i].timer); gpio_free(pdata->buttons[i].gpio); } Loading
include/linux/gpio_keys.h +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ struct gpio_keys_button { char *desc; int type; /* input event type (EV_KEY, EV_SW) */ int wakeup; /* configure the button as a wake-up source */ int debounce_interval; /* debounce ticks interval in msecs */ }; struct gpio_keys_platform_data { Loading