<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>