Re: [PATCH 6/8] i2c: rtl9300: intoduce new function properties to driver data
From: Rustam Adilov
Date: Mon Mar 16 2026 - 12:42:32 EST
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@xxxxxxxxxxx>
>> ---
>> 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@xxxxxxxxxxx/