Commit | Line | Data |
---|---|---|
6af6dc2d SG |
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> | |
017f14e8 | 25 | #include <linux/bitops.h> |
6af6dc2d SG |
26 | #include <linux/i2c.h> |
27 | #include <linux/input.h> | |
d1fd345e | 28 | #include <linux/interrupt.h> |
6af6dc2d | 29 | #include <linux/kernel.h> |
6af6dc2d SG |
30 | #include <linux/platform_device.h> |
31 | #include <linux/slab.h> | |
32 | #include <linux/input/matrix_keypad.h> | |
33 | #include <linux/mfd/cros_ec.h> | |
34 | #include <linux/mfd/cros_ec_commands.h> | |
35 | ||
36 | /* | |
37 | * @rows: Number of rows in the keypad | |
38 | * @cols: Number of columns in the keypad | |
39 | * @row_shift: log2 or number of rows, rounded up | |
40 | * @keymap_data: Matrix keymap data used to convert to keyscan values | |
41 | * @ghost_filter: true to enable the matrix key-ghosting filter | |
017f14e8 | 42 | * @valid_keys: bitmap of existing keys for each matrix column |
64757eba | 43 | * @old_kb_state: bitmap of keys pressed last scan |
6af6dc2d SG |
44 | * @dev: Device pointer |
45 | * @idev: Input device | |
46 | * @ec: Top level ChromeOS device to use to talk to EC | |
6af6dc2d SG |
47 | */ |
48 | struct cros_ec_keyb { | |
49 | unsigned int rows; | |
50 | unsigned int cols; | |
51 | int row_shift; | |
52 | const struct matrix_keymap_data *keymap_data; | |
53 | bool ghost_filter; | |
017f14e8 | 54 | uint8_t *valid_keys; |
64757eba | 55 | uint8_t *old_kb_state; |
6af6dc2d SG |
56 | |
57 | struct device *dev; | |
58 | struct input_dev *idev; | |
59 | struct cros_ec_device *ec; | |
6af6dc2d SG |
60 | }; |
61 | ||
62 | ||
6af6dc2d SG |
63 | /* |
64 | * Returns true when there is at least one combination of pressed keys that | |
65 | * results in ghosting. | |
66 | */ | |
67 | static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf) | |
68 | { | |
017f14e8 TB |
69 | int col1, col2, buf1, buf2; |
70 | struct device *dev = ckdev->dev; | |
71 | uint8_t *valid_keys = ckdev->valid_keys; | |
6af6dc2d SG |
72 | |
73 | /* | |
74 | * Ghosting happens if for any pressed key X there are other keys | |
75 | * pressed both in the same row and column of X as, for instance, | |
76 | * in the following diagram: | |
77 | * | |
78 | * . . Y . g . | |
79 | * . . . . . . | |
80 | * . . . . . . | |
81 | * . . X . Z . | |
82 | * | |
83 | * In this case only X, Y, and Z are pressed, but g appears to be | |
84 | * pressed too (see Wikipedia). | |
6af6dc2d | 85 | */ |
017f14e8 TB |
86 | for (col1 = 0; col1 < ckdev->cols; col1++) { |
87 | buf1 = buf[col1] & valid_keys[col1]; | |
88 | for (col2 = col1 + 1; col2 < ckdev->cols; col2++) { | |
89 | buf2 = buf[col2] & valid_keys[col2]; | |
90 | if (hweight8(buf1 & buf2) > 1) { | |
91 | dev_dbg(dev, "ghost found at: B[%02d]:0x%02x & B[%02d]:0x%02x", | |
92 | col1, buf1, col2, buf2); | |
93 | return true; | |
94 | } | |
95 | } | |
96 | } | |
6af6dc2d SG |
97 | |
98 | return false; | |
99 | } | |
100 | ||
017f14e8 | 101 | |
6af6dc2d SG |
102 | /* |
103 | * Compares the new keyboard state to the old one and produces key | |
104 | * press/release events accordingly. The keyboard state is 13 bytes (one byte | |
105 | * per column) | |
106 | */ | |
107 | static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, | |
108 | uint8_t *kb_state, int len) | |
109 | { | |
110 | struct input_dev *idev = ckdev->idev; | |
111 | int col, row; | |
112 | int new_state; | |
64757eba | 113 | int old_state; |
6af6dc2d SG |
114 | int num_cols; |
115 | ||
116 | num_cols = len; | |
117 | ||
118 | if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) { | |
119 | /* | |
120 | * Simple-minded solution: ignore this state. The obvious | |
121 | * improvement is to only ignore changes to keys involved in | |
122 | * the ghosting, but process the other changes. | |
123 | */ | |
124 | dev_dbg(ckdev->dev, "ghosting found\n"); | |
125 | return; | |
126 | } | |
127 | ||
128 | for (col = 0; col < ckdev->cols; col++) { | |
129 | for (row = 0; row < ckdev->rows; row++) { | |
130 | int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); | |
131 | const unsigned short *keycodes = idev->keycode; | |
6af6dc2d | 132 | |
6af6dc2d | 133 | new_state = kb_state[col] & (1 << row); |
64757eba DA |
134 | old_state = ckdev->old_kb_state[col] & (1 << row); |
135 | if (new_state != old_state) { | |
6af6dc2d SG |
136 | dev_dbg(ckdev->dev, |
137 | "changed: [r%d c%d]: byte %02x\n", | |
138 | row, col, new_state); | |
139 | ||
64757eba DA |
140 | input_report_key(idev, keycodes[pos], |
141 | new_state); | |
6af6dc2d SG |
142 | } |
143 | } | |
64757eba | 144 | ckdev->old_kb_state[col] = kb_state[col]; |
6af6dc2d SG |
145 | } |
146 | input_sync(ckdev->idev); | |
147 | } | |
148 | ||
6af6dc2d SG |
149 | static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) |
150 | { | |
5799f95a BR |
151 | struct cros_ec_command msg = { |
152 | .version = 0, | |
153 | .command = EC_CMD_MKBP_STATE, | |
154 | .outdata = NULL, | |
155 | .outsize = 0, | |
156 | .indata = kb_state, | |
157 | .insize = ckdev->cols, | |
158 | }; | |
159 | ||
a6551a76 | 160 | return cros_ec_cmd_xfer(ckdev->ec, &msg); |
6af6dc2d SG |
161 | } |
162 | ||
d1fd345e | 163 | static irqreturn_t cros_ec_keyb_irq(int irq, void *data) |
6af6dc2d | 164 | { |
d1fd345e AB |
165 | struct cros_ec_keyb *ckdev = data; |
166 | struct cros_ec_device *ec = ckdev->ec; | |
6af6dc2d | 167 | int ret; |
6af6dc2d SG |
168 | uint8_t kb_state[ckdev->cols]; |
169 | ||
d1fd345e AB |
170 | if (device_may_wakeup(ec->dev)) |
171 | pm_wakeup_event(ec->dev, 0); | |
172 | ||
6af6dc2d SG |
173 | ret = cros_ec_keyb_get_state(ckdev, kb_state); |
174 | if (ret >= 0) | |
175 | cros_ec_keyb_process(ckdev, kb_state, ret); | |
d1fd345e AB |
176 | else |
177 | dev_err(ec->dev, "failed to get keyboard state: %d\n", ret); | |
6af6dc2d | 178 | |
d1fd345e AB |
179 | return IRQ_HANDLED; |
180 | } | |
181 | ||
182 | static int cros_ec_keyb_open(struct input_dev *dev) | |
183 | { | |
184 | struct cros_ec_keyb *ckdev = input_get_drvdata(dev); | |
185 | struct cros_ec_device *ec = ckdev->ec; | |
186 | ||
187 | return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, | |
188 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | |
189 | "cros_ec_keyb", ckdev); | |
190 | } | |
191 | ||
192 | static void cros_ec_keyb_close(struct input_dev *dev) | |
193 | { | |
194 | struct cros_ec_keyb *ckdev = input_get_drvdata(dev); | |
195 | struct cros_ec_device *ec = ckdev->ec; | |
196 | ||
197 | free_irq(ec->irq, ckdev); | |
6af6dc2d SG |
198 | } |
199 | ||
017f14e8 TB |
200 | /* |
201 | * Walks keycodes flipping bit in buffer COLUMNS deep where bit is ROW. Used by | |
202 | * ghosting logic to ignore NULL or virtual keys. | |
203 | */ | |
204 | static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev) | |
205 | { | |
206 | int row, col; | |
207 | int row_shift = ckdev->row_shift; | |
208 | unsigned short *keymap = ckdev->idev->keycode; | |
209 | unsigned short code; | |
210 | ||
211 | BUG_ON(ckdev->idev->keycodesize != sizeof(*keymap)); | |
212 | ||
213 | for (col = 0; col < ckdev->cols; col++) { | |
214 | for (row = 0; row < ckdev->rows; row++) { | |
215 | code = keymap[MATRIX_SCAN_CODE(row, col, row_shift)]; | |
216 | if (code && (code != KEY_BATTERY)) | |
217 | ckdev->valid_keys[col] |= 1 << row; | |
218 | } | |
219 | dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n", | |
220 | col, ckdev->valid_keys[col]); | |
221 | } | |
222 | } | |
223 | ||
6af6dc2d SG |
224 | static int cros_ec_keyb_probe(struct platform_device *pdev) |
225 | { | |
226 | struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); | |
227 | struct device *dev = ec->dev; | |
228 | struct cros_ec_keyb *ckdev; | |
229 | struct input_dev *idev; | |
230 | struct device_node *np; | |
231 | int err; | |
232 | ||
233 | np = pdev->dev.of_node; | |
234 | if (!np) | |
235 | return -ENODEV; | |
236 | ||
237 | ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); | |
238 | if (!ckdev) | |
239 | return -ENOMEM; | |
240 | err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, | |
241 | &ckdev->cols); | |
242 | if (err) | |
243 | return err; | |
017f14e8 TB |
244 | |
245 | ckdev->valid_keys = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); | |
246 | if (!ckdev->valid_keys) | |
247 | return -ENOMEM; | |
248 | ||
64757eba DA |
249 | ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); |
250 | if (!ckdev->old_kb_state) | |
251 | return -ENOMEM; | |
6af6dc2d SG |
252 | |
253 | idev = devm_input_allocate_device(&pdev->dev); | |
254 | if (!idev) | |
255 | return -ENOMEM; | |
256 | ||
d1fd345e AB |
257 | if (!ec->irq) { |
258 | dev_err(dev, "no EC IRQ specified\n"); | |
259 | return -EINVAL; | |
260 | } | |
261 | ||
6af6dc2d | 262 | ckdev->ec = ec; |
6af6dc2d SG |
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; | |
017f14e8 TB |
292 | cros_ec_keyb_compute_valid_keys(ckdev); |
293 | ||
6af6dc2d SG |
294 | err = input_register_device(ckdev->idev); |
295 | if (err) { | |
296 | dev_err(dev, "cannot register input device\n"); | |
297 | return err; | |
298 | } | |
299 | ||
300 | return 0; | |
301 | } | |
302 | ||
303 | #ifdef CONFIG_PM_SLEEP | |
03832aa8 GU |
304 | /* Clear any keys in the buffer */ |
305 | static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) | |
306 | { | |
307 | uint8_t old_state[ckdev->cols]; | |
308 | uint8_t new_state[ckdev->cols]; | |
309 | unsigned long duration; | |
310 | int i, ret; | |
311 | ||
312 | /* | |
313 | * Keep reading until we see that the scan state does not change. | |
314 | * That indicates that we are done. | |
315 | * | |
316 | * Assume that the EC keyscan buffer is at most 32 deep. | |
317 | */ | |
318 | duration = jiffies; | |
319 | ret = cros_ec_keyb_get_state(ckdev, new_state); | |
320 | for (i = 1; !ret && i < 32; i++) { | |
321 | memcpy(old_state, new_state, sizeof(old_state)); | |
322 | ret = cros_ec_keyb_get_state(ckdev, new_state); | |
323 | if (0 == memcmp(old_state, new_state, sizeof(old_state))) | |
324 | break; | |
325 | } | |
326 | duration = jiffies - duration; | |
327 | dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, | |
328 | jiffies_to_usecs(duration)); | |
329 | } | |
330 | ||
6af6dc2d SG |
331 | static int cros_ec_keyb_resume(struct device *dev) |
332 | { | |
333 | struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); | |
334 | ||
335 | /* | |
336 | * When the EC is not a wake source, then it could not have caused the | |
337 | * resume, so we clear the EC's key scan buffer. If the EC was a | |
338 | * wake source (e.g. the lid is open and the user might press a key to | |
339 | * wake) then the key scan buffer should be preserved. | |
340 | */ | |
341 | if (ckdev->ec->was_wake_device) | |
342 | cros_ec_keyb_clear_keyboard(ckdev); | |
343 | ||
344 | return 0; | |
345 | } | |
346 | ||
347 | #endif | |
348 | ||
349 | static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); | |
350 | ||
3f1fe73b SS |
351 | #ifdef CONFIG_OF |
352 | static const struct of_device_id cros_ec_keyb_of_match[] = { | |
353 | { .compatible = "google,cros-ec-keyb" }, | |
354 | {}, | |
355 | }; | |
356 | MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match); | |
357 | #endif | |
358 | ||
6af6dc2d SG |
359 | static struct platform_driver cros_ec_keyb_driver = { |
360 | .probe = cros_ec_keyb_probe, | |
361 | .driver = { | |
362 | .name = "cros-ec-keyb", | |
3f1fe73b | 363 | .of_match_table = of_match_ptr(cros_ec_keyb_of_match), |
6af6dc2d SG |
364 | .pm = &cros_ec_keyb_pm_ops, |
365 | }, | |
366 | }; | |
367 | ||
368 | module_platform_driver(cros_ec_keyb_driver); | |
369 | ||
370 | MODULE_LICENSE("GPL"); | |
371 | MODULE_DESCRIPTION("ChromeOS EC keyboard driver"); | |
372 | MODULE_ALIAS("platform:cros-ec-keyb"); |