]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/input/keyboard/sh_keysc.c
6218b2f024957bcffcac9d953c3e279852cdb34f
[net-next-2.6.git] / drivers / input / keyboard / sh_keysc.c
1 /*
2  * SuperH KEYSC Keypad Driver
3  *
4  * Copyright (C) 2008 Magnus Damm
5  *
6  * Based on gpio_keys.c, Copyright 2005 Phil Blundell
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/interrupt.h>
17 #include <linux/irq.h>
18 #include <linux/delay.h>
19 #include <linux/platform_device.h>
20 #include <linux/input.h>
21 #include <linux/input/sh_keysc.h>
22 #include <linux/clk.h>
23 #include <linux/io.h>
24
25 static const struct {
26         unsigned char kymd, keyout, keyin;
27 } sh_keysc_mode[] = {
28         [SH_KEYSC_MODE_1] = { 0, 6, 5 },
29         [SH_KEYSC_MODE_2] = { 1, 5, 6 },
30         [SH_KEYSC_MODE_3] = { 2, 4, 7 },
31         [SH_KEYSC_MODE_4] = { 3, 6, 6 },
32         [SH_KEYSC_MODE_5] = { 4, 6, 7 },
33 };
34
35 struct sh_keysc_priv {
36         void __iomem *iomem_base;
37         struct clk *clk;
38         unsigned long last_keys;
39         struct input_dev *input;
40         struct sh_keysc_info pdata;
41 };
42
43 #define KYCR1 0
44 #define KYCR2 1
45 #define KYINDR 2
46 #define KYOUTDR 3
47
48 #define KYCR2_IRQ_LEVEL    0x10
49 #define KYCR2_IRQ_DISABLED 0x00
50
51 static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr)
52 {
53         return ioread16(p->iomem_base + (reg_nr << 2));
54 }
55
56 static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr,
57                            unsigned long value)
58 {
59         iowrite16(value, p->iomem_base + (reg_nr << 2));
60 }
61
62 static void sh_keysc_level_mode(struct sh_keysc_priv *p,
63                                 unsigned long keys_set)
64 {
65         struct sh_keysc_info *pdata = &p->pdata;
66
67         sh_keysc_write(p, KYOUTDR, 0);
68         sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8));
69
70         if (pdata->kycr2_delay)
71                 udelay(pdata->kycr2_delay);
72 }
73
74 static irqreturn_t sh_keysc_isr(int irq, void *dev_id)
75 {
76         struct platform_device *pdev = dev_id;
77         struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
78         struct sh_keysc_info *pdata = &priv->pdata;
79         unsigned long keys, keys1, keys0, mask;
80         unsigned char keyin_set, tmp;
81         int i, k;
82
83         dev_dbg(&pdev->dev, "isr!\n");
84
85         keys1 = ~0;
86         keys0 = 0;
87
88         do {
89                 keys = 0;
90                 keyin_set = 0;
91
92                 sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED);
93
94                 for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) {
95                         sh_keysc_write(priv, KYOUTDR, 0xfff ^ (3 << (i * 2)));
96                         udelay(pdata->delay);
97                         tmp = sh_keysc_read(priv, KYINDR);
98
99                         keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i);
100                         tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1;
101                         keyin_set |= tmp;
102                 }
103
104                 sh_keysc_level_mode(priv, keyin_set);
105
106                 keys ^= ~0;
107                 keys &= (1 << (sh_keysc_mode[pdata->mode].keyin *
108                                sh_keysc_mode[pdata->mode].keyout)) - 1;
109                 keys1 &= keys;
110                 keys0 |= keys;
111
112                 dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys);
113
114         } while (sh_keysc_read(priv, KYCR2) & 0x01);
115
116         dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n",
117                 priv->last_keys, keys0, keys1);
118
119         for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
120                 k = pdata->keycodes[i];
121                 if (!k)
122                         continue;
123
124                 mask = 1 << i;
125
126                 if (!((priv->last_keys ^ keys0) & mask))
127                         continue;
128
129                 if ((keys1 | keys0) & mask) {
130                         input_event(priv->input, EV_KEY, k, 1);
131                         priv->last_keys |= mask;
132                 }
133
134                 if (!(keys1 & mask)) {
135                         input_event(priv->input, EV_KEY, k, 0);
136                         priv->last_keys &= ~mask;
137                 }
138
139         }
140         input_sync(priv->input);
141
142         return IRQ_HANDLED;
143 }
144
145 static int __devinit sh_keysc_probe(struct platform_device *pdev)
146 {
147         struct sh_keysc_priv *priv;
148         struct sh_keysc_info *pdata;
149         struct resource *res;
150         struct input_dev *input;
151         char clk_name[8];
152         int i;
153         int irq, error;
154
155         if (!pdev->dev.platform_data) {
156                 dev_err(&pdev->dev, "no platform data defined\n");
157                 error = -EINVAL;
158                 goto err0;
159         }
160
161         error = -ENXIO;
162         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
163         if (res == NULL) {
164                 dev_err(&pdev->dev, "failed to get I/O memory\n");
165                 goto err0;
166         }
167
168         irq = platform_get_irq(pdev, 0);
169         if (irq < 0) {
170                 dev_err(&pdev->dev, "failed to get irq\n");
171                 goto err0;
172         }
173
174         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
175         if (priv == NULL) {
176                 dev_err(&pdev->dev, "failed to allocate driver data\n");
177                 error = -ENOMEM;
178                 goto err0;
179         }
180
181         platform_set_drvdata(pdev, priv);
182         memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata));
183         pdata = &priv->pdata;
184
185         priv->iomem_base = ioremap_nocache(res->start, resource_size(res));
186         if (priv->iomem_base == NULL) {
187                 dev_err(&pdev->dev, "failed to remap I/O memory\n");
188                 error = -ENXIO;
189                 goto err1;
190         }
191
192         snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id);
193         priv->clk = clk_get(&pdev->dev, clk_name);
194         if (IS_ERR(priv->clk)) {
195                 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
196                 error = PTR_ERR(priv->clk);
197                 goto err2;
198         }
199
200         priv->input = input_allocate_device();
201         if (!priv->input) {
202                 dev_err(&pdev->dev, "failed to allocate input device\n");
203                 error = -ENOMEM;
204                 goto err3;
205         }
206
207         input = priv->input;
208         input->evbit[0] = BIT_MASK(EV_KEY);
209
210         input->name = pdev->name;
211         input->phys = "sh-keysc-keys/input0";
212         input->dev.parent = &pdev->dev;
213
214         input->id.bustype = BUS_HOST;
215         input->id.vendor = 0x0001;
216         input->id.product = 0x0001;
217         input->id.version = 0x0100;
218
219         input->keycode = pdata->keycodes;
220         input->keycodesize = sizeof(pdata->keycodes[0]);
221         input->keycodemax = ARRAY_SIZE(pdata->keycodes);
222
223         error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
224         if (error) {
225                 dev_err(&pdev->dev, "failed to request IRQ\n");
226                 goto err4;
227         }
228
229         for (i = 0; i < SH_KEYSC_MAXKEYS; i++)
230                 __set_bit(pdata->keycodes[i], input->keybit);
231         __clear_bit(KEY_RESERVED, input->keybit);
232
233         error = input_register_device(input);
234         if (error) {
235                 dev_err(&pdev->dev, "failed to register input device\n");
236                 goto err5;
237         }
238
239         clk_enable(priv->clk);
240
241         sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) |
242                        pdata->scan_timing);
243         sh_keysc_level_mode(priv, 0);
244
245         device_init_wakeup(&pdev->dev, 1);
246
247         return 0;
248
249  err5:
250         free_irq(irq, pdev);
251  err4:
252         input_free_device(input);
253  err3:
254         clk_put(priv->clk);
255  err2:
256         iounmap(priv->iomem_base);
257  err1:
258         platform_set_drvdata(pdev, NULL);
259         kfree(priv);
260  err0:
261         return error;
262 }
263
264 static int __devexit sh_keysc_remove(struct platform_device *pdev)
265 {
266         struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
267
268         sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED);
269
270         input_unregister_device(priv->input);
271         free_irq(platform_get_irq(pdev, 0), pdev);
272         iounmap(priv->iomem_base);
273
274         clk_disable(priv->clk);
275         clk_put(priv->clk);
276
277         platform_set_drvdata(pdev, NULL);
278         kfree(priv);
279
280         return 0;
281 }
282
283 static int sh_keysc_suspend(struct device *dev)
284 {
285         struct platform_device *pdev = to_platform_device(dev);
286         struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
287         int irq = platform_get_irq(pdev, 0);
288         unsigned short value;
289
290         value = sh_keysc_read(priv, KYCR1);
291
292         if (device_may_wakeup(dev)) {
293                 value |= 0x80;
294                 enable_irq_wake(irq);
295         } else {
296                 value &= ~0x80;
297         }
298
299         sh_keysc_write(priv, KYCR1, value);
300
301         return 0;
302 }
303
304 static int sh_keysc_resume(struct device *dev)
305 {
306         struct platform_device *pdev = to_platform_device(dev);
307         int irq = platform_get_irq(pdev, 0);
308
309         if (device_may_wakeup(dev))
310                 disable_irq_wake(irq);
311
312         return 0;
313 }
314
315 static const struct dev_pm_ops sh_keysc_dev_pm_ops = {
316         .suspend = sh_keysc_suspend,
317         .resume = sh_keysc_resume,
318 };
319
320 struct platform_driver sh_keysc_device_driver = {
321         .probe          = sh_keysc_probe,
322         .remove         = __devexit_p(sh_keysc_remove),
323         .driver         = {
324                 .name   = "sh_keysc",
325                 .pm     = &sh_keysc_dev_pm_ops,
326         }
327 };
328
329 static int __init sh_keysc_init(void)
330 {
331         return platform_driver_register(&sh_keysc_device_driver);
332 }
333
334 static void __exit sh_keysc_exit(void)
335 {
336         platform_driver_unregister(&sh_keysc_device_driver);
337 }
338
339 module_init(sh_keysc_init);
340 module_exit(sh_keysc_exit);
341
342 MODULE_AUTHOR("Magnus Damm");
343 MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver");
344 MODULE_LICENSE("GPL");