Skip to content

Commit 1e33137

Browse files
jonasjelonekAndi Shyti
authored andcommitted
i2c: rtl9300: add support for RTL9310 I2C controller
Add support for the internal I2C controllers of RTL9310 series based SoCs to the driver for RTL9300. Add register definitions, chip-specific functions and compatible strings for known RTL9310-based SoCs RTL9311, RTL9312 and RTL9313. Make use of a new device tree property 'realtek,scl' which needs to be specified in case both or only the second master is used. This is required due how the register layout changed in contrast to RTL9300, which has SCL selection in a global register instead of a master-specific one. Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com> Tested-by: Sven Eckelmann <sven@narfation.org> Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz> Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de> Signed-off-by: Andi Shyti <andi.shyti@kernel.org> Link: https://lore.kernel.org/r/20250927101931.71575-10-jelonek.jonas@gmail.com
1 parent 99fd09e commit 1e33137

1 file changed

Lines changed: 44 additions & 3 deletions

File tree

drivers/i2c/busses/i2c-rtl9300.c

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,16 @@ struct rtl9300_i2c_drv_data {
6060
};
6161

6262
#define RTL9300_I2C_MUX_NCHAN 8
63+
#define RTL9310_I2C_MUX_NCHAN 12
6364

6465
struct rtl9300_i2c {
6566
struct regmap *regmap;
6667
struct device *dev;
67-
struct rtl9300_i2c_chan chans[RTL9300_I2C_MUX_NCHAN];
68+
struct rtl9300_i2c_chan chans[RTL9310_I2C_MUX_NCHAN];
6869
struct regmap_field *fields[F_NUM_FIELDS];
6970
u32 reg_base;
7071
u32 data_reg;
72+
u8 scl_num;
7173
u8 sda_num;
7274
struct mutex lock;
7375
};
@@ -98,6 +100,12 @@ struct rtl9300_i2c_xfer {
98100
#define RTL9300_I2C_MST_DATA_WORD3 0x14
99101
#define RTL9300_I2C_MST_GLB_CTRL 0x384
100102

103+
#define RTL9310_I2C_MST_IF_CTRL 0x1004
104+
#define RTL9310_I2C_MST_IF_SEL 0x1008
105+
#define RTL9310_I2C_MST_CTRL 0x0
106+
#define RTL9310_I2C_MST_MEMADDR_CTRL 0x4
107+
#define RTL9310_I2C_MST_DATA_CTRL 0x8
108+
101109
static int rtl9300_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len)
102110
{
103111
int ret;
@@ -114,6 +122,11 @@ static int rtl9300_i2c_select_scl(struct rtl9300_i2c *i2c, u8 scl)
114122
return regmap_field_write(i2c->fields[F_SCL_SEL], 1);
115123
}
116124

125+
static int rtl9310_i2c_select_scl(struct rtl9300_i2c *i2c, u8 scl)
126+
{
127+
return regmap_field_update_bits(i2c->fields[F_SCL_SEL], BIT(scl), BIT(scl));
128+
}
129+
117130
static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan)
118131
{
119132
struct rtl9300_i2c_drv_data *drv_data;
@@ -127,7 +140,7 @@ static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_c
127140
return ret;
128141

129142
drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
130-
ret = drv_data->select_scl(i2c, 0);
143+
ret = drv_data->select_scl(i2c, i2c->scl_num);
131144
if (ret)
132145
return ret;
133146

@@ -361,7 +374,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
361374
struct fwnode_handle *child;
362375
struct rtl9300_i2c_drv_data *drv_data;
363376
struct reg_field fields[F_NUM_FIELDS];
364-
u32 clock_freq, sda_num;
377+
u32 clock_freq, scl_num, sda_num;
365378
int ret, i = 0;
366379

367380
i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
@@ -379,6 +392,11 @@ static int rtl9300_i2c_probe(struct platform_device *pdev)
379392
if (ret)
380393
return ret;
381394

395+
ret = device_property_read_u32(dev, "realtek,scl", &scl_num);
396+
if (ret || scl_num != 1)
397+
scl_num = 0;
398+
i2c->scl_num = (u8)scl_num;
399+
382400
platform_set_drvdata(pdev, i2c);
383401

384402
drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
@@ -474,12 +492,35 @@ static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
474492
.max_nchan = RTL9300_I2C_MUX_NCHAN,
475493
};
476494

495+
static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
496+
.field_desc = {
497+
[F_SCL_SEL] = GLB_REG_FIELD(RTL9310_I2C_MST_IF_SEL, 12, 13),
498+
[F_SDA_SEL] = GLB_REG_FIELD(RTL9310_I2C_MST_IF_SEL, 0, 11),
499+
[F_SCL_FREQ] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 30, 31),
500+
[F_DEV_ADDR] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 11, 17),
501+
[F_SDA_OUT_SEL] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 18, 21),
502+
[F_MEM_ADDR_WIDTH] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 9, 10),
503+
[F_DATA_WIDTH] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 5, 8),
504+
[F_RD_MODE] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 4, 4),
505+
[F_RWOP] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 2, 2),
506+
[F_I2C_FAIL] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 1, 1),
507+
[F_I2C_TRIG] = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 0, 0),
508+
[F_MEM_ADDR] = MST_REG_FIELD(RTL9310_I2C_MST_MEMADDR_CTRL, 0, 23),
509+
},
510+
.select_scl = rtl9310_i2c_select_scl,
511+
.data_reg = RTL9310_I2C_MST_DATA_CTRL,
512+
.max_nchan = RTL9310_I2C_MUX_NCHAN,
513+
};
477514

478515
static const struct of_device_id i2c_rtl9300_dt_ids[] = {
479516
{ .compatible = "realtek,rtl9301-i2c", .data = (void *) &rtl9300_i2c_drv_data },
480517
{ .compatible = "realtek,rtl9302b-i2c", .data = (void *) &rtl9300_i2c_drv_data },
481518
{ .compatible = "realtek,rtl9302c-i2c", .data = (void *) &rtl9300_i2c_drv_data },
482519
{ .compatible = "realtek,rtl9303-i2c", .data = (void *) &rtl9300_i2c_drv_data },
520+
{ .compatible = "realtek,rtl9310-i2c", .data = (void *) &rtl9310_i2c_drv_data },
521+
{ .compatible = "realtek,rtl9311-i2c", .data = (void *) &rtl9310_i2c_drv_data },
522+
{ .compatible = "realtek,rtl9312-i2c", .data = (void *) &rtl9310_i2c_drv_data },
523+
{ .compatible = "realtek,rtl9313-i2c", .data = (void *) &rtl9310_i2c_drv_data },
483524
{}
484525
};
485526
MODULE_DEVICE_TABLE(of, i2c_rtl9300_dt_ids);

0 commit comments

Comments
 (0)