1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * HID driver for Google Hammer device. 4 * 5 * Copyright (c) 2017 Google Inc. 6 * Author: Wei-Ning Huang <wnhuang@google.com> 7 */ 8 9 /* 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the Free 12 * Software Foundation; either version 2 of the License, or (at your option) 13 * any later version. 14 */ 15 16 #include <linux/acpi.h> 17 #include <linux/hid.h> 18 #include <linux/input/vivaldi-fmap.h> 19 #include <linux/leds.h> 20 #include <linux/module.h> 21 #include <linux/of.h> 22 #include <linux/platform_data/cros_ec_commands.h> 23 #include <linux/platform_data/cros_ec_proto.h> 24 #include <linux/platform_device.h> 25 #include <linux/unaligned.h> 26 27 #include "hid-ids.h" 28 #include "hid-vivaldi-common.h" 29 30 /* 31 * C(hrome)B(ase)A(ttached)S(witch) - switch exported by Chrome EC and reporting 32 * state of the "Whiskers" base - attached or detached. Whiskers USB device also 33 * reports position of the keyboard - folded or not. Combining base state and 34 * position allows us to generate proper "Tablet mode" events. 35 */ 36 struct cbas_ec { 37 struct device *dev; /* The platform device (EC) */ 38 struct input_dev *input; 39 bool base_present; 40 bool base_folded; 41 struct notifier_block notifier; 42 }; 43 44 static struct cbas_ec cbas_ec; 45 static DEFINE_SPINLOCK(cbas_ec_lock); 46 static DEFINE_MUTEX(cbas_ec_reglock); 47 48 static bool cbas_parse_base_state(const void *data) 49 { 50 u32 switches = get_unaligned_le32(data); 51 52 return !!(switches & BIT(EC_MKBP_BASE_ATTACHED)); 53 } 54 55 static int cbas_ec_query_base(struct cros_ec_device *ec_dev, bool get_state, 56 bool *state) 57 { 58 struct ec_params_mkbp_info *params; 59 struct cros_ec_command *msg; 60 int ret; 61 62 msg = kzalloc_flex(*msg, data, max(sizeof(u32), sizeof(*params))); 63 if (!msg) 64 return -ENOMEM; 65 66 msg->command = EC_CMD_MKBP_INFO; 67 msg->version = 1; 68 msg->outsize = sizeof(*params); 69 msg->insize = sizeof(u32); 70 params = (struct ec_params_mkbp_info *)msg->data; 71 params->info_type = get_state ? 72 EC_MKBP_INFO_CURRENT : EC_MKBP_INFO_SUPPORTED; 73 params->event_type = EC_MKBP_EVENT_SWITCH; 74 75 ret = cros_ec_cmd_xfer_status(ec_dev, msg); 76 if (ret >= 0) { 77 if (ret != sizeof(u32)) { 78 dev_warn(ec_dev->dev, "wrong result size: %d != %zu\n", 79 ret, sizeof(u32)); 80 ret = -EPROTO; 81 } else { 82 *state = cbas_parse_base_state(msg->data); 83 ret = 0; 84 } 85 } 86 87 kfree(msg); 88 89 return ret; 90 } 91 92 static int cbas_ec_notify(struct notifier_block *nb, 93 unsigned long queued_during_suspend, 94 void *_notify) 95 { 96 struct cros_ec_device *ec = _notify; 97 unsigned long flags; 98 bool base_present; 99 100 if (ec->event_data.event_type == EC_MKBP_EVENT_SWITCH) { 101 base_present = cbas_parse_base_state( 102 &ec->event_data.data.switches); 103 dev_dbg(cbas_ec.dev, 104 "%s: base: %d\n", __func__, base_present); 105 106 if (device_may_wakeup(cbas_ec.dev) || 107 !queued_during_suspend) { 108 109 pm_wakeup_event(cbas_ec.dev, 0); 110 111 spin_lock_irqsave(&cbas_ec_lock, flags); 112 113 /* 114 * While input layer dedupes the events, we do not want 115 * to disrupt the state reported by the base by 116 * overriding it with state reported by the LID. Only 117 * report changes, as we assume that on attach the base 118 * is not folded. 119 */ 120 if (base_present != cbas_ec.base_present) { 121 input_report_switch(cbas_ec.input, 122 SW_TABLET_MODE, 123 !base_present); 124 input_sync(cbas_ec.input); 125 cbas_ec.base_present = base_present; 126 } 127 128 spin_unlock_irqrestore(&cbas_ec_lock, flags); 129 } 130 } 131 132 return NOTIFY_OK; 133 } 134 135 static __maybe_unused int cbas_ec_resume(struct device *dev) 136 { 137 struct cros_ec_device *ec = dev_get_drvdata(dev->parent); 138 bool base_present; 139 int error; 140 141 error = cbas_ec_query_base(ec, true, &base_present); 142 if (error) { 143 dev_warn(dev, "failed to fetch base state on resume: %d\n", 144 error); 145 } else { 146 spin_lock_irq(&cbas_ec_lock); 147 148 cbas_ec.base_present = base_present; 149 150 /* 151 * Only report if base is disconnected. If base is connected, 152 * it will resend its state on resume, and we'll update it 153 * in hammer_event(). 154 */ 155 if (!cbas_ec.base_present) { 156 input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1); 157 input_sync(cbas_ec.input); 158 } 159 160 spin_unlock_irq(&cbas_ec_lock); 161 } 162 163 return 0; 164 } 165 166 static SIMPLE_DEV_PM_OPS(cbas_ec_pm_ops, NULL, cbas_ec_resume); 167 168 static void cbas_ec_set_input(struct input_dev *input) 169 { 170 /* Take the lock so hammer_event() does not race with us here */ 171 spin_lock_irq(&cbas_ec_lock); 172 cbas_ec.input = input; 173 spin_unlock_irq(&cbas_ec_lock); 174 } 175 176 static int __cbas_ec_probe(struct platform_device *pdev) 177 { 178 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); 179 struct input_dev *input; 180 bool base_supported; 181 int error; 182 183 error = cbas_ec_query_base(ec, false, &base_supported); 184 if (error) 185 return error; 186 187 if (!base_supported) 188 return -ENXIO; 189 190 input = devm_input_allocate_device(&pdev->dev); 191 if (!input) 192 return -ENOMEM; 193 194 input->name = "Whiskers Tablet Mode Switch"; 195 input->id.bustype = BUS_HOST; 196 197 input_set_capability(input, EV_SW, SW_TABLET_MODE); 198 199 error = input_register_device(input); 200 if (error) { 201 dev_err(&pdev->dev, "cannot register input device: %d\n", 202 error); 203 return error; 204 } 205 206 /* Seed the state */ 207 error = cbas_ec_query_base(ec, true, &cbas_ec.base_present); 208 if (error) { 209 dev_err(&pdev->dev, "cannot query base state: %d\n", error); 210 return error; 211 } 212 213 if (!cbas_ec.base_present) 214 cbas_ec.base_folded = false; 215 216 dev_dbg(&pdev->dev, "%s: base: %d, folded: %d\n", __func__, 217 cbas_ec.base_present, cbas_ec.base_folded); 218 219 input_report_switch(input, SW_TABLET_MODE, 220 !cbas_ec.base_present || cbas_ec.base_folded); 221 222 cbas_ec_set_input(input); 223 224 cbas_ec.dev = &pdev->dev; 225 cbas_ec.notifier.notifier_call = cbas_ec_notify; 226 error = blocking_notifier_chain_register(&ec->event_notifier, 227 &cbas_ec.notifier); 228 if (error) { 229 dev_err(&pdev->dev, "cannot register notifier: %d\n", error); 230 cbas_ec_set_input(NULL); 231 return error; 232 } 233 234 device_init_wakeup(&pdev->dev, true); 235 return 0; 236 } 237 238 static int cbas_ec_probe(struct platform_device *pdev) 239 { 240 int retval; 241 242 mutex_lock(&cbas_ec_reglock); 243 244 if (cbas_ec.input) { 245 retval = -EBUSY; 246 goto out; 247 } 248 249 retval = __cbas_ec_probe(pdev); 250 251 out: 252 mutex_unlock(&cbas_ec_reglock); 253 return retval; 254 } 255 256 static void cbas_ec_remove(struct platform_device *pdev) 257 { 258 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); 259 260 mutex_lock(&cbas_ec_reglock); 261 262 blocking_notifier_chain_unregister(&ec->event_notifier, 263 &cbas_ec.notifier); 264 cbas_ec_set_input(NULL); 265 266 mutex_unlock(&cbas_ec_reglock); 267 } 268 269 #ifdef CONFIG_ACPI 270 static const struct acpi_device_id cbas_ec_acpi_ids[] = { 271 { "GOOG000B", 0 }, 272 { } 273 }; 274 MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids); 275 #endif 276 277 #ifdef CONFIG_OF 278 static const struct of_device_id cbas_ec_of_match[] = { 279 { .compatible = "google,cros-cbas" }, 280 { }, 281 }; 282 MODULE_DEVICE_TABLE(of, cbas_ec_of_match); 283 #endif 284 285 static struct platform_driver cbas_ec_driver = { 286 .probe = cbas_ec_probe, 287 .remove = cbas_ec_remove, 288 .driver = { 289 .name = "cbas_ec", 290 .acpi_match_table = ACPI_PTR(cbas_ec_acpi_ids), 291 .of_match_table = of_match_ptr(cbas_ec_of_match), 292 .pm = &cbas_ec_pm_ops, 293 }, 294 }; 295 296 #define MAX_BRIGHTNESS 100 297 298 struct hammer_kbd_leds { 299 struct led_classdev cdev; 300 struct hid_device *hdev; 301 u8 buf[2] ____cacheline_aligned; 302 }; 303 304 static int hammer_kbd_brightness_set_blocking(struct led_classdev *cdev, 305 enum led_brightness br) 306 { 307 struct hammer_kbd_leds *led = container_of(cdev, 308 struct hammer_kbd_leds, 309 cdev); 310 int ret; 311 312 led->buf[0] = 0; 313 led->buf[1] = br; 314 315 /* 316 * Request USB HID device to be in Full On mode, so that sending 317 * hardware output report and hardware raw request won't fail. 318 */ 319 ret = hid_hw_power(led->hdev, PM_HINT_FULLON); 320 if (ret < 0) { 321 hid_err(led->hdev, "failed: device not resumed %d\n", ret); 322 return ret; 323 } 324 325 ret = hid_hw_output_report(led->hdev, led->buf, sizeof(led->buf)); 326 if (ret == -ENOSYS) 327 ret = hid_hw_raw_request(led->hdev, 0, led->buf, 328 sizeof(led->buf), 329 HID_OUTPUT_REPORT, 330 HID_REQ_SET_REPORT); 331 if (ret < 0) 332 hid_err(led->hdev, "failed to set keyboard backlight: %d\n", 333 ret); 334 335 /* Request USB HID device back to Normal Mode. */ 336 hid_hw_power(led->hdev, PM_HINT_NORMAL); 337 338 return ret; 339 } 340 341 static int hammer_register_leds(struct hid_device *hdev) 342 { 343 struct hammer_kbd_leds *kbd_backlight; 344 345 kbd_backlight = devm_kzalloc(&hdev->dev, sizeof(*kbd_backlight), 346 GFP_KERNEL); 347 if (!kbd_backlight) 348 return -ENOMEM; 349 350 kbd_backlight->hdev = hdev; 351 kbd_backlight->cdev.name = "hammer::kbd_backlight"; 352 kbd_backlight->cdev.max_brightness = MAX_BRIGHTNESS; 353 kbd_backlight->cdev.brightness_set_blocking = 354 hammer_kbd_brightness_set_blocking; 355 kbd_backlight->cdev.flags = LED_HW_PLUGGABLE; 356 357 /* Set backlight to 0% initially. */ 358 hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0); 359 360 return devm_led_classdev_register(&hdev->dev, &kbd_backlight->cdev); 361 } 362 363 #define HID_UP_GOOGLEVENDOR 0xffd10000 364 #define HID_VD_KBD_FOLDED 0x00000019 365 #define HID_USAGE_KBD_FOLDED (HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED) 366 367 /* HID usage for keyboard backlight (Alphanumeric display brightness) */ 368 #define HID_AD_BRIGHTNESS 0x00140046 369 370 static int hammer_input_mapping(struct hid_device *hdev, struct hid_input *hi, 371 struct hid_field *field, 372 struct hid_usage *usage, 373 unsigned long **bit, int *max) 374 { 375 if (usage->hid == HID_USAGE_KBD_FOLDED) { 376 /* 377 * We do not want to have this usage mapped as it will get 378 * mixed in with "base attached" signal and delivered over 379 * separate input device for tablet switch mode. 380 */ 381 return -1; 382 } 383 384 return 0; 385 } 386 387 static void hammer_folded_event(struct hid_device *hdev, bool folded) 388 { 389 unsigned long flags; 390 391 spin_lock_irqsave(&cbas_ec_lock, flags); 392 393 /* 394 * If we are getting events from Whiskers that means that it 395 * is attached to the lid. 396 */ 397 cbas_ec.base_present = true; 398 cbas_ec.base_folded = folded; 399 hid_dbg(hdev, "%s: base: %d, folded: %d\n", __func__, 400 cbas_ec.base_present, cbas_ec.base_folded); 401 402 if (cbas_ec.input) { 403 input_report_switch(cbas_ec.input, SW_TABLET_MODE, folded); 404 input_sync(cbas_ec.input); 405 } 406 407 spin_unlock_irqrestore(&cbas_ec_lock, flags); 408 } 409 410 static int hammer_event(struct hid_device *hid, struct hid_field *field, 411 struct hid_usage *usage, __s32 value) 412 { 413 if (usage->hid == HID_USAGE_KBD_FOLDED) { 414 hammer_folded_event(hid, value); 415 return 1; /* We handled this event */ 416 } 417 418 return 0; 419 } 420 421 static bool hammer_has_folded_event(struct hid_device *hdev) 422 { 423 return !!hid_find_field(hdev, HID_INPUT_REPORT, 424 HID_GD_KEYBOARD, HID_USAGE_KBD_FOLDED); 425 } 426 427 static bool hammer_has_backlight_control(struct hid_device *hdev) 428 { 429 return !!hid_find_field(hdev, HID_OUTPUT_REPORT, 430 HID_GD_KEYBOARD, HID_AD_BRIGHTNESS); 431 } 432 433 static void hammer_get_folded_state(struct hid_device *hdev) 434 { 435 struct hid_report *report; 436 char *buf; 437 int len, rlen; 438 int a; 439 440 report = hdev->report_enum[HID_INPUT_REPORT].report_id_hash[0x0]; 441 442 if (!report || report->maxfield < 1) 443 return; 444 445 len = hid_report_len(report) + 1; 446 447 buf = kmalloc(len, GFP_KERNEL); 448 if (!buf) 449 return; 450 451 rlen = hid_hw_raw_request(hdev, report->id, buf, len, report->type, HID_REQ_GET_REPORT); 452 453 if (rlen != len) { 454 hid_warn(hdev, "Unable to read base folded state: %d (expected %d)\n", rlen, len); 455 goto out; 456 } 457 458 for (a = 0; a < report->maxfield; a++) { 459 struct hid_field *field = report->field[a]; 460 461 if (field->usage->hid == HID_USAGE_KBD_FOLDED) { 462 u32 value = hid_field_extract(hdev, buf+1, 463 field->report_offset, field->report_size); 464 465 hammer_folded_event(hdev, value); 466 break; 467 } 468 } 469 470 out: 471 kfree(buf); 472 } 473 474 static void hammer_stop(void *hdev) 475 { 476 hid_hw_stop(hdev); 477 } 478 479 static int hammer_probe(struct hid_device *hdev, 480 const struct hid_device_id *id) 481 { 482 struct vivaldi_data *vdata; 483 int error; 484 485 vdata = devm_kzalloc(&hdev->dev, sizeof(*vdata), GFP_KERNEL); 486 if (!vdata) 487 return -ENOMEM; 488 489 hid_set_drvdata(hdev, vdata); 490 491 error = hid_parse(hdev); 492 if (error) 493 return error; 494 495 error = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 496 if (error) 497 return error; 498 499 error = devm_add_action(&hdev->dev, hammer_stop, hdev); 500 if (error) 501 return error; 502 503 /* 504 * We always want to poll for, and handle tablet mode events from 505 * devices that have folded usage, even when nobody has opened the input 506 * device. This also prevents the hid core from dropping early tablet 507 * mode events from the device. 508 */ 509 if (hammer_has_folded_event(hdev)) { 510 hdev->quirks |= HID_QUIRK_ALWAYS_POLL; 511 error = hid_hw_open(hdev); 512 if (error) 513 return error; 514 515 hammer_get_folded_state(hdev); 516 } 517 518 if (hammer_has_backlight_control(hdev)) { 519 error = hammer_register_leds(hdev); 520 if (error) 521 hid_warn(hdev, 522 "Failed to register keyboard backlight: %d\n", 523 error); 524 } 525 526 return 0; 527 } 528 529 static void hammer_remove(struct hid_device *hdev) 530 { 531 unsigned long flags; 532 533 if (hammer_has_folded_event(hdev)) { 534 hid_hw_close(hdev); 535 536 /* 537 * If we are disconnecting then most likely Whiskers is 538 * being removed. Even if it is not removed, without proper 539 * keyboard we should not stay in clamshell mode. 540 * 541 * The reason for doing it here and not waiting for signal 542 * from EC, is that on some devices there are high leakage 543 * on Whiskers pins and we do not detect disconnect reliably, 544 * resulting in devices being stuck in clamshell mode. 545 */ 546 spin_lock_irqsave(&cbas_ec_lock, flags); 547 if (cbas_ec.input && cbas_ec.base_present) { 548 input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1); 549 input_sync(cbas_ec.input); 550 } 551 cbas_ec.base_present = false; 552 spin_unlock_irqrestore(&cbas_ec_lock, flags); 553 } 554 555 /* Unregistering LEDs and stopping the hardware is done via devm */ 556 } 557 558 static const struct hid_device_id hammer_devices[] = { 559 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 560 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) }, 561 { HID_DEVICE(BUS_USB, HID_GROUP_VIVALDI, 562 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) }, 563 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 564 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, 565 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 566 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_JEWEL) }, 567 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 568 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, 569 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 570 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, 571 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 572 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, 573 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 574 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, 575 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 576 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) }, 577 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 578 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WHISKERS) }, 579 { } 580 }; 581 MODULE_DEVICE_TABLE(hid, hammer_devices); 582 583 static struct hid_driver hammer_driver = { 584 .name = "hammer", 585 .id_table = hammer_devices, 586 .probe = hammer_probe, 587 .remove = hammer_remove, 588 .feature_mapping = vivaldi_feature_mapping, 589 .input_mapping = hammer_input_mapping, 590 .event = hammer_event, 591 .driver = { 592 .dev_groups = vivaldi_attribute_groups, 593 }, 594 }; 595 596 static int __init hammer_init(void) 597 { 598 int error; 599 600 error = platform_driver_register(&cbas_ec_driver); 601 if (error) 602 return error; 603 604 error = hid_register_driver(&hammer_driver); 605 if (error) { 606 platform_driver_unregister(&cbas_ec_driver); 607 return error; 608 } 609 610 return 0; 611 } 612 module_init(hammer_init); 613 614 static void __exit hammer_exit(void) 615 { 616 hid_unregister_driver(&hammer_driver); 617 platform_driver_unregister(&cbas_ec_driver); 618 } 619 module_exit(hammer_exit); 620 621 MODULE_DESCRIPTION("HID driver for Google Hammer device."); 622 MODULE_LICENSE("GPL"); 623