From: Mingming Lee
Add MediaTek I2C basic driver
Reviewed-by: Heiko Schocher
Signed-off-by: Mingming Lee
---
Changes for v3:
- fixed code veriew note in v2
- optimize the dma read/write flow in mtk_i2c_do_transfer()
Changes for v2:
- using error number defined in include/linux/errno.h
---
drivers/i2c/Kconfig | 8 +
drivers/i2c/Makefile | 1 +
drivers/i2c/mt_i2c.c | 713 +++
3 files changed, 722 insertions(+)
create mode 100644 drivers/i2c/mt_i2c.c
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index dec6dc9..e217673 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -159,6 +159,14 @@ config SYS_I2C_MESON
internal buffer holding up to 8 bytes for transfers and supports
both 7-bit and 10-bit addresses.
+config SYS_I2C_MTK
+ bool "MediaTek I2C driver"
+ help
+ This selects the MediaTek Integrated Inter Circuit bus driver.
+ The I2C bus adapter is the base for some other I2C client, eg: touch,
sensors.
+ If you want to use MediaTek I2C interface, say Y here.
+ If unsure, say N.
+
config SYS_I2C_MXC
bool "NXP MXC I2C driver"
help
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index e851ec4..7227742 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o
obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o
obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
+obj-$(CONFIG_SYS_I2C_MTK) += mt_i2c.o
obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
obj-$(CONFIG_SYS_I2C_OCTEON) += octeon_i2c.o
obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o
diff --git a/drivers/i2c/mt_i2c.c b/drivers/i2c/mt_i2c.c
new file mode 100644
index 000..e1de933
--- /dev/null
+++ b/drivers/i2c/mt_i2c.c
@@ -0,0 +1,713 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek I2C Interface driver
+ *
+ * Copyright (C) 2020 MediaTek Inc.
+ * Author: Mingming Lee
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define I2C_RS_TRANSFERBIT(4)
+#define I2C_HS_NACKERR BIT(2)
+#define I2C_ACKERR BIT(1)
+#define I2C_TRANSAC_COMP BIT(0)
+#define I2C_TRANSAC_START BIT(0)
+#define I2C_RS_MUL_CNFGBIT(15)
+#define I2C_RS_MUL_TRIGBIT(14)
+#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_DELAY_LEN 0x0002
+#define I2C_ST_START_CON 0x8001
+#define I2C_FS_START_CON 0x1800
+#define I2C_TIME_CLR_VALUE 0x
+#define I2C_TIME_DEFAULT_VALUE 0x0003
+#define I2C_WRRD_TRANAC_VALUE 0x0002
+#define I2C_RD_TRANAC_VALUE0x0001
+
+#define I2C_DMA_CON_TX 0x
+#define I2C_DMA_CON_RX 0x0001
+#define I2C_DMA_START_EN 0x0001
+#define I2C_DMA_INT_FLAG_NONE 0x
+#define I2C_DMA_CLR_FLAG 0x
+#define I2C_DMA_TX_RX 0x
+#define I2C_DMA_HARD_RST 0x0002
+
+#define MAX_ST_MODE_SPEED 10
+#define MAX_FS_MODE_SPEED 40
+#define MAX_HS_MODE_SPEED 340
+#define MAX_SAMPLE_CNT_DIV 8
+#define MAX_STEP_CNT_DIV 64
+#define MAX_HS_STEP_CNT_DIV8
+#define I2C_DEFAULT_CLK_DIV4
+
+#define MAX_I2C_ADDR 0x7f
+#define MAX_I2C_LEN0xff
+#define TRANS_ADDR_ONLYBIT(8)
+#define TRANSFER_TIMEOUT 5 /* us */
+#define I2C_FIFO_STAT1_MASK0x001f
+#define TIMING_SAMPLE_OFFSET 8
+#define HS_SAMPLE_OFFSET 12
+#define HS_STEP_OFFSET 8
+
+#define I2C_CONTROL_WRAPPERBIT(0)
+#define I2C_CONTROL_RS BIT(1)
+#define I2C_CONTROL_DMA_EN BIT(2)
+#define I2C_CONTROL_CLK_EXT_EN BIT(3)
+#define I2C_CONTROL_DIR_CHANGE BIT(4)
+#define I2C_CONTROL_ACKERR_DET_EN BIT(5)
+#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6)
+#define I2C_CONTROL_DMAACK BIT(8)
+#define I2C_CONTROL_ASYNC BIT(9)
+
+enum I2C_REGS_OFFSET {
+ REG_PORT = 0x0,
+ REG_SLAVE_ADDR = 0x04,
+ REG_INTR_MASK = 0x08,
+ REG_INTR_STAT = 0x0c,
+ REG_CONTROL = 0x10,
+ REG_TRANSFER_LEN = 0x14,
+ REG_TRANSAC_LEN = 0x18,
+ REG_DELAY_LEN = 0x1c,
+ REG_TIMING = 0x20,
+ REG_START = 0x24,
+ REG_EXT_CONF = 0x28,
+ REG_FIFO_STAT1 = 0x2c,
+ REG_FIFO_STAT = 0x30,
+ REG_FIFO_THRESH = 0x34,
+ REG_FIFO_ADDR_CLR =