Skip to content

Commit 4682bb8

Browse files
jwrdegoedeJiri Kosina
authored andcommitted
HID: lg-g15: Add support for the G510's M1-M3 and MR LEDs
Add support for controlling the LEDs below the M1-M3 and MR keys on the G510. Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 1f8cde2 commit 4682bb8

File tree

1 file changed

+90
-3
lines changed

1 file changed

+90
-3
lines changed

drivers/hid/hid-lg-g15.c

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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 ********/
357441
static 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

Comments
 (0)