]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/input/keyboard/st-keyscan.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
[karo-tx-linux.git] / drivers / input / keyboard / st-keyscan.c
1 /*
2  * STMicroelectronics Key Scanning driver
3  *
4  * Copyright (c) 2014 STMicroelectonics Ltd.
5  * Author: Stuart Menefy <stuart.menefy@st.com>
6  *
7  * Based on sh_keysc.c, copyright 2008 Magnus Damm
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/module.h>
15 #include <linux/interrupt.h>
16 #include <linux/platform_device.h>
17 #include <linux/clk.h>
18 #include <linux/io.h>
19 #include <linux/input/matrix_keypad.h>
20
21 #define ST_KEYSCAN_MAXKEYS 16
22
23 #define KEYSCAN_CONFIG_OFF              0x0
24 #define KEYSCAN_CONFIG_ENABLE           0x1
25 #define KEYSCAN_DEBOUNCE_TIME_OFF       0x4
26 #define KEYSCAN_MATRIX_STATE_OFF        0x8
27 #define KEYSCAN_MATRIX_DIM_OFF          0xc
28 #define KEYSCAN_MATRIX_DIM_X_SHIFT      0x0
29 #define KEYSCAN_MATRIX_DIM_Y_SHIFT      0x2
30
31 struct st_keyscan {
32         void __iomem *base;
33         int irq;
34         struct clk *clk;
35         struct input_dev *input_dev;
36         unsigned long last_state;
37         unsigned int n_rows;
38         unsigned int n_cols;
39         unsigned int debounce_us;
40 };
41
42 static irqreturn_t keyscan_isr(int irq, void *dev_id)
43 {
44         struct st_keyscan *keypad = dev_id;
45         unsigned short *keycode = keypad->input_dev->keycode;
46         unsigned long state, change;
47         int bit_nr;
48
49         state = readl(keypad->base + KEYSCAN_MATRIX_STATE_OFF) & 0xffff;
50         change = keypad->last_state ^ state;
51         keypad->last_state = state;
52
53         for_each_set_bit(bit_nr, &change, BITS_PER_LONG)
54                 input_report_key(keypad->input_dev,
55                                  keycode[bit_nr], state & BIT(bit_nr));
56
57         input_sync(keypad->input_dev);
58
59         return IRQ_HANDLED;
60 }
61
62 static int keyscan_start(struct st_keyscan *keypad)
63 {
64         int error;
65
66         error = clk_enable(keypad->clk);
67         if (error)
68                 return error;
69
70         writel(keypad->debounce_us * (clk_get_rate(keypad->clk) / 1000000),
71                keypad->base + KEYSCAN_DEBOUNCE_TIME_OFF);
72
73         writel(((keypad->n_cols - 1) << KEYSCAN_MATRIX_DIM_X_SHIFT) |
74                ((keypad->n_rows - 1) << KEYSCAN_MATRIX_DIM_Y_SHIFT),
75                keypad->base + KEYSCAN_MATRIX_DIM_OFF);
76
77         writel(KEYSCAN_CONFIG_ENABLE, keypad->base + KEYSCAN_CONFIG_OFF);
78
79         return 0;
80 }
81
82 static void keyscan_stop(struct st_keyscan *keypad)
83 {
84         writel(0, keypad->base + KEYSCAN_CONFIG_OFF);
85
86         clk_disable(keypad->clk);
87 }
88
89 static int keyscan_open(struct input_dev *dev)
90 {
91         struct st_keyscan *keypad = input_get_drvdata(dev);
92
93         return keyscan_start(keypad);
94 }
95
96 static void keyscan_close(struct input_dev *dev)
97 {
98         struct st_keyscan *keypad = input_get_drvdata(dev);
99
100         keyscan_stop(keypad);
101 }
102
103 static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data)
104 {
105         struct device *dev = keypad_data->input_dev->dev.parent;
106         struct device_node *np = dev->of_node;
107         int error;
108
109         error = matrix_keypad_parse_properties(dev, &keypad_data->n_rows,
110                                                &keypad_data->n_cols);
111         if (error) {
112                 dev_err(dev, "failed to parse keypad params\n");
113                 return error;
114         }
115
116         of_property_read_u32(np, "st,debounce-us", &keypad_data->debounce_us);
117
118         dev_dbg(dev, "n_rows=%d n_col=%d debounce=%d\n",
119                 keypad_data->n_rows, keypad_data->n_cols,
120                 keypad_data->debounce_us);
121
122         return 0;
123 }
124
125 static int keyscan_probe(struct platform_device *pdev)
126 {
127         struct st_keyscan *keypad_data;
128         struct input_dev *input_dev;
129         struct resource *res;
130         int error;
131
132         if (!pdev->dev.of_node) {
133                 dev_err(&pdev->dev, "no DT data present\n");
134                 return -EINVAL;
135         }
136
137         keypad_data = devm_kzalloc(&pdev->dev, sizeof(*keypad_data),
138                                    GFP_KERNEL);
139         if (!keypad_data)
140                 return -ENOMEM;
141
142         input_dev = devm_input_allocate_device(&pdev->dev);
143         if (!input_dev) {
144                 dev_err(&pdev->dev, "failed to allocate the input device\n");
145                 return -ENOMEM;
146         }
147
148         input_dev->name = pdev->name;
149         input_dev->phys = "keyscan-keys/input0";
150         input_dev->dev.parent = &pdev->dev;
151         input_dev->open = keyscan_open;
152         input_dev->close = keyscan_close;
153
154         input_dev->id.bustype = BUS_HOST;
155
156         error = keypad_matrix_key_parse_dt(keypad_data);
157         if (error)
158                 return error;
159
160         error = matrix_keypad_build_keymap(NULL, NULL,
161                                            keypad_data->n_rows,
162                                            keypad_data->n_cols,
163                                            NULL, input_dev);
164         if (error) {
165                 dev_err(&pdev->dev, "failed to build keymap\n");
166                 return error;
167         }
168
169         input_set_drvdata(input_dev, keypad_data);
170
171         keypad_data->input_dev = input_dev;
172
173         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
174         keypad_data->base = devm_ioremap_resource(&pdev->dev, res);
175         if (IS_ERR(keypad_data->base))
176                 return PTR_ERR(keypad_data->base);
177
178         keypad_data->clk = devm_clk_get(&pdev->dev, NULL);
179         if (IS_ERR(keypad_data->clk)) {
180                 dev_err(&pdev->dev, "cannot get clock\n");
181                 return PTR_ERR(keypad_data->clk);
182         }
183
184         error = clk_enable(keypad_data->clk);
185         if (error) {
186                 dev_err(&pdev->dev, "failed to enable clock\n");
187                 return error;
188         }
189
190         keyscan_stop(keypad_data);
191
192         keypad_data->irq = platform_get_irq(pdev, 0);
193         if (keypad_data->irq < 0) {
194                 dev_err(&pdev->dev, "no IRQ specified\n");
195                 return -EINVAL;
196         }
197
198         error = devm_request_irq(&pdev->dev, keypad_data->irq, keyscan_isr, 0,
199                                  pdev->name, keypad_data);
200         if (error) {
201                 dev_err(&pdev->dev, "failed to request IRQ\n");
202                 return error;
203         }
204
205         error = input_register_device(input_dev);
206         if (error) {
207                 dev_err(&pdev->dev, "failed to register input device\n");
208                 return error;
209         }
210
211         platform_set_drvdata(pdev, keypad_data);
212
213         device_set_wakeup_capable(&pdev->dev, 1);
214
215         return 0;
216 }
217
218 #ifdef CONFIG_PM_SLEEP
219 static int keyscan_suspend(struct device *dev)
220 {
221         struct platform_device *pdev = to_platform_device(dev);
222         struct st_keyscan *keypad = platform_get_drvdata(pdev);
223         struct input_dev *input = keypad->input_dev;
224
225         mutex_lock(&input->mutex);
226
227         if (device_may_wakeup(dev))
228                 enable_irq_wake(keypad->irq);
229         else if (input->users)
230                 keyscan_stop(keypad);
231
232         mutex_unlock(&input->mutex);
233         return 0;
234 }
235
236 static int keyscan_resume(struct device *dev)
237 {
238         struct platform_device *pdev = to_platform_device(dev);
239         struct st_keyscan *keypad = platform_get_drvdata(pdev);
240         struct input_dev *input = keypad->input_dev;
241         int retval = 0;
242
243         mutex_lock(&input->mutex);
244
245         if (device_may_wakeup(dev))
246                 disable_irq_wake(keypad->irq);
247         else if (input->users)
248                 retval = keyscan_start(keypad);
249
250         mutex_unlock(&input->mutex);
251         return retval;
252 }
253 #endif
254
255 static SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops, keyscan_suspend, keyscan_resume);
256
257 static const struct of_device_id keyscan_of_match[] = {
258         { .compatible = "st,sti-keyscan" },
259         { },
260 };
261 MODULE_DEVICE_TABLE(of, keyscan_of_match);
262
263 static struct platform_driver keyscan_device_driver = {
264         .probe          = keyscan_probe,
265         .driver         = {
266                 .name   = "st-keyscan",
267                 .pm     = &keyscan_dev_pm_ops,
268                 .of_match_table = of_match_ptr(keyscan_of_match),
269         }
270 };
271
272 module_platform_driver(keyscan_device_driver);
273
274 MODULE_AUTHOR("Stuart Menefy <stuart.menefy@st.com>");
275 MODULE_DESCRIPTION("STMicroelectronics keyscan device driver");
276 MODULE_LICENSE("GPL");