blob: 90df4df58b076ee3feac7f50db0d3d27760f9cbb [file] [log] [blame]
Gabor Juhos0e7d0c82010-12-06 17:14:47 -08001/*
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>
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080020#include <linux/slab.h>
21#include <linux/input.h>
22#include <linux/input-polldev.h>
23#include <linux/ioport.h>
24#include <linux/platform_device.h>
25#include <linux/gpio.h>
Aaron Lu633a21d2014-10-21 23:30:25 +020026#include <linux/gpio/consumer.h>
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080027#include <linux/gpio_keys.h>
Aaron Lub26d4e22014-10-21 13:34:00 +020028#include <linux/property.h>
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080029
30#define DRV_NAME "gpio-keys-polled"
31
32struct gpio_keys_button_data {
33 int last_state;
34 int count;
35 int threshold;
36 int can_sleep;
37};
38
39struct gpio_keys_polled_dev {
40 struct input_polled_dev *poll_dev;
41 struct device *dev;
Dmitry Torokhov2976f242012-07-29 22:48:33 -070042 const struct gpio_keys_platform_data *pdata;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080043 struct gpio_keys_button_data data[0];
44};
45
46static void gpio_keys_polled_check_state(struct input_dev *input,
47 struct gpio_keys_button *button,
48 struct gpio_keys_button_data *bdata)
49{
50 int state;
51
52 if (bdata->can_sleep)
Aaron Lu633a21d2014-10-21 23:30:25 +020053 state = !!gpiod_get_value_cansleep(button->gpiod);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080054 else
Aaron Lu633a21d2014-10-21 23:30:25 +020055 state = !!gpiod_get_value(button->gpiod);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080056
57 if (state != bdata->last_state) {
58 unsigned int type = button->type ?: EV_KEY;
59
Aaron Lu633a21d2014-10-21 23:30:25 +020060 input_event(input, type, button->code, state);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080061 input_sync(input);
62 bdata->count = 0;
63 bdata->last_state = state;
64 }
65}
66
67static void gpio_keys_polled_poll(struct input_polled_dev *dev)
68{
69 struct gpio_keys_polled_dev *bdev = dev->private;
Dmitry Torokhov2976f242012-07-29 22:48:33 -070070 const struct gpio_keys_platform_data *pdata = bdev->pdata;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080071 struct input_dev *input = dev->input;
72 int i;
73
Dmitry Torokhov2976f242012-07-29 22:48:33 -070074 for (i = 0; i < pdata->nbuttons; i++) {
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080075 struct gpio_keys_button_data *bdata = &bdev->data[i];
76
77 if (bdata->count < bdata->threshold)
78 bdata->count++;
79 else
80 gpio_keys_polled_check_state(input, &pdata->buttons[i],
81 bdata);
82 }
83}
84
85static void gpio_keys_polled_open(struct input_polled_dev *dev)
86{
87 struct gpio_keys_polled_dev *bdev = dev->private;
Dmitry Torokhov2976f242012-07-29 22:48:33 -070088 const struct gpio_keys_platform_data *pdata = bdev->pdata;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080089
90 if (pdata->enable)
91 pdata->enable(bdev->dev);
92}
93
94static void gpio_keys_polled_close(struct input_polled_dev *dev)
95{
96 struct gpio_keys_polled_dev *bdev = dev->private;
Dmitry Torokhov2976f242012-07-29 22:48:33 -070097 const struct gpio_keys_platform_data *pdata = bdev->pdata;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -080098
99 if (pdata->disable)
100 pdata->disable(bdev->dev);
101}
102
Bill Pemberton5298cc42012-11-23 21:38:25 -0800103static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev)
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700104{
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700105 struct gpio_keys_platform_data *pdata;
106 struct gpio_keys_button *button;
Aaron Lub26d4e22014-10-21 13:34:00 +0200107 struct fwnode_handle *child;
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700108 int error;
109 int nbuttons;
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700110
Aaron Lub26d4e22014-10-21 13:34:00 +0200111 nbuttons = device_get_child_node_count(dev);
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700112 if (nbuttons == 0)
113 return NULL;
114
Alexander Shiyan68252632014-04-28 10:48:49 -0700115 pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * sizeof(*button),
116 GFP_KERNEL);
117 if (!pdata)
118 return ERR_PTR(-ENOMEM);
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700119
120 pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
121
Aaron Lub26d4e22014-10-21 13:34:00 +0200122 pdata->rep = device_property_present(dev, "autorepeat");
123 device_property_read_u32(dev, "poll-interval", &pdata->poll_interval);
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700124
Aaron Lub26d4e22014-10-21 13:34:00 +0200125 device_for_each_child_node(dev, child) {
126 struct gpio_desc *desc;
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700127
Aaron Lub26d4e22014-10-21 13:34:00 +0200128 desc = devm_get_gpiod_from_child(dev, child);
129 if (IS_ERR(desc)) {
130 error = PTR_ERR(desc);
Gabor Juhosd46329a2012-12-23 01:54:58 -0800131 if (error != -EPROBE_DEFER)
132 dev_err(dev,
133 "Failed to get gpio flags, error: %d\n",
134 error);
Aaron Lub26d4e22014-10-21 13:34:00 +0200135 fwnode_handle_put(child);
Alexander Shiyan68252632014-04-28 10:48:49 -0700136 return ERR_PTR(error);
Gabor Juhosd46329a2012-12-23 01:54:58 -0800137 }
138
Aaron Lub26d4e22014-10-21 13:34:00 +0200139 button = &pdata->buttons[pdata->nbuttons++];
140 button->gpiod = desc;
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700141
Aaron Lub26d4e22014-10-21 13:34:00 +0200142 if (fwnode_property_read_u32(child, "linux,code", &button->code)) {
143 dev_err(dev, "Button without keycode: %d\n",
144 pdata->nbuttons - 1);
145 fwnode_handle_put(child);
Alexander Shiyan68252632014-04-28 10:48:49 -0700146 return ERR_PTR(-EINVAL);
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700147 }
148
Aaron Lub26d4e22014-10-21 13:34:00 +0200149 fwnode_property_read_string(child, "label", &button->desc);
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700150
Aaron Lub26d4e22014-10-21 13:34:00 +0200151 if (fwnode_property_read_u32(child, "linux,input-type",
152 &button->type))
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700153 button->type = EV_KEY;
154
Aaron Lub26d4e22014-10-21 13:34:00 +0200155 button->wakeup = fwnode_property_present(child, "gpio-key,wakeup");
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700156
Aaron Lub26d4e22014-10-21 13:34:00 +0200157 if (fwnode_property_read_u32(child, "debounce-interval",
158 &button->debounce_interval))
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700159 button->debounce_interval = 5;
160 }
161
Alexander Shiyan68252632014-04-28 10:48:49 -0700162 if (pdata->nbuttons == 0)
163 return ERR_PTR(-EINVAL);
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700164
165 return pdata;
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700166}
167
Jingoo Han90c98ef2014-05-07 12:58:36 -0700168static const struct of_device_id gpio_keys_polled_of_match[] = {
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700169 { .compatible = "gpio-keys-polled", },
170 { },
171};
172MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match);
173
Bill Pemberton5298cc42012-11-23 21:38:25 -0800174static int gpio_keys_polled_probe(struct platform_device *pdev)
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800175{
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800176 struct device *dev = &pdev->dev;
Dmitry Torokhov2976f242012-07-29 22:48:33 -0700177 const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800178 struct gpio_keys_polled_dev *bdev;
179 struct input_polled_dev *poll_dev;
180 struct input_dev *input;
Alexander Shiyan68252632014-04-28 10:48:49 -0700181 size_t size;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800182 int error;
183 int i;
184
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700185 if (!pdata) {
186 pdata = gpio_keys_polled_get_devtree_pdata(dev);
187 if (IS_ERR(pdata))
188 return PTR_ERR(pdata);
189 if (!pdata) {
190 dev_err(dev, "missing platform data\n");
191 return -EINVAL;
192 }
193 }
194
195 if (!pdata->poll_interval) {
196 dev_err(dev, "missing poll_interval value\n");
Alexander Shiyan68252632014-04-28 10:48:49 -0700197 return -EINVAL;
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700198 }
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800199
Alexander Shiyan68252632014-04-28 10:48:49 -0700200 size = sizeof(struct gpio_keys_polled_dev) +
201 pdata->nbuttons * sizeof(struct gpio_keys_button_data);
202 bdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800203 if (!bdev) {
204 dev_err(dev, "no memory for private data\n");
Alexander Shiyan68252632014-04-28 10:48:49 -0700205 return -ENOMEM;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800206 }
207
Alexander Shiyan68252632014-04-28 10:48:49 -0700208 poll_dev = devm_input_allocate_polled_device(&pdev->dev);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800209 if (!poll_dev) {
210 dev_err(dev, "no memory for polled device\n");
Alexander Shiyan68252632014-04-28 10:48:49 -0700211 return -ENOMEM;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800212 }
213
214 poll_dev->private = bdev;
215 poll_dev->poll = gpio_keys_polled_poll;
216 poll_dev->poll_interval = pdata->poll_interval;
217 poll_dev->open = gpio_keys_polled_open;
218 poll_dev->close = gpio_keys_polled_close;
219
220 input = poll_dev->input;
221
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800222 input->name = pdev->name;
223 input->phys = DRV_NAME"/input0";
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800224
225 input->id.bustype = BUS_HOST;
226 input->id.vendor = 0x0001;
227 input->id.product = 0x0001;
228 input->id.version = 0x0100;
229
Alexander Shiyan1a22e162012-11-29 08:57:17 -0800230 __set_bit(EV_KEY, input->evbit);
231 if (pdata->rep)
232 __set_bit(EV_REP, input->evbit);
233
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800234 for (i = 0; i < pdata->nbuttons; i++) {
235 struct gpio_keys_button *button = &pdata->buttons[i];
236 struct gpio_keys_button_data *bdata = &bdev->data[i];
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800237 unsigned int type = button->type ?: EV_KEY;
238
239 if (button->wakeup) {
240 dev_err(dev, DRV_NAME " does not support wakeup\n");
Alexander Shiyan68252632014-04-28 10:48:49 -0700241 return -EINVAL;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800242 }
243
Aaron Lu633a21d2014-10-21 23:30:25 +0200244 /*
245 * Legacy GPIO number so request the GPIO here and
246 * convert it to descriptor.
247 */
248 if (!button->gpiod && gpio_is_valid(button->gpio)) {
249 unsigned flags = 0;
250
251 if (button->active_low)
252 flags |= GPIOF_ACTIVE_LOW;
253
254 error = devm_gpio_request_one(&pdev->dev, button->gpio,
255 flags, button->desc ? : DRV_NAME);
256 if (error) {
257 dev_err(dev, "unable to claim gpio %u, err=%d\n",
258 button->gpio, error);
259 return error;
260 }
261
262 button->gpiod = gpio_to_desc(button->gpio);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800263 }
264
Aaron Lu633a21d2014-10-21 23:30:25 +0200265 if (IS_ERR(button->gpiod))
266 return PTR_ERR(button->gpiod);
267
268 bdata->can_sleep = gpiod_cansleep(button->gpiod);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800269 bdata->last_state = -1;
270 bdata->threshold = DIV_ROUND_UP(button->debounce_interval,
271 pdata->poll_interval);
272
273 input_set_capability(input, type, button->code);
274 }
275
276 bdev->poll_dev = poll_dev;
277 bdev->dev = dev;
278 bdev->pdata = pdata;
279 platform_set_drvdata(pdev, bdev);
280
281 error = input_register_polled_device(poll_dev);
282 if (error) {
283 dev_err(dev, "unable to register polled device, err=%d\n",
284 error);
Alexander Shiyan68252632014-04-28 10:48:49 -0700285 return error;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800286 }
287
288 /* report initial state of the buttons */
289 for (i = 0; i < pdata->nbuttons; i++)
290 gpio_keys_polled_check_state(input, &pdata->buttons[i],
Alexandre Pereira da Silvaa2f25242012-07-31 22:08:45 -0700291 &bdev->data[i]);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800292
293 return 0;
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800294}
295
296static struct platform_driver gpio_keys_polled_driver = {
297 .probe = gpio_keys_polled_probe,
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800298 .driver = {
299 .name = DRV_NAME,
Aaron Lub26d4e22014-10-21 13:34:00 +0200300 .of_match_table = gpio_keys_polled_of_match,
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800301 },
302};
JJ Ding5146c842011-11-29 11:08:39 -0800303module_platform_driver(gpio_keys_polled_driver);
Gabor Juhos0e7d0c82010-12-06 17:14:47 -0800304
305MODULE_LICENSE("GPL v2");
306MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
307MODULE_DESCRIPTION("Polled GPIO Buttons driver");
308MODULE_ALIAS("platform:" DRV_NAME);