Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

i2c: rtl9300: add RTL9607C i2c controller support

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>
Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260401180648.337834-9-adilov@disroot.org

authored by

Rustam Adilov and committed by
Andi Shyti
40890b5f 991cd899

+70
+70
drivers/i2c/busses/i2c-rtl9300.c
··· 57 57 F_SDA_SEL, 58 58 F_BUSY, 59 59 F_CLK_DIV, 60 + F_EXT_SCK_5MS, 60 61 61 62 /* keep last */ 62 63 F_NUM_FIELDS ··· 78 77 79 78 #define RTL9300_I2C_MUX_NCHAN 8 80 79 #define RTL9310_I2C_MUX_NCHAN 12 80 + #define RTL9607_I2C_MUX_NCHAN 1 81 81 82 82 #define RTL9300_I2C_MAX_DATA_LEN 16 83 + #define RTL9607_I2C_MAX_DATA_LEN 4 83 84 84 85 struct rtl9300_i2c { 85 86 struct regmap *regmap; ··· 129 126 #define RTL9310_I2C_MST_CTRL 0x0 130 127 #define RTL9310_I2C_MST_MEMADDR_CTRL 0x4 131 128 #define RTL9310_I2C_MST_DATA_CTRL 0x8 129 + 130 + #define RTL9607_I2C_CONFIG 0x22f50 131 + #define RTL9607_IO_MODE_EN 0x23014 132 + #define RTL9607_I2C_IND_WD 0x0 133 + #define RTL9607_I2C_IND_ADR 0x8 134 + #define RTL9607_I2C_IND_CMD 0x10 135 + #define RTL9607_I2C_IND_RD 0x18 136 + #define RTL9607_REG_ADDR_8BIT_LEN 0 132 137 133 138 static int rtl9300_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len) 134 139 { ··· 189 178 return 0; 190 179 } 191 180 181 + static int rtl9607_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan) 182 + { 183 + const struct rtl9300_i2c_drv_data *drv_data; 184 + int ret; 185 + 186 + if (i2c->sda_num == chan->sda_num) 187 + return 0; 188 + 189 + ret = regmap_field_write(i2c->fields[F_CLK_DIV], chan->clk_div); 190 + if (ret) 191 + return ret; 192 + 193 + drv_data = device_get_match_data(i2c->dev); 194 + ret = drv_data->select_scl(i2c, i2c->scl_num); 195 + if (ret) 196 + return ret; 197 + 198 + i2c->sda_num = chan->sda_num; 199 + return 0; 200 + } 201 + 192 202 static void rtl9300_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *chan) 193 203 { 194 204 struct rtl9300_i2c *i2c = chan->i2c; ··· 232 200 chan->sda_num, clock_freq); 233 201 break; 234 202 } 203 + } 204 + 205 + static void rtl9607_i2c_config_clock(u32 clock_freq, struct rtl9300_i2c_chan *chan) 206 + { 207 + struct rtl9300_i2c *i2c = chan->i2c; 208 + 209 + chan->clk_div = clk_get_rate(i2c->clk) / clock_freq - 1; 235 210 } 236 211 237 212 static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, u8 len) ··· 461 422 return regmap_field_write(i2c->fields[F_RD_MODE], 0); 462 423 } 463 424 425 + static int rtl9607_i2c_init(struct rtl9300_i2c *i2c) 426 + { 427 + return regmap_field_write(i2c->fields[F_EXT_SCK_5MS], 1); 428 + } 429 + 464 430 static int rtl9300_i2c_probe(struct platform_device *pdev) 465 431 { 466 432 struct device *dev = &pdev->dev; ··· 618 574 .reg_addr_8bit_len = RTL9300_REG_ADDR_8BIT_LEN, 619 575 }; 620 576 577 + static const struct rtl9300_i2c_drv_data rtl9607_i2c_drv_data = { 578 + .field_desc = { 579 + [F_SCL_SEL] = GLB_REG_FIELD(RTL9607_IO_MODE_EN, 13, 14), 580 + [F_EXT_SCK_5MS] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 26, 26), 581 + [F_DEV_ADDR] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 14, 20), 582 + [F_MEM_ADDR_WIDTH] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 12, 13), 583 + [F_DATA_WIDTH] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 10, 11), 584 + [F_CLK_DIV] = MST_REG_FIELD(RTL9607_I2C_CONFIG, 0, 9), 585 + [F_I2C_FAIL] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 3, 3), 586 + [F_BUSY] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 2, 2), 587 + [F_RWOP] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 1, 1), 588 + [F_I2C_TRIG] = MST_REG_FIELD(RTL9607_I2C_IND_CMD, 0, 0), 589 + [F_MEM_ADDR] = MST_REG_FIELD(RTL9607_I2C_IND_ADR, 0, 31), 590 + }, 591 + .select_scl = rtl9310_i2c_select_scl, 592 + .config_chan = rtl9607_i2c_config_chan, 593 + .config_clock = rtl9607_i2c_config_clock, 594 + .misc_init = rtl9607_i2c_init, 595 + .rd_reg = RTL9607_I2C_IND_RD, 596 + .wd_reg = RTL9607_I2C_IND_WD, 597 + .max_nchan = RTL9607_I2C_MUX_NCHAN, 598 + .max_data_len = RTL9607_I2C_MAX_DATA_LEN, 599 + .reg_addr_8bit_len = RTL9607_REG_ADDR_8BIT_LEN, 600 + }; 601 + 621 602 static const struct of_device_id i2c_rtl9300_dt_ids[] = { 622 603 { .compatible = "realtek,rtl9301-i2c", .data = (void *) &rtl9300_i2c_drv_data }, 623 604 { .compatible = "realtek,rtl9302b-i2c", .data = (void *) &rtl9300_i2c_drv_data }, ··· 652 583 { .compatible = "realtek,rtl9311-i2c", .data = (void *) &rtl9310_i2c_drv_data }, 653 584 { .compatible = "realtek,rtl9312-i2c", .data = (void *) &rtl9310_i2c_drv_data }, 654 585 { .compatible = "realtek,rtl9313-i2c", .data = (void *) &rtl9310_i2c_drv_data }, 586 + { .compatible = "realtek,rtl9607-i2c", .data = (void *) &rtl9607_i2c_drv_data }, 655 587 {} 656 588 }; 657 589 MODULE_DEVICE_TABLE(of, i2c_rtl9300_dt_ids);