From patchwork Fri Aug 19 06:59:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gireesh Hiremath X-Patchwork-Id: 12948450 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C41AC3F6B0 for ; Fri, 19 Aug 2022 07:00:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346859AbiHSHAn (ORCPT ); Fri, 19 Aug 2022 03:00:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346933AbiHSHAe (ORCPT ); Fri, 19 Aug 2022 03:00:34 -0400 Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on2062.outbound.protection.outlook.com [40.107.22.62]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B861ABD2A9; Fri, 19 Aug 2022 00:00:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LUByJoV/fd7wrpGdkRlGo77XsrZwCQPw0P5U8OjdJoFu121HEikTSc7dvyHgY78TOYw2+ns5I4s23Y2KMtyw4BlOd61o2q50yGBd0kVD5bUiK0jfmG5vTum6GMqiefJFxo29OJ0cc9Q+mW5bT4uG0JFy5k6r+uq/LQQIwE2ZBMhcc7GtIEO2/2gIg/42XeLKbkZ4CWrUTtwn++h6ICazxIoKTwH5YIxZCtChXTYZMmzbnSmKt3RdhcxQMRkjyBDvYMIjWw8IPBmUZI5tvjPZuSy05ZtLO0lM/bL6Hot6Rcr1Xc6porKZIc4xyYzgH1G43ASR3CIUM1Vxfi5QX5SBFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ZOSRmtYp9EHzQ7qyTrbRl+w0m8lh4snJR2d9TnB1KDg=; b=PUovgICm/0cGAZhZ/eFoj8D2b/LWGgo4DbT/zyBsUE451uUzDyEYaCotkoLCdbaQK+lSHI0zsWc32vcvZcV++SKyOQ9rZzDP/w4scHDj9Qa/4a05FPauSg1naXnl+Kh4UlXheaes1TjOHTtWZQBBXU9f+DiEFH4nDWanBhBHdU6tlrDs9zP7+tvuedOZcQtTpMjbNWyOH+6FrZrwwFnJr94BAKEYvxa9B2c/riGt5wOJC7tZ/RZecc4+jD9SysiA9g3GJywyuqQZCF9ZV08lw8QwQrdpiP1oa26VMP1En2kj+ptyjHB94Tlhr9llV/S22+5qwKIEZIGLjtHZ+yiyTg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 139.15.153.203) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=in.bosch.com; dmarc=pass (p=reject sp=none pct=100) action=none header.from=in.bosch.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=in.bosch.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZOSRmtYp9EHzQ7qyTrbRl+w0m8lh4snJR2d9TnB1KDg=; b=fTTglObntL7T2T//QqhEurZjQjOz0mp8aiN9V2/GUzIvWHhJBvLJq7XChUVZS75rgUbcipe4d6o7eLTJbAX4eSbOOmZ6p4KdCzRuJ51iZcF+sPPhlCoSxMYLuhOKFB3XZbYrizhDVfL3wMFq1Ld+b+UKahZ/+ZlRYbIov2DlAHA= Received: from DB6PR07CA0166.eurprd07.prod.outlook.com (2603:10a6:6:43::20) by AM4PR1001MB1300.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:200:96::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.16; Fri, 19 Aug 2022 07:00:30 +0000 Received: from DBAEUR03FT017.eop-EUR03.prod.protection.outlook.com (2603:10a6:6:43:cafe::83) by DB6PR07CA0166.outlook.office365.com (2603:10a6:6:43::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5566.9 via Frontend Transport; Fri, 19 Aug 2022 07:00:30 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 139.15.153.203) smtp.mailfrom=in.bosch.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=in.bosch.com; Received-SPF: Pass (protection.outlook.com: domain of in.bosch.com designates 139.15.153.203 as permitted sender) receiver=protection.outlook.com; client-ip=139.15.153.203; helo=eop.bosch-org.com; pr=C Received: from eop.bosch-org.com (139.15.153.203) by DBAEUR03FT017.mail.protection.outlook.com (100.127.142.243) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.15 via Frontend Transport; Fri, 19 Aug 2022 07:00:29 +0000 Received: from FE-EXCAS2001.de.bosch.com (10.139.217.200) by eop.bosch-org.com (139.15.153.203) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Fri, 19 Aug 2022 09:00:25 +0200 Received: from FE-HUB2000.de.bosch.com (10.4.103.109) by FE-EXCAS2001.de.bosch.com (10.139.217.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Fri, 19 Aug 2022 09:00:25 +0200 Received: from localhost.localdomain (10.167.0.81) by FE-HUB2000.de.bosch.com (10.4.103.109) with Microsoft SMTP Server id 15.1.2375.31; Fri, 19 Aug 2022 09:00:21 +0200 From: To: , , , , , , , , , , , , , , , , , CC: , , , Subject: [PATCH v3 1/3] driver: input: matric-keypad: switch to gpiod Date: Fri, 19 Aug 2022 06:59:44 +0000 Message-ID: <20220819065946.9572-1-Gireesh.Hiremath@in.bosch.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Originating-IP: [10.167.0.81] X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 472e6795-97b8-4d48-4ab5-08da81b080c4 X-MS-TrafficTypeDiagnostic: AM4PR1001MB1300:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: dAsjepNA/e2md6p52shODFQlZ/YiJ05BqBqLAUPPl+o8WFTPq7Mp3P8sMizstncDsCpm2UufqB5Qx8QcZQwl0OdeCHqW8aoQgkwxAJwAODYvB+pJB8KCyZumSU5Kl0Vivh0XTbyfrp9D2xFl5TFbpqLkIIJurW8eRazDxs3lr7q2qKD0GG1ucLqn+Hw5bMJI4DK6qq/7SHShjln94mF7fpH0vnXTIVWYvF7HdsjLSIuRBpgp9fyowFuKoZ+x7MHTX1WXlGTSPBlyKTB7tmzX3SsHkYWLmItfKOfWbVSQoKxM9KZE/bwXOa1OhY6svyxI5JXslkV7vXf/LYFwXf4voKkaEeUu5tFu0xa2cx4gsu164Bv2W97HddpNirPA/ZficwlcJVW6Guj5/BA5l1EQAAExEQ9e14g/iKeqX7NOBazv1hiDyoJi7FxfwmO0d+H4yd10mQ0gHm2XcginVzuCE1iRj9MsvvZbURxajeZiHhbjgo30SqRzT2g4BKGJUB1wTU5s60ygz/Bu8iQizUsfYGv2VgH68gA1l93QuMKkbBFOMOvOYlnXO+tGo5AFo2Q6YL0yDInXTJHZUG/9N9xGtGhbSYLgquXbFH3O0dlLCOeIUzxUy/5yqJCYFICccI6AyV+NZ7Z2u+1JHsARaZrWJNRzaSOLwoPWoRK/q9XRMBrwmOVdjQNjf9XL69OfMNDE9t2H64XRH5+Jj/a7Zh42UN++lYCcaeIGQxxPhyWvcKEd4MtBbGTsAXWWObwnqHdpQgdh+aBZPVrj7rOZf4q2Ig2q0jjbxHug2tOoR83W2wUpV1DsNZqiSqFLcvs9w0J5 X-Forefront-Antispam-Report: CIP:139.15.153.203;CTRY:DE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:eop.bosch-org.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230016)(4636009)(136003)(39860400002)(346002)(376002)(396003)(36840700001)(46966006)(40470700004)(70206006)(70586007)(4326008)(8676002)(478600001)(2906002)(5660300002)(316002)(107886003)(6666004)(336012)(186003)(26005)(1076003)(110136005)(2876002)(54906003)(16526019)(47076005)(2616005)(83380400001)(82740400003)(40460700003)(86362001)(7049001)(40480700001)(82310400005)(81166007)(7416002)(8936002)(356005)(41300700001)(36860700001)(82960400001)(921005)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: in.bosch.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Aug 2022 07:00:29.9827 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 472e6795-97b8-4d48-4ab5-08da81b080c4 X-MS-Exchange-CrossTenant-Id: 0ae51e19-07c8-4e4b-bb6d-648ee58410f4 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0ae51e19-07c8-4e4b-bb6d-648ee58410f4;Ip=[139.15.153.203];Helo=[eop.bosch-org.com] X-MS-Exchange-CrossTenant-AuthSource: DBAEUR03FT017.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR1001MB1300 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: Gireesh Hiremath Switch from gpio API to gpiod API Signed-off-by: Gireesh Hiremath Gbp-Pq: Topic apertis/guardian Gbp-Pq: Name driver-input-matric-keypad-switch-gpio-to-gpiod.patch Reported-by: kernel test robot Reported-by: Dan Carpenter --- drivers/input/keyboard/matrix_keypad.c | 84 ++++++++++---------------- include/linux/input/matrix_keypad.h | 4 +- 2 files changed, 33 insertions(+), 55 deletions(-) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 30924b57058f..b99574edad9c 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -15,11 +15,10 @@ #include #include #include -#include +#include #include #include #include -#include #include struct matrix_keypad { @@ -49,11 +48,11 @@ static void __activate_col(const struct matrix_keypad_platform_data *pdata, bool level_on = !pdata->active_low; if (on) { - gpio_direction_output(pdata->col_gpios[col], level_on); + gpiod_direction_output(pdata->col_gpios[col], level_on); } else { - gpio_set_value_cansleep(pdata->col_gpios[col], !level_on); + gpiod_set_value_cansleep(pdata->col_gpios[col], !level_on); if (!pdata->drive_inactive_cols) - gpio_direction_input(pdata->col_gpios[col]); + gpiod_direction_input(pdata->col_gpios[col]); } } @@ -78,7 +77,7 @@ static void activate_all_cols(const struct matrix_keypad_platform_data *pdata, static bool row_asserted(const struct matrix_keypad_platform_data *pdata, int row) { - return gpio_get_value_cansleep(pdata->row_gpios[row]) ? + return gpiod_get_value_cansleep(pdata->row_gpios[row]) ? !pdata->active_low : pdata->active_low; } @@ -91,7 +90,7 @@ static void enable_row_irqs(struct matrix_keypad *keypad) enable_irq(pdata->clustered_irq); else { for (i = 0; i < pdata->num_row_gpios; i++) - enable_irq(gpio_to_irq(pdata->row_gpios[i])); + enable_irq(gpiod_to_irq(pdata->row_gpios[i])); } } @@ -104,7 +103,7 @@ static void disable_row_irqs(struct matrix_keypad *keypad) disable_irq_nosync(pdata->clustered_irq); else { for (i = 0; i < pdata->num_row_gpios; i++) - disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i])); + disable_irq_nosync(gpiod_to_irq(pdata->row_gpios[i])); } } @@ -230,7 +229,7 @@ static void matrix_keypad_stop(struct input_dev *dev) static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) { const struct matrix_keypad_platform_data *pdata = keypad->pdata; - unsigned int gpio; + struct gpio_desc *gpio; int i; if (pdata->clustered_irq > 0) { @@ -242,7 +241,7 @@ static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) if (!test_bit(i, keypad->disabled_gpios)) { gpio = pdata->row_gpios[i]; - if (enable_irq_wake(gpio_to_irq(gpio)) == 0) + if (enable_irq_wake(gpiod_to_irq(gpio)) == 0) __set_bit(i, keypad->disabled_gpios); } } @@ -252,7 +251,7 @@ static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad) { const struct matrix_keypad_platform_data *pdata = keypad->pdata; - unsigned int gpio; + struct gpio_desc *gpio; int i; if (pdata->clustered_irq > 0) { @@ -264,7 +263,7 @@ static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad) for (i = 0; i < pdata->num_row_gpios; i++) { if (test_and_clear_bit(i, keypad->disabled_gpios)) { gpio = pdata->row_gpios[i]; - disable_irq_wake(gpio_to_irq(gpio)); + disable_irq_wake(gpiod_to_irq(gpio)); } } } @@ -308,27 +307,11 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, /* initialized strobe lines as outputs, activated */ for (i = 0; i < pdata->num_col_gpios; i++) { - err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col"); - if (err) { - dev_err(&pdev->dev, - "failed to request GPIO%d for COL%d\n", - pdata->col_gpios[i], i); - goto err_free_cols; - } - - gpio_direction_output(pdata->col_gpios[i], !pdata->active_low); + gpiod_direction_output(pdata->col_gpios[i], !pdata->active_low); } for (i = 0; i < pdata->num_row_gpios; i++) { - err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row"); - if (err) { - dev_err(&pdev->dev, - "failed to request GPIO%d for ROW%d\n", - pdata->row_gpios[i], i); - goto err_free_rows; - } - - gpio_direction_input(pdata->row_gpios[i]); + gpiod_direction_input(pdata->row_gpios[i]); } if (pdata->clustered_irq > 0) { @@ -344,7 +327,7 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, } else { for (i = 0; i < pdata->num_row_gpios; i++) { err = request_any_context_irq( - gpio_to_irq(pdata->row_gpios[i]), + gpiod_to_irq(pdata->row_gpios[i]), matrix_keypad_interrupt, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, @@ -352,7 +335,7 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, if (err < 0) { dev_err(&pdev->dev, "Unable to acquire interrupt for GPIO line %i\n", - pdata->row_gpios[i]); + i); goto err_free_irqs; } } @@ -364,15 +347,12 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, err_free_irqs: while (--i >= 0) - free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); + free_irq(gpiod_to_irq(pdata->row_gpios[i]), keypad); i = pdata->num_row_gpios; err_free_rows: while (--i >= 0) - gpio_free(pdata->row_gpios[i]); + gpiod_put(pdata->row_gpios[i]); i = pdata->num_col_gpios; -err_free_cols: - while (--i >= 0) - gpio_free(pdata->col_gpios[i]); return err; } @@ -386,14 +366,14 @@ static void matrix_keypad_free_gpio(struct matrix_keypad *keypad) free_irq(pdata->clustered_irq, keypad); } else { for (i = 0; i < pdata->num_row_gpios; i++) - free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); + free_irq(gpiod_to_irq(pdata->row_gpios[i]), keypad); } for (i = 0; i < pdata->num_row_gpios; i++) - gpio_free(pdata->row_gpios[i]); + gpiod_put(pdata->row_gpios[i]); for (i = 0; i < pdata->num_col_gpios; i++) - gpio_free(pdata->col_gpios[i]); + gpiod_put(pdata->col_gpios[i]); } #ifdef CONFIG_OF @@ -402,7 +382,8 @@ matrix_keypad_parse_dt(struct device *dev) { struct matrix_keypad_platform_data *pdata; struct device_node *np = dev->of_node; - unsigned int *gpios; + struct gpio_desc **gpios; + struct gpio_desc *desc; int ret, i, nrow, ncol; if (!np) { @@ -416,8 +397,8 @@ matrix_keypad_parse_dt(struct device *dev) return ERR_PTR(-ENOMEM); } - pdata->num_row_gpios = nrow = of_gpio_named_count(np, "row-gpios"); - pdata->num_col_gpios = ncol = of_gpio_named_count(np, "col-gpios"); + pdata->num_row_gpios = nrow = gpiod_count(dev, "row"); + pdata->num_col_gpios = ncol = gpiod_count(dev, "col"); if (nrow <= 0 || ncol <= 0) { dev_err(dev, "number of keypad rows/columns not specified\n"); return ERR_PTR(-EINVAL); @@ -429,9 +410,6 @@ matrix_keypad_parse_dt(struct device *dev) pdata->wakeup = of_property_read_bool(np, "wakeup-source") || of_property_read_bool(np, "linux,wakeup"); /* legacy */ - if (of_get_property(np, "gpio-activelow", NULL)) - pdata->active_low = true; - pdata->drive_inactive_cols = of_property_read_bool(np, "drive-inactive-cols"); @@ -441,7 +419,7 @@ matrix_keypad_parse_dt(struct device *dev) gpios = devm_kcalloc(dev, pdata->num_row_gpios + pdata->num_col_gpios, - sizeof(unsigned int), + sizeof(*gpios), GFP_KERNEL); if (!gpios) { dev_err(dev, "could not allocate memory for gpios\n"); @@ -449,17 +427,17 @@ matrix_keypad_parse_dt(struct device *dev) } for (i = 0; i < nrow; i++) { - ret = of_get_named_gpio(np, "row-gpios", i); - if (ret < 0) + desc = devm_gpiod_get_index(dev, "row", i, GPIOD_IN); + if (IS_ERR(desc)) return ERR_PTR(ret); - gpios[i] = ret; + gpios[i] = desc; } for (i = 0; i < ncol; i++) { - ret = of_get_named_gpio(np, "col-gpios", i); - if (ret < 0) + desc = devm_gpiod_get_index(dev, "col", i, GPIOD_IN); + if (IS_ERR(desc)) return ERR_PTR(ret); - gpios[nrow + i] = ret; + gpios[nrow + i] = desc; } pdata->row_gpios = gpios; diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 9476768c3b90..8ad7d4626e62 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h @@ -59,8 +59,8 @@ struct matrix_keymap_data { struct matrix_keypad_platform_data { const struct matrix_keymap_data *keymap_data; - const unsigned int *row_gpios; - const unsigned int *col_gpios; + struct gpio_desc **row_gpios; + struct gpio_desc **col_gpios; unsigned int num_row_gpios; unsigned int num_col_gpios; From patchwork Fri Aug 19 06:59:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gireesh Hiremath X-Patchwork-Id: 12948451 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDDACC25B0E for ; Fri, 19 Aug 2022 07:00:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346900AbiHSHAo (ORCPT ); Fri, 19 Aug 2022 03:00:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346939AbiHSHAg (ORCPT ); Fri, 19 Aug 2022 03:00:36 -0400 Received: from EUR04-DB3-obe.outbound.protection.outlook.com (mail-eopbgr60051.outbound.protection.outlook.com [40.107.6.51]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F08BC57B6; Fri, 19 Aug 2022 00:00:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fU4xYXN9oDZ/yUSgoc/eH/QuiS6LZ+ogXNJFiTHIqrlHjSU/uqHJYa1FCOzEPbJs/Q9zkoTIpx9+MPeIBKM/y3AGl82gz5kdmA+jKKi9dqlSpmWsIGe3hH6m8fMiABslriAgumX4FfGK4oKDBALNrBsvj62rAqp/M7HxudNs2Bewcda+XVKPl2OccnyKHC6YO9FoZISgqHYe46s5rG+t4K6LGWboxg+gwkXdah4nqEVhD2ZPPU0xY8+3TeM9chZKYWtCD4DTEiSwTIe8ZZgm3AubBv+pcB64PJbYpgYrwBybkVn7iTygHm++H5TJ5NZlO8KHaxCIdop6du12pJqn9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=i3UWGlXUGE7kDqs2tk6w1whSdABvOLxtHp+zAIJP9R8=; b=jCwPZyhe7ZmFTY2XCCNwSVB33sGa6mXGsnZKdZNwEmOgQOQtM28Z2uVEtmIIP9m/LppYjjOonj+R/28d1NJjURGrQlUwFCYqzNY5ihovwLZDevBKqoX7xjpI9+1+PWzmnePaG++zeCwxw0QDLe3H7ldzYFhWMfBFaSl4D/b0cwgXMid/Yn6q63aBp1iTLdGNB3QlaQtGsq9kqgU1B3SqS71AKUpOJOa2br964fmwCAK3XgaM0vkJgQ4mEKEz2S2OfQtnfWn6Xs7M1rf2CNAXlM1N3CvWvj5m6tqZmt9G0ZV1uVN3GG843R8jIXKPyl4ZvmYGgKpmpZXjB3RLdRR8kQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 139.15.153.203) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=in.bosch.com; dmarc=pass (p=reject sp=none pct=100) action=none header.from=in.bosch.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=in.bosch.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=i3UWGlXUGE7kDqs2tk6w1whSdABvOLxtHp+zAIJP9R8=; b=UlsCBaqvH+YCTPLUirB3Xr/YAuyMWPQsHgTQBoI0eC0ogmSbKlC7KX7BplBLiEgJouOr08gFWI+bQCOeuUeF9fujVPe/msiTz7FTqAD9BNFw5WOPVZPPnIkd3nJFsRgqxNYnQCD0rZ66GeVTsbGNaBAjAVp7Cu0hzb21bsobqFM= Received: from DB6PR07CA0174.eurprd07.prod.outlook.com (2603:10a6:6:43::28) by AM5PR10MB1761.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:206:1c::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5504.16; Fri, 19 Aug 2022 07:00:31 +0000 Received: from DBAEUR03FT017.eop-EUR03.prod.protection.outlook.com (2603:10a6:6:43:cafe::e3) by DB6PR07CA0174.outlook.office365.com (2603:10a6:6:43::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5566.9 via Frontend Transport; Fri, 19 Aug 2022 07:00:30 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 139.15.153.203) smtp.mailfrom=in.bosch.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=in.bosch.com; Received-SPF: Pass (protection.outlook.com: domain of in.bosch.com designates 139.15.153.203 as permitted sender) receiver=protection.outlook.com; client-ip=139.15.153.203; helo=eop.bosch-org.com; pr=C Received: from eop.bosch-org.com (139.15.153.203) by DBAEUR03FT017.mail.protection.outlook.com (100.127.142.243) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.15 via Frontend Transport; Fri, 19 Aug 2022 07:00:30 +0000 Received: from SI-EXCAS2000.de.bosch.com (10.139.217.201) by eop.bosch-org.com (139.15.153.203) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Fri, 19 Aug 2022 09:00:29 +0200 Received: from FE-HUB2000.de.bosch.com (10.4.103.109) by SI-EXCAS2000.de.bosch.com (10.139.217.201) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Fri, 19 Aug 2022 09:00:29 +0200 Received: from localhost.localdomain (10.167.0.81) by FE-HUB2000.de.bosch.com (10.4.103.109) with Microsoft SMTP Server id 15.1.2375.31; Fri, 19 Aug 2022 09:00:25 +0200 From: To: , , , , , , , , , , , , , , , , , CC: , , , Subject: [PATCH v3 2/3] driver: input: matric-keypad: add reduced matrix support Date: Fri, 19 Aug 2022 06:59:45 +0000 Message-ID: <20220819065946.9572-2-Gireesh.Hiremath@in.bosch.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220819065946.9572-1-Gireesh.Hiremath@in.bosch.com> References: <20220819065946.9572-1-Gireesh.Hiremath@in.bosch.com> MIME-Version: 1.0 X-Originating-IP: [10.167.0.81] X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 977c3600-af60-4e2c-cbad-08da81b08149 X-MS-TrafficTypeDiagnostic: AM5PR10MB1761:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: oYf1o4yjqbVwKRM/Ts4cHWUOlBZHQY7qH7fDJrYNfXMG/jhmQMpzdnG6k6bWwvCjeaFClnu561VJ5O1samE9Sek+YUdBibLYGZtvMZKAXDMMuTKWw/j80xNDjUzoAFYDQPg0wGsZ5OXmNRyfsM2IStjX5niFaAcJ38vDBmLHoPp/0d2lCe0otClVQzjCrYYYgFaU98j5oCMKpliYVTN9aBBfFWKaPNOh4NwHmStxx8w/jacti+OxGbfOraBkpdzVDOXlPpGRyyqap0O0tsHbRo2KqT+7U0V8uTz2AD6TQOuNeMaH3ny0UeiP/seZmT1XO8KMOjvLkDrpLjAPq+4Z11Q+FJiYHULaql2cwjHYyPJpX1GNBD8XlaKYLlisnOb1w48BAPnhEQaHhJYYq9mTg+T1Pt6z4Ro95QqgzuwVqNGzHDIEp/Lb2nQW12kYS+uLEEGs2oQ+e7AcD52ho4s6OulWc8NWpAa1GCmGx5rKS9mM1XRGyNrRz0cgB45dfazthv/h7LAQxMVSBwkRUYtB3+oRbYsAOH7cKOgnbOSwb0eo5ci3Ip+5xbpYFbbSx1QdmoRBSHM8a6ODR0wUyB8ZOdXFu4FTr3Bfm+8qJuXxsFv3nMOmeLiUV2RsTVy1729lTLcasViIfpsnbMYU1m2VnCqrQPH6UYD6/7IxYhI9Uk0IJ8FTRCLiwHomIC49IyUCAjFIXuXi6xK8NiHecRYhNjl5lfhrwKJM34Qxm+nH5hqKnAXzVrLGjNqhSl2mtvq3RSR8Mk9TSOACfsxnR+cvEvMj+o2CXcrWMLUTx4ISkz8Ody1tD6N6RPBSbaLSJR9j X-Forefront-Antispam-Report: CIP:139.15.153.203;CTRY:DE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:eop.bosch-org.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230016)(4636009)(346002)(396003)(136003)(39860400002)(376002)(36840700001)(40470700004)(46966006)(110136005)(70586007)(54906003)(70206006)(316002)(40480700001)(36860700001)(478600001)(8936002)(82960400001)(7049001)(5660300002)(7416002)(2906002)(86362001)(82740400003)(82310400005)(40460700003)(8676002)(41300700001)(2876002)(30864003)(4326008)(16526019)(81166007)(356005)(2616005)(921005)(107886003)(186003)(1076003)(47076005)(26005)(6666004)(336012)(83380400001)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: in.bosch.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Aug 2022 07:00:30.8420 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 977c3600-af60-4e2c-cbad-08da81b08149 X-MS-Exchange-CrossTenant-Id: 0ae51e19-07c8-4e4b-bb6d-648ee58410f4 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0ae51e19-07c8-4e4b-bb6d-648ee58410f4;Ip=[139.15.153.203];Helo=[eop.bosch-org.com] X-MS-Exchange-CrossTenant-AuthSource: DBAEUR03FT017.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR10MB1761 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: Gireesh Hiremath Add support to reduced matrix keypad driver. Tested on Bosch Guardian Dtect board(TI-am335x). Signed-off-by: Gireesh Hiremath Reported-by: kernel test robot Reported-by: kernel test robot Reported-by: kernel test robot Reported-by: Dan Carpenter --- drivers/input/keyboard/matrix_keypad.c | 559 +++++++++++++++++++++---- include/linux/input/matrix_keypad.h | 68 +-- 2 files changed, 520 insertions(+), 107 deletions(-) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index b99574edad9c..72c0663b6ed3 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -21,9 +21,30 @@ #include #include +struct button_states { + uint8_t previous_state : 1; + uint8_t current_state : 1; +}; + +union button_event { + uint8_t clear_event; + struct { + uint8_t global_changed : 1; + uint8_t pressed : 1; + uint8_t released : 1; + } status; +}; + +struct button { + uint8_t key; + union button_event event; + struct button_states state; +}; + struct matrix_keypad { const struct matrix_keypad_platform_data *pdata; struct input_dev *input_dev; + struct button *button_array; unsigned int row_shift; DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); @@ -31,11 +52,34 @@ struct matrix_keypad { uint32_t last_key_state[MATRIX_MAX_COLS]; struct delayed_work work; spinlock_t lock; + int8_t current_line_gpio; bool scan_pending; bool stopped; bool gpio_all_disabled; }; +struct keypad_info { + unsigned char mode; +}; + +static const struct keypad_info keypad_infos[] = { + { + .mode = GENERIC, + }, + { + .mode = REDUCED, + }, +}; + +#ifdef CONFIG_OF +static const struct of_device_id matrix_keypad_dt_match[] = { + { .compatible = "gpio-matrix-keypad", .data = &keypad_infos[0] }, + { .compatible = "gpio-matrix-keypad-reduced", + .data = &keypad_infos[1] }, + {} +}; +MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match); +#endif /* * NOTE: If drive_inactive_cols is false, then the GPIO has to be put into * HiZ when de-activated to cause minmal side effect when scanning other @@ -78,7 +122,8 @@ static bool row_asserted(const struct matrix_keypad_platform_data *pdata, int row) { return gpiod_get_value_cansleep(pdata->row_gpios[row]) ? - !pdata->active_low : pdata->active_low; + !pdata->active_low : + pdata->active_low; } static void enable_row_irqs(struct matrix_keypad *keypad) @@ -107,6 +152,247 @@ static void disable_row_irqs(struct matrix_keypad *keypad) } } +static void +__activate_line_driving(const struct matrix_keypad_platform_data *pdata, + int line, bool on) +{ + bool level_on = pdata->active_low; + + if (on) + gpiod_direction_output(pdata->desc_gpios[line], level_on); + else + gpiod_direction_input(pdata->desc_gpios[line]); +} + +static void +activate_line_driving(const struct matrix_keypad_platform_data *pdata, int line, + bool on) +{ + __activate_line_driving(pdata, line, on); + + if (on && pdata->col_scan_delay_us) + udelay(pdata->col_scan_delay_us); +} + +static void button_init(struct button *btn, bool btn_hw_state, int key) +{ + btn->state.previous_state = btn_hw_state; + btn->state.current_state = btn_hw_state; + btn->event.clear_event = 0; + btn->key = key; +} + +static bool check_button_changes(struct button *btn) +{ + /* Check if Button is pressed */ + if ((!btn->state.previous_state) && btn->state.current_state) + btn->event.status.pressed = true; + + /* Check if Button is released */ + else if (btn->state.previous_state && (!btn->state.current_state)) + btn->event.status.released = true; + + if (btn->event.clear_event != 0) + btn->event.status.global_changed = true; + + btn->state.previous_state = btn->state.current_state; + + return btn->event.status.global_changed; +} + +static union button_event get_and_clear_events(struct button *btn) +{ + union button_event temp = btn->event; + + btn->event.clear_event = 0; + + return temp; +} + +static union button_event get_and_clear_btn_events(struct matrix_keypad *keypad, + int btn_index) +{ + if (btn_index < keypad->pdata->num_of_buttons) + return get_and_clear_events(&keypad->button_array[btn_index]); + else + return get_and_clear_events(&keypad->button_array[0]); +} + +static void button_hdl_init(struct matrix_keypad *keypad) +{ + const struct matrix_keypad_platform_data *pdata = keypad->pdata; + int row, col, index; + int i; + + /* Init Button Objects, will be reinited once states are captured */ + i = 0; + for (row = 1; row < pdata->num_line_gpios; row++) + for (col = 0; col < row; col++) { + index = (row * pdata->num_line_gpios) + col; + if (pdata->keycode[index] != pdata->keycode[0]) { + if (i < pdata->num_of_buttons) { + button_init(&keypad->button_array[i], + false, + pdata->keycode[index]); + i++; + } + } + } + + pr_debug("[matrix-keypad]: %s Done\n", __func__); +} + +static void on_button_event(struct matrix_keypad *keypad, int btn_index, + union button_event btn_event, + struct input_dev *input_dev) +{ + unsigned int key_code = 0; + int key_value = 0; + + key_code = keypad->button_array[btn_index].key; + + if (btn_event.status.pressed) { + key_value = 1; + pr_debug("[matrix-keypad]:%d Pressed\n", key_code); + } + + if (btn_event.status.released) { + key_value = 0; + pr_debug("[matrix-keypad]:%d Released\n", key_code); + } + + input_report_key(input_dev, key_code, key_value); + input_sync(input_dev); +} + +static void process_button_events(struct matrix_keypad *keypad, + struct input_dev *input_dev) +{ + int btn_index; + + for (btn_index = 0; btn_index < keypad->pdata->num_of_buttons; + btn_index++) { + const union button_event beEvent = + get_and_clear_btn_events(keypad, (int)btn_index); + + if (beEvent.status.global_changed) { + on_button_event(keypad, (int)btn_index, beEvent, + input_dev); + } + } +} + +static bool get_gpio_line_value(const struct matrix_keypad_platform_data *pdata, + int row) +{ + return gpiod_get_value(pdata->desc_gpios[row]) ? pdata->active_low : + !pdata->active_low; +} + +static uint8_t get_btn_index(struct matrix_keypad *keypad, int btn_key) +{ + uint8_t i; + + for (i = 0; i < keypad->pdata->num_of_buttons; i++) { + if (keypad->button_array[i].key == btn_key) + break; + } + return i; +} + +static void set_btn_state_by_hw(struct button *btn, bool buttonstate) +{ + btn->state.current_state = buttonstate; +} + +static void poll_prepare(struct matrix_keypad *keypad) +{ + const struct matrix_keypad_platform_data *pdata = keypad->pdata; + + keypad->current_line_gpio = 0; + activate_line_driving(pdata, (int)keypad->current_line_gpio, true); +} + +static void poll_process(struct matrix_keypad *keypad, + struct input_dev *input_dev) +{ + const struct matrix_keypad_platform_data *pdata = keypad->pdata; + bool btn_changes_occured = false; + int btn_index; + + for (btn_index = 0; btn_index < pdata->num_of_buttons; btn_index++) { + btn_changes_occured |= + check_button_changes(&keypad->button_array[btn_index]); + } + + if (btn_changes_occured) + process_button_events(keypad, input_dev); + + keypad->current_line_gpio = 0; +} + +static void poll_update(struct matrix_keypad *keypad, + struct input_dev *input_dev) +{ + const struct matrix_keypad_platform_data *pdata = keypad->pdata; + uint8_t *btn_keylines; + uint8_t number_of_buttons_pressed = 0; + uint8_t btn_index; + uint8_t btn_key; + uint16_t index; + int i; + + btn_keylines = + kcalloc(pdata->num_line_gpios, sizeof(uint8_t), GFP_KERNEL); + for (i = 0; i < pdata->num_line_gpios; i++) { + index = (keypad->current_line_gpio * pdata->num_line_gpios) + i; + btn_key = pdata->keycode[index]; + btn_keylines[i] = false; + + if ((btn_key != pdata->keycode[0]) && + (get_gpio_line_value(pdata, (int)i) != false)) { + btn_keylines[i] = true; + number_of_buttons_pressed++; + } + } + if (number_of_buttons_pressed < 2) { + for (i = 0; i < pdata->num_line_gpios; i++) { + index = (keypad->current_line_gpio * + pdata->num_line_gpios) + + i; + btn_key = pdata->keycode[index]; + if (btn_key != pdata->keycode[0]) { + btn_index = get_btn_index(keypad, btn_key); + set_btn_state_by_hw( + &keypad->button_array[btn_index], + btn_keylines[i]); + } + } + } + + kfree(btn_keylines); + activate_line_driving(pdata, (int)keypad->current_line_gpio, false); + keypad->current_line_gpio++; + activate_line_driving( + pdata, (int)(keypad->current_line_gpio % pdata->num_line_gpios), + true); +} + +static void matrix_keypad_poll(struct input_dev *input) +{ + struct matrix_keypad *keypad = input_get_drvdata(input); + struct input_dev *input_dev = keypad->input_dev; + + if (keypad->stopped == false) { + if (keypad->current_line_gpio == + keypad->pdata->num_line_gpios) { + poll_process(keypad, input_dev); + } else { + poll_update(keypad, input_dev); + } + } +} + /* * This gets the keys from keyboard and reports it to input subsystem */ @@ -127,7 +413,6 @@ static void matrix_keypad_scan(struct work_struct *work) /* assert each column and read the row status out */ for (col = 0; col < pdata->num_col_gpios; col++) { - activate_col(pdata, col, true); for (row = 0; row < pdata->num_row_gpios; row++) @@ -150,8 +435,7 @@ static void matrix_keypad_scan(struct work_struct *work) code = MATRIX_SCAN_CODE(row, col, keypad->row_shift); input_event(input_dev, EV_MSC, MSC_SCAN, code); - input_report_key(input_dev, - keycodes[code], + input_report_key(input_dev, keycodes[code], new_state[col] & (1 << row)); } } @@ -186,7 +470,7 @@ static irqreturn_t matrix_keypad_interrupt(int irq, void *id) disable_row_irqs(keypad); keypad->scan_pending = true; schedule_delayed_work(&keypad->work, - msecs_to_jiffies(keypad->pdata->debounce_ms)); + msecs_to_jiffies(keypad->pdata->debounce_ms)); out: spin_unlock_irqrestore(&keypad->lock, flags); @@ -204,7 +488,8 @@ static int matrix_keypad_start(struct input_dev *dev) * Schedule an immediate key scan to capture current key state; * columns will be activated and IRQs be enabled after the scan. */ - schedule_delayed_work(&keypad->work, 0); + if (keypad->pdata->mode == GENERIC) + schedule_delayed_work(&keypad->work, 0); return 0; } @@ -217,7 +502,9 @@ static void matrix_keypad_stop(struct input_dev *dev) keypad->stopped = true; spin_unlock_irq(&keypad->lock); - flush_delayed_work(&keypad->work); + if (keypad->pdata->mode == GENERIC) + flush_delayed_work(&keypad->work); + /* * matrix_keypad_scan() will leave IRQs enabled; * we should disable them now. @@ -236,7 +523,6 @@ static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) if (enable_irq_wake(pdata->clustered_irq) == 0) keypad->gpio_all_disabled = true; } else { - for (i = 0; i < pdata->num_row_gpios; i++) { if (!test_bit(i, keypad->disabled_gpios)) { gpio = pdata->row_gpios[i]; @@ -296,8 +582,8 @@ static int matrix_keypad_resume(struct device *dev) } #endif -static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, - matrix_keypad_suspend, matrix_keypad_resume); +static SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, matrix_keypad_suspend, + matrix_keypad_resume); static int matrix_keypad_init_gpio(struct platform_device *pdev, struct matrix_keypad *keypad) @@ -316,9 +602,9 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, if (pdata->clustered_irq > 0) { err = request_any_context_irq(pdata->clustered_irq, - matrix_keypad_interrupt, - pdata->clustered_irq_flags, - "matrix-keypad", keypad); + matrix_keypad_interrupt, + pdata->clustered_irq_flags, + "matrix-keypad", keypad); if (err < 0) { dev_err(&pdev->dev, "Unable to acquire clustered interrupt\n"); @@ -327,11 +613,10 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, } else { for (i = 0; i < pdata->num_row_gpios; i++) { err = request_any_context_irq( - gpiod_to_irq(pdata->row_gpios[i]), - matrix_keypad_interrupt, - IRQF_TRIGGER_RISING | - IRQF_TRIGGER_FALLING, - "matrix-keypad", keypad); + gpiod_to_irq(pdata->row_gpios[i]), + matrix_keypad_interrupt, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "matrix-keypad", keypad); if (err < 0) { dev_err(&pdev->dev, "Unable to acquire interrupt for GPIO line %i\n", @@ -361,30 +646,42 @@ static void matrix_keypad_free_gpio(struct matrix_keypad *keypad) { const struct matrix_keypad_platform_data *pdata = keypad->pdata; int i; - - if (pdata->clustered_irq > 0) { - free_irq(pdata->clustered_irq, keypad); + if (pdata->mode == REDUCED) { + for (i = 0; i < pdata->num_line_gpios; i++) + gpiod_put(pdata->desc_gpios[i]); } else { - for (i = 0; i < pdata->num_row_gpios; i++) - free_irq(gpiod_to_irq(pdata->row_gpios[i]), keypad); - } + if (pdata->clustered_irq > 0) { + free_irq(pdata->clustered_irq, keypad); + } else { + for (i = 0; i < pdata->num_row_gpios; i++) + free_irq(gpiod_to_irq(pdata->row_gpios[i]), + keypad); + } - for (i = 0; i < pdata->num_row_gpios; i++) - gpiod_put(pdata->row_gpios[i]); + for (i = 0; i < pdata->num_row_gpios; i++) + gpiod_put(pdata->row_gpios[i]); - for (i = 0; i < pdata->num_col_gpios; i++) - gpiod_put(pdata->col_gpios[i]); + for (i = 0; i < pdata->num_col_gpios; i++) + gpiod_put(pdata->col_gpios[i]); + } } #ifdef CONFIG_OF static struct matrix_keypad_platform_data * matrix_keypad_parse_dt(struct device *dev) { + const struct of_device_id *of_id = + of_match_device(matrix_keypad_dt_match, dev); struct matrix_keypad_platform_data *pdata; struct device_node *np = dev->of_node; + const struct keypad_info *info = of_id->data; struct gpio_desc **gpios; struct gpio_desc *desc; int ret, i, nrow, ncol; + int8_t *keycode; + uint32_t *ptr; + int num_gpio; + int keymap; if (!np) { dev_err(dev, "device lacks DT data\n"); @@ -397,11 +694,23 @@ matrix_keypad_parse_dt(struct device *dev) return ERR_PTR(-ENOMEM); } - pdata->num_row_gpios = nrow = gpiod_count(dev, "row"); - pdata->num_col_gpios = ncol = gpiod_count(dev, "col"); - if (nrow <= 0 || ncol <= 0) { - dev_err(dev, "number of keypad rows/columns not specified\n"); - return ERR_PTR(-EINVAL); + pdata->mode = info->mode; + + if (pdata->mode == REDUCED) { + num_gpio = gpiod_count(dev, "line"); + if (num_gpio <= 0) { + dev_err(dev, "number of gpio line not specified\n"); + return ERR_PTR(-EINVAL); + } + } else { + pdata->num_row_gpios = nrow = gpiod_count(dev, "row"); + pdata->num_col_gpios = ncol = gpiod_count(dev, "col"); + + if (nrow <= 0 || ncol <= 0) { + dev_err(dev, + "number of keypad rows/columns not specified\n"); + return ERR_PTR(-EINVAL); + } } if (of_get_property(np, "linux,no-autorepeat", NULL)) @@ -415,34 +724,90 @@ matrix_keypad_parse_dt(struct device *dev) of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms); of_property_read_u32(np, "col-scan-delay-us", - &pdata->col_scan_delay_us); - - gpios = devm_kcalloc(dev, - pdata->num_row_gpios + pdata->num_col_gpios, - sizeof(*gpios), - GFP_KERNEL); - if (!gpios) { - dev_err(dev, "could not allocate memory for gpios\n"); - return ERR_PTR(-ENOMEM); - } + &pdata->col_scan_delay_us); + if (pdata->mode == REDUCED) { + gpios = devm_kcalloc(dev, num_gpio, sizeof(*gpios), GFP_KERNEL); + if (!gpios) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < num_gpio; i++) { + desc = devm_gpiod_get_index(dev, "line", i, GPIOD_ASIS); + if (IS_ERR(desc)) + return ERR_PTR(-EPROBE_DEFER); + gpios[i] = desc; + } - for (i = 0; i < nrow; i++) { - desc = devm_gpiod_get_index(dev, "row", i, GPIOD_IN); - if (IS_ERR(desc)) - return ERR_PTR(ret); - gpios[i] = desc; - } + pdata->desc_gpios = gpios; + pdata->num_line_gpios = num_gpio; + + if (!gpiod_is_active_low(pdata->desc_gpios[0])) + pdata->active_low = true; + } else { + gpios = devm_kcalloc( + dev, pdata->num_row_gpios + pdata->num_col_gpios, + sizeof(*gpios), GFP_KERNEL); + if (!gpios) { + dev_err(dev, "could not allocate memory for gpios\n"); + return ERR_PTR(-ENOMEM); + } + + for (i = 0; i < nrow; i++) { + desc = devm_gpiod_get_index(dev, "row", i, GPIOD_IN); + if (IS_ERR(desc)) + return ERR_PTR(ret); + gpios[i] = desc; + } + + for (i = 0; i < ncol; i++) { + desc = devm_gpiod_get_index(dev, "col", i, GPIOD_IN); + if (IS_ERR(desc)) + return ERR_PTR(ret); + gpios[nrow + i] = desc; + } - for (i = 0; i < ncol; i++) { - desc = devm_gpiod_get_index(dev, "col", i, GPIOD_IN); - if (IS_ERR(desc)) - return ERR_PTR(ret); - gpios[nrow + i] = desc; + pdata->row_gpios = gpios; + pdata->col_gpios = &gpios[pdata->num_row_gpios]; } - pdata->row_gpios = gpios; - pdata->col_gpios = &gpios[pdata->num_row_gpios]; + if (pdata->mode == REDUCED) { + if (of_property_read_u32(np, "poll-interval-ms", + &pdata->poll_interval_ms)) + pdata->poll_interval_ms = 10; + of_property_read_u32(np, "number-of-buttons", + &pdata->num_of_buttons); + if (pdata->num_of_buttons <= 0) { + dev_err(dev, "number of button not specified\n"); + return ERR_PTR(-EINVAL); + } + + keymap = device_property_count_u32(dev, "linux,keymap"); + if (keymap <= 0 || + keymap > (pdata->num_line_gpios * pdata->num_line_gpios)) { + dev_err(dev, "linux,keymap property count is invalid"); + return ERR_PTR(-ENXIO); + } + + ptr = devm_kzalloc(dev, (keymap * sizeof(uint32_t)), + GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + if (device_property_read_u32_array(dev, "linux,keymap", ptr, + keymap)) { + dev_err(dev, "problem parsing keymap property\n"); + return ERR_PTR(-EINVAL); + } + + keycode = devm_kzalloc(dev, (keymap * sizeof(int8_t)), + GFP_KERNEL); + if (!keycode) + return ERR_PTR(-ENOMEM); + + pdata->keycode = keycode; + for (i = 0; i < keymap; i++) + pdata->keycode[i] = KEYCODE(ptr[i]); + } return pdata; } #else @@ -483,22 +848,58 @@ static int matrix_keypad_probe(struct platform_device *pdev) keypad->pdata = pdata; keypad->row_shift = get_count_order(pdata->num_col_gpios); keypad->stopped = true; - INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); + + if (pdata->mode == REDUCED) { + keypad->button_array = devm_kzalloc( + &pdev->dev, + sizeof(struct button) * (pdata->num_of_buttons), + GFP_KERNEL); + if (!keypad->button_array) { + dev_err(&pdev->dev, + "could not allocate memory for button array\n"); + goto err_free_mem; + ; + } + + poll_prepare(keypad); + + err = input_setup_polling(input_dev, matrix_keypad_poll); + if (err) { + dev_err(&pdev->dev, + "unable to set up polling, err=%d\n", err); + return err; + } + + input_set_poll_interval(input_dev, pdata->poll_interval_ms); + } else { + INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); + } spin_lock_init(&keypad->lock); - input_dev->name = pdev->name; - input_dev->id.bustype = BUS_HOST; - input_dev->dev.parent = &pdev->dev; - input_dev->open = matrix_keypad_start; - input_dev->close = matrix_keypad_stop; - - err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, - pdata->num_row_gpios, - pdata->num_col_gpios, - NULL, input_dev); - if (err) { - dev_err(&pdev->dev, "failed to build keymap\n"); - goto err_free_mem; + input_dev->name = pdev->name; + input_dev->id.bustype = BUS_HOST; + input_dev->dev.parent = &pdev->dev; + input_dev->open = matrix_keypad_start; + input_dev->close = matrix_keypad_stop; + + if (pdata->mode == REDUCED) { + err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, + pdata->num_line_gpios, + pdata->num_line_gpios, NULL, + input_dev); + if (err) { + dev_err(&pdev->dev, "failed to build keymap for reduced mode\n"); + goto err_free_mem; + } + } else { + err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, + pdata->num_row_gpios, + pdata->num_col_gpios, NULL, + input_dev); + if (err) { + dev_err(&pdev->dev, "failed to build keymap for generic mode\n"); + goto err_free_mem; + } } if (!pdata->no_autorepeat) @@ -506,9 +907,13 @@ static int matrix_keypad_probe(struct platform_device *pdev) input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); - err = matrix_keypad_init_gpio(pdev, keypad); - if (err) - goto err_free_mem; + if (pdata->mode == REDUCED) { + button_hdl_init(keypad); + } else { + err = matrix_keypad_init_gpio(pdev, keypad); + if (err) + goto err_free_mem; + } err = input_register_device(keypad->input_dev); if (err) @@ -538,14 +943,6 @@ static int matrix_keypad_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF -static const struct of_device_id matrix_keypad_dt_match[] = { - { .compatible = "gpio-matrix-keypad" }, - { } -}; -MODULE_DEVICE_TABLE(of, matrix_keypad_dt_match); -#endif - static struct platform_driver matrix_keypad_driver = { .probe = matrix_keypad_probe, .remove = matrix_keypad_remove, diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 8ad7d4626e62..d5ba9ec21752 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h @@ -6,18 +6,22 @@ #include #include -#define MATRIX_MAX_ROWS 32 -#define MATRIX_MAX_COLS 32 +#define MATRIX_MAX_ROWS 32 +#define MATRIX_MAX_COLS 32 -#define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\ - (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\ - ((val) & 0xffff)) +#define KEY(row, col, val) \ + ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) | \ + (((col) & (MATRIX_MAX_COLS - 1)) << 16) | ((val)&0xffff)) -#define KEY_ROW(k) (((k) >> 24) & 0xff) -#define KEY_COL(k) (((k) >> 16) & 0xff) -#define KEY_VAL(k) ((k) & 0xffff) +#define KEY_ROW(k) (((k) >> 24) & 0xff) +#define KEY_COL(k) (((k) >> 16) & 0xff) +#define KEY_VAL(k) ((k)&0xffff) -#define MATRIX_SCAN_CODE(row, col, row_shift) (((row) << (row_shift)) + (col)) +#define MATRIX_SCAN_CODE(row, col, row_shift) (((row) << (row_shift)) + (col)) +#define KEYCODE(keymap) (keymap & 0xFFFF) + +#define GENERIC (1) /* keypad mode generic */ +#define REDUCED (2) /* keypad mode reduced */ /** * struct matrix_keymap_data - keymap for matrix keyboards @@ -30,7 +34,7 @@ */ struct matrix_keymap_data { const uint32_t *keymap; - unsigned int keymap_size; + unsigned int keymap_size; }; /** @@ -38,6 +42,7 @@ struct matrix_keymap_data { * @keymap_data: pointer to &matrix_keymap_data * @row_gpios: pointer to array of gpio numbers representing rows * @col_gpios: pointer to array of gpio numbers reporesenting colums + * @desc_gpios: actual number of gpio used devide in reduced mode * @num_row_gpios: actual number of row gpios used by device * @num_col_gpios: actual number of col gpios used by device * @col_scan_delay_us: delay, measured in microseconds, that is @@ -46,6 +51,12 @@ struct matrix_keymap_data { * @clustered_irq: may be specified if interrupts of all row/column GPIOs * are bundled to one single irq * @clustered_irq_flags: flags that are needed for the clustered irq + * @num_line_gpios: actual number of gpio line in reduced mode + * @num_of_buttons: number of physical buttons on keypad + * in reduced mode + * @poll_interval_ms: interval to poll gpio in reduced mode + * @keycode: hold the keycode value + * @mode: flag to set mode * @active_low: gpio polarity * @wakeup: controls whether the device should be set up as wakeup * source @@ -61,32 +72,37 @@ struct matrix_keypad_platform_data { struct gpio_desc **row_gpios; struct gpio_desc **col_gpios; + struct gpio_desc **desc_gpios; - unsigned int num_row_gpios; - unsigned int num_col_gpios; + unsigned int num_row_gpios; + unsigned int num_col_gpios; - unsigned int col_scan_delay_us; + unsigned int col_scan_delay_us; /* key debounce interval in milli-second */ - unsigned int debounce_ms; + unsigned int debounce_ms; + + unsigned int clustered_irq; + unsigned int clustered_irq_flags; + unsigned int num_line_gpios; + unsigned int num_of_buttons; + unsigned int poll_interval_ms; - unsigned int clustered_irq; - unsigned int clustered_irq_flags; + int8_t *keycode; + int8_t mode; - bool active_low; - bool wakeup; - bool no_autorepeat; - bool drive_inactive_cols; + bool active_low; + bool wakeup; + bool no_autorepeat; + bool drive_inactive_cols; }; int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, - const char *keymap_name, - unsigned int rows, unsigned int cols, - unsigned short *keymap, + const char *keymap_name, unsigned int rows, + unsigned int cols, unsigned short *keymap, struct input_dev *input_dev); -int matrix_keypad_parse_properties(struct device *dev, - unsigned int *rows, unsigned int *cols); - +int matrix_keypad_parse_properties(struct device *dev, unsigned int *rows, + unsigned int *cols); #define matrix_keypad_parse_of_params matrix_keypad_parse_properties #endif /* _MATRIX_KEYPAD_H */ From patchwork Fri Aug 19 06:59:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gireesh Hiremath X-Patchwork-Id: 12948452 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC2F7C32771 for ; Fri, 19 Aug 2022 07:00:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346790AbiHSHAu (ORCPT ); Fri, 19 Aug 2022 03:00:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346858AbiHSHAl (ORCPT ); Fri, 19 Aug 2022 03:00:41 -0400 Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on2078.outbound.protection.outlook.com [40.107.22.78]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACA551A83B; Fri, 19 Aug 2022 00:00:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dpBhCRreRtAsetNaqRYtFz/7uhXS2Zc5YXYiX7yJnEq2DF4Jgkumx99JDHw20rBfOodvjyvoFoRKnC3CbbODUldcSDYyJcq+Ww08kyQieKQrqlslFkdgTtVZEVyIh+IVBoXxHbzF8tuBRw7qoD0w3CVw+kcVYIEWWhaZmxVDSyrDFbJlJsNjAi/E8Jb3KMhTJLDyquRN5NeqcGahFm1jPLbOnK560nLHfvk/S4gsWXKqXq4a+C/k5YqdZG4XY0uDU+kXUbuamn2HLHiIdCvBBTYHVx35VUcbY9bf+4TlDQ1XzhBeQ4akjV8uAr8+N8YCxSc3AH2P8Jy1629q+IhsmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gd3VYNsGQXI3W91x8h9TQ2L9ikaOGmPCMBRYTR6flyM=; b=KPloVDin7TaIhsycEscYwMfBtjbxvQAjFpuXEOwqffnQ6tcj+6LVcLb29nj9E6TbaXDX3sRlv74kBm8Dhkys8DDK1ltmoM217oW1Az9zoHBcvFcHJxAGxfptLsa/j2aMP3jf0nznMMs3XYMahrJViqXSuNZ64sP1TFhyadV/ZSDvGn0M8/l3CVSFVxZF6GxW4zgnJeb0OL7j+dsoGOztDfeNkLKcNQBjqLervZxXxqhaD9bpQkOs89fibf0L5nVDxMhH7qSFlT42k4H4PBIe20I9Qw/SyxzADhpg0FEjnn8MGK3y2PyWyvTmeXsmZnU0/6p7QwqobSPkbB0pTU5H3Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 139.15.153.203) smtp.rcpttodomain=vger.kernel.org smtp.mailfrom=in.bosch.com; dmarc=pass (p=reject sp=none pct=100) action=none header.from=in.bosch.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=in.bosch.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gd3VYNsGQXI3W91x8h9TQ2L9ikaOGmPCMBRYTR6flyM=; b=Kzv4w4PrMsqecBlJZ67Ap+G/idoD3FiGH9EhYtQXtdnnwqf+Z55/nU89/ElNMaIZ3ci9Jn1Q6TZRwNTauAE9DGlUAvOgYxY+769r2lDonqwf9hmHUMCBUXALI5SHldS6dQaWxyXnKuZmGinfmfpklKIXokMu1yQISZDChXcAA3Y= Received: from DB8PR09CA0011.eurprd09.prod.outlook.com (2603:10a6:10:a0::24) by VI1PR10MB3535.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:800:13e::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.16; Fri, 19 Aug 2022 07:00:33 +0000 Received: from DBAEUR03FT020.eop-EUR03.prod.protection.outlook.com (2603:10a6:10:a0:cafe::f1) by DB8PR09CA0011.outlook.office365.com (2603:10a6:10:a0::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5525.11 via Frontend Transport; Fri, 19 Aug 2022 07:00:33 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 139.15.153.203) smtp.mailfrom=in.bosch.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=in.bosch.com; Received-SPF: Pass (protection.outlook.com: domain of in.bosch.com designates 139.15.153.203 as permitted sender) receiver=protection.outlook.com; client-ip=139.15.153.203; helo=eop.bosch-org.com; pr=C Received: from eop.bosch-org.com (139.15.153.203) by DBAEUR03FT020.mail.protection.outlook.com (100.127.143.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.15 via Frontend Transport; Fri, 19 Aug 2022 07:00:33 +0000 Received: from SI-EXCAS2001.de.bosch.com (10.139.217.202) by eop.bosch-org.com (139.15.153.203) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Fri, 19 Aug 2022 09:00:33 +0200 Received: from FE-HUB2000.de.bosch.com (10.4.103.109) by SI-EXCAS2001.de.bosch.com (10.139.217.202) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Fri, 19 Aug 2022 09:00:32 +0200 Received: from localhost.localdomain (10.167.0.81) by FE-HUB2000.de.bosch.com (10.4.103.109) with Microsoft SMTP Server id 15.1.2375.31; Fri, 19 Aug 2022 09:00:29 +0200 From: To: , , , , , , , , , , , , , , , , , CC: , , , Subject: [PATCH v3 3/3] dt-bindings: input: gpio-matrix-keypad: add reduced matrix keypad bindings definition Date: Fri, 19 Aug 2022 06:59:46 +0000 Message-ID: <20220819065946.9572-3-Gireesh.Hiremath@in.bosch.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220819065946.9572-1-Gireesh.Hiremath@in.bosch.com> References: <20220819065946.9572-1-Gireesh.Hiremath@in.bosch.com> MIME-Version: 1.0 X-Originating-IP: [10.167.0.81] X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f28012e3-4ae4-4ce1-207a-08da81b082d5 X-MS-TrafficTypeDiagnostic: VI1PR10MB3535:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: QBTm6S3Lm9eZlfqvKHnxFToa+7YmL+W2hXhiEH+QoXs73Z0Iqm3E9Qt7b96wubq7cht84u5n+gbZ2k7bbk2zN5uJ22edrD0VwieU8C/xeKxvUsdH6bmiQraX1h3xO7FTdPexe+hPtdU/yDhdgCyvdZRkZ9yI5ekNxUTu82VPQJiRiQqhVyM2ObYmQrAp12uMsKuX50/FJ0DYd9tnMtI6jHg5brBX7gOFkfe7Fgk3nddm1rPTX8SrY2h1puMM0V+gvgG+FXWRueWF28VkEgG/9zX7n6gVgkFWAUMVJguPsio8EgEz2fBfC4uIKwqoem1UqBqkk6K8mvTT+pqECzTtoyWAkueArp26PHQRqtLNjc4bhfbC65lqJYUziiGyZhLDMueuMCYWQ0S7mvX4GPJmpOuTPzR1QkqAHnTAcvBO+cDfEEOBvgIxRlbwWDYB0wCny6V7GhIy3EWHfqmdbhwyoXRTm0k+NPjfh5bcKdzJzKpH1NyzhF1dm+Wsnd+sy9owIGVN/ptzpuS763JIMnnaDbhJC5zEiBKmNN3y75jzFyUTlxshDvJNrQSnH/QgtXf1M2YTUb3xbwxuLNUHFH24xjUsPsAgvRfolU/4dToXOHnKgMewnZfwHWdsUGBRxOYP9s/LD5s0FWRqX5swzhN6mJq7reKcPLqRi2apB3rW0gNgqT6Z08VHqrPSbwjnsKCrav4CjCf0fL4baaMI0ezSg6896dROhad3ahJn+q5x4qQDJ9U6/k8IMtJaZ87k3hFsEvMOms8utxz3mgC/jNI5Tb2bbsj10lW4CaUDytMr5zDLY0sNVbCqY5HNJ3JZmexU X-Forefront-Antispam-Report: CIP:139.15.153.203;CTRY:DE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:eop.bosch-org.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230016)(4636009)(346002)(396003)(376002)(39860400002)(136003)(46966006)(36840700001)(40470700004)(7049001)(81166007)(82960400001)(82310400005)(316002)(110136005)(54906003)(8676002)(356005)(4326008)(8936002)(70206006)(86362001)(5660300002)(70586007)(26005)(40480700001)(47076005)(36860700001)(40460700003)(107886003)(2616005)(186003)(16526019)(336012)(1076003)(82740400003)(7416002)(6666004)(41300700001)(478600001)(921005)(2906002)(2876002)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: in.bosch.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Aug 2022 07:00:33.4329 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f28012e3-4ae4-4ce1-207a-08da81b082d5 X-MS-Exchange-CrossTenant-Id: 0ae51e19-07c8-4e4b-bb6d-648ee58410f4 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0ae51e19-07c8-4e4b-bb6d-648ee58410f4;Ip=[139.15.153.203];Helo=[eop.bosch-org.com] X-MS-Exchange-CrossTenant-AuthSource: DBAEUR03FT020.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR10MB3535 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: Gireesh Hiremath Add binding definition for the support of the reduced matrix keypad driver. Signed-off-by: Gireesh Hiremath --- .../bindings/input/gpio-matrix-keypad.txt | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt index 570dc10f0cd7..1cedec29505c 100644 --- a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt +++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt @@ -1,11 +1,46 @@ * GPIO driven matrix keypad device tree bindings GPIO driven matrix keypad is used to interface a SoC with a matrix keypad. + +Generic mode: The matrix keypad supports multiple row and column lines, a key can be placed at each intersection of a unique row and a unique column. The matrix keypad can sense a key-press and key-release by means of GPIO lines and report the event using GPIO interrupts to the cpu. +Reduced mode: +The reduced matric keypad supports multiple gpio lines, all gpio lines +act as row as well as column lines, a key can be placed at each intersection +of a row number not equal to a column number and they are diagonally +symmetric. + +Example- For 5 gpio lines, possible matrix is 5x5 and maximum possible + keys are 10. + + Sample matrix table for 7 buttons and 5 gpio lines + + ------------------------------------------------------ + |Row\Col |GPIO 0 | GPIO 1 | GPIO 2 | GPIO 3 | GPIO 4 | + ------------------------------------------------------ + | GPIO 0 | X | KEY_9 | KEY_2 | X | KEY_1 | + ------------------------------------------------------ + | GPIO 1 | KEY_9 | X | KEY_6 | X | X | + ------------------------------------------------------ + | GPIO 2 | KEY_2 | KEY_6 | X | KEY_4 | KEY_7 | + ------------------------------------------------------ + | GPIO 3 | X | X | KEY_4 | X | KEY_8 | + ------------------------------------------------------ + | GPIO 4 | KEY_1 | X | KEY_7 | KEY_8 | X | + ------------------------------------------------------ + X - invalid key + KEY_x - preferred key code + +The reduced mode sense a key-press and key-release by polling +GPIO lines and report the event. + + +Generic mode: + Required Properties: - compatible: Should be "gpio-matrix-keypad" - row-gpios: List of gpios used as row lines. The gpio specifier @@ -47,3 +82,64 @@ Example: 0x0101001C 0x0201006C>; }; + +Reduced mode: + +Required Properties: +- compatible: Should be "gpio-matrix-keypad-reduced" +- number-of-buttons: Number of buttons connected to the keypad controller. +- line-gpios: Gpio lines connected to keypad controller. + all gpio lines act as row as well as column lines. +- linux,keymap: An array of packed 1-cell entries containing the + equivalent of row, column and linux key-code. + The 32-bit big endian cell is packed as: + row << 24 | column << 16 | key-code + +Optional Properties: +- poll-interval-ms: Time interval between poll. +- linux,no-autorepeat: Do no enable autorepeat feature. +- col-scan-delay-us: Delay before scanning next active line. + +Example: + keypad { + compatible = "gpio-matrix-keypad-reduced"; + poll-interval-ms = <10>; + col-scan-delay-us = <2>; + number-of-buttons = <7>; + linux,no-autorepeat; + line-gpios = < + &gpio1 24 1 /*gpio_56*/ + &gpio1 23 1 /*gpio_55*/ + &gpio1 22 1 /*gpio_54*/ + &gpio1 20 1 /*gpio_52*/ + &gpio1 16 1 /*gpio_48*/ + >; + linux,keymap = < + 0x00000000 /* row 0, col 0, KEY_RESERVED */ + 0x0001000a /* row 0, col 1, KEY_9 */ + 0x00020003 /* row 0, col 2, KEY_2 */ + 0x00030000 /* row 0, col 3, KEY_RESERVED */ + 0x00040002 /* row 0, col 4, KEY_1 */ + 0x0100000a /* row 1, col 0, KEY_9 */ + 0x01010000 /* row 1, col 1, KEY_RESERVED */ + 0x01020007 /* row 1, col 2, KEY_6 */ + 0x01030000 /* row 1, col 3, KEY_RESERVED */ + 0x01040000 /* row 1, col 4, KEY_RESERVED */ + 0x02000003 /* row 2, col 0, KEY_2 */ + 0x02010007 /* row 2, col 1, KEY_6 */ + 0x02020000 /* row 2, col 2, KEY_RESERVED */ + 0x02030005 /* row 2, col 3, KEY_4 */ + 0x02040008 /* row 2, col 4, KEY_7 */ + 0x03000000 /* row 3, col 0, KEY_RESERVED */ + 0x03010000 /* row 3, col 1, KEY_RESERVED */ + 0x03020005 /* row 3, col 2, KEY_4 */ + 0x03030000 /* row 3, col 3, KEY_RESERVED */ + 0x03040009 /* row 3, col 4, KEY_8 */ + 0x04000002 /* row 4, col 0, KEY_1 */ + 0x04010000 /* row 4, col 1, KEY_RESERVED */ + 0x04020008 /* row 4, col 2, KEY_7 */ + 0x04030009 /* row 4, col 3, KEY_8 */ + 0x04040000 /* row 4, col 4, KEY_RESERVED */ + >; + + };