@@ -28,6 +28,7 @@ enum lg_g15_model {
28
28
LG_G15_V2 ,
29
29
LG_G510 ,
30
30
LG_G510_USB_AUDIO ,
31
+ LG_Z10 ,
31
32
};
32
33
33
34
enum lg_g15_led_type {
@@ -457,14 +458,34 @@ static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15)
457
458
return ret ;
458
459
459
460
return lg_g510_update_mkey_led_brightness (g15 );
461
+ case LG_Z10 :
462
+ /*
463
+ * Getting the LCD backlight brightness is not supported.
464
+ * Reading Feature(2) fails with -EPIPE and this crashes
465
+ * the LCD and touch keys part of the speakers.
466
+ */
467
+ return 0 ;
460
468
}
461
469
return - EINVAL ; /* Never reached */
462
470
}
463
471
464
472
/******** Input functions ********/
465
473
466
474
/* On the G15 Mark I Logitech has been quite creative with which bit is what */
467
- static int lg_g15_event (struct lg_g15_data * g15 , u8 * data , int size )
475
+ static void lg_g15_handle_lcd_menu_keys (struct lg_g15_data * g15 , u8 * data )
476
+ {
477
+ int i , val ;
478
+
479
+ /* Most left (round/display) button below the LCD */
480
+ input_report_key (g15 -> input , KEY_KBD_LCD_MENU1 , data [8 ] & 0x80 );
481
+ /* 4 other buttons below the LCD */
482
+ for (i = 0 ; i < 4 ; i ++ ) {
483
+ val = data [i + 2 ] & 0x80 ;
484
+ input_report_key (g15 -> input , KEY_KBD_LCD_MENU2 + i , val );
485
+ }
486
+ }
487
+
488
+ static int lg_g15_event (struct lg_g15_data * g15 , u8 * data )
468
489
{
469
490
int i , val ;
470
491
@@ -494,13 +515,7 @@ static int lg_g15_event(struct lg_g15_data *g15, u8 *data, int size)
494
515
/* MR */
495
516
input_report_key (g15 -> input , KEY_MACRO_RECORD_START , data [7 ] & 0x40 );
496
517
497
- /* Most left (round) button below the LCD */
498
- input_report_key (g15 -> input , KEY_KBD_LCD_MENU1 , data [8 ] & 0x80 );
499
- /* 4 other buttons below the LCD */
500
- for (i = 0 ; i < 4 ; i ++ ) {
501
- val = data [i + 2 ] & 0x80 ;
502
- input_report_key (g15 -> input , KEY_KBD_LCD_MENU2 + i , val );
503
- }
518
+ lg_g15_handle_lcd_menu_keys (g15 , data );
504
519
505
520
/* Backlight cycle button pressed? */
506
521
if (data [1 ] & 0x80 )
@@ -510,7 +525,7 @@ static int lg_g15_event(struct lg_g15_data *g15, u8 *data, int size)
510
525
return 0 ;
511
526
}
512
527
513
- static int lg_g15_v2_event (struct lg_g15_data * g15 , u8 * data , int size )
528
+ static int lg_g15_v2_event (struct lg_g15_data * g15 , u8 * data )
514
529
{
515
530
int i , val ;
516
531
@@ -542,7 +557,7 @@ static int lg_g15_v2_event(struct lg_g15_data *g15, u8 *data, int size)
542
557
return 0 ;
543
558
}
544
559
545
- static int lg_g510_event (struct lg_g15_data * g15 , u8 * data , int size )
560
+ static int lg_g510_event (struct lg_g15_data * g15 , u8 * data )
546
561
{
547
562
bool game_mode_enabled ;
548
563
int i , val ;
@@ -586,7 +601,7 @@ static int lg_g510_event(struct lg_g15_data *g15, u8 *data, int size)
586
601
return 0 ;
587
602
}
588
603
589
- static int lg_g510_leds_event (struct lg_g15_data * g15 , u8 * data , int size )
604
+ static int lg_g510_leds_event (struct lg_g15_data * g15 , u8 * data )
590
605
{
591
606
bool backlight_disabled ;
592
607
@@ -613,18 +628,24 @@ static int lg_g15_raw_event(struct hid_device *hdev, struct hid_report *report,
613
628
switch (g15 -> model ) {
614
629
case LG_G15 :
615
630
if (data [0 ] == 0x02 && size == 9 )
616
- return lg_g15_event (g15 , data , size );
631
+ return lg_g15_event (g15 , data );
617
632
break ;
618
633
case LG_G15_V2 :
619
634
if (data [0 ] == 0x02 && size == 5 )
620
- return lg_g15_v2_event (g15 , data , size );
635
+ return lg_g15_v2_event (g15 , data );
636
+ break ;
637
+ case LG_Z10 :
638
+ if (data [0 ] == 0x02 && size == 9 ) {
639
+ lg_g15_handle_lcd_menu_keys (g15 , data );
640
+ input_sync (g15 -> input );
641
+ }
621
642
break ;
622
643
case LG_G510 :
623
644
case LG_G510_USB_AUDIO :
624
645
if (data [0 ] == 0x03 && size == 5 )
625
- return lg_g510_event (g15 , data , size );
646
+ return lg_g510_event (g15 , data );
626
647
if (data [0 ] == 0x04 && size == 2 )
627
- return lg_g510_leds_event (g15 , data , size );
648
+ return lg_g510_leds_event (g15 , data );
628
649
break ;
629
650
}
630
651
@@ -645,25 +666,18 @@ static void lg_g15_input_close(struct input_dev *dev)
645
666
hid_hw_close (hdev );
646
667
}
647
668
648
- static int lg_g15_register_led (struct lg_g15_data * g15 , int i )
669
+ static int lg_g15_register_led (struct lg_g15_data * g15 , int i , const char * name )
649
670
{
650
- static const char * const led_names [] = {
651
- "g15::kbd_backlight" ,
652
- "g15::lcd_backlight" ,
653
- "g15::macro_preset1" ,
654
- "g15::macro_preset2" ,
655
- "g15::macro_preset3" ,
656
- "g15::macro_record" ,
657
- };
658
-
659
671
g15 -> leds [i ].led = i ;
660
- g15 -> leds [i ].cdev .name = led_names [ i ] ;
672
+ g15 -> leds [i ].cdev .name = name ;
661
673
662
674
switch (g15 -> model ) {
663
675
case LG_G15 :
664
676
case LG_G15_V2 :
665
- g15 -> leds [i ].cdev .brightness_set_blocking = lg_g15_led_set ;
666
677
g15 -> leds [i ].cdev .brightness_get = lg_g15_led_get ;
678
+ fallthrough ;
679
+ case LG_Z10 :
680
+ g15 -> leds [i ].cdev .brightness_set_blocking = lg_g15_led_set ;
667
681
if (i < LG_G15_BRIGHTNESS_MAX ) {
668
682
g15 -> leds [i ].cdev .flags = LED_BRIGHT_HW_CHANGED ;
669
683
g15 -> leds [i ].cdev .max_brightness = 2 ;
@@ -702,8 +716,38 @@ static int lg_g15_register_led(struct lg_g15_data *g15, int i)
702
716
return devm_led_classdev_register (& g15 -> hdev -> dev , & g15 -> leds [i ].cdev );
703
717
}
704
718
719
+ /* Common input device init code shared between keyboards and Z-10 speaker handling */
720
+ static void lg_g15_init_input_dev (struct hid_device * hdev , struct input_dev * input ,
721
+ const char * name )
722
+ {
723
+ int i ;
724
+
725
+ input -> name = name ;
726
+ input -> phys = hdev -> phys ;
727
+ input -> uniq = hdev -> uniq ;
728
+ input -> id .bustype = hdev -> bus ;
729
+ input -> id .vendor = hdev -> vendor ;
730
+ input -> id .product = hdev -> product ;
731
+ input -> id .version = hdev -> version ;
732
+ input -> dev .parent = & hdev -> dev ;
733
+ input -> open = lg_g15_input_open ;
734
+ input -> close = lg_g15_input_close ;
735
+
736
+ /* Keys below the LCD, intended for controlling a menu on the LCD */
737
+ for (i = 0 ; i < 5 ; i ++ )
738
+ input_set_capability (input , EV_KEY , KEY_KBD_LCD_MENU1 + i );
739
+ }
740
+
705
741
static int lg_g15_probe (struct hid_device * hdev , const struct hid_device_id * id )
706
742
{
743
+ static const char * const led_names [] = {
744
+ "g15::kbd_backlight" ,
745
+ "g15::lcd_backlight" ,
746
+ "g15::macro_preset1" ,
747
+ "g15::macro_preset2" ,
748
+ "g15::macro_preset3" ,
749
+ "g15::macro_record" ,
750
+ };
707
751
u8 gkeys_settings_output_report = 0 ;
708
752
u8 gkeys_settings_feature_report = 0 ;
709
753
struct hid_report_enum * rep_enum ;
@@ -744,6 +788,8 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
744
788
745
789
g15 -> hdev = hdev ;
746
790
g15 -> model = id -> driver_data ;
791
+ g15 -> input = input ;
792
+ input_set_drvdata (input , hdev );
747
793
hid_set_drvdata (hdev , (void * )g15 );
748
794
749
795
switch (g15 -> model ) {
@@ -772,6 +818,9 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
772
818
gkeys_settings_feature_report = 0x01 ;
773
819
gkeys = 18 ;
774
820
break ;
821
+ case LG_Z10 :
822
+ connect_mask = HID_CONNECT_HIDRAW ;
823
+ break ;
775
824
}
776
825
777
826
ret = hid_hw_start (hdev , connect_mask );
@@ -814,17 +863,21 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
814
863
if (ret )
815
864
goto error_hw_stop ;
816
865
866
+ if (g15 -> model == LG_Z10 ) {
867
+ lg_g15_init_input_dev (hdev , g15 -> input , "Logitech Z-10 LCD Menu Keys" );
868
+ ret = input_register_device (g15 -> input );
869
+ if (ret )
870
+ goto error_hw_stop ;
871
+
872
+ ret = lg_g15_register_led (g15 , 1 , "z-10::lcd_backlight" );
873
+ if (ret )
874
+ goto error_hw_stop ;
875
+
876
+ return 0 ; /* All done */
877
+ }
878
+
817
879
/* Setup and register input device */
818
- input -> name = "Logitech Gaming Keyboard Gaming Keys" ;
819
- input -> phys = hdev -> phys ;
820
- input -> uniq = hdev -> uniq ;
821
- input -> id .bustype = hdev -> bus ;
822
- input -> id .vendor = hdev -> vendor ;
823
- input -> id .product = hdev -> product ;
824
- input -> id .version = hdev -> version ;
825
- input -> dev .parent = & hdev -> dev ;
826
- input -> open = lg_g15_input_open ;
827
- input -> close = lg_g15_input_close ;
880
+ lg_g15_init_input_dev (hdev , input , "Logitech Gaming Keyboard Gaming Keys" );
828
881
829
882
/* G-keys */
830
883
for (i = 0 ; i < gkeys ; i ++ )
@@ -835,10 +888,6 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
835
888
input_set_capability (input , EV_KEY , KEY_MACRO_PRESET1 + i );
836
889
input_set_capability (input , EV_KEY , KEY_MACRO_RECORD_START );
837
890
838
- /* Keys below the LCD, intended for controlling a menu on the LCD */
839
- for (i = 0 ; i < 5 ; i ++ )
840
- input_set_capability (input , EV_KEY , KEY_KBD_LCD_MENU1 + i );
841
-
842
891
/*
843
892
* On the G510 only report headphone and mic mute keys when *not* using
844
893
* the builtin USB audio device. When the builtin audio is used these
@@ -850,16 +899,13 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
850
899
input_set_capability (input , EV_KEY , KEY_F20 );
851
900
}
852
901
853
- g15 -> input = input ;
854
- input_set_drvdata (input , hdev );
855
-
856
902
ret = input_register_device (input );
857
903
if (ret )
858
904
goto error_hw_stop ;
859
905
860
906
/* Register LED devices */
861
907
for (i = 0 ; i < LG_G15_LED_MAX ; i ++ ) {
862
- ret = lg_g15_register_led (g15 , i );
908
+ ret = lg_g15_register_led (g15 , i , led_names [ i ] );
863
909
if (ret )
864
910
goto error_hw_stop ;
865
911
}
@@ -890,6 +936,10 @@ static const struct hid_device_id lg_g15_devices[] = {
890
936
{ HID_USB_DEVICE (USB_VENDOR_ID_LOGITECH ,
891
937
USB_DEVICE_ID_LOGITECH_G510_USB_AUDIO ),
892
938
.driver_data = LG_G510_USB_AUDIO },
939
+ /* Z-10 speakers */
940
+ { HID_USB_DEVICE (USB_VENDOR_ID_LOGITECH ,
941
+ USB_DEVICE_ID_LOGITECH_Z_10_SPK ),
942
+ .driver_data = LG_Z10 },
893
943
{ }
894
944
};
895
945
MODULE_DEVICE_TABLE (hid , lg_g15_devices );
@@ -902,4 +952,5 @@ static struct hid_driver lg_g15_driver = {
902
952
};
903
953
module_hid_driver (lg_g15_driver );
904
954
955
+ MODULE_AUTHOR (
"Hans de Goede <[email protected] >" );
905
956
MODULE_LICENSE ("GPL" );
0 commit comments