aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-05 20:36:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-05 20:36:20 -0400
commitd7ab7302f970a254997687a1cdede421a5635c68 (patch)
tree71341b72e81c8e031b98e8115c51682427192798 /drivers/input
parent01227a889ed56ae53aeebb9f93be9d54dd8b2de8 (diff)
parent99f4c6b66a9ae362d21e6df95d04bc74e04d285e (diff)
Merge tag 'mfd-3.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next
Pull MFD update from Samuel Ortiz: "For 3.10 we have a few new MFD drivers for: - The ChromeOS embedded controller which provides keyboard, battery and power management services. This controller is accessible through i2c or SPI. - Silicon Laboratories 476x controller, providing access to their FM chipset and their audio codec. - Realtek's RTS5249, a memory stick, MMC and SD/SDIO PCI based reader. - Nokia's Tahvo power button and watchdog device. This device is very similar to Retu and is thus supported by the same code base. - STMicroelectronics STMPE1801, a keyboard and GPIO controller supported by the stmpe driver. - ST-Ericsson AB8540 and AB8505 power management and voltage converter controllers through the existing ab8500 code. Some other drivers got cleaned up or improved. In particular: - The Linaro/STE guys got the ab8500 driver in sync with their internal code through a series of optimizations, fixes and improvements. - The AS3711 and OMAP USB drivers now have DT support. - The arizona clock and interrupt handling code got improved. - The wm5102 register patch and boot mechanism also got improved." * tag 'mfd-3.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next: (104 commits) mfd: si476x: Don't use 0bNNN mfd: vexpress: Handle pending config transactions mfd: ab8500: Export ab8500_gpadc_sw_hw_convert properly mfd: si476x: Fix i2c warning mfd: si476x: Add header files and Kbuild plumbing mfd: si476x: Add chip properties handling code mfd: si476x: Add the bulk of the core driver mfd: si476x: Add commands abstraction layer mfd: rtsx: Support RTS5249 mfd: retu: Add Tahvo support mfd: ucb1400: Pass ucb1400-gpio data through ac97 bus mfd: wm8994: Add some OF properties mfd: wm8994: Add device ID data to WM8994 OF device IDs input: Export matrix_keypad_parse_of_params() mfd: tps65090: Add compatible string for charger subnode mfd: db8500-prcmu: Support platform dependant device selection mfd: syscon: Fix warnings when printing resource_size_t of: Add stub of_get_parent for non-OF builds mfd: omap-usb-tll: Convert to devm_ioremap_resource() mfd: omap-usb-host: Convert to devm_ioremap_resource() ...
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/keyboard/Kconfig12
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c334
-rw-r--r--drivers/input/keyboard/lpc32xx-keys.c11
-rw-r--r--drivers/input/keyboard/omap4-keypad.c16
-rw-r--r--drivers/input/keyboard/tca8418_keypad.c7
-rw-r--r--drivers/input/matrix-keymap.c20
7 files changed, 383 insertions, 18 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index ac0500667000..6a195d5e90ff 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -628,4 +628,16 @@ config KEYBOARD_W90P910
628 To compile this driver as a module, choose M here: the 628 To compile this driver as a module, choose M here: the
629 module will be called w90p910_keypad. 629 module will be called w90p910_keypad.
630 630
631config KEYBOARD_CROS_EC
632 tristate "ChromeOS EC keyboard"
633 select INPUT_MATRIXKMAP
634 depends on MFD_CROS_EC
635 help
636 Say Y here to enable the matrix keyboard used by ChromeOS devices
637 and implemented on the ChromeOS EC. You must enable one bus option
638 (MFD_CROS_EC_I2C or MFD_CROS_EC_SPI) to use this.
639
640 To compile this driver as a module, choose M here: the
641 module will be called cros_ec_keyb.
642
631endif 643endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 49b16453d00e..0c43e8cf8d0e 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
11obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o 11obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o
12obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o 12obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
13obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o 13obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
14obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o
14obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o 15obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o
15obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o 16obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
16obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o 17obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
new file mode 100644
index 000000000000..49557f27bfa6
--- /dev/null
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -0,0 +1,334 @@
1/*
2 * ChromeOS EC keyboard driver
3 *
4 * Copyright (C) 2012 Google, Inc
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * This driver uses the Chrome OS EC byte-level message-based protocol for
16 * communicating the keyboard state (which keys are pressed) from a keyboard EC
17 * to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing,
18 * but everything else (including deghosting) is done here. The main
19 * motivation for this is to keep the EC firmware as simple as possible, since
20 * it cannot be easily upgraded and EC flash/IRAM space is relatively
21 * expensive.
22 */
23
24#include <linux/module.h>
25#include <linux/i2c.h>
26#include <linux/input.h>
27#include <linux/kernel.h>
28#include <linux/notifier.h>
29#include <linux/platform_device.h>
30#include <linux/slab.h>
31#include <linux/input/matrix_keypad.h>
32#include <linux/mfd/cros_ec.h>
33#include <linux/mfd/cros_ec_commands.h>
34
35/*
36 * @rows: Number of rows in the keypad
37 * @cols: Number of columns in the keypad
38 * @row_shift: log2 or number of rows, rounded up
39 * @keymap_data: Matrix keymap data used to convert to keyscan values
40 * @ghost_filter: true to enable the matrix key-ghosting filter
41 * @dev: Device pointer
42 * @idev: Input device
43 * @ec: Top level ChromeOS device to use to talk to EC
44 * @event_notifier: interrupt event notifier for transport devices
45 */
46struct cros_ec_keyb {
47 unsigned int rows;
48 unsigned int cols;
49 int row_shift;
50 const struct matrix_keymap_data *keymap_data;
51 bool ghost_filter;
52
53 struct device *dev;
54 struct input_dev *idev;
55 struct cros_ec_device *ec;
56 struct notifier_block notifier;
57};
58
59
60static bool cros_ec_keyb_row_has_ghosting(struct cros_ec_keyb *ckdev,
61 uint8_t *buf, int row)
62{
63 int pressed_in_row = 0;
64 int row_has_teeth = 0;
65 int col, mask;
66
67 mask = 1 << row;
68 for (col = 0; col < ckdev->cols; col++) {
69 if (buf[col] & mask) {
70 pressed_in_row++;
71 row_has_teeth |= buf[col] & ~mask;
72 if (pressed_in_row > 1 && row_has_teeth) {
73 /* ghosting */
74 dev_dbg(ckdev->dev,
75 "ghost found at: r%d c%d, pressed %d, teeth 0x%x\n",
76 row, col, pressed_in_row,
77 row_has_teeth);
78 return true;
79 }
80 }
81 }
82
83 return false;
84}
85
86/*
87 * Returns true when there is at least one combination of pressed keys that
88 * results in ghosting.
89 */
90static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
91{
92 int row;
93
94 /*
95 * Ghosting happens if for any pressed key X there are other keys
96 * pressed both in the same row and column of X as, for instance,
97 * in the following diagram:
98 *
99 * . . Y . g .
100 * . . . . . .
101 * . . . . . .
102 * . . X . Z .
103 *
104 * In this case only X, Y, and Z are pressed, but g appears to be
105 * pressed too (see Wikipedia).
106 *
107 * We can detect ghosting in a single pass (*) over the keyboard state
108 * by maintaining two arrays. pressed_in_row counts how many pressed
109 * keys we have found in a row. row_has_teeth is true if any of the
110 * pressed keys for this row has other pressed keys in its column. If
111 * at any point of the scan we find that a row has multiple pressed
112 * keys, and at least one of them is at the intersection with a column
113 * with multiple pressed keys, we're sure there is ghosting.
114 * Conversely, if there is ghosting, we will detect such situation for
115 * at least one key during the pass.
116 *
117 * (*) This looks linear in the number of keys, but it's not. We can
118 * cheat because the number of rows is small.
119 */
120 for (row = 0; row < ckdev->rows; row++)
121 if (cros_ec_keyb_row_has_ghosting(ckdev, buf, row))
122 return true;
123
124 return false;
125}
126
127/*
128 * Compares the new keyboard state to the old one and produces key
129 * press/release events accordingly. The keyboard state is 13 bytes (one byte
130 * per column)
131 */
132static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
133 uint8_t *kb_state, int len)
134{
135 struct input_dev *idev = ckdev->idev;
136 int col, row;
137 int new_state;
138 int num_cols;
139
140 num_cols = len;
141
142 if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) {
143 /*
144 * Simple-minded solution: ignore this state. The obvious
145 * improvement is to only ignore changes to keys involved in
146 * the ghosting, but process the other changes.
147 */
148 dev_dbg(ckdev->dev, "ghosting found\n");
149 return;
150 }
151
152 for (col = 0; col < ckdev->cols; col++) {
153 for (row = 0; row < ckdev->rows; row++) {
154 int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
155 const unsigned short *keycodes = idev->keycode;
156 int code;
157
158 code = keycodes[pos];
159 new_state = kb_state[col] & (1 << row);
160 if (!!new_state != test_bit(code, idev->key)) {
161 dev_dbg(ckdev->dev,
162 "changed: [r%d c%d]: byte %02x\n",
163 row, col, new_state);
164
165 input_report_key(idev, code, new_state);
166 }
167 }
168 }
169 input_sync(ckdev->idev);
170}
171
172static int cros_ec_keyb_open(struct input_dev *dev)
173{
174 struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
175
176 return blocking_notifier_chain_register(&ckdev->ec->event_notifier,
177 &ckdev->notifier);
178}
179
180static void cros_ec_keyb_close(struct input_dev *dev)
181{
182 struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
183
184 blocking_notifier_chain_unregister(&ckdev->ec->event_notifier,
185 &ckdev->notifier);
186}
187
188static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
189{
190 return ckdev->ec->command_recv(ckdev->ec, EC_CMD_MKBP_STATE,
191 kb_state, ckdev->cols);
192}
193
194static int cros_ec_keyb_work(struct notifier_block *nb,
195 unsigned long state, void *_notify)
196{
197 int ret;
198 struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
199 notifier);
200 uint8_t kb_state[ckdev->cols];
201
202 ret = cros_ec_keyb_get_state(ckdev, kb_state);
203 if (ret >= 0)
204 cros_ec_keyb_process(ckdev, kb_state, ret);
205
206 return NOTIFY_DONE;
207}
208
209/* Clear any keys in the buffer */
210static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
211{
212 uint8_t old_state[ckdev->cols];
213 uint8_t new_state[ckdev->cols];
214 unsigned long duration;
215 int i, ret;
216
217 /*
218 * Keep reading until we see that the scan state does not change.
219 * That indicates that we are done.
220 *
221 * Assume that the EC keyscan buffer is at most 32 deep.
222 */
223 duration = jiffies;
224 ret = cros_ec_keyb_get_state(ckdev, new_state);
225 for (i = 1; !ret && i < 32; i++) {
226 memcpy(old_state, new_state, sizeof(old_state));
227 ret = cros_ec_keyb_get_state(ckdev, new_state);
228 if (0 == memcmp(old_state, new_state, sizeof(old_state)))
229 break;
230 }
231 duration = jiffies - duration;
232 dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i,
233 jiffies_to_usecs(duration));
234}
235
236static int cros_ec_keyb_probe(struct platform_device *pdev)
237{
238 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
239 struct device *dev = ec->dev;
240 struct cros_ec_keyb *ckdev;
241 struct input_dev *idev;
242 struct device_node *np;
243 int err;
244
245 np = pdev->dev.of_node;
246 if (!np)
247 return -ENODEV;
248
249 ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL);
250 if (!ckdev)
251 return -ENOMEM;
252 err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows,
253 &ckdev->cols);
254 if (err)
255 return err;
256
257 idev = devm_input_allocate_device(&pdev->dev);
258 if (!idev)
259 return -ENOMEM;
260
261 ckdev->ec = ec;
262 ckdev->notifier.notifier_call = cros_ec_keyb_work;
263 ckdev->dev = dev;
264 dev_set_drvdata(&pdev->dev, ckdev);
265
266 idev->name = ec->ec_name;
267 idev->phys = ec->phys_name;
268 __set_bit(EV_REP, idev->evbit);
269
270 idev->id.bustype = BUS_VIRTUAL;
271 idev->id.version = 1;
272 idev->id.product = 0;
273 idev->dev.parent = &pdev->dev;
274 idev->open = cros_ec_keyb_open;
275 idev->close = cros_ec_keyb_close;
276
277 ckdev->ghost_filter = of_property_read_bool(np,
278 "google,needs-ghost-filter");
279
280 err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols,
281 NULL, idev);
282 if (err) {
283 dev_err(dev, "cannot build key matrix\n");
284 return err;
285 }
286
287 ckdev->row_shift = get_count_order(ckdev->cols);
288
289 input_set_capability(idev, EV_MSC, MSC_SCAN);
290 input_set_drvdata(idev, ckdev);
291 ckdev->idev = idev;
292 err = input_register_device(ckdev->idev);
293 if (err) {
294 dev_err(dev, "cannot register input device\n");
295 return err;
296 }
297
298 return 0;
299}
300
301#ifdef CONFIG_PM_SLEEP
302static int cros_ec_keyb_resume(struct device *dev)
303{
304 struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
305
306 /*
307 * When the EC is not a wake source, then it could not have caused the
308 * resume, so we clear the EC's key scan buffer. If the EC was a
309 * wake source (e.g. the lid is open and the user might press a key to
310 * wake) then the key scan buffer should be preserved.
311 */
312 if (ckdev->ec->was_wake_device)
313 cros_ec_keyb_clear_keyboard(ckdev);
314
315 return 0;
316}
317
318#endif
319
320static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume);
321
322static struct platform_driver cros_ec_keyb_driver = {
323 .probe = cros_ec_keyb_probe,
324 .driver = {
325 .name = "cros-ec-keyb",
326 .pm = &cros_ec_keyb_pm_ops,
327 },
328};
329
330module_platform_driver(cros_ec_keyb_driver);
331
332MODULE_LICENSE("GPL");
333MODULE_DESCRIPTION("ChromeOS EC keyboard driver");
334MODULE_ALIAS("platform:cros-ec-keyb");
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c
index 1b8add6cfb9d..42181435fe67 100644
--- a/drivers/input/keyboard/lpc32xx-keys.c
+++ b/drivers/input/keyboard/lpc32xx-keys.c
@@ -144,12 +144,13 @@ static int lpc32xx_parse_dt(struct device *dev,
144{ 144{
145 struct device_node *np = dev->of_node; 145 struct device_node *np = dev->of_node;
146 u32 rows = 0, columns = 0; 146 u32 rows = 0, columns = 0;
147 int err;
147 148
148 of_property_read_u32(np, "keypad,num-rows", &rows); 149 err = matrix_keypad_parse_of_params(dev, &rows, &columns);
149 of_property_read_u32(np, "keypad,num-columns", &columns); 150 if (err)
150 if (!rows || rows != columns) { 151 return err;
151 dev_err(dev, 152 if (rows != columns) {
152 "rows and columns must be specified and be equal!\n"); 153 dev_err(dev, "rows and columns must be equal!\n");
153 return -EINVAL; 154 return -EINVAL;
154 } 155 }
155 156
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c
index e25b022692cd..1b289092f4e3 100644
--- a/drivers/input/keyboard/omap4-keypad.c
+++ b/drivers/input/keyboard/omap4-keypad.c
@@ -215,18 +215,12 @@ static int omap4_keypad_parse_dt(struct device *dev,
215 struct omap4_keypad *keypad_data) 215 struct omap4_keypad *keypad_data)
216{ 216{
217 struct device_node *np = dev->of_node; 217 struct device_node *np = dev->of_node;
218 int err;
218 219
219 if (!np) { 220 err = matrix_keypad_parse_of_params(dev, &keypad_data->rows,
220 dev_err(dev, "missing DT data"); 221 &keypad_data->cols);
221 return -EINVAL; 222 if (err)
222 } 223 return err;
223
224 of_property_read_u32(np, "keypad,num-rows", &keypad_data->rows);
225 of_property_read_u32(np, "keypad,num-columns", &keypad_data->cols);
226 if (!keypad_data->rows || !keypad_data->cols) {
227 dev_err(dev, "number of keypad rows/columns not specified\n");
228 return -EINVAL;
229 }
230 224
231 if (of_get_property(np, "linux,input-no-autorepeat", NULL)) 225 if (of_get_property(np, "linux,input-no-autorepeat", NULL))
232 keypad_data->no_autorepeat = true; 226 keypad_data->no_autorepeat = true;
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
index a34cc6714e5b..55c15304ddbc 100644
--- a/drivers/input/keyboard/tca8418_keypad.c
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -288,8 +288,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
288 irq_is_gpio = pdata->irq_is_gpio; 288 irq_is_gpio = pdata->irq_is_gpio;
289 } else { 289 } else {
290 struct device_node *np = dev->of_node; 290 struct device_node *np = dev->of_node;
291 of_property_read_u32(np, "keypad,num-rows", &rows); 291 int err;
292 of_property_read_u32(np, "keypad,num-columns", &cols); 292
293 err = matrix_keypad_parse_of_params(dev, &rows, &cols);
294 if (err)
295 return err;
293 rep = of_property_read_bool(np, "keypad,autorepeat"); 296 rep = of_property_read_bool(np, "keypad,autorepeat");
294 } 297 }
295 298
diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c
index 3ae496ea5fe6..08b61f506db6 100644
--- a/drivers/input/matrix-keymap.c
+++ b/drivers/input/matrix-keymap.c
@@ -50,6 +50,26 @@ static bool matrix_keypad_map_key(struct input_dev *input_dev,
50} 50}
51 51
52#ifdef CONFIG_OF 52#ifdef CONFIG_OF
53int matrix_keypad_parse_of_params(struct device *dev,
54 unsigned int *rows, unsigned int *cols)
55{
56 struct device_node *np = dev->of_node;
57
58 if (!np) {
59 dev_err(dev, "missing DT data");
60 return -EINVAL;
61 }
62 of_property_read_u32(np, "keypad,num-rows", rows);
63 of_property_read_u32(np, "keypad,num-columns", cols);
64 if (!*rows || !*cols) {
65 dev_err(dev, "number of keypad rows/columns not specified\n");
66 return -EINVAL;
67 }
68
69 return 0;
70}
71EXPORT_SYMBOL_GPL(matrix_keypad_parse_of_params);
72
53static int matrix_keypad_parse_of_keymap(const char *propname, 73static int matrix_keypad_parse_of_keymap(const char *propname,
54 unsigned int rows, unsigned int cols, 74 unsigned int rows, unsigned int cols,
55 struct input_dev *input_dev) 75 struct input_dev *input_dev)