[Armadeus-commitlog] armadeus branch, master, updated. armadeus-5.2-117-g288d696
Brought to you by:
sszy
|
From: jorasse <jo...@us...> - 2013-01-14 20:45:10
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 288d696b320bd58b59fa008555ffd6b413eb71c7 (commit)
from f39081101716f7454fd062c4379ab2eba8b354cc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 288d696b320bd58b59fa008555ffd6b413eb71c7
Author: Eric Jarrige <eri...@ar...>
Date: Mon Jan 14 21:49:11 2013 +0100
[UBOOT] 2012.04: APF27: add I2C driver and support for I2C multibus
-----------------------------------------------------------------------
Summary of changes:
.../device/armadeus/apf27/apf27-u-boot-2012.04.h | 14 +-
...-Add-support-for-the-armadeus-apf27-board.patch | 15 +-
.../2012.04/304-Add-FPGA-support-apf27.patch | 2 +-
.../u-boot/2012.04/370-imx27-add-i2c-driver.patch | 690 ++++++++++++++++++++
...c_i2c-add_support_for_the_iMX51_processor.patch | 26 -
5 files changed, 712 insertions(+), 35 deletions(-)
create mode 100644 patches/u-boot/2012.04/370-imx27-add-i2c-driver.patch
delete mode 100644 patches/u-boot/2012.04/424-armadeus-mxc_i2c-add_support_for_the_iMX51_processor.patch
diff --git a/buildroot/target/device/armadeus/apf27/apf27-u-boot-2012.04.h b/buildroot/target/device/armadeus/apf27/apf27-u-boot-2012.04.h
index 315e5fc..a62c410 100644
--- a/buildroot/target/device/armadeus/apf27/apf27-u-boot-2012.04.h
+++ b/buildroot/target/device/armadeus/apf27/apf27-u-boot-2012.04.h
@@ -25,7 +25,7 @@
#define CONFIG_VERSION_VARIABLE
#define CONFIG_ENV_VERSION "3.2"
-#define CONFIG_IDENT_STRING " apf27 patch 3.7"
+#define CONFIG_IDENT_STRING " apf27 patch 3.8"
#define CONFIG_BOARD_NAME apf27
/*
@@ -79,13 +79,13 @@
#define CONFIG_CMD_ASKENV /* ask for env variable */
#define CONFIG_CMD_BSP /* Board Specific functions */
#define CONFIG_CMD_CACHE /* icache, dcache */
-/*#define CONFIG_CMD_DATE */ /* support for RTC, date/time...*/
+#define CONFIG_CMD_DATE /* support for RTC, date/time...*/
#define CONFIG_CMD_DHCP /* DHCP Support */
#define CONFIG_CMD_DNS
-/*#define CONFIG_CMD_EEPROM */ /* EEPROM read/write support */
+#define CONFIG_CMD_EEPROM /* EEPROM read/write support */
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_FAT /* FAT support */
-/*#define CONFIG_CMD_I2C */ /* I2C serial bus support */
+#define CONFIG_CMD_I2C /* I2C serial bus support */
#define CONFIG_CMD_IMX_FUSE /* imx iim fuse */
#define CONFIG_CMD_MII /* MII support */
#define CONFIG_CMD_MMC
@@ -386,12 +386,12 @@
#ifdef CONFIG_CMD_I2C
#define CONFIG_HARD_I2C 1
-
+#define CONFIG_I2C_MXC
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_BASE IMX_I2C1_BASE
#define CONFIG_SYS_I2C_SPEED 100000 /* 100 kHz */
#define CONFIG_SYS_I2C_SLAVE 0x7F
-
#define CONFIG_I2C_CMD_TREE
-#define CONFIG_I2C_MULTI_BUS 2
#define CONFIG_SYS_I2C_NOPROBES { }
#ifdef CONFIG_CMD_EEPROM
diff --git a/patches/u-boot/2012.04/302-Add-support-for-the-armadeus-apf27-board.patch b/patches/u-boot/2012.04/302-Add-support-for-the-armadeus-apf27-board.patch
index 4c00a2f..310640f 100644
--- a/patches/u-boot/2012.04/302-Add-support-for-the-armadeus-apf27-board.patch
+++ b/patches/u-boot/2012.04/302-Add-support-for-the-armadeus-apf27-board.patch
@@ -78,7 +78,7 @@ new file mode 100644
index 0000000..c55da1a
--- /dev/null
+++ b/board/armadeus/apf27/apf27.c
-@@ -0,0 +1,325 @@
+@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2007 Sascha Hauer, Pengutronix
+ * Copyright (C) 2008-2012 Eric Jarrige <eri...@ar...>
@@ -247,6 +247,9 @@ index 0000000..c55da1a
+ writel(CONFIG_SYS_GIUS_F_VAL, ®s->port[PORTF].gius);
+}
+
++void bus_i2c_init(void *base, int speed, int slave_addr,
++ int (*idle_bus_fn)(void *p), void *p);
++
+static int apf27_devices_init(void)
+{
+ struct gpio_regs *regs = (struct gpio_regs *)IMX_GPIO_BASE;
@@ -272,6 +275,10 @@ index 0000000..c55da1a
+ PF23_AIN_FEC_TX_EN,
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
++ PC5_PF_I2C2_DATA,
++ PC6_PF_I2C2_CLK,
++ PD17_PF_I2C_DATA,
++ PD18_PF_I2C_CLK,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(mode); i++)
@@ -283,6 +290,12 @@ index 0000000..c55da1a
+ writel(readl(®s->port[PORTF].dr) | (1 << 16),
+ ®s->port[PORTF].dr);
+#endif
++#if defined(CONFIG_I2C_MXC) && defined(CONFIG_I2C_MULTI_BUS)
++ bus_i2c_init(IMX_I2C1_BASE, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
++ NULL, NULL);
++ bus_i2c_init(IMX_I2C2_BASE, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE,
++ NULL, NULL);
++#endif
+ return 0;
+}
+
diff --git a/patches/u-boot/2012.04/304-Add-FPGA-support-apf27.patch b/patches/u-boot/2012.04/304-Add-FPGA-support-apf27.patch
index 8693bec..2d0f7eb 100644
--- a/patches/u-boot/2012.04/304-Add-FPGA-support-apf27.patch
+++ b/patches/u-boot/2012.04/304-Add-FPGA-support-apf27.patch
@@ -36,7 +36,7 @@ index c55da1a..98152f1 100644
#include <jffs2/jffs2.h>
#include <nand.h>
#include <netdev.h>
-@@ -256,6 +257,21 @@ misc_init_r(void)
+@@ -269,6 +270,21 @@ misc_init_r(void)
struct mtd_device *dev;
struct part_info *part;
diff --git a/patches/u-boot/2012.04/370-imx27-add-i2c-driver.patch b/patches/u-boot/2012.04/370-imx27-add-i2c-driver.patch
new file mode 100644
index 0000000..abfa819
--- /dev/null
+++ b/patches/u-boot/2012.04/370-imx27-add-i2c-driver.patch
@@ -0,0 +1,690 @@
+Signed-off-by: Eric Jarrige <eri...@ar...>
+---
+diff -purN uboot/arch/arm/cpu/arm926ejs/mx27/generic.c uboot/arch/arm/cpu/arm926ejs/mx27/generic.c
+--- uboot/arch/arm/cpu/arm926ejs/mx27/generic.c
++++ uboot/arch/arm/cpu/arm926ejs/mx27/generic.c
+@@ -158,6 +158,8 @@ unsigned int mxc_get_clock(enum mxc_cloc
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return imx_get_armclk();
++ case MXC_IPG_PERCLK:
++ return imx_get_ahbclk()/2;
+ case MXC_UART_CLK:
+ return imx_get_perclk1();
+ case MXC_FEC_CLK:
+diff -purN uboot/arch/arm/include/asm/arch-mx27/clock.h uboot/arch/arm/include/asm/arch-mx27/clock.h
+--- uboot/arch/arm/include/asm/arch-mx27/clock.h
++++ uboot/arch/arm/include/asm/arch-mx27/clock.h
+@@ -26,6 +26,7 @@
+
+ enum mxc_clock {
+ MXC_ARM_CLK,
++ MXC_IPG_PERCLK,
+ MXC_UART_CLK,
+ MXC_ESDHC_CLK,
+ MXC_FEC_CLK,
+diff -purN uboot/drivers/i2c/mxc_i2c.c uboot/drivers/i2c/mxc_i2c.c
+--- uboot/drivers/i2c/mxc_i2c.c
++++ uboot/drivers/i2c/mxc_i2c.c
+@@ -31,13 +31,12 @@
+ */
+
+ #include <common.h>
+-#include <asm/io.h>
+-
+-#if defined(CONFIG_HARD_I2C)
+-
+ #include <asm/arch/clock.h>
+ #include <asm/arch/imx-regs.h>
++#include <asm/errno.h>
++#include <asm/io.h>
+ #include <i2c.h>
++#include <watchdog.h>
+
+ struct mxc_i2c_regs {
+ uint32_t iadr;
+@@ -56,34 +55,14 @@ struct mxc_i2c_regs {
+
+ #define I2SR_ICF (1 << 7)
+ #define I2SR_IBB (1 << 5)
++#define I2SR_IAL (1 << 4)
+ #define I2SR_IIF (1 << 1)
+ #define I2SR_RX_NO_AK (1 << 0)
+
+-#if defined(CONFIG_SYS_I2C_MX31_PORT1)
+-#define I2C_BASE 0x43f80000
+-#define I2C_CLK_OFFSET 26
+-#elif defined (CONFIG_SYS_I2C_MX31_PORT2)
+-#define I2C_BASE 0x43f98000
+-#define I2C_CLK_OFFSET 28
+-#elif defined (CONFIG_SYS_I2C_MX31_PORT3)
+-#define I2C_BASE 0x43f84000
+-#define I2C_CLK_OFFSET 30
+-#elif defined(CONFIG_SYS_I2C_MX53_PORT1)
+-#define I2C_BASE I2C1_BASE_ADDR
+-#elif defined(CONFIG_SYS_I2C_MX53_PORT2)
+-#define I2C_BASE I2C2_BASE_ADDR
+-#elif defined(CONFIG_SYS_I2C_MX35_PORT1)
+-#define I2C_BASE I2C_BASE_ADDR
+-#elif defined(CONFIG_SYS_I2C_MX35_PORT2)
+-#define I2C_BASE I2C2_BASE_ADDR
+-#elif defined(CONFIG_SYS_I2C_MX35_PORT3)
+-#define I2C_BASE I2C3_BASE_ADDR
+-#else
+-#error "define CONFIG_SYS_I2C_MX<Processor>_PORTx to use the mx I2C driver"
++#if defined(CONFIG_HARD_I2C) && !defined(CONFIG_SYS_I2C_BASE)
++#error "define CONFIG_SYS_I2C_BASE to use the mxc_i2c driver"
+ #endif
+
+-#define I2C_MAX_TIMEOUT 10000
+-
+ static u16 i2c_clk_div[50][2] = {
+ { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 },
+ { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 },
+@@ -114,7 +93,7 @@ static uint8_t i2c_imx_get_clk(unsigned
+ (struct clock_control_regs *)CCM_BASE;
+
+ /* start the required I2C clock */
+- writel(readl(&sc_regs->cgr0) | (3 << I2C_CLK_OFFSET),
++ writel(readl(&sc_regs->cgr0) | (3 << CONFIG_SYS_I2C_CLK_OFFSET),
+ &sc_regs->cgr0);
+ #endif
+
+@@ -134,46 +113,29 @@ static uint8_t i2c_imx_get_clk(unsigned
+ }
+
+ /*
+- * Reset I2C Controller
++ * Set I2C Bus speed
+ */
+-void i2c_reset(void)
++int bus_i2c_set_bus_speed(void *base, int speed)
+ {
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+-
+- writeb(0, &i2c_regs->i2cr); /* Reset module */
+- writeb(0, &i2c_regs->i2sr);
+-}
+-
+-/*
+- * Init I2C Bus
+- */
+-void i2c_init(int speed, int unused)
+-{
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
++ struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
+ u8 clk_idx = i2c_imx_get_clk(speed);
+ u8 idx = i2c_clk_div[clk_idx][1];
+
+ /* Store divider value */
+ writeb(idx, &i2c_regs->ifdr);
+
+- i2c_reset();
+-}
+-
+-/*
+- * Set I2C Speed
+- */
+-int i2c_set_bus_speed(unsigned int speed)
+-{
+- i2c_init(speed, 0);
++ /* Reset module */
++ writeb(0, &i2c_regs->i2cr);
++ writeb(0, &i2c_regs->i2sr);
+ return 0;
+ }
+
+ /*
+ * Get I2C Speed
+ */
+-unsigned int i2c_get_bus_speed(void)
++unsigned int bus_i2c_get_bus_speed(void *base)
+ {
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
++ struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
+ u8 clk_idx = readb(&i2c_regs->ifdr);
+ u8 clk_div;
+
+@@ -183,216 +145,163 @@ unsigned int i2c_get_bus_speed(void)
+ return mxc_get_clock(MXC_IPG_PERCLK) / i2c_clk_div[clk_div][0];
+ }
+
+-/*
+- * Wait for bus to be busy (or free if for_busy = 0)
+- *
+- * for_busy = 1: Wait for IBB to be asserted
+- * for_busy = 0: Wait for IBB to be de-asserted
+- */
+-int i2c_imx_bus_busy(int for_busy)
+-{
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+- unsigned int temp;
+-
+- int timeout = I2C_MAX_TIMEOUT;
+-
+- while (timeout--) {
+- temp = readb(&i2c_regs->i2sr);
+-
+- if (for_busy && (temp & I2SR_IBB))
+- return 0;
+- if (!for_busy && !(temp & I2SR_IBB))
+- return 0;
+-
+- udelay(1);
++#define ST_BUS_IDLE (0 | (I2SR_IBB << 8))
++#define ST_BUS_BUSY (I2SR_IBB | (I2SR_IBB << 8))
++#define ST_IIF (I2SR_IIF | (I2SR_IIF << 8))
++
++static int wait_for_sr_state(struct mxc_i2c_regs *i2c_regs, unsigned state)
++{
++ unsigned sr;
++ ulong elapsed;
++ ulong start_time = get_timer(0);
++ for (;;) {
++ sr = readb(&i2c_regs->i2sr);
++ if (sr & I2SR_IAL) {
++ writeb(sr & ~I2SR_IAL, &i2c_regs->i2sr);
++ printf("%s: Arbitration lost sr=%x cr=%x state=%x\n",
++ __func__, sr, readb(&i2c_regs->i2cr), state);
++ return -ERESTART;
++ }
++ if ((sr & (state >> 8)) == (unsigned char)state)
++ return sr;
++ WATCHDOG_RESET();
++ elapsed = get_timer(start_time);
++ if (elapsed > (CONFIG_SYS_HZ / 10)) /* .1 seconds */
++ break;
+ }
+-
+- return 1;
++ printf("%s: failed sr=%x cr=%x state=%x\n", __func__,
++ sr, readb(&i2c_regs->i2cr), state);
++ return -ETIMEDOUT;
+ }
+
+-/*
+- * Wait for transaction to complete
+- */
+-int i2c_imx_trx_complete(void)
++static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
+ {
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+- int timeout = I2C_MAX_TIMEOUT;
+-
+- while (timeout--) {
+- if (readb(&i2c_regs->i2sr) & I2SR_IIF) {
+- writeb(0, &i2c_regs->i2sr);
+- return 0;
+- }
+-
+- udelay(1);
+- }
++ int ret;
+
+- return 1;
++ writeb(0, &i2c_regs->i2sr);
++ writeb(byte, &i2c_regs->i2dr);
++ ret = wait_for_sr_state(i2c_regs, ST_IIF);
++ if (ret < 0)
++ return ret;
++ if (ret & I2SR_RX_NO_AK)
++ return -ENODEV;
++ return 0;
+ }
+
+ /*
+- * Check if the transaction was ACKed
++ * Stop I2C transaction
+ */
+-int i2c_imx_acked(void)
++static void i2c_imx_stop(struct mxc_i2c_regs *i2c_regs)
+ {
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
++ int ret;
++ unsigned int temp = readb(&i2c_regs->i2cr);
+
+- return readb(&i2c_regs->i2sr) & I2SR_RX_NO_AK;
++ temp &= ~(I2CR_MSTA | I2CR_MTX);
++ writeb(temp, &i2c_regs->i2cr);
++ ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
++ if (ret < 0)
++ printf("%s:trigger stop failed\n", __func__);
+ }
+
+ /*
+- * Start the controller
++ * Send start signal, chip address and
++ * write register address
+ */
+-int i2c_imx_start(void)
++static int i2c_init_transfer_(struct mxc_i2c_regs *i2c_regs,
++ uchar chip, uint addr, int alen)
+ {
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+- unsigned int temp = 0;
+- int result;
+- int speed = i2c_get_bus_speed();
+- u8 clk_idx = i2c_imx_get_clk(speed);
+- u8 idx = i2c_clk_div[clk_idx][1];
+-
+- /* Store divider value */
+- writeb(idx, &i2c_regs->ifdr);
++ unsigned int temp;
++ int ret;
+
+ /* Enable I2C controller */
++ if (!(readb(&i2c_regs->i2cr) & I2CR_IEN)) {
++ writeb(I2CR_IEN, &i2c_regs->i2cr);
++ /* Wait for controller to be stable */
++ udelay(50);
++ }
++ if (readb(&i2c_regs->iadr) == (chip << 1))
++ writeb((chip << 1) ^ 2, &i2c_regs->iadr);
+ writeb(0, &i2c_regs->i2sr);
+- writeb(I2CR_IEN, &i2c_regs->i2cr);
+-
+- /* Wait controller to be stable */
+- udelay(50);
++ ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
++ if (ret < 0)
++ return ret;
+
+ /* Start I2C transaction */
+ temp = readb(&i2c_regs->i2cr);
+ temp |= I2CR_MSTA;
+ writeb(temp, &i2c_regs->i2cr);
+
+- result = i2c_imx_bus_busy(1);
+- if (result)
+- return result;
++ ret = wait_for_sr_state(i2c_regs, ST_BUS_BUSY);
++ if (ret < 0)
++ return ret;
+
+ temp |= I2CR_MTX | I2CR_TX_NO_AK;
+ writeb(temp, &i2c_regs->i2cr);
+
+- return 0;
+-}
+-
+-/*
+- * Stop the controller
+- */
+-void i2c_imx_stop(void)
+-{
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+- unsigned int temp = 0;
+-
+- /* Stop I2C transaction */
+- temp = readb(&i2c_regs->i2cr);
+- temp |= ~(I2CR_MSTA | I2CR_MTX);
+- writeb(temp, &i2c_regs->i2cr);
+-
+- i2c_imx_bus_busy(0);
+-
+- /* Disable I2C controller */
+- writeb(0, &i2c_regs->i2cr);
+-}
+-
+-/*
+- * Set chip address and access mode
+- *
+- * read = 1: READ access
+- * read = 0: WRITE access
+- */
+-int i2c_imx_set_chip_addr(uchar chip, int read)
+-{
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+- int ret;
+-
+- writeb((chip << 1) | read, &i2c_regs->i2dr);
+-
+- ret = i2c_imx_trx_complete();
+- if (ret)
+- return ret;
+-
+- ret = i2c_imx_acked();
+- if (ret)
++ /* write slave address */
++ ret = tx_byte(i2c_regs, chip << 1);
++ if (ret < 0)
+ return ret;
+
+- return ret;
+-}
+-
+-/*
+- * Write register address
+- */
+-int i2c_imx_set_reg_addr(uint addr, int alen)
+-{
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+- int ret = 0;
+-
+ while (alen--) {
+- writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->i2dr);
+-
+- ret = i2c_imx_trx_complete();
+- if (ret)
+- break;
+-
+- ret = i2c_imx_acked();
+- if (ret)
+- break;
++ ret = tx_byte(i2c_regs, (addr >> (alen * 8)) & 0xff);
++ if (ret < 0)
++ return ret;
+ }
+-
+- return ret;
++ return 0;
+ }
+
+-/*
+- * Try if a chip add given address responds (probe the chip)
+- */
+-int i2c_probe(uchar chip)
++static int i2c_idle_bus(void *base);
++
++static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
++ uchar chip, uint addr, int alen)
+ {
++ int retry;
+ int ret;
++ for (retry = 0; retry < 3; retry++) {
++ ret = i2c_init_transfer_(i2c_regs, chip, addr, alen);
++ if (ret >= 0)
++ return 0;
++ i2c_imx_stop(i2c_regs);
++ if (ret == -ENODEV)
++ return ret;
+
+- ret = i2c_imx_start();
+- if (ret)
+- return ret;
+-
+- ret = i2c_imx_set_chip_addr(chip, 0);
+- if (ret)
+- return ret;
+-
+- i2c_imx_stop();
+-
++ printf("%s: failed for chip 0x%x retry=%d\n", __func__, chip,
++ retry);
++ if (ret != -ERESTART)
++ writeb(0, &i2c_regs->i2cr); /* Disable controller */
++ udelay(100);
++ if (i2c_idle_bus(i2c_regs) < 0)
++ break;
++ }
++ printf("%s: give up i2c_regs=%p\n", __func__, i2c_regs);
+ return ret;
+ }
+
+ /*
+ * Read data from I2C device
+ */
+-int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
++int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf,
++ int len)
+ {
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+ int ret;
+ unsigned int temp;
+ int i;
++ struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
+
+- ret = i2c_imx_start();
+- if (ret)
+- return ret;
+-
+- /* write slave address */
+- ret = i2c_imx_set_chip_addr(chip, 0);
+- if (ret)
+- return ret;
+-
+- ret = i2c_imx_set_reg_addr(addr, alen);
+- if (ret)
++ ret = i2c_init_transfer(i2c_regs, chip, addr, alen);
++ if (ret < 0)
+ return ret;
+
+ temp = readb(&i2c_regs->i2cr);
+ temp |= I2CR_RSTA;
+ writeb(temp, &i2c_regs->i2cr);
+
+- ret = i2c_imx_set_chip_addr(chip, 1);
+- if (ret)
++ ret = tx_byte(i2c_regs, (chip << 1) | 1);
++ if (ret < 0) {
++ i2c_imx_stop(i2c_regs);
+ return ret;
++ }
+
+ /* setup bus to read data */
+ temp = readb(&i2c_regs->i2cr);
+@@ -400,73 +309,192 @@ int i2c_read(uchar chip, uint addr, int
+ if (len == 1)
+ temp |= I2CR_TX_NO_AK;
+ writeb(temp, &i2c_regs->i2cr);
+- readb(&i2c_regs->i2dr);
++ writeb(0, &i2c_regs->i2sr);
++ readb(&i2c_regs->i2dr); /* dummy read to clear ICF */
+
+ /* read data */
+ for (i = 0; i < len; i++) {
+- ret = i2c_imx_trx_complete();
+- if (ret)
++ ret = wait_for_sr_state(i2c_regs, ST_IIF);
++ if (ret < 0) {
++ i2c_imx_stop(i2c_regs);
+ return ret;
++ }
+
+ /*
+ * It must generate STOP before read I2DR to prevent
+ * controller from generating another clock cycle
+ */
+ if (i == (len - 1)) {
+- temp = readb(&i2c_regs->i2cr);
+- temp &= ~(I2CR_MSTA | I2CR_MTX);
+- writeb(temp, &i2c_regs->i2cr);
+- i2c_imx_bus_busy(0);
++ i2c_imx_stop(i2c_regs);
+ } else if (i == (len - 2)) {
+ temp = readb(&i2c_regs->i2cr);
+ temp |= I2CR_TX_NO_AK;
+ writeb(temp, &i2c_regs->i2cr);
+ }
+-
++ writeb(0, &i2c_regs->i2sr);
+ buf[i] = readb(&i2c_regs->i2dr);
+ }
+-
+- i2c_imx_stop();
+-
+- return ret;
++ i2c_imx_stop(i2c_regs);
++ return 0;
+ }
+
+ /*
+ * Write data to I2C device
+ */
+-int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
++int bus_i2c_write(void *base, uchar chip, uint addr, int alen,
++ const uchar *buf, int len)
+ {
+- struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+ int ret;
+ int i;
++ struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)base;
+
+- ret = i2c_imx_start();
+- if (ret)
++ ret = i2c_init_transfer(i2c_regs, chip, addr, alen);
++ if (ret < 0)
+ return ret;
+
+- /* write slave address */
+- ret = i2c_imx_set_chip_addr(chip, 0);
+- if (ret)
+- return ret;
++ for (i = 0; i < len; i++) {
++ ret = tx_byte(i2c_regs, buf[i]);
++ if (ret < 0)
++ break;
++ }
++ i2c_imx_stop(i2c_regs);
++ return ret;
++}
+
+- ret = i2c_imx_set_reg_addr(addr, alen);
++struct i2c_parms {
++ void *base;
++ void *idle_bus_data;
++ int (*idle_bus_fn)(void *p);
++};
++
++struct sram_data {
++ unsigned curr_i2c_bus;
++ struct i2c_parms i2c_data[3];
++};
++
++/*
++ * For SPL boot some boards need i2c before SDRAM is initialized so force
++ * variables to live in SRAM
++ */
++static struct sram_data __attribute__((section(".data"))) srdata;
++
++void *get_base(void)
++{
++#ifdef CONFIG_SYS_I2C_BASE
++#ifdef CONFIG_I2C_MULTI_BUS
++ void *ret = srdata.i2c_data[srdata.curr_i2c_bus].base;
+ if (ret)
+ return ret;
++#endif
++ return (void *)CONFIG_SYS_I2C_BASE;
++#elif defined(CONFIG_I2C_MULTI_BUS)
++ return srdata.i2c_data[srdata.curr_i2c_bus].base;
++#else
++ return srdata.i2c_data[0].base;
++#endif
++}
+
+- for (i = 0; i < len; i++) {
+- writeb(buf[i], &i2c_regs->i2dr);
++static struct i2c_parms *i2c_get_parms(void *base)
++{
++ int i = 0;
++ struct i2c_parms *p = srdata.i2c_data;
++ while (i < ARRAY_SIZE(srdata.i2c_data)) {
++ if (p->base == base)
++ return p;
++ p++;
++ i++;
++ }
++ printf("Invalid I2C base: %p\n", base);
++ return NULL;
++}
+
+- ret = i2c_imx_trx_complete();
+- if (ret)
+- return ret;
++static int i2c_idle_bus(void *base)
++{
++ struct i2c_parms *p = i2c_get_parms(base);
++ if (p && p->idle_bus_fn)
++ return p->idle_bus_fn(p->idle_bus_data);
++ return 0;
++}
+
+- ret = i2c_imx_acked();
+- if (ret)
+- return ret;
++#ifdef CONFIG_I2C_MULTI_BUS
++unsigned int i2c_get_bus_num(void)
++{
++ return srdata.curr_i2c_bus;
++}
++
++int i2c_set_bus_num(unsigned bus_idx)
++{
++ if (bus_idx >= ARRAY_SIZE(srdata.i2c_data))
++ return -1;
++ if (!srdata.i2c_data[bus_idx].base)
++ return -1;
++ srdata.curr_i2c_bus = bus_idx;
++ return 0;
++}
++#endif
++
++int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
++{
++ return bus_i2c_read(get_base(), chip, addr, alen, buf, len);
++}
++
++int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
++{
++ return bus_i2c_write(get_base(), chip, addr, alen, buf, len);
++}
++
++/*
++ * Test if a chip at a given address responds (probe the chip)
++ */
++int i2c_probe(uchar chip)
++{
++ return bus_i2c_write(get_base(), chip, 0, 0, NULL, 0);
++}
++
++void bus_i2c_init(void *base, int speed, int unused,
++ int (*idle_bus_fn)(void *p), void *idle_bus_data)
++{
++ int i = 0;
++ struct i2c_parms *p = srdata.i2c_data;
++ if (!base)
++ return;
++ for (;;) {
++ if (!p->base || (p->base == base)) {
++ p->base = base;
++ if (idle_bus_fn) {
++ p->idle_bus_fn = idle_bus_fn;
++ p->idle_bus_data = idle_bus_data;
++ }
++ break;
++ }
++ p++;
++ i++;
++ if (i >= ARRAY_SIZE(srdata.i2c_data))
++ return;
+ }
++ bus_i2c_set_bus_speed(base, speed);
++}
++
++/*
++ * Init I2C Bus
++ */
++void i2c_init(int speed, int unused)
++{
++ bus_i2c_init(get_base(), speed, unused, NULL, NULL);
++}
+
+- i2c_imx_stop();
++/*
++ * Set I2C Speed
++ */
++int i2c_set_bus_speed(unsigned int speed)
++{
++ return bus_i2c_set_bus_speed(get_base(), speed);
++}
+
+- return ret;
++/*
++ * Get I2C Speed
++ */
++unsigned int i2c_get_bus_speed(void)
++{
++ return bus_i2c_get_bus_speed(get_base());
+ }
+-#endif /* CONFIG_HARD_I2C */
diff --git a/patches/u-boot/2012.04/424-armadeus-mxc_i2c-add_support_for_the_iMX51_processor.patch b/patches/u-boot/2012.04/424-armadeus-mxc_i2c-add_support_for_the_iMX51_processor.patch
deleted file mode 100644
index 32bed66..0000000
--- a/patches/u-boot/2012.04/424-armadeus-mxc_i2c-add_support_for_the_iMX51_processor.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Signed-off-by: Philippe Reynes <tr...@ya...>
-Signed-off-by: Julien Boibessot <jul...@ar...>
-
----
- drivers/i2c/mxc_i2c.c | 4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
-index c88ac7c..cc410c0 100644
---- a/drivers/i2c/mxc_i2c.c
-+++ b/drivers/i2c/mxc_i2c.c
-@@ -68,9 +68,9 @@ struct mxc_i2c_regs {
- #elif defined (CONFIG_SYS_I2C_MX31_PORT3)
- #define I2C_BASE 0x43f84000
- #define I2C_CLK_OFFSET 30
--#elif defined(CONFIG_SYS_I2C_MX53_PORT1)
-+#elif defined(CONFIG_SYS_I2C_MX53_PORT1) || defined(CONFIG_SYS_I2C_MX51_PORT1)
- #define I2C_BASE I2C1_BASE_ADDR
--#elif defined(CONFIG_SYS_I2C_MX53_PORT2)
-+#elif defined(CONFIG_SYS_I2C_MX53_PORT2) || defined(CONFIG_SYS_I2C_MX51_PORT2)
- #define I2C_BASE I2C2_BASE_ADDR
- #elif defined(CONFIG_SYS_I2C_MX35_PORT1)
- #define I2C_BASE I2C_BASE_ADDR
---
-1.7.4.4
-
hooks/post-receive
--
armadeus
|