{"id":2232225,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2232225/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/20260504003421.2545713-4-mikhail.kshevetskiy@iopsys.eu/","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/1.2/projects/18/?format=json","name":"U-Boot","link_name":"uboot","list_id":"u-boot.lists.denx.de","list_email":"u-boot@lists.denx.de","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260504003421.2545713-4-mikhail.kshevetskiy@iopsys.eu>","list_archive_url":null,"date":"2026-05-04T00:34:15","name":"[v3,3/9] pinctrl: airoha: add shared pinctrl code","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"9c2a8e68c75d4d0f45b007f0bb087f898055b831","submitter":{"id":84987,"url":"http://patchwork.ozlabs.org/api/1.2/people/84987/?format=json","name":"Mikhail Kshevetskiy","email":"mikhail.kshevetskiy@iopsys.eu"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/20260504003421.2545713-4-mikhail.kshevetskiy@iopsys.eu/mbox/","series":[{"id":502598,"url":"http://patchwork.ozlabs.org/api/1.2/series/502598/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=502598","date":"2026-05-04T00:34:12","name":"pinctrl: add support of Airoha SoCs","version":3,"mbox":"http://patchwork.ozlabs.org/series/502598/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2232225/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2232225/checks/","tags":{},"related":[],"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256\n header.s=selector1 header.b=iEcvfbMn;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)","phobos.denx.de;\n dmarc=pass (p=reject dis=none) header.from=iopsys.eu","phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de","phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b=\"iEcvfbMn\";\n\tdkim-atps=neutral","phobos.denx.de;\n dmarc=pass (p=reject dis=none) header.from=iopsys.eu","phobos.denx.de;\n spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu","dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=iopsys.eu;"],"Received":["from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g82jd3189z1yJ0\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 04 May 2026 10:35:17 +1000 (AEST)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 6BA178464D;\n\tMon,  4 May 2026 02:34:50 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id EEB0A84660; Mon,  4 May 2026 02:34:49 +0200 (CEST)","from DB3PR0202CU003.outbound.protection.outlook.com\n (mail-northeuropeazlp170100001.outbound.protection.outlook.com\n [IPv6:2a01:111:f403:c200::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 0721E84605\n for <u-boot@lists.denx.de>; Mon,  4 May 2026 02:34:47 +0200 (CEST)","from VI1PR08MB10029.eurprd08.prod.outlook.com\n (2603:10a6:800:1c6::15) by DU0PR08MB8662.eurprd08.prod.outlook.com\n (2603:10a6:10:402::11) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9870.25; Mon, 4 May\n 2026 00:34:44 +0000","from VI1PR08MB10029.eurprd08.prod.outlook.com\n ([fe80::5e67:2d67:644b:9681]) by VI1PR08MB10029.eurprd08.prod.outlook.com\n ([fe80::5e67:2d67:644b:9681%6]) with mapi id 15.20.9846.025; Mon, 4 May 2026\n 00:34:44 +0000"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_PASS,SPF_PASS autolearn=no\n autolearn_force=no version=3.4.2","ARC-Seal":"i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n b=AMDAogl7jlreAS62NmLyxrnRXyZmNws6GKlngDuU+6pJhUBk7pkDYWHE1JZQ5wA9pn9WZG4CypfttT7jDy/gAzYLSEbDWta+gMBv02dVF+rc9FKieI7wkRHj2fYASXcT9cvVwxDLN2BZ8zkwu/Wh7zds7MJ5EdWcYM306XY+55VcnMBv0QYiHjzj6v6kOP20kMrI9+eXBI6ZMo8qXyUGwWwbHKzD25UkoC8lEBXDojFWBosoH+DkgYduSV41qOgPXiDDv/Vir/TdlOoy7osJq4XuBnybGV0evnjTBxtYmOSxUKvW5U/ZiDzd2sr8s2envSjJV7HewXPc/JWfZjF6Lw==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector10001;\n 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;\n bh=G8ES6e2RCeDl3j6yfEOwGZAnnZXYxsHLIgEvr7n257E=;\n b=OTkTQ5oUIg5qpLEh/0ygJd2Be1IIjQozaTAuR+LrtoN/dLzd3Sd/5KHXnwHSpYC+NcU20SNYSo8VgtBByYA7KUW304qGv9btPuKTTTGjMbuOZUh2NFsDCR9MvaK5W9fHCHXukkc5vgOQUXeyVblEawAVd7RbghuTCvGyYW7NF/4pNbLC7i256zxUGslbD5+sG3tgzbfko/U7Iw1M8lo5TzS6QazbNG+8XEsXrMWqwnVeWJOLGIB5UdI5B+QKr4Z+clWRTwXMVMQNbvaAjOoANDDNTHtS1ueYlsv/1uoN7jux6/c515rdZEhWVol/liYCrJmiFwt0pBpfFonrCNqykg==","ARC-Authentication-Results":"i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu;\n dkim=pass header.d=iopsys.eu; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu;\n s=selector1;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=G8ES6e2RCeDl3j6yfEOwGZAnnZXYxsHLIgEvr7n257E=;\n b=iEcvfbMnU0+JP3Ecqe1VnGtj7nSCDz13Nk72nlE7Tb9rEKRxhAvEF1AO7xqxzy20HBj4FdFpmKumTr7HlSlTmyubKc8jPL1f0PsNaqSif2pzs7iKqeo2xiFeQ5GGxCw5WHOHRo8c6C0j0wrV8QCJbzOHiA9tkk9UKNLQkE6fVd3QgzVc5iLklh7Z+ie2pYp8eInN7OUBS7Ba3TNrBSP/iLPWTWM8aOghMvj9eE+rY6SQzWqZt6XxhvnPIcDMnV7wazuDXC/2pVr9hGnlQ5kzbiDqDtw8646m1LiFijAdovjUQzw18ZSAUSi83yj9PCXZF5z//1SVuHtWZyxjdUav2Q==","From":"Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>","To":"Tom Rini <trini@konsulko.com>, Christian Marangi <ansuelsmth@gmail.com>,\n Simon Glass <sjg@chromium.org>,\n Marek Vasut <marek.vasut+renesas@mailbox.org>, Peng Fan <peng.fan@nxp.com>,\n Michael Trimarchi <michael@amarulasolutions.com>,\n Anis Chali <chalianis1@gmail.com>, Michal Simek <michal.simek@amd.com>,\n Dan Carpenter <dan.carpenter@linaro.org>,\n Sean Anderson <sean.anderson@linux.dev>, Yao Zi <me@ziyao.cc>,\n \"Yury Norov (NVIDIA)\" <yury.norov@gmail.com>,\n Geert Uytterhoeven <geert+renesas@glider.be>,\n Alexandre Belloni <alexandre.belloni@bootlin.com>,\n Crt Mori <cmo@melexis.com>, Richard Genoud <richard.genoud@bootlin.com>,\n u-boot@lists.denx.de, David Lechner <dlechner@baylibre.com>,\n Lorenzo Bianconi <lorenzo@kernel.org>,\n Markus Gothe <markus.gothe@genexis.eu>,\n Matheus Sampaio Queiroga <srherobrine20@gmail.com>,\n Benjamin Larsson <benjamin.larsson@genexis.eu>","Cc":"Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>","Subject":"[PATCH v3 3/9] pinctrl: airoha: add shared pinctrl code","Date":"Mon,  4 May 2026 03:34:15 +0300","Message-ID":"<20260504003421.2545713-4-mikhail.kshevetskiy@iopsys.eu>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<20260504003421.2545713-1-mikhail.kshevetskiy@iopsys.eu>","References":"<20260504003421.2545713-1-mikhail.kshevetskiy@iopsys.eu>","Content-Transfer-Encoding":"8bit","Content-Type":"text/plain","X-ClientProxiedBy":"GV2PEPF00023A03.SWEP280.PROD.OUTLOOK.COM\n (2603:10a6:158:400::2aa) To VI1PR08MB10029.eurprd08.prod.outlook.com\n (2603:10a6:800:1c6::15)","MIME-Version":"1.0","X-MS-PublicTrafficType":"Email","X-MS-TrafficTypeDiagnostic":"VI1PR08MB10029:EE_|DU0PR08MB8662:EE_","X-MS-Office365-Filtering-Correlation-Id":"033d5cb5-94bd-4280-40fe-08dea974f034","X-MS-Exchange-SenderADCheck":"1","X-MS-Exchange-AntiSpam-Relay":"0","X-Microsoft-Antispam":"BCL:0;\n ARA:13230040|1800799024|366016|52116014|7416014|376014|38350700014|921020|56012099003|22082099003|18002099003;","X-Microsoft-Antispam-Message-Info":"\n rv0a/RSDv8vcEhzZF5UopQye8ivFrjvtZNa3xdMfCuumFdICDMX045e3gY2udT2vwE2Kxf5cnbMCjVD2K4S0VM/aQZQzgCQ0Y1lnkt2mEScjak38MhSxnxyPN8Oa/+5xO2kWjBezKduOkiloGww6kKcgL3Fj1zplBTdmcelPotsSwoAWMIPzrAFUDmKPH9yM+fjdd4YtEvC4vGLeNmRU6wwZRheA45s95HQfIF1mHLtp/Qs4luNpl8m7bDd5Kltb4h94ABvJ1jvU8HDOveW1hjeXHFCL5R0wEb+8W+e0GwQNW6Fs9kU+iXSrxCJkMZWONppjcTHOsWzmB8Se7h3vh1MnoOpiri04AwIvPgSdZc3zahVM7nGwwNZJxpbE4UsXTUmCJSVgagu7WjNV7LjOT6U5fOVwMOhOyi04DezKcf0v+v+YoV5yMqUPKSKg6RBiGa1fjnx4bqNXzML550op24yIu1q5cloEPEiiD9T+doMiqul/uHbCAvkYslKHI3My0u9+O4Jvbaz6deig9kUqUUyONHW8WuITtdl3YZ3Me5PSWUUZHQGBmH9CJapwDywhzQePHEmEWMhn1ZWr8BiK5tYcNHMFZqPxEBDavbFz9AsN/1jTnG5JsAKmLFfxq8/nj7h2GAvRdgwMtMiPxTCB5vhBjHslgdhwmhMQ2/jY5U2ZrCnG/5mVqAGWYXqBfjwi1uehKUdkirlP2TKEbDbqR+oVI59A1rAWfmomN9S+bLLUuJz7s0ZYbu03IK3iPzgxLVMLIMpUhc2zNP+944Dn0A==","X-Forefront-Antispam-Report":"CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:VI1PR08MB10029.eurprd08.prod.outlook.com; PTR:;\n CAT:NONE;\n SFS:(13230040)(1800799024)(366016)(52116014)(7416014)(376014)(38350700014)(921020)(56012099003)(22082099003)(18002099003);\n DIR:OUT; SFP:1102;","X-MS-Exchange-AntiSpam-MessageData-ChunkCount":"1","X-MS-Exchange-AntiSpam-MessageData-0":"\n ZxPZ28FVnCf+ilXkP43AnI9X7RSESqKqjt+Hpd0kR9YkIbGuiJ3VZgnmpx6IQu84EemibMhtbVXGcPdZ14rkIrzgGvls7TMhqqWVg7ziw9ovxEhv3TY3ldEZLcwllvdv6v66JEsxN2t0ei6YcoZDH0ON35NL6s3T8kS5Er07JSwjhjf+UR57FPH90jfhA1c12FQhAA0JjO9L//+c21dum7S0PZGMm3uC2REbZI/ppB7WO8t1rTXqM8iRaxMRV8TRW5u+MaQgtaQXNX9r/7dImwcjCh/DLM/pZ7kUfLGcK6e1dcExipoatGiQiPjMBLX5MlZCxeXwThBZ6/w1/R+wjVx037IhTKGbeYUuWfjvLb78/y3NXrhZ7ybg/gKs3qpAhVSPalWUZmhkBblCnSUvLky9rr9ncpTKMSmPsjibtd19EbVg20sltmM+xnM6U/uwsNlqGnIzcPkrkQyhhdtkexAF+DNxk4r7HCnWngj6/Ayv5rY0GPI/HqcJ0d6GMBr9sKu7k0ueicjwDflPmSiXrDkRUk+VNNl89itFcJA/vrYlwolILDipacymt45Ybs6pd0ESfdnkNekh9XYEe2ctvA4mlvAgpauvYzDPrxLR3nu0eh37UPXgI8dhGDii+dzc7w9c5t7stA7N5pBi83vCGz3mH/ZhGF0r8vNwI0i/FQ9x3CnDFwWeEAn8lfTD3jcZjiZ9v2iQCpug2c4n2UWJkNqWibHiE2SY7PptYcyrWehGOomGBqG1s3lEVmLmiUmKCDQ2wG4WfUbgtSE9VB6ownnJuMYuWUhZt0VAUXsUSopuXh7kT2EKCAtF8WAABp2X461ivALd9ooDZhNj4OHHlF8JLyZD+53V5WgHRm5ZCP6iaQr9dYmZmqJu8cl3Bs7uTjbZA+dNOqmHE06yA08yo3X6wJqHaZvCguzdLzjnIPqZyRH4usLJtdKVC6y+hh7RhaiM0yhPgsutiHWm+bBz1EYHj3icg8EblwAZG20TSSzoediOioFfXcmnDTa2AyzkMtlSfwHqCFHrx0iwwZ8GW8nV7Uui4J9VE2ramd2FDPzQsWfgQy1iWji6Lpv/ybW/TJC6sq+aj44OSSEAjF6Ki5yfzlpW6BkTCBrwzTCiGdUrFWmDspA1HLU0hG2Q+Cgfd+jQOimZ2QsZ522tInza8ZCLWHJC4gnCVu0uuIEG3wMin7iGyt63m8khY922qUY0SdKBQ3ussG+NttPENJuP8/P0k9sw4B+LgZXI4EocFsT0ZdO6oJN1dE799qq35KuP+yHO1Jf9mQilJv5P/7jWEGMFwefRMLw++8afPfEcAqTwh/xCwBo5qkUOyLVipv2ZxdrhKjqhuaUyOb45ZIvjlgaCIZcNU3DOl/f9Gb6TSSTRPh/7Trypmou2xDHbH6cDYLXdwg9B+aFFgbRUaPH6kM2WiYRAN8EKT/BCbYVrWY+x2O76qzdlfy+9nWyr5lkRQhXlWsUSpPbaS7hYF1G7PlagNRANk79n9bk7tw74LclHOp21LKWForJASEs3yYFztE7k31eiBVAlWuirT7QesNt/ra6yJlT/0PJWbRPR6s4OlX3+gLXsZdYRTb9NWxDHNLrIYjx2vE2LUxL7j2Nrv2Hi+dWaxjAaRvr7zxswULbJa0ddKmQI9ZrfuCvOKziIWX2MRP4bXs599Ql5mRryGf7mNr5pEnvErzthXGmZIsZRpnkXVNtWGPsT9+fp9RyP8/ZuElOfjRmM2ceaprgeg3wVNTDAaYhIiSTtmAO/r/I=","X-OriginatorOrg":"iopsys.eu","X-MS-Exchange-CrossTenant-Network-Message-Id":"\n 033d5cb5-94bd-4280-40fe-08dea974f034","X-MS-Exchange-CrossTenant-AuthSource":"VI1PR08MB10029.eurprd08.prod.outlook.com","X-MS-Exchange-CrossTenant-AuthAs":"Internal","X-MS-Exchange-CrossTenant-OriginalArrivalTime":"04 May 2026 00:34:44.7591 (UTC)","X-MS-Exchange-CrossTenant-FromEntityHeader":"Hosted","X-MS-Exchange-CrossTenant-Id":"8d891be1-7bce-4216-9a99-bee9de02ba58","X-MS-Exchange-CrossTenant-MailboxType":"HOSTED","X-MS-Exchange-CrossTenant-UserPrincipalName":"\n tj53OBz41oaq/huDkmjE/7+uY3KaW4qlagsPqVUnkJof/k/ZoAtk/p3T4Uvi+/ChDi058epYTBt6/LotccznXtZEE5ow68tA+Gc6ajafSJQ=","X-MS-Exchange-Transport-CrossTenantHeadersStamped":"DU0PR08MB8662","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.39","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<https://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>","X-Virus-Scanned":"clamav-milter 0.103.8 at phobos.denx.de","X-Virus-Status":"Clean"},"content":"This patch introduce shared Airoha pinctrl code.\n\nSigned-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>\n---\n drivers/pinctrl/Kconfig                 |   1 +\n drivers/pinctrl/Makefile                |   1 +\n drivers/pinctrl/airoha/Kconfig          |  11 +\n drivers/pinctrl/airoha/Makefile         |   3 +\n drivers/pinctrl/airoha/airoha-common.h  | 513 +++++++++++++++\n drivers/pinctrl/airoha/pinctrl-airoha.c | 827 ++++++++++++++++++++++++\n 6 files changed, 1356 insertions(+)\n create mode 100644 drivers/pinctrl/airoha/Kconfig\n create mode 100644 drivers/pinctrl/airoha/Makefile\n create mode 100644 drivers/pinctrl/airoha/airoha-common.h\n create mode 100644 drivers/pinctrl/airoha/pinctrl-airoha.c","diff":"diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig\nindex 578edbf8168..46a95a1ab6b 100644\n--- a/drivers/pinctrl/Kconfig\n+++ b/drivers/pinctrl/Kconfig\n@@ -405,6 +405,7 @@ config SPL_PINCTRL_ZYNQMP\n \n endif\n \n+source \"drivers/pinctrl/airoha/Kconfig\"\n source \"drivers/pinctrl/broadcom/Kconfig\"\n source \"drivers/pinctrl/exynos/Kconfig\"\n source \"drivers/pinctrl/intel/Kconfig\"\ndiff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile\nindex 29fb9b484d0..b03e838ab39 100644\n--- a/drivers/pinctrl/Makefile\n+++ b/drivers/pinctrl/Makefile\n@@ -24,6 +24,7 @@ obj-$(CONFIG_PINCTRL_PIC32)\t+= pinctrl_pic32.o\n obj-$(CONFIG_PINCTRL_EXYNOS)\t+= exynos/\n obj-$(CONFIG_PINCTRL_K210)\t+= pinctrl-k210.o\n obj-$(CONFIG_PINCTRL_MESON)\t+= meson/\n+obj-$(CONFIG_PINCTRL_AIROHA)\t+= airoha/\n obj-$(CONFIG_PINCTRL_MTK)\t+= mediatek/\n obj-$(CONFIG_PINCTRL_MSCC)\t+= mscc/\n obj-$(CONFIG_ARCH_MVEBU)\t+= mvebu/\ndiff --git a/drivers/pinctrl/airoha/Kconfig b/drivers/pinctrl/airoha/Kconfig\nnew file mode 100644\nindex 00000000000..eb87afbb374\n--- /dev/null\n+++ b/drivers/pinctrl/airoha/Kconfig\n@@ -0,0 +1,11 @@\n+# SPDX-License-Identifier: GPL-2.0-only\n+\n+config PINCTRL_AIROHA\n+\tdepends on ARCH_AIROHA\n+\tselect PINCTRL_FULL\n+\tselect PINCTRL_GENERIC\n+\tselect PINMUX\n+\tselect PINCONF\n+\tselect REGMAP\n+\tselect SYSCON\n+\tbool\ndiff --git a/drivers/pinctrl/airoha/Makefile b/drivers/pinctrl/airoha/Makefile\nnew file mode 100644\nindex 00000000000..a25b744dd7a\n--- /dev/null\n+++ b/drivers/pinctrl/airoha/Makefile\n@@ -0,0 +1,3 @@\n+# SPDX-License-Identifier: GPL-2.0\n+\n+obj-$(CONFIG_PINCTRL_AIROHA)\t\t+= pinctrl-airoha.o\ndiff --git a/drivers/pinctrl/airoha/airoha-common.h b/drivers/pinctrl/airoha/airoha-common.h\nnew file mode 100644\nindex 00000000000..61a8b1345b5\n--- /dev/null\n+++ b/drivers/pinctrl/airoha/airoha-common.h\n@@ -0,0 +1,513 @@\n+/* SPDX-License-Identifier: GPL-2.0-only */\n+#ifndef __AIROHA_COMMON_HEADER__\n+#define __AIROHA_COMMON_HEADER__\n+\n+#include <linux/types.h>\n+#include <linux/bitops.h>\n+#include <linux/bitfield.h>\n+#include <linux/pinctrl/pinctrl.h>\n+\n+#include <dm/device.h>\n+#include <dm/pinctrl.h>\n+\n+#define PINCTRL_PIN_GROUP(id, table)\t\t\t\t\t\\\n+\tPINCTRL_PINGROUP(id, table##_pins, ARRAY_SIZE(table##_pins))\n+\n+#define PINCTRL_FUNC_DESC(id, table)\t\t\t\t\t\\\n+\t{\t\t\t\t\t\t\t\t\\\n+\t\t.desc = PINCTRL_PINFUNCTION(id, table##_groups,\t\\\n+\t\t\t\t\t    ARRAY_SIZE(table##_groups)),\\\n+\t\t.groups = table##_func_group,\t\t\t\t\\\n+\t\t.group_size = ARRAY_SIZE(table##_func_group),\t\t\\\n+\t}\n+\n+#define PINCTRL_CONF_DESC(p, offset, mask)\t\t\t\t\\\n+\t{\t\t\t\t\t\t\t\t\\\n+\t\t.pin = p,\t\t\t\t\t\t\\\n+\t\t.reg = { offset, mask },\t\t\t\t\\\n+\t}\n+\n+/* MUX */\n+#define AN7581_REG_GPIO_2ND_I2C_MODE\t0x0214\n+#define EN7523_REG_GPIO_2ND_I2C_MODE\t0x0210\n+#define GPIO_MDC_IO_MASTER_MODE_MODE\tBIT(14)\n+#define GPIO_I2C_MASTER_MODE_MODE\tBIT(13)\n+#define GPIO_I2S_MODE_MASK\t\tBIT(12)\n+#define GPIO_I2C_SLAVE_MODE_MODE\tBIT(11)\n+#define GPIO_LAN3_LED1_MODE_MASK\tBIT(10)\n+#define GPIO_LAN3_LED0_MODE_MASK\tBIT(9)\n+#define GPIO_LAN2_LED1_MODE_MASK\tBIT(8)\n+#define GPIO_LAN2_LED0_MODE_MASK\tBIT(7)\n+#define GPIO_LAN1_LED1_MODE_MASK\tBIT(6)\n+#define GPIO_LAN1_LED0_MODE_MASK\tBIT(5)\n+#define GPIO_LAN0_LED1_MODE_MASK\tBIT(4)\n+#define GPIO_LAN0_LED0_MODE_MASK\tBIT(3)\n+#define PON_TOD_1PPS_MODE_MASK\t\tBIT(2)\n+#define GSW_TOD_1PPS_MODE_MASK\t\tBIT(1)\n+#define GPIO_2ND_I2C_MODE_MASK\t\tBIT(0)\n+#define NPU_UART_MODE_MASK\t\tBIT(2)\n+\n+#define REG_GPIO_SPI_CS1_MODE\t\t0x0218\n+#define EN7523_REG_GPIO_SPI_CS1_MODE\t0x0214\n+\n+#define GPIO_PCM_SPI_CS4_MODE_MASK\t\tBIT(21)\n+#define GPIO_PCM_SPI_CS3_MODE_MASK\t\tBIT(20)\n+#define GPIO_PCM_SPI_CS2_MODE_P156_MASK\t\tBIT(19)\n+#define GPIO_PCM_SPI_CS2_MODE_P128_MASK\t\tBIT(18)\n+#define AN7583_GPIO_PCM_SPI_CS2_MODE_MASK\tBIT(18)\n+#define GPIO_PCM_SPI_CS1_MODE_MASK\t\tBIT(17)\n+#define GPIO_PCM_SPI_MODE_MASK\t\t\tBIT(16)\n+#define GPIO_PCM2_MODE_MASK\t\t\tBIT(13)\n+#define GPIO_PCM1_MODE_MASK\t\t\tBIT(12)\n+#define GPIO_PCM_INT_MODE_MASK\t\t\tBIT(9)\n+#define GPIO_PCM_RESET_MODE_MASK\t\tBIT(8)\n+#define GPIO_SPI_QUAD_MODE_MASK\t\t\tBIT(4)\n+#define GPIO_SPI_CS4_MODE_MASK\t\t\tBIT(3)\n+#define GPIO_SPI_CS3_MODE_MASK\t\t\tBIT(2)\n+#define GPIO_SPI_CS2_MODE_MASK\t\t\tBIT(1)\n+#define GPIO_SPI_CS1_MODE_MASK\t\t\tBIT(0)\n+\n+#define REG_GPIO_PON_MODE\t\t\t0x021c\n+#define EN7523_REG_GPIO_PON_MODE\t\t0x0218\n+#define GPIO_PARALLEL_NAND_MODE_MASK\t\tBIT(14)\n+#define GPIO_SGMII_MDIO_MODE_MASK\t\tBIT(13)\n+#define GPIO_PCIE_RESET2_MASK\t\t\tBIT(12)\n+#define SIPO_RCLK_MODE_MASK\t\t\tBIT(11)\n+#define GPIO_PCIE_RESET1_MASK\t\t\tBIT(10)\n+#define GPIO_PCIE_RESET0_MASK\t\t\tBIT(9)\n+#define GPIO_UART5_MODE_MASK\t\t\tBIT(8)\n+#define GPIO_UART4_MODE_MASK\t\t\tBIT(7)\n+#define GPIO_HSUART_CTS_RTS_MODE_MASK\t\tBIT(6)\n+#define GPIO_HSUART_MODE_MASK\t\t\tBIT(5)\n+#define GPIO_UART2_CTS_RTS_MODE_MASK\t\tBIT(4)\n+#define GPIO_UART2_MODE_MASK\t\t\tBIT(3)\n+#define GPIO_SIPO_MODE_MASK\t\t\tBIT(2)\n+#define GPIO_EMMC_MODE_MASK\t\t\tBIT(1)\n+#define GPIO_PON_MODE_MASK\t\t\tBIT(0)\n+\n+#define REG_NPU_UART_EN\t\t\t0x0224\n+#define EN7523_REG_NPU_UART_EN\t\t0x0220\n+#define JTAG_UDI_EN_MASK\t\tBIT(4)\n+#define JTAG_DFD_EN_MASK\t\tBIT(3)\n+\n+#define REG_FORCE_GPIO_EN\t\t0x0228\n+#define FORCE_GPIO_EN(n)\t\tBIT(n)\n+\n+/* LED MAP */\n+#define REG_LAN_LED0_MAPPING\t\t0x027c\n+#define REG_LAN_LED1_MAPPING\t\t0x0280\n+\n+#define LAN4_LED_MAPPING_MASK\t\tGENMASK(18, 16)\n+#define LAN4_PHY_LED_MAP(_n)\t\tFIELD_PREP_CONST(LAN4_LED_MAPPING_MASK, (_n))\n+\n+#define LAN3_LED_MAPPING_MASK\t\tGENMASK(14, 12)\n+#define LAN3_PHY_LED_MAP(_n)\t\tFIELD_PREP_CONST(LAN3_LED_MAPPING_MASK, (_n))\n+\n+#define LAN2_LED_MAPPING_MASK\t\tGENMASK(10, 8)\n+#define LAN2_PHY_LED_MAP(_n)\t\tFIELD_PREP_CONST(LAN2_LED_MAPPING_MASK, (_n))\n+\n+#define LAN1_LED_MAPPING_MASK\t\tGENMASK(6, 4)\n+#define LAN1_PHY_LED_MAP(_n)\t\tFIELD_PREP_CONST(LAN1_LED_MAPPING_MASK, (_n))\n+\n+#define LAN0_LED_MAPPING_MASK\t\tGENMASK(2, 0)\n+#define LAN0_PHY_LED_MAP(_n)\t\tFIELD_PREP_CONST(LAN0_LED_MAPPING_MASK, (_n))\n+\n+/* CONF */\n+#define REG_I2C_SDA_E2\t\t\t0x001c\n+#define AN7583_I2C1_SCL_E2_MASK\t\tBIT(16)\n+#define AN7583_I2C1_SDA_E2_MASK\t\tBIT(15)\n+#define SPI_MISO_E2_MASK\t\tBIT(14)\n+#define SPI_MOSI_E2_MASK\t\tBIT(13)\n+#define SPI_CLK_E2_MASK\t\t\tBIT(12)\n+#define SPI_CS0_E2_MASK\t\t\tBIT(11)\n+#define EN7523_SPI_MISO_E2_MASK\t\tBIT(13)\n+#define EN7523_SPI_MOSI_E2_MASK\t\tBIT(12)\n+#define EN7523_SPI_CLK_E2_MASK\t\tBIT(11)\n+#define EN7523_SPI_CS0_E2_MASK\t\tBIT(10)\n+#define PCIE2_RESET_E2_MASK\t\tBIT(10)\n+#define PCIE1_RESET_E2_MASK\t\tBIT(9)\n+#define PCIE0_RESET_E2_MASK\t\tBIT(8)\n+#define AN7583_MDIO_0_E2_MASK\t\tBIT(5)\n+#define AN7583_MDC_0_E2_MASK\t\tBIT(4)\n+#define UART1_RXD_E2_MASK\t\tBIT(3)\n+#define UART1_TXD_E2_MASK\t\tBIT(2)\n+#define I2C_SCL_E2_MASK\t\t\tBIT(1)\n+#define I2C_SDA_E2_MASK\t\t\tBIT(0)\n+\n+#define REG_I2C_SDA_E4\t\t\t0x0020\n+#define AN7583_I2C1_SCL_E4_MASK\t\tBIT(16)\n+#define AN7583_I2C1_SDA_E4_MASK\t\tBIT(15)\n+#define SPI_MISO_E4_MASK\t\tBIT(14)\n+#define SPI_MOSI_E4_MASK\t\tBIT(13)\n+#define SPI_CLK_E4_MASK\t\t\tBIT(12)\n+#define SPI_CS0_E4_MASK\t\t\tBIT(11)\n+#define EN7523_SPI_MISO_E4_MASK\t\tBIT(13)\n+#define EN7523_SPI_MOSI_E4_MASK\t\tBIT(12)\n+#define EN7523_SPI_CLK_E4_MASK\t\tBIT(11)\n+#define EN7523_SPI_CS0_E4_MASK\t\tBIT(10)\n+#define PCIE2_RESET_E4_MASK\t\tBIT(10)\n+#define PCIE1_RESET_E4_MASK\t\tBIT(9)\n+#define PCIE0_RESET_E4_MASK\t\tBIT(8)\n+#define AN7583_MDIO_0_E4_MASK\t\tBIT(5)\n+#define AN7583_MDC_0_E4_MASK\t\tBIT(4)\n+#define UART1_RXD_E4_MASK\t\tBIT(3)\n+#define UART1_TXD_E4_MASK\t\tBIT(2)\n+#define I2C_SCL_E4_MASK\t\t\tBIT(1)\n+#define I2C_SDA_E4_MASK\t\t\tBIT(0)\n+\n+#define REG_GPIO_L_E2\t\t\t0x0024\n+#define REG_GPIO_L_E4\t\t\t0x0028\n+#define REG_GPIO_H_E2\t\t\t0x002c\n+#define REG_GPIO_H_E4\t\t\t0x0030\n+\n+#define REG_I2C_SDA_PU\t\t\t0x0044\n+#define AN7583_I2C1_SCL_PU_MASK\t\tBIT(16)\n+#define AN7583_I2C1_SDA_PU_MASK\t\tBIT(15)\n+#define SPI_MISO_PU_MASK\t\tBIT(14)\n+#define SPI_MOSI_PU_MASK\t\tBIT(13)\n+#define SPI_CLK_PU_MASK\t\t\tBIT(12)\n+#define SPI_CS0_PU_MASK\t\t\tBIT(11)\n+#define EN7523_SPI_MISO_PU_MASK\t\tBIT(13)\n+#define EN7523_SPI_MOSI_PU_MASK\t\tBIT(12)\n+#define EN7523_SPI_CLK_PU_MASK\t\tBIT(11)\n+#define EN7523_SPI_CS0_PU_MASK\t\tBIT(10)\n+#define PCIE2_RESET_PU_MASK\t\tBIT(10)\n+#define PCIE1_RESET_PU_MASK\t\tBIT(9)\n+#define PCIE0_RESET_PU_MASK\t\tBIT(8)\n+#define AN7583_MDIO_0_PU_MASK\t\tBIT(5)\n+#define AN7583_MDC_0_PU_MASK\t\tBIT(4)\n+#define UART1_RXD_PU_MASK\t\tBIT(3)\n+#define UART1_TXD_PU_MASK\t\tBIT(2)\n+#define I2C_SCL_PU_MASK\t\t\tBIT(1)\n+#define I2C_SDA_PU_MASK\t\t\tBIT(0)\n+\n+#define REG_I2C_SDA_PD\t\t\t0x0048\n+#define AN7583_I2C1_SDA_PD_MASK\t\tBIT(16)\n+#define AN7583_I2C1_SCL_PD_MASK\t\tBIT(15)\n+#define SPI_MISO_PD_MASK\t\tBIT(14)\n+#define SPI_MOSI_PD_MASK\t\tBIT(13)\n+#define SPI_CLK_PD_MASK\t\t\tBIT(12)\n+#define SPI_CS0_PD_MASK\t\t\tBIT(11)\n+#define EN7523_SPI_MISO_PD_MASK\t\tBIT(13)\n+#define EN7523_SPI_MOSI_PD_MASK\t\tBIT(12)\n+#define EN7523_SPI_CLK_PD_MASK\t\tBIT(11)\n+#define EN7523_SPI_CS0_PD_MASK\t\tBIT(10)\n+#define PCIE2_RESET_PD_MASK\t\tBIT(10)\n+#define PCIE1_RESET_PD_MASK\t\tBIT(9)\n+#define PCIE0_RESET_PD_MASK\t\tBIT(8)\n+#define AN7583_MDIO_0_PD_MASK\t\tBIT(5)\n+#define AN7583_MDC_0_PD_MASK\t\tBIT(4)\n+#define UART1_RXD_PD_MASK\t\tBIT(3)\n+#define UART1_TXD_PD_MASK\t\tBIT(2)\n+#define I2C_SCL_PD_MASK\t\t\tBIT(1)\n+#define I2C_SDA_PD_MASK\t\t\tBIT(0)\n+\n+#define REG_GPIO_L_PU\t\t\t0x004c\n+#define REG_GPIO_L_PD\t\t\t0x0050\n+#define REG_GPIO_H_PU\t\t\t0x0054\n+#define REG_GPIO_H_PD\t\t\t0x0058\n+\n+#define REG_PCIE_RESET_OD\t\t0x018c\n+#define PCIE2_RESET_OD_MASK\t\tBIT(2)\n+#define PCIE1_RESET_OD_MASK\t\tBIT(1)\n+#define PCIE0_RESET_OD_MASK\t\tBIT(0)\n+\n+/* GPIOs */\n+#define REG_GPIO_CTRL\t\t0x0000\n+#define REG_GPIO_DATA\t\t0x0004\n+#define REG_GPIO_INT\t\t0x0008\n+#define REG_GPIO_INT_EDGE\t0x000c\n+#define REG_GPIO_INT_LEVEL\t0x0010\n+#define REG_GPIO_OE\t\t0x0014\n+#define REG_GPIO_CTRL1\t\t0x0020\n+\n+/* PWM MODE CONF */\n+#define REG_GPIO_FLASH_MODE_CFG\t\t0x0034\n+#define GPIO15_FLASH_MODE_CFG\t\tBIT(15)\n+#define GPIO14_FLASH_MODE_CFG\t\tBIT(14)\n+#define GPIO13_FLASH_MODE_CFG\t\tBIT(13)\n+#define GPIO12_FLASH_MODE_CFG\t\tBIT(12)\n+#define GPIO11_FLASH_MODE_CFG\t\tBIT(11)\n+#define GPIO10_FLASH_MODE_CFG\t\tBIT(10)\n+#define GPIO9_FLASH_MODE_CFG\t\tBIT(9)\n+#define GPIO8_FLASH_MODE_CFG\t\tBIT(8)\n+#define GPIO7_FLASH_MODE_CFG\t\tBIT(7)\n+#define GPIO6_FLASH_MODE_CFG\t\tBIT(6)\n+#define GPIO5_FLASH_MODE_CFG\t\tBIT(5)\n+#define GPIO4_FLASH_MODE_CFG\t\tBIT(4)\n+#define GPIO3_FLASH_MODE_CFG\t\tBIT(3)\n+#define GPIO2_FLASH_MODE_CFG\t\tBIT(2)\n+#define GPIO1_FLASH_MODE_CFG\t\tBIT(1)\n+#define GPIO0_FLASH_MODE_CFG\t\tBIT(0)\n+\n+#define REG_GPIO_CTRL2\t0x0060\n+#define REG_GPIO_CTRL3\t0x0064\n+\n+/* PWM MODE CONF EXT */\n+#define REG_GPIO_FLASH_MODE_CFG_EXT\t0x0068\n+#define GPIO51_FLASH_MODE_CFG\t\tBIT(31)\n+#define GPIO50_FLASH_MODE_CFG\t\tBIT(30)\n+#define GPIO49_FLASH_MODE_CFG\t\tBIT(29)\n+#define GPIO48_FLASH_MODE_CFG\t\tBIT(28)\n+#define GPIO47_FLASH_MODE_CFG\t\tBIT(27)\n+#define GPIO46_FLASH_MODE_CFG\t\tBIT(26)\n+#define GPIO45_FLASH_MODE_CFG\t\tBIT(25)\n+#define GPIO44_FLASH_MODE_CFG\t\tBIT(24)\n+#define GPIO43_FLASH_MODE_CFG\t\tBIT(23)\n+#define GPIO42_FLASH_MODE_CFG\t\tBIT(22)\n+#define GPIO41_FLASH_MODE_CFG\t\tBIT(21)\n+#define GPIO40_FLASH_MODE_CFG\t\tBIT(20)\n+#define GPIO39_FLASH_MODE_CFG\t\tBIT(19)\n+#define GPIO38_FLASH_MODE_CFG\t\tBIT(18)\n+#define GPIO37_FLASH_MODE_CFG\t\tBIT(17)\n+#define GPIO36_FLASH_MODE_CFG\t\tBIT(16)\n+#define GPIO31_FLASH_MODE_CFG\t\tBIT(15)\n+#define GPIO30_FLASH_MODE_CFG\t\tBIT(14)\n+#define GPIO29_FLASH_MODE_CFG\t\tBIT(13)\n+#define GPIO28_FLASH_MODE_CFG\t\tBIT(12)\n+#define GPIO27_FLASH_MODE_CFG\t\tBIT(11)\n+#define GPIO26_FLASH_MODE_CFG\t\tBIT(10)\n+#define GPIO25_FLASH_MODE_CFG\t\tBIT(9)\n+#define GPIO24_FLASH_MODE_CFG\t\tBIT(8)\n+#define GPIO23_FLASH_MODE_CFG\t\tBIT(7)\n+#define GPIO22_FLASH_MODE_CFG\t\tBIT(6)\n+#define GPIO21_FLASH_MODE_CFG\t\tBIT(5)\n+#define GPIO20_FLASH_MODE_CFG\t\tBIT(4)\n+#define GPIO19_FLASH_MODE_CFG\t\tBIT(3)\n+#define GPIO18_FLASH_MODE_CFG\t\tBIT(2)\n+#define GPIO17_FLASH_MODE_CFG\t\tBIT(1)\n+#define GPIO16_FLASH_MODE_CFG\t\tBIT(0)\n+\n+#define REG_GPIO_DATA1\t\t\t0x0070\n+#define REG_GPIO_OE1\t\t\t0x0078\n+#define REG_GPIO_INT1\t\t\t0x007c\n+#define REG_GPIO_INT_EDGE1\t\t0x0080\n+#define REG_GPIO_INT_EDGE2\t\t0x0084\n+#define REG_GPIO_INT_EDGE3\t\t0x0088\n+#define REG_GPIO_INT_LEVEL1\t\t0x008c\n+#define REG_GPIO_INT_LEVEL2\t\t0x0090\n+#define REG_GPIO_INT_LEVEL3\t\t0x0094\n+\n+#define AIROHA_NUM_PINS\t\t\t64\n+#define AIROHA_PIN_BANK_SIZE\t\t(AIROHA_NUM_PINS / 2)\n+#define AIROHA_REG_GPIOCTRL_NUM_PIN\t(AIROHA_NUM_PINS / 4)\n+\n+/* PWM */\n+#define AIROHA_PINCTRL_PWM(gpio, mux_val)\t\t\\\n+\t{\t\t\t\t\t\t\\\n+\t\t.name = (gpio),\t\t\t\t\\\n+\t\t.regmap[0] = {\t\t\t\t\\\n+\t\t\tAIROHA_FUNC_PWM_MUX,\t\t\\\n+\t\t\tREG_GPIO_FLASH_MODE_CFG,\t\\\n+\t\t\t(mux_val),\t\t\t\\\n+\t\t\t(mux_val)\t\t\t\\\n+\t\t},\t\t\t\t\t\\\n+\t\t.regmap_size = 1,\t\t\t\\\n+\t}\t\t\t\t\t\t\\\n+\n+#define AIROHA_PINCTRL_PWM_EXT(gpio, mux_val)\t\t\\\n+\t{\t\t\t\t\t\t\\\n+\t\t.name = (gpio),\t\t\t\t\\\n+\t\t.regmap[0] = {\t\t\t\t\\\n+\t\t\tAIROHA_FUNC_PWM_EXT_MUX,\t\\\n+\t\t\tREG_GPIO_FLASH_MODE_CFG_EXT,\t\\\n+\t\t\t(mux_val),\t\t\t\\\n+\t\t\t(mux_val)\t\t\t\\\n+\t\t},\t\t\t\t\t\\\n+\t\t.regmap_size = 1,\t\t\t\\\n+\t}\t\t\t\t\t\t\\\n+\n+#define AIROHA_PINCTRL_PHY_LED0(variant, gpio, mux_val, map_mask, map_val)\t\\\n+\t{\t\t\t\t\t\t\t\t\t\\\n+\t\t.name = (gpio),\t\t\t\t\t\t\t\\\n+\t\t.regmap[0] = {\t\t\t\t\t\t\t\\\n+\t\t\tAIROHA_FUNC_MUX,\t\t\t\t\t\\\n+\t\t\tvariant##_REG_GPIO_2ND_I2C_MODE,\t\t\t\\\n+\t\t\t(mux_val),\t\t\t\t\t\t\\\n+\t\t\t(mux_val),\t\t\t\t\t\t\\\n+\t\t},\t\t\t\t\t\t\t\t\\\n+\t\t.regmap[1] = {\t\t\t\t\t\t\t\\\n+\t\t\tAIROHA_FUNC_MUX,\t\t\t\t\t\\\n+\t\t\tREG_LAN_LED0_MAPPING,\t\t\t\t\t\\\n+\t\t\t(map_mask),\t\t\t\t\t\t\\\n+\t\t\t(map_val),\t\t\t\t\t\t\\\n+\t\t},\t\t\t\t\t\t\t\t\\\n+\t\t.regmap_size = 2,\t\t\t\t\t\t\\\n+\t}\n+\n+#define AIROHA_PINCTRL_PHY_LED1(variant, gpio, mux_val, map_mask, map_val)\t\\\n+\t{\t\t\t\t\t\t\t\t\t\\\n+\t\t.name = (gpio),\t\t\t\t\t\t\t\\\n+\t\t.regmap[0] = {\t\t\t\t\t\t\t\\\n+\t\t\tAIROHA_FUNC_MUX,\t\t\t\t\t\\\n+\t\t\tvariant##_REG_GPIO_2ND_I2C_MODE,\t\t\t\\\n+\t\t\t(mux_val),\t\t\t\t\t\t\\\n+\t\t\t(mux_val),\t\t\t\t\t\t\\\n+\t\t},\t\t\t\t\t\t\t\t\\\n+\t\t.regmap[1] = {\t\t\t\t\t\t\t\\\n+\t\t\tAIROHA_FUNC_MUX,\t\t\t\t\t\\\n+\t\t\tREG_LAN_LED1_MAPPING,\t\t\t\t\t\\\n+\t\t\t(map_mask),\t\t\t\t\t\t\\\n+\t\t\t(map_val),\t\t\t\t\t\t\\\n+\t\t},\t\t\t\t\t\t\t\t\\\n+\t\t.regmap_size = 2,\t\t\t\t\t\t\\\n+\t}\n+\n+#define airoha_pinctrl_get_pullup_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP,\t\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_get_pulldown_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN,\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2,\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4,\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_get_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD,\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_set_pullup_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLUP,\t\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_set_pulldown_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PULLDOWN,\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_set_drive_e2_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E2,\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_set_drive_e4_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_DRIVE_E4,\t\\\n+\t\t\t\t(pin), (val))\n+#define airoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, val)\t\t\t\\\n+\tairoha_pinctrl_set_conf((pinctrl), AIROHA_PINCTRL_CONFS_PCIE_RST_OD,\t\\\n+\t\t\t\t(pin), (val))\n+\n+static const u32 gpio_data_regs[] = {\n+\tREG_GPIO_DATA,\n+\tREG_GPIO_DATA1\n+};\n+\n+static const u32 gpio_out_regs[] = {\n+\tREG_GPIO_OE,\n+\tREG_GPIO_OE1\n+};\n+\n+static const u32 gpio_dir_regs[] = {\n+\tREG_GPIO_CTRL,\n+\tREG_GPIO_CTRL1,\n+\tREG_GPIO_CTRL2,\n+\tREG_GPIO_CTRL3\n+};\n+\n+static const u32 irq_status_regs[] = {\n+\tREG_GPIO_INT,\n+\tREG_GPIO_INT1\n+};\n+\n+static const u32 irq_level_regs[] = {\n+\tREG_GPIO_INT_LEVEL,\n+\tREG_GPIO_INT_LEVEL1,\n+\tREG_GPIO_INT_LEVEL2,\n+\tREG_GPIO_INT_LEVEL3\n+};\n+\n+static const u32 irq_edge_regs[] = {\n+\tREG_GPIO_INT_EDGE,\n+\tREG_GPIO_INT_EDGE1,\n+\tREG_GPIO_INT_EDGE2,\n+\tREG_GPIO_INT_EDGE3\n+};\n+\n+struct airoha_pinctrl_reg {\n+\tu32 offset;\n+\tu32 mask;\n+};\n+\n+enum airoha_pinctrl_mux_func {\n+\tAIROHA_FUNC_MUX,\n+\tAIROHA_FUNC_PWM_MUX,\n+\tAIROHA_FUNC_PWM_EXT_MUX,\n+};\n+\n+struct airoha_pinctrl_func_group {\n+\tconst char *name;\n+\tstruct {\n+\t\tenum airoha_pinctrl_mux_func mux;\n+\t\tu32 offset;\n+\t\tu32 mask;\n+\t\tu32 val;\n+\t} regmap[2];\n+\tint regmap_size;\n+};\n+\n+struct airoha_pinctrl_func {\n+\tconst struct pinfunction desc;\n+\tconst struct airoha_pinctrl_func_group *groups;\n+\tu8 group_size;\n+};\n+\n+struct airoha_pinctrl_conf {\n+\tu32 pin;\n+\tstruct airoha_pinctrl_reg reg;\n+};\n+\n+struct airoha_pinctrl_gpiochip {\n+\tstruct udevice *dev;\n+\n+\t/* gpio */\n+\tconst u32 *data;\n+\tconst u32 *dir;\n+\tconst u32 *out;\n+\t/* irq */\n+\tconst u32 *status;\n+\tconst u32 *level;\n+\tconst u32 *edge;\n+\n+\tu32 irq_type[AIROHA_NUM_PINS];\n+};\n+\n+struct airoha_pinctrl_confs_info {\n+\tconst struct airoha_pinctrl_conf *confs;\n+\tunsigned int num_confs;\n+};\n+\n+enum airoha_pinctrl_confs_type {\n+\tAIROHA_PINCTRL_CONFS_PULLUP,\n+\tAIROHA_PINCTRL_CONFS_PULLDOWN,\n+\tAIROHA_PINCTRL_CONFS_DRIVE_E2,\n+\tAIROHA_PINCTRL_CONFS_DRIVE_E4,\n+\tAIROHA_PINCTRL_CONFS_PCIE_RST_OD,\n+\n+\tAIROHA_PINCTRL_CONFS_MAX\n+};\n+\n+struct airoha_pinctrl {\n+\tstruct udevice *dev;\n+\tstruct airoha_pinctrl_match_data *data;\n+\n+\tstruct regmap *chip_scu;\n+\tstruct regmap *regmap;\n+\n+\tstruct airoha_pinctrl_gpiochip gpiochip;\n+};\n+\n+struct airoha_pinctrl_match_data {\n+\tconst int gpio_offs;\n+\tconst int gpio_pin_cnt;\n+\tconst struct pinctrl_pin_desc *pins;\n+\tconst unsigned int num_pins;\n+\tconst struct pingroup *grps;\n+\tconst unsigned int num_grps;\n+\tconst struct airoha_pinctrl_func *funcs;\n+\tconst unsigned int num_funcs;\n+\tconst struct airoha_pinctrl_confs_info confs_info[AIROHA_PINCTRL_CONFS_MAX];\n+};\n+\n+extern const struct pinctrl_ops airoha_pinctrl_ops;\n+\n+int airoha_pinctrl_probe(struct udevice *dev);\n+int airoha_pinctrl_bind(struct udevice *dev);\n+\n+#endif\ndiff --git a/drivers/pinctrl/airoha/pinctrl-airoha.c b/drivers/pinctrl/airoha/pinctrl-airoha.c\nnew file mode 100644\nindex 00000000000..67f3a0fb312\n--- /dev/null\n+++ b/drivers/pinctrl/airoha/pinctrl-airoha.c\n@@ -0,0 +1,827 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Author: Lorenzo Bianconi <lorenzo@kernel.org>\n+ * Author: Benjamin Larsson <benjamin.larsson@genexis.eu>\n+ * Author: Markus Gothe <markus.gothe@genexis.eu>\n+ * Author: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>\n+ */\n+#include <dm.h>\n+#include <dm/device_compat.h>\n+#include <dm/device-internal.h>\n+#include <dm/lists.h>\n+#include <dm/ofnode.h>\n+#include <asm-generic/gpio.h>\n+#include <dt-bindings/pinctrl/mt65xx.h>\n+#include <regmap.h>\n+\n+#include <syscon.h>\n+#include <asm/arch/scu-regmap.h>\n+\n+#include \"airoha-common.h\"\n+\n+static int pin_to_gpio(struct airoha_pinctrl *pinctrl, unsigned int pin)\n+{\n+\tstruct airoha_pinctrl_match_data *data = pinctrl->data;\n+\n+\tif ((pin < data->gpio_offs) ||\n+\t    (pin > data->gpio_offs + data->gpio_pin_cnt))\n+\t\treturn -EINVAL;\n+\n+\treturn pin - data->gpio_offs;\n+}\n+\n+/* gpio callbacks */\n+static int airoha_gpio_set(struct udevice *dev, unsigned int gpio,\n+\t\t\t   int value)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);\n+\tu32 offset = gpio % AIROHA_PIN_BANK_SIZE;\n+\tu8 index = gpio / AIROHA_PIN_BANK_SIZE;\n+\n+\treturn regmap_update_bits(pinctrl->regmap,\n+\t\t\t\t  pinctrl->gpiochip.data[index],\n+\t\t\t\t  BIT(offset), value ? BIT(offset) : 0);\n+}\n+\n+static int airoha_gpio_get(struct udevice *dev, unsigned int gpio)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);\n+\tu32 val, pin = gpio % AIROHA_PIN_BANK_SIZE;\n+\tu8 index = gpio / AIROHA_PIN_BANK_SIZE;\n+\tint err;\n+\n+\terr = regmap_read(pinctrl->regmap,\n+\t\t\t  pinctrl->gpiochip.data[index], &val);\n+\n+\treturn err ? err : !!(val & BIT(pin));\n+}\n+\n+static int airoha_gpio_get_direction(struct udevice *dev, unsigned int gpio)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);\n+\tu32 mask, index, val;\n+\tint err, field_shift;\n+\n+\tfield_shift = 2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN);\n+\tmask = GENMASK(field_shift + 1, field_shift);\n+\tindex = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;\n+\n+\terr = regmap_read(pinctrl->regmap,\n+\t\t\t  pinctrl->gpiochip.dir[index], &val);\n+\tif (err)\n+\t\treturn err;\n+\n+\tif ((val & mask) > BIT(field_shift))\n+\t\treturn -EINVAL;\n+\n+\treturn (val & mask) ? GPIOF_OUTPUT : GPIOF_INPUT;\n+}\n+\n+static int airoha_gpio_set_direction(struct udevice *dev,\n+\t\t\t\t     unsigned int gpio, bool input)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);\n+\tu32 mask, index;\n+\tint err, field_shift;\n+\n+\t/* set output enable */\n+\tmask = BIT(gpio % AIROHA_PIN_BANK_SIZE);\n+\tindex = gpio / AIROHA_PIN_BANK_SIZE;\n+\terr = regmap_update_bits(pinctrl->regmap, pinctrl->gpiochip.out[index],\n+\t\t\t\t mask, !input ? mask : 0);\n+\tif (err)\n+\t\treturn err;\n+\n+\t/* set direction */\n+\tfield_shift = 2 * (gpio % AIROHA_REG_GPIOCTRL_NUM_PIN);\n+\tmask = GENMASK(field_shift + 1, field_shift);\n+\tindex = gpio / AIROHA_REG_GPIOCTRL_NUM_PIN;\n+\n+\treturn regmap_update_bits(pinctrl->regmap,\n+\t\t\t\t  pinctrl->gpiochip.dir[index],\n+\t\t\t\t  mask, !input ? BIT(field_shift) : 0);\n+}\n+\n+static int airoha_gpio_direction_input(struct udevice *dev, unsigned int gpio)\n+{\n+\treturn airoha_gpio_set_direction(dev, gpio, true);\n+}\n+\n+static int airoha_gpio_direction_output(struct udevice *dev, unsigned int gpio,\n+\t\t\t\t\tint val)\n+{\n+\tint err;\n+\n+\terr = airoha_gpio_set_direction(dev, gpio, false);\n+\tif (err)\n+\t\treturn err;\n+\n+\treturn airoha_gpio_set(dev, gpio, val);\n+}\n+\n+static int airoha_pinctrl_gpio_probe(struct udevice *dev)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev->parent);\n+\tstruct gpio_dev_priv *uc_priv;\n+\n+\tuc_priv = dev_get_uclass_priv(dev);\n+\tuc_priv->bank_name = \"airoha\";\n+\tuc_priv->gpio_count = pinctrl->data->gpio_pin_cnt;\n+\n+\treturn 0;\n+}\n+\n+static int airoha_pinctrl_gpio_bind(struct udevice *dev)\n+{\n+\tdev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);\n+\n+\treturn 0;\n+}\n+\n+static const struct dm_gpio_ops airoha_pinctrl_gpio_ops = {\n+\t.set_value = airoha_gpio_set,\n+\t.get_value = airoha_gpio_get,\n+\t.get_function = airoha_gpio_get_direction,\n+\t.direction_input = airoha_gpio_direction_input,\n+\t.direction_output = airoha_gpio_direction_output,\n+};\n+\n+static struct driver airoha_pinctrl_gpio_driver = {\n+\t.name = \"airoha_pinctrl_gpio\",\n+\t.id = UCLASS_GPIO,\n+\t.probe = airoha_pinctrl_gpio_probe,\n+\t.bind = airoha_pinctrl_gpio_bind,\n+\t.ops = &airoha_pinctrl_gpio_ops,\n+};\n+\n+static int airoha_gpiochip_register(struct udevice *parent)\n+{\n+\tstruct airoha_pinctrl *pinctrl;\n+\tstruct uclass_driver *drv;\n+\tstruct udevice *dev;\n+\tint ret;\n+\tofnode node;\n+\n+\tdrv = lists_uclass_lookup(UCLASS_GPIO);\n+\tif (!drv)\n+\t\treturn -ENOENT;\n+\n+\t/*\n+\t * Support upstream linux DTSI that define gpio-controller\n+\t * in the root node (instead of a dedicated subnode)\n+\t */\n+\tif (dev_read_bool(parent, \"gpio-controller\")) {\n+\t\t/* upstream DTSI, use current node */\n+\t\tnode = dev_ofnode(parent);\n+\t} else {\n+\t\t/* legacy DTSI, search for gpio-controller subnode */\n+\t\tret = -ENOENT;\n+\t\tdev_for_each_subnode(node, parent)\n+\t\t\tif (ofnode_read_bool(node, \"gpio-controller\")) {\n+\t\t\t\tret = 0;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\tret = device_bind_with_driver_data(parent, &airoha_pinctrl_gpio_driver,\n+\t\t\t\t\t   \"airoha_pinctrl_gpio\", 0, node,\n+\t\t\t\t\t   &dev);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tpinctrl = dev_get_priv(parent);\n+\tpinctrl->gpiochip.dev = dev;\n+\n+\treturn 0;\n+}\n+\n+/* pinmux callbacks */\n+static int airoha_pinmux_set_mux(struct airoha_pinctrl *pinctrl,\n+\t\t\t\t unsigned int selector,\n+\t\t\t\t unsigned int group)\n+{\n+\tconst struct airoha_pinctrl_func *func;\n+\tconst struct pingroup *grp;\n+\tint i;\n+\n+\tfunc = &pinctrl->data->funcs[selector];\n+\tgrp = &pinctrl->data->grps[group];\n+\n+\tdev_dbg(pinctrl->dev, \"enable function %s group %s\\n\",\n+\t\tfunc->desc.name, grp->name);\n+\n+\tfor (i = 0; i < func->group_size; i++) {\n+\t\tconst struct airoha_pinctrl_func_group *group;\n+\t\tint j;\n+\n+\t\tgroup = &func->groups[i];\n+\t\tif (strcmp(group->name, grp->name))\n+\t\t\tcontinue;\n+\n+\t\tfor (j = 0; j < group->regmap_size; j++) {\n+\t\t\tswitch (group->regmap[j].mux) {\n+\t\t\tcase AIROHA_FUNC_PWM_EXT_MUX:\n+\t\t\tcase AIROHA_FUNC_PWM_MUX:\n+\t\t\t\tregmap_update_bits(pinctrl->regmap,\n+\t\t\t\t\t\t   group->regmap[j].offset,\n+\t\t\t\t\t\t   group->regmap[j].mask,\n+\t\t\t\t\t\t   group->regmap[j].val);\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\tregmap_update_bits(pinctrl->chip_scu,\n+\t\t\t\t\t\t   group->regmap[j].offset,\n+\t\t\t\t\t\t   group->regmap[j].mask,\n+\t\t\t\t\t\t   group->regmap[j].val);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\n+\treturn -EINVAL;\n+}\n+\n+static int airoha_pinmux_set_direction(struct airoha_pinctrl *pinctrl,\n+\t\t\t\t       unsigned int p, bool input)\n+{\n+\tint gpio;\n+\n+\tgpio = pin_to_gpio(pinctrl, p);\n+\tif (gpio < 0)\n+\t\treturn gpio;\n+\n+\treturn airoha_gpio_set_direction(pinctrl->gpiochip.dev, gpio, input);\n+}\n+\n+/* pinconf callbacks */\n+static const struct airoha_pinctrl_reg *\n+airoha_pinctrl_get_conf_reg(const struct airoha_pinctrl_conf *conf,\n+\t\t\t    int conf_size, int pin)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < conf_size; i++) {\n+\t\tif (conf[i].pin == pin)\n+\t\t\treturn &conf[i].reg;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static int airoha_pinctrl_get_conf(struct airoha_pinctrl *pinctrl,\n+\t\t\t\t   enum airoha_pinctrl_confs_type conf_type,\n+\t\t\t\t   int pin, u32 *val)\n+{\n+\tconst struct airoha_pinctrl_confs_info *confs_info;\n+\tconst struct airoha_pinctrl_reg *reg;\n+\n+\tconfs_info = &pinctrl->data->confs_info[conf_type];\n+\n+\treg = airoha_pinctrl_get_conf_reg(confs_info->confs,\n+\t\t\t\t\t  confs_info->num_confs,\n+\t\t\t\t\t  pin);\n+\tif (!reg)\n+\t\treturn -EINVAL;\n+\n+\tif (regmap_read(pinctrl->chip_scu, reg->offset, val))\n+\t\treturn -EINVAL;\n+\n+\t*val = (*val & reg->mask) >> __ffs(reg->mask);\n+\n+\treturn 0;\n+}\n+\n+static int airoha_pinctrl_set_conf(struct airoha_pinctrl *pinctrl,\n+\t\t\t\t   enum airoha_pinctrl_confs_type conf_type,\n+\t\t\t\t   int pin, u32 val)\n+{\n+\tconst struct airoha_pinctrl_confs_info *confs_info;\n+\tconst struct airoha_pinctrl_reg *reg = NULL;\n+\n+\tconfs_info = &pinctrl->data->confs_info[conf_type];\n+\n+\treg = airoha_pinctrl_get_conf_reg(confs_info->confs,\n+\t\t\t\t\t  confs_info->num_confs,\n+\t\t\t\t\t  pin);\n+\tif (!reg)\n+\t\treturn -EINVAL;\n+\n+\tif (regmap_update_bits(pinctrl->chip_scu, reg->offset, reg->mask,\n+\t\t\t       val << __ffs(reg->mask)))\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n+static int airoha_pinconf_get_direction(struct airoha_pinctrl *pinctrl, u32 p)\n+{\n+\tint gpio;\n+\n+\tgpio = pin_to_gpio(pinctrl, p);\n+\tif (gpio < 0)\n+\t\treturn gpio;\n+\n+\treturn airoha_gpio_get_direction(pinctrl->gpiochip.dev, gpio);\n+}\n+\n+static int airoha_pinconf_get(struct airoha_pinctrl *pinctrl,\n+\t\t\t      unsigned int pin, unsigned long *config)\n+{\n+\tenum pin_config_param param = pinconf_to_config_param(*config);\n+\tu32 arg;\n+\n+\tswitch (param) {\n+\tcase PIN_CONFIG_BIAS_PULL_DOWN:\n+\tcase PIN_CONFIG_BIAS_DISABLE:\n+\tcase PIN_CONFIG_BIAS_PULL_UP: {\n+\t\tu32 pull_up, pull_down;\n+\n+\t\tif (airoha_pinctrl_get_pullup_conf(pinctrl, pin, &pull_up) ||\n+\t\t    airoha_pinctrl_get_pulldown_conf(pinctrl, pin, &pull_down))\n+\t\t\treturn -EINVAL;\n+\n+\t\tif (param == PIN_CONFIG_BIAS_PULL_UP &&\n+\t\t    !(pull_up && !pull_down))\n+\t\t\treturn -EINVAL;\n+\t\telse if (param == PIN_CONFIG_BIAS_PULL_DOWN &&\n+\t\t\t !(pull_down && !pull_up))\n+\t\t\treturn -EINVAL;\n+\t\telse if (pull_up || pull_down)\n+\t\t\treturn -EINVAL;\n+\n+\t\targ = 1;\n+\t\tbreak;\n+\t}\n+\tcase PIN_CONFIG_DRIVE_STRENGTH: {\n+\t\tu32 e2, e4;\n+\n+\t\tif (airoha_pinctrl_get_drive_e2_conf(pinctrl, pin, &e2) ||\n+\t\t    airoha_pinctrl_get_drive_e4_conf(pinctrl, pin, &e4))\n+\t\t\treturn -EINVAL;\n+\n+\t\targ = e4 << 1 | e2;\n+\t\tbreak;\n+\t}\n+\tcase PIN_CONFIG_DRIVE_OPEN_DRAIN:\n+\t\tif (airoha_pinctrl_get_pcie_rst_od_conf(pinctrl, pin, &arg))\n+\t\t\treturn -EINVAL;\n+\t\tbreak;\n+\tcase PIN_CONFIG_OUTPUT_ENABLE:\n+\tcase PIN_CONFIG_INPUT_ENABLE:\n+\t\targ = airoha_pinconf_get_direction(pinctrl, pin);\n+\t\tif (arg != param)\n+\t\t\treturn -EINVAL;\n+\n+\t\targ = 1;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\t*config = pinconf_to_config_packed(param, arg);\n+\n+\treturn 0;\n+}\n+\n+static int airoha_pinconf_set_pin_value(struct airoha_pinctrl *pinctrl,\n+\t\t\t\t\tunsigned int p, bool value)\n+{\n+\tint gpio;\n+\n+\tgpio = pin_to_gpio(pinctrl, p);\n+\tif (gpio < 0)\n+\t\treturn gpio;\n+\n+\treturn airoha_gpio_set(pinctrl->gpiochip.dev, gpio, value);\n+}\n+\n+static int airoha_pinconf_set(struct airoha_pinctrl *pinctrl,\n+\t\t\t      unsigned int pin, unsigned long *configs,\n+\t\t\t      unsigned int num_configs)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < num_configs; i++) {\n+\t\tu32 param = pinconf_to_config_param(configs[i]);\n+\t\tu32 arg = pinconf_to_config_argument(configs[i]);\n+\n+\t\tswitch (param) {\n+\t\tcase PIN_CONFIG_BIAS_DISABLE:\n+\t\t\tairoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);\n+\t\t\tairoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);\n+\t\t\tbreak;\n+\t\tcase PIN_CONFIG_BIAS_PULL_UP:\n+\t\t\tairoha_pinctrl_set_pulldown_conf(pinctrl, pin, 0);\n+\t\t\tairoha_pinctrl_set_pullup_conf(pinctrl, pin, 1);\n+\t\t\tbreak;\n+\t\tcase PIN_CONFIG_BIAS_PULL_DOWN:\n+\t\t\tairoha_pinctrl_set_pulldown_conf(pinctrl, pin, 1);\n+\t\t\tairoha_pinctrl_set_pullup_conf(pinctrl, pin, 0);\n+\t\t\tbreak;\n+\t\tcase PIN_CONFIG_DRIVE_STRENGTH: {\n+\t\t\tu32 e2 = 0, e4 = 0;\n+\n+\t\t\tswitch (arg) {\n+\t\t\tcase MTK_DRIVE_2mA:\n+\t\t\t\tbreak;\n+\t\t\tcase MTK_DRIVE_4mA:\n+\t\t\t\te2 = 1;\n+\t\t\t\tbreak;\n+\t\t\tcase MTK_DRIVE_6mA:\n+\t\t\t\te4 = 1;\n+\t\t\t\tbreak;\n+\t\t\tcase MTK_DRIVE_8mA:\n+\t\t\t\te2 = 1;\n+\t\t\t\te4 = 1;\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\n+\t\t\tairoha_pinctrl_set_drive_e2_conf(pinctrl, pin, e2);\n+\t\t\tairoha_pinctrl_set_drive_e4_conf(pinctrl, pin, e4);\n+\t\t\tbreak;\n+\t\t}\n+\t\tcase PIN_CONFIG_DRIVE_OPEN_DRAIN:\n+\t\t\tairoha_pinctrl_set_pcie_rst_od_conf(pinctrl, pin, !!arg);\n+\t\t\tbreak;\n+\t\tcase PIN_CONFIG_OUTPUT_ENABLE:\n+\t\tcase PIN_CONFIG_INPUT_ENABLE:\n+\t\tcase PIN_CONFIG_OUTPUT: {\n+\t\t\tbool input = param == PIN_CONFIG_INPUT_ENABLE;\n+\t\t\tint err;\n+\n+\t\t\terr = airoha_pinmux_set_direction(pinctrl, pin, input);\n+\t\t\tif (err)\n+\t\t\t\treturn err;\n+\n+\t\t\tif (param == PIN_CONFIG_OUTPUT) {\n+\t\t\t\terr = airoha_pinconf_set_pin_value(pinctrl,\n+\t\t\t\t\t\t\t\t   pin, !!arg);\n+\t\t\t\tif (err)\n+\t\t\t\t\treturn err;\n+\t\t\t}\n+\n+\t\t\tbreak;\n+\t\t}\n+\t\tdefault:\n+\t\t\treturn -EOPNOTSUPP;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int airoha_pinconf_group_set(struct airoha_pinctrl *pinctrl,\n+\t\t\t\t    unsigned int group, unsigned long *configs,\n+\t\t\t\t    unsigned int num_configs)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < pinctrl->data->grps[group].npins; i++) {\n+\t\tint err;\n+\n+\t\terr = airoha_pinconf_set(pinctrl,\n+\t\t\t\t\t pinctrl->data->grps[group].pins[i],\n+\t\t\t\t\t configs, num_configs);\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int airoha_get_pins_count(struct udevice *dev)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\treturn pinctrl->data->num_pins;\n+}\n+\n+static const char *airoha_get_pin_name(struct udevice *dev, unsigned selector)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\treturn pinctrl->data->pins[selector].name;\n+}\n+\n+static int airoha_get_groups_count(struct udevice *dev)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\treturn pinctrl->data->num_grps;\n+}\n+\n+static const char *airoha_get_group_name(struct udevice *dev, unsigned selector)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\treturn pinctrl->data->grps[selector].name;\n+}\n+\n+static int airoha_get_funcs_count(struct udevice *dev)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\treturn pinctrl->data->num_funcs;\n+}\n+\n+static const char *airoha_get_func_name(struct udevice *dev, unsigned selector)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\treturn pinctrl->data->funcs[selector].desc.name;\n+}\n+\n+static int airoha_pinmux_group_set(struct udevice *dev, unsigned group_selector,\n+\t\t\t\t   unsigned func_selector)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\tdev_dbg(dev, \"enabling %s function for pin group %s\\n\",\n+\t\tairoha_get_func_name(dev, func_selector),\n+\t\tairoha_get_group_name(dev, group_selector));\n+\n+\treturn airoha_pinmux_set_mux(pinctrl, func_selector, group_selector);\n+}\n+\n+static int airoha_pinmux_set(struct udevice *dev, unsigned pin_selector,\n+\t\t\t     unsigned func_selector)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\tconst struct airoha_pinctrl_match_data *data = pinctrl->data;\n+\tconst char *pin_name;\n+\tunsigned selector;\n+\n+\tpin_name = data->pins[pin_selector].name;\n+\n+\t/* find group matching the pin_name */\n+\tfor (selector = 0; selector < data->num_grps; selector++) {\n+\t\tif (!strcmp(pin_name, data->grps[selector].name))\n+\t\t\treturn airoha_pinmux_group_set(dev, selector,\n+\t\t\t\t\t\t       func_selector);\n+\t}\n+\n+\treturn -ENOENT;\n+}\n+\n+static const struct pinconf_param airoha_pinconf_params[] = {\n+\t{ \"bias-disable\",     PIN_CONFIG_BIAS_DISABLE,     0 },\n+\t{ \"bias-pull-up\",     PIN_CONFIG_BIAS_PULL_UP,     1 },\n+\t{ \"bias-pull-down\",   PIN_CONFIG_BIAS_PULL_DOWN,   1 },\n+\t{ \"drive-strength\",   PIN_CONFIG_DRIVE_STRENGTH,   0 },\n+\t{ \"drive-open-drain\", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },\n+\t{ \"output-enable\",    PIN_CONFIG_OUTPUT_ENABLE,    1 },\n+\t{ \"input-enable\",     PIN_CONFIG_INPUT_ENABLE,     1 },\n+};\n+\n+static int airoha_pinconf_set_handler(struct udevice *dev, unsigned pin_selector,\n+\t\t\t\t      unsigned param, unsigned argument)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\tunsigned long configs[1] = { pinconf_to_config_packed(param, argument) };\n+\tunsigned int pin = pinctrl->data->pins[pin_selector].number;\n+\n+\tdev_dbg(dev, \"enabling %s=%d property for pin %s\\n\",\n+\t\tairoha_pinconf_params[param].property, argument,\n+\t\tairoha_get_pin_name(dev, pin_selector));\n+\n+\treturn airoha_pinconf_set(pinctrl, pin, configs,\n+\t\t\t\t  ARRAY_SIZE(configs));\n+}\n+\n+static int airoha_pinconf_group_set_handler(struct udevice *dev, unsigned group_selector,\n+\t\t\t\t\t    unsigned param, unsigned argument)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\tunsigned long configs[1] = { pinconf_to_config_packed(param, argument) };\n+\n+\tdev_dbg(dev, \"enabling %s=%d property for pin group %s\\n\",\n+\t\tairoha_pinconf_params[param].property, argument,\n+\t\tairoha_get_group_name(dev, group_selector));\n+\n+\treturn airoha_pinconf_group_set(pinctrl, group_selector,\n+\t\t\t\t\tconfigs, ARRAY_SIZE(configs));\n+}\n+\n+static int pin_in_group(unsigned int pin, const struct pingroup *grp)\n+{\n+\tfor (int i = 0; i < grp->npins; i++) {\n+\t\tif (grp->pins[i] == pin)\n+\t\t\treturn 1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int func_grp_active(struct airoha_pinctrl *pinctrl,\n+\t\t\t   const struct airoha_pinctrl_func *func,\n+\t\t\t   const char *grp_name)\n+{\n+\tconst struct airoha_pinctrl_func_group *func_grp;\n+\tu32 val, match;\n+\tint ret;\n+\n+\tfor (int i = 0; i < func->group_size; i++) {\n+\t\tif (strcmp(func->groups[i].name, grp_name))\n+\t\t\tcontinue;\n+\n+\t\tmatch = 0;\n+\t\tfunc_grp = &func->groups[i];\n+\t\tfor (int j = 0; j < func_grp->regmap_size; j++) {\n+\t\t\tswitch (func_grp->regmap[j].mux) {\n+\t\t\tcase AIROHA_FUNC_PWM_EXT_MUX:\n+\t\t\tcase AIROHA_FUNC_PWM_MUX:\n+\t\t\t\tret = regmap_read(pinctrl->regmap,\n+\t\t\t\t\t\t  func_grp->regmap[j].offset,\n+\t\t\t\t\t\t  &val);\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\tret = regmap_read(pinctrl->chip_scu,\n+\t\t\t\t\t\t  func_grp->regmap[j].offset,\n+\t\t\t\t\t\t  &val);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (ret)\n+\t\t\t\tbreak;\n+\n+\t\t\tif ((val & func_grp->regmap[j].mask) !=\n+\t\t\t    func_grp->regmap[j].val)\n+\t\t\t\tbreak;\n+\n+\t\t\tmatch++;\n+\t\t}\n+\n+\t\treturn match == func->groups[i].regmap_size;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int airoha_get_pin_muxing(struct udevice *dev, unsigned int selector,\n+\t\t\t\t char *buf, int size)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\tstruct airoha_pinctrl_match_data *data = pinctrl->data;\n+\tstruct udevice *gpio_dev = pinctrl->gpiochip.dev;\n+\tconst char *name, *type;\n+\tint ret, gpio, found = 0;\n+\tunsigned long config;\n+\tunsigned int param, pin;\n+\tu32 val;\n+\n+\tpin = data->pins[selector].number;\n+\tfor (int i = 0; i < data->num_grps; i++) {\n+\t\tif (!pin_in_group(pin, &data->grps[i]))\n+\t\t\tcontinue;\n+\n+\t\tname = data->grps[i].name;\n+\t\tfor (int j = 0; j < data->num_funcs; j++) {\n+\t\t\tif (!func_grp_active(pinctrl, &data->funcs[j], name))\n+\t\t\t\tcontinue;\n+\n+\t\t\tret = snprintf(buf, size, \"%s(%s)\",\n+\t\t\t\t       data->funcs[j].desc.name, name);\n+\t\t\tif (ret < 0)\n+\t\t\t\treturn -ENOSPC;\n+\n+\t\t\tfound = 1;\n+\t\t\tbuf += ret;\n+\t\t\tsize -= ret;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (found)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (!found) {\n+\t\tgpio = pin_to_gpio(pinctrl, pin);\n+\t\tif (gpio < 0) {\n+\t\t\t/*\n+\t\t\t * WARNING: non-gpio pin with unknown function.\n+\t\t\t *\n+\t\t\t * This should not have happened, the function group\n+\t\t\t * tables are incomplete. Please fix ASAP.\n+\t\t\t */\n+\t\t\tret = snprintf(buf, size, \"default\");\n+\t\t} else {\n+\t\t\t/* assume gpio */\n+\t\t\tval = airoha_gpio_get(gpio_dev, gpio);\n+\t\t\tswitch (airoha_gpio_get_direction(gpio_dev, gpio)) {\n+\t\t\tcase GPIOF_INPUT:\n+\t\t\t\ttype = \"input\";\n+\t\t\t\tbreak;\n+\t\t\tcase GPIOF_OUTPUT:\n+\t\t\t\ttype = \"output\";\n+\t\t\t\tbreak;\n+\t\t\tdefault:\n+\t\t\t\ttype = \"unknown\";\n+\t\t\t\tbreak;\n+\t\t\t};\n+\t\t\tret = snprintf(buf, size, \"gpio%d, %s(%d)\",\n+\t\t\t\t       gpio, type, val);\n+\t\t}\n+\n+\t\tif (ret < 0)\n+\t\t\treturn -ENOSPC;\n+\n+\t\tbuf += ret;\n+\t\tsize -= ret;\n+\t}\n+\n+\tfor (int i = 0; i < ARRAY_SIZE(airoha_pinconf_params); i++) {\n+\t\tparam = airoha_pinconf_params[i].param;\n+\t\tconfig = pinconf_to_config_packed(param, 0);\n+\t\tret = airoha_pinconf_get(pinctrl, pin, &config);\n+\t\tif (ret < 0)\n+\t\t\tcontinue;\n+\n+\t\tname = airoha_pinconf_params[i].property;\n+\t\tswitch (param) {\n+\t\tcase PIN_CONFIG_BIAS_DISABLE:\n+\t\tcase PIN_CONFIG_BIAS_PULL_UP:\n+\t\tcase PIN_CONFIG_BIAS_PULL_DOWN:\n+\t\t\tret = snprintf(buf, size, \", %s\", name);\n+\t\t\tbreak;\n+\n+\t\tcase PIN_CONFIG_DRIVE_STRENGTH:\n+\t\tcase PIN_CONFIG_DRIVE_OPEN_DRAIN:\n+\t\t\tval = pinconf_to_config_argument(config);\n+\t\t\tret = snprintf(buf, size, \", %s(%d)\", name, val);\n+\t\t\tbreak;\n+\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (ret < 0)\n+\t\t\treturn -ENOSPC;\n+\n+\t\tbuf += ret;\n+\t\tsize -= ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+const struct pinctrl_ops airoha_pinctrl_ops = {\n+\t.get_pins_count\t\t= airoha_get_pins_count,\n+\t.get_pin_name\t\t= airoha_get_pin_name,\n+\t.get_groups_count\t= airoha_get_groups_count,\n+\t.get_group_name\t\t= airoha_get_group_name,\n+\t.get_functions_count\t= airoha_get_funcs_count,\n+\t.get_function_name\t= airoha_get_func_name,\n+\t.pinmux_set\t\t= airoha_pinmux_set,\n+\t.pinmux_group_set\t= airoha_pinmux_group_set,\n+\n+\t.pinconf_num_params\t= ARRAY_SIZE(airoha_pinconf_params),\n+\t.pinconf_params\t\t= airoha_pinconf_params,\n+\t.pinconf_set\t\t= airoha_pinconf_set_handler,\n+\t.pinconf_group_set\t= airoha_pinconf_group_set_handler,\n+\n+\t.set_state\t\t= pinctrl_generic_set_state,\n+\t.get_pin_muxing\t\t= airoha_get_pin_muxing,\n+};\n+\n+int airoha_pinctrl_probe(struct udevice *dev)\n+{\n+\tstruct airoha_pinctrl *pinctrl = dev_get_priv(dev);\n+\n+\tpinctrl->dev = dev;\n+\tpinctrl->data = (struct airoha_pinctrl_match_data *)dev_get_driver_data(dev);\n+\n+\tpinctrl->regmap = syscon_node_to_regmap(dev_ofnode(dev->parent));\n+\tif (IS_ERR(pinctrl->regmap))\n+\t\treturn PTR_ERR(pinctrl->regmap);\n+\n+\tpinctrl->chip_scu = airoha_get_chip_scu_regmap();\n+\tif (IS_ERR(pinctrl->chip_scu))\n+\t\treturn PTR_ERR(pinctrl->chip_scu);\n+\n+\tpinctrl->gpiochip.data   = gpio_data_regs;\n+\tpinctrl->gpiochip.dir    = gpio_dir_regs;\n+\tpinctrl->gpiochip.out    = gpio_out_regs;\n+\tpinctrl->gpiochip.status = irq_status_regs;\n+\tpinctrl->gpiochip.level  = irq_level_regs;\n+\tpinctrl->gpiochip.edge   = irq_edge_regs;\n+\n+\treturn airoha_gpiochip_register(dev);\n+}\n+\n+int airoha_pinctrl_bind(struct udevice *dev)\n+{\n+\t/*\n+\t * Make sure that the pinctrl driver gets probed after binding\n+\t * as on EN7523/AN7581/AN7583 the pinctrl driver is the one that\n+\t * is also registering the GPIO one during probe, so if its not\n+\t * probed GPIOs are not registered as well.\n+\t */\n+\tdev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);\n+\n+\treturn 0;\n+}\n","prefixes":["v3","3/9"]}