aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/rotary_encoder.c
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2012-08-01 01:08:50 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-08-22 01:29:51 -0400
commit80c99bcd28617bd534b6f9489857235ee613c797 (patch)
treecd6c9bd5d05962927e2f21632ca60529fb4c1b54 /drivers/input/misc/rotary_encoder.c
parentce9195378299ff2f3d703937de46bdd338e780eb (diff)
Input: rotary-encoder - add DT bindings
This adds devicetree bindings to the rotary encoder driver and some documentation about how to use them. Tested on a PXA3xx platform. Signed-off-by: Daniel Mack <zonque@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/misc/rotary_encoder.c')
-rw-r--r--drivers/input/misc/rotary_encoder.c96
1 files changed, 80 insertions, 16 deletions
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index ea51265d4e04..99a49e4968d2 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -24,6 +24,8 @@
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/rotary_encoder.h> 25#include <linux/rotary_encoder.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/of_platform.h>
28#include <linux/of_gpio.h>
27 29
28#define DRV_NAME "rotary-encoder" 30#define DRV_NAME "rotary-encoder"
29 31
@@ -140,6 +142,56 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
140 return IRQ_HANDLED; 142 return IRQ_HANDLED;
141} 143}
142 144
145#ifdef CONFIG_OF
146static struct of_device_id rotary_encoder_of_match[] = {
147 { .compatible = "rotary-encoder", },
148 { },
149};
150MODULE_DEVICE_TABLE(of, rotary_encoder_of_match);
151
152static struct rotary_encoder_platform_data * __devinit
153rotary_encoder_parse_dt(struct device *dev)
154{
155 const struct of_device_id *of_id =
156 of_match_device(rotary_encoder_of_match, dev);
157 struct device_node *np = dev->of_node;
158 struct rotary_encoder_platform_data *pdata;
159 enum of_gpio_flags flags;
160
161 if (!of_id || !np)
162 return NULL;
163
164 pdata = kzalloc(sizeof(struct rotary_encoder_platform_data),
165 GFP_KERNEL);
166 if (!pdata)
167 return ERR_PTR(-ENOMEM);
168
169 of_property_read_u32(np, "rotary-encoder,steps", &pdata->steps);
170 of_property_read_u32(np, "linux,axis", &pdata->axis);
171
172 pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
173 pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
174
175 pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
176 pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
177
178 pdata->relative_axis = !!of_get_property(np,
179 "rotary-encoder,relative-axis", NULL);
180 pdata->rollover = !!of_get_property(np,
181 "rotary-encoder,rollover", NULL);
182 pdata->half_period = !!of_get_property(np,
183 "rotary-encoder,half-period", NULL);
184
185 return pdata;
186}
187#else
188static inline struct rotary_encoder_platform_data *
189rotary_encoder_parse_dt(struct device *dev)
190{
191 return NULL;
192}
193#endif
194
143static int __devinit rotary_encoder_probe(struct platform_device *pdev) 195static int __devinit rotary_encoder_probe(struct platform_device *pdev)
144{ 196{
145 struct device *dev = &pdev->dev; 197 struct device *dev = &pdev->dev;
@@ -150,14 +202,19 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
150 int err; 202 int err;
151 203
152 if (!pdata) { 204 if (!pdata) {
153 dev_err(&pdev->dev, "missing platform data\n"); 205 pdata = rotary_encoder_parse_dt(dev);
154 return -ENOENT; 206 if (IS_ERR(pdata))
207 return PTR_ERR(pdata);
208
209 if (!pdata) {
210 dev_err(dev, "missing platform data\n");
211 return -EINVAL;
212 }
155 } 213 }
156 214
157 encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL); 215 encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
158 input = input_allocate_device(); 216 input = input_allocate_device();
159 if (!encoder || !input) { 217 if (!encoder || !input) {
160 dev_err(&pdev->dev, "failed to allocate memory for device\n");
161 err = -ENOMEM; 218 err = -ENOMEM;
162 goto exit_free_mem; 219 goto exit_free_mem;
163 } 220 }
@@ -165,10 +222,9 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
165 encoder->input = input; 222 encoder->input = input;
166 encoder->pdata = pdata; 223 encoder->pdata = pdata;
167 224
168 /* create and register the input driver */
169 input->name = pdev->name; 225 input->name = pdev->name;
170 input->id.bustype = BUS_HOST; 226 input->id.bustype = BUS_HOST;
171 input->dev.parent = &pdev->dev; 227 input->dev.parent = dev;
172 228
173 if (pdata->relative_axis) { 229 if (pdata->relative_axis) {
174 input->evbit[0] = BIT_MASK(EV_REL); 230 input->evbit[0] = BIT_MASK(EV_REL);
@@ -179,17 +235,11 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
179 pdata->axis, 0, pdata->steps, 0, 1); 235 pdata->axis, 0, pdata->steps, 0, 1);
180 } 236 }
181 237
182 err = input_register_device(input);
183 if (err) {
184 dev_err(dev, "failed to register input device\n");
185 goto exit_free_mem;
186 }
187
188 /* request the GPIOs */ 238 /* request the GPIOs */
189 err = gpio_request_one(pdata->gpio_a, GPIOF_IN, dev_name(dev)); 239 err = gpio_request_one(pdata->gpio_a, GPIOF_IN, dev_name(dev));
190 if (err) { 240 if (err) {
191 dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a); 241 dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a);
192 goto exit_unregister_input; 242 goto exit_free_mem;
193 } 243 }
194 244
195 err = gpio_request_one(pdata->gpio_b, GPIOF_IN, dev_name(dev)); 245 err = gpio_request_one(pdata->gpio_b, GPIOF_IN, dev_name(dev));
@@ -225,22 +275,30 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
225 goto exit_free_irq_a; 275 goto exit_free_irq_a;
226 } 276 }
227 277
278 err = input_register_device(input);
279 if (err) {
280 dev_err(dev, "failed to register input device\n");
281 goto exit_free_irq_b;
282 }
283
228 platform_set_drvdata(pdev, encoder); 284 platform_set_drvdata(pdev, encoder);
229 285
230 return 0; 286 return 0;
231 287
288exit_free_irq_b:
289 free_irq(encoder->irq_b, encoder);
232exit_free_irq_a: 290exit_free_irq_a:
233 free_irq(encoder->irq_a, encoder); 291 free_irq(encoder->irq_a, encoder);
234exit_free_gpio_b: 292exit_free_gpio_b:
235 gpio_free(pdata->gpio_b); 293 gpio_free(pdata->gpio_b);
236exit_free_gpio_a: 294exit_free_gpio_a:
237 gpio_free(pdata->gpio_a); 295 gpio_free(pdata->gpio_a);
238exit_unregister_input:
239 input_unregister_device(input);
240 input = NULL; /* so we don't try to free it */
241exit_free_mem: 296exit_free_mem:
242 input_free_device(input); 297 input_free_device(input);
243 kfree(encoder); 298 kfree(encoder);
299 if (!dev_get_platdata(&pdev->dev))
300 kfree(pdata);
301
244 return err; 302 return err;
245} 303}
246 304
@@ -253,10 +311,15 @@ static int __devexit rotary_encoder_remove(struct platform_device *pdev)
253 free_irq(encoder->irq_b, encoder); 311 free_irq(encoder->irq_b, encoder);
254 gpio_free(pdata->gpio_a); 312 gpio_free(pdata->gpio_a);
255 gpio_free(pdata->gpio_b); 313 gpio_free(pdata->gpio_b);
314
256 input_unregister_device(encoder->input); 315 input_unregister_device(encoder->input);
257 platform_set_drvdata(pdev, NULL);
258 kfree(encoder); 316 kfree(encoder);
259 317
318 if (!dev_get_platdata(&pdev->dev))
319 kfree(pdata);
320
321 platform_set_drvdata(pdev, NULL);
322
260 return 0; 323 return 0;
261} 324}
262 325
@@ -266,6 +329,7 @@ static struct platform_driver rotary_encoder_driver = {
266 .driver = { 329 .driver = {
267 .name = DRV_NAME, 330 .name = DRV_NAME,
268 .owner = THIS_MODULE, 331 .owner = THIS_MODULE,
332 .of_match_table = of_match_ptr(rotary_encoder_of_match),
269 } 333 }
270}; 334};
271module_platform_driver(rotary_encoder_driver); 335module_platform_driver(rotary_encoder_driver);