From patchwork Wed Mar 25 10:07:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wengbj X-Patchwork-Id: 454338 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 1B61C1400B7 for ; Wed, 25 Mar 2015 21:08:05 +1100 (AEDT) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id D1BFD28BEB2; Wed, 25 Mar 2015 11:07:23 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00 autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 9D44F28BEB2 for ; Wed, 25 Mar 2015 11:07:12 +0100 (CET) X-policyd-weight: using cached result; rate: -5.5 Received: from regular1.263xmail.com (regular1.263xmail.com [211.150.99.135]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Wed, 25 Mar 2015 11:07:02 +0100 (CET) Received: from fl.service?t-firefly.com (unknown [192.168.167.11]) by regular1.263xmail.com (Postfix) with SMTP id A838019855; Wed, 25 Mar 2015 18:07:27 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 1 Received: from mae.263xmail.com (out134-29.mxttb2.hichina.com [218.244.134.29]) by smtp.263.net (Postfix) with ESMTP id 810ED427; Wed, 25 Mar 2015 18:07:26 +0800 (CST) Received: from fl.service?t-firefly.com (localhost [127.0.0.1]) by mae.263xmail.com (Postfix) with SMTP id 5D3FA27ED08; Wed, 25 Mar 2015 18:07:28 +0800 (CST) X-MAE-MAIL_UID: 00551288df08b7dc@maes@17f9a9ccff51b93e X-MAE-ID: 223.6.254.61 X-RL-NAME: fl.service@t-firefly.com X-LOGIN-NAME: fl.service@t-firefly.com X-SENDER-IP: 183.32.175.141 X-SENDER: fl.service@t-firefly.com From: wengbj To: blogic@openwrt.org Date: Wed, 25 Mar 2015 18:07:48 +0800 Message-Id: <1427278068-14853-1-git-send-email-fl.service@t-firefly.com> X-Mailer: git-send-email 1.7.9.5 Cc: fl.service@t-firefly.com, zxf@t-chip.com.cn, linux.c@foxmail.com, dxj@t-chip.com.cn, wbj@t-chip.com.cn, openwrt-devel@lists.openwrt.org Subject: [OpenWrt-Devel] [PATCH] ralink: MT7621 add i2c controller driver X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" ralink i2c driver is not working on MT7621 platform. Porting a new drivers from MTK's source code. Signed-off-by: Jay Weng --- package/kernel/linux/modules/fs.mk | 4 +- package/kernel/linux/modules/usb.mk | 13 +- target/linux/ramips/dts/FIREWRT.dts | 2 +- target/linux/ramips/image/Makefile | 2 +- target/linux/ramips/mt7621/config-3.18 | 16 +- .../0111-i2c-MIPS-add-mt7621-I2C-driver.patch | 335 ++++++++++++++++++++ 6 files changed, 359 insertions(+), 13 deletions(-) create mode 100755 target/linux/ramips/patches-3.18/0111-i2c-MIPS-add-mt7621-I2C-driver.patch diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk index 64182e6..e3e8c57 100644 --- a/package/kernel/linux/modules/fs.mk +++ b/package/kernel/linux/modules/fs.mk @@ -156,8 +156,8 @@ define KernelPackage/fs-ext4 SUBMENU:=$(FS_MENU) TITLE:=EXT4 filesystem support KCONFIG:= \ - CONFIG_EXT4_FS \ - CONFIG_JBD2 + CONFIG_EXT4_FS=y \ + CONFIG_JBD2=y FILES:= \ $(LINUX_DIR)/fs/ext4/ext4.ko \ $(LINUX_DIR)/fs/jbd2/jbd2.ko \ diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk index be1553a..fa01a65 100644 --- a/package/kernel/linux/modules/usb.mk +++ b/package/kernel/linux/modules/usb.mk @@ -15,7 +15,7 @@ define KernelPackage/usb-core SUBMENU:=$(USB_MENU) TITLE:=Support for USB DEPENDS:=@USB_SUPPORT - KCONFIG:=CONFIG_USB CONFIG_XPS_USB_HCD_XILINX=n CONFIG_USB_FHCI_HCD=n + KCONFIG:=CONFIG_USB=y CONFIG_XPS_USB_HCD_XILINX=n CONFIG_USB_FHCI_HCD=n FILES:= \ $(LINUX_DIR)/drivers/usb/core/usbcore.ko \ $(LINUX_DIR)/drivers/usb/usb-common.ko@lt3.16 \ @@ -168,7 +168,7 @@ $(eval $(call KernelPackage,usb-phy-omap-usb2)) define KernelPackage/usb-phy-omap-usb3 TITLE:=Support for OMAP USB3 PHY - KCONFIG:=CONFIG_OMAP_USB3 + KCONFIG:=CONFIG_OMAP_USB3=y DEPENDS:=@TARGET_omap +kmod-usb-phy-omap-usb2 FILES:=$(LINUX_DIR)/drivers/usb/phy/phy-omap-usb3.ko AUTOLOAD:=$(call AutoLoad,45,phy-omap-usb3) @@ -873,8 +873,7 @@ $(eval $(call KernelPackage,usb-serial-qualcomm)) define KernelPackage/usb-storage TITLE:=USB Storage support DEPENDS:= +kmod-scsi-core - KCONFIG:=CONFIG_USB_STORAGE - FILES:=$(LINUX_DIR)/drivers/usb/storage/usb-storage.ko + KCONFIG:= CONFIG_USB_STORAGE=y AUTOLOAD:=$(call AutoProbe,usb-storage,1) $(call AddDepends/usb) endef @@ -1477,9 +1476,9 @@ define KernelPackage/usb3 TITLE:=Support for USB3 controllers DEPENDS:=+TARGET_omap:kmod-usb-phy-omap-usb3 KCONFIG:= \ - CONFIG_USB_XHCI_HCD \ - CONFIG_USB_XHCI_PCI \ - CONFIG_USB_XHCI_PLATFORM \ + CONFIG_USB_XHCI_HCD=y \ + CONFIG_USB_XHCI_PCI=y \ + CONFIG_USB_XHCI_PLATFORM=y \ CONFIG_USB_XHCI_HCD_DEBUGGING=n FILES:= \ $(XHCI_FILES) diff --git a/target/linux/ramips/dts/FIREWRT.dts b/target/linux/ramips/dts/FIREWRT.dts index 54f0e55..e25a035 100644 --- a/target/linux/ramips/dts/FIREWRT.dts +++ b/target/linux/ramips/dts/FIREWRT.dts @@ -12,7 +12,7 @@ }; chosen { - bootargs = "console=ttyS0,57600"; + bootargs = "console=ttyS0,57600 root=/dev/sda1 rw rootwait init=/bin/bash"; }; sdhci@10130000 { diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile index 45ae3a5..13fac3b 100644 --- a/target/linux/ramips/image/Makefile +++ b/target/linux/ramips/image/Makefile @@ -901,7 +901,7 @@ endif # ifeq ($(SUBTARGET),mt7621) - TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt + TARGET_DEVICES += firewrt endif define Device/mt7621 diff --git a/target/linux/ramips/mt7621/config-3.18 b/target/linux/ramips/mt7621/config-3.18 index 11d372b..2b7bea1 100644 --- a/target/linux/ramips/mt7621/config-3.18 +++ b/target/linux/ramips/mt7621/config-3.18 @@ -34,6 +34,10 @@ CONFIG_CPU_RMAP=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRC16=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y CONFIG_CSRC_R4K=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y @@ -41,6 +45,8 @@ CONFIG_DMA_NONCOHERENT=y CONFIG_DTB_RT_NONE=y CONFIG_DTC=y CONFIG_EARLY_PRINTK=y +CONFIG_EXT4_FS=y +CONFIG_FS_MBCACHE=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y @@ -99,6 +105,7 @@ CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_IRQ_GIC=y CONFIG_IRQ_WORK=y +CONFIG_JBD2=y CONFIG_LIBFDT=y CONFIG_MDIO_BOARDINFO=y CONFIG_MIPS=y @@ -126,13 +133,13 @@ CONFIG_MTD_SPLIT_FIRMWARE=y CONFIG_MTD_SPLIT_SEAMA_FW=y CONFIG_MTD_SPLIT_TRX_FW=y CONFIG_MTD_SPLIT_UIMAGE_FW=y -# CONFIG_MTK_MTD_NAND is not set CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NET_FLOW_LIMIT=y CONFIG_NET_RALINK=y CONFIG_NET_RALINK_GSW_MT7620=y CONFIG_NET_RALINK_MDIO=y CONFIG_NET_RALINK_MT7620=y +CONFIG_NLS=y CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y # CONFIG_NO_IOPORT_MAP is not set CONFIG_NR_CPUS=4 @@ -173,7 +180,7 @@ CONFIG_RESET_CONTROLLER=y CONFIG_RFS_ACCEL=y CONFIG_RPS=y CONFIG_SCHED_SMT=y -# CONFIG_SCSI_DMA is not set +CONFIG_SCSI=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_SLAB is not set @@ -206,11 +213,16 @@ CONFIG_SYS_SUPPORTS_SCHED_SMT=y CONFIG_SYS_SUPPORTS_SMP=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TREE_RCU=y +CONFIG_USB=y +CONFIG_USB_COMMON=y # CONFIG_USB_EHCI_HCD is not set CONFIG_USB_MT7621_XHCI_PLATFORM=y CONFIG_USB_PHY=y +CONFIG_USB_STORAGE=y CONFIG_USB_SUPPORT=y # CONFIG_USB_UHCI_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y CONFIG_USB_XHCI_PLATFORM=y CONFIG_USE_OF=y CONFIG_WATCHDOG_CORE=y diff --git a/target/linux/ramips/patches-3.18/0111-i2c-MIPS-add-mt7621-I2C-driver.patch b/target/linux/ramips/patches-3.18/0111-i2c-MIPS-add-mt7621-I2C-driver.patch new file mode 100755 index 0000000..5df95f4 --- /dev/null +++ b/target/linux/ramips/patches-3.18/0111-i2c-MIPS-add-mt7621-I2C-driver.patch @@ -0,0 +1,335 @@ +Index: linux-3.18.9/drivers/i2c/busses/Kconfig +=================================================================== +--- linux-3.18.9.orig/drivers/i2c/busses/Kconfig 2015-03-23 15:00:11.730403938 +0800 ++++ linux-3.18.9/drivers/i2c/busses/Kconfig 2015-03-23 15:00:11.982403926 +0800 +@@ -714,6 +714,10 @@ + tristate "Ralink I2C Controller" + select OF_I2C + ++config I2C_MT7621 ++ tristate "MT7621 I2C Controller" ++ select OF_I2C ++ + config HAVE_S3C2410_I2C + bool + help +Index: linux-3.18.9/drivers/i2c/busses/Makefile +=================================================================== +--- linux-3.18.9.orig/drivers/i2c/busses/Makefile 2015-03-23 15:00:11.730403938 +0800 ++++ linux-3.18.9/drivers/i2c/busses/Makefile 2015-03-23 15:00:11.982403926 +0800 +@@ -67,6 +67,7 @@ + obj-$(CONFIG_I2C_PXA) += i2c-pxa.o + obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o + obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o ++obj-$(CONFIG_I2C_MT7621) += i2c-mt7621.o + obj-$(CONFIG_I2C_QUP) += i2c-qup.o + obj-$(CONFIG_I2C_RIIC) += i2c-riic.o + obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o +Index: linux-3.18.9/drivers/i2c/busses/i2c-mt7621.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.18.9/drivers/i2c/busses/i2c-mt7621.c 2015-03-23 16:31:42.684747034 +0800 +@@ -0,0 +1,303 @@ ++/* ++ * drivers/i2c/busses/i2c-mt7621.c ++ * ++ * Copyright (C) 2013 Steven Liu ++ * ++ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus. ++ * (C) 2014 Sittisak ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define REG_CONFIG_REG 0x00 ++#define REG_CLKDIV_REG 0x04 ++#define REG_DEVADDR_REG 0x08 ++#define REG_ADDR_REG 0x0C ++#define REG_DATAOUT_REG 0x10 ++#define REG_DATAIN_REG 0x14 ++#define REG_STATUS_REG 0x18 ++#define REG_STARTXFR_REG 0x1C ++#define REG_BYTECNT_REG 0x20 ++#define REG_SM0_IS_AUTOMODE 0x28 ++#define REG_SM0CTL0 0x40 ++ ++ ++#define I2C_STARTERR 0x10 ++#define I2C_ACKERR 0x08 ++#define I2C_DATARDY 0x04 ++#define I2C_SDOEMPTY 0x02 ++#define I2C_BUSY 0x01 ++ ++/* I2C_CFG register bit field */ ++#define I2C_CFG_ADDRLEN_8 (7<<5) /* 8 bits */ ++#define I2C_CFG_DEVADLEN_7 (6<<2) ++#define I2C_CFG_ADDRDIS BIT(1) ++#define I2C_CFG_DEVADDIS BIT(0) ++ ++#define I2C_CFG_DEFAULT (I2C_CFG_ADDRLEN_8 | \ ++ I2C_CFG_DEVADLEN_7 | \ ++ I2C_CFG_ADDRDIS) ++ ++#define I2C_RETRY 0x1000 ++ ++#define CLKDIV_VALUE 333 ++#define i2c_busy_loop (CLKDIV_VALUE*30) ++ ++#define READ_CMD 0x01 ++#define WRITE_CMD 0x00 ++#define READ_BLOCK 16 ++ ++#define SM0_ODRAIN BIT(31) ++#define SM0_VSYNC_MODE BIT(28) ++#define SM0_CLK_DIV (CLKDIV_VALUE << 16) ++#define SM0_WAIT_LEVEL BIT(6) ++#define SM0_EN BIT(1) ++ ++#define SM0_CFG_DEFUALT (SM0_ODRAIN | SM0_VSYNC_MODE | \ ++ SM0_CLK_DIV | SM0_WAIT_LEVEL | \ ++ SM0_EN) ++/***********************************************************/ ++ ++static void __iomem *membase; ++static struct i2c_adapter *adapter; ++ ++static void rt_i2c_w32(u32 val, unsigned reg) ++{ ++ iowrite32(val, membase + reg); ++} ++ ++static u32 rt_i2c_r32(unsigned reg) ++{ ++ return ioread32(membase + reg); ++} ++ ++static void mt7621_i2c_reset(struct i2c_adapter *a) ++{ ++ device_reset(a->dev.parent); ++} ++static void mt7621_i2c_enable(struct i2c_msg *msg) ++{ ++ rt_i2c_w32(msg->addr,REG_DEVADDR_REG); ++ rt_i2c_w32(0,REG_ADDR_REG); ++} ++ ++static void i2c_master_init(struct i2c_adapter *a) ++{ ++ mt7621_i2c_reset(a); ++ rt_i2c_w32(I2C_CFG_DEFAULT,REG_CONFIG_REG); ++ rt_i2c_w32(SM0_CFG_DEFUALT,REG_SM0CTL0); ++ rt_i2c_w32(1,REG_SM0_IS_AUTOMODE);//auto mode ++} ++ ++ ++static inline int rt_i2c_wait_rx_done(void) ++{ ++ int i=0; ++ while((!(rt_i2c_r32(REG_STATUS_REG) & I2C_DATARDY)) && (i=i2c_busy_loop){ ++ pr_err("err,wait for idle timeout"); ++ return -ETIMEDOUT; ++ } ++ return 0; ++} ++ ++static inline int rt_i2c_wait_idle(void) ++{ ++ int i=0; ++ while((rt_i2c_r32(REG_STATUS_REG) & I2C_BUSY) && (i=i2c_busy_loop){ ++ pr_err("err,wait for idle timeout"); ++ return -ETIMEDOUT; ++ } ++ return 0; ++} ++ ++static inline int rt_i2c_wait_tx_done(void) ++{ ++ int i=0; ++ while((!(rt_i2c_r32(REG_STATUS_REG) & I2C_SDOEMPTY)) && (i=i2c_busy_loop){ ++ pr_err("err,wait for idle timeout"); ++ return -ETIMEDOUT; ++ } ++ return 0; ++} ++ ++static int rt_i2c_handle_msg(struct i2c_adapter *a, struct i2c_msg* msg) ++{ ++ int i = 0, j = 0, pos = 0; ++ int nblock = msg->len / READ_BLOCK; ++ int rem = msg->len % READ_BLOCK; ++ ++ if (msg->flags & I2C_M_TEN) { ++ printk("10 bits addr not supported\n"); ++ return -EINVAL; ++ } ++ ++ if (msg->flags & I2C_M_RD) { ++ for (i = 0; i < nblock; i++) { ++ if (rt_i2c_wait_idle()) ++ goto err_timeout; ++ rt_i2c_w32(READ_BLOCK - 1, REG_BYTECNT_REG); ++ rt_i2c_w32(READ_CMD, REG_STARTXFR_REG); ++ for (j = 0; j < READ_BLOCK; j++) { ++ if (rt_i2c_wait_rx_done()) ++ goto err_timeout; ++ msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG); ++ } ++ } ++ ++ if (rt_i2c_wait_idle()) ++ goto err_timeout; ++ rt_i2c_w32(rem - 1, REG_BYTECNT_REG); ++ rt_i2c_w32(READ_CMD, REG_STARTXFR_REG); ++ ++ for (i = 0; i < rem; i++) { ++ if (rt_i2c_wait_rx_done()) ++ goto err_timeout; ++ msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG); ++ } ++ } else { ++ if (rt_i2c_wait_idle()) ++ goto err_timeout; ++ rt_i2c_w32(msg->len - 1, REG_BYTECNT_REG); ++ for (i = 0; i < msg->len; i++) { ++ rt_i2c_w32(msg->buf[i], REG_DATAOUT_REG); ++ if(i == 0) ++ rt_i2c_w32(WRITE_CMD, REG_STARTXFR_REG); ++ ++ if (rt_i2c_wait_tx_done()) ++ goto err_timeout; ++ } ++ } ++ ++ return 0; ++err_timeout: ++ return -ETIMEDOUT; ++} ++ ++static int rt_i2c_master_xfer(struct i2c_adapter *a, struct i2c_msg *m, int n) ++{ ++ int i = 0; ++ int ret = 0; ++ i2c_master_init(a); ++ mt7621_i2c_enable(m); ++ ++ for (i = 0; i != n && ret==0; i++) { ++ ret = rt_i2c_handle_msg(a, &m[i]); ++ if (ret) ++ return ret; ++ } ++ return i; ++} ++ ++static u32 rt_i2c_func(struct i2c_adapter *a) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; ++} ++ ++static const struct i2c_algorithm rt_i2c_algo = { ++ .master_xfer = rt_i2c_master_xfer, ++ .functionality = rt_i2c_func, ++}; ++ ++static int rt_i2c_probe(struct platform_device *pdev) ++{ ++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ int ret; ++ ++ adapter = devm_kzalloc(&pdev->dev,sizeof(struct i2c_adapter), GFP_KERNEL); ++ if (!adapter) { ++ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n"); ++ return -ENOMEM; ++ } ++ membase = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(membase)) ++ return PTR_ERR(membase); ++ ++ strlcpy(adapter->name, dev_name(&pdev->dev), sizeof(adapter->name)); ++ ++ adapter->owner = THIS_MODULE; ++ adapter->nr = pdev->id; ++ adapter->timeout = HZ; ++ adapter->algo = &rt_i2c_algo; ++ adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; ++ adapter->dev.parent = &pdev->dev; ++ adapter->dev.of_node = pdev->dev.of_node; ++ ++ platform_set_drvdata(pdev, adapter); ++ ++ ret = i2c_add_numbered_adapter(adapter); ++ if (ret) ++ return ret; ++ ++ dev_info(&pdev->dev,"loaded"); ++ ++ return 0; ++} ++ ++static int rt_i2c_remove(struct platform_device *pdev) ++{ ++ platform_set_drvdata(pdev, NULL); ++ return 0; ++} ++ ++static const struct of_device_id i2c_rt_dt_ids[] = { ++ { .compatible = "ralink,i2c-mt7621", }, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids); ++ ++static struct platform_driver rt_i2c_driver = { ++ .probe = rt_i2c_probe, ++ .remove = rt_i2c_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "i2c-mt7621", ++ .of_match_table = i2c_rt_dt_ids, ++ }, ++}; ++ ++static int __init i2c_rt_init (void) ++{ ++ return platform_driver_register(&rt_i2c_driver); ++} ++ ++static void __exit i2c_rt_exit (void) ++{ ++ platform_driver_unregister(&rt_i2c_driver); ++} ++module_init (i2c_rt_init); ++module_exit (i2c_rt_exit); ++ ++MODULE_AUTHOR("Steven Liu "); ++MODULE_DESCRIPTION("MT7621 I2c host driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:MT7621-I2C");