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