From patchwork Sun Jul 31 15:23:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 9253397 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D4614601C0 for ; Sun, 31 Jul 2016 15:23:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5E2E2848A for ; Sun, 31 Jul 2016 15:23:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9D382848B; Sun, 31 Jul 2016 15:23:39 +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=-6.9 required=2.0 tests=BAYES_00,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 538D42848E for ; Sun, 31 Jul 2016 15:23:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753778AbcGaPXh (ORCPT ); Sun, 31 Jul 2016 11:23:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44204 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753359AbcGaPXf (ORCPT ); Sun, 31 Jul 2016 11:23:35 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1B4A820279; Sun, 31 Jul 2016 15:23:22 +0000 (UTC) Received: from shalem.localdomain.com (vpn1-6-127.ams2.redhat.com [10.36.6.127]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u6VFNCw2006607; Sun, 31 Jul 2016 11:23:19 -0400 From: Hans de Goede To: Dmitry Torokhov , Rob Herring Cc: Maxime Ripard , Chen-Yu Tsai , linux-input@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree , Hans de Goede Subject: [PATCH 2/4] input: touchscreen: Add LED trigger support to the softbutton code Date: Sun, 31 Jul 2016 17:23:08 +0200 Message-Id: <1469978590-14081-3-git-send-email-hdegoede@redhat.com> In-Reply-To: <1469978590-14081-1-git-send-email-hdegoede@redhat.com> References: <1469978590-14081-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Sun, 31 Jul 2016 15:23:22 +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 In some hardware there are 1 or more LEDs behind the touchscreen softbuttons, which are intended to provide visual feedback to the user that the softbutton has been pressed, this commit adds support for this. Signed-off-by: Hans de Goede --- .../bindings/input/touchscreen/softbuttons.txt | 4 ++ drivers/input/touchscreen/softbuttons.c | 49 +++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt index 3eb6f4c..b425b95 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/softbuttons.txt @@ -17,6 +17,10 @@ Required subnode-properties: - softbutton-min-y : Y start of the area the softbutton area covers - softbutton-max-y : Y end of the area the softbutton area covers +Optional subnode-properties: +- linux,led-trigger : String for a LED trigger for providing visual + feedback that the softbutton has been pressed + Example: #include diff --git a/drivers/input/touchscreen/softbuttons.c b/drivers/input/touchscreen/softbuttons.c index 47aea18..9a3fbfa 100644 --- a/drivers/input/touchscreen/softbuttons.c +++ b/drivers/input/touchscreen/softbuttons.c @@ -11,6 +11,7 @@ #include #include +#include #include struct touchscreen_softbutton { @@ -19,6 +20,8 @@ struct touchscreen_softbutton { u32 min_y; u32 max_y; u32 keycode; + const char *ledtrigger_name; + struct led_trigger *ledtrigger; }; struct touchscreen_softbutton_info { @@ -48,7 +51,7 @@ struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons( struct device *dev = input->dev.parent; struct device_node *np, *pp; struct touchscreen_softbutton_info *info; - int i, err, button_count; + int i, j, err, button_count; np = dev->of_node; if (!np) @@ -103,6 +106,36 @@ struct touchscreen_softbutton_info *devm_touchscreen_alloc_softbuttons( dev_err(dev, "%s: Inval max-y prop\n", pp->name); return ERR_PTR(-EINVAL); } + + err = of_property_read_string(pp, "linux,led-trigger", + &btn->ledtrigger_name); + if (err) + continue; /* The LED trigger is optional */ + + /* Check if another softbutton uses the same trigger */ + for (j = 0; j < i; j++) { + if (info->buttons[j].ledtrigger_name && + strcmp(info->buttons[j].ledtrigger_name, + btn->ledtrigger_name) == 0) { + btn->ledtrigger = info->buttons[j].ledtrigger; + break; + } + } + if (!btn->ledtrigger) { + btn->ledtrigger = + devm_kzalloc(dev, sizeof(*btn->ledtrigger), + GFP_KERNEL); + if (!btn->ledtrigger) + return ERR_PTR(-ENOMEM); + + btn->ledtrigger->name = btn->ledtrigger_name; + err = devm_led_trigger_register(dev, btn->ledtrigger); + if (err) { + dev_err(dev, "%s: Ledtrigger register error\n", + pp->name); + return ERR_PTR(err); + } + } } __set_bit(EV_KEY, input->evbit); @@ -126,6 +159,7 @@ bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info, unsigned int x, unsigned int y, bool down) { int i; + unsigned long led_delay = 1000; /* Keep the led on 1s after release */ if (info == NULL) return false; @@ -137,6 +171,19 @@ bool touchscreen_handle_softbuttons(struct touchscreen_softbutton_info *info, y <= info->buttons[i].max_y) { input_report_key(info->input, info->buttons[i].keycode, down); + + if (info->buttons[i].ledtrigger && down) { + led_trigger_event(info->buttons[i].ledtrigger, + LED_FULL); + } else if (info->buttons[i].ledtrigger && !down) { + /* Led must be off before calling blink */ + led_trigger_event(info->buttons[i].ledtrigger, + LED_OFF); + led_trigger_blink_oneshot( + info->buttons[i].ledtrigger, + &led_delay, &led_delay, 0); + } + return true; } }