Thecus N2100 copy-on-button kernel module. Works with triggerhappy daemon.
[n2100.git] / n2100_copy_button.c
1 /*
2  *  Driver for buttons on GPIO lines not capable of generating interrupts
3  *
4  *  Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org>
5  *  Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com>
6  *
7  *  This file was based on: /drivers/input/misc/cobalt_btns.c
8  *      Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
9  *
10  *  also was based on: /drivers/input/keyboard/gpio_keys.c
11  *      Copyright 2005 Phil Blundell
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License version 2 as
15  *  published by the Free Software Foundation.
16  */
17
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/slab.h>
22 #include <linux/input.h>
23 #include <linux/input-polldev.h>
24 #include <linux/ioport.h>
25 #include <linux/gpio.h>
26 #include <linux/gpio_keys.h>
27 #include <linux/platform_device.h>
28 #include <mach/hardware.h>
29
30 #define DRV_NAME        "n2100-copy-button"
31
32 struct gpio_keys_polled_device {
33         struct input_polled_dev *poll_dev;
34         struct device *dev;
35         int gpio;
36         int last_state;
37         int count;
38         int threshold;
39 };
40
41 static struct gpio_keys_polled_device bdev;
42
43 static void gpio_keys_polled_check_state(struct input_dev *input,
44                                          struct gpio_keys_polled_device *bdata)
45 {
46         int state;
47         state = !!gpio_get_value(bdata->gpio);
48
49         if (state != bdata->last_state) {
50                 input_event(input, EV_KEY, KEY_COPY,
51                             !state);
52                 input_sync(input);
53                 bdata->count = 0;
54                 bdata->last_state = state;
55         }
56 }
57
58 static void gpio_keys_polled_poll(struct input_polled_dev *dev)
59 {
60         struct gpio_keys_polled_device *bdev = dev->private;
61         struct input_dev *input = dev->input;
62
63         gpio_keys_polled_check_state(input, bdev);
64 }
65
66 static int __devinit gpio_keys_polled_init(void)
67 {
68         struct input_polled_dev *poll_dev;
69         struct input_dev *input;
70         int error;
71         unsigned int gpio = N2100_COPY_BUTTON;
72         
73         poll_dev = input_allocate_polled_device();
74         if (!poll_dev) {
75                 pr_err("no memory for polled device\n");
76                 error = -ENOMEM;
77                 goto err_free_bdev;
78         }
79
80         poll_dev->private = &bdev;
81         poll_dev->poll = gpio_keys_polled_poll;
82         poll_dev->poll_interval = 100;
83
84         input = poll_dev->input;
85
86         input->evbit[0] = BIT(EV_KEY);
87         input->name = "copy-button";
88         input->phys = DRV_NAME"/input0";
89 //      input->dev.parent = &pdev->dev;
90
91         input->id.bustype = BUS_HOST;
92         input->id.vendor = 0x0001;
93         input->id.product = 0x0001;
94         input->id.version = 0x0100;
95
96         error = gpio_request(gpio,
97                              "N2100 copy button");
98         if (error) {
99                 pr_err("unable to claim gpio %u, err=%d\n",
100                         gpio, error);
101                 goto err_free_gpio;
102         }
103
104         error = gpio_direction_input(gpio);
105         if (error) {
106                 pr_err("unable to set direction on gpio %u, err=%d\n",
107                         gpio, error);
108                 goto err_free_gpio;
109         }
110
111         bdev.last_state = -1;
112         bdev.threshold = 2;
113
114         input_set_capability(input, EV_KEY, KEY_COPY);
115
116         bdev.poll_dev = poll_dev;
117
118         error = input_register_polled_device(poll_dev);
119         if (error) {
120                 pr_err("unable to register polled device, err=%d\n",
121                         error);
122                 goto err_free_gpio;
123         }
124
125         /* report initial state of the buttons */
126         gpio_keys_polled_check_state(input, &bdev);
127
128         return 0;
129
130 err_free_gpio:
131         gpio_free(N2100_COPY_BUTTON);
132         input_free_polled_device(poll_dev);
133
134 err_free_bdev:
135         return error;
136 }
137
138 static void __devexit gpio_keys_polled_exit(void)
139 {
140         input_unregister_polled_device(bdev.poll_dev);
141         gpio_free(N2100_COPY_BUTTON);
142         input_free_polled_device(bdev.poll_dev);
143 }
144
145 module_init(gpio_keys_polled_init);
146 module_exit(gpio_keys_polled_exit);
147
148 MODULE_LICENSE("GPL v2");
149 MODULE_AUTHOR("Roman Bazalevskiy <rvb@rvb.name>, Gabor Juhos <juhosg@openwrt.org>");
150 MODULE_DESCRIPTION("Polled GPIO Copy Buttons driver for Thecus N2100");
151 MODULE_ALIAS("platform:" DRV_NAME);