[PATCH] dt-bindings: i2c: Add device clock-stretch time via dts
From: Qii Wang tSU,STA/tHD,STA/tSU,STOP maybe out of spec due to device clock-stretching or circuit loss, we could get device clock-stretch time from dts to adjust these parameters to meet the spec via EXT_CONF register. Signed-off-by: Qii Wang --- Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt index 7f0194f..97f66f0 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt @@ -32,6 +32,7 @@ Optional properties: - mediatek,have-pmic: platform can control i2c form special pmic side. Only mt6589 and mt8135 support this feature. - mediatek,use-push-pull: IO config use push-pull mode. + - clock-stretch-ns: Slave device clock-stretch time. Example: -- 1.9.1
[RESEND] i2c: mediatek: Get device clock-stretch time via dts
From: Qii Wang tSU,STA/tHD,STA/tSU,STOP maybe out of spec due to device clock-stretching or circuit loss, we could get device clock-stretch time from dts to adjust these parameters to meet the spec via EXT_CONF register. Signed-off-by: Qii Wang --- drivers/i2c/busses/i2c-mt65xx.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 2ffd2f3..47c7255 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -245,6 +245,7 @@ struct mtk_i2c { u16 irq_stat; /* interrupt status */ unsigned int clk_src_div; unsigned int speed_hz; /* The speed in transfer */ + unsigned int clock_stretch_ns; enum mtk_trans_op op; u16 timing_reg; u16 high_speed_reg; @@ -607,7 +608,8 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c, else clk_ns = sample_ns / 2; - su_sta_cnt = DIV_ROUND_UP(spec->min_su_sta_ns, clk_ns); + su_sta_cnt = DIV_ROUND_UP(spec->min_su_sta_ns + i2c->clock_stretch_ns, + clk_ns); if (su_sta_cnt > max_sta_cnt) return -1; @@ -1171,6 +1173,8 @@ static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c) if (i2c->clk_src_div == 0) return -EINVAL; + of_property_read_u32(np, "clock-stretch-ns", &i2c->clock_stretch_ns); + i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic"); i2c->use_push_pull = of_property_read_bool(np, "mediatek,use-push-pull"); -- 1.9.1
[PATCH] i2c: mediatek: Get device clock-stretch time via dts
From: Qii Wang tSU,STA/tHD,STA/tSU,STOP maybe out of spec due to device clock-stretching or circuit loss, we could get device clock-stretch time from dts to adjust these parameters to meet the spec via EXT_CONF register. Signed-off-by: Qii Wang --- drivers/i2c/busses/i2c-mt65xx.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 2ffd2f3..47c7255 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -245,6 +245,7 @@ struct mtk_i2c { u16 irq_stat; /* interrupt status */ unsigned int clk_src_div; unsigned int speed_hz; /* The speed in transfer */ + unsigned int clock_stretch_ns; enum mtk_trans_op op; u16 timing_reg; u16 high_speed_reg; @@ -607,7 +608,8 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c, else clk_ns = sample_ns / 2; - su_sta_cnt = DIV_ROUND_UP(spec->min_su_sta_ns, clk_ns); + su_sta_cnt = DIV_ROUND_UP(spec->min_su_sta_ns + i2c->clock_stretch_ns, + clk_ns); if (su_sta_cnt > max_sta_cnt) return -1; @@ -1171,6 +1173,8 @@ static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c) if (i2c->clk_src_div == 0) return -EINVAL; + of_property_read_u32(np, "clock-stretch-ns", &i2c->clock_stretch_ns); + i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic"); i2c->use_push_pull = of_property_read_bool(np, "mediatek,use-push-pull"); -- 1.9.1
[RESEND, V2] i2c: mediatek: Move suspend and resume handling to NOIRQ phase
From: Qii Wang Some i2c device driver indirectly uses I2C driver when it is now being suspended. The i2c devices driver is suspended during the NOIRQ phase and this cannot be changed due to other dependencies. Therefore, we also need to move the suspend handling for the I2C controller driver to the NOIRQ phase as well. Signed-off-by: Qii Wang --- Changes in v2: - Replied some comments - Fixed the wrong spelling medaitek to mediatek drivers/i2c/busses/i2c-mt65xx.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 0818d3e..2ffd2f3 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1275,7 +1275,8 @@ static int mtk_i2c_probe(struct platform_device *pdev) mtk_i2c_clock_disable(i2c); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, - IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c); + IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, + I2C_DRV_NAME, i2c); if (ret < 0) { dev_err(&pdev->dev, "Request I2C IRQ %d fail\n", irq); @@ -1302,7 +1303,16 @@ static int mtk_i2c_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -static int mtk_i2c_resume(struct device *dev) +static int mtk_i2c_suspend_noirq(struct device *dev) +{ + struct mtk_i2c *i2c = dev_get_drvdata(dev); + + i2c_mark_adapter_suspended(&i2c->adap); + + return 0; +} + +static int mtk_i2c_resume_noirq(struct device *dev) { int ret; struct mtk_i2c *i2c = dev_get_drvdata(dev); @@ -1317,12 +1327,15 @@ static int mtk_i2c_resume(struct device *dev) mtk_i2c_clock_disable(i2c); + i2c_mark_adapter_resumed(&i2c->adap); + return 0; } #endif static const struct dev_pm_ops mtk_i2c_pm = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, mtk_i2c_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq, + mtk_i2c_resume_noirq) }; static struct platform_driver mtk_i2c_driver = { -- 1.9.1
i2c: mediatek: Fix apdma and i2c hand-shake timeout
From: Qii Wang With the apdma remove hand-shake signal, it requirs special operation timing to reset i2c manually, otherwise the interrupt will not be triggered, i2c transmission will be timeout. Signed-off-by: Qii Wang --- drivers/i2c/busses/i2c-mt65xx.c | 27 ++- 1 file changed, 22 insertions(+), 5 deletions(-) base Message ID: 1605701861-30800-1-git-send-email-qii.w...@mediatek.com diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 6f61595..2ffd2f3 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -38,6 +38,7 @@ #define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 #define I2C_IO_CONFIG_PUSH_PULL0x #define I2C_SOFT_RST 0x0001 +#define I2C_HANDSHAKE_RST 0x0020 #define I2C_FIFO_ADDR_CLR 0x0001 #define I2C_DELAY_LEN 0x0002 #define I2C_TIME_CLR_VALUE 0x @@ -45,6 +46,7 @@ #define I2C_WRRD_TRANAC_VALUE 0x0002 #define I2C_RD_TRANAC_VALUE0x0001 #define I2C_SCL_MIS_COMP_VALUE 0x +#define I2C_CHN_CLR_FLAG 0x #define I2C_DMA_CON_TX 0x #define I2C_DMA_CON_RX 0x0001 @@ -54,7 +56,9 @@ #define I2C_DMA_START_EN 0x0001 #define I2C_DMA_INT_FLAG_NONE 0x #define I2C_DMA_CLR_FLAG 0x +#define I2C_DMA_WARM_RST 0x0001 #define I2C_DMA_HARD_RST 0x0002 +#define I2C_DMA_HANDSHAKE_RST 0x0004 #define MAX_SAMPLE_CNT_DIV 8 #define MAX_STEP_CNT_DIV 64 @@ -475,11 +479,24 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) { u16 control_reg; - writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); - udelay(50); - writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); - - mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); + if (i2c->dev_comp->dma_sync) { + writel(I2C_DMA_WARM_RST, i2c->pdmabase + OFFSET_RST); + udelay(10); + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); + udelay(10); + writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_HARD_RST, + i2c->pdmabase + OFFSET_RST); + mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST | I2C_SOFT_RST, + OFFSET_SOFTRESET); + udelay(10); + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); + mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET); + } else { + writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); + udelay(50); + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); + mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); + } /* Set ioconfig */ if (i2c->use_push_pull) -- 1.9.1
[PATCH] arm64: dts: mediatek: Correct i2c clock of MT8192
From: Qii Wang imp wrapper clock is the i2c source clock of MT8192 Signed-off-by: Qii Wang --- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 43 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index faea0d9..9c194a8 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -17,6 +17,19 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + }; + clk26m: oscillator0 { compatible = "fixed-clock"; #clock-cells = <0>; @@ -593,7 +606,8 @@ reg = <0 0x11cb 0 0x1000>, <0 0x10217300 0 0x80>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_e CLK_IMP_IIC_WRAP_E_I2C3>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -612,7 +626,8 @@ reg = <0 0x11d0 0 0x1000>, <0 0x10217600 0 0x180>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -625,7 +640,8 @@ reg = <0 0x11d01000 0 0x1000>, <0 0x10217780 0 0x180>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C8>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -638,7 +654,8 @@ reg = <0 0x11d02000 0 0x1000>, <0 0x10217900 0 0x180>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C9>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -657,7 +674,8 @@ reg = <0 0x11d2 0 0x1000>, <0 0x10217100 0 0x80>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C1>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -670,7 +688,8 @@ reg = <0 0x11d21000 0 0x1000>, <0 0x10217180 0 0x180>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C2>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -683,7 +702,8 @@ reg = <0 0x11d22000 0 0x1000>, <0 0x10217380 0 0x180>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C4>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -702,7 +722,8 @@ reg = <0 0x11e0 0 0x1000>, <0 0x10217500 0 0x80>; interrupts = ; - clocks = <&clk26m>, <&clk26m>; + clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C5>, +<&infracfg CLK_INFRA_AP_DMA>; clock-names = "main", "dma"; clock-div = <1>; #address-cells = <1>; @@ -721,
[v2] i2c: mediatek: Move suspend and resume handling to NOIRQ phase
From: Qii Wang Some i2c device driver indirectly uses I2C driver when it is now being suspended. The i2c devices driver is suspended during the NOIRQ phase and this cannot be changed due to other dependencies. Therefore, we also need to move the suspend handling for the I2C controller driver to the NOIRQ phase as well. Signed-off-by: Qii Wang --- Changes in v2: - fix the wrong spelling medaitek to mediatek drivers/i2c/busses/i2c-mt65xx.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 33de99b..6f61595 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1258,7 +1258,8 @@ static int mtk_i2c_probe(struct platform_device *pdev) mtk_i2c_clock_disable(i2c); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, - IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c); + IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, + I2C_DRV_NAME, i2c); if (ret < 0) { dev_err(&pdev->dev, "Request I2C IRQ %d fail\n", irq); @@ -1285,7 +1286,16 @@ static int mtk_i2c_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -static int mtk_i2c_resume(struct device *dev) +static int mtk_i2c_suspend_noirq(struct device *dev) +{ + struct mtk_i2c *i2c = dev_get_drvdata(dev); + + i2c_mark_adapter_suspended(&i2c->adap); + + return 0; +} + +static int mtk_i2c_resume_noirq(struct device *dev) { int ret; struct mtk_i2c *i2c = dev_get_drvdata(dev); @@ -1300,12 +1310,15 @@ static int mtk_i2c_resume(struct device *dev) mtk_i2c_clock_disable(i2c); + i2c_mark_adapter_resumed(&i2c->adap); + return 0; } #endif static const struct dev_pm_ops mtk_i2c_pm = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, mtk_i2c_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq, + mtk_i2c_resume_noirq) }; static struct platform_driver mtk_i2c_driver = { -- 1.9.1
[i2c-next,PATCH] i2c: medaitek: Move suspend and resume handling to NOIRQ phase
From: Qii Wang Some i2c device driver indirectly uses I2C driver when it is now being suspended. The i2c devices driver is suspended during the NOIRQ phase and this cannot be changed due to other dependencies. Therefore, we also need to move the suspend handling for the I2C controller driver to the NOIRQ phase as well. Signed-off-by: Qii Wang --- drivers/i2c/busses/i2c-mt65xx.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 33de99b..6f61595 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1258,7 +1258,8 @@ static int mtk_i2c_probe(struct platform_device *pdev) mtk_i2c_clock_disable(i2c); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, - IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c); + IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, + I2C_DRV_NAME, i2c); if (ret < 0) { dev_err(&pdev->dev, "Request I2C IRQ %d fail\n", irq); @@ -1285,7 +1286,16 @@ static int mtk_i2c_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -static int mtk_i2c_resume(struct device *dev) +static int mtk_i2c_suspend_noirq(struct device *dev) +{ + struct mtk_i2c *i2c = dev_get_drvdata(dev); + + i2c_mark_adapter_suspended(&i2c->adap); + + return 0; +} + +static int mtk_i2c_resume_noirq(struct device *dev) { int ret; struct mtk_i2c *i2c = dev_get_drvdata(dev); @@ -1300,12 +1310,15 @@ static int mtk_i2c_resume(struct device *dev) mtk_i2c_clock_disable(i2c); + i2c_mark_adapter_resumed(&i2c->adap); + return 0; } #endif static const struct dev_pm_ops mtk_i2c_pm = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, mtk_i2c_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq, + mtk_i2c_resume_noirq) }; static struct platform_driver mtk_i2c_driver = { -- 1.9.1
[PATCH] i2c: mediatek: move dma reset before i2c reset
From: Qii Wang The i2c driver default do dma reset after i2c reset, but sometimes i2c reset will trigger dma tx2rx, then apdma write data to dram which has been i2c_put_dma_safe_msg_buf(kfree). Move dma reset before i2c reset in mtk_i2c_init_hw to fix it. Signed-off-by: Qii Wang --- drivers/i2c/busses/i2c-mt65xx.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 0cbdfbe..33de99b 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -475,6 +475,10 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) { u16 control_reg; + writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); + udelay(50); + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); + mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); /* Set ioconfig */ @@ -529,10 +533,6 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) mtk_i2c_writew(i2c, control_reg, OFFSET_CONTROL); mtk_i2c_writew(i2c, I2C_DELAY_LEN, OFFSET_DELAY_LEN); - - writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); - udelay(50); - writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); } static const struct i2c_spec_values *mtk_i2c_get_spec(unsigned int speed) -- 1.9.1
[PATCH] i2c: mediatek: Fix generic definitions for bus frequencies
From: Qii Wang The master code needs to being sent when the speed is more than I2C_MAX_FAST_MODE_PLUS_FREQ instead of I2C_MAX_HIGH_SPEED_MODE_FREQ. Fix it. Signed-off-by: Qii Wang --- drivers/i2c/busses/i2c-mt65xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index efc1404..0cbdfbe 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -681,8 +681,8 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src, unsigned int cnt_mul; int ret = -EINVAL; - if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) - target_speed = I2C_MAX_FAST_MODE_PLUS_FREQ; + if (target_speed > I2C_MAX_HIGH_SPEED_MODE_FREQ) + target_speed = I2C_MAX_HIGH_SPEED_MODE_FREQ; max_step_cnt = mtk_i2c_max_step_cnt(target_speed); base_step_cnt = max_step_cnt; @@ -759,7 +759,7 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk) for (clk_div = 1; clk_div <= max_clk_div; clk_div++) { clk_src = parent_clk / clk_div; - if (target_speed > I2C_MAX_FAST_MODE_FREQ) { + if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) { /* Set master code speed register */ ret = mtk_i2c_calculate_speed(i2c, clk_src, I2C_MAX_FAST_MODE_FREQ, -- 1.9.1
[next] i2c: mediatek: Use div_u64 for 64-bit division to fix 32-bit kernels
From: Qii Wang Use div_u64 for 64-bit division, and change sample_ns type to unsigned int. Otherwise, the module will reference __udivdi3 under 32-bit kernels, which is not allowed in kernel space. Signed-off-by: Qii Wang --- drivers/i2c/busses/i2c-mt65xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 7020618..deef69e 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -551,7 +551,8 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c, const struct i2c_spec_values *spec; unsigned int su_sta_cnt, low_cnt, high_cnt, max_step_cnt; unsigned int sda_max, sda_min, clk_ns, max_sta_cnt = 0x3f; - long long sample_ns = (10 * (sample_cnt + 1)) / clk_src; + unsigned int sample_ns = div_u64(10ULL * (sample_cnt + 1), +clk_src); if (!i2c->dev_comp->timing_adjust) return 0; -- 1.9.1
[PATCH] arm64: dts: mt8183: add I2C nodes
From: Qii Wang Add i2c nodes to mt8183 and mt8183-evb. Signed-off-by: Qii Wang --- arch/arm64/boot/dts/mediatek/mt8183-evb.dts | 96 ++ arch/arm64/boot/dts/mediatek/mt8183.dtsi| 189 2 files changed, 285 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts index d8e555c..1fb195c 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts @@ -30,7 +30,103 @@ status = "okay"; }; +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c_pins_0>; + status = "okay"; + clock-frequency = <10>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c_pins_1>; + status = "okay"; + clock-frequency = <10>; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c_pins_2>; + status = "okay"; + clock-frequency = <10>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c_pins_3>; + status = "okay"; + clock-frequency = <10>; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c_pins_4>; + status = "okay"; + clock-frequency = <100>; +}; + +&i2c5 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c_pins_5>; + status = "okay"; + clock-frequency = <100>; +}; + &pio { + i2c_pins_0: i2c0{ + pins_i2c{ + pinmux = , +; + mediatek,pull-up-adv = <3>; + mediatek,drive-strength-adv = <00>; + }; + }; + + i2c_pins_1: i2c1{ + pins_i2c{ + pinmux = , +; + mediatek,pull-up-adv = <3>; + mediatek,drive-strength-adv = <00>; + }; + }; + + i2c_pins_2: i2c2{ + pins_i2c{ + pinmux = , +; + mediatek,pull-up-adv = <3>; + mediatek,drive-strength-adv = <00>; + }; + }; + + i2c_pins_3: i2c3{ + pins_i2c{ + pinmux = , +; + mediatek,pull-up-adv = <3>; + mediatek,drive-strength-adv = <00>; + }; + }; + + i2c_pins_4: i2c4{ + pins_i2c{ + pinmux = , +; + mediatek,pull-up-adv = <3>; + mediatek,drive-strength-adv = <00>; + }; + }; + + i2c_pins_5: i2c5{ + pins_i2c{ + pinmux = , +; + mediatek,pull-up-adv = <3>; + mediatek,drive-strength-adv = <00>; + }; + }; + spi_pins_0: spi0{ pins_spi{ pinmux = , diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index c2749c4..ab71291 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -16,6 +16,21 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -294,6 +309,64 @@ status = "disabled"; }; + i2c6: i2c@11005000 { + compatible = "mediatek,mt8183-i2c"; + reg = <0 0x11005000 0 0x1000>, + <0 0x11000600 0 0x80>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_I2C6>, +<&infracfg CLK_INFRA_AP_DMA>; + clock-names = "main", "dma"; + clock-div = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c0: i2c@11007000 { + compatible = "mediatek,mt8183-i2c"; + reg = <0 0x11007000 0 0x1000>, + <0 0x1180 0 0x80>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_I2C0>, +<&infracfg CLK_INFRA_AP_DMA>; +
[PATCH] dt-bindings: i3c: cdns: Use correct cells for I2C device
From: Qii Wang I2C device reg should be "reg = <0x52 0x0 0x10>;" Signed-off-by: Qii Wang --- .../devicetree/bindings/i3c/cdns,i3c-master.txt|2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/i3c/cdns,i3c-master.txt b/Documentation/devicetree/bindings/i3c/cdns,i3c-master.txt index 69da211..1cf6182 100644 --- a/Documentation/devicetree/bindings/i3c/cdns,i3c-master.txt +++ b/Documentation/devicetree/bindings/i3c/cdns,i3c-master.txt @@ -38,6 +38,6 @@ Example: nunchuk: nunchuk@52 { compatible = "nintendo,nunchuk"; - reg = <0x52 0x8010 0>; + reg = <0x52 0x0 0x10>; }; }; -- 1.7.9.5
[PATCH 1/5] dt-bindings: i2c: Add Mediatek MT7629 i2c binding
From: qii wang Add MT7629 i2c binding to i2c-mt2712.txt and there is no need to modify i2c driver. Signed-off-by: qii wang --- Documentation/devicetree/bindings/i2c/i2c-mtk.txt |1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt index e199695..7729e57 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt @@ -10,6 +10,7 @@ Required properties: "mediatek,mt6589-i2c": for MediaTek MT6589 "mediatek,mt7622-i2c": for MediaTek MT7622 "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for MediaTek MT7623 + "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek mt7629 "mediatek,mt8173-i2c": for MediaTek MT8173 - reg: physical base address of the controller and dma base, length of memory mapped region. -- 1.7.9.5
[PATCH 3/5] i2c: mediatek: Add offsets array for new i2c registers
From: qii wang New i2c registers would have different offsets, so we use different offsets array to distinguish different i2c registers version. Signed-off-by: qii wang --- drivers/i2c/busses/i2c-mt65xx.c | 163 +-- 1 file changed, 104 insertions(+), 59 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 660de1e..428ac99 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -106,34 +106,62 @@ enum mtk_trans_op { }; enum I2C_REGS_OFFSET { - OFFSET_DATA_PORT = 0x0, - OFFSET_SLAVE_ADDR = 0x04, - OFFSET_INTR_MASK = 0x08, - OFFSET_INTR_STAT = 0x0c, - OFFSET_CONTROL = 0x10, - OFFSET_TRANSFER_LEN = 0x14, - OFFSET_TRANSAC_LEN = 0x18, - OFFSET_DELAY_LEN = 0x1c, - OFFSET_TIMING = 0x20, - OFFSET_START = 0x24, - OFFSET_EXT_CONF = 0x28, - OFFSET_FIFO_STAT = 0x30, - OFFSET_FIFO_THRESH = 0x34, - OFFSET_FIFO_ADDR_CLR = 0x38, - OFFSET_IO_CONFIG = 0x40, - OFFSET_RSV_DEBUG = 0x44, - OFFSET_HS = 0x48, - OFFSET_SOFTRESET = 0x50, - OFFSET_DCM_EN = 0x54, - OFFSET_PATH_DIR = 0x60, - OFFSET_DEBUGSTAT = 0x64, - OFFSET_DEBUGCTRL = 0x68, - OFFSET_TRANSFER_LEN_AUX = 0x6c, - OFFSET_CLOCK_DIV = 0x70, + OFFSET_DATA_PORT, + OFFSET_SLAVE_ADDR, + OFFSET_INTR_MASK, + OFFSET_INTR_STAT, + OFFSET_CONTROL, + OFFSET_TRANSFER_LEN, + OFFSET_TRANSAC_LEN, + OFFSET_DELAY_LEN, + OFFSET_TIMING, + OFFSET_START, + OFFSET_EXT_CONF, + OFFSET_FIFO_STAT, + OFFSET_FIFO_THRESH, + OFFSET_FIFO_ADDR_CLR, + OFFSET_IO_CONFIG, + OFFSET_RSV_DEBUG, + OFFSET_HS, + OFFSET_SOFTRESET, + OFFSET_DCM_EN, + OFFSET_PATH_DIR, + OFFSET_DEBUGSTAT, + OFFSET_DEBUGCTRL, + OFFSET_TRANSFER_LEN_AUX, + OFFSET_CLOCK_DIV, +}; + +static const u16 mt_i2c_regs_v1[] = { + [OFFSET_DATA_PORT] = 0x0, + [OFFSET_SLAVE_ADDR] = 0x4, + [OFFSET_INTR_MASK] = 0x8, + [OFFSET_INTR_STAT] = 0xc, + [OFFSET_CONTROL] = 0x10, + [OFFSET_TRANSFER_LEN] = 0x14, + [OFFSET_TRANSAC_LEN] = 0x18, + [OFFSET_DELAY_LEN] = 0x1c, + [OFFSET_TIMING] = 0x20, + [OFFSET_START] = 0x24, + [OFFSET_EXT_CONF] = 0x28, + [OFFSET_FIFO_STAT] = 0x30, + [OFFSET_FIFO_THRESH] = 0x34, + [OFFSET_FIFO_ADDR_CLR] = 0x38, + [OFFSET_IO_CONFIG] = 0x40, + [OFFSET_RSV_DEBUG] = 0x44, + [OFFSET_HS] = 0x48, + [OFFSET_SOFTRESET] = 0x50, + [OFFSET_DCM_EN] = 0x54, + [OFFSET_PATH_DIR] = 0x60, + [OFFSET_DEBUGSTAT] = 0x64, + [OFFSET_DEBUGCTRL] = 0x68, + [OFFSET_TRANSFER_LEN_AUX] = 0x6c, + [OFFSET_CLOCK_DIV] = 0x70, }; struct mtk_i2c_compatible { const struct i2c_adapter_quirks *quirks; + const u16 *regs; unsigned char pmic_i2c: 1; unsigned char dcm: 1; unsigned char auto_restart: 1; @@ -181,6 +209,7 @@ struct mtk_i2c { }; static const struct mtk_i2c_compatible mt2712_compat = { + .regs = mt_i2c_regs_v1, .pmic_i2c = 0, .dcm = 1, .auto_restart = 1, @@ -191,6 +220,7 @@ struct mtk_i2c { static const struct mtk_i2c_compatible mt6577_compat = { .quirks = &mt6577_i2c_quirks, + .regs = mt_i2c_regs_v1, .pmic_i2c = 0, .dcm = 1, .auto_restart = 0, @@ -201,6 +231,7 @@ struct mtk_i2c { static const struct mtk_i2c_compatible mt6589_compat = { .quirks = &mt6577_i2c_quirks, + .regs = mt_i2c_regs_v1, .pmic_i2c = 1, .dcm = 0, .auto_restart = 0, @@ -211,6 +242,7 @@ struct mtk_i2c { static const struct mtk_i2c_compatible mt7622_compat = { .quirks = &mt7622_i2c_quirks, + .regs = mt_i2c_regs_v1, .pmic_i2c = 0, .dcm = 1, .auto_restart = 1, @@ -220,6 +252,7 @@ struct mtk_i2c { }; static const struct mtk_i2c_compatible mt8173_compat = { + .regs = mt_i2c_regs_v1, .pmic_i2c = 0, .dcm = 1, .auto_restart = 1, @@ -238,6 +271,17 @@ struct mtk_i2c { }; MODULE_DEVICE_TABLE(of, mtk_i2c_of_match); +static u16 mtk_i2c_readw(struct mtk_i2c *i2c, enum I2C_REGS_OFFSET reg) +{ + return readw(i2c->base + i2c->dev_comp->regs[reg]); +} + +static void mtk_i2c_writew(struct mtk_i2c *i2c, u16 val, + enum I2C_REGS_OFFSET reg) +{ + writew(val, i2c->base + i2c->dev_comp->regs[reg]); +} + static int mtk_i2c_clock_enable(struct mtk_i2c *i2c) { int ret; @@ -278,31 +322,31 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c) { u16 control_reg; - writew(I2C_SOFT_RST, i2c->base + OFFSET_SOFTRESET); + mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); /* Set ioconfig */ if (i2c->use_push_pull) - writew(I2C_IO_CONFIG_PUSH_PULL, i2c->base
[PATCH 2/5] i2c: mediatek: remove useless code and replace definitions
From: qii wang Completion_done is useless when we don't use its return value, so we remove it. Different speeds have been defined by macros, so we use macros definitions. Signed-off-by: qii wang --- drivers/i2c/busses/i2c-mt65xx.c |6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index a74ef76..660de1e 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -456,7 +456,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, control_reg = readw(i2c->base + OFFSET_CONTROL) & ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS); - if ((i2c->speed_hz > 40) || (left_num >= 1)) + if ((i2c->speed_hz > MAX_FS_MODE_SPEED) || (left_num >= 1)) control_reg |= I2C_CONTROL_RS; if (i2c->op == I2C_MASTER_WRRD) @@ -465,7 +465,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, writew(control_reg, i2c->base + OFFSET_CONTROL); /* set start condition */ - if (i2c->speed_hz <= 10) + if (i2c->speed_hz <= I2C_DEFAULT_SPEED) writew(I2C_ST_START_CON, i2c->base + OFFSET_EXT_CONF); else writew(I2C_FS_START_CON, i2c->base + OFFSET_EXT_CONF); @@ -642,8 +642,6 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, return -ETIMEDOUT; } - completion_done(&i2c->msg_complete); - if (i2c->irq_stat & (I2C_HS_NACKERR | I2C_ACKERR)) { dev_dbg(i2c->dev, "addr: %x, transfer ACK error\n", msgs->addr); mtk_i2c_init_hw(i2c); -- 1.7.9.5
[PATCH 4/5] dt-bindings: i2c: Add Mediatek MT8183 i2c binding
From: qii wang Add MT8183 i2c binding to binding file. Compare to 2712 i2c controller, MT8183 has different registers, offsets, clock, and multi-user function. Signed-off-by: qii wang --- Documentation/devicetree/bindings/i2c/i2c-mtk.txt |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt index 7729e57..dfde624 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt @@ -12,14 +12,15 @@ Required properties: "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for MediaTek MT7623 "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek mt7629 "mediatek,mt8173-i2c": for MediaTek MT8173 + "mediatek,mt8183-i2c": for MediaTek MT8183 - reg: physical base address of the controller and dma base, length of memory mapped region. - interrupts: interrupt number to the cpu. - clock-div: the fixed value for frequency divider of clock source in i2c module. Each IC may be different. - clocks: clock name from clock manager - - clock-names: Must include "main" and "dma", if enable have-pmic need include -"pmic" extra. + - clock-names: Must include "main" and "dma", "arb" is optional, if enable +have-pmic need include "pmic" extra. Optional properties: - clock-frequency: Frequency in Hz of the bus when transfer, the default value @@ -27,6 +28,8 @@ Optional properties: - mediatek,have-pmic: platform can control i2c form special pmic side. Only mt6589 and mt8135 support this feature. - mediatek,use-push-pull: IO config use push-pull mode. + - ch-offset: base reg offset for multi-user. + - mediatek,share-i3c: i3c controller can share i2c function. Example: -- 1.7.9.5
[PATCH 0/5] add i2c support for mt7629 and mt8183
This series are based on 4.20-rc1 and provide five patches to support mt7629 and mt8183 IC. qii wang (5): dt-bindings: i2c: Add Mediatek MT7629 i2c binding i2c: mediatek: remove useless code and replace definitions i2c: mediatek: Add offsets array for new i2c registers dt-bindings: i2c: Add Mediatek MT8183 i2c binding i2c: mediatek: Add i2c compatible for MediaTek MT8183 Documentation/devicetree/bindings/i2c/i2c-mtk.txt |8 +- drivers/i2c/busses/i2c-mt65xx.c | 299 - 2 files changed, 239 insertions(+), 68 deletions(-) -- 1.7.9.5
[PATCH 5/5] i2c: mediatek: Add i2c compatible for MediaTek MT8183
From: qii wang Add i2c compatible for MT8183. Compare to 2712 i2c controller, MT8183 has different registers, offsets, clock, and multi-user function. Signed-off-by: qii wang --- drivers/i2c/busses/i2c-mt65xx.c | 136 +-- 1 file changed, 130 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 428ac99..6b979ab 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -35,17 +35,23 @@ #include #define I2C_RS_TRANSFER(1 << 4) +#define I2C_ARB_LOST (1 << 3) #define I2C_HS_NACKERR (1 << 2) #define I2C_ACKERR (1 << 1) #define I2C_TRANSAC_COMP (1 << 0) #define I2C_TRANSAC_START (1 << 0) +#define I2C_RESUME_ARBIT (1 << 1) #define I2C_RS_MUL_CNFG(1 << 15) #define I2C_RS_MUL_TRIG(1 << 14) +#define I2C_HS_TIME_EN (1 << 7) #define I2C_DCM_DISABLE0x #define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 #define I2C_IO_CONFIG_PUSH_PULL0x #define I2C_SOFT_RST 0x0001 #define I2C_FIFO_ADDR_CLR 0x0001 +#define I2C_FIFO_ADDR_CLRH 0x0002 +#define I2C_FIFO_ADDR_CLR_MCH 0x0004 +#define I2C_HFIFO_DATA 0x8208 #define I2C_DELAY_LEN 0x0002 #define I2C_ST_START_CON 0x8001 #define I2C_FS_START_CON 0x1800 @@ -76,6 +82,8 @@ #define I2C_CONTROL_DIR_CHANGE (0x1 << 4) #define I2C_CONTROL_ACKERR_DET_EN (0x1 << 5) #define I2C_CONTROL_TRANSFER_LEN_CHANGE (0x1 << 6) +#define I2C_CONTROL_DMAACK_EN (0x1 << 8) +#define I2C_CONTROL_ASYNC_MODE (0x1 << 9) #define I2C_CONTROL_WRAPPER (0x1 << 0) #define I2C_DRV_NAME "i2c-mt65xx" @@ -130,6 +138,15 @@ enum I2C_REGS_OFFSET { OFFSET_DEBUGCTRL, OFFSET_TRANSFER_LEN_AUX, OFFSET_CLOCK_DIV, + /* MT8183 only regs */ + OFFSET_LTIMING, + OFFSET_DATA_TIMING, + OFFSET_MCU_INTR, + OFFSET_HW_TIMEOUT, + OFFSET_HFIFO_DATA, + OFFSET_HFIFO_STAT, + OFFSET_MULTI_DMA, + OFFSET_ROLLBACK, }; static const u16 mt_i2c_regs_v1[] = { @@ -159,6 +176,39 @@ enum I2C_REGS_OFFSET { [OFFSET_CLOCK_DIV] = 0x70, }; +static const u16 mt_i2c_regs_v2[] = { + [OFFSET_DATA_PORT] = 0x0, + [OFFSET_SLAVE_ADDR] = 0x4, + [OFFSET_INTR_MASK] = 0x8, + [OFFSET_INTR_STAT] = 0xc, + [OFFSET_CONTROL] = 0x10, + [OFFSET_TRANSFER_LEN] = 0x14, + [OFFSET_TRANSAC_LEN] = 0x18, + [OFFSET_DELAY_LEN] = 0x1c, + [OFFSET_TIMING] = 0x20, + [OFFSET_START] = 0x24, + [OFFSET_EXT_CONF] = 0x28, + [OFFSET_LTIMING] = 0x2c, + [OFFSET_HS] = 0x30, + [OFFSET_IO_CONFIG] = 0x34, + [OFFSET_FIFO_ADDR_CLR] = 0x38, + [OFFSET_DATA_TIMING] = 0x3c, + [OFFSET_MCU_INTR] = 0x40, + [OFFSET_TRANSFER_LEN_AUX] = 0x44, + [OFFSET_CLOCK_DIV] = 0x48, + [OFFSET_HW_TIMEOUT] = 0x4c, + [OFFSET_SOFTRESET] = 0x50, + [OFFSET_HFIFO_DATA] = 0x70, + [OFFSET_DEBUGSTAT] = 0xe0, + [OFFSET_DEBUGCTRL] = 0xe8, + [OFFSET_FIFO_STAT] = 0xf4, + [OFFSET_FIFO_THRESH] = 0xf8, + [OFFSET_HFIFO_STAT] = 0xfc, + [OFFSET_DCM_EN] = 0xf88, + [OFFSET_MULTI_DMA] = 0xf8c, + [OFFSET_ROLLBACK] = 0xf98, +}; + struct mtk_i2c_compatible { const struct i2c_adapter_quirks *quirks; const u16 *regs; @@ -168,6 +218,7 @@ struct mtk_i2c_compatible { unsigned char aux_len_reg: 1; unsigned char support_33bits: 1; unsigned char timing_adjust: 1; + unsigned char dma_sync: 1; }; struct mtk_i2c { @@ -181,8 +232,11 @@ struct mtk_i2c { struct clk *clk_main; /* main clock for i2c bus */ struct clk *clk_dma;/* DMA clock for i2c via DMA */ struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */ + struct clk *clk_arb;/* Arbitrator clock for i2c */ bool have_pmic; /* can use i2c pins from PMIC */ bool use_push_pull; /* IO config push-pull mode */ + bool share_i3c; /* share i3c IP*/ + u32 ch_offset; /* i2c multi-user channel offset */ u16 irq_stat; /* interrupt status */ unsigned int clk_src_div; @@ -190,6 +244,7 @@ struct mtk_i2c { enum mtk_trans_op op; u16 timing_reg; u16 high_speed_reg; + u16 ltiming_reg; unsigned char auto_restart; bool ignore_restart_irq; const struct mtk_i2c_compatible *dev_comp; @@ -216,6 +271,7 @@ struct mtk_i2c { .aux_len_reg = 1, .support_33bits = 1, .timing_adjust = 1, + .dma_sync = 0, }; st