aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/spear-keyboard.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c
index e83cab27eb56..6f287f7e1538 100644
--- a/drivers/input/keyboard/spear-keyboard.c
+++ b/drivers/input/keyboard/spear-keyboard.c
@@ -19,6 +19,7 @@
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/of.h>
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23#include <linux/pm_wakeup.h> 24#include <linux/pm_wakeup.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
@@ -63,6 +64,7 @@ struct spear_kbd {
63 unsigned int mode; 64 unsigned int mode;
64 unsigned short last_key; 65 unsigned short last_key;
65 unsigned short keycodes[NUM_ROWS * NUM_COLS]; 66 unsigned short keycodes[NUM_ROWS * NUM_COLS];
67 bool rep;
66}; 68};
67 69
68static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) 70static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
@@ -138,27 +140,49 @@ static void spear_kbd_close(struct input_dev *dev)
138 kbd->last_key = KEY_RESERVED; 140 kbd->last_key = KEY_RESERVED;
139} 141}
140 142
141static int __devinit spear_kbd_probe(struct platform_device *pdev) 143#ifdef CONFIG_OF
144static int __devinit spear_kbd_parse_dt(struct platform_device *pdev,
145 struct spear_kbd *kbd)
142{ 146{
143 const struct kbd_platform_data *pdata = pdev->dev.platform_data; 147 struct device_node *np = pdev->dev.of_node;
144 const struct matrix_keymap_data *keymap;
145 struct spear_kbd *kbd;
146 struct input_dev *input_dev;
147 struct resource *res;
148 int irq;
149 int error; 148 int error;
149 u32 val;
150 150
151 if (!pdata) { 151 if (!np) {
152 dev_err(&pdev->dev, "Invalid platform data\n"); 152 dev_err(&pdev->dev, "Missing DT data\n");
153 return -EINVAL; 153 return -EINVAL;
154 } 154 }
155 155
156 keymap = pdata->keymap; 156 if (of_property_read_bool(np, "autorepeat"))
157 if (!keymap) { 157 kbd->rep = true;
158 dev_err(&pdev->dev, "no keymap defined\n"); 158
159 return -EINVAL; 159 error = of_property_read_u32(np, "st,mode", &val);
160 if (error) {
161 dev_err(&pdev->dev, "DT: Invalid or missing mode\n");
162 return error;
160 } 163 }
161 164
165 kbd->mode = val;
166 return 0;
167}
168#else
169static inline int spear_kbd_parse_dt(struct platform_device *pdev,
170 struct spear_kbd *kbd)
171{
172 return -ENOSYS;
173}
174#endif
175
176static int __devinit spear_kbd_probe(struct platform_device *pdev)
177{
178 struct kbd_platform_data *pdata = dev_get_platdata(&pdev->dev);
179 const struct matrix_keymap_data *keymap = pdata ? pdata->keymap : NULL;
180 struct spear_kbd *kbd;
181 struct input_dev *input_dev;
182 struct resource *res;
183 int irq;
184 int error;
185
162 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 186 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
163 if (!res) { 187 if (!res) {
164 dev_err(&pdev->dev, "no keyboard resource defined\n"); 188 dev_err(&pdev->dev, "no keyboard resource defined\n");
@@ -181,7 +205,15 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev)
181 205
182 kbd->input = input_dev; 206 kbd->input = input_dev;
183 kbd->irq = irq; 207 kbd->irq = irq;
184 kbd->mode = pdata->mode; 208
209 if (!pdata) {
210 error = spear_kbd_parse_dt(pdev, kbd);
211 if (error)
212 goto err_free_mem;
213 } else {
214 kbd->mode = pdata->mode;
215 kbd->rep = pdata->rep;
216 }
185 217
186 kbd->res = request_mem_region(res->start, resource_size(res), 218 kbd->res = request_mem_region(res->start, resource_size(res),
187 pdev->name); 219 pdev->name);
@@ -221,7 +253,7 @@ static int __devinit spear_kbd_probe(struct platform_device *pdev)
221 goto err_put_clk; 253 goto err_put_clk;
222 } 254 }
223 255
224 if (pdata->rep) 256 if (kbd->rep)
225 __set_bit(EV_REP, input_dev->evbit); 257 __set_bit(EV_REP, input_dev->evbit);
226 input_set_capability(input_dev, EV_MSC, MSC_SCAN); 258 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
227 259
@@ -318,6 +350,14 @@ static int spear_kbd_resume(struct device *dev)
318 350
319static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume); 351static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume);
320 352
353#ifdef CONFIG_OF
354static const struct of_device_id spear_kbd_id_table[] = {
355 { .compatible = "st,spear300-kbd" },
356 {}
357};
358MODULE_DEVICE_TABLE(of, spear_kbd_id_table);
359#endif
360
321static struct platform_driver spear_kbd_driver = { 361static struct platform_driver spear_kbd_driver = {
322 .probe = spear_kbd_probe, 362 .probe = spear_kbd_probe,
323 .remove = __devexit_p(spear_kbd_remove), 363 .remove = __devexit_p(spear_kbd_remove),
@@ -325,6 +365,7 @@ static struct platform_driver spear_kbd_driver = {
325 .name = "keyboard", 365 .name = "keyboard",
326 .owner = THIS_MODULE, 366 .owner = THIS_MODULE,
327 .pm = &spear_kbd_pm_ops, 367 .pm = &spear_kbd_pm_ops,
368 .of_match_table = of_match_ptr(spear_kbd_id_table),
328 }, 369 },
329}; 370};
330module_platform_driver(spear_kbd_driver); 371module_platform_driver(spear_kbd_driver);