From patchwork Mon May 20 18:15:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 10952193 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 93F681708 for ; Mon, 20 May 2019 18:15:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 84198288B9 for ; Mon, 20 May 2019 18:15:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 78B24288DC; Mon, 20 May 2019 18:15:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F037288B9 for ; Mon, 20 May 2019 18:15:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727205AbfETSPm (ORCPT ); Mon, 20 May 2019 14:15:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49678 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726447AbfETSPm (ORCPT ); Mon, 20 May 2019 14:15:42 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A77153091753; Mon, 20 May 2019 18:15:41 +0000 (UTC) Received: from shalem.localdomain.com (ovpn-116-135.ams2.redhat.com [10.36.116.135]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8989B5DEA8; Mon, 20 May 2019 18:15:40 +0000 (UTC) From: Hans de Goede To: Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: Hans de Goede , linux-input@vger.kernel.org Subject: [PATCH 4/7] HID: lg-g15: Add support for the M1-M3 and MR LEDs Date: Mon, 20 May 2019 20:15:22 +0200 Message-Id: <20190520181525.4898-5-hdegoede@redhat.com> In-Reply-To: <20190520181525.4898-1-hdegoede@redhat.com> References: <20190520181525.4898-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Mon, 20 May 2019 18:15:41 +0000 (UTC) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support for controlling the LEDs below the M1-M3 and MR keys. Signed-off-by: Hans de Goede --- drivers/hid/hid-lg-g15.c | 54 ++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c index 51c92951975c..3d0909e8f211 100644 --- a/drivers/hid/hid-lg-g15.c +++ b/drivers/hid/hid-lg-g15.c @@ -28,6 +28,11 @@ enum lg_g15_led_type { LG_G15_KBD_BRIGHTNESS, LG_G15_LCD_BRIGHTNESS, LG_G15_BRIGHTNESS_MAX, + LG_G15_MACRO_PRESET1 = 2, + LG_G15_MACRO_PRESET2, + LG_G15_MACRO_PRESET3, + LG_G15_MACRO_RECORD, + LG_G15_LED_MAX }; struct lg_g15_led { @@ -45,7 +50,7 @@ struct lg_g15_data { struct input_dev *input; struct hid_device *hdev; enum lg_g15_model model; - struct lg_g15_led leds[LG_G15_BRIGHTNESS_MAX]; + struct lg_g15_led leds[LG_G15_LED_MAX]; }; static int lg_g15_update_led_brightness(struct lg_g15_data *g15) @@ -62,6 +67,16 @@ static int lg_g15_update_led_brightness(struct lg_g15_data *g15) g15->leds[LG_G15_KBD_BRIGHTNESS].brightness = g15->transfer_buf[1]; g15->leds[LG_G15_LCD_BRIGHTNESS].brightness = g15->transfer_buf[2]; + + g15->leds[LG_G15_MACRO_PRESET1].brightness = + !(g15->transfer_buf[3] & 0x01); + g15->leds[LG_G15_MACRO_PRESET2].brightness = + !(g15->transfer_buf[3] & 0x02); + g15->leds[LG_G15_MACRO_PRESET3].brightness = + !(g15->transfer_buf[3] & 0x04); + g15->leds[LG_G15_MACRO_RECORD].brightness = + !(g15->transfer_buf[3] & 0x08); + return 0; } @@ -86,7 +101,8 @@ static int lg_g15_led_set(struct led_classdev *led_cdev, struct lg_g15_led *g15_led = container_of(led_cdev, struct lg_g15_led, cdev); struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent); - int ret; + u8 val, mask = 0; + int i, ret; /* Ignore LED off on unregister / keyboard unplug */ if (led_cdev->flags & LED_UNREGISTERING) @@ -95,10 +111,26 @@ static int lg_g15_led_set(struct led_classdev *led_cdev, mutex_lock(&g15->mutex); g15->transfer_buf[0] = LG_G15_FEATURE_REPORT; - g15->transfer_buf[1] = g15_led->led + 1; - g15->transfer_buf[2] = brightness << (g15_led->led * 4); g15->transfer_buf[3] = 0; + if (g15_led->led < LG_G15_BRIGHTNESS_MAX) { + g15->transfer_buf[1] = g15_led->led + 1; + g15->transfer_buf[2] = brightness << (g15_led->led * 4); + } else { + for (i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; i++) { + if (i == g15_led->led) + val = brightness; + else + val = g15->leds[i].brightness; + + if (val) + mask |= 1 << (i - LG_G15_MACRO_PRESET1); + } + + g15->transfer_buf[1] = 0x04; + g15->transfer_buf[2] = ~mask; + } + ret = hid_hw_raw_request(g15->hdev, LG_G15_FEATURE_REPORT, g15->transfer_buf, 4, HID_FEATURE_REPORT, HID_REQ_SET_REPORT); @@ -257,14 +289,22 @@ static int lg_g15_register_led(struct lg_g15_data *g15, int i) const char * const led_names[] = { "g15::kbd_backlight", "g15::lcd_backlight", + "g15::macro_preset1", + "g15::macro_preset2", + "g15::macro_preset3", + "g15::macro_record", }; g15->leds[i].led = i; g15->leds[i].cdev.name = led_names[i]; g15->leds[i].cdev.brightness_set_blocking = lg_g15_led_set; g15->leds[i].cdev.brightness_get = lg_g15_led_get; - g15->leds[i].cdev.flags = LED_BRIGHT_HW_CHANGED; - g15->leds[i].cdev.max_brightness = 2; + if (i < LG_G15_BRIGHTNESS_MAX) { + g15->leds[i].cdev.flags = LED_BRIGHT_HW_CHANGED; + g15->leds[i].cdev.max_brightness = 2; + } else { + g15->leds[i].cdev.max_brightness = 1; + } return devm_led_classdev_register(&g15->hdev->dev, &g15->leds[i].cdev); } @@ -375,7 +415,7 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id) goto error_hw_stop; /* Register LED devices */ - for (i = 0; i < LG_G15_BRIGHTNESS_MAX; i++) { + for (i = 0; i < LG_G15_LED_MAX; i++) { ret = lg_g15_register_led(g15, i); if (ret) goto error_hw_stop;