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/leds.h> 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/platform_data/cros_ec_commands.h> 22 #include <linux/platform_data/cros_ec_proto.h> 23 #include <linux/platform_device.h> 24 #include <linux/pm_wakeup.h> 25 #include <asm/unaligned.h> 26 27 #include "hid-ids.h" 28 29 /* 30 * C(hrome)B(ase)A(ttached)S(witch) - switch exported by Chrome EC and reporting 31 * state of the "Whiskers" base - attached or detached. Whiskers USB device also 32 * reports position of the keyboard - folded or not. Combining base state and 33 * position allows us to generate proper "Tablet mode" events. 34 */ 35 struct cbas_ec { 36 struct device *dev; /* The platform device (EC) */ 37 struct input_dev *input; 38 bool base_present; 39 bool base_folded; 40 struct notifier_block notifier; 41 }; 42 43 static struct cbas_ec cbas_ec; 44 static DEFINE_SPINLOCK(cbas_ec_lock); 45 static DEFINE_MUTEX(cbas_ec_reglock); 46 47 static bool cbas_parse_base_state(const void *data) 48 { 49 u32 switches = get_unaligned_le32(data); 50 51 return !!(switches & BIT(EC_MKBP_BASE_ATTACHED)); 52 } 53 54 static int cbas_ec_query_base(struct cros_ec_device *ec_dev, bool get_state, 55 bool *state) 56 { 57 struct ec_params_mkbp_info *params; 58 struct cros_ec_command *msg; 59 int ret; 60 61 msg = kzalloc(sizeof(*msg) + max(sizeof(u32), sizeof(*params)), 62 GFP_KERNEL); 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 int 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 return 0; 268 } 269 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 276 #ifdef CONFIG_OF 277 static const struct of_device_id cbas_ec_of_match[] = { 278 { .compatible = "google,cros-cbas" }, 279 { }, 280 }; 281 MODULE_DEVICE_TABLE(of, cbas_ec_of_match); 282 #endif 283 284 static struct platform_driver cbas_ec_driver = { 285 .probe = cbas_ec_probe, 286 .remove = cbas_ec_remove, 287 .driver = { 288 .name = "cbas_ec", 289 .acpi_match_table = ACPI_PTR(cbas_ec_acpi_ids), 290 .of_match_table = of_match_ptr(cbas_ec_of_match), 291 .pm = &cbas_ec_pm_ops, 292 }, 293 }; 294 295 #define MAX_BRIGHTNESS 100 296 297 struct hammer_kbd_leds { 298 struct led_classdev cdev; 299 struct hid_device *hdev; 300 u8 buf[2] ____cacheline_aligned; 301 }; 302 303 static int hammer_kbd_brightness_set_blocking(struct led_classdev *cdev, 304 enum led_brightness br) 305 { 306 struct hammer_kbd_leds *led = container_of(cdev, 307 struct hammer_kbd_leds, 308 cdev); 309 int ret; 310 311 led->buf[0] = 0; 312 led->buf[1] = br; 313 314 /* 315 * Request USB HID device to be in Full On mode, so that sending 316 * hardware output report and hardware raw request won't fail. 317 */ 318 ret = hid_hw_power(led->hdev, PM_HINT_FULLON); 319 if (ret < 0) { 320 hid_err(led->hdev, "failed: device not resumed %d\n", ret); 321 return ret; 322 } 323 324 ret = hid_hw_output_report(led->hdev, led->buf, sizeof(led->buf)); 325 if (ret == -ENOSYS) 326 ret = hid_hw_raw_request(led->hdev, 0, led->buf, 327 sizeof(led->buf), 328 HID_OUTPUT_REPORT, 329 HID_REQ_SET_REPORT); 330 if (ret < 0) 331 hid_err(led->hdev, "failed to set keyboard backlight: %d\n", 332 ret); 333 334 /* Request USB HID device back to Normal Mode. */ 335 hid_hw_power(led->hdev, PM_HINT_NORMAL); 336 337 return ret; 338 } 339 340 static int hammer_register_leds(struct hid_device *hdev) 341 { 342 struct hammer_kbd_leds *kbd_backlight; 343 int error; 344 345 kbd_backlight = kzalloc(sizeof(*kbd_backlight), GFP_KERNEL); 346 if (!kbd_backlight) 347 return -ENOMEM; 348 349 kbd_backlight->hdev = hdev; 350 kbd_backlight->cdev.name = "hammer::kbd_backlight"; 351 kbd_backlight->cdev.max_brightness = MAX_BRIGHTNESS; 352 kbd_backlight->cdev.brightness_set_blocking = 353 hammer_kbd_brightness_set_blocking; 354 kbd_backlight->cdev.flags = LED_HW_PLUGGABLE; 355 356 /* Set backlight to 0% initially. */ 357 hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0); 358 359 error = led_classdev_register(&hdev->dev, &kbd_backlight->cdev); 360 if (error) 361 goto err_free_mem; 362 363 hid_set_drvdata(hdev, kbd_backlight); 364 return 0; 365 366 err_free_mem: 367 kfree(kbd_backlight); 368 return error; 369 } 370 371 static void hammer_unregister_leds(struct hid_device *hdev) 372 { 373 struct hammer_kbd_leds *kbd_backlight = hid_get_drvdata(hdev); 374 375 if (kbd_backlight) { 376 led_classdev_unregister(&kbd_backlight->cdev); 377 kfree(kbd_backlight); 378 } 379 } 380 381 #define HID_UP_GOOGLEVENDOR 0xffd10000 382 #define HID_VD_KBD_FOLDED 0x00000019 383 #define HID_USAGE_KBD_FOLDED (HID_UP_GOOGLEVENDOR | HID_VD_KBD_FOLDED) 384 385 /* HID usage for keyboard backlight (Alphanumeric display brightness) */ 386 #define HID_AD_BRIGHTNESS 0x00140046 387 388 static int hammer_input_mapping(struct hid_device *hdev, struct hid_input *hi, 389 struct hid_field *field, 390 struct hid_usage *usage, 391 unsigned long **bit, int *max) 392 { 393 if (usage->hid == HID_USAGE_KBD_FOLDED) { 394 /* 395 * We do not want to have this usage mapped as it will get 396 * mixed in with "base attached" signal and delivered over 397 * separate input device for tablet switch mode. 398 */ 399 return -1; 400 } 401 402 return 0; 403 } 404 405 static void hammer_folded_event(struct hid_device *hdev, bool folded) 406 { 407 unsigned long flags; 408 409 spin_lock_irqsave(&cbas_ec_lock, flags); 410 411 /* 412 * If we are getting events from Whiskers that means that it 413 * is attached to the lid. 414 */ 415 cbas_ec.base_present = true; 416 cbas_ec.base_folded = folded; 417 hid_dbg(hdev, "%s: base: %d, folded: %d\n", __func__, 418 cbas_ec.base_present, cbas_ec.base_folded); 419 420 if (cbas_ec.input) { 421 input_report_switch(cbas_ec.input, SW_TABLET_MODE, folded); 422 input_sync(cbas_ec.input); 423 } 424 425 spin_unlock_irqrestore(&cbas_ec_lock, flags); 426 } 427 428 static int hammer_event(struct hid_device *hid, struct hid_field *field, 429 struct hid_usage *usage, __s32 value) 430 { 431 if (usage->hid == HID_USAGE_KBD_FOLDED) { 432 hammer_folded_event(hid, value); 433 return 1; /* We handled this event */ 434 } 435 436 return 0; 437 } 438 439 static bool hammer_has_usage(struct hid_device *hdev, unsigned int report_type, 440 unsigned application, unsigned usage) 441 { 442 struct hid_report_enum *re = &hdev->report_enum[report_type]; 443 struct hid_report *report; 444 int i, j; 445 446 list_for_each_entry(report, &re->report_list, list) { 447 if (report->application != application) 448 continue; 449 450 for (i = 0; i < report->maxfield; i++) { 451 struct hid_field *field = report->field[i]; 452 453 for (j = 0; j < field->maxusage; j++) 454 if (field->usage[j].hid == usage) 455 return true; 456 } 457 } 458 459 return false; 460 } 461 462 static bool hammer_has_folded_event(struct hid_device *hdev) 463 { 464 return hammer_has_usage(hdev, HID_INPUT_REPORT, 465 HID_GD_KEYBOARD, HID_USAGE_KBD_FOLDED); 466 } 467 468 static bool hammer_has_backlight_control(struct hid_device *hdev) 469 { 470 return hammer_has_usage(hdev, HID_OUTPUT_REPORT, 471 HID_GD_KEYBOARD, HID_AD_BRIGHTNESS); 472 } 473 474 static void hammer_get_folded_state(struct hid_device *hdev) 475 { 476 struct hid_report *report; 477 char *buf; 478 int len, rlen; 479 int a; 480 481 report = hdev->report_enum[HID_INPUT_REPORT].report_id_hash[0x0]; 482 483 if (!report || report->maxfield < 1) 484 return; 485 486 len = hid_report_len(report) + 1; 487 488 buf = kmalloc(len, GFP_KERNEL); 489 if (!buf) 490 return; 491 492 rlen = hid_hw_raw_request(hdev, report->id, buf, len, report->type, HID_REQ_GET_REPORT); 493 494 if (rlen != len) { 495 hid_warn(hdev, "Unable to read base folded state: %d (expected %d)\n", rlen, len); 496 goto out; 497 } 498 499 for (a = 0; a < report->maxfield; a++) { 500 struct hid_field *field = report->field[a]; 501 502 if (field->usage->hid == HID_USAGE_KBD_FOLDED) { 503 u32 value = hid_field_extract(hdev, buf+1, 504 field->report_offset, field->report_size); 505 506 hammer_folded_event(hdev, value); 507 break; 508 } 509 } 510 511 out: 512 kfree(buf); 513 } 514 515 static int hammer_probe(struct hid_device *hdev, 516 const struct hid_device_id *id) 517 { 518 int error; 519 520 error = hid_parse(hdev); 521 if (error) 522 return error; 523 524 error = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 525 if (error) 526 return error; 527 528 /* 529 * We always want to poll for, and handle tablet mode events from 530 * devices that have folded usage, even when nobody has opened the input 531 * device. This also prevents the hid core from dropping early tablet 532 * mode events from the device. 533 */ 534 if (hammer_has_folded_event(hdev)) { 535 hdev->quirks |= HID_QUIRK_ALWAYS_POLL; 536 error = hid_hw_open(hdev); 537 if (error) 538 return error; 539 540 hammer_get_folded_state(hdev); 541 } 542 543 if (hammer_has_backlight_control(hdev)) { 544 error = hammer_register_leds(hdev); 545 if (error) 546 hid_warn(hdev, 547 "Failed to register keyboard backlight: %d\n", 548 error); 549 } 550 551 return 0; 552 } 553 554 static void hammer_remove(struct hid_device *hdev) 555 { 556 unsigned long flags; 557 558 if (hammer_has_folded_event(hdev)) { 559 hid_hw_close(hdev); 560 561 /* 562 * If we are disconnecting then most likely Whiskers is 563 * being removed. Even if it is not removed, without proper 564 * keyboard we should not stay in clamshell mode. 565 * 566 * The reason for doing it here and not waiting for signal 567 * from EC, is that on some devices there are high leakage 568 * on Whiskers pins and we do not detect disconnect reliably, 569 * resulting in devices being stuck in clamshell mode. 570 */ 571 spin_lock_irqsave(&cbas_ec_lock, flags); 572 if (cbas_ec.input && cbas_ec.base_present) { 573 input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1); 574 input_sync(cbas_ec.input); 575 } 576 cbas_ec.base_present = false; 577 spin_unlock_irqrestore(&cbas_ec_lock, flags); 578 } 579 580 hammer_unregister_leds(hdev); 581 582 hid_hw_stop(hdev); 583 } 584 585 static const struct hid_device_id hammer_devices[] = { 586 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 587 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) }, 588 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 589 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) }, 590 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 591 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, 592 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 593 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, 594 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 595 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, 596 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 597 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, 598 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 599 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, 600 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 601 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) }, 602 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 603 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WHISKERS) }, 604 { } 605 }; 606 MODULE_DEVICE_TABLE(hid, hammer_devices); 607 608 static struct hid_driver hammer_driver = { 609 .name = "hammer", 610 .id_table = hammer_devices, 611 .probe = hammer_probe, 612 .remove = hammer_remove, 613 .input_mapping = hammer_input_mapping, 614 .event = hammer_event, 615 }; 616 617 static int __init hammer_init(void) 618 { 619 int error; 620 621 error = platform_driver_register(&cbas_ec_driver); 622 if (error) 623 return error; 624 625 error = hid_register_driver(&hammer_driver); 626 if (error) { 627 platform_driver_unregister(&cbas_ec_driver); 628 return error; 629 } 630 631 return 0; 632 } 633 module_init(hammer_init); 634 635 static void __exit hammer_exit(void) 636 { 637 hid_unregister_driver(&hammer_driver); 638 platform_driver_unregister(&cbas_ec_driver); 639 } 640 module_exit(hammer_exit); 641 642 MODULE_LICENSE("GPL"); 643