get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.1/patches/2226508/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2226508,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2226508/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260422143112.1329478-3-raymondmaoca@gmail.com/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/18/?format=api",
        "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
    },
    "msgid": "<20260422143112.1329478-3-raymondmaoca@gmail.com>",
    "date": "2026-04-22T14:30:58",
    "name": "[02/16] pinctrl: add pinctrl driver for Spacemit K1 SoC",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "718806d363bd2ca1c8c6ea545549057dbe107b09",
    "submitter": {
        "id": 91989,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/91989/?format=api",
        "name": "Raymond Mao",
        "email": "raymondmaoca@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260422143112.1329478-3-raymondmaoca@gmail.com/mbox/",
    "series": [
        {
            "id": 501020,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/501020/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=501020",
            "date": "2026-04-22T14:30:56",
            "name": "Add PIN and SPI support for Spacemit K1",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501020/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2226508/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2226508/checks/",
    "tags": {},
    "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=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=l9kFJGGA;\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=none dis=none) header.from=gmail.com",
            "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=gmail.com header.i=@gmail.com header.b=\"l9kFJGGA\";\n\tdkim-atps=neutral",
            "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=raymondmaoca@gmail.com"
        ],
        "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 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g11rX2ZCmz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 00:31:56 +1000 (AEST)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id F0021842C7;\n\tWed, 22 Apr 2026 16:31:49 +0200 (CEST)",
            "by phobos.denx.de (Postfix, from userid 109)\n id B710684312; Wed, 22 Apr 2026 16:31:38 +0200 (CEST)",
            "from mail-qt1-x835.google.com (mail-qt1-x835.google.com\n [IPv6:2607:f8b0:4864:20::835])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 8EF8F842CE\n for <u-boot@lists.denx.de>; Wed, 22 Apr 2026 16:31:33 +0200 (CEST)",
            "by mail-qt1-x835.google.com with SMTP id\n d75a77b69052e-50d6b9bca48so71254771cf.2\n for <u-boot@lists.denx.de>; Wed, 22 Apr 2026 07:31:33 -0700 (PDT)",
            "from ubuntu.localdomain (172-97-209-197.cpe.distributel.net.\n [172.97.209.197]) by smtp.gmail.com with ESMTPSA id\n d75a77b69052e-50e394903dfsm138772501cf.26.2026.04.22.07.31.30\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 22 Apr 2026 07:31:31 -0700 (PDT)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-1.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_GMAIL_RCVD,FREEMAIL_FROM,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=no\n autolearn_force=no version=3.4.2",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1776868292; x=1777473092; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=IRj5nJ7FHCTpew7h6huIRAeng6HEU8UKlf2+PFarWi8=;\n b=l9kFJGGASNiQkkVsNrXZGH6pCiEgTNs3hJKhwSl1dqyyyPuVRpIrfBbvTXypUpzsIQ\n mrLfjj5XKm/EKqT0ESWidlpAR4+8kFj+p0chSGseH1BQIFK0mfdcmRHNkQwo0BuX5oGk\n /TZ3MuvjPGoETRRll9zwCGWrJLQBZd7udcCk1451K8p7Tx4aUlEaqusvbNxkjcnY17Yg\n Bi6d/IvAO7CrFSke98k54QfhzPQohjIU726in697pSR5GngMvOiJ3X0KP0sArPXqsmmv\n b1dPRLuxplOPBSPSlf7fchWkXx9rf54ibOl8Ah2RuvKMT9We4IOzJkuOEjr7b0uDRt4Z\n hXcg==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776868292; x=1777473092;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=IRj5nJ7FHCTpew7h6huIRAeng6HEU8UKlf2+PFarWi8=;\n b=WgdGVnGSfqruDXl+VjfV9lixlYEdYwBeaHxy7vnsvOdjDQEtj36Ks5nch1fqMsd2+X\n 27qSMJGJrp6putjZF8dmI9E5cyxuKdW+4l2sCz1mBf4W42GflxveJQ56xvX7E+vnlOUK\n dTWLGjaiPeJpbp/xP0nPu/LH6jNDBoa+K0pl3U6gAAFVi8sQlB9hjeN8y6v+8VNboLi6\n H7zY+ofDnfVFDb04PnGz1wwp1lp8g54I9nyMO6m2p9gntTYLOu3k0cIxcShfmbj82EYP\n 5MHTLLGsR9uMBUJnf/MrA+rKhIp0GPTV0Tjx0kH5MnmlPP+Yuvj2cMF4sm8VU6iF/isD\n pdPQ==",
        "X-Gm-Message-State": "AOJu0YxoAq9Cw9ALgcKmX8ej5AS+jD2y1EvozXkrcq/rlhC6iaCqMpG+\n 7/Yt7eBvblbdhRmBhDrPnIEuZgPR+NyN8hD9X/98eRYgeCE4dcD8Hq9PFiNIs8sh",
        "X-Gm-Gg": "AeBDietYYEt7KvtacwN8UK8K1n7O2agIFuuuFrmg8MLJMaZkaS79kahThBcStdr+Xgz\n 0upUP8keD9kzk7mKjQqqRnmeO61+j+mL3+gRxKmFCl5L15acp8vPiyag3mqkFIM3ZG0nm35Mk6m\n +KdolqnhAnopc3R3COlAPMCLO/k0BvE7qiKKUlq1hQhYxmcn2K29qCCWZpmISK+tZZ4XdrQYZBf\n dCZvo4oJg2okoNfwerq/d2OjqspMIw6enZuvMayyTIbdj+5V/ypd40DmrXRCnMX9U6OCPidnN2Y\n CprBJdJ/oKM0Zcb5Kg6N+noD9SWQaTFLP6vnKOARtuq7Rze2I4BUwRez0slE6bAwD8nCMx11m9j\n aNEfNrO/qEMb382brfI8DssCbaykDeHUaG9EqLRiQ9Ci619MFc7HzZ0Z4Ow87cQW4vy2NlWluUz\n 0bJhYUNUhh812krbrfDSHWqE6Sl32KIEnewlHSzj35nl84OcDnhYmlVnQBAMr8E6J0zZmtEgLxA\n sXlfJdZ1BH9EeI9kcOlMQ==",
        "X-Received": "by 2002:a05:622a:5ce:b0:50d:8389:c3f3 with SMTP id\n d75a77b69052e-50e36d9c15fmr323811581cf.54.1776868291663;\n Wed, 22 Apr 2026 07:31:31 -0700 (PDT)",
        "From": "Raymond Mao <raymondmaoca@gmail.com>",
        "To": "u-boot@lists.denx.de",
        "Cc": "uboot@riscstar.com, u-boot-spacemit@groups.io, raymond.mao@riscstar.com,\n rick@andestech.com, ycliang@andestech.com, trini@konsulko.com,\n lukma@denx.de, hs@nabladev.com, jh80.chung@samsung.com, peng.fan@nxp.com,\n xypron.glpk@gmx.de, randolph@andestech.com, dlan@gentoo.org,\n junhui.liu@pigmoral.tech, neil.armstrong@linaro.org,\n quentin.schulz@cherry.de, samuel@sholland.org, raymondmaoca@gmail.com",
        "Subject": "[PATCH 02/16] pinctrl: add pinctrl driver for Spacemit K1 SoC",
        "Date": "Wed, 22 Apr 2026 10:30:58 -0400",
        "Message-Id": "<20260422143112.1329478-3-raymondmaoca@gmail.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20260422143112.1329478-1-raymondmaoca@gmail.com>",
        "References": "<20260422143112.1329478-1-raymondmaoca@gmail.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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": "From: Raymond Mao <raymond.mao@riscstar.com>\n\nAdd pinctrl driver for Spacemit K1 SoC.\n\nSigned-off-by: Raymond Mao <raymond.mao@riscstar.com>\n---\n drivers/pinctrl/Kconfig               |   1 +\n drivers/pinctrl/Makefile              |   1 +\n drivers/pinctrl/spacemit/Kconfig      |   9 +\n drivers/pinctrl/spacemit/Makefile     |   2 +\n drivers/pinctrl/spacemit/pinctrl-k1.c | 550 ++++++++++++++++++++++++++\n 5 files changed, 563 insertions(+)\n create mode 100644 drivers/pinctrl/spacemit/Kconfig\n create mode 100644 drivers/pinctrl/spacemit/Makefile\n create mode 100644 drivers/pinctrl/spacemit/pinctrl-k1.c",
    "diff": "diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig\nindex 578edbf8168..a3abe0ea04d 100644\n--- a/drivers/pinctrl/Kconfig\n+++ b/drivers/pinctrl/Kconfig\n@@ -419,6 +419,7 @@ source \"drivers/pinctrl/nxp/Kconfig\"\n source \"drivers/pinctrl/qcom/Kconfig\"\n source \"drivers/pinctrl/renesas/Kconfig\"\n source \"drivers/pinctrl/rockchip/Kconfig\"\n+source \"drivers/pinctrl/spacemit/Kconfig\"\n source \"drivers/pinctrl/sunxi/Kconfig\"\n source \"drivers/pinctrl/tegra/Kconfig\"\n source \"drivers/pinctrl/uniphier/Kconfig\"\ndiff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile\nindex 29fb9b484d0..ece7a57767c 100644\n--- a/drivers/pinctrl/Makefile\n+++ b/drivers/pinctrl/Makefile\n@@ -33,6 +33,7 @@ obj-$(CONFIG_PINCTRL_SCMI)\t+= pinctrl-scmi.o\n obj-$(CONFIG_PINCTRL_SINGLE)\t+= pinctrl-single.o\n obj-$(CONFIG_PINCTRL_STI)\t+= pinctrl-sti.o\n obj-$(CONFIG_PINCTRL_STM32)\t+= pinctrl_stm32.o\n+obj-$(CONFIG_$(PHASE_)PINCTRL_SPACEMIT_K1) += spacemit/\n obj-$(CONFIG_$(PHASE_)PINCTRL_SX150X) += pinctrl-sx150x.o\n obj-$(CONFIG_$(PHASE_)PINCTRL_STMFX)\t+= pinctrl-stmfx.o\n obj-$(CONFIG_PINCTRL_TH1520)\t+= pinctrl-th1520.o\ndiff --git a/drivers/pinctrl/spacemit/Kconfig b/drivers/pinctrl/spacemit/Kconfig\nnew file mode 100644\nindex 00000000000..6aab89e160c\n--- /dev/null\n+++ b/drivers/pinctrl/spacemit/Kconfig\n@@ -0,0 +1,9 @@\n+config PINCTRL_SPACEMIT_K1\n+\tbool \"Spacemit K1 SoC pinctrl driver\"\n+\tdepends on PINCTRL_GENERIC && DM\n+\thelp\n+\t  Supports pin multiplexing control on Spacemit K1 SoCs.\n+\n+\t  The driver is controlled by a device tree node which contains both\n+\t  the GPIO definitions and pin control functions for each available\n+\t  multiplex function.\ndiff --git a/drivers/pinctrl/spacemit/Makefile b/drivers/pinctrl/spacemit/Makefile\nnew file mode 100644\nindex 00000000000..0dc43c72cb1\n--- /dev/null\n+++ b/drivers/pinctrl/spacemit/Makefile\n@@ -0,0 +1,2 @@\n+# SPDX-License-Identifier: GPL-2.0\n+obj-y += pinctrl-k1.o\ndiff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c\nnew file mode 100644\nindex 00000000000..a6a22eacac7\n--- /dev/null\n+++ b/drivers/pinctrl/spacemit/pinctrl-k1.c\n@@ -0,0 +1,550 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Copyright (c) 2024 Yixun Lan <dlan@gentoo.org>\n+ * Copyright (c) 2025-2026 RISCstar Ltd.\n+ */\n+\n+#include <clk.h>\n+#include <dm/device.h>\n+#include <dm/device_compat.h>\n+#include <dm/pinctrl.h>\n+#include <dm/read.h>\n+#include <linux/bitops.h>\n+#include <linux/errno.h>\n+#include <linux/io.h>\n+\n+/*\n+ * +---------+----------+-----------+--------+--------+----------+--------+\n+ * |   pull  |   drive  | schmitter |  slew  |  edge  |  strong  |   mux  |\n+ * | up/down | strength |  trigger  |  rate  | detect |   pull   |  mode  |\n+ * +---------+----------+-----------+--------+--------+----------+--------+\n+ *   3 bits     3 bits     2 bits     1 bit    3 bits     1 bit    3 bits\n+ */\n+\n+#define PAD_MUX\t\t\tGENMASK(2, 0)\n+#define PAD_STRONG_PULL\t\tBIT(3)\n+#define PAD_EDGE_RISE\t\tBIT(4)\n+#define PAD_EDGE_FALL\t\tBIT(5)\n+#define PAD_EDGE_CLEAR\t\tBIT(6)\n+#define PAD_SLEW_RATE\t\tGENMASK(12, 11)\n+#define PAD_SLEW_RATE_EN\tBIT(7)\n+#define PAD_SCHMITT\t\tGENMASK(9, 8)\n+#define PAD_DRIVE\t\tGENMASK(12, 10)\n+#define PAD_PULLDOWN\t\tBIT(13)\n+#define PAD_PULLUP\t\tBIT(14)\n+#define PAD_PULL_EN\t\tBIT(15)\n+\n+#define PIN_POWER_STATE_1V8\t\t1800\n+#define PIN_POWER_STATE_3V3\t\t3300\n+\n+enum spacemit_pin_io_type {\n+\tIO_TYPE_NONE = 0,\n+\tIO_TYPE_1V8,\n+\tIO_TYPE_3V3,\n+\tIO_TYPE_EXTERNAL,\n+};\n+\n+struct spacemit_pin_io {\n+\tunsigned int\tpin : 12;\t// 0~4095\n+\tunsigned int\tio_type : 4;\t// 0~15\n+\tunsigned int\tds : 8;\t\t// 0~255\n+\tunsigned int\treserved : 8;\n+};\n+\n+struct spacemit_pinctrl_data {\n+\tstruct spacemit_pin_io *io_pins;\n+\tint nr_io_pins;\n+\n+\tvoid __iomem * (*pin_to_reg)(struct udevice *dev, unsigned int pin);\n+\tint (*get_gpio_mux)(struct udevice *dev, unsigned int pin);\n+\tint (*get_pins)(struct udevice *dev);\n+\tint (*get_functions)(struct udevice *dev);\n+\tint (*get_io_type)(struct udevice *dev, unsigned int pin);\n+};\n+\n+struct spacemit_pinctrl_priv {\n+\tvoid __iomem\t\t*regs;\n+\tstruct spacemit_pin_io\t*io_pins;\n+\tint\t\t\tnr_io_pins;\n+};\n+\n+struct spacemit_pin_mux_config {\n+\tconst struct spacemit_pin\t*pin;\n+\tu32\t\t\t\tconfig;\n+};\n+\n+struct spacemit_pin_drv_strength {\n+\tunsigned int\tval : 8;\n+\tunsigned int\tma : 16;\n+\tunsigned int\treserved : 8;\n+};\n+\n+static char pin_name[PINNAME_SIZE];\n+\n+/* External: IO voltage via external source, can be 1.8V or 3.3V */\n+static struct spacemit_pin_io k1_io_pins[] = {\n+\t{ 47, IO_TYPE_EXTERNAL, 0, },\n+\t{ 48, IO_TYPE_EXTERNAL, 0, },\n+\t{ 49, IO_TYPE_EXTERNAL, 0, },\n+\t{ 50, IO_TYPE_EXTERNAL, 0, },\n+\t{ 51, IO_TYPE_EXTERNAL, 0, },\n+\t{ 52, IO_TYPE_EXTERNAL, 0, },\n+\t{ 75, IO_TYPE_EXTERNAL, 0, },\n+\t{ 76, IO_TYPE_EXTERNAL, 0, },\n+\t{ 77, IO_TYPE_EXTERNAL, 0, },\n+\t{ 78, IO_TYPE_EXTERNAL, 0, },\n+\t{ 79, IO_TYPE_EXTERNAL, 0, },\n+\t{ 80, IO_TYPE_EXTERNAL, 0, },\n+\t{ 98, IO_TYPE_EXTERNAL, 0, },\n+\t{ 99, IO_TYPE_EXTERNAL, 0, },\n+\t{ 100, IO_TYPE_EXTERNAL, 0, },\n+\t{ 101, IO_TYPE_EXTERNAL, 0, },\n+\t{ 102, IO_TYPE_EXTERNAL, 0, },\n+\t{ 103, IO_TYPE_EXTERNAL, 0, },\n+\t{ 104, IO_TYPE_EXTERNAL, 0, },\n+\t{ 105, IO_TYPE_EXTERNAL, 0, },\n+\t{ 106, IO_TYPE_EXTERNAL, 0, },\n+\t{ 107, IO_TYPE_EXTERNAL, 0, },\n+\t{ 108, IO_TYPE_EXTERNAL, 0, },\n+\t{ 109, IO_TYPE_EXTERNAL, 0, },\n+};\n+\n+static inline int k1_get_pins(struct udevice *dev)\n+{\n+\treturn 128;\n+}\n+\n+static inline int k1_get_functions(struct udevice *dev)\n+{\n+\treturn 7;\n+}\n+\n+// The pin number equals to the gpio number.\n+static void __iomem *k1_pin_to_reg(struct udevice *dev, unsigned int pin)\n+{\n+\tstruct spacemit_pinctrl_priv *priv = dev_get_priv(dev);\n+\tunsigned int offset = 1;\n+\n+\tif (pin < 86) {\n+\t\toffset += pin;\n+\t} else if (pin < 93) {\n+\t\toffset += pin + 36;\n+\t} else if (pin < 98) {\n+\t\toffset += pin + 23;\n+\t} else if (pin == 98) {\t\t// QSPI_DAT3\n+\t\toffset += 92;\n+\t} else if (pin == 99) {\t\t// QSPI_DAT2\n+\t\toffset += 91;\n+\t} else if (pin == 100) {\t// QSPI_DAT1\n+\t\toffset += 90;\n+\t} else if (pin == 101) {\t// QSPI_DAT0\n+\t\toffset += 89;\n+\t} else if (pin == 102) {\t// QSPI_CLK\n+\t\toffset += 94;\n+\t} else if (pin == 103) {\t// QSPI_CS1\n+\t\toffset += 93;\n+\t} else if (pin < 111) {\n+\t\toffset += pin + 5;\n+\t} else if (pin < 128) {\n+\t\toffset += pin + 19;\n+\t} else {\n+\t\tdev_err(dev, \"Invalid pin (%u)\\n\", pin);\n+\t\treturn NULL;\n+\t}\n+\treturn priv->regs + (offset << 2);\n+}\n+\n+static int k1_get_gpio_mux(struct udevice *dev, unsigned int selector)\n+{\n+\tu32 mux = 0;\n+\n+\tif (selector < 70) {\n+\t\tmux = 0;\n+\t} else if (selector < 74) {\n+\t\tmux = 1;\n+\t} else if (selector < 93) {\n+\t\tmux = 0;\n+\t} else if (selector < 104) {\n+\t\tmux = 1;\n+\t} else if (selector < 110) {\n+\t\tmux = 4;\n+\t} else if (selector < 128) {\n+\t\tmux = 0;\n+\t} else {\n+\t\tdev_err(dev, \"Invalid pin (%u)\\n\", selector);\n+\t\treturn -EINVAL;\n+\t}\n+\treturn mux;\n+}\n+\n+static int k1_get_io_type(struct udevice *dev, unsigned int selector)\n+{\n+\tif (selector < 47)\n+\t\treturn IO_TYPE_1V8;\n+\telse if (selector < 53)\n+\t\treturn IO_TYPE_EXTERNAL;\n+\telse if (selector < 75)\n+\t\treturn IO_TYPE_1V8;\n+\telse if (selector < 81)\n+\t\treturn IO_TYPE_EXTERNAL;\n+\telse if (selector < 98)\n+\t\treturn IO_TYPE_1V8;\n+\telse if (selector < 110)\n+\t\treturn IO_TYPE_EXTERNAL;\n+\telse if (selector < 128)\n+\t\treturn IO_TYPE_1V8;\n+\treturn -EINVAL;\n+}\n+\n+/* use IO high level output current as the table */\n+static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = {\n+\t{ 0, 11 },\n+\t{ 2, 21 },\n+\t{ 4, 32 },\n+\t{ 6, 42 },\n+};\n+\n+static struct spacemit_pin_drv_strength spacemit_ds_3v3_tbl[8] = {\n+\t{ 0,  7 },\n+\t{ 2, 10 },\n+\t{ 4, 13 },\n+\t{ 6, 16 },\n+\t{ 1, 19 },\n+\t{ 3, 23 },\n+\t{ 5, 26 },\n+\t{ 7, 29 },\n+};\n+\n+static inline u8 spacemit_get_ds_value(struct spacemit_pin_drv_strength *tbl,\n+\t\t\t\t       u32 num, u32 ma)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < num; i++)\n+\t\tif (ma <= tbl[i].ma)\n+\t\t\treturn tbl[i].val;\n+\n+\treturn tbl[num - 1].val;\n+}\n+\n+static inline u32 spacemit_get_ds_ma(struct spacemit_pin_drv_strength *tbl,\n+\t\t\t\t     u32 num, u32 val)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < num; i++)\n+\t\tif (val == tbl[i].val)\n+\t\t\treturn tbl[i].ma;\n+\n+\treturn 0;\n+}\n+\n+static inline u8 spacemit_get_drive_strength(enum spacemit_pin_io_type type,\n+\t\t\t\t\t     u32 ma)\n+{\n+\tswitch (type) {\n+\tcase IO_TYPE_1V8:\n+\t\treturn spacemit_get_ds_value(spacemit_ds_1v8_tbl,\n+\t\t\t\t\t     ARRAY_SIZE(spacemit_ds_1v8_tbl),\n+\t\t\t\t\t     ma);\n+\tcase IO_TYPE_3V3:\n+\t\treturn spacemit_get_ds_value(spacemit_ds_3v3_tbl,\n+\t\t\t\t\t     ARRAY_SIZE(spacemit_ds_3v3_tbl),\n+\t\t\t\t\t     ma);\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+static inline u32 spacemit_get_drive_strength_ma(enum spacemit_pin_io_type type,\n+\t\t\t\t\t\t u32 value)\n+{\n+\tswitch (type) {\n+\tcase IO_TYPE_1V8:\n+\t\treturn spacemit_get_ds_ma(spacemit_ds_1v8_tbl,\n+\t\t\t\t\t  ARRAY_SIZE(spacemit_ds_1v8_tbl),\n+\t\t\t\t\t  value & 0x6);\n+\tcase IO_TYPE_3V3:\n+\t\treturn spacemit_get_ds_ma(spacemit_ds_3v3_tbl,\n+\t\t\t\t\t  ARRAY_SIZE(spacemit_ds_3v3_tbl),\n+\t\t\t\t\t  value);\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+static inline u16 spacemit_dt_get_pin(u32 value)\n+{\n+\treturn value >> 16;\n+}\n+\n+static inline u16 spacemit_dt_get_pin_mux(u32 value)\n+{\n+\treturn value & GENMASK(15, 0);\n+}\n+\n+static int spacemit_get_pins_count(struct udevice *dev)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tif (!data || !data->get_pins)\n+\t\treturn -EINVAL;\n+\treturn data->get_pins(dev);\n+}\n+\n+static const char *spacemit_get_pin_name(struct udevice *dev,\n+\t\t\t\t\t unsigned int selector)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\tunsigned int npins;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tif (!data || !data->get_pins)\n+\t\treturn NULL;\n+\tnpins = data->get_pins(dev);\n+\n+\tif (selector >= npins)\n+\t\tsnprintf(pin_name, PINNAME_SIZE, \"Error\");\n+\telse\n+\t\tsnprintf(pin_name, PINNAME_SIZE, \"PIN%u\", selector);\n+\n+\treturn pin_name;\n+}\n+\n+static int spacemit_get_functions_count(struct udevice *dev)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tif (!data || !data->get_functions)\n+\t\treturn -EINVAL;\n+\treturn data->get_functions(dev);\n+}\n+\n+static int spacemit_get_pin_muxing(struct udevice *dev, unsigned int pin,\n+\t\t\t\t   char *buf, int size)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\tvoid __iomem *addr;\n+\tu32 mux, val;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tif (!data || !data->pin_to_reg)\n+\t\treturn -EINVAL;\n+\n+\taddr = data->pin_to_reg(dev, pin);\n+\tif (!addr)\n+\t\treturn -EINVAL;\n+\n+\tval = readl(addr);\n+\tmux = val & PAD_MUX;\n+\tsnprintf(buf, size, \"[%p] 0x%08x MUX%d\", addr, val, mux);\n+\treturn 0;\n+}\n+\n+static int spacemit_pinctrl_request_gpio(struct udevice *dev,\n+\t\t\t\t\t unsigned int selector)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\tvoid __iomem *addr;\n+\tint mux;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tif (!data || !data->pin_to_reg || !data->get_gpio_mux)\n+\t\treturn -EINVAL;\n+\taddr = data->pin_to_reg(dev, selector);\n+\tmux = data->get_gpio_mux(dev, selector);\n+\tif (mux < 0) {\n+\t\tdev_err(dev, \"Invalid pin (%d)\\n\", selector);\n+\t\treturn -EINVAL;\n+\t}\n+\tclrsetbits_le32(addr, PAD_MUX, mux & PAD_MUX);\n+\treturn 0;\n+}\n+\n+static int spacemit_pinctrl_free_gpio(struct udevice *dev,\n+\t\t\t\t      unsigned int selector)\n+{\n+\treturn 0;\n+}\n+\n+static int spacemit_pinmux_set(struct udevice *dev, unsigned int pin,\n+\t\t\t       unsigned int mux)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\tvoid __iomem *addr;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tif (!data || !data->pin_to_reg)\n+\t\treturn -EINVAL;\n+\taddr = data->pin_to_reg(dev, pin);\n+\tclrsetbits_le32(addr, PAD_MUX, mux & PAD_MUX);\n+\treturn 0;\n+}\n+\n+static int spacemit_pinmux_property_set(struct udevice *dev, u32 pinmux_group)\n+{\n+\tu32 pin, mux;\n+\n+\tpin = spacemit_dt_get_pin(pinmux_group);\n+\tmux = spacemit_dt_get_pin_mux(pinmux_group);\n+\treturn spacemit_pinmux_set(dev, pin, mux);\n+}\n+\n+static const struct pinconf_param spacemit_pinconf_params[] = {\n+\t{ \"bias-disable\",\tPIN_CONFIG_BIAS_DISABLE,\t0 },\n+\t{ \"bias-pull-down\",\tPIN_CONFIG_BIAS_PULL_DOWN,\t1 },\n+\t{ \"bias-pull-up\",\tPIN_CONFIG_BIAS_PULL_UP,\t1 },\n+\t{ \"drive-strength\",\tPIN_CONFIG_DRIVE_STRENGTH,\tU32_MAX },\n+\t{ \"power-source\",\tPIN_CONFIG_POWER_SOURCE,\tU32_MAX },\n+};\n+\n+static int spacemit_pinconf_set(struct udevice *dev, unsigned int pin_selector,\n+\t\t\t\tunsigned int param, unsigned int argument)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\tstruct spacemit_pinctrl_priv *priv = dev_get_priv(dev);\n+\tvoid __iomem *addr;\n+\tu32 mask = 0;\n+\tunsigned int io_type;\n+\tu8 ds;\n+\tbool found;\n+\tint i;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tif (!data || !data->pin_to_reg)\n+\t\treturn -EINVAL;\n+\taddr = data->pin_to_reg(dev, pin_selector);\n+\tswitch (param) {\n+\tcase PIN_CONFIG_BIAS_DISABLE:\n+\t\tclrbits_le32(addr, PAD_PULLUP | PAD_PULLDOWN | PAD_PULL_EN);\n+\t\tbreak;\n+\tcase PIN_CONFIG_BIAS_PULL_DOWN:\n+\t\tmask = PAD_PULLDOWN | PAD_PULLUP | PAD_PULL_EN;\n+\t\tclrsetbits_le32(addr, mask, PAD_PULLDOWN | PAD_PULL_EN);\n+\t\tbreak;\n+\tcase PIN_CONFIG_BIAS_PULL_UP:\n+\t\tmask = PAD_PULLDOWN | PAD_PULLUP | PAD_PULL_EN;\n+\t\tclrsetbits_le32(addr, mask, PAD_PULLUP | PAD_PULL_EN);\n+\t\tbreak;\n+\tcase PIN_CONFIG_DRIVE_STRENGTH:\n+\t\tio_type = IO_TYPE_1V8;\n+\t\tfor (i = 0; i < priv->nr_io_pins; i++) {\n+\t\t\tif (priv->io_pins[i].pin != pin_selector)\n+\t\t\t\tcontinue;\n+\t\t\tio_type = priv->io_pins[i].io_type;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (io_type != IO_TYPE_3V3 && io_type != IO_TYPE_1V8) {\n+\t\t\tdev_err(dev, \"Invalid IO type (%d)\\n\", io_type);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tds = spacemit_get_drive_strength(io_type, argument);\n+\t\tclrsetbits_le32(addr, PAD_DRIVE, ds);\n+\t\tbreak;\n+\tcase PIN_CONFIG_POWER_SOURCE:\n+\t\tfor (i = 0, found = false; i < priv->nr_io_pins; i++) {\n+\t\t\tif (priv->io_pins[i].pin != pin_selector)\n+\t\t\t\tcontinue;\n+\t\t\tif (argument == PIN_POWER_STATE_3V3) {\n+\t\t\t\tpriv->io_pins[i].io_type = IO_TYPE_3V3;\n+\t\t\t\tfound = true;\n+\t\t\t} else if (argument == PIN_POWER_STATE_1V8) {\n+\t\t\t\tpriv->io_pins[i].io_type = IO_TYPE_1V8;\n+\t\t\t\tfound = true;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (!found && argument != PIN_POWER_STATE_1V8) {\n+\t\t\tdev_err(dev, \"Invalid power source (%d)\\n\", argument);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\treturn 0;\n+}\n+\n+static int spacemit_pinctrl_probe(struct udevice *dev)\n+{\n+\tstruct spacemit_pinctrl_data *data;\n+\tstruct spacemit_pinctrl_priv *priv;\n+\tstruct clk_bulk clks;\n+\tsize_t size;\n+\tint ret;\n+\n+\tdata = (struct spacemit_pinctrl_data *)dev_get_driver_data(dev);\n+\tpriv = dev_get_priv(dev);\n+\tpriv->regs = dev_read_addr_ptr(dev);\n+\tif (!priv->regs) {\n+\t\tdev_err(dev, \"Fail to get base address\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tpriv->nr_io_pins = data->nr_io_pins;\n+\tsize = priv->nr_io_pins * sizeof(struct spacemit_pin_io);\n+\tpriv->io_pins = (struct spacemit_pin_io *)memdup(data->io_pins, size);\n+\tif (!priv->io_pins) {\n+\t\tdev_err(dev, \"Fail to allocate memory\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tret = clk_get_bulk(dev, &clks);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Fail to get bulk clks\\n\");\n+\t\tgoto out_get_clk;\n+\t}\n+\tret = clk_enable_bulk(&clks);\n+\tif (ret) {\n+\t\tdev_err(dev, \"Fail to enable bulk clks\\n\");\n+\t\tgoto out_clks;\n+\t}\n+\treturn 0;\n+out_clks:\n+\tclk_release_bulk(&clks);\n+out_get_clk:\n+\tfree(priv->io_pins);\n+\treturn ret;\n+}\n+\n+static const struct spacemit_pinctrl_data k1_pinctrl_data = {\n+\t.io_pins\t= k1_io_pins,\n+\t.nr_io_pins\t= ARRAY_SIZE(k1_io_pins),\n+\t.pin_to_reg\t= k1_pin_to_reg,\n+\t.get_gpio_mux\t= k1_get_gpio_mux,\n+\t.get_pins\t= k1_get_pins,\n+\t.get_functions\t= k1_get_functions,\n+\t.get_io_type\t= k1_get_io_type,\n+};\n+\n+static const struct udevice_id spacemit_pinctrl_ids[] = {\n+\t{\n+\t\t.compatible = \"spacemit,k1-pinctrl\",\n+\t\t.data = (uintptr_t)&k1_pinctrl_data,\n+\t}, { /* sentinel */ }\n+};\n+\n+static const struct pinctrl_ops spacemit_pinctrl_ops = {\n+\t.get_pins_count\t\t= spacemit_get_pins_count,\n+\t.get_pin_name\t\t= spacemit_get_pin_name,\n+\t.get_functions_count\t= spacemit_get_functions_count,\n+\t.get_pin_muxing\t\t= spacemit_get_pin_muxing,\n+\t.set_state\t\t= pinctrl_generic_set_state,\n+\t.gpio_request_enable\t= spacemit_pinctrl_request_gpio,\n+\t.gpio_disable_free\t= spacemit_pinctrl_free_gpio,\n+\t.pinmux_set\t\t= spacemit_pinmux_set,\n+\t.pinmux_property_set\t= spacemit_pinmux_property_set,\n+\t.pinconf_num_params\t= ARRAY_SIZE(spacemit_pinconf_params),\n+\t.pinconf_params\t\t= spacemit_pinconf_params,\n+\t.pinconf_set\t\t= spacemit_pinconf_set,\n+};\n+\n+U_BOOT_DRIVER(spacemit_pinctrl) = {\n+\t.name\t\t= \"spacemit_pinctrl\",\n+\t.id\t\t= UCLASS_PINCTRL,\n+\t.of_match\t= spacemit_pinctrl_ids,\n+\t.ops\t\t= &spacemit_pinctrl_ops,\n+\t.priv_auto\t= sizeof(struct spacemit_pinctrl_priv),\n+\t.probe\t\t= spacemit_pinctrl_probe,\n+};\n",
    "prefixes": [
        "02/16"
    ]
}