Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp864242ybb; Sat, 28 Mar 2020 12:01:13 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvYhTiKb3YXqanW636cqsuFv64N0hmu3O1E47eB1L/UfOy6uRh503icnCz8za0Y3GfFe3rJ X-Received: by 2002:a4a:41ce:: with SMTP id x197mr4267274ooa.77.1585422072967; Sat, 28 Mar 2020 12:01:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585422072; cv=none; d=google.com; s=arc-20160816; b=zN7Tc9i5pGTltkP3w4jdEcECrU5SL4appB1F92bMC/oh36hVi/gVaJA3Z1idDfjSp0 1ClsTJYJSkG2HPYBdoeIvcKv/iYrGX7Hc/v+P9nGHZ54ft5t9mtXtmqec2FgWehBhO5X 66ZTlxaJbgqNIRJH5GQl4Bae2j91R7iToaFfYNsgAiDOEOZIU3IUfyk3zfB/+JavY/6v AquxuIcasJhx5W5Qt8opCrrpuT8+ofvTs0IBK1gJzw8ZiD03kXVxOkyH+jbrd/86A56b uif8pI5ky92nfj9c9UnTs5Nh3So7oTulPPb6GpglxbiH945iXNfAvjlxa5I7rYHOHl0g kSDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=cb6A4ZievIvvysAvumZN4FIO7dPjsgeMK8Q/oul1Xgs=; b=N6hFlHcvJEvYbUXt7Yy4U6b66Rog8n29BCxVtBhQzv/CxhCArbUuwT8yPFkC4FJRT2 eoXwxddf5C1W7cfvzFfftIqY3z7VzJ0YxD6Pd9zPSr+HwvrUmuJWUOGh5iQFBLZph7PD Vdv/y7+XcyiXB6OL8zmhaGmmsg/d4oMJ6UvDKuBSM1/4RXr0+W1pdl/WJvyw4/vihB3D hcNI9cBCLjUNtsJ2BWyP2rUWUPnootazikRUlnwKkc1RT5i27fNQixK8E2JEhaVRKKGq e8Tk7n0ylaQm2cjCjGUwvgm4hn0h9tbUalQTaqBrWAFkJgiAfiPd49HS8C/grtiE2Sti efuQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=DAQ8XHD8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p19si3981583oic.39.2020.03.28.12.00.59; Sat, 28 Mar 2020 12:01:12 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=DAQ8XHD8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727286AbgC1S7a (ORCPT + 99 others); Sat, 28 Mar 2020 14:59:30 -0400 Received: from mail-yb1-f202.google.com ([209.85.219.202]:37399 "EHLO mail-yb1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727137AbgC1S72 (ORCPT ); Sat, 28 Mar 2020 14:59:28 -0400 Received: by mail-yb1-f202.google.com with SMTP id k8so12756699ybo.4 for ; Sat, 28 Mar 2020 11:59:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=cb6A4ZievIvvysAvumZN4FIO7dPjsgeMK8Q/oul1Xgs=; b=DAQ8XHD8okBVh2XJa2USholx+1RJddSlBF8w3rKul+bEhcpC5OB7CgsmbHySNT5MJU H5RfSes0X3kz7itAjJPnhGW4wMPiSdhkWYf5TbYt5tcDeJDy1CysmVteAXTw3wLkp5+S uAxj5rvzEzFn4lrDtMMHQOLiRcEhwZnrVWDEUoDI2Iw3aup9M/ylYf/ozgT9Qzu1o2zX m3HgF5Bbc9x1zyMdpXaDku2GIEi6EAVYOZbHMvjK8Hy8yfPGIoQxFqW8EaiDNoFTPimU ysxEwBS4A/KOyF+PfZ32GBx3fzfxIoUKYx2NiCsCtEIcJinhiawCVDMwPC2Ra9kbTe6Y xPQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=cb6A4ZievIvvysAvumZN4FIO7dPjsgeMK8Q/oul1Xgs=; b=b7E5Xj/uApVjtwtIYMqt6cBkQTZGWQDcV+8jXWAgmaWcuePI9L1AO2+YKbq6UkBBWK oJBW1Szt6uL5XZ2CgtEPV5jfblFH6PdGUQCt8bUPhgUAR7jOZWHYUmKMaDHLr6LEQjf2 vJC7ib9cz2bXDXcLeh+uSShfPGyEYDPY97DXr5QUciTm/aHCs7F9xvflSG7FzIA7kAI0 kffCgrrF2+1ojVqq+WSG0Q3IR4EBi3u7A/q5xBrNuAAH+S8ss3lORay6bc5KQzfL+PPO Bpj+Nv4S2E9G/Cr1jIOBQWWINoXnFN5URAJzAIA+MaRiJfHx5MnQfUu7K8dKDVjyrShS dFbA== X-Gm-Message-State: ANhLgQ2XuQ2MWRJ+R7GRIWOXgIqJRhi+sw9LfPggmxr++X80P8XSkutD eUoAYJtnUFoRe4uSUSfC6swlSn+n/rYq X-Received: by 2002:a25:9d88:: with SMTP id v8mr7013374ybp.433.1585421966999; Sat, 28 Mar 2020 11:59:26 -0700 (PDT) Date: Sat, 28 Mar 2020 11:59:13 -0700 In-Reply-To: <20200328185916.98423-1-rajatja@google.com> Message-Id: <20200328185916.98423-2-rajatja@google.com> Mime-Version: 1.0 References: <20200328185916.98423-1-rajatja@google.com> X-Mailer: git-send-email 2.26.0.rc2.310.g2932bb562d-goog Subject: [PATCH v4 2/5] Input: atkbd: Expose function row physical map to userspace From: Rajat Jain To: Dmitry Torokhov , dtor@google.com, Rob Herring , Mark Rutland , Rajat Jain , Kate Stewart , Enrico Weigelt , Greg Kroah-Hartman , Thomas Gleixner , Allison Randal , "Rafael J. Wysocki" , Stephen Boyd , linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, furquan@google.com, dlaurie@google.com, bleung@google.com, zentaro@google.com, dbehr@google.com Cc: rajatxjain@gmail.com Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Certain keyboards have their top-row keys intended for actions such as "Browser back", "Browser Refresh", "Fullscreen" etc as their primary mode, thus they will send physical codes for those actions. Further, they don't have a dedicated "Fn" key so don't have the capability to generate function key codes (e.g. F1, F2 etc..). However in this case, if userspace still wants to "synthesize" those function keys using the top row action keys, it needs to know the physical position of the top row keys. (Essentially a mapping between usage codes and a physical location in the top row). This patch enhances the atkbd driver to receive such a mapping from the firmware / device tree, and expose it to userspace in the form of a function-row-physmap attribute. The attribute would be a space separated ordered list of physical codes, for the keys in the function row, in left-to-right order. The attribute will only be present if the kernel knows about such mapping, otherwise the attribute shall not be visible. Signed-off-by: Rajat Jain --- v4: Same as v3 v3: Change to dev_dbg and remove unecessary error check v2: Remove the Change-Id from the commit log drivers/input/keyboard/atkbd.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 7e3eae54c1926..3b20aba1861cd 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -24,6 +24,7 @@ #include #include #include +#include #define DRIVER_DESC "AT and PS/2 keyboard driver" @@ -63,6 +64,8 @@ static bool atkbd_terminal; module_param_named(terminal, atkbd_terminal, bool, 0); MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2"); +#define MAX_FUNCTION_ROW_KEYS 24 + /* * Scancode to keycode tables. These are just the default setting, and * are loadable via a userland utility. @@ -230,6 +233,9 @@ struct atkbd { /* Serializes reconnect(), attr->set() and event work */ struct mutex mutex; + + u16 function_row_physmap[MAX_FUNCTION_ROW_KEYS]; + int num_function_row_keys; }; /* @@ -283,6 +289,7 @@ static struct device_attribute atkbd_attr_##_name = \ __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL); ATKBD_DEFINE_RO_ATTR(err_count); +ATKBD_DEFINE_RO_ATTR(function_row_physmap); static struct attribute *atkbd_attributes[] = { &atkbd_attr_extra.attr, @@ -292,11 +299,42 @@ static struct attribute *atkbd_attributes[] = { &atkbd_attr_softrepeat.attr, &atkbd_attr_softraw.attr, &atkbd_attr_err_count.attr, + &atkbd_attr_function_row_physmap.attr, NULL }; +static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf) +{ + ssize_t size = 0; + int i; + + if (!atkbd->num_function_row_keys) + return 0; + + for (i = 0; i < atkbd->num_function_row_keys; i++) + size += sprintf(buf + size, "%02X ", + atkbd->function_row_physmap[i]); + size += sprintf(buf + size, "\n"); + return size; +} + +static umode_t atkbd_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int i) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct serio *serio = to_serio_port(dev); + struct atkbd *atkbd = serio_get_drvdata(serio); + + if (attr == &atkbd_attr_function_row_physmap.attr && + !atkbd->num_function_row_keys) + return 0; + + return attr->mode; +} + static struct attribute_group atkbd_attribute_group = { .attrs = atkbd_attributes, + .is_visible = atkbd_attr_is_visible, }; static const unsigned int xl_table[] = { @@ -1121,6 +1159,22 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) } } +static void atkbd_parse_fwnode_data(struct serio *serio) +{ + struct atkbd *atkbd = serio_get_drvdata(serio); + struct device *dev = &serio->dev; + int n; + + /* Parse "function-row-physmap" property */ + n = device_property_count_u16(dev, "function-row-physmap"); + if (n > 0 && n <= MAX_FUNCTION_ROW_KEYS && + !device_property_read_u16_array(dev, "function-row-physmap", + atkbd->function_row_physmap, n)) { + atkbd->num_function_row_keys = n; + dev_dbg(dev, "FW reported %d function-row key locations\n", n); + } +} + /* * atkbd_connect() is called when the serio module finds an interface * that isn't handled yet by an appropriate device driver. We check if @@ -1184,6 +1238,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) atkbd->id = 0xab00; } + atkbd_parse_fwnode_data(serio); + atkbd_set_keycode_table(atkbd); atkbd_set_device_attrs(atkbd); -- 2.26.0.rc2.310.g2932bb562d-goog