diff options
author | Alexandre Pereira da Silva <aletes.xgr@gmail.com> | 2012-08-01 01:08:45 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-08-22 01:29:50 -0400 |
commit | a2f25245269d754a9fd687a15db975271a58c5e0 (patch) | |
tree | 06f8849b00f16f657334309155a460ad53c235fd /drivers | |
parent | 2976f247989cbff1019fa3740938b0b086de5659 (diff) |
Input: gpio_keys_polled - convert to dt
Signed-off-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/keyboard/gpio_keys_polled.c | 132 |
1 files changed, 127 insertions, 5 deletions
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 2619297f384a..790895206212 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
27 | #include <linux/gpio_keys.h> | 27 | #include <linux/gpio_keys.h> |
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/of_gpio.h> | ||
28 | 30 | ||
29 | #define DRV_NAME "gpio-keys-polled" | 31 | #define DRV_NAME "gpio-keys-polled" |
30 | 32 | ||
@@ -100,6 +102,99 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev) | |||
100 | pdata->disable(bdev->dev); | 102 | pdata->disable(bdev->dev); |
101 | } | 103 | } |
102 | 104 | ||
105 | #ifdef CONFIG_OF | ||
106 | static struct gpio_keys_platform_data * __devinit | ||
107 | gpio_keys_polled_get_devtree_pdata(struct device *dev) | ||
108 | { | ||
109 | struct device_node *node, *pp; | ||
110 | struct gpio_keys_platform_data *pdata; | ||
111 | struct gpio_keys_button *button; | ||
112 | int error; | ||
113 | int nbuttons; | ||
114 | int i; | ||
115 | |||
116 | node = dev->of_node; | ||
117 | if (!node) | ||
118 | return NULL; | ||
119 | |||
120 | nbuttons = of_get_child_count(node); | ||
121 | if (nbuttons == 0) | ||
122 | return NULL; | ||
123 | |||
124 | pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), | ||
125 | GFP_KERNEL); | ||
126 | if (!pdata) { | ||
127 | error = -ENOMEM; | ||
128 | goto err_out; | ||
129 | } | ||
130 | |||
131 | pdata->buttons = (struct gpio_keys_button *)(pdata + 1); | ||
132 | |||
133 | pdata->rep = !!of_get_property(node, "autorepeat", NULL); | ||
134 | of_property_read_u32(node, "poll-interval", &pdata->poll_interval); | ||
135 | |||
136 | i = 0; | ||
137 | for_each_child_of_node(node, pp) { | ||
138 | enum of_gpio_flags flags; | ||
139 | |||
140 | if (!of_find_property(pp, "gpios", NULL)) { | ||
141 | pdata->nbuttons--; | ||
142 | dev_warn(dev, "Found button without gpios\n"); | ||
143 | continue; | ||
144 | } | ||
145 | |||
146 | button = &pdata->buttons[i++]; | ||
147 | |||
148 | button->gpio = of_get_gpio_flags(pp, 0, &flags); | ||
149 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
150 | |||
151 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | ||
152 | dev_err(dev, "Button without keycode: 0x%x\n", | ||
153 | button->gpio); | ||
154 | error = -EINVAL; | ||
155 | goto err_free_pdata; | ||
156 | } | ||
157 | |||
158 | button->desc = of_get_property(pp, "label", NULL); | ||
159 | |||
160 | if (of_property_read_u32(pp, "linux,input-type", &button->type)) | ||
161 | button->type = EV_KEY; | ||
162 | |||
163 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | ||
164 | |||
165 | if (of_property_read_u32(pp, "debounce-interval", | ||
166 | &button->debounce_interval)) | ||
167 | button->debounce_interval = 5; | ||
168 | } | ||
169 | |||
170 | if (pdata->nbuttons == 0) { | ||
171 | error = -EINVAL; | ||
172 | goto err_free_pdata; | ||
173 | } | ||
174 | |||
175 | return pdata; | ||
176 | |||
177 | err_free_pdata: | ||
178 | kfree(pdata); | ||
179 | err_out: | ||
180 | return ERR_PTR(error); | ||
181 | } | ||
182 | |||
183 | static struct of_device_id gpio_keys_polled_of_match[] = { | ||
184 | { .compatible = "gpio-keys-polled", }, | ||
185 | { }, | ||
186 | }; | ||
187 | MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); | ||
188 | |||
189 | #else | ||
190 | |||
191 | static inline struct gpio_keys_platform_data * | ||
192 | gpio_keys_polled_get_devtree_pdata(struct device *dev) | ||
193 | { | ||
194 | return NULL; | ||
195 | } | ||
196 | #endif | ||
197 | |||
103 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | 198 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) |
104 | { | 199 | { |
105 | struct device *dev = &pdev->dev; | 200 | struct device *dev = &pdev->dev; |
@@ -110,15 +205,29 @@ static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | |||
110 | int error; | 205 | int error; |
111 | int i; | 206 | int i; |
112 | 207 | ||
113 | if (!pdata || !pdata->poll_interval) | 208 | if (!pdata) { |
114 | return -EINVAL; | 209 | pdata = gpio_keys_polled_get_devtree_pdata(dev); |
210 | if (IS_ERR(pdata)) | ||
211 | return PTR_ERR(pdata); | ||
212 | if (!pdata) { | ||
213 | dev_err(dev, "missing platform data\n"); | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | if (!pdata->poll_interval) { | ||
219 | dev_err(dev, "missing poll_interval value\n"); | ||
220 | error = -EINVAL; | ||
221 | goto err_free_pdata; | ||
222 | } | ||
115 | 223 | ||
116 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + | 224 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + |
117 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), | 225 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), |
118 | GFP_KERNEL); | 226 | GFP_KERNEL); |
119 | if (!bdev) { | 227 | if (!bdev) { |
120 | dev_err(dev, "no memory for private data\n"); | 228 | dev_err(dev, "no memory for private data\n"); |
121 | return -ENOMEM; | 229 | error = -ENOMEM; |
230 | goto err_free_pdata; | ||
122 | } | 231 | } |
123 | 232 | ||
124 | poll_dev = input_allocate_polled_device(); | 233 | poll_dev = input_allocate_polled_device(); |
@@ -197,7 +306,7 @@ static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | |||
197 | /* report initial state of the buttons */ | 306 | /* report initial state of the buttons */ |
198 | for (i = 0; i < pdata->nbuttons; i++) | 307 | for (i = 0; i < pdata->nbuttons; i++) |
199 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | 308 | gpio_keys_polled_check_state(input, &pdata->buttons[i], |
200 | &bdev->data[i]); | 309 | &bdev->data[i]); |
201 | 310 | ||
202 | return 0; | 311 | return 0; |
203 | 312 | ||
@@ -209,8 +318,13 @@ err_free_gpio: | |||
209 | 318 | ||
210 | err_free_bdev: | 319 | err_free_bdev: |
211 | kfree(bdev); | 320 | kfree(bdev); |
212 | |||
213 | platform_set_drvdata(pdev, NULL); | 321 | platform_set_drvdata(pdev, NULL); |
322 | |||
323 | err_free_pdata: | ||
324 | /* If we have no platform_data, we allocated pdata dynamically. */ | ||
325 | if (!dev_get_platdata(&pdev->dev)) | ||
326 | kfree(pdata); | ||
327 | |||
214 | return error; | 328 | return error; |
215 | } | 329 | } |
216 | 330 | ||
@@ -227,6 +341,13 @@ static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) | |||
227 | 341 | ||
228 | input_free_polled_device(bdev->poll_dev); | 342 | input_free_polled_device(bdev->poll_dev); |
229 | 343 | ||
344 | /* | ||
345 | * If we had no platform_data, we allocated pdata dynamically and | ||
346 | * must free it here. | ||
347 | */ | ||
348 | if (!dev_get_platdata(&pdev->dev)) | ||
349 | kfree(pdata); | ||
350 | |||
230 | kfree(bdev); | 351 | kfree(bdev); |
231 | platform_set_drvdata(pdev, NULL); | 352 | platform_set_drvdata(pdev, NULL); |
232 | 353 | ||
@@ -239,6 +360,7 @@ static struct platform_driver gpio_keys_polled_driver = { | |||
239 | .driver = { | 360 | .driver = { |
240 | .name = DRV_NAME, | 361 | .name = DRV_NAME, |
241 | .owner = THIS_MODULE, | 362 | .owner = THIS_MODULE, |
363 | .of_match_table = of_match_ptr(gpio_keys_polled_of_match), | ||
242 | }, | 364 | }, |
243 | }; | 365 | }; |
244 | module_platform_driver(gpio_keys_polled_driver); | 366 | module_platform_driver(gpio_keys_polled_driver); |