diff options
Diffstat (limited to 'drivers/input/keyboard/gpio_keys_polled.c')
-rw-r--r-- | drivers/input/keyboard/gpio_keys_polled.c | 112 |
1 files changed, 51 insertions, 61 deletions
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 432d36395f35..c9c1c8ca7267 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -23,10 +23,9 @@ | |||
23 | #include <linux/ioport.h> | 23 | #include <linux/ioport.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/gpio/consumer.h> | ||
26 | #include <linux/gpio_keys.h> | 27 | #include <linux/gpio_keys.h> |
27 | #include <linux/of.h> | 28 | #include <linux/property.h> |
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/of_gpio.h> | ||
30 | 29 | ||
31 | #define DRV_NAME "gpio-keys-polled" | 30 | #define DRV_NAME "gpio-keys-polled" |
32 | 31 | ||
@@ -51,15 +50,14 @@ static void gpio_keys_polled_check_state(struct input_dev *input, | |||
51 | int state; | 50 | int state; |
52 | 51 | ||
53 | if (bdata->can_sleep) | 52 | if (bdata->can_sleep) |
54 | state = !!gpio_get_value_cansleep(button->gpio); | 53 | state = !!gpiod_get_value_cansleep(button->gpiod); |
55 | else | 54 | else |
56 | state = !!gpio_get_value(button->gpio); | 55 | state = !!gpiod_get_value(button->gpiod); |
57 | 56 | ||
58 | if (state != bdata->last_state) { | 57 | if (state != bdata->last_state) { |
59 | unsigned int type = button->type ?: EV_KEY; | 58 | unsigned int type = button->type ?: EV_KEY; |
60 | 59 | ||
61 | input_event(input, type, button->code, | 60 | input_event(input, type, button->code, state); |
62 | !!(state ^ button->active_low)); | ||
63 | input_sync(input); | 61 | input_sync(input); |
64 | bdata->count = 0; | 62 | bdata->count = 0; |
65 | bdata->last_state = state; | 63 | bdata->last_state = state; |
@@ -102,21 +100,15 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev) | |||
102 | pdata->disable(bdev->dev); | 100 | pdata->disable(bdev->dev); |
103 | } | 101 | } |
104 | 102 | ||
105 | #ifdef CONFIG_OF | ||
106 | static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev) | 103 | static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev) |
107 | { | 104 | { |
108 | struct device_node *node, *pp; | ||
109 | struct gpio_keys_platform_data *pdata; | 105 | struct gpio_keys_platform_data *pdata; |
110 | struct gpio_keys_button *button; | 106 | struct gpio_keys_button *button; |
107 | struct fwnode_handle *child; | ||
111 | int error; | 108 | int error; |
112 | int nbuttons; | 109 | int nbuttons; |
113 | int i; | ||
114 | |||
115 | node = dev->of_node; | ||
116 | if (!node) | ||
117 | return NULL; | ||
118 | 110 | ||
119 | nbuttons = of_get_child_count(node); | 111 | nbuttons = device_get_child_node_count(dev); |
120 | if (nbuttons == 0) | 112 | if (nbuttons == 0) |
121 | return NULL; | 113 | return NULL; |
122 | 114 | ||
@@ -126,52 +118,44 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct | |||
126 | return ERR_PTR(-ENOMEM); | 118 | return ERR_PTR(-ENOMEM); |
127 | 119 | ||
128 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); | 120 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); |
129 | pdata->nbuttons = nbuttons; | ||
130 | 121 | ||
131 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); | 122 | pdata->rep = device_property_present(dev, "autorepeat"); |
132 | of_property_read_u32(node, "poll-interval", &pdata->poll_interval); | 123 | device_property_read_u32(dev, "poll-interval", &pdata->poll_interval); |
133 | 124 | ||
134 | i = 0; | 125 | device_for_each_child_node(dev, child) { |
135 | for_each_child_of_node(node, pp) { | 126 | struct gpio_desc *desc; |
136 | int gpio; | ||
137 | enum of_gpio_flags flags; | ||
138 | 127 | ||
139 | if (!of_find_property(pp, "gpios", NULL)) { | 128 | desc = devm_get_gpiod_from_child(dev, child); |
140 | pdata->nbuttons--; | 129 | if (IS_ERR(desc)) { |
141 | dev_warn(dev, "Found button without gpios\n"); | 130 | error = PTR_ERR(desc); |
142 | continue; | ||
143 | } | ||
144 | |||
145 | gpio = of_get_gpio_flags(pp, 0, &flags); | ||
146 | if (gpio < 0) { | ||
147 | error = gpio; | ||
148 | if (error != -EPROBE_DEFER) | 131 | if (error != -EPROBE_DEFER) |
149 | dev_err(dev, | 132 | dev_err(dev, |
150 | "Failed to get gpio flags, error: %d\n", | 133 | "Failed to get gpio flags, error: %d\n", |
151 | error); | 134 | error); |
135 | fwnode_handle_put(child); | ||
152 | return ERR_PTR(error); | 136 | return ERR_PTR(error); |
153 | } | 137 | } |
154 | 138 | ||
155 | button = &pdata->buttons[i++]; | 139 | button = &pdata->buttons[pdata->nbuttons++]; |
156 | 140 | button->gpiod = desc; | |
157 | button->gpio = gpio; | ||
158 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
159 | 141 | ||
160 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | 142 | if (fwnode_property_read_u32(child, "linux,code", &button->code)) { |
161 | dev_err(dev, "Button without keycode: 0x%x\n", | 143 | dev_err(dev, "Button without keycode: %d\n", |
162 | button->gpio); | 144 | pdata->nbuttons - 1); |
145 | fwnode_handle_put(child); | ||
163 | return ERR_PTR(-EINVAL); | 146 | return ERR_PTR(-EINVAL); |
164 | } | 147 | } |
165 | 148 | ||
166 | button->desc = of_get_property(pp, "label", NULL); | 149 | fwnode_property_read_string(child, "label", &button->desc); |
167 | 150 | ||
168 | if (of_property_read_u32(pp, "linux,input-type", &button->type)) | 151 | if (fwnode_property_read_u32(child, "linux,input-type", |
152 | &button->type)) | ||
169 | button->type = EV_KEY; | 153 | button->type = EV_KEY; |
170 | 154 | ||
171 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | 155 | button->wakeup = fwnode_property_present(child, "gpio-key,wakeup"); |
172 | 156 | ||
173 | if (of_property_read_u32(pp, "debounce-interval", | 157 | if (fwnode_property_read_u32(child, "debounce-interval", |
174 | &button->debounce_interval)) | 158 | &button->debounce_interval)) |
175 | button->debounce_interval = 5; | 159 | button->debounce_interval = 5; |
176 | } | 160 | } |
177 | 161 | ||
@@ -187,15 +171,6 @@ static const struct of_device_id gpio_keys_polled_of_match[] = { | |||
187 | }; | 171 | }; |
188 | MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); | 172 | MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); |
189 | 173 | ||
190 | #else | ||
191 | |||
192 | static inline struct gpio_keys_platform_data * | ||
193 | gpio_keys_polled_get_devtree_pdata(struct device *dev) | ||
194 | { | ||
195 | return NULL; | ||
196 | } | ||
197 | #endif | ||
198 | |||
199 | static int gpio_keys_polled_probe(struct platform_device *pdev) | 174 | static int gpio_keys_polled_probe(struct platform_device *pdev) |
200 | { | 175 | { |
201 | struct device *dev = &pdev->dev; | 176 | struct device *dev = &pdev->dev; |
@@ -259,7 +234,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
259 | for (i = 0; i < pdata->nbuttons; i++) { | 234 | for (i = 0; i < pdata->nbuttons; i++) { |
260 | struct gpio_keys_button *button = &pdata->buttons[i]; | 235 | struct gpio_keys_button *button = &pdata->buttons[i]; |
261 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | 236 | struct gpio_keys_button_data *bdata = &bdev->data[i]; |
262 | unsigned int gpio = button->gpio; | ||
263 | unsigned int type = button->type ?: EV_KEY; | 237 | unsigned int type = button->type ?: EV_KEY; |
264 | 238 | ||
265 | if (button->wakeup) { | 239 | if (button->wakeup) { |
@@ -267,15 +241,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) | |||
267 | return -EINVAL; | 241 | return -EINVAL; |
268 | } | 242 | } |
269 | 243 | ||
270 | error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN, | 244 | /* |
271 | button->desc ? : DRV_NAME); | 245 | * Legacy GPIO number so request the GPIO here and |
272 | if (error) { | 246 | * convert it to descriptor. |
273 | dev_err(dev, "unable to claim gpio %u, err=%d\n", | 247 | */ |
274 | gpio, error); | 248 | if (!button->gpiod && gpio_is_valid(button->gpio)) { |
275 | return error; | 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); | ||
276 | } | 263 | } |
277 | 264 | ||
278 | bdata->can_sleep = gpio_cansleep(gpio); | 265 | if (IS_ERR(button->gpiod)) |
266 | return PTR_ERR(button->gpiod); | ||
267 | |||
268 | bdata->can_sleep = gpiod_cansleep(button->gpiod); | ||
279 | bdata->last_state = -1; | 269 | bdata->last_state = -1; |
280 | bdata->threshold = DIV_ROUND_UP(button->debounce_interval, | 270 | bdata->threshold = DIV_ROUND_UP(button->debounce_interval, |
281 | pdata->poll_interval); | 271 | pdata->poll_interval); |
@@ -308,7 +298,7 @@ static struct platform_driver gpio_keys_polled_driver = { | |||
308 | .driver = { | 298 | .driver = { |
309 | .name = DRV_NAME, | 299 | .name = DRV_NAME, |
310 | .owner = THIS_MODULE, | 300 | .owner = THIS_MODULE, |
311 | .of_match_table = of_match_ptr(gpio_keys_polled_of_match), | 301 | .of_match_table = gpio_keys_polled_of_match, |
312 | }, | 302 | }, |
313 | }; | 303 | }; |
314 | module_platform_driver(gpio_keys_polled_driver); | 304 | module_platform_driver(gpio_keys_polled_driver); |