* [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller
@ 2026-03-14 8:26 Rustam Adilov
2026-03-14 8:26 ` [PATCH 1/8] i2c: rtl9300: split data_reg into read and write reg Rustam Adilov
` (8 more replies)
0 siblings, 9 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
This patch series for the RTL9300 I2C driver adds i2c support for
RTL9607C SoC. They are somewhat different to the RTL9300 and
RTL9310 but not enough to warrant a new whole driver.
The patch series was split into patches that add/change something in the
driver to smooth out the RTL9607C support addition in the end and for
ease of review. Because of that, the patch 8 depends on all the prior
patches before it.
RTL9607C primarly uses the i2c controller for communication with laser
driver over on i2c interface 1 or 2.
I have successfully tested the byte read operations on my RTL9607C board
which has GN25L95 laser driver in OpenWrt.
Rustam Adilov (8):
i2c: rtl9300: split data_reg into read and write reg
i2c: rtl9300: introduce max length property to driver data
i2c: rtl9300: introduce F_BUSY to the reg_fields struct
i2c: rtl9300: introduce a property for 8 bit width reg address
i2c: rtl9300: introduce clk struct for upcoming rtl9607 support
i2c: rtl9300: intoduce new function properties to driver data
dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support
i2c: rtl9300: add RTL9607C i2c controller support
.../bindings/i2c/realtek,rtl9301-i2c.yaml | 15 ++
drivers/i2c/busses/i2c-rtl9300.c | 179 +++++++++++++++---
2 files changed, 165 insertions(+), 29 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 1/8] i2c: rtl9300: split data_reg into read and write reg
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-14 8:26 ` [PATCH 2/8] i2c: rtl9300: introduce max length property to driver data Rustam Adilov
` (7 subsequent siblings)
8 siblings, 0 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
In RTL9607C i2c controller, there are 2 separate registers for reads
and writes as opposed the combined 1 on rtl9300 and rtl9310.
In preparation for RTL9607C support, split it up into rd_reg and wd_reg
properties and change the i2c read and write functions accordingly.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
drivers/i2c/busses/i2c-rtl9300.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 672cb978066d..66390420bd6a 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -55,7 +55,8 @@ enum rtl9300_i2c_reg_fields {
struct rtl9300_i2c_drv_data {
struct rtl9300_i2c_reg_field field_desc[F_NUM_FIELDS];
int (*select_scl)(struct rtl9300_i2c *i2c, u8 scl);
- u32 data_reg;
+ u32 rd_reg;
+ u32 wd_reg;
u8 max_nchan;
};
@@ -68,7 +69,8 @@ struct rtl9300_i2c {
struct rtl9300_i2c_chan chans[RTL9310_I2C_MUX_NCHAN];
struct regmap_field *fields[F_NUM_FIELDS];
u32 reg_base;
- u32 data_reg;
+ u32 rd_reg;
+ u32 wd_reg;
u8 scl_num;
u8 sda_num;
struct mutex lock;
@@ -165,7 +167,7 @@ static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
if (len > 16)
return -EIO;
- ret = regmap_bulk_read(i2c->regmap, i2c->data_reg, vals, ARRAY_SIZE(vals));
+ ret = regmap_bulk_read(i2c->regmap, i2c->rd_reg, vals, ARRAY_SIZE(vals));
if (ret)
return ret;
@@ -192,12 +194,12 @@ static int rtl9300_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
vals[reg] |= buf[i] << shift;
}
- return regmap_bulk_write(i2c->regmap, i2c->data_reg, vals, ARRAY_SIZE(vals));
+ return regmap_bulk_write(i2c->regmap, i2c->wd_reg, vals, ARRAY_SIZE(vals));
}
static int rtl9300_i2c_writel(struct rtl9300_i2c *i2c, u32 data)
{
- return regmap_write(i2c->regmap, i2c->data_reg, data);
+ return regmap_write(i2c->regmap, i2c->wd_reg, data);
}
static int rtl9300_i2c_prepare_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_xfer *xfer)
@@ -262,14 +264,14 @@ static int rtl9300_i2c_do_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_xfer
if (!xfer->write) {
switch (xfer->type) {
case RTL9300_I2C_XFER_BYTE:
- ret = regmap_read(i2c->regmap, i2c->data_reg, &val);
+ ret = regmap_read(i2c->regmap, i2c->rd_reg, &val);
if (ret)
return ret;
*xfer->data = val & 0xff;
break;
case RTL9300_I2C_XFER_WORD:
- ret = regmap_read(i2c->regmap, i2c->data_reg, &val);
+ ret = regmap_read(i2c->regmap, i2c->rd_reg, &val);
if (ret)
return ret;
@@ -402,7 +404,8 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
if (device_get_child_node_count(dev) > drv_data->max_nchan)
return dev_err_probe(dev, -EINVAL, "Too many channels\n");
- i2c->data_reg = i2c->reg_base + drv_data->data_reg;
+ i2c->rd_reg = i2c->reg_base + drv_data->rd_reg;
+ i2c->wd_reg = i2c->reg_base + drv_data->wd_reg;
for (i = 0; i < F_NUM_FIELDS; i++) {
fields[i] = drv_data->field_desc[i].field;
if (drv_data->field_desc[i].scope == REG_SCOPE_MASTER)
@@ -487,7 +490,8 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
[F_SDA_SEL] = GLB_REG_FIELD(RTL9300_I2C_MST_GLB_CTRL, 0, 7),
},
.select_scl = rtl9300_i2c_select_scl,
- .data_reg = RTL9300_I2C_MST_DATA_WORD0,
+ .rd_reg = RTL9300_I2C_MST_DATA_WORD0,
+ .wd_reg = RTL9300_I2C_MST_DATA_WORD0,
.max_nchan = RTL9300_I2C_MUX_NCHAN,
};
@@ -507,7 +511,8 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
[F_MEM_ADDR] = MST_REG_FIELD(RTL9310_I2C_MST_MEMADDR_CTRL, 0, 23),
},
.select_scl = rtl9310_i2c_select_scl,
- .data_reg = RTL9310_I2C_MST_DATA_CTRL,
+ .rd_reg = RTL9310_I2C_MST_DATA_CTRL,
+ .wd_reg = RTL9310_I2C_MST_DATA_CTRL,
.max_nchan = RTL9310_I2C_MUX_NCHAN,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 2/8] i2c: rtl9300: introduce max length property to driver data
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
2026-03-14 8:26 ` [PATCH 1/8] i2c: rtl9300: split data_reg into read and write reg Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-14 8:26 ` [PATCH 3/8] i2c: rtl9300: introduce F_BUSY to the reg_fields struct Rustam Adilov
` (6 subsequent siblings)
8 siblings, 0 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
In RTL9607C i2c controller, theoretical maximum the data length
can be is 4 bytes as opposed to 16 bytes on rtl9300 and rtl9310.
Introduce a new property to the driver data struct for that.
Adjust if statement in prepare_xfer function to follow that new
property instead of the hardcoded value.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
drivers/i2c/busses/i2c-rtl9300.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 66390420bd6a..1354c8a7a369 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -58,11 +58,14 @@ struct rtl9300_i2c_drv_data {
u32 rd_reg;
u32 wd_reg;
u8 max_nchan;
+ u8 max_data_len;
};
#define RTL9300_I2C_MUX_NCHAN 8
#define RTL9310_I2C_MUX_NCHAN 12
+#define RTL9300_I2C_MAX_DATA_LEN 16
+
struct rtl9300_i2c {
struct regmap *regmap;
struct device *dev;
@@ -204,9 +207,11 @@ static int rtl9300_i2c_writel(struct rtl9300_i2c *i2c, u32 data)
static int rtl9300_i2c_prepare_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_xfer *xfer)
{
+ const struct rtl9300_i2c_drv_data *drv_data;
int ret;
- if (xfer->data_len < 1 || xfer->data_len > 16)
+ drv_data = device_get_match_data(i2c->dev);
+ if (xfer->data_len < 1 || xfer->data_len > drv_data->max_data_len)
return -EINVAL;
ret = regmap_field_write(i2c->fields[F_DEV_ADDR], xfer->dev_addr);
@@ -493,6 +498,7 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
.rd_reg = RTL9300_I2C_MST_DATA_WORD0,
.wd_reg = RTL9300_I2C_MST_DATA_WORD0,
.max_nchan = RTL9300_I2C_MUX_NCHAN,
+ .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
};
static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
@@ -514,6 +520,7 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
.rd_reg = RTL9310_I2C_MST_DATA_CTRL,
.wd_reg = RTL9310_I2C_MST_DATA_CTRL,
.max_nchan = RTL9310_I2C_MUX_NCHAN,
+ .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
};
static const struct of_device_id i2c_rtl9300_dt_ids[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 3/8] i2c: rtl9300: introduce F_BUSY to the reg_fields struct
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
2026-03-14 8:26 ` [PATCH 1/8] i2c: rtl9300: split data_reg into read and write reg Rustam Adilov
2026-03-14 8:26 ` [PATCH 2/8] i2c: rtl9300: introduce max length property to driver data Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-14 8:26 ` [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address Rustam Adilov
` (5 subsequent siblings)
8 siblings, 0 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
In RTL9607C i2c controller the busy check operation is done on the
separate bit of the command register as opposed to self clearing
command trigger bit on the rtl9300 and rtl9310 i2c controllers.
Introduce a new F_BUSY field to the reg_fields struct for that
and change the regmap read poll function to use F_BUSY
instead of I2C_TRIG.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
drivers/i2c/busses/i2c-rtl9300.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 1354c8a7a369..2525b57a9d03 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -47,6 +47,7 @@ enum rtl9300_i2c_reg_fields {
F_SCL_SEL,
F_SDA_OUT_SEL,
F_SDA_SEL,
+ F_BUSY,
/* keep last */
F_NUM_FIELDS
@@ -256,7 +257,7 @@ static int rtl9300_i2c_do_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_xfer
if (ret)
return ret;
- ret = regmap_field_read_poll_timeout(i2c->fields[F_I2C_TRIG], val, !val, 100, 100000);
+ ret = regmap_field_read_poll_timeout(i2c->fields[F_BUSY], val, !val, 100, 100000);
if (ret)
return ret;
@@ -493,6 +494,7 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
[F_MEM_ADDR_WIDTH] = MST_REG_FIELD(RTL9300_I2C_MST_CTRL2, 2, 3),
[F_SCL_FREQ] = MST_REG_FIELD(RTL9300_I2C_MST_CTRL2, 0, 1),
[F_SDA_SEL] = GLB_REG_FIELD(RTL9300_I2C_MST_GLB_CTRL, 0, 7),
+ [F_BUSY] = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 0, 0),
},
.select_scl = rtl9300_i2c_select_scl,
.rd_reg = RTL9300_I2C_MST_DATA_WORD0,
@@ -515,6 +517,7 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
[F_I2C_FAIL] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 1, 1),
[F_I2C_TRIG] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 0, 0),
[F_MEM_ADDR] = MST_REG_FIELD(RTL9310_I2C_MST_MEMADDR_CTRL, 0, 23),
+ [F_BUSY] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 0, 0),
},
.select_scl = rtl9310_i2c_select_scl,
.rd_reg = RTL9310_I2C_MST_DATA_CTRL,
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
` (2 preceding siblings ...)
2026-03-14 8:26 ` [PATCH 3/8] i2c: rtl9300: introduce F_BUSY to the reg_fields struct Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-15 21:26 ` Chris Packham
2026-03-15 21:31 ` Chris Packham
2026-03-14 8:26 ` [PATCH 5/8] i2c: rtl9300: introduce clk struct for upcoming rtl9607 support Rustam Adilov
` (4 subsequent siblings)
8 siblings, 2 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
In RTL9607C i2c controller, in order to indicate that the width of
memory address is 8 bits, 0 is written to MEM_ADDR_WIDTH field as
opposed to 1 for RTL9300 and RTL9310.
Introduce a new property to a driver data to indicate what value
need to written to MEM_ADDR_WIDTH field for this case.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
drivers/i2c/busses/i2c-rtl9300.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 2525b57a9d03..86a82f2c3ce0 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -60,6 +60,7 @@ struct rtl9300_i2c_drv_data {
u32 wd_reg;
u8 max_nchan;
u8 max_data_len;
+ u8 reg_addr_8bit_len;
};
#define RTL9300_I2C_MUX_NCHAN 8
@@ -105,6 +106,7 @@ struct rtl9300_i2c_xfer {
#define RTL9300_I2C_MST_DATA_WORD2 0x10
#define RTL9300_I2C_MST_DATA_WORD3 0x14
#define RTL9300_I2C_MST_GLB_CTRL 0x384
+#define RTL9300_REG_ADDR_8BIT_LEN 1
#define RTL9310_I2C_MST_IF_CTRL 0x1004
#define RTL9310_I2C_MST_IF_SEL 0x1008
@@ -299,6 +301,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
union i2c_smbus_data *data)
{
struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap);
+ const struct rtl9300_i2c_drv_data *drv_data;
struct rtl9300_i2c *i2c = chan->i2c;
struct rtl9300_i2c_xfer xfer = {0};
int ret;
@@ -308,6 +311,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
guard(rtl9300_i2c)(i2c);
+ drv_data = device_get_match_data(i2c->dev);
ret = rtl9300_i2c_config_chan(i2c, chan);
if (ret)
return ret;
@@ -315,7 +319,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
xfer.dev_addr = addr & 0x7f;
xfer.write = (read_write == I2C_SMBUS_WRITE);
xfer.reg_addr = command;
- xfer.reg_addr_len = 1;
+ xfer.reg_addr_len = drv_data->reg_addr_8bit_len;
switch (size) {
case I2C_SMBUS_BYTE:
@@ -501,6 +505,7 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
.wd_reg = RTL9300_I2C_MST_DATA_WORD0,
.max_nchan = RTL9300_I2C_MUX_NCHAN,
.max_data_len = RTL9300_I2C_MAX_DATA_LEN,
+ .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
};
static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
@@ -524,6 +529,7 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
.wd_reg = RTL9310_I2C_MST_DATA_CTRL,
.max_nchan = RTL9310_I2C_MUX_NCHAN,
.max_data_len = RTL9300_I2C_MAX_DATA_LEN,
+ .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
};
static const struct of_device_id i2c_rtl9300_dt_ids[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 5/8] i2c: rtl9300: introduce clk struct for upcoming rtl9607 support
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
` (3 preceding siblings ...)
2026-03-14 8:26 ` [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-14 8:26 ` [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data Rustam Adilov
` (3 subsequent siblings)
8 siblings, 0 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
In RTL9607C i2c controller, there is 10 bit CLK_DIV field for
setting the clock of i2c interface which depends on the rate
of i2c clk (which seems be fixed to 62.5MHz according to Realtek SDK).
Introduce the clk struct and the respective F_CLK_DIV and clk_div
which are going to be used in the upcoming patch for rtl9607c i2c
controller support addition.
devm_clk_get_optional_enabled() function was used for cleaner code
as it automatically returns NULL if the clk is not present, which is
going to be the case for RTL9300 and RTL9310 i2c controllers.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
drivers/i2c/busses/i2c-rtl9300.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 86a82f2c3ce0..4953223ec97c 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/bits.h>
+#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/mod_devicetable.h>
@@ -22,6 +23,7 @@ struct rtl9300_i2c_chan {
struct rtl9300_i2c *i2c;
enum rtl9300_bus_freq bus_freq;
u8 sda_num;
+ u32 clk_div;
};
enum rtl9300_i2c_reg_scope {
@@ -48,6 +50,7 @@ enum rtl9300_i2c_reg_fields {
F_SDA_OUT_SEL,
F_SDA_SEL,
F_BUSY,
+ F_CLK_DIV,
/* keep last */
F_NUM_FIELDS
@@ -79,6 +82,7 @@ struct rtl9300_i2c {
u8 scl_num;
u8 sda_num;
struct mutex lock;
+ struct clk *clk;
};
DEFINE_GUARD(rtl9300_i2c, struct rtl9300_i2c *, mutex_lock(&_T->lock), mutex_unlock(&_T->lock))
@@ -426,6 +430,10 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
if (ret)
return ret;
+ i2c->clk = devm_clk_get_optional_enabled(dev, NULL);
+ if (IS_ERR(i2c->clk))
+ return dev_err_probe(dev, PTR_ERR(i2c->clk), "Failed to enable i2c clock\n");
+
i = 0;
for_each_child_of_node_scoped(dev->of_node, child) {
struct rtl9300_i2c_chan *chan = &i2c->chans[i];
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
` (4 preceding siblings ...)
2026-03-14 8:26 ` [PATCH 5/8] i2c: rtl9300: introduce clk struct for upcoming rtl9607 support Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-15 21:36 ` Chris Packham
2026-03-14 8:26 ` [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support Rustam Adilov
` (2 subsequent siblings)
8 siblings, 1 reply; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
Due to the very nature of differences between RTL9607C i2c controller
and RTL9300 / RTL9310 that are incompatible with each other in some areas
of this driver, for example in clock configuration, channel configuration
and initialization at the end of the probe, introduce new function
properties to the driver data struct to handle those differences.
With these new properties, create configuration functions for RTL9300 and
RTL9310 and assign them to their respective driver data structs.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
drivers/i2c/busses/i2c-rtl9300.c | 54 ++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 16 deletions(-)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 4953223ec97c..7930f47a37b2 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -59,6 +59,9 @@ enum rtl9300_i2c_reg_fields {
struct rtl9300_i2c_drv_data {
struct rtl9300_i2c_reg_field field_desc[F_NUM_FIELDS];
int (*select_scl)(struct rtl9300_i2c *i2c, u8 scl);
+ int (*config_chan)(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan);
+ void (*config_clock)(u32 clock_freq, struct rtl9300_i2c_chan *chan);
+ int (*misc_init)(struct rtl9300_i2c *i2c);
u32 rd_reg;
u32 wd_reg;
u8 max_nchan;
@@ -169,6 +172,24 @@ static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_c
return 0;
}
+static void rtl9300_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *chan)
+{
+ struct rtl9300_i2c *i2c = chan->i2c;
+
+ switch (clock_freq) {
+ case I2C_MAX_STANDARD_MODE_FREQ:
+ chan->bus_freq = RTL9300_I2C_STD_FREQ;
+ break;
+ case I2C_MAX_FAST_MODE_FREQ:
+ chan->bus_freq = RTL9300_I2C_FAST_FREQ;
+ break;
+ default:
+ dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
+ chan->sda_num, clock_freq);
+ break;
+ }
+}
+
static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
{
u32 vals[4] = {};
@@ -316,7 +337,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
guard(rtl9300_i2c)(i2c);
drv_data = device_get_match_data(i2c->dev);
- ret = rtl9300_i2c_config_chan(i2c, chan);
+ ret = drv_data->config_chan(i2c, chan);
if (ret)
return ret;
@@ -383,6 +404,12 @@ static struct i2c_adapter_quirks rtl9300_i2c_quirks = {
.max_write_len = 16,
};
+static int rtl9300_i2c_init(struct rtl9300_i2c *i2c)
+{
+ /* only use standard read format */
+ return regmap_field_write(i2c->fields[F_RD_MODE], 0);
+}
+
static int rtl9300_i2c_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -447,21 +474,11 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
if (ret)
clock_freq = I2C_MAX_STANDARD_MODE_FREQ;
- switch (clock_freq) {
- case I2C_MAX_STANDARD_MODE_FREQ:
- chan->bus_freq = RTL9300_I2C_STD_FREQ;
- break;
- case I2C_MAX_FAST_MODE_FREQ:
- chan->bus_freq = RTL9300_I2C_FAST_FREQ;
- break;
- default:
- dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
- sda_num, clock_freq);
- break;
- }
-
chan->sda_num = sda_num;
chan->i2c = i2c;
+
+ drv_data->config_clock(clock_freq, chan);
+
adap = &i2c->chans[i].adap;
adap->owner = THIS_MODULE;
adap->algo = &rtl9300_i2c_algo;
@@ -479,8 +496,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
}
i2c->sda_num = 0xff;
- /* only use standard read format */
- ret = regmap_field_write(i2c->fields[F_RD_MODE], 0);
+ ret = drv_data->misc_init(i2c);
if (ret)
return ret;
@@ -509,6 +525,9 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
[F_BUSY] = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 0, 0),
},
.select_scl = rtl9300_i2c_select_scl,
+ .config_chan = rtl9300_i2c_config_chan,
+ .config_clock = rtl9300_i2c_config_clock,
+ .misc_init = rtl9300_i2c_init,
.rd_reg = RTL9300_I2C_MST_DATA_WORD0,
.wd_reg = RTL9300_I2C_MST_DATA_WORD0,
.max_nchan = RTL9300_I2C_MUX_NCHAN,
@@ -533,6 +552,9 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
[F_BUSY] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 0, 0),
},
.select_scl = rtl9310_i2c_select_scl,
+ .config_chan = rtl9300_i2c_config_chan,
+ .config_clock = rtl9300_i2c_config_clock,
+ .misc_init = rtl9300_i2c_init,
.rd_reg = RTL9310_I2C_MST_DATA_CTRL,
.wd_reg = RTL9310_I2C_MST_DATA_CTRL,
.max_nchan = RTL9310_I2C_MUX_NCHAN,
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
` (5 preceding siblings ...)
2026-03-14 8:26 ` [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-15 8:56 ` Krzysztof Kozlowski
2026-03-14 8:26 ` [PATCH 8/8] i2c: rtl9300: add RTL9607C i2c controller support Rustam Adilov
2026-03-15 21:45 ` [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Chris Packham
8 siblings, 1 reply; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
Add the "realtek,rtl9607-i2c" compatible for i2c controller on the
RTL9607C SoC series.
Add a clocks property to the properties since RTL9607C requires it
along with the realtek,scl.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
.../bindings/i2c/realtek,rtl9301-i2c.yaml | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
index f9a449fee2b0..5873cfdc5b3e 100644
--- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
@@ -15,6 +15,8 @@ description:
assigned to either I2C controller.
RTL9310 SoCs have equal capabilities but support 12 common SDA lines which
can be assigned to either I2C controller.
+ RTL9607C SoCs have equal capabilities but each controller only supports 1
+ SCL/SDA line.
properties:
compatible:
@@ -34,6 +36,7 @@ properties:
- enum:
- realtek,rtl9301-i2c
- realtek,rtl9310-i2c
+ - realtek,rtl9607-i2c
reg:
items:
@@ -51,6 +54,9 @@ properties:
The SCL line number of this I2C controller.
enum: [ 0, 1 ]
+ clocks:
+ maxItems: 1
+
patternProperties:
'^i2c@[0-9ab]$':
$ref: /schemas/i2c/i2c-controller.yaml
@@ -81,6 +87,15 @@ allOf:
then:
patternProperties:
'^i2c@[89ab]$': false
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: realtek,rtl9607-i2c
+ then:
+ required:
+ - realtek,scl
+ - clocks
required:
- compatible
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 8/8] i2c: rtl9300: add RTL9607C i2c controller support
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
` (6 preceding siblings ...)
2026-03-14 8:26 ` [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support Rustam Adilov
@ 2026-03-14 8:26 ` Rustam Adilov
2026-03-15 21:45 ` [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Chris Packham
8 siblings, 0 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-14 8:26 UTC (permalink / raw)
To: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Cc: Rustam Adilov
Add support for the internal I2C controllers of RTL9607C series based
SoCs. Add register definitions, chip-specific functions and macros too.
Make use of the clk introduced from the previous patch to get the clk_div
value and use it during the rtl9607c channel configuration.
Introduce a new EXT_SCK_5MS field to the reg fields struct which is going
to be initialized by rtl9607c init function at the end of the probe.
This patch depends on all the previous patches in this patch series.
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
drivers/i2c/busses/i2c-rtl9300.c | 70 ++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
index 7930f47a37b2..4ea9e0bade19 100644
--- a/drivers/i2c/busses/i2c-rtl9300.c
+++ b/drivers/i2c/busses/i2c-rtl9300.c
@@ -51,6 +51,7 @@ enum rtl9300_i2c_reg_fields {
F_SDA_SEL,
F_BUSY,
F_CLK_DIV,
+ F_EXT_SCK_5MS,
/* keep last */
F_NUM_FIELDS
@@ -71,8 +72,10 @@ struct rtl9300_i2c_drv_data {
#define RTL9300_I2C_MUX_NCHAN 8
#define RTL9310_I2C_MUX_NCHAN 12
+#define RTL9607_I2C_MUX_NCHAN 1
#define RTL9300_I2C_MAX_DATA_LEN 16
+#define RTL9607_I2C_MAX_DATA_LEN 4
struct rtl9300_i2c {
struct regmap *regmap;
@@ -121,6 +124,14 @@ struct rtl9300_i2c_xfer {
#define RTL9310_I2C_MST_MEMADDR_CTRL 0x4
#define RTL9310_I2C_MST_DATA_CTRL 0x8
+#define RTL9607_I2C_CONFIG 0x22f50
+#define RTL9607_IO_MODE_EN 0x23014
+#define RTL9607_I2C_IND_WD 0x0
+#define RTL9607_I2C_IND_ADR 0x8
+#define RTL9607_I2C_IND_CMD 0x10
+#define RTL9607_I2C_IND_RD 0x18
+#define RTL9607_REG_ADDR_8BIT_LEN 0
+
static int rtl9300_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len)
{
int ret;
@@ -172,6 +183,27 @@ static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_c
return 0;
}
+static int rtl9607_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan)
+{
+ const struct rtl9300_i2c_drv_data *drv_data;
+ int ret;
+
+ if (i2c->sda_num == chan->sda_num)
+ return 0;
+
+ ret = regmap_field_write(i2c->fields[F_CLK_DIV], chan->clk_div);
+ if (ret)
+ return ret;
+
+ drv_data = device_get_match_data(i2c->dev);
+ ret = drv_data->select_scl(i2c, i2c->scl_num);
+ if (ret)
+ return ret;
+
+ i2c->sda_num = chan->sda_num;
+ return 0;
+}
+
static void rtl9300_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *chan)
{
struct rtl9300_i2c *i2c = chan->i2c;
@@ -190,6 +222,13 @@ static void rtl9300_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *ch
}
}
+static void rtl9607_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *chan)
+{
+ struct rtl9300_i2c *i2c = chan->i2c;
+
+ chan->clk_div = clk_get_rate(i2c->clk) / clock_freq - 1;
+}
+
static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
{
u32 vals[4] = {};
@@ -410,6 +449,11 @@ static int rtl9300_i2c_init(struct rtl9300_i2c *i2c)
return regmap_field_write(i2c->fields[F_RD_MODE], 0);
}
+static int rtl9607_i2c_init(struct rtl9300_i2c *i2c)
+{
+ return regmap_field_write(i2c->fields[F_EXT_SCK_5MS], 1);
+}
+
static int rtl9300_i2c_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -562,6 +606,31 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
.reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
};
+static const struct rtl9300_i2c_drv_data rtl9607_i2c_drv_data = {
+ .field_desc = {
+ [F_SCL_SEL] = GLB_REG_FIELD(RTL9607_IO_MODE_EN, 13, 14),
+ [F_EXT_SCK_5MS] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 26, 26),
+ [F_DEV_ADDR] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 14, 20),
+ [F_MEM_ADDR_WIDTH] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 12, 13),
+ [F_DATA_WIDTH] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 10, 11),
+ [F_CLK_DIV] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 0, 9),
+ [F_I2C_FAIL] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 3, 3),
+ [F_BUSY] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 2, 2),
+ [F_RWOP] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 1, 1),
+ [F_I2C_TRIG] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 0, 0),
+ [F_MEM_ADDR] = MST_REG_FIELD(RTL9607_I2C_IND_ADR, 0, 31),
+ },
+ .select_scl = rtl9310_i2c_select_scl,
+ .config_chan = rtl9607_i2c_config_chan,
+ .config_clock = rtl9607_i2c_config_clock,
+ .misc_init = rtl9607_i2c_init,
+ .rd_reg = RTL9607_I2C_IND_RD,
+ .wd_reg = RTL9607_I2C_IND_WD,
+ .max_nchan = RTL9607_I2C_MUX_NCHAN,
+ .max_data_len = RTL9607_I2C_MAX_DATA_LEN,
+ .reg_addr_8bit_len = RTL9607_REG_ADDR_8BIT_LEN,
+};
+
static const struct of_device_id i2c_rtl9300_dt_ids[] = {
{ .compatible = "realtek,rtl9301-i2c", .data = (void *) &rtl9300_i2c_drv_data },
{ .compatible = "realtek,rtl9302b-i2c", .data = (void *) &rtl9300_i2c_drv_data },
@@ -571,6 +640,7 @@ static const struct of_device_id i2c_rtl9300_dt_ids[] = {
{ .compatible = "realtek,rtl9311-i2c", .data = (void *) &rtl9310_i2c_drv_data },
{ .compatible = "realtek,rtl9312-i2c", .data = (void *) &rtl9310_i2c_drv_data },
{ .compatible = "realtek,rtl9313-i2c", .data = (void *) &rtl9310_i2c_drv_data },
+ { .compatible = "realtek,rtl9607-i2c", .data = (void *) &rtl9607_i2c_drv_data },
{}
};
MODULE_DEVICE_TABLE(of, i2c_rtl9300_dt_ids);
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support
2026-03-14 8:26 ` [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support Rustam Adilov
@ 2026-03-15 8:56 ` Krzysztof Kozlowski
2026-03-15 10:10 ` Rustam Adilov
0 siblings, 1 reply; 20+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-15 8:56 UTC (permalink / raw)
To: Rustam Adilov
Cc: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
On Sat, Mar 14, 2026 at 01:26:27PM +0500, Rustam Adilov wrote:
> Add the "realtek,rtl9607-i2c" compatible for i2c controller on the
> RTL9607C SoC series.
>
> Add a clocks property to the properties since RTL9607C requires it
> along with the realtek,scl.
>
> Signed-off-by: Rustam Adilov <adilov@disroot.org>
> ---
> .../bindings/i2c/realtek,rtl9301-i2c.yaml | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
> index f9a449fee2b0..5873cfdc5b3e 100644
> --- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
> +++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
> @@ -15,6 +15,8 @@ description:
> assigned to either I2C controller.
> RTL9310 SoCs have equal capabilities but support 12 common SDA lines which
> can be assigned to either I2C controller.
> + RTL9607C SoCs have equal capabilities but each controller only supports 1
> + SCL/SDA line.
>
> properties:
> compatible:
> @@ -34,6 +36,7 @@ properties:
> - enum:
> - realtek,rtl9301-i2c
> - realtek,rtl9310-i2c
> + - realtek,rtl9607-i2c
>
> reg:
> items:
> @@ -51,6 +54,9 @@ properties:
> The SCL line number of this I2C controller.
> enum: [ 0, 1 ]
>
> + clocks:
> + maxItems: 1
> +
> patternProperties:
> '^i2c@[0-9ab]$':
> $ref: /schemas/i2c/i2c-controller.yaml
> @@ -81,6 +87,15 @@ allOf:
> then:
> patternProperties:
> '^i2c@[89ab]$': false
Other devices do not have any clock input? Hard to believe, but if that
was the case then previous "if:then:" should disallow this. But if you
assume they have clock, which is expected, then document this in the
commit msg. Now you just silently add clock to each of existing variant
without any explanation WHY.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support
2026-03-15 8:56 ` Krzysztof Kozlowski
@ 2026-03-15 10:10 ` Rustam Adilov
2026-03-15 10:15 ` Krzysztof Kozlowski
0 siblings, 1 reply; 20+ messages in thread
From: Rustam Adilov @ 2026-03-15 10:10 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
Hello,
On 2026-03-15 08:56, Krzysztof Kozlowski wrote:
> On Sat, Mar 14, 2026 at 01:26:27PM +0500, Rustam Adilov wrote:
>> Add the "realtek,rtl9607-i2c" compatible for i2c controller on the
>> RTL9607C SoC series.
>>
>> Add a clocks property to the properties since RTL9607C requires it
>> along with the realtek,scl.
>>
>> Signed-off-by: Rustam Adilov <adilov@disroot.org>
>> ---
>> .../bindings/i2c/realtek,rtl9301-i2c.yaml | 15 +++++++++++++++
>> 1 file changed, 15 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>> index f9a449fee2b0..5873cfdc5b3e 100644
>> --- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>> +++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>> @@ -15,6 +15,8 @@ description:
>> assigned to either I2C controller.
>> RTL9310 SoCs have equal capabilities but support 12 common SDA lines which
>> can be assigned to either I2C controller.
>> + RTL9607C SoCs have equal capabilities but each controller only supports 1
>> + SCL/SDA line.
>>
>> properties:
>> compatible:
>> @@ -34,6 +36,7 @@ properties:
>> - enum:
>> - realtek,rtl9301-i2c
>> - realtek,rtl9310-i2c
>> + - realtek,rtl9607-i2c
>>
>> reg:
>> items:
>> @@ -51,6 +54,9 @@ properties:
>> The SCL line number of this I2C controller.
>> enum: [ 0, 1 ]
>>
>> + clocks:
>> + maxItems: 1
>> +
>> patternProperties:
>> '^i2c@[0-9ab]$':
>> $ref: /schemas/i2c/i2c-controller.yaml
>> @@ -81,6 +87,15 @@ allOf:
>> then:
>> patternProperties:
>> '^i2c@[89ab]$': false
>
> Other devices do not have any clock input? Hard to believe, but if that
> was the case then previous "if:then:" should disallow this. But if you
> assume they have clock, which is expected, then document this in the
> commit msg. Now you just silently add clock to each of existing variant
> without any explanation WHY.
As far as i can tell, that does seem to be the case that they don't need the
clocks input. In RTL9300 and RL9310 there is a simple SCL_FREQ bit field that
sets the frequency from preselected option (100khz, 400kHz, 2.5MHz and 50kHz) and
it is gotten straight from the clock-frequency of the i2c child nodes.
But in RTL9607C there is CLK_DIV bit field instead and it is set to the calculated
value of "clk_get_rate(i2c->clk) / i2c->bus_freq - 1" and that is why it requires
clocks.
With this, what should be changed in this i2c bindings file? I was under assumption
that even if only RTL9607 requires the clocks i would still need to add it to the
properties along with the "if:then:" but if not then i can remove it.
>
> Best regards,
> Krzysztof
Best,
Rustam
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support
2026-03-15 10:10 ` Rustam Adilov
@ 2026-03-15 10:15 ` Krzysztof Kozlowski
2026-03-15 16:18 ` Rustam Adilov
0 siblings, 1 reply; 20+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-15 10:15 UTC (permalink / raw)
To: Rustam Adilov
Cc: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel
On 15/03/2026 11:10, Rustam Adilov wrote:
> Hello,
>
> On 2026-03-15 08:56, Krzysztof Kozlowski wrote:
>> On Sat, Mar 14, 2026 at 01:26:27PM +0500, Rustam Adilov wrote:
>>> Add the "realtek,rtl9607-i2c" compatible for i2c controller on the
>>> RTL9607C SoC series.
>>>
>>> Add a clocks property to the properties since RTL9607C requires it
>>> along with the realtek,scl.
>>>
>>> Signed-off-by: Rustam Adilov <adilov@disroot.org>
>>> ---
>>> .../bindings/i2c/realtek,rtl9301-i2c.yaml | 15 +++++++++++++++
>>> 1 file changed, 15 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>>> index f9a449fee2b0..5873cfdc5b3e 100644
>>> --- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>>> +++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>>> @@ -15,6 +15,8 @@ description:
>>> assigned to either I2C controller.
>>> RTL9310 SoCs have equal capabilities but support 12 common SDA lines which
>>> can be assigned to either I2C controller.
>>> + RTL9607C SoCs have equal capabilities but each controller only supports 1
>>> + SCL/SDA line.
>>>
>>> properties:
>>> compatible:
>>> @@ -34,6 +36,7 @@ properties:
>>> - enum:
>>> - realtek,rtl9301-i2c
>>> - realtek,rtl9310-i2c
>>> + - realtek,rtl9607-i2c
>>>
>>> reg:
>>> items:
>>> @@ -51,6 +54,9 @@ properties:
>>> The SCL line number of this I2C controller.
>>> enum: [ 0, 1 ]
>>>
>>> + clocks:
>>> + maxItems: 1
>>> +
>>> patternProperties:
>>> '^i2c@[0-9ab]$':
>>> $ref: /schemas/i2c/i2c-controller.yaml
>>> @@ -81,6 +87,15 @@ allOf:
>>> then:
>>> patternProperties:
>>> '^i2c@[89ab]$': false
>>
>> Other devices do not have any clock input? Hard to believe, but if that
>> was the case then previous "if:then:" should disallow this. But if you
>> assume they have clock, which is expected, then document this in the
>> commit msg. Now you just silently add clock to each of existing variant
>> without any explanation WHY.
>
> As far as i can tell, that does seem to be the case that they don't need the
> clocks input. In RTL9300 and RL9310 there is a simple SCL_FREQ bit field that
> sets the frequency from preselected option (100khz, 400kHz, 2.5MHz and 50kHz) and
> it is gotten straight from the clock-frequency of the i2c child nodes.
And from where does this clock gets its frequency? Really SoC IP block
not having clock input would mean it is not part of the SoC, because it
would have completely independent clock domain.
> But in RTL9607C there is CLK_DIV bit field instead and it is set to the calculated
> value of "clk_get_rate(i2c->clk) / i2c->bus_freq - 1" and that is why it requires
> clocks.
>
> With this, what should be changed in this i2c bindings file? I was under assumption
If devices *do not have* clock, you set it as false (see example schema
and even line above!). Clue here is what I wrote "devices" and "do not
have".
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support
2026-03-15 10:15 ` Krzysztof Kozlowski
@ 2026-03-15 16:18 ` Rustam Adilov
0 siblings, 0 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-15 16:18 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Chris Packham, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c, devicetree, linux-kernel, Jonas Jelonek
On 2026-03-15 10:15, Krzysztof Kozlowski wrote:
> On 15/03/2026 11:10, Rustam Adilov wrote:
>> Hello,
>>
>> On 2026-03-15 08:56, Krzysztof Kozlowski wrote:
>>> On Sat, Mar 14, 2026 at 01:26:27PM +0500, Rustam Adilov wrote:
>>>> Add the "realtek,rtl9607-i2c" compatible for i2c controller on the
>>>> RTL9607C SoC series.
>>>>
>>>> Add a clocks property to the properties since RTL9607C requires it
>>>> along with the realtek,scl.
>>>>
>>>> Signed-off-by: Rustam Adilov <adilov@disroot.org>
>>>> ---
>>>> .../bindings/i2c/realtek,rtl9301-i2c.yaml | 15 +++++++++++++++
>>>> 1 file changed, 15 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>>>> index f9a449fee2b0..5873cfdc5b3e 100644
>>>> --- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>>>> +++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
>>>> @@ -15,6 +15,8 @@ description:
>>>> assigned to either I2C controller.
>>>> RTL9310 SoCs have equal capabilities but support 12 common SDA lines which
>>>> can be assigned to either I2C controller.
>>>> + RTL9607C SoCs have equal capabilities but each controller only supports 1
>>>> + SCL/SDA line.
>>>>
>>>> properties:
>>>> compatible:
>>>> @@ -34,6 +36,7 @@ properties:
>>>> - enum:
>>>> - realtek,rtl9301-i2c
>>>> - realtek,rtl9310-i2c
>>>> + - realtek,rtl9607-i2c
>>>>
>>>> reg:
>>>> items:
>>>> @@ -51,6 +54,9 @@ properties:
>>>> The SCL line number of this I2C controller.
>>>> enum: [ 0, 1 ]
>>>>
>>>> + clocks:
>>>> + maxItems: 1
>>>> +
>>>> patternProperties:
>>>> '^i2c@[0-9ab]$':
>>>> $ref: /schemas/i2c/i2c-controller.yaml
>>>> @@ -81,6 +87,15 @@ allOf:
>>>> then:
>>>> patternProperties:
>>>> '^i2c@[89ab]$': false
>>>
>>> Other devices do not have any clock input? Hard to believe, but if that
>>> was the case then previous "if:then:" should disallow this. But if you
>>> assume they have clock, which is expected, then document this in the
>>> commit msg. Now you just silently add clock to each of existing variant
>>> without any explanation WHY.
>>
>> As far as i can tell, that does seem to be the case that they don't need the
>> clocks input. In RTL9300 and RL9310 there is a simple SCL_FREQ bit field that
>> sets the frequency from preselected option (100khz, 400kHz, 2.5MHz and 50kHz) and
>> it is gotten straight from the clock-frequency of the i2c child nodes.
>
> And from where does this clock gets its frequency? Really SoC IP block
> not having clock input would mean it is not part of the SoC, because it
> would have completely independent clock domain.
I will have to leave this question to someone who knows it as i certainly don't know.
Maybe the driver maintainer has some knowledge on this.
>> But in RTL9607C there is CLK_DIV bit field instead and it is set to the calculated
>> value of "clk_get_rate(i2c->clk) / i2c->bus_freq - 1" and that is why it requires
>> clocks.
>>
>> With this, what should be changed in this i2c bindings file? I was under assumption
>
> If devices *do not have* clock, you set it as false (see example schema
> and even line above!). Clue here is what I wrote "devices" and "do not
> have".
I have read the example-schema file and from what i understand it i can put the
"else: properties: clocks: false" ?
So then, the whole would look like
- if:
properties:
compatible:
contains:
const: realtek,rtl9607-i2c
then:
required:
- realtek,scl
- clocks
else:
properties:
clocks: false
Let me know if my understanding of scheme is accurate cause i am very new to this.
Or should the "clocks: false" be under each other "if:" for rtl9300 and rtl9310
const compatibles?
> Best regards,
> Krzysztof
Best,
Rustam
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address
2026-03-14 8:26 ` [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address Rustam Adilov
@ 2026-03-15 21:26 ` Chris Packham
2026-03-15 21:31 ` Chris Packham
1 sibling, 0 replies; 20+ messages in thread
From: Chris Packham @ 2026-03-15 21:26 UTC (permalink / raw)
To: Rustam Adilov, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
On 14/03/2026 21:26, Rustam Adilov wrote:
> In RTL9607C i2c controller, in order to indicate that the width of
> memory address is 8 bits, 0 is written to MEM_ADDR_WIDTH field as
> opposed to 1 for RTL9300 and RTL9310.
>
> Introduce a new property to a driver data to indicate what value
> need to written to MEM_ADDR_WIDTH field for this case.
>
> Signed-off-by: Rustam Adilov <adilov@disroot.org>
> ---
> drivers/i2c/busses/i2c-rtl9300.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
> index 2525b57a9d03..86a82f2c3ce0 100644
> --- a/drivers/i2c/busses/i2c-rtl9300.c
> +++ b/drivers/i2c/busses/i2c-rtl9300.c
> @@ -60,6 +60,7 @@ struct rtl9300_i2c_drv_data {
> u32 wd_reg;
> u8 max_nchan;
> u8 max_data_len;
> + u8 reg_addr_8bit_len;
> };
>
> #define RTL9300_I2C_MUX_NCHAN 8
> @@ -105,6 +106,7 @@ struct rtl9300_i2c_xfer {
> #define RTL9300_I2C_MST_DATA_WORD2 0x10
> #define RTL9300_I2C_MST_DATA_WORD3 0x14
> #define RTL9300_I2C_MST_GLB_CTRL 0x384
> +#define RTL9300_REG_ADDR_8BIT_LEN 1
>
> #define RTL9310_I2C_MST_IF_CTRL 0x1004
> #define RTL9310_I2C_MST_IF_SEL 0x1008
> @@ -299,6 +301,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
> union i2c_smbus_data *data)
> {
> struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap);
> + const struct rtl9300_i2c_drv_data *drv_data;
> struct rtl9300_i2c *i2c = chan->i2c;
> struct rtl9300_i2c_xfer xfer = {0};
> int ret;
> @@ -308,6 +311,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>
> guard(rtl9300_i2c)(i2c);
>
> + drv_data = device_get_match_data(i2c->dev);
> ret = rtl9300_i2c_config_chan(i2c, chan);
> if (ret)
> return ret;
> @@ -315,7 +319,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
> xfer.dev_addr = addr & 0x7f;
> xfer.write = (read_write == I2C_SMBUS_WRITE);
> xfer.reg_addr = command;
> - xfer.reg_addr_len = 1;
> + xfer.reg_addr_len = drv_data->reg_addr_8bit_len;
>
> switch (size) {
> case I2C_SMBUS_BYTE:
> @@ -501,6 +505,7 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
> .wd_reg = RTL9300_I2C_MST_DATA_WORD0,
> .max_nchan = RTL9300_I2C_MUX_NCHAN,
> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
> };
>
> static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
> @@ -524,6 +529,7 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
> .wd_reg = RTL9310_I2C_MST_DATA_CTRL,
> .max_nchan = RTL9310_I2C_MUX_NCHAN,
> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
> };
>
> static const struct of_device_id i2c_rtl9300_dt_ids[] = {
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address
2026-03-14 8:26 ` [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address Rustam Adilov
2026-03-15 21:26 ` Chris Packham
@ 2026-03-15 21:31 ` Chris Packham
2026-03-16 16:28 ` Rustam Adilov
1 sibling, 1 reply; 20+ messages in thread
From: Chris Packham @ 2026-03-15 21:31 UTC (permalink / raw)
To: Rustam Adilov, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Hi Rustam,
(sorry I might have prematurely hit send on an earlier reply)
On 14/03/2026 21:26, Rustam Adilov wrote:
> In RTL9607C i2c controller, in order to indicate that the width of
> memory address is 8 bits, 0 is written to MEM_ADDR_WIDTH field as
> opposed to 1 for RTL9300 and RTL9310.
>
> Introduce a new property to a driver data to indicate what value
> need to written to MEM_ADDR_WIDTH field for this case.
>
> Signed-off-by: Rustam Adilov <adilov@disroot.org>
> ---
> drivers/i2c/busses/i2c-rtl9300.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
> index 2525b57a9d03..86a82f2c3ce0 100644
> --- a/drivers/i2c/busses/i2c-rtl9300.c
> +++ b/drivers/i2c/busses/i2c-rtl9300.c
> @@ -60,6 +60,7 @@ struct rtl9300_i2c_drv_data {
> u32 wd_reg;
> u8 max_nchan;
> u8 max_data_len;
> + u8 reg_addr_8bit_len;
> };
>
> #define RTL9300_I2C_MUX_NCHAN 8
> @@ -105,6 +106,7 @@ struct rtl9300_i2c_xfer {
> #define RTL9300_I2C_MST_DATA_WORD2 0x10
> #define RTL9300_I2C_MST_DATA_WORD3 0x14
> #define RTL9300_I2C_MST_GLB_CTRL 0x384
> +#define RTL9300_REG_ADDR_8BIT_LEN 1
>
> #define RTL9310_I2C_MST_IF_CTRL 0x1004
> #define RTL9310_I2C_MST_IF_SEL 0x1008
> @@ -299,6 +301,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
> union i2c_smbus_data *data)
> {
> struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap);
> + const struct rtl9300_i2c_drv_data *drv_data;
> struct rtl9300_i2c *i2c = chan->i2c;
> struct rtl9300_i2c_xfer xfer = {0};
> int ret;
> @@ -308,6 +311,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>
> guard(rtl9300_i2c)(i2c);
>
> + drv_data = device_get_match_data(i2c->dev);
> ret = rtl9300_i2c_config_chan(i2c, chan);
> if (ret)
> return ret;
> @@ -315,7 +319,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
> xfer.dev_addr = addr & 0x7f;
> xfer.write = (read_write == I2C_SMBUS_WRITE);
> xfer.reg_addr = command;
> - xfer.reg_addr_len = 1;
> + xfer.reg_addr_len = drv_data->reg_addr_8bit_len;
For this one I wonder if we could come up with something that involves a
subtraction for the rtl9607? len = 1 just makes sense to me so maybe
RTL_9300_ADDR_LEN(1) which expands to 1 - 0 on the rtl9300 and 1 - 1 on
the rtl9607 would be easier to follow.
Not a deal breaker just thought I'd mention it.
>
> switch (size) {
> case I2C_SMBUS_BYTE:
> @@ -501,6 +505,7 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
> .wd_reg = RTL9300_I2C_MST_DATA_WORD0,
> .max_nchan = RTL9300_I2C_MUX_NCHAN,
> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
> };
>
> static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
> @@ -524,6 +529,7 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
> .wd_reg = RTL9310_I2C_MST_DATA_CTRL,
> .max_nchan = RTL9310_I2C_MUX_NCHAN,
> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
> };
>
> static const struct of_device_id i2c_rtl9300_dt_ids[] = {
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data
2026-03-14 8:26 ` [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data Rustam Adilov
@ 2026-03-15 21:36 ` Chris Packham
2026-03-16 16:42 ` Rustam Adilov
0 siblings, 1 reply; 20+ messages in thread
From: Chris Packham @ 2026-03-15 21:36 UTC (permalink / raw)
To: Rustam Adilov, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
Jan Kantert
Hi Rustam,
On 14/03/2026 21:26, Rustam Adilov wrote:
> Due to the very nature of differences between RTL9607C i2c controller
> and RTL9300 / RTL9310 that are incompatible with each other in some areas
> of this driver, for example in clock configuration, channel configuration
> and initialization at the end of the probe, introduce new function
> properties to the driver data struct to handle those differences.
>
> With these new properties, create configuration functions for RTL9300 and
> RTL9310 and assign them to their respective driver data structs.
>
> Signed-off-by: Rustam Adilov <adilov@disroot.org>
> ---
> drivers/i2c/busses/i2c-rtl9300.c | 54 ++++++++++++++++++++++----------
> 1 file changed, 38 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
> index 4953223ec97c..7930f47a37b2 100644
> --- a/drivers/i2c/busses/i2c-rtl9300.c
> +++ b/drivers/i2c/busses/i2c-rtl9300.c
> @@ -59,6 +59,9 @@ enum rtl9300_i2c_reg_fields {
> struct rtl9300_i2c_drv_data {
> struct rtl9300_i2c_reg_field field_desc[F_NUM_FIELDS];
> int (*select_scl)(struct rtl9300_i2c *i2c, u8 scl);
> + int (*config_chan)(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan);
> + void (*config_clock)(u32 clock_freq, struct rtl9300_i2c_chan *chan);
> + int (*misc_init)(struct rtl9300_i2c *i2c);
> u32 rd_reg;
> u32 wd_reg;
> u8 max_nchan;
> @@ -169,6 +172,24 @@ static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_c
> return 0;
> }
>
> +static void rtl9300_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *chan)
> +{
> + struct rtl9300_i2c *i2c = chan->i2c;
> +
> + switch (clock_freq) {
> + case I2C_MAX_STANDARD_MODE_FREQ:
> + chan->bus_freq = RTL9300_I2C_STD_FREQ;
> + break;
> + case I2C_MAX_FAST_MODE_FREQ:
> + chan->bus_freq = RTL9300_I2C_FAST_FREQ;
> + break;
There was a series from Jan Kantert[1] (added to Cc) that added a few
more speeds as supported. Looks like maybe it got missed or perhaps you
need to rebase on a different tree.
> + default:
> + dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
> + chan->sda_num, clock_freq);
> + break;
> + }
> +}
> +
> static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
> {
> u32 vals[4] = {};
> @@ -316,7 +337,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
> guard(rtl9300_i2c)(i2c);
>
> drv_data = device_get_match_data(i2c->dev);
> - ret = rtl9300_i2c_config_chan(i2c, chan);
> + ret = drv_data->config_chan(i2c, chan);
> if (ret)
> return ret;
>
> @@ -383,6 +404,12 @@ static struct i2c_adapter_quirks rtl9300_i2c_quirks = {
> .max_write_len = 16,
> };
>
> +static int rtl9300_i2c_init(struct rtl9300_i2c *i2c)
> +{
> + /* only use standard read format */
> + return regmap_field_write(i2c->fields[F_RD_MODE], 0);
> +}
> +
> static int rtl9300_i2c_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> @@ -447,21 +474,11 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
> if (ret)
> clock_freq = I2C_MAX_STANDARD_MODE_FREQ;
>
> - switch (clock_freq) {
> - case I2C_MAX_STANDARD_MODE_FREQ:
> - chan->bus_freq = RTL9300_I2C_STD_FREQ;
> - break;
> - case I2C_MAX_FAST_MODE_FREQ:
> - chan->bus_freq = RTL9300_I2C_FAST_FREQ;
> - break;
> - default:
> - dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
> - sda_num, clock_freq);
> - break;
> - }
> -
> chan->sda_num = sda_num;
> chan->i2c = i2c;
> +
> + drv_data->config_clock(clock_freq, chan);
> +
> adap = &i2c->chans[i].adap;
> adap->owner = THIS_MODULE;
> adap->algo = &rtl9300_i2c_algo;
> @@ -479,8 +496,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
> }
> i2c->sda_num = 0xff;
>
> - /* only use standard read format */
> - ret = regmap_field_write(i2c->fields[F_RD_MODE], 0);
> + ret = drv_data->misc_init(i2c);
> if (ret)
> return ret;
>
> @@ -509,6 +525,9 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
> [F_BUSY] = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 0, 0),
> },
> .select_scl = rtl9300_i2c_select_scl,
> + .config_chan = rtl9300_i2c_config_chan,
> + .config_clock = rtl9300_i2c_config_clock,
> + .misc_init = rtl9300_i2c_init,
> .rd_reg = RTL9300_I2C_MST_DATA_WORD0,
> .wd_reg = RTL9300_I2C_MST_DATA_WORD0,
> .max_nchan = RTL9300_I2C_MUX_NCHAN,
> @@ -533,6 +552,9 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
> [F_BUSY] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 0, 0),
> },
> .select_scl = rtl9310_i2c_select_scl,
> + .config_chan = rtl9300_i2c_config_chan,
> + .config_clock = rtl9300_i2c_config_clock,
> + .misc_init = rtl9300_i2c_init,
> .rd_reg = RTL9310_I2C_MST_DATA_CTRL,
> .wd_reg = RTL9310_I2C_MST_DATA_CTRL,
> .max_nchan = RTL9310_I2C_MUX_NCHAN,
--
[1] -
https://lore.kernel.org/all/20260227111134.2163701-1-jan-kernel@kantert.net/
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
` (7 preceding siblings ...)
2026-03-14 8:26 ` [PATCH 8/8] i2c: rtl9300: add RTL9607C i2c controller support Rustam Adilov
@ 2026-03-15 21:45 ` Chris Packham
8 siblings, 0 replies; 20+ messages in thread
From: Chris Packham @ 2026-03-15 21:45 UTC (permalink / raw)
To: Rustam Adilov, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-i2c@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Hi Rustam,
On 14/03/2026 21:26, Rustam Adilov wrote:
> This patch series for the RTL9300 I2C driver adds i2c support for
> RTL9607C SoC. They are somewhat different to the RTL9300 and
> RTL9310 but not enough to warrant a new whole driver.
>
> The patch series was split into patches that add/change something in the
> driver to smooth out the RTL9607C support addition in the end and for
> ease of review. Because of that, the patch 8 depends on all the prior
> patches before it.
>
> RTL9607C primarly uses the i2c controller for communication with laser
> driver over on i2c interface 1 or 2.
>
> I have successfully tested the byte read operations on my RTL9607C board
> which has GN25L95 laser driver in OpenWrt.
>
> Rustam Adilov (8):
> i2c: rtl9300: split data_reg into read and write reg
> i2c: rtl9300: introduce max length property to driver data
> i2c: rtl9300: introduce F_BUSY to the reg_fields struct
> i2c: rtl9300: introduce a property for 8 bit width reg address
> i2c: rtl9300: introduce clk struct for upcoming rtl9607 support
> i2c: rtl9300: intoduce new function properties to driver data
> dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support
> i2c: rtl9300: add RTL9607C i2c controller support
Patches 1-5, 8
Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
There is a bit of a conflict with another topic that is either in-flight
or lost for patch 6 (I replied to that one specifically) and I see you
and Krzyztof are still discussion the dt-bindings changes.
>
> .../bindings/i2c/realtek,rtl9301-i2c.yaml | 15 ++
> drivers/i2c/busses/i2c-rtl9300.c | 179 +++++++++++++++---
> 2 files changed, 165 insertions(+), 29 deletions(-)
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address
2026-03-15 21:31 ` Chris Packham
@ 2026-03-16 16:28 ` Rustam Adilov
2026-03-16 20:24 ` Chris Packham
0 siblings, 1 reply; 20+ messages in thread
From: Rustam Adilov @ 2026-03-16 16:28 UTC (permalink / raw)
To: Chris Packham
Cc: Andi Shyti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-i2c, devicetree, linux-kernel
Hello,
On 2026-03-15 21:31, Chris Packham wrote:
> Hi Rustam,
>
> (sorry I might have prematurely hit send on an earlier reply)
>
> On 14/03/2026 21:26, Rustam Adilov wrote:
>> In RTL9607C i2c controller, in order to indicate that the width of
>> memory address is 8 bits, 0 is written to MEM_ADDR_WIDTH field as
>> opposed to 1 for RTL9300 and RTL9310.
>>
>> Introduce a new property to a driver data to indicate what value
>> need to written to MEM_ADDR_WIDTH field for this case.
>>
>> Signed-off-by: Rustam Adilov <adilov@disroot.org>
>> ---
>> drivers/i2c/busses/i2c-rtl9300.c | 8 +++++++-
>> 1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
>> index 2525b57a9d03..86a82f2c3ce0 100644
>> --- a/drivers/i2c/busses/i2c-rtl9300.c
>> +++ b/drivers/i2c/busses/i2c-rtl9300.c
>> @@ -60,6 +60,7 @@ struct rtl9300_i2c_drv_data {
>> u32 wd_reg;
>> u8 max_nchan;
>> u8 max_data_len;
>> + u8 reg_addr_8bit_len;
>> };
>>
>> #define RTL9300_I2C_MUX_NCHAN 8
>> @@ -105,6 +106,7 @@ struct rtl9300_i2c_xfer {
>> #define RTL9300_I2C_MST_DATA_WORD2 0x10
>> #define RTL9300_I2C_MST_DATA_WORD3 0x14
>> #define RTL9300_I2C_MST_GLB_CTRL 0x384
>> +#define RTL9300_REG_ADDR_8BIT_LEN 1
>>
>> #define RTL9310_I2C_MST_IF_CTRL 0x1004
>> #define RTL9310_I2C_MST_IF_SEL 0x1008
>> @@ -299,6 +301,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>> union i2c_smbus_data *data)
>> {
>> struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap);
>> + const struct rtl9300_i2c_drv_data *drv_data;
>> struct rtl9300_i2c *i2c = chan->i2c;
>> struct rtl9300_i2c_xfer xfer = {0};
>> int ret;
>> @@ -308,6 +311,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>>
>> guard(rtl9300_i2c)(i2c);
>>
>> + drv_data = device_get_match_data(i2c->dev);
>> ret = rtl9300_i2c_config_chan(i2c, chan);
>> if (ret)
>> return ret;
>> @@ -315,7 +319,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>> xfer.dev_addr = addr & 0x7f;
>> xfer.write = (read_write == I2C_SMBUS_WRITE);
>> xfer.reg_addr = command;
>> - xfer.reg_addr_len = 1;
>> + xfer.reg_addr_len = drv_data->reg_addr_8bit_len;
>
> For this one I wonder if we could come up with something that involves a
> subtraction for the rtl9607? len = 1 just makes sense to me so maybe
> RTL_9300_ADDR_LEN(1) which expands to 1 - 0 on the rtl9300 and 1 - 1 on
> the rtl9607 would be easier to follow.
I am not entirely sure i understand this approach. Is RTL_9300_ADDR_LEN(1)
gonna be a "#define"? Would like to know before i proceed with possible
changes for v2.
And wouldn't something like this work just as well:
xfer.reg_addr_len = 1 - drv_data->subtract_len;
But then, i honestly think "drv_data->reg_addr_8bit_len" would be a bit less
cluttery?
> Not a deal breaker just thought I'd mention it.
>
>>
>> switch (size) {
>> case I2C_SMBUS_BYTE:
>> @@ -501,6 +505,7 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
>> .wd_reg = RTL9300_I2C_MST_DATA_WORD0,
>> .max_nchan = RTL9300_I2C_MUX_NCHAN,
>> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
>> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
>> };
>>
>> static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
>> @@ -524,6 +529,7 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
>> .wd_reg = RTL9310_I2C_MST_DATA_CTRL,
>> .max_nchan = RTL9310_I2C_MUX_NCHAN,
>> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
>> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
>> };
>>
>> static const struct of_device_id i2c_rtl9300_dt_ids[] = {
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data
2026-03-15 21:36 ` Chris Packham
@ 2026-03-16 16:42 ` Rustam Adilov
0 siblings, 0 replies; 20+ messages in thread
From: Rustam Adilov @ 2026-03-16 16:42 UTC (permalink / raw)
To: Chris Packham
Cc: Andi Shyti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-i2c, devicetree, linux-kernel, Jan Kantert
On 2026-03-15 21:36, Chris Packham wrote:
> Hi Rustam,
>
> On 14/03/2026 21:26, Rustam Adilov wrote:
>> Due to the very nature of differences between RTL9607C i2c controller
>> and RTL9300 / RTL9310 that are incompatible with each other in some areas
>> of this driver, for example in clock configuration, channel configuration
>> and initialization at the end of the probe, introduce new function
>> properties to the driver data struct to handle those differences.
>>
>> With these new properties, create configuration functions for RTL9300 and
>> RTL9310 and assign them to their respective driver data structs.
>>
>> Signed-off-by: Rustam Adilov <adilov@disroot.org>
>> ---
>> drivers/i2c/busses/i2c-rtl9300.c | 54 ++++++++++++++++++++++----------
>> 1 file changed, 38 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
>> index 4953223ec97c..7930f47a37b2 100644
>> --- a/drivers/i2c/busses/i2c-rtl9300.c
>> +++ b/drivers/i2c/busses/i2c-rtl9300.c
>> @@ -59,6 +59,9 @@ enum rtl9300_i2c_reg_fields {
>> struct rtl9300_i2c_drv_data {
>> struct rtl9300_i2c_reg_field field_desc[F_NUM_FIELDS];
>> int (*select_scl)(struct rtl9300_i2c *i2c, u8 scl);
>> + int (*config_chan)(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan);
>> + void (*config_clock)(u32 clock_freq, struct rtl9300_i2c_chan *chan);
>> + int (*misc_init)(struct rtl9300_i2c *i2c);
>> u32 rd_reg;
>> u32 wd_reg;
>> u8 max_nchan;
>> @@ -169,6 +172,24 @@ static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_c
>> return 0;
>> }
>>
>> +static void rtl9300_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *chan)
>> +{
>> + struct rtl9300_i2c *i2c = chan->i2c;
>> +
>> + switch (clock_freq) {
>> + case I2C_MAX_STANDARD_MODE_FREQ:
>> + chan->bus_freq = RTL9300_I2C_STD_FREQ;
>> + break;
>> + case I2C_MAX_FAST_MODE_FREQ:
>> + chan->bus_freq = RTL9300_I2C_FAST_FREQ;
>> + break;
> There was a series from Jan Kantert[1] (added to Cc) that added a few
> more speeds as supported. Looks like maybe it got missed or perhaps you
> need to rebase on a different tree.
I did actually notice them when i wanted to add my patches to the OpenWrt cause Jan's patches
were merged there as pending. It shouldn't be hard to rebase my patches on top of them i think..
Will do that for v2 of this patch series.
>> + default:
>> + dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
>> + chan->sda_num, clock_freq);
>> + break;
>> + }
>> +}
>> +
>> static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
>> {
>> u32 vals[4] = {};
>> @@ -316,7 +337,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>> guard(rtl9300_i2c)(i2c);
>>
>> drv_data = device_get_match_data(i2c->dev);
>> - ret = rtl9300_i2c_config_chan(i2c, chan);
>> + ret = drv_data->config_chan(i2c, chan);
>> if (ret)
>> return ret;
>>
>> @@ -383,6 +404,12 @@ static struct i2c_adapter_quirks rtl9300_i2c_quirks = {
>> .max_write_len = 16,
>> };
>>
>> +static int rtl9300_i2c_init(struct rtl9300_i2c *i2c)
>> +{
>> + /* only use standard read format */
>> + return regmap_field_write(i2c->fields[F_RD_MODE], 0);
>> +}
>> +
>> static int rtl9300_i2c_probe(struct platform_device *pdev)
>> {
>> struct device *dev = &pdev->dev;
>> @@ -447,21 +474,11 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
>> if (ret)
>> clock_freq = I2C_MAX_STANDARD_MODE_FREQ;
>>
>> - switch (clock_freq) {
>> - case I2C_MAX_STANDARD_MODE_FREQ:
>> - chan->bus_freq = RTL9300_I2C_STD_FREQ;
>> - break;
>> - case I2C_MAX_FAST_MODE_FREQ:
>> - chan->bus_freq = RTL9300_I2C_FAST_FREQ;
>> - break;
>> - default:
>> - dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
>> - sda_num, clock_freq);
>> - break;
>> - }
>> -
>> chan->sda_num = sda_num;
>> chan->i2c = i2c;
>> +
>> + drv_data->config_clock(clock_freq, chan);
>> +
>> adap = &i2c->chans[i].adap;
>> adap->owner = THIS_MODULE;
>> adap->algo = &rtl9300_i2c_algo;
>> @@ -479,8 +496,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
>> }
>> i2c->sda_num = 0xff;
>>
>> - /* only use standard read format */
>> - ret = regmap_field_write(i2c->fields[F_RD_MODE], 0);
>> + ret = drv_data->misc_init(i2c);
>> if (ret)
>> return ret;
>>
>> @@ -509,6 +525,9 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
>> [F_BUSY] = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 0, 0),
>> },
>> .select_scl = rtl9300_i2c_select_scl,
>> + .config_chan = rtl9300_i2c_config_chan,
>> + .config_clock = rtl9300_i2c_config_clock,
>> + .misc_init = rtl9300_i2c_init,
>> .rd_reg = RTL9300_I2C_MST_DATA_WORD0,
>> .wd_reg = RTL9300_I2C_MST_DATA_WORD0,
>> .max_nchan = RTL9300_I2C_MUX_NCHAN,
>> @@ -533,6 +552,9 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
>> [F_BUSY] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 0, 0),
>> },
>> .select_scl = rtl9310_i2c_select_scl,
>> + .config_chan = rtl9300_i2c_config_chan,
>> + .config_clock = rtl9300_i2c_config_clock,
>> + .misc_init = rtl9300_i2c_init,
>> .rd_reg = RTL9310_I2C_MST_DATA_CTRL,
>> .wd_reg = RTL9310_I2C_MST_DATA_CTRL,
>> .max_nchan = RTL9310_I2C_MUX_NCHAN,
> --
> [1] -
> https://lore.kernel.org/all/20260227111134.2163701-1-jan-kernel@kantert.net/
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address
2026-03-16 16:28 ` Rustam Adilov
@ 2026-03-16 20:24 ` Chris Packham
0 siblings, 0 replies; 20+ messages in thread
From: Chris Packham @ 2026-03-16 20:24 UTC (permalink / raw)
To: Rustam Adilov
Cc: Andi Shyti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-i2c@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
On 17/03/2026 05:28, Rustam Adilov wrote:
> Hello,
> On 2026-03-15 21:31, Chris Packham wrote:
>> Hi Rustam,
>>
>> (sorry I might have prematurely hit send on an earlier reply)
>>
>> On 14/03/2026 21:26, Rustam Adilov wrote:
>>> In RTL9607C i2c controller, in order to indicate that the width of
>>> memory address is 8 bits, 0 is written to MEM_ADDR_WIDTH field as
>>> opposed to 1 for RTL9300 and RTL9310.
>>>
>>> Introduce a new property to a driver data to indicate what value
>>> need to written to MEM_ADDR_WIDTH field for this case.
>>>
>>> Signed-off-by: Rustam Adilov <adilov@disroot.org>
>>> ---
>>> drivers/i2c/busses/i2c-rtl9300.c | 8 +++++++-
>>> 1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c
>>> index 2525b57a9d03..86a82f2c3ce0 100644
>>> --- a/drivers/i2c/busses/i2c-rtl9300.c
>>> +++ b/drivers/i2c/busses/i2c-rtl9300.c
>>> @@ -60,6 +60,7 @@ struct rtl9300_i2c_drv_data {
>>> u32 wd_reg;
>>> u8 max_nchan;
>>> u8 max_data_len;
>>> + u8 reg_addr_8bit_len;
>>> };
>>>
>>> #define RTL9300_I2C_MUX_NCHAN 8
>>> @@ -105,6 +106,7 @@ struct rtl9300_i2c_xfer {
>>> #define RTL9300_I2C_MST_DATA_WORD2 0x10
>>> #define RTL9300_I2C_MST_DATA_WORD3 0x14
>>> #define RTL9300_I2C_MST_GLB_CTRL 0x384
>>> +#define RTL9300_REG_ADDR_8BIT_LEN 1
>>>
>>> #define RTL9310_I2C_MST_IF_CTRL 0x1004
>>> #define RTL9310_I2C_MST_IF_SEL 0x1008
>>> @@ -299,6 +301,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>>> union i2c_smbus_data *data)
>>> {
>>> struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap);
>>> + const struct rtl9300_i2c_drv_data *drv_data;
>>> struct rtl9300_i2c *i2c = chan->i2c;
>>> struct rtl9300_i2c_xfer xfer = {0};
>>> int ret;
>>> @@ -308,6 +311,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>>>
>>> guard(rtl9300_i2c)(i2c);
>>>
>>> + drv_data = device_get_match_data(i2c->dev);
>>> ret = rtl9300_i2c_config_chan(i2c, chan);
>>> if (ret)
>>> return ret;
>>> @@ -315,7 +319,7 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
>>> xfer.dev_addr = addr & 0x7f;
>>> xfer.write = (read_write == I2C_SMBUS_WRITE);
>>> xfer.reg_addr = command;
>>> - xfer.reg_addr_len = 1;
>>> + xfer.reg_addr_len = drv_data->reg_addr_8bit_len;
>> For this one I wonder if we could come up with something that involves a
>> subtraction for the rtl9607? len = 1 just makes sense to me so maybe
>> RTL_9300_ADDR_LEN(1) which expands to 1 - 0 on the rtl9300 and 1 - 1 on
>> the rtl9607 would be easier to follow.
> I am not entirely sure i understand this approach. Is RTL_9300_ADDR_LEN(1)
> gonna be a "#define"? Would like to know before i proceed with possible
> changes for v2.
I was thinking
#define RTL_9300_ADDR_LEN(n) ((n) - drv_data->subtract_len)
Or something like that (I couldn't think of a better macro name).
> And wouldn't something like this work just as well:
>
> xfer.reg_addr_len = 1 - drv_data->subtract_len;
>
> But then, i honestly think "drv_data->reg_addr_8bit_len" would be a bit less
> cluttery?
Probably a question of taste. I'm fine with keeping your original
reg_addr_8bit_len it was more a case of me thinking "how is the length
of an 8-bit command anything other than 1" but I know the answer is
"because realtek".
>> Not a deal breaker just thought I'd mention it.
>>
>>>
>>> switch (size) {
>>> case I2C_SMBUS_BYTE:
>>> @@ -501,6 +505,7 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
>>> .wd_reg = RTL9300_I2C_MST_DATA_WORD0,
>>> .max_nchan = RTL9300_I2C_MUX_NCHAN,
>>> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
>>> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
>>> };
>>>
>>> static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
>>> @@ -524,6 +529,7 @@ static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
>>> .wd_reg = RTL9310_I2C_MST_DATA_CTRL,
>>> .max_nchan = RTL9310_I2C_MUX_NCHAN,
>>> .max_data_len = RTL9300_I2C_MAX_DATA_LEN,
>>> + .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN,
>>> };
>>>
>>> static const struct of_device_id i2c_rtl9300_dt_ids[] = {
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2026-03-16 20:24 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-14 8:26 [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Rustam Adilov
2026-03-14 8:26 ` [PATCH 1/8] i2c: rtl9300: split data_reg into read and write reg Rustam Adilov
2026-03-14 8:26 ` [PATCH 2/8] i2c: rtl9300: introduce max length property to driver data Rustam Adilov
2026-03-14 8:26 ` [PATCH 3/8] i2c: rtl9300: introduce F_BUSY to the reg_fields struct Rustam Adilov
2026-03-14 8:26 ` [PATCH 4/8] i2c: rtl9300: introduce a property for 8 bit width reg address Rustam Adilov
2026-03-15 21:26 ` Chris Packham
2026-03-15 21:31 ` Chris Packham
2026-03-16 16:28 ` Rustam Adilov
2026-03-16 20:24 ` Chris Packham
2026-03-14 8:26 ` [PATCH 5/8] i2c: rtl9300: introduce clk struct for upcoming rtl9607 support Rustam Adilov
2026-03-14 8:26 ` [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data Rustam Adilov
2026-03-15 21:36 ` Chris Packham
2026-03-16 16:42 ` Rustam Adilov
2026-03-14 8:26 ` [PATCH 7/8] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9607C support Rustam Adilov
2026-03-15 8:56 ` Krzysztof Kozlowski
2026-03-15 10:10 ` Rustam Adilov
2026-03-15 10:15 ` Krzysztof Kozlowski
2026-03-15 16:18 ` Rustam Adilov
2026-03-14 8:26 ` [PATCH 8/8] i2c: rtl9300: add RTL9607C i2c controller support Rustam Adilov
2026-03-15 21:45 ` [PATCH 0/8] i2c: rtl9300: support for RTL9607C I2C controller Chris Packham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox