Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp14180863pxu; Mon, 4 Jan 2021 15:23:12 -0800 (PST) X-Google-Smtp-Source: ABdhPJyhon+4DCQ3mEPcFhVULsqtwcPu9dVfW7ID4HSvezUxxIXll+KR7547l/DeS2BOmNlDTsON X-Received: by 2002:a17:906:7f10:: with SMTP id d16mr68381003ejr.104.1609802592365; Mon, 04 Jan 2021 15:23:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609802592; cv=none; d=google.com; s=arc-20160816; b=TgIohKLgo+C/bHXzAYdJy+X+qVi4BF7OHcSqM7ygGYJWi7WNlOyq2feRinYYumR6Rz R8GpUzG7YpZKrn4tCYlduIDA9kkPySpnEphvzqeQuxl1vSEyvd1V5q4ordBve+hXwxCY mHYZhkb36FRx2e/89SyKmJYq4NCeQKmmXHkqF5/nnyRfDTZtCyrxYwujRQPpi8ANzf5a MJQMUxcOUPgfG/UiJreK/bQXezLsb/xCm6uDblLL+XlIC0udP9nm/6ADinkNUzoE6ZNL CWuLvMGKAU5halZvUsi7t8RXPiQcfIDOebofkCAsf4e7uJ+jHRIDGTti0v3Zv8KKdygE evTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JZOlQj0JLO6r78FAjqdLGe/A26q+7HZVrLl16AaDzeg=; b=dv7rylOVHigr3AVRF1px5kgWMzh/eu+uiEdJ5gCKtDayaILQKg8tboUlcc+ELvp3R9 +SIMXEDopKxYXVCeKKPEfjzCHgiFCiURrdH2/penuEeXT1JwLDvXD32PLLOkC7e4cpzz +ORIc6SWMkeYj0hn8rrEqRALEH3qGIg78X1X1P/n3S0qjcaq6KP5Kd6+uFTReX2co3e8 JXMGrtWaqOy0JRlDwT9G+TcMBLnnJM/4AtkjqL9uiV5NgHRTq4pjXRQCojmSPxpoW748 M7aKQLNJERvwLSczsTWhImXWbYGKof6LEzAJquNinzAuTIVrCOcf7ccgqQb7cgdQmEmR SdMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=CdpERZg3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id oy13si29283997ejb.397.2021.01.04.15.22.49; Mon, 04 Jan 2021 15:23:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=CdpERZg3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727199AbhADXVx (ORCPT + 99 others); Mon, 4 Jan 2021 18:21:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57226 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726643AbhADXVx (ORCPT ); Mon, 4 Jan 2021 18:21:53 -0500 Received: from mail-oi1-x22d.google.com (mail-oi1-x22d.google.com [IPv6:2607:f8b0:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E9E3AC061793 for ; Mon, 4 Jan 2021 15:21:12 -0800 (PST) Received: by mail-oi1-x22d.google.com with SMTP id p5so34025654oif.7 for ; Mon, 04 Jan 2021 15:21:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JZOlQj0JLO6r78FAjqdLGe/A26q+7HZVrLl16AaDzeg=; b=CdpERZg3rfH3oizVzPZrdaJBzWshww722TBp6ftNzokdkgMnu4wHbrlsRkjLPhxlXG FJEQSp4mppvf37oWc5P6Wid9q7hFMHJ8yhSCagsHGsBeFXeiaXVPHkgxwSVyRod2kxAI bYhlB/xNIddFkB+IOWFDimgg539IpYEVFNtes= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JZOlQj0JLO6r78FAjqdLGe/A26q+7HZVrLl16AaDzeg=; b=jGiHmpG/+AdVGIkBbuwpJcH+dLUGXC65JNRpmZ2U3LsTK1NDZOLjRGGrMNdnvBfRgc CxTgHCiSkaV2jVn/PYw1N1MPMH9u65J9AwxqEfUkVTCX1oV7sHOci3rGOjWlrHH3AX/f 5PV+UjiYfS/0r+rRtVoLdu+xyMhJrCQJn/pAe3UxbCEkp/7TzyVrFsJCEyhH9IUtXOaI Bz8EgUSBV+4xUWZ4ONgrYvaI1L/Q1jYvGcM6jOMmB1IuFiA8Krwr77Xl5v/aGkQc925/ Ww5pxh07nfAucnJe5m6Pja5qRmP0lRKj9mGDkUGIPNxPajpryDmD8Y+WZjUVtPxXx6qz mVBg== X-Gm-Message-State: AOAM530lsx/zYdYMX0BMjs61JKIZbvThQRKw8v7iAERwQKM5v20YERLz TpO/0wVR2Yz9zdbCjYSurU+yOqDCUIl4Lg== X-Received: by 2002:a17:90a:cb8b:: with SMTP id a11mr1062501pju.3.1609800941694; Mon, 04 Jan 2021 14:55:41 -0800 (PST) Received: from philipchen.mtv.corp.google.com ([2620:15c:202:201:a6ae:11ff:fe11:fd59]) by smtp.gmail.com with ESMTPSA id c18sm54951051pfj.200.2021.01.04.14.55.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Jan 2021 14:55:41 -0800 (PST) From: Philip Chen To: LKML , dmitry.torokhov@gmail.com Cc: dianders@chromium.org, swboyd@chromium.org, Philip Chen , Benson Leung , Enric Balletbo i Serra , Guenter Roeck , Lee Jones , linux-input@vger.kernel.org Subject: [PATCH v2 2/2] Input: cros-ec-keyb - Expose function row physical map to userspace Date: Mon, 4 Jan 2021 14:55:32 -0800 Message-Id: <20210104145523.v2.2.Ibe7d7d53c5b4fe72c60de90111ff763b53f38dbb@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210104145523.v2.1.I025fb861cd5fa0ef5286b7dce514728e9df7ae74@changeid> References: <20210104145523.v2.1.I025fb861cd5fa0ef5286b7dce514728e9df7ae74@changeid> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The top-row keys in a keyboard usually have dual functionalities. E.g. A function key "F1" is also an action key "Browser back". Therefore, when an application receives an action key code from a top-row key press, the application needs to know how to correlate the action key code with the function key code and do the conversion whenever necessary. Since the userpace already knows the key scanlines (row/column) associated with a received key code. Essentially, the userspace only needs a mapping between the key row/column and the matching physical location in the top row. This patch enhances the cros-ec-keyb driver to create such a mapping and expose it to userspace in the form of a function-row-physmap attribute. The attribute would be a space separated ordered list of row/column codes, for the keys in the function row, in a left-to-right order. The attribute will only be present when the device has a custom design for the top-row keys. Signed-off-by: Philip Chen --- Changes in v2: - create function-row-physmap file in sysfs by parsing `function-row-physmap` property from DT - assume the device already has a correct keymap to reflect the custom top-row keys (if they exist) drivers/input/keyboard/cros_ec_keyb.c | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index b379ed7628781..06642e4ce9c63 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -27,6 +27,8 @@ #include +#define MAX_NUM_TOP_ROW_KEYS 15 + /** * struct cros_ec_keyb - Structure representing EC keyboard device * @@ -35,6 +37,7 @@ * @row_shift: log2 or number of rows, rounded up * @keymap_data: Matrix keymap data used to convert to keyscan values * @ghost_filter: true to enable the matrix key-ghosting filter + * @has_custom_top_row_keys: true if the keyboard has custom top row keys * @valid_keys: bitmap of existing keys for each matrix column * @old_kb_state: bitmap of keys pressed last scan * @dev: Device pointer @@ -49,6 +52,7 @@ struct cros_ec_keyb { int row_shift; const struct matrix_keymap_data *keymap_data; bool ghost_filter; + bool has_custom_top_row_keys; uint8_t *valid_keys; uint8_t *old_kb_state; @@ -587,6 +591,65 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev) return 0; } +static ssize_t function_row_physmap_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t size = 0; + u8 i; + u16 code; + u32 top_row_key_code[MAX_NUM_TOP_ROW_KEYS] = {0}; + struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); + + if (of_property_read_variable_u32_array(dev->of_node, + "function-row-physmap", + top_row_key_code, + 0, + MAX_NUM_TOP_ROW_KEYS) > 0) + return 0; + + ckdev->has_custom_top_row_keys = true; + + for (i = 0; i < MAX_NUM_TOP_ROW_KEYS; i++) { + if (!top_row_key_code[i]) + break; + code = MATRIX_SCAN_CODE(KEY_ROW(top_row_key_code[i]), + KEY_COL(top_row_key_code[i]), + ckdev->row_shift); + size += scnprintf(buf + size, PAGE_SIZE - size, "%02X ", code); + } + size += scnprintf(buf + size, PAGE_SIZE - size, "\n"); + + return size; +} + +static DEVICE_ATTR_RO(function_row_physmap); + +static struct attribute *cros_ec_keyb_attrs[] = { + &dev_attr_function_row_physmap.attr, + NULL, +}; + +static umode_t cros_ec_keyb_attr_is_visible(struct kobject *kobj, + struct attribute *attr, + int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); + + if (attr == &dev_attr_function_row_physmap.attr && + !ckdev->has_custom_top_row_keys) + return 0; + + return attr->mode; +} + +static const struct attribute_group cros_ec_keyb_attr_group = { + .is_visible = cros_ec_keyb_attr_is_visible, + .attrs = cros_ec_keyb_attrs, +}; + + static int cros_ec_keyb_probe(struct platform_device *pdev) { struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); @@ -617,6 +680,12 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) return err; } + err = sysfs_create_group(&dev->kobj, &cros_ec_keyb_attr_group); + if (err) { + dev_err(dev, "failed to create attributes. err=%d\n", err); + return err; + } + ckdev->notifier.notifier_call = cros_ec_keyb_work; err = blocking_notifier_chain_register(&ckdev->ec->event_notifier, &ckdev->notifier); @@ -632,6 +701,9 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) static int cros_ec_keyb_remove(struct platform_device *pdev) { struct cros_ec_keyb *ckdev = dev_get_drvdata(&pdev->dev); + struct device *dev = &pdev->dev; + + sysfs_remove_group(&dev->kobj, &cros_ec_keyb_attr_group); blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, &ckdev->notifier); -- 2.26.2