@@ -35,6 +35,7 @@ struct cbas_ec {
35
35
struct device * dev ; /* The platform device (EC) */
36
36
struct input_dev * input ;
37
37
bool base_present ;
38
+ bool base_folded ;
38
39
struct notifier_block notifier ;
39
40
};
40
41
@@ -208,7 +209,14 @@ static int __cbas_ec_probe(struct platform_device *pdev)
208
209
return error ;
209
210
}
210
211
211
- input_report_switch (input , SW_TABLET_MODE , !cbas_ec .base_present );
212
+ if (!cbas_ec .base_present )
213
+ cbas_ec .base_folded = false;
214
+
215
+ dev_dbg (& pdev -> dev , "%s: base: %d, folded: %d\n" , __func__ ,
216
+ cbas_ec .base_present , cbas_ec .base_folded );
217
+
218
+ input_report_switch (input , SW_TABLET_MODE ,
219
+ !cbas_ec .base_present || cbas_ec .base_folded );
212
220
213
221
cbas_ec_set_input (input );
214
222
@@ -322,10 +330,9 @@ static int hammer_kbd_brightness_set_blocking(struct led_classdev *cdev,
322
330
static int hammer_register_leds (struct hid_device * hdev )
323
331
{
324
332
struct hammer_kbd_leds * kbd_backlight ;
333
+ int error ;
325
334
326
- kbd_backlight = devm_kzalloc (& hdev -> dev ,
327
- sizeof (* kbd_backlight ),
328
- GFP_KERNEL );
335
+ kbd_backlight = kzalloc (sizeof (* kbd_backlight ), GFP_KERNEL );
329
336
if (!kbd_backlight )
330
337
return - ENOMEM ;
331
338
@@ -339,7 +346,26 @@ static int hammer_register_leds(struct hid_device *hdev)
339
346
/* Set backlight to 0% initially. */
340
347
hammer_kbd_brightness_set_blocking (& kbd_backlight -> cdev , 0 );
341
348
342
- return devm_led_classdev_register (& hdev -> dev , & kbd_backlight -> cdev );
349
+ error = led_classdev_register (& hdev -> dev , & kbd_backlight -> cdev );
350
+ if (error )
351
+ goto err_free_mem ;
352
+
353
+ hid_set_drvdata (hdev , kbd_backlight );
354
+ return 0 ;
355
+
356
+ err_free_mem :
357
+ kfree (kbd_backlight );
358
+ return error ;
359
+ }
360
+
361
+ static void hammer_unregister_leds (struct hid_device * hdev )
362
+ {
363
+ struct hammer_kbd_leds * kbd_backlight = hid_get_drvdata (hdev );
364
+
365
+ if (kbd_backlight ) {
366
+ led_classdev_unregister (& kbd_backlight -> cdev );
367
+ kfree (kbd_backlight );
368
+ }
343
369
}
344
370
345
371
#define HID_UP_GOOGLEVENDOR 0xffd10000
@@ -376,8 +402,9 @@ static int hammer_event(struct hid_device *hid, struct hid_field *field,
376
402
usage -> hid == WHISKERS_KBD_FOLDED ) {
377
403
spin_lock_irqsave (& cbas_ec_lock , flags );
378
404
405
+ cbas_ec .base_folded = value ;
379
406
hid_dbg (hid , "%s: base: %d, folded: %d\n" , __func__ ,
380
- cbas_ec .base_present , value );
407
+ cbas_ec .base_present , cbas_ec . base_folded );
381
408
382
409
/*
383
410
* We should not get event if base is detached, but in case
@@ -436,23 +463,27 @@ static int hammer_probe(struct hid_device *hdev,
436
463
{
437
464
int error ;
438
465
466
+ error = hid_parse (hdev );
467
+ if (error )
468
+ return error ;
469
+
470
+ error = hid_hw_start (hdev , HID_CONNECT_DEFAULT );
471
+ if (error )
472
+ return error ;
473
+
439
474
/*
440
475
* We always want to poll for, and handle tablet mode events from
441
476
* Whiskers, even when nobody has opened the input device. This also
442
477
* prevents the hid core from dropping early tablet mode events from
443
478
* the device.
444
479
*/
445
480
if (hdev -> product == USB_DEVICE_ID_GOOGLE_WHISKERS &&
446
- hammer_is_keyboard_interface (hdev ))
481
+ hammer_is_keyboard_interface (hdev )) {
447
482
hdev -> quirks |= HID_QUIRK_ALWAYS_POLL ;
448
-
449
- error = hid_parse (hdev );
450
- if (error )
451
- return error ;
452
-
453
- error = hid_hw_start (hdev , HID_CONNECT_DEFAULT );
454
- if (error )
455
- return error ;
483
+ error = hid_hw_open (hdev );
484
+ if (error )
485
+ return error ;
486
+ }
456
487
457
488
if (hammer_has_backlight_control (hdev )) {
458
489
error = hammer_register_leds (hdev );
@@ -465,6 +496,15 @@ static int hammer_probe(struct hid_device *hdev,
465
496
return 0 ;
466
497
}
467
498
499
+ static void hammer_remove (struct hid_device * hdev )
500
+ {
501
+ if (hdev -> product == USB_DEVICE_ID_GOOGLE_WHISKERS &&
502
+ hammer_is_keyboard_interface (hdev ))
503
+ hid_hw_close (hdev );
504
+
505
+ hammer_unregister_leds (hdev );
506
+ hid_hw_stop (hdev );
507
+ }
468
508
469
509
static const struct hid_device_id hammer_devices [] = {
470
510
{ HID_DEVICE (BUS_USB , HID_GROUP_GENERIC ,
@@ -483,6 +523,7 @@ static struct hid_driver hammer_driver = {
483
523
.name = "hammer" ,
484
524
.id_table = hammer_devices ,
485
525
.probe = hammer_probe ,
526
+ .remove = hammer_remove ,
486
527
.input_mapping = hammer_input_mapping ,
487
528
.event = hammer_event ,
488
529
};
0 commit comments