[PATCH] dt-bindings: i2c: Add device clock-stretch time via dts

2021-03-13 Thread qii.wang
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

2021-03-13 Thread qii.wang
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

2021-02-03 Thread qii.wang
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

2021-01-09 Thread qii.wang
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

2020-12-24 Thread qii.wang
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

2020-12-21 Thread qii.wang
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

2020-11-18 Thread qii.wang
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

2020-11-07 Thread qii.wang
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

2020-10-30 Thread qii.wang
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

2020-09-11 Thread qii.wang
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

2020-05-20 Thread qii.wang
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

2019-08-22 Thread qii.wang
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

2019-06-30 Thread qii.wang
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

2018-12-03 Thread qii.wang
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

2018-12-03 Thread qii.wang
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

2018-12-03 Thread qii.wang
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

2018-12-03 Thread qii.wang
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

2018-12-03 Thread qii.wang
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

2018-12-03 Thread qii.wang
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