From: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
To: Lee Jones <lee@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Loic Poulain <loic.poulain@oss.qualcomm.com>,
Robert Foss <rfoss@kernel.org>,
Andi Shyti <andi.shyti@kernel.org>
Cc: mfd@lists.linux.dev, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-i2c@vger.kernel.org, vikram.sharma@oss.qualcomm.com,
nihal.gupta@oss.qualcomm.com, vtumati@quicinc.com,
bryan.odonoghue@linaro.org,
Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
Subject: [PATCH RFC 3/3] i2c: qcom-cci: Support the CCU output mux
Date: Thu, 05 Nov 2026 19:11:01 +0800 [thread overview]
Message-ID: <20261105-ccu-v1-3-3accc4b901de@oss.qualcomm.com> (raw)
In-Reply-To: <20261105-ccu-v1-0-3accc4b901de@oss.qualcomm.com>
On SoCs such as Nord, the CCIs are wrapped by a CCU. After reset, the
CCI I2C ports are routed to the CCU, and the CCU output mux must select
the CCI before any transfer can take place.
Get the mux register and bits from the optional qcom,ccu-mux-sel syscon
reference and select the CCI at probe and runtime resume, right after
enabling the CCI clocks and before the CCI is reset or configured, as
the mux register is not retained across power collapse.
The mux register is accessible only with the camera subsystem top power
domain and AHB clock enabled, both of which are CCI resources. The
syscon regmap serializes the accesses from multiple CCI instances.
Signed-off-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
---
drivers/i2c/busses/Kconfig | 1 +
drivers/i2c/busses/i2c-qcom-cci.c | 42 +++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 275aaa7f35833f0b07ae13e88def21c3fbc6c787..63ba7314ee7c7cc57115e267a006cd058fe3e305 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1061,6 +1061,7 @@ config I2C_PXA_SLAVE
config I2C_QCOM_CCI
tristate "Qualcomm Camera Control Interface"
depends on ARCH_QCOM || COMPILE_TEST
+ select MFD_SYSCON
select PM_OPP
help
If you say yes to this option, support will be included for the
diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
index 76a5dedf659fb8396ca5df188143469977526505..0e2190cf3300b7da727fc798a1440f30fa73e28d 100644
--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -7,11 +7,13 @@
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/pm_opp.h>
+#include <linux/regmap.h>
#define CCI_HW_VERSION 0x0
#define CCI_RESET_CMD 0x004
@@ -137,9 +139,26 @@ struct cci {
struct clk_bulk_data *clocks;
int nclocks;
struct clk *cci_clk;
+ /* Optional CCU output mux, routing the I2C ports to the CCI */
+ struct regmap *ccu_mux;
+ u32 ccu_mux_reg;
+ u32 ccu_mux_mask;
struct cci_master master[NUM_MASTERS];
};
+/*
+ * Hand the I2C ports over to the CCI. This has to be done with the CCI
+ * clocks enabled, which the mux register access needs, and before the CCI
+ * is reset or configured.
+ */
+static int cci_ccu_mux_select(struct cci *cci)
+{
+ if (!cci->ccu_mux)
+ return 0;
+
+ return regmap_set_bits(cci->ccu_mux, cci->ccu_mux_reg, cci->ccu_mux_mask);
+}
+
static irqreturn_t cci_isr(int irq, void *dev)
{
struct cci *cci = dev;
@@ -651,6 +670,12 @@ static int __maybe_unused cci_resume_runtime(struct device *dev)
if (ret)
return ret;
+ ret = cci_ccu_mux_select(cci);
+ if (ret) {
+ cci_disable_clocks(cci);
+ return ret;
+ }
+
return cci_init(cci);
}
@@ -668,6 +693,7 @@ static int cci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct resource *r;
+ u32 mux_args[2];
struct cci *cci;
int ret, i;
u32 val;
@@ -730,6 +756,18 @@ static int cci_probe(struct platform_device *pdev)
if (IS_ERR(cci->base))
return PTR_ERR(cci->base);
+ cci->ccu_mux = syscon_regmap_lookup_by_phandle_args(dev->of_node, "qcom,ccu-mux-sel",
+ 2, mux_args);
+ if (IS_ERR(cci->ccu_mux)) {
+ ret = PTR_ERR(cci->ccu_mux);
+ if (ret != -ENOENT)
+ return dev_err_probe(dev, ret, "failed to get CCU mux\n");
+ cci->ccu_mux = NULL;
+ } else {
+ cci->ccu_mux_reg = mux_args[0];
+ cci->ccu_mux_mask = mux_args[1];
+ }
+
/* Clocks */
ret = devm_clk_bulk_get_all(dev, &cci->clocks);
@@ -761,6 +799,10 @@ static int cci_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ ret = cci_ccu_mux_select(cci);
+ if (ret)
+ goto disable_clocks;
+
/* Interrupt */
ret = platform_get_irq(pdev, 0);
--
2.34.1
prev parent reply other threads:[~2026-11-05 11:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 11:10 [PATCH RFC 0/3] Support the Nord CCI " Wenmeng Liu
2026-11-05 11:10 ` [PATCH RFC 1/3] dt-bindings: mfd: syscon: Add Qualcomm Nord Titan CAM_TOP Wenmeng Liu
2026-11-05 11:11 ` [PATCH RFC 2/3] dt-bindings: i2c: qcom-cci: Document Nord compatible Wenmeng Liu
2026-11-05 11:11 ` Wenmeng Liu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261105-ccu-v1-3-3accc4b901de@oss.qualcomm.com \
--to=wenmeng.liu@oss.qualcomm.com \
--cc=andi.shyti@kernel.org \
--cc=bryan.odonoghue@linaro.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=loic.poulain@oss.qualcomm.com \
--cc=mfd@lists.linux.dev \
--cc=nihal.gupta@oss.qualcomm.com \
--cc=rfoss@kernel.org \
--cc=robh@kernel.org \
--cc=vikram.sharma@oss.qualcomm.com \
--cc=vtumati@quicinc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®