@@ -353,6 +353,90 @@ static void lg_g510_leds_sync_work(struct work_struct *work)
353353 mutex_unlock (& g15 -> mutex );
354354}
355355
356+ static int lg_g510_update_mkey_led_brightness (struct lg_g15_data * g15 )
357+ {
358+ int ret ;
359+
360+ ret = hid_hw_raw_request (g15 -> hdev , LG_G510_FEATURE_M_KEYS_LEDS ,
361+ g15 -> transfer_buf , 2 ,
362+ HID_FEATURE_REPORT , HID_REQ_GET_REPORT );
363+ if (ret != 2 ) {
364+ hid_err (g15 -> hdev , "Error getting LED brightness: %d\n" , ret );
365+ ret = (ret < 0 ) ? ret : - EIO ;
366+ }
367+
368+ g15 -> leds [LG_G15_MACRO_PRESET1 ].brightness =
369+ !!(g15 -> transfer_buf [1 ] & 0x80 );
370+ g15 -> leds [LG_G15_MACRO_PRESET2 ].brightness =
371+ !!(g15 -> transfer_buf [1 ] & 0x40 );
372+ g15 -> leds [LG_G15_MACRO_PRESET3 ].brightness =
373+ !!(g15 -> transfer_buf [1 ] & 0x20 );
374+ g15 -> leds [LG_G15_MACRO_RECORD ].brightness =
375+ !!(g15 -> transfer_buf [1 ] & 0x10 );
376+
377+ return 0 ;
378+ }
379+
380+ static enum led_brightness lg_g510_mkey_led_get (struct led_classdev * led_cdev )
381+ {
382+ struct lg_g15_led * g15_led =
383+ container_of (led_cdev , struct lg_g15_led , cdev );
384+ struct lg_g15_data * g15 = dev_get_drvdata (led_cdev -> dev -> parent );
385+ enum led_brightness brightness ;
386+
387+ mutex_lock (& g15 -> mutex );
388+ lg_g510_update_mkey_led_brightness (g15 );
389+ brightness = g15 -> leds [g15_led -> led ].brightness ;
390+ mutex_unlock (& g15 -> mutex );
391+
392+ return brightness ;
393+ }
394+
395+ static int lg_g510_mkey_led_set (struct led_classdev * led_cdev ,
396+ enum led_brightness brightness )
397+ {
398+ struct lg_g15_led * g15_led =
399+ container_of (led_cdev , struct lg_g15_led , cdev );
400+ struct lg_g15_data * g15 = dev_get_drvdata (led_cdev -> dev -> parent );
401+ u8 val , mask = 0 ;
402+ int i , ret ;
403+
404+ /* Ignore LED off on unregister / keyboard unplug */
405+ if (led_cdev -> flags & LED_UNREGISTERING )
406+ return 0 ;
407+
408+ mutex_lock (& g15 -> mutex );
409+
410+ for (i = LG_G15_MACRO_PRESET1 ; i < LG_G15_LED_MAX ; i ++ ) {
411+ if (i == g15_led -> led )
412+ val = brightness ;
413+ else
414+ val = g15 -> leds [i ].brightness ;
415+
416+ if (val )
417+ mask |= 0x80 >> (i - LG_G15_MACRO_PRESET1 );
418+ }
419+
420+ g15 -> transfer_buf [0 ] = LG_G510_FEATURE_M_KEYS_LEDS ;
421+ g15 -> transfer_buf [1 ] = mask ;
422+
423+ ret = hid_hw_raw_request (g15 -> hdev , LG_G510_FEATURE_M_KEYS_LEDS ,
424+ g15 -> transfer_buf , 2 ,
425+ HID_FEATURE_REPORT , HID_REQ_SET_REPORT );
426+ if (ret == 2 ) {
427+ /* Success */
428+ g15_led -> brightness = brightness ;
429+ ret = 0 ;
430+ } else {
431+ hid_err (g15 -> hdev , "Error setting LED brightness: %d\n" , ret );
432+ ret = (ret < 0 ) ? ret : - EIO ;
433+ }
434+
435+ mutex_unlock (& g15 -> mutex );
436+
437+ return ret ;
438+ }
439+
356440/******** Generic LED functions ********/
357441static int lg_g15_get_initial_led_brightness (struct lg_g15_data * g15 )
358442{
@@ -372,7 +456,7 @@ static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15)
372456 if (ret )
373457 return ret ;
374458
375- return 0 ;
459+ return lg_g510_update_mkey_led_brightness ( g15 ) ;
376460 }
377461 return - EINVAL ; /* Never reached */
378462}
@@ -606,8 +690,11 @@ static int lg_g15_register_led(struct lg_g15_data *g15, int i)
606690 g15 -> leds [i ].cdev .groups = lg_g510_kbd_led_groups ;
607691 break ;
608692 default :
609- /* TODO: Add support for M1 - M3 and MR leds */
610- return 0 ;
693+ g15 -> leds [i ].cdev .brightness_set_blocking =
694+ lg_g510_mkey_led_set ;
695+ g15 -> leds [i ].cdev .brightness_get =
696+ lg_g510_mkey_led_get ;
697+ g15 -> leds [i ].cdev .max_brightness = 1 ;
611698 }
612699 break ;
613700 }
0 commit comments