<html><head><meta http-equiv="content-type" content="text/html; charset=GB2312"><style>body { line-height: 1.5; }blockquote { margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em; }body { font-size: 10.5pt; font-family: ËÎÌå; color: rgb(0, 0, 0); line-height: 1.5; }</style></head><body>
<div><span></span>Dear All:</div><div><span style="background-color: rgba(0, 0, 0, 0);">    Oh , i am sorry . Please ignore this patch .</span></div><div><span style="background-color: rgba(0, 0, 0, 0);">    i will send a new version .</span></div>
<div><br></div><hr style="width: 210px; height: 1px;" color="#b5c4df" size="1" align="left">
<div><span><div style="MARGIN: 10px; FONT-FAMILY: verdana; FONT-SIZE: 10pt"><b style="color: rgb(51, 51, 153); font-size: 14px; line-height: 21px; font-family: Calibri;"><div style="font-size: 15px; line-height: normal;"><font color="#333399">Best Regards.</font></div><div style="font-size: 15px; line-height: normal;"><font color="#333399">Jay Weng</font></div><div style="font-size: 15px; line-height: normal;"><font color="#333399"><br></font></div><div style="font-size: 15px; line-height: normal;"><img src="cid:_Foxmail.1@6d1179e6-4a37-8230-8d42-8a331ea3e8bb" border="0" style="max-width: 100%; height: auto !important;"></div><div style="font-size: 15px; line-height: normal;"><font color="#333399"><span style="line-height: 1.5; background-color: window;"></span><span style="background-color: window;">Website:  </span><span style="line-height: 1.5; background-color: window;">www.t-firefly.com</span></font></div><div style="font-size: 15px; line-height: normal;"><span style="line-height: 1.5; background-color: window;"><font color="#333399">E-mail:  fl.</font></span><span style="background-color: rgba(0, 0, 0, 0); line-height: 1.5;">service@t-firefly.com</span></div></b></div></span></div>
<blockquote style="margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em;"><div> </div><div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm"><div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px;FONT-FAMILY:tahoma;COLOR:#000000; BACKGROUND: #efefef; PADDING-BOTTOM: 8px; PADDING-TOP: 8px"><div><b>From:</b> <a href="mailto:fl.service@t-firefly.com">wengbj</a></div><div><b>Date:</b> 2015-03-25 18:07</div><div><b>To:</b> <a href="mailto:blogic@openwrt.org">blogic</a></div><div><b>CC:</b> <a href="mailto:openwrt-devel@lists.openwrt.org">openwrt-devel</a>; <a href="mailto:linux.c@foxmail.com">linux.c</a>; <a href="mailto:fl.service@t-firefly.com">fl.service</a>; <a href="mailto:wbj@t-chip.com.cn">wbj</a>; <a href="mailto:zxf@t-chip.com.cn">zxf</a>; <a href="mailto:dxj@t-chip.com.cn">dxj</a></div><div><b>Subject:</b> [PATCH] ralink: MT7621 add i2c controller driver</div></div></div><div><div>ralink i2c driver is not working on MT7621 platform. Porting a new drivers from MTK's source code.</div>
<div> </div>
<div>Signed-off-by: Jay Weng <fl.service@t-firefly.com></div>
<div>---</div>
<div> package/kernel/linux/modules/fs.mk                 |    4 +-</div>
<div> package/kernel/linux/modules/usb.mk                |   13 +-</div>
<div> target/linux/ramips/dts/FIREWRT.dts                |    2 +-</div>
<div> target/linux/ramips/image/Makefile                 |    2 +-</div>
<div> target/linux/ramips/mt7621/config-3.18             |   16 +-</div>
<div> .../0111-i2c-MIPS-add-mt7621-I2C-driver.patch      |  335 ++++++++++++++++++++</div>
<div> 6 files changed, 359 insertions(+), 13 deletions(-)</div>
<div> create mode 100755 target/linux/ramips/patches-3.18/0111-i2c-MIPS-add-mt7621-I2C-driver.patch</div>
<div> </div>
<div>diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk</div>
<div>index 64182e6..e3e8c57 100644</div>
<div>--- a/package/kernel/linux/modules/fs.mk</div>
<div>+++ b/package/kernel/linux/modules/fs.mk</div>
<div>@@ -156,8 +156,8 @@ define KernelPackage/fs-ext4</div>
<div>   SUBMENU:=$(FS_MENU)</div>
<div>   TITLE:=EXT4 filesystem support</div>
<div>   KCONFIG:= \</div>
<div>-    CONFIG_EXT4_FS \</div>
<div>-    CONFIG_JBD2</div>
<div>+    CONFIG_EXT4_FS=y \</div>
<div>+    CONFIG_JBD2=y</div>
<div>   FILES:= \</div>
<div>     $(LINUX_DIR)/fs/ext4/ext4.ko \</div>
<div>     $(LINUX_DIR)/fs/jbd2/jbd2.ko \</div>
<div>diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk</div>
<div>index be1553a..fa01a65 100644</div>
<div>--- a/package/kernel/linux/modules/usb.mk</div>
<div>+++ b/package/kernel/linux/modules/usb.mk</div>
<div>@@ -15,7 +15,7 @@ define KernelPackage/usb-core</div>
<div>   SUBMENU:=$(USB_MENU)</div>
<div>   TITLE:=Support for USB</div>
<div>   DEPENDS:=@USB_SUPPORT</div>
<div>-  KCONFIG:=CONFIG_USB CONFIG_XPS_USB_HCD_XILINX=n CONFIG_USB_FHCI_HCD=n</div>
<div>+  KCONFIG:=CONFIG_USB=y CONFIG_XPS_USB_HCD_XILINX=n CONFIG_USB_FHCI_HCD=n</div>
<div>   FILES:= \</div>
<div>     $(LINUX_DIR)/drivers/usb/core/usbcore.ko \</div>
<div>     $(LINUX_DIR)/drivers/usb/usb-common.ko@lt3.16 \</div>
<div>@@ -168,7 +168,7 @@ $(eval $(call KernelPackage,usb-phy-omap-usb2))</div>
<div> </div>
<div> define KernelPackage/usb-phy-omap-usb3</div>
<div>   TITLE:=Support for OMAP USB3 PHY</div>
<div>-  KCONFIG:=CONFIG_OMAP_USB3</div>
<div>+  KCONFIG:=CONFIG_OMAP_USB3=y</div>
<div>   DEPENDS:=@TARGET_omap +kmod-usb-phy-omap-usb2</div>
<div>   FILES:=$(LINUX_DIR)/drivers/usb/phy/phy-omap-usb3.ko</div>
<div>   AUTOLOAD:=$(call AutoLoad,45,phy-omap-usb3)</div>
<div>@@ -873,8 +873,7 @@ $(eval $(call KernelPackage,usb-serial-qualcomm))</div>
<div> define KernelPackage/usb-storage</div>
<div>   TITLE:=USB Storage support</div>
<div>   DEPENDS:= +kmod-scsi-core</div>
<div>-  KCONFIG:=CONFIG_USB_STORAGE</div>
<div>-  FILES:=$(LINUX_DIR)/drivers/usb/storage/usb-storage.ko</div>
<div>+  KCONFIG:= CONFIG_USB_STORAGE=y</div>
<div>   AUTOLOAD:=$(call AutoProbe,usb-storage,1)</div>
<div>   $(call AddDepends/usb)</div>
<div> endef</div>
<div>@@ -1477,9 +1476,9 @@ define KernelPackage/usb3</div>
<div>   TITLE:=Support for USB3 controllers</div>
<div>   DEPENDS:=+TARGET_omap:kmod-usb-phy-omap-usb3</div>
<div>   KCONFIG:= \</div>
<div>-    CONFIG_USB_XHCI_HCD \</div>
<div>-    CONFIG_USB_XHCI_PCI \</div>
<div>-    CONFIG_USB_XHCI_PLATFORM \</div>
<div>+    CONFIG_USB_XHCI_HCD=y \</div>
<div>+    CONFIG_USB_XHCI_PCI=y \</div>
<div>+    CONFIG_USB_XHCI_PLATFORM=y \</div>
<div>     CONFIG_USB_XHCI_HCD_DEBUGGING=n</div>
<div>   FILES:= \</div>
<div>     $(XHCI_FILES)</div>
<div>diff --git a/target/linux/ramips/dts/FIREWRT.dts b/target/linux/ramips/dts/FIREWRT.dts</div>
<div>index 54f0e55..e25a035 100644</div>
<div>--- a/target/linux/ramips/dts/FIREWRT.dts</div>
<div>+++ b/target/linux/ramips/dts/FIREWRT.dts</div>
<div>@@ -12,7 +12,7 @@</div>
<div>     };</div>
<div> </div>
<div>     chosen {</div>
<div>-            bootargs = "console=ttyS0,57600";</div>
<div>+            bootargs = "console=ttyS0,57600 root=/dev/sda1 rw rootwait init=/bin/bash";</div>
<div>     };</div>
<div> </div>
<div>     sdhci@10130000 {</div>
<div>diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile</div>
<div>index 45ae3a5..13fac3b 100644</div>
<div>--- a/target/linux/ramips/image/Makefile</div>
<div>+++ b/target/linux/ramips/image/Makefile</div>
<div>@@ -901,7 +901,7 @@ endif</div>
<div> #</div>
<div> </div>
<div> ifeq ($(SUBTARGET),mt7621)</div>
<div>-  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt</div>
<div>+  TARGET_DEVICES += firewrt</div>
<div> endif</div>
<div> </div>
<div> define Device/mt7621</div>
<div>diff --git a/target/linux/ramips/mt7621/config-3.18 b/target/linux/ramips/mt7621/config-3.18</div>
<div>index 11d372b..2b7bea1 100644</div>
<div>--- a/target/linux/ramips/mt7621/config-3.18</div>
<div>+++ b/target/linux/ramips/mt7621/config-3.18</div>
<div>@@ -34,6 +34,10 @@ CONFIG_CPU_RMAP=y</div>
<div> CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y</div>
<div> CONFIG_CPU_SUPPORTS_HIGHMEM=y</div>
<div> CONFIG_CPU_SUPPORTS_MSA=y</div>
<div>+CONFIG_CRC16=y</div>
<div>+CONFIG_CRYPTO_CRC32C=y</div>
<div>+CONFIG_CRYPTO_HASH=y</div>
<div>+CONFIG_CRYPTO_HASH2=y</div>
<div> CONFIG_CSRC_R4K=y</div>
<div> CONFIG_DEBUG_PINCTRL=y</div>
<div> CONFIG_DMA_NONCOHERENT=y</div>
<div>@@ -41,6 +45,8 @@ CONFIG_DMA_NONCOHERENT=y</div>
<div> CONFIG_DTB_RT_NONE=y</div>
<div> CONFIG_DTC=y</div>
<div> CONFIG_EARLY_PRINTK=y</div>
<div>+CONFIG_EXT4_FS=y</div>
<div>+CONFIG_FS_MBCACHE=y</div>
<div> CONFIG_GENERIC_ATOMIC64=y</div>
<div> CONFIG_GENERIC_CLOCKEVENTS=y</div>
<div> CONFIG_GENERIC_CLOCKEVENTS_BUILD=y</div>
<div>@@ -99,6 +105,7 @@ CONFIG_IRQ_DOMAIN=y</div>
<div> CONFIG_IRQ_FORCED_THREADING=y</div>
<div> CONFIG_IRQ_GIC=y</div>
<div> CONFIG_IRQ_WORK=y</div>
<div>+CONFIG_JBD2=y</div>
<div> CONFIG_LIBFDT=y</div>
<div> CONFIG_MDIO_BOARDINFO=y</div>
<div> CONFIG_MIPS=y</div>
<div>@@ -126,13 +133,13 @@ CONFIG_MTD_SPLIT_FIRMWARE=y</div>
<div> CONFIG_MTD_SPLIT_SEAMA_FW=y</div>
<div> CONFIG_MTD_SPLIT_TRX_FW=y</div>
<div> CONFIG_MTD_SPLIT_UIMAGE_FW=y</div>
<div>-# CONFIG_MTK_MTD_NAND is not set</div>
<div> CONFIG_NEED_DMA_MAP_STATE=y</div>
<div> CONFIG_NET_FLOW_LIMIT=y</div>
<div> CONFIG_NET_RALINK=y</div>
<div> CONFIG_NET_RALINK_GSW_MT7620=y</div>
<div> CONFIG_NET_RALINK_MDIO=y</div>
<div> CONFIG_NET_RALINK_MT7620=y</div>
<div>+CONFIG_NLS=y</div>
<div> CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y</div>
<div> # CONFIG_NO_IOPORT_MAP is not set</div>
<div> CONFIG_NR_CPUS=4</div>
<div>@@ -173,7 +180,7 @@ CONFIG_RESET_CONTROLLER=y</div>
<div> CONFIG_RFS_ACCEL=y</div>
<div> CONFIG_RPS=y</div>
<div> CONFIG_SCHED_SMT=y</div>
<div>-# CONFIG_SCSI_DMA is not set</div>
<div>+CONFIG_SCSI=y</div>
<div> CONFIG_SERIAL_8250_NR_UARTS=4</div>
<div> CONFIG_SERIAL_OF_PLATFORM=y</div>
<div> # CONFIG_SLAB is not set</div>
<div>@@ -206,11 +213,16 @@ CONFIG_SYS_SUPPORTS_SCHED_SMT=y</div>
<div> CONFIG_SYS_SUPPORTS_SMP=y</div>
<div> CONFIG_TICK_CPU_ACCOUNTING=y</div>
<div> CONFIG_TREE_RCU=y</div>
<div>+CONFIG_USB=y</div>
<div>+CONFIG_USB_COMMON=y</div>
<div> # CONFIG_USB_EHCI_HCD is not set</div>
<div> CONFIG_USB_MT7621_XHCI_PLATFORM=y</div>
<div> CONFIG_USB_PHY=y</div>
<div>+CONFIG_USB_STORAGE=y</div>
<div> CONFIG_USB_SUPPORT=y</div>
<div> # CONFIG_USB_UHCI_HCD is not set</div>
<div>+CONFIG_USB_XHCI_HCD=y</div>
<div>+CONFIG_USB_XHCI_PCI=y</div>
<div> CONFIG_USB_XHCI_PLATFORM=y</div>
<div> CONFIG_USE_OF=y</div>
<div> CONFIG_WATCHDOG_CORE=y</div>
<div>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</div>
<div>new file mode 100755</div>
<div>index 0000000..5df95f4</div>
<div>--- /dev/null</div>
<div>+++ b/target/linux/ramips/patches-3.18/0111-i2c-MIPS-add-mt7621-I2C-driver.patch</div>
<div>@@ -0,0 +1,335 @@</div>
<div>+Index: linux-3.18.9/drivers/i2c/busses/Kconfig</div>
<div>+===================================================================</div>
<div>+--- linux-3.18.9.orig/drivers/i2c/busses/Kconfig    2015-03-23 15:00:11.730403938 +0800</div>
<div>++++ linux-3.18.9/drivers/i2c/busses/Kconfig 2015-03-23 15:00:11.982403926 +0800</div>
<div>+@@ -714,6 +714,10 @@</div>
<div>+    tristate "Ralink I2C Controller"</div>
<div>+    select OF_I2C</div>
<div>+ </div>
<div>++config I2C_MT7621</div>
<div>++   tristate "MT7621 I2C Controller"</div>
<div>++   select OF_I2C</div>
<div>++</div>
<div>+ config HAVE_S3C2410_I2C</div>
<div>+    bool</div>
<div>+    help</div>
<div>+Index: linux-3.18.9/drivers/i2c/busses/Makefile</div>
<div>+===================================================================</div>
<div>+--- linux-3.18.9.orig/drivers/i2c/busses/Makefile   2015-03-23 15:00:11.730403938 +0800</div>
<div>++++ linux-3.18.9/drivers/i2c/busses/Makefile        2015-03-23 15:00:11.982403926 +0800</div>
<div>+@@ -67,6 +67,7 @@</div>
<div>+ obj-$(CONFIG_I2C_PXA)              += i2c-pxa.o</div>
<div>+ obj-$(CONFIG_I2C_PXA_PCI)  += i2c-pxa-pci.o</div>
<div>+ obj-$(CONFIG_I2C_RALINK)   += i2c-ralink.o</div>
<div>++obj-$(CONFIG_I2C_MT7621)   += i2c-mt7621.o</div>
<div>+ obj-$(CONFIG_I2C_QUP)              += i2c-qup.o</div>
<div>+ obj-$(CONFIG_I2C_RIIC)             += i2c-riic.o</div>
<div>+ obj-$(CONFIG_I2C_RK3X)             += i2c-rk3x.o</div>
<div>+Index: linux-3.18.9/drivers/i2c/busses/i2c-mt7621.c</div>
<div>+===================================================================</div>
<div>+--- /dev/null       1970-01-01 00:00:00.000000000 +0000</div>
<div>++++ linux-3.18.9/drivers/i2c/busses/i2c-mt7621.c    2015-03-23 16:31:42.684747034 +0800</div>
<div>+@@ -0,0 +1,303 @@</div>
<div>++/*</div>
<div>++ * drivers/i2c/busses/i2c-mt7621.c</div>
<div>++ *</div>
<div>++ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com></div>
<div>++ *</div>
<div>++ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.</div>
<div>++ * (C) 2014 Sittisak <sittisaks@hotmail.com></div>
<div>++ *</div>
<div>++ * This software is licensed under the terms of the GNU General Public</div>
<div>++ * License version 2, as published by the Free Software Foundation, and</div>
<div>++ * may be copied, distributed, and modified under those terms.</div>
<div>++ *</div>
<div>++ * This program is distributed in the hope that it will be useful,</div>
<div>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of</div>
<div>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</div>
<div>++ * GNU General Public License for more details.</div>
<div>++ *</div>
<div>++ */</div>
<div>++</div>
<div>++#include <linux/interrupt.h></div>
<div>++#include <linux/kernel.h></div>
<div>++#include <linux/module.h></div>
<div>++#include <linux/reset.h></div>
<div>++#include <linux/delay.h></div>
<div>++#include <linux/slab.h></div>
<div>++#include <linux/init.h></div>
<div>++#include <linux/errno.h></div>
<div>++#include <linux/platform_device.h></div>
<div>++#include <linux/i2c.h></div>
<div>++#include <linux/io.h></div>
<div>++#include <linux/err.h></div>
<div>++</div>
<div>++#include <asm/mach-ralink/ralink_regs.h></div>
<div>++</div>
<div>++#define REG_CONFIG_REG                       0x00</div>
<div>++#define REG_CLKDIV_REG                       0x04</div>
<div>++#define REG_DEVADDR_REG                      0x08</div>
<div>++#define REG_ADDR_REG                         0x0C</div>
<div>++#define REG_DATAOUT_REG                      0x10</div>
<div>++#define REG_DATAIN_REG                       0x14</div>
<div>++#define REG_STATUS_REG                       0x18</div>
<div>++#define REG_STARTXFR_REG                     0x1C</div>
<div>++#define REG_BYTECNT_REG                      0x20</div>
<div>++#define REG_SM0_IS_AUTOMODE                  0x28</div>
<div>++#define REG_SM0CTL0                          0x40</div>
<div>++</div>
<div>++</div>
<div>++#define I2C_STARTERR                         0x10</div>
<div>++#define I2C_ACKERR                           0x08</div>
<div>++#define I2C_DATARDY                          0x04</div>
<div>++#define I2C_SDOEMPTY                         0x02</div>
<div>++#define I2C_BUSY                             0x01</div>
<div>++</div>
<div>++/* I2C_CFG register bit field */</div>
<div>++#define I2C_CFG_ADDRLEN_8                    (7<<5)   /* 8 bits */</div>
<div>++#define I2C_CFG_DEVADLEN_7                   (6<<2)</div>
<div>++#define I2C_CFG_ADDRDIS                      BIT(1)</div>
<div>++#define I2C_CFG_DEVADDIS                     BIT(0)</div>
<div>++</div>
<div>++#define I2C_CFG_DEFAULT    (I2C_CFG_ADDRLEN_8 | \</div>
<div>++           I2C_CFG_DEVADLEN_7 | \</div>
<div>++           I2C_CFG_ADDRDIS)</div>
<div>++</div>
<div>++#define I2C_RETRY                            0x1000</div>
<div>++</div>
<div>++#define CLKDIV_VALUE                         333</div>
<div>++#define i2c_busy_loop                        (CLKDIV_VALUE*30)</div>
<div>++</div>
<div>++#define READ_CMD                             0x01</div>
<div>++#define WRITE_CMD                            0x00</div>
<div>++#define READ_BLOCK                           16</div>
<div>++</div>
<div>++#define SM0_ODRAIN                           BIT(31)</div>
<div>++#define SM0_VSYNC_MODE                       BIT(28)</div>
<div>++#define SM0_CLK_DIV                          (CLKDIV_VALUE << 16)</div>
<div>++#define SM0_WAIT_LEVEL                       BIT(6)</div>
<div>++#define SM0_EN                               BIT(1)</div>
<div>++</div>
<div>++#define SM0_CFG_DEFUALT (SM0_ODRAIN | SM0_VSYNC_MODE | \</div>
<div>++                        SM0_CLK_DIV | SM0_WAIT_LEVEL | \</div>
<div>++                        SM0_EN) </div>
<div>++/***********************************************************/</div>
<div>++</div>
<div>++static void __iomem *membase;</div>
<div>++static struct i2c_adapter *adapter;</div>
<div>++</div>
<div>++static void rt_i2c_w32(u32 val, unsigned reg)</div>
<div>++{</div>
<div>++   iowrite32(val, membase + reg);</div>
<div>++}</div>
<div>++</div>
<div>++static u32 rt_i2c_r32(unsigned reg)</div>
<div>++{</div>
<div>++   return ioread32(membase + reg);</div>
<div>++}</div>
<div>++</div>
<div>++static void mt7621_i2c_reset(struct i2c_adapter *a)</div>
<div>++{</div>
<div>++   device_reset(a->dev.parent);</div>
<div>++}</div>
<div>++static void mt7621_i2c_enable(struct i2c_msg *msg)</div>
<div>++{</div>
<div>++   rt_i2c_w32(msg->addr,REG_DEVADDR_REG);</div>
<div>++   rt_i2c_w32(0,REG_ADDR_REG);</div>
<div>++}</div>
<div>++</div>
<div>++static void i2c_master_init(struct i2c_adapter *a)</div>
<div>++{</div>
<div>++   mt7621_i2c_reset(a); </div>
<div>++   rt_i2c_w32(I2C_CFG_DEFAULT,REG_CONFIG_REG);    </div>
<div>++   rt_i2c_w32(SM0_CFG_DEFUALT,REG_SM0CTL0);</div>
<div>++   rt_i2c_w32(1,REG_SM0_IS_AUTOMODE);//auto mode</div>
<div>++}</div>
<div>++</div>
<div>++</div>
<div>++static inline int rt_i2c_wait_rx_done(void)</div>
<div>++{</div>
<div>++   int i=0;</div>
<div>++   while((!(rt_i2c_r32(REG_STATUS_REG) & I2C_DATARDY)) && (i<i2c_busy_loop))</div>
<div>++           i++;</div>
<div>++   if(i>=i2c_busy_loop){</div>
<div>++           pr_err("err,wait for idle timeout");</div>
<div>++           return -ETIMEDOUT;</div>
<div>++   }</div>
<div>++   return 0;</div>
<div>++}</div>
<div>++</div>
<div>++static inline int rt_i2c_wait_idle(void)</div>
<div>++{</div>
<div>++   int i=0;</div>
<div>++   while((rt_i2c_r32(REG_STATUS_REG) & I2C_BUSY) && (i<i2c_busy_loop))</div>
<div>++           i++;</div>
<div>++   if(i>=i2c_busy_loop){</div>
<div>++           pr_err("err,wait for idle timeout");</div>
<div>++           return -ETIMEDOUT;</div>
<div>++   }</div>
<div>++   return 0;</div>
<div>++}</div>
<div>++</div>
<div>++static inline int rt_i2c_wait_tx_done(void)</div>
<div>++{</div>
<div>++   int i=0;</div>
<div>++   while((!(rt_i2c_r32(REG_STATUS_REG) & I2C_SDOEMPTY)) && (i<i2c_busy_loop))</div>
<div>++           i++;</div>
<div>++   if(i>=i2c_busy_loop){</div>
<div>++           pr_err("err,wait for idle timeout");</div>
<div>++           return -ETIMEDOUT;</div>
<div>++   }</div>
<div>++   return 0;</div>
<div>++}</div>
<div>++</div>
<div>++static int rt_i2c_handle_msg(struct i2c_adapter *a, struct i2c_msg* msg)</div>
<div>++{</div>
<div>++   int i = 0, j = 0, pos = 0;</div>
<div>++   int nblock = msg->len / READ_BLOCK;</div>
<div>++   int rem = msg->len % READ_BLOCK;</div>
<div>++</div>
<div>++   if (msg->flags & I2C_M_TEN) {</div>
<div>++           printk("10 bits addr not supported\n");</div>
<div>++           return -EINVAL;</div>
<div>++   }</div>
<div>++</div>
<div>++   if (msg->flags & I2C_M_RD) {</div>
<div>++           for (i = 0; i < nblock; i++) {</div>
<div>++                   if (rt_i2c_wait_idle())</div>
<div>++                           goto err_timeout;</div>
<div>++                   rt_i2c_w32(READ_BLOCK - 1, REG_BYTECNT_REG);</div>
<div>++                   rt_i2c_w32(READ_CMD, REG_STARTXFR_REG);</div>
<div>++                   for (j = 0; j < READ_BLOCK; j++) {</div>
<div>++                           if (rt_i2c_wait_rx_done())</div>
<div>++                                   goto err_timeout;</div>
<div>++                           msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG);</div>
<div>++                   }</div>
<div>++           }</div>
<div>++</div>
<div>++           if (rt_i2c_wait_idle())</div>
<div>++               goto err_timeout;</div>
<div>++           rt_i2c_w32(rem - 1, REG_BYTECNT_REG);</div>
<div>++           rt_i2c_w32(READ_CMD, REG_STARTXFR_REG);</div>
<div>++           </div>
<div>++           for (i = 0; i < rem; i++) {</div>
<div>++                   if (rt_i2c_wait_rx_done())</div>
<div>++                           goto err_timeout;</div>
<div>++                   msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG);</div>
<div>++           }</div>
<div>++   } else {</div>
<div>++           if (rt_i2c_wait_idle())</div>
<div>++                goto err_timeout;</div>
<div>++           rt_i2c_w32(msg->len - 1, REG_BYTECNT_REG);</div>
<div>++           for (i = 0; i < msg->len; i++) {</div>
<div>++                   rt_i2c_w32(msg->buf[i], REG_DATAOUT_REG);</div>
<div>++                   if(i == 0)</div>
<div>++                           rt_i2c_w32(WRITE_CMD, REG_STARTXFR_REG);</div>
<div>++</div>
<div>++                   if (rt_i2c_wait_tx_done())</div>
<div>++                           goto err_timeout;</div>
<div>++           }</div>
<div>++   }</div>
<div>++</div>
<div>++   return 0;</div>
<div>++err_timeout:</div>
<div>++   return -ETIMEDOUT;</div>
<div>++}</div>
<div>++</div>
<div>++static int rt_i2c_master_xfer(struct i2c_adapter *a, struct i2c_msg *m, int n)</div>
<div>++{</div>
<div>++   int i = 0;</div>
<div>++   int ret = 0;</div>
<div>++   i2c_master_init(a);</div>
<div>++   mt7621_i2c_enable(m);</div>
<div>++</div>
<div>++   for (i = 0; i != n && ret==0; i++) {</div>
<div>++           ret = rt_i2c_handle_msg(a, &m[i]);</div>
<div>++           if (ret) </div>
<div>++                   return ret;     </div>
<div>++   }</div>
<div>++   return i;</div>
<div>++}</div>
<div>++</div>
<div>++static u32 rt_i2c_func(struct i2c_adapter *a)</div>
<div>++{</div>
<div>++   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;</div>
<div>++}</div>
<div>++</div>
<div>++static const struct i2c_algorithm rt_i2c_algo = {</div>
<div>++   .master_xfer    = rt_i2c_master_xfer,</div>
<div>++   .functionality  = rt_i2c_func,</div>
<div>++};</div>
<div>++</div>
<div>++static int rt_i2c_probe(struct platform_device *pdev)</div>
<div>++{</div>
<div>++   struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);</div>
<div>++   int ret;</div>
<div>++</div>
<div>++   adapter = devm_kzalloc(&pdev->dev,sizeof(struct i2c_adapter), GFP_KERNEL);</div>
<div>++   if (!adapter) {</div>
<div>++           dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");</div>
<div>++           return -ENOMEM;</div>
<div>++   }</div>
<div>++   membase = devm_ioremap_resource(&pdev->dev, res);</div>
<div>++   if (IS_ERR(membase))</div>
<div>++           return PTR_ERR(membase);</div>
<div>++</div>
<div>++   strlcpy(adapter->name, dev_name(&pdev->dev), sizeof(adapter->name));</div>
<div>++</div>
<div>++   adapter->owner = THIS_MODULE;</div>
<div>++   adapter->nr = pdev->id;</div>
<div>++   adapter->timeout = HZ;</div>
<div>++   adapter->algo = &rt_i2c_algo;</div>
<div>++   adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;</div>
<div>++   adapter->dev.parent = &pdev->dev;</div>
<div>++   adapter->dev.of_node = pdev->dev.of_node;</div>
<div>++</div>
<div>++   platform_set_drvdata(pdev, adapter);</div>
<div>++   </div>
<div>++   ret = i2c_add_numbered_adapter(adapter);</div>
<div>++   if (ret)</div>
<div>++           return ret;</div>
<div>++</div>
<div>++   dev_info(&pdev->dev,"loaded");</div>
<div>++</div>
<div>++   return 0;</div>
<div>++}</div>
<div>++</div>
<div>++static int rt_i2c_remove(struct platform_device *pdev)</div>
<div>++{</div>
<div>++   platform_set_drvdata(pdev, NULL);</div>
<div>++   return 0;</div>
<div>++}</div>
<div>++</div>
<div>++static const struct of_device_id i2c_rt_dt_ids[] = {</div>
<div>++   { .compatible = "ralink,i2c-mt7621", },</div>
<div>++   { /* sentinel */ }</div>
<div>++};</div>
<div>++</div>
<div>++MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids);</div>
<div>++</div>
<div>++static struct platform_driver rt_i2c_driver = {</div>
<div>++   .probe          = rt_i2c_probe,</div>
<div>++   .remove         = rt_i2c_remove,</div>
<div>++   .driver         = {</div>
<div>++           .owner  = THIS_MODULE,</div>
<div>++           .name   = "i2c-mt7621",</div>
<div>++           .of_match_table = i2c_rt_dt_ids,</div>
<div>++   },</div>
<div>++};</div>
<div>++</div>
<div>++static int __init i2c_rt_init (void)</div>
<div>++{</div>
<div>++   return platform_driver_register(&rt_i2c_driver);</div>
<div>++}</div>
<div>++</div>
<div>++static void __exit i2c_rt_exit (void)</div>
<div>++{</div>
<div>++   platform_driver_unregister(&rt_i2c_driver);</div>
<div>++}</div>
<div>++module_init (i2c_rt_init);</div>
<div>++module_exit (i2c_rt_exit);</div>
<div>++</div>
<div>++MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");</div>
<div>++MODULE_DESCRIPTION("MT7621 I2c host driver");</div>
<div>++MODULE_LICENSE("GPL");</div>
<div>++MODULE_ALIAS("platform:MT7621-I2C");</div>
<div>-- </div>
<div>1.7.9.5</div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
</div></blockquote>
</body></html>