Skip to content

Commit 79085c7

Browse files
dtorJiri Kosina
authored andcommitted
HID: google: whiskers: signal tablet mode switch on disconnect
Currently, the tablet mode switch that takes two signals as its input: base attached switch from the EC and some GMR signal from whiskers when it's folded over. This tablet mode switch is then sent to Chrome, which changes the UI. However, there are some units which have a lot of leakage on the ADC pins that the EC uses to determine whether or not a base is attached. This can result in the base being physically detached, but the EC thinking that it's still attached. The user would then be stuck in laptop mode and wouldn't be able to rotate their display. To work around this let's send "tablet mode" signal when we remove HID interface, which normally happens when we physically disconnect whiskers. Signed-off-by: Dmitry Torokhov <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 38e57f0 commit 79085c7

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

drivers/hid/hid-google-hammer.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,11 +498,33 @@ static int hammer_probe(struct hid_device *hdev,
498498

499499
static void hammer_remove(struct hid_device *hdev)
500500
{
501+
unsigned long flags;
502+
501503
if (hdev->product == USB_DEVICE_ID_GOOGLE_WHISKERS &&
502-
hammer_is_keyboard_interface(hdev))
504+
hammer_is_keyboard_interface(hdev)) {
503505
hid_hw_close(hdev);
504506

507+
/*
508+
* If we are disconnecting then most likely Whiskers is
509+
* being removed. Even if it is not removed, without proper
510+
* keyboard we should not stay in clamshell mode.
511+
*
512+
* The reason for doing it here and not waiting for signal
513+
* from EC, is that on some devices there are high leakage
514+
* on Whiskers pins and we do not detect disconnect reliably,
515+
* resulting in devices being stuck in clamshell mode.
516+
*/
517+
spin_lock_irqsave(&cbas_ec_lock, flags);
518+
if (cbas_ec.input && cbas_ec.base_present) {
519+
input_report_switch(cbas_ec.input, SW_TABLET_MODE, 1);
520+
input_sync(cbas_ec.input);
521+
}
522+
cbas_ec.base_present = false;
523+
spin_unlock_irqrestore(&cbas_ec_lock, flags);
524+
}
525+
505526
hammer_unregister_leds(hdev);
527+
506528
hid_hw_stop(hdev);
507529
}
508530

0 commit comments

Comments
 (0)