Lines Matching +full:cros +full:- +full:ec +full:- +full:i2c

1 // SPDX-License-Identifier: GPL-2.0
2 // ChromeOS EC keyboard driver
6 // This driver uses the ChromeOS EC byte-level message-based protocol for
7 // communicating the keyboard state (which keys are pressed) from a keyboard EC
8 // to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing,
10 // motivation for this is to keep the EC firmware as simple as possible, since
11 // it cannot be easily upgraded and EC flash/IRAM space is relatively
17 #include <linux/i2c.h>
19 #include <linux/input/vivaldi-fmap.h>
33 * struct cros_ec_keyb - Structure representing EC keyboard device
39 * @ghost_filter: true to enable the matrix key-ghosting filter
43 * @ec: Top level ChromeOS device to use to talk to EC
45 * @bs_idev: The input device for non-matrix buttons and switches (or NULL).
59 struct cros_ec_device *ec; member
69 * struct cros_ec_bs_map - Mapping between Linux keycodes and EC button/switch
85 /* cros_ec_keyb_bs - Map EC button/switch #defines into kernel ones */
125 struct device *dev = ckdev->dev; in cros_ec_keyb_has_ghosting()
126 uint8_t *valid_keys = ckdev->valid_keys; in cros_ec_keyb_has_ghosting()
141 for (col1 = 0; col1 < ckdev->cols; col1++) { in cros_ec_keyb_has_ghosting()
143 for (col2 = col1 + 1; col2 < ckdev->cols; col2++) { in cros_ec_keyb_has_ghosting()
165 struct input_dev *idev = ckdev->idev; in cros_ec_keyb_process()
170 if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) { in cros_ec_keyb_process()
172 * Simple-minded solution: ignore this state. The obvious in cros_ec_keyb_process()
176 dev_dbg(ckdev->dev, "ghosting found\n"); in cros_ec_keyb_process()
180 for (col = 0; col < ckdev->cols; col++) { in cros_ec_keyb_process()
181 for (row = 0; row < ckdev->rows; row++) { in cros_ec_keyb_process()
182 int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); in cros_ec_keyb_process()
183 const unsigned short *keycodes = idev->keycode; in cros_ec_keyb_process()
186 old_state = ckdev->old_kb_state[col] & (1 << row); in cros_ec_keyb_process()
188 dev_dbg(ckdev->dev, in cros_ec_keyb_process()
197 ckdev->old_kb_state[col] = kb_state[col]; in cros_ec_keyb_process()
199 input_sync(ckdev->idev); in cros_ec_keyb_process()
203 * cros_ec_keyb_report_bs - Report non-matrixed buttons or switches
205 * This takes a bitmap of buttons or switches from the EC and reports events,
210 * @mask: A bitmap of buttons from the EC.
216 struct input_dev *idev = ckdev->bs_idev; in cros_ec_keyb_report_bs()
222 if (map->ev_type != ev_type) in cros_ec_keyb_report_bs()
225 input_event(idev, ev_type, map->code, in cros_ec_keyb_report_bs()
226 !!(mask & BIT(map->bit)) ^ map->inverted); in cros_ec_keyb_report_bs()
241 * suspend. Switches will be re-checked in in cros_ec_keyb_work()
244 if (queued_during_suspend && !device_may_wakeup(ckdev->dev)) in cros_ec_keyb_work()
247 switch (ckdev->ec->event_data.event_type) { in cros_ec_keyb_work()
249 pm_wakeup_event(ckdev->dev, 0); in cros_ec_keyb_work()
251 if (ckdev->ec->event_size != ckdev->cols) { in cros_ec_keyb_work()
252 dev_err(ckdev->dev, in cros_ec_keyb_work()
258 ckdev->ec->event_data.data.key_matrix, in cros_ec_keyb_work()
259 ckdev->ec->event_size); in cros_ec_keyb_work()
263 pm_wakeup_event(ckdev->dev, 0); in cros_ec_keyb_work()
265 val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq); in cros_ec_keyb_work()
266 dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val); in cros_ec_keyb_work()
272 pm_wakeup_event(ckdev->dev, 0); in cros_ec_keyb_work()
274 if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) { in cros_ec_keyb_work()
276 &ckdev->ec->event_data.data.buttons); in cros_ec_keyb_work()
280 &ckdev->ec->event_data.data.switches); in cros_ec_keyb_work()
300 int row_shift = ckdev->row_shift; in cros_ec_keyb_compute_valid_keys()
301 unsigned short *keymap = ckdev->idev->keycode; in cros_ec_keyb_compute_valid_keys()
304 BUG_ON(ckdev->idev->keycodesize != sizeof(*keymap)); in cros_ec_keyb_compute_valid_keys()
306 for (col = 0; col < ckdev->cols; col++) { in cros_ec_keyb_compute_valid_keys()
307 for (row = 0; row < ckdev->rows; row++) { in cros_ec_keyb_compute_valid_keys()
310 ckdev->valid_keys[col] |= 1 << row; in cros_ec_keyb_compute_valid_keys()
312 dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n", in cros_ec_keyb_compute_valid_keys()
313 col, ckdev->valid_keys[col]); in cros_ec_keyb_compute_valid_keys()
318 * cros_ec_keyb_info - Wrap the EC command EC_CMD_MKBP_INFO
323 * @ec_dev: The EC device
332 * Returns 0 if no error or -error upon error.
347 return -ENOMEM; in cros_ec_keyb_info()
349 msg->command = EC_CMD_MKBP_INFO; in cros_ec_keyb_info()
350 msg->version = 1; in cros_ec_keyb_info()
351 msg->outsize = sizeof(*params); in cros_ec_keyb_info()
352 msg->insize = result_size; in cros_ec_keyb_info()
353 params = (struct ec_params_mkbp_info *)msg->data; in cros_ec_keyb_info()
354 params->info_type = info_type; in cros_ec_keyb_info()
355 params->event_type = event_type; in cros_ec_keyb_info()
358 if (ret == -ENOPROTOOPT) { in cros_ec_keyb_info()
363 dev_warn(ec_dev->dev, "Transfer error %d/%d: %d\n", in cros_ec_keyb_info()
366 dev_warn(ec_dev->dev, "Wrong size %d/%d: %d != %zu\n", in cros_ec_keyb_info()
369 ret = -EPROTO; in cros_ec_keyb_info()
371 memcpy(result, msg->data, result_size); in cros_ec_keyb_info()
381 * cros_ec_keyb_query_switches - Query the state of switches and report
383 * This will ask the EC about the current state of switches and report to the
389 * Returns 0 if no error or -error upon error.
393 struct cros_ec_device *ec_dev = ckdev->ec; in cros_ec_keyb_query_switches()
410 * cros_ec_keyb_resume - Resume the keyboard
412 * We use the resume notification as a chance to query the EC for switches.
416 * Returns 0 if no error or -error upon error.
422 if (ckdev->bs_idev) in cros_ec_keyb_resume()
429 * cros_ec_keyb_register_bs - Register non-matrix buttons/switches
431 * Handles all the bits of the keyboard driver related to non-matrix buttons
432 * and switches, including asking the EC about which are present and telling
436 * but the ckdev->bs_idev will remain NULL when this function exits.
439 * @expect_buttons_switches: Indicates that EC must report button and/or
442 * Returns 0 if no error or -error upon error.
447 struct cros_ec_device *ec_dev = ckdev->ec; in cros_ec_keyb_register_bs()
448 struct device *dev = ckdev->dev; in cros_ec_keyb_register_bs()
472 return expect_buttons_switches ? -EINVAL : 0; in cros_ec_keyb_register_bs()
475 * We call the non-matrix buttons/switches 'input1', if present. in cros_ec_keyb_register_bs()
476 * Allocate phys before input dev, to ensure correct tear-down in cros_ec_keyb_register_bs()
479 phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input1", ec_dev->phys_name); in cros_ec_keyb_register_bs()
481 return -ENOMEM; in cros_ec_keyb_register_bs()
485 return -ENOMEM; in cros_ec_keyb_register_bs()
487 idev->name = "cros_ec_buttons"; in cros_ec_keyb_register_bs()
488 idev->phys = phys; in cros_ec_keyb_register_bs()
489 __set_bit(EV_REP, idev->evbit); in cros_ec_keyb_register_bs()
491 idev->id.bustype = BUS_VIRTUAL; in cros_ec_keyb_register_bs()
492 idev->id.version = 1; in cros_ec_keyb_register_bs()
493 idev->id.product = 0; in cros_ec_keyb_register_bs()
494 idev->dev.parent = dev; in cros_ec_keyb_register_bs()
497 ckdev->bs_idev = idev; in cros_ec_keyb_register_bs()
502 if ((map->ev_type == EV_KEY && (buttons & BIT(map->bit))) || in cros_ec_keyb_register_bs()
503 (map->ev_type == EV_SW && (switches & BIT(map->bit)))) in cros_ec_keyb_register_bs()
504 input_set_capability(idev, map->ev_type, map->code); in cros_ec_keyb_register_bs()
513 ret = input_register_device(ckdev->bs_idev); in cros_ec_keyb_register_bs()
524 u32 *physmap = ckdev->vdata.function_row_physmap; in cros_ec_keyb_parse_vivaldi_physmap()
530 n_physmap = device_property_count_u32(ckdev->dev, in cros_ec_keyb_parse_vivaldi_physmap()
531 "function-row-physmap"); in cros_ec_keyb_parse_vivaldi_physmap()
536 dev_warn(ckdev->dev, in cros_ec_keyb_parse_vivaldi_physmap()
542 error = device_property_read_u32_array(ckdev->dev, in cros_ec_keyb_parse_vivaldi_physmap()
543 "function-row-physmap", in cros_ec_keyb_parse_vivaldi_physmap()
546 dev_warn(ckdev->dev, in cros_ec_keyb_parse_vivaldi_physmap()
547 "failed to parse function-row-physmap property: %d\n", in cros_ec_keyb_parse_vivaldi_physmap()
559 scancode = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); in cros_ec_keyb_parse_vivaldi_physmap()
563 ckdev->vdata.num_function_row_keys = n_physmap; in cros_ec_keyb_parse_vivaldi_physmap()
567 * cros_ec_keyb_register_matrix - Register matrix keys
573 * Returns 0 if no error or -error upon error.
577 struct cros_ec_device *ec_dev = ckdev->ec; in cros_ec_keyb_register_matrix()
578 struct device *dev = ckdev->dev; in cros_ec_keyb_register_matrix()
583 err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols); in cros_ec_keyb_register_matrix()
587 ckdev->valid_keys = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL); in cros_ec_keyb_register_matrix()
588 if (!ckdev->valid_keys) in cros_ec_keyb_register_matrix()
589 return -ENOMEM; in cros_ec_keyb_register_matrix()
591 ckdev->old_kb_state = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL); in cros_ec_keyb_register_matrix()
592 if (!ckdev->old_kb_state) in cros_ec_keyb_register_matrix()
593 return -ENOMEM; in cros_ec_keyb_register_matrix()
597 * dev, to ensure correct tear-down ordering. in cros_ec_keyb_register_matrix()
599 phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input0", ec_dev->phys_name); in cros_ec_keyb_register_matrix()
601 return -ENOMEM; in cros_ec_keyb_register_matrix()
605 return -ENOMEM; in cros_ec_keyb_register_matrix()
607 idev->name = CROS_EC_DEV_NAME; in cros_ec_keyb_register_matrix()
608 idev->phys = phys; in cros_ec_keyb_register_matrix()
609 __set_bit(EV_REP, idev->evbit); in cros_ec_keyb_register_matrix()
611 idev->id.bustype = BUS_VIRTUAL; in cros_ec_keyb_register_matrix()
612 idev->id.version = 1; in cros_ec_keyb_register_matrix()
613 idev->id.product = 0; in cros_ec_keyb_register_matrix()
614 idev->dev.parent = dev; in cros_ec_keyb_register_matrix()
616 ckdev->ghost_filter = device_property_read_bool(dev, in cros_ec_keyb_register_matrix()
617 "google,needs-ghost-filter"); in cros_ec_keyb_register_matrix()
619 err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, in cros_ec_keyb_register_matrix()
626 ckdev->row_shift = get_count_order(ckdev->cols); in cros_ec_keyb_register_matrix()
630 ckdev->idev = idev; in cros_ec_keyb_register_matrix()
634 err = input_register_device(ckdev->idev); in cros_ec_keyb_register_matrix()
648 const struct vivaldi_data *data = &ckdev->vdata; in function_row_physmap_show()
668 !ckdev->vdata.num_function_row_keys) in cros_ec_keyb_attr_is_visible()
671 return attr->mode; in cros_ec_keyb_attr_is_visible()
681 struct cros_ec_device *ec; in cros_ec_keyb_probe() local
682 struct device *dev = &pdev->dev; in cros_ec_keyb_probe()
688 * If the parent ec device has not been probed yet, defer the probe of in cros_ec_keyb_probe()
691 ec = dev_get_drvdata(pdev->dev.parent); in cros_ec_keyb_probe()
692 if (!ec) in cros_ec_keyb_probe()
693 return -EPROBE_DEFER; in cros_ec_keyb_probe()
697 return -ENOMEM; in cros_ec_keyb_probe()
699 ckdev->ec = ec; in cros_ec_keyb_probe()
700 ckdev->dev = dev; in cros_ec_keyb_probe()
714 dev_err(dev, "cannot register non-matrix inputs: %d\n", err); in cros_ec_keyb_probe()
724 ckdev->notifier.notifier_call = cros_ec_keyb_work; in cros_ec_keyb_probe()
725 err = blocking_notifier_chain_register(&ckdev->ec->event_notifier, in cros_ec_keyb_probe()
726 &ckdev->notifier); in cros_ec_keyb_probe()
732 device_init_wakeup(ckdev->dev, true); in cros_ec_keyb_probe()
738 struct cros_ec_keyb *ckdev = dev_get_drvdata(&pdev->dev); in cros_ec_keyb_remove()
740 blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, in cros_ec_keyb_remove()
741 &ckdev->notifier); in cros_ec_keyb_remove()
756 { .compatible = "google,cros-ec-keyb" },
757 { .compatible = "google,cros-ec-keyb-switches", .data = (void *)true },
769 .name = "cros-ec-keyb",
779 MODULE_DESCRIPTION("ChromeOS EC keyboard driver");
780 MODULE_ALIAS("platform:cros-ec-keyb");