Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2217554/?format=api
{ "id": 2217554, "url": "http://patchwork.ozlabs.org/api/patches/2217554/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-i2c/patch/20260330-atciic100-v4-2-d40822f63e4e@andestech.com/", "project": { "id": 35, "url": "http://patchwork.ozlabs.org/api/projects/35/?format=api", "name": "Linux I2C development", "link_name": "linux-i2c", "list_id": "linux-i2c.vger.kernel.org", "list_email": "linux-i2c@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260330-atciic100-v4-2-d40822f63e4e@andestech.com>", "list_archive_url": null, "date": "2026-03-30T07:30:32", "name": "[v4,2/4] i2c: add Andes I2C driver support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "f370c6e3184faa8a60e5ba3c3c5ee21254dd0cd9", "submitter": { "id": 92477, "url": "http://patchwork.ozlabs.org/api/people/92477/?format=api", "name": "Ben Zong-You Xie via B4 Relay", "email": "devnull+ben717.andestech.com@kernel.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-i2c/patch/20260330-atciic100-v4-2-d40822f63e4e@andestech.com/mbox/", "series": [ { "id": 497967, "url": "http://patchwork.ozlabs.org/api/series/497967/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-i2c/list/?series=497967", "date": "2026-03-30T07:30:33", "name": "i2c: add support for Andes platform", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/497967/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2217554/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2217554/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-i2c+bounces-16866-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-i2c@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=aUAxQAgJ;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-i2c+bounces-16866-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"aUAxQAgJ\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\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 4fkjkN22p6z1yG8\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 30 Mar 2026 18:37:00 +1100 (AEDT)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 69B6930420A7\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 30 Mar 2026 07:30:40 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 904843A1680;\n\tMon, 30 Mar 2026 07:30:36 +0000 (UTC)", "from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 2807037F00E;\n\tMon, 30 Mar 2026 07:30:36 +0000 (UTC)", "by smtp.kernel.org (Postfix) with ESMTPS id E3779C2BCB4;\n\tMon, 30 Mar 2026 07:30:35 +0000 (UTC)", "from aws-us-west-2-korg-lkml-1.web.codeaurora.org\n (localhost.localdomain [127.0.0.1])\n\tby smtp.lore.kernel.org (Postfix) with ESMTP id D5373FF4959;\n\tMon, 30 Mar 2026 07:30:35 +0000 (UTC)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1774855836; cv=none;\n b=C7+oYNJ5msPfWyaPNKBIdcykYlMiaVC1UKSz8U3IhcWpuT3mzVSz8qYe7PbAqrCVsSqknlQhrcngPDPuyeF5od67nNa1kWGU8uBK/HxrW233enQTxUO4cnEJMYIcIu2wSIkEkBNRbvNtLisEr8GfjVElcqGkVPSBfWDw5TTibsY=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1774855836; c=relaxed/simple;\n\tbh=5fPzt3XdA3Yulgacz2ac1L2irSRMu6WojI6m9w7c+2U=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=ipxVNHSEQ1mWHCGPEBDWiORYNR9gUHUOWgbdH+efEVCXLoqUii0/pdbDsJ/Tq1f4KF5FY4e3kQ2G+eT7bgKeqD0edvrXhnfqFsFWqVIbLn2tRvHmjWLXn5COjs/GOVd1uaWyZF+xBACIzjy51kCRhD0Ho+43zOGNXxazm5foGTg=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=aUAxQAgJ; arc=none smtp.client-ip=10.30.226.201", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1774855835;\n\tbh=5fPzt3XdA3Yulgacz2ac1L2irSRMu6WojI6m9w7c+2U=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;\n\tb=aUAxQAgJDDgZDdGuVizi5Ucm1Jqjc7ZH2wF19bxEqcbt+KnFpxi/sXaGLT/YtAG/O\n\t R6+xniN/pDxSDgezq1O93aJaju2kAELcYFmJPn8d2VIi9/vsXO72r9uYpJMlVohiF8\n\t KxQQtu5hWamLzCtAu/jLWuScUNWKfPo6ny7g2YJkYvEVr1VCeuQ8OniwZqClXXQwJ9\n\t 8zJ7G3u5p9ffattD3Dg3JIpPI62/ApwHDGoK6DNJfAyLmvnIl4+iurpPIsoY6FFS2M\n\t UuUlkboItZv5eDdIPo1XoPytCoV51QnjI0rAsC1uDmV5iyuKz3qEpJIDarEBl9kj/P\n\t IP/W8lGk40+lA==", "From": "Ben Zong-You Xie via B4 Relay <devnull+ben717.andestech.com@kernel.org>", "Date": "Mon, 30 Mar 2026 15:30:32 +0800", "Subject": "[PATCH v4 2/4] i2c: add Andes I2C driver support", "Precedence": "bulk", "X-Mailing-List": "linux-i2c@vger.kernel.org", "List-Id": "<linux-i2c.vger.kernel.org>", "List-Subscribe": "<mailto:linux-i2c+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-i2c+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20260330-atciic100-v4-2-d40822f63e4e@andestech.com>", "References": "<20260330-atciic100-v4-0-d40822f63e4e@andestech.com>", "In-Reply-To": "<20260330-atciic100-v4-0-d40822f63e4e@andestech.com>", "To": "Andi Shyti <andi.shyti@kernel.org>, Rob Herring <robh@kernel.org>,\n Krzysztof Kozlowski <krzk+dt@kernel.org>,\n Conor Dooley <conor+dt@kernel.org>, Paul Walmsley <pjw@kernel.org>,\n Palmer Dabbelt <palmer@dabbelt.com>, Albert Ou <aou@eecs.berkeley.edu>,\n Alexandre Ghiti <alex@ghiti.fr>", "Cc": "linux-i2c@vger.kernel.org, devicetree@vger.kernel.org,\n linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,\n Ben Zong-You Xie <ben717@andestech.com>", "X-Mailer": "b4 0.15-dev-47773", "X-Developer-Signature": "v=1; a=ed25519-sha256; t=1774855834; l=11439;\n i=ben717@andestech.com; s=20260120; h=from:subject:message-id;\n bh=3+VjWSgAEZB0R4IY99RGMkxW2+TuaVt98VIntlANnLM=;\n b=EILeU0fgt0YGmdEA/+N7Yj5wG0hAHk5WxST/m07dWsCiCmN5QgrDe/tpDi/8s3lWAz2AHV3LL\n MOGCQV4jSufCQVMIHMuuqDYe/JUkeQVWgJnkbniW/MeNAhVPtdtQkoO", "X-Developer-Key": "i=ben717@andestech.com; a=ed25519;\n pk=nb8L7zQKGJpYk0yvrYKjViOZ34A36g1ZIsCmCsP518s=", "X-Endpoint-Received": "by B4 Relay for ben717@andestech.com/20260120 with\n auth_id=610", "X-Original-From": "Ben Zong-You Xie <ben717@andestech.com>", "Reply-To": "ben717@andestech.com" }, "content": "From: Ben Zong-You Xie <ben717@andestech.com>\n\nAdd support for Andes I2C driver. Andes I2C can act as either a\ncontroller or a target, depending on the control register settings. Now,\nwe only support controller mode.\n\nSigned-off-by: Ben Zong-You Xie <ben717@andestech.com>\n---\n drivers/i2c/busses/Kconfig | 10 ++\n drivers/i2c/busses/Makefile | 1 +\n drivers/i2c/busses/i2c-andes.c | 341 +++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 352 insertions(+)", "diff": "diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig\nindex 7cb6b9b864a7..6aaa5a1223c2 100644\n--- a/drivers/i2c/busses/Kconfig\n+++ b/drivers/i2c/busses/Kconfig\n@@ -446,6 +446,16 @@ config I2C_AT91_SLAVE_EXPERIMENTAL\n \t - There are some mismatches with a SAMA5D4 as slave and a SAMA5D2 as\n \t master.\n \n+config I2C_ANDES\n+\ttristate \"Andes I2C Controller\"\n+\tdepends on ARCH_ANDES || COMPILE_TEST\n+\thelp\n+\t If you say yes to this option, support will be included for the\n+\t Andes I2C controller.\n+\n+\t This support is also available as a module. If so, the module\n+\t will be called i2c-andes.\n+\n config I2C_AU1550\n \ttristate \"Au1550/Au1200/Au1300 SMBus interface\"\n \tdepends on MIPS_ALCHEMY\ndiff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile\nindex 547123ab351f..89d85d10f8d2 100644\n--- a/drivers/i2c/busses/Makefile\n+++ b/drivers/i2c/busses/Makefile\n@@ -41,6 +41,7 @@ obj-$(CONFIG_I2C_ASPEED)\t+= i2c-aspeed.o\n obj-$(CONFIG_I2C_AT91)\t\t+= i2c-at91.o\n i2c-at91-y\t\t\t:= i2c-at91-core.o i2c-at91-master.o\n i2c-at91-$(CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL)\t+= i2c-at91-slave.o\n+obj-$(CONFIG_I2C_ANDES)\t\t+= i2c-andes.o\n obj-$(CONFIG_I2C_AU1550)\t+= i2c-au1550.o\n obj-$(CONFIG_I2C_AXXIA)\t\t+= i2c-axxia.o\n obj-$(CONFIG_I2C_BCM2835)\t+= i2c-bcm2835.o\ndiff --git a/drivers/i2c/busses/i2c-andes.c b/drivers/i2c/busses/i2c-andes.c\nnew file mode 100644\nindex 000000000000..5f135d8c9b13\n--- /dev/null\n+++ b/drivers/i2c/busses/i2c-andes.c\n@@ -0,0 +1,341 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Driver for Andes I2C controller, used in Andes AE350 platform and QiLai SoC\n+ *\n+ * Copyright (C) 2026 Andes Technology Corporation.\n+ */\n+\n+#include <linux/bitfield.h>\n+#include <linux/completion.h>\n+#include <linux/iopoll.h>\n+#include <linux/i2c.h>\n+#include <linux/of_device.h>\n+#include <linux/platform_device.h>\n+#include <linux/regmap.h>\n+#include <linux/spinlock.h>\n+\n+#define ANDES_I2C_ID_REG\t\t0x0\n+#define ANDES_I2C_ID_MASK\t\tGENMASK(31, 8)\n+#define ANDES_I2C_ID\t\t\t0x020210\n+\n+#define\tANDES_I2C_CFG_REG\t\t0x10\n+#define ANDES_I2C_CFG_FIFOSIZE\t\tGENMASK(1, 0)\n+\n+#define\tANDES_I2C_INTEN_REG\t\t0x14\n+#define\tANDES_I2C_INTEN_FIFO_EMPTY\tBIT(0)\n+#define\tANDES_I2C_INTEN_FIFO_FULL\tBIT(1)\n+#define\tANDES_I2C_INTEN_CMPL\t\tBIT(9)\n+\n+#define\tANDES_I2C_STATUS_REG\t\t0x18\n+#define ANDES_I2C_STATUS_FIFO_EMPTY\tBIT(0)\n+#define ANDES_I2C_STATUS_FIFO_FULL\tBIT(1)\n+#define ANDES_I2C_STATUS_ADDR_HIT\tBIT(3)\n+#define ANDES_I2C_STATUS_CMPL\t\tBIT(9)\n+#define ANDES_I2C_STATUS_W1C\t\tGENMASK(9, 3)\n+\n+#define\tANDES_I2C_ADDR_REG\t\t0x1C\n+\n+#define\tANDES_I2C_DATA_REG\t\t0x20\n+\n+#define\tANDES_I2C_CTRL_REG\t\t0x24\n+#define ANDES_I2C_CTRL_DATA_CNT\t\tGENMASK(7, 0)\n+#define ANDES_I2C_CTRL_DIR\t\tBIT(8)\n+#define ANDES_I2C_CTRL_PHASE\t\tGENMASK(12, 9)\n+\n+#define\tANDES_I2C_CMD_REG\t\t0x28\n+#define ANDES_I2C_CMD_ACTION\t\tGENMASK(2, 0)\n+#define ANDES_I2C_CMD_TRANS\t\tBIT(0)\n+\n+#define\tANDES_I2C_SETUP_REG\t\t0x2C\n+#define ANDES_I2C_SETUP_IICEN\t\tBIT(0)\n+#define ANDES_I2C_SETUP_REQ\t\tBIT(2)\n+\n+#define ANDES_I2C_TPM_REG\t\t0x30\n+\n+#define ANDES_I2C_TIMEOUT_US\t\t400000\n+#define ANDES_I2C_TIMEOUT\t\tusecs_to_jiffies(ANDES_I2C_TIMEOUT_US)\n+\n+#define ANDES_I2C_MAX_DATA_LEN\t\t256\n+\n+struct andes_i2c {\n+\tstruct i2c_adapter adap;\n+\tstruct completion completion;\n+\tspinlock_t lock;\n+\tstruct regmap *map;\n+\tu8 *buf;\n+\tunsigned int fifo_size;\n+\tint irq;\n+\tu16 buf_len;\n+\tbool addr_hit;\n+\tbool xfer_done;\n+};\n+\n+static const struct regmap_config andes_i2c_regmap_config = {\n+\t.name = \"andes_i2c\",\n+\t.reg_bits = 32,\n+\t.reg_stride = 4,\n+\t.val_bits = 32,\n+\t.pad_bits = 0,\n+\t.max_register = ANDES_I2C_TPM_REG,\n+\t.cache_type = REGCACHE_NONE,\n+};\n+\n+static void andes_i2c_xfer_common(struct andes_i2c *i2c, u32 status)\n+{\n+\tunsigned long flags;\n+\tunsigned int fsize = i2c->fifo_size;\n+\tunsigned int val;\n+\n+\tspin_lock_irqsave(&i2c->lock, flags);\n+\tif (status & ANDES_I2C_STATUS_FIFO_EMPTY) {\n+\t\t/* Disable the FIFO empty interrupt for the last write */\n+\t\tif (i2c->buf_len <= fsize) {\n+\t\t\tfsize = i2c->buf_len;\n+\t\t\tregmap_clear_bits(i2c->map, ANDES_I2C_INTEN_REG,\n+\t\t\t\t\t ANDES_I2C_INTEN_FIFO_EMPTY);\n+\t\t}\n+\n+\t\twhile (fsize--) {\n+\t\t\tval = *i2c->buf++;\n+\t\t\tregmap_write(i2c->map, ANDES_I2C_DATA_REG, val);\n+\t\t\ti2c->buf_len--;\n+\t\t}\n+\t} else if (status & ANDES_I2C_STATUS_FIFO_FULL) {\n+\t\twhile (fsize--) {\n+\t\t\tregmap_read(i2c->map, ANDES_I2C_DATA_REG, &val);\n+\t\t\t*i2c->buf++ = (u8)val;\n+\t\t\ti2c->buf_len--;\n+\t\t}\n+\t}\n+\n+\tif (status & ANDES_I2C_STATUS_CMPL) {\n+\t\ti2c->xfer_done = true;\n+\t\tif (status & ANDES_I2C_STATUS_ADDR_HIT)\n+\t\t\ti2c->addr_hit = true;\n+\n+\t\t/* Write 1 to clear the status */\n+\t\tregmap_set_bits(i2c->map, ANDES_I2C_STATUS_REG,\n+\t\t\t\tANDES_I2C_STATUS_W1C);\n+\n+\t\t/* For the last read, retrieve all remaining data in FIFO. */\n+\t\twhile (i2c->buf_len > 0) {\n+\t\t\tregmap_read(i2c->map, ANDES_I2C_DATA_REG, &val);\n+\t\t\t*i2c->buf++ = (u8)val;\n+\t\t\ti2c->buf_len--;\n+\t\t}\n+\t}\n+\n+\tspin_unlock_irqrestore(&i2c->lock, flags);\n+}\n+\n+static irqreturn_t andes_i2c_irq_handler(int irq, void *data)\n+{\n+\tstruct andes_i2c *i2c = data;\n+\tu32 i2c_status;\n+\n+\tregmap_read(i2c->map, ANDES_I2C_STATUS_REG, &i2c_status);\n+\tandes_i2c_xfer_common(i2c, i2c_status);\n+\tif (i2c->xfer_done)\n+\t\tcomplete(&i2c->completion);\n+\n+\treturn IRQ_HANDLED;\n+}\n+\n+static int andes_i2c_xfer_wait(struct andes_i2c *i2c, struct i2c_msg *msg)\n+{\n+\tunsigned int mask;\n+\tunsigned int i2c_ctrl;\n+\n+\t/*\n+\t * Set the data count. If there are 256 bytes to be transmitted, write\n+\t * zero to the data count field.\n+\t */\n+\tregmap_update_bits(i2c->map, ANDES_I2C_CTRL_REG,\n+\t\t\t ANDES_I2C_CTRL_DATA_CNT,\n+\t\t\t FIELD_PREP(ANDES_I2C_CTRL_DATA_CNT, i2c->buf_len));\n+\n+\tregmap_set_bits(i2c->map, ANDES_I2C_CTRL_REG, ANDES_I2C_CTRL_PHASE);\n+\tif (msg->flags & I2C_M_RD)\n+\t\tregmap_set_bits(i2c->map, ANDES_I2C_CTRL_REG,\n+\t\t\t\tANDES_I2C_CTRL_DIR);\n+\telse\n+\t\tregmap_clear_bits(i2c->map, ANDES_I2C_CTRL_REG,\n+\t\t\t\t ANDES_I2C_CTRL_DIR);\n+\n+\tregmap_write(i2c->map, ANDES_I2C_ADDR_REG, msg->addr);\n+\n+\tif (i2c->irq >= 0) {\n+\t\tmask = ANDES_I2C_INTEN_CMPL;\n+\t\tmask |= (msg->flags & I2C_M_RD) ? ANDES_I2C_INTEN_FIFO_FULL\n+\t\t\t\t\t\t: ANDES_I2C_INTEN_FIFO_EMPTY;\n+\t\tregmap_set_bits(i2c->map, ANDES_I2C_INTEN_REG, mask);\n+\t}\n+\n+\tregmap_set_bits(i2c->map, ANDES_I2C_CMD_REG, ANDES_I2C_CMD_TRANS);\n+\tif (i2c->irq >= 0) {\n+\t\tunsigned long time_left;\n+\n+\t\ttime_left = wait_for_completion_timeout(&i2c->completion,\n+\t\t\t\t\t\t\tANDES_I2C_TIMEOUT);\n+\t\tif (!time_left)\n+\t\t\treturn -ETIMEDOUT;\n+\n+\t\tif (!i2c->addr_hit)\n+\t\t\treturn -ENXIO;\n+\n+\t\tregmap_write(i2c->map, ANDES_I2C_INTEN_REG, 0);\n+\t\treinit_completion(&i2c->completion);\n+\t} else {\n+\t\tunsigned int val;\n+\t\tint ret;\n+\n+\t\tmask = ANDES_I2C_STATUS_CMPL;\n+\t\tmask |= (msg->flags & I2C_M_RD) ? ANDES_I2C_STATUS_FIFO_FULL\n+\t\t\t\t\t\t: ANDES_I2C_STATUS_FIFO_EMPTY;\n+\t\twhile (!i2c->xfer_done) {\n+\t\t\tret = regmap_read_poll_timeout(i2c->map,\n+\t\t\t\t\t\t ANDES_I2C_STATUS_REG,\n+\t\t\t\t\t\t val, val & mask, 2000,\n+\t\t\t\t\t\t ANDES_I2C_TIMEOUT_US);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\n+\t\t\tandes_i2c_xfer_common(i2c, val);\n+\t\t}\n+\n+\t\tif (!i2c->addr_hit)\n+\t\t\treturn -ENXIO;\n+\t}\n+\n+\t/* Check if all data is successfully transmitted */\n+\tregmap_read(i2c->map, ANDES_I2C_CTRL_REG, &i2c_ctrl);\n+\tif (FIELD_GET(ANDES_I2C_CTRL_DATA_CNT, i2c_ctrl))\n+\t\treturn -EIO;\n+\n+\treturn 0;\n+}\n+\n+static int andes_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,\n+\t\t\t int num)\n+{\n+\tint i;\n+\tstruct i2c_msg *m;\n+\tstruct andes_i2c *i2c = i2c_get_adapdata(adap);\n+\tint ret;\n+\n+\tfor (i = 0; i < num; i++) {\n+\t\tm = &msg[i];\n+\t\ti2c->addr_hit = false;\n+\t\ti2c->buf = m->buf;\n+\t\ti2c->buf_len = m->len;\n+\t\ti2c->xfer_done = false;\n+\t\tret = andes_i2c_xfer_wait(i2c, m);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn num;\n+}\n+\n+static u32 andes_i2c_func(struct i2c_adapter *adap)\n+{\n+\treturn I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;\n+}\n+\n+static struct i2c_algorithm andes_i2c_algo = {\n+\t.xfer = andes_i2c_xfer,\n+\t.functionality = andes_i2c_func,\n+};\n+\n+static const struct i2c_adapter_quirks andes_i2c_quirks = {\n+\t.flags = I2C_AQ_NO_ZERO_LEN,\n+\t.max_write_len = ANDES_I2C_MAX_DATA_LEN,\n+\t.max_read_len = ANDES_I2C_MAX_DATA_LEN,\n+};\n+\n+static int andes_i2c_probe(struct platform_device *pdev)\n+{\n+\tstruct device *dev = &pdev->dev;\n+\tstruct andes_i2c *i2c;\n+\tvoid __iomem *reg_base;\n+\tu32 i2c_id;\n+\tint ret;\n+\tstruct i2c_adapter *adap;\n+\n+\ti2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);\n+\tif (!i2c)\n+\t\treturn -ENOMEM;\n+\n+\treg_base = devm_platform_ioremap_resource(pdev, 0);\n+\tif (IS_ERR(reg_base))\n+\t\treturn dev_err_probe(dev, PTR_ERR(reg_base),\n+\t\t\t\t \"failed to map I/O space\\n\");\n+\n+\ti2c->map = devm_regmap_init_mmio(dev, reg_base,\n+\t\t\t\t\t &andes_i2c_regmap_config);\n+\tif (IS_ERR(i2c->map))\n+\t\treturn dev_err_probe(dev, PTR_ERR(i2c->map),\n+\t\t\t\t \"failed to initialize regmap\\n\");\n+\n+\tregmap_read(i2c->map, ANDES_I2C_ID_REG, &i2c_id);\n+\tif (FIELD_GET(ANDES_I2C_ID_MASK, i2c_id) != ANDES_I2C_ID)\n+\t\treturn dev_err_probe(dev, -ENODEV, \"unmatched hardware ID 0x%x\\n\",\n+\t\t\t\t i2c_id);\n+\n+\ti2c->irq = platform_get_irq(pdev, 0);\n+\tif (i2c->irq >= 0) {\n+\t\tret = devm_request_irq(dev, i2c->irq, andes_i2c_irq_handler, 0,\n+\t\t\t\t dev_name(dev), i2c);\n+\t\tif (ret < 0)\n+\t\t\treturn dev_err_probe(dev, ret, \"unable to request IRQ %d\\n\",\n+\t\t\t\t\t i2c->irq);\n+\t} else {\n+\t\tdev_warn(dev, \"no IRQ resource, falling back to poll mode\\n\");\n+\t}\n+\n+\tspin_lock_init(&i2c->lock);\n+\tinit_completion(&i2c->completion);\n+\tadap = &i2c->adap;\n+\tstrscpy(adap->name, pdev->name, sizeof(adap->name));\n+\tadap->algo = &andes_i2c_algo;\n+\tadap->class = I2C_CLASS_HWMON;\n+\tadap->dev.parent = dev;\n+\tadap->dev.of_node = dev->of_node;\n+\tadap->owner = THIS_MODULE;\n+\tadap->quirks = &andes_i2c_quirks;\n+\tadap->retries = 1;\n+\tadap->timeout = ANDES_I2C_TIMEOUT;\n+\ti2c_set_adapdata(adap, i2c);\n+\tplatform_set_drvdata(pdev, i2c);\n+\tret = devm_i2c_add_adapter(dev, adap);\n+\tif (ret)\n+\t\treturn dev_err_probe(dev, ret, \"failed to add adapter\\n\");\n+\n+\tregmap_read(i2c->map, ANDES_I2C_CFG_REG, &i2c->fifo_size);\n+\ti2c->fifo_size = 2 << FIELD_GET(ANDES_I2C_CFG_FIFOSIZE, i2c->fifo_size);\n+\n+\tregmap_set_bits(i2c->map, ANDES_I2C_SETUP_REG,\n+\t\t\tANDES_I2C_SETUP_IICEN | ANDES_I2C_SETUP_REQ);\n+\treturn 0;\n+}\n+\n+static const struct of_device_id andes_i2c_of_match[] = {\n+\t{ .compatible = \"andestech,ae350-i2c\" },\n+\t{ /* sentinel */ }\n+};\n+\n+MODULE_DEVICE_TABLE(of, andes_i2c_of_match);\n+\n+static struct platform_driver andes_i2c_platform_driver = {\n+\t.driver = {\n+\t\t.name = \"andes_i2c\",\n+\t\t.of_match_table\t= andes_i2c_of_match,\n+\t},\n+\t.probe = andes_i2c_probe,\n+};\n+\n+module_platform_driver(andes_i2c_platform_driver);\n+\n+MODULE_AUTHOR(\"Ben Zong-You Xie <ben717@andestech.com>\");\n+MODULE_DESCRIPTION(\"Andes I2C controller driver\");\n+MODULE_LICENSE(\"GPL\");\n", "prefixes": [ "v4", "2/4" ] }