summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schaeffer <daniel.schaeffer@timesys.com>2009-10-08 13:30:58 -0400
committerDaniel Schaeffer <daniel.schaeffer@timesys.com>2009-10-08 13:30:58 -0400
commit954237a65dc8fd061892b84c79b31beccf1cc3a6 (patch)
tree49456fe0e4fcf52c48c8fdd4e2a2b9bec09162d6
parent0d67e29725ba728344fe829689104e21b24e8aa3 (diff)
This patch originally from LogicPD OMAP35x Release 1.6.1 Original Patch Name: u-boot-2009.03-lv-som-03-i2c.patch
-rw-r--r--board/omap3/common/Makefile2
-rw-r--r--board/omap3/common/power-lv_som.c76
-rw-r--r--board/omap3/lv_som/lv_som.c2
-rw-r--r--drivers/i2c/omap24xx_i2c.c263
4 files changed, 279 insertions, 64 deletions
diff --git a/board/omap3/common/Makefile b/board/omap3/common/Makefile
index 627a538c9a..91e4467874 100644
--- a/board/omap3/common/Makefile
+++ b/board/omap3/common/Makefile
@@ -33,7 +33,7 @@ COBJS-$(CONFIG_OMAP3_BEAGLE) += power.o
COBJS-$(CONFIG_OMAP3_OVERO) += power.o
COBJS-$(CONFIG_OMAP3_PANDORA) += power.o
COBJS-$(CONFIG_OMAP3_ZOOM1) += power.o
-COBJS-$(CONFIG_OMAP3_LV_SOM) += power.o
+COBJS-$(CONFIG_OMAP3_LV_SOM) += power-lv_som.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/board/omap3/common/power-lv_som.c b/board/omap3/common/power-lv_som.c
new file mode 100644
index 0000000000..93703bcc6b
--- /dev/null
+++ b/board/omap3/common/power-lv_som.c
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2004-2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ * Sunil Kumar <sunilsaini05@gmail.com>
+ * Shashi Ranjan <shashiranjanmca05@gmail.com>
+ *
+ * Derived from Beagle Board and 3430 SDP code by
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Syed Mohammed Khasim <khasim@ti.com>
+ *
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <i2c.h>
+
+/******************************************************************************
+ * Routine: power_init_r
+ * Description: Configure power supply
+ *****************************************************************************/
+void power_init_r(void)
+{
+ unsigned char byte;
+ unsigned short msg;
+
+#ifdef CONFIG_DRIVER_OMAP34XX_I2C
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+ /*
+ * Configure OMAP3 supply voltages in power management
+ * companion chip.
+ */
+
+ /* set VAUX1 to 3.0v */
+
+ // Select output voltage
+ byte = 0x04;
+ i2c_write(PWRMGT_ADDR_ID4, 0x72, 1, &byte, 1);
+
+ // Select the processor resource group
+ byte = 0x20;
+ i2c_write(PWRMGT_ADDR_ID4, 0x72, 1, &byte, 1);
+
+ // Enable I2C access to the Power bus
+ byte = 0x02;
+ i2c_write(PWRMGT_ADDR_ID4, 0x4a, 1, &byte, 1);
+
+ // Send Message MSB
+ msg = (1 << 13) | (1<<4) | (0xd<<0); // group(process_grp1):resource(vaux1):res_active;
+ byte = (msg >> 8);
+ i2c_write(PWRMGT_ADDR_ID4, 0x4b, 1, &byte, 1);
+
+ // Send Message LSB
+ byte = (msg && 0xff);
+ i2c_write(PWRMGT_ADDR_ID4, 0x4c, 1, &byte, 1);
+#endif
+}
diff --git a/board/omap3/lv_som/lv_som.c b/board/omap3/lv_som/lv_som.c
index 5ad92a00ef..16940b6bb2 100644
--- a/board/omap3/lv_som/lv_som.c
+++ b/board/omap3/lv_som/lv_som.c
@@ -78,7 +78,7 @@ int misc_init_r(void)
*****************************************************************************/
static void setup_net_chip(void)
{
- gpio_t *gpio3_base = (gpio_t *)OMAP34XX_GPIO3_BASE;
+ // gpio_t *gpio3_base = (gpio_t *)OMAP34XX_GPIO3_BASE;
gpmc_csx_t *gpmc_cs1_base = (gpmc_csx_t *)GPMC_CONFIG_CS1_BASE;
ctrl_t *ctrl_base = (ctrl_t *)OMAP34XX_CTRL_BASE;
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 678460325d..2436fceeb1 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -25,40 +25,175 @@
#include <asm/arch/i2c.h>
#include <asm/io.h>
+#undef DEBUG_I2C
+
+#ifdef DEBUG_I2C
+static struct {
+ char *name;
+ unsigned addr;
+} _i2c_reg_names[] = {
+ { "I2C_STAT", I2C_STAT },
+ { "I2C_SYSC", I2C_SYSC },
+ { "I2C_CON", I2C_CON },
+ { "I2C_SCLL", I2C_SCLL },
+ { "I2C_SCLH", I2C_SCLH },
+ { "I2C_CON", I2C_CON },
+ { "I2C_OA", I2C_OA },
+ { "I2C_IE", I2C_IE },
+ { "I2C_CNT", I2C_CNT },
+ { "I2C_SA", I2C_SA },
+ { "I2C_DATA", I2C_DATA },
+ { "I2C_PSC", I2C_PSC },
+ { NULL, 0x0 }
+};
+#define __my_writew(val, addr) _my_writew(__LINE__, (val), (addr));
+void _my_writew(int line, unsigned short val, unsigned int addr)
+{
+ int i;
+ for (i=0; _i2c_reg_names[i].name; ++i)
+ if (_i2c_reg_names[i].addr == addr)
+ break;
+
+ if (_i2c_reg_names[i].addr)
+ printf("%d: writew(%04x, %s)\n", line, val, _i2c_reg_names[i].name);
+ else
+ printf("%d: writew(%04x, %08x)\n", line, val, addr);
+ writew(val, addr);
+}
+
+#define __my_readw(addr) _my_readw(__LINE__, (addr))
+unsigned short _my_readw(int line, unsigned int addr)
+{
+ unsigned short val;
+ int i;
+ for (i=0; _i2c_reg_names[i].name; ++i)
+ if (_i2c_reg_names[i].addr == addr)
+ break;
+
+ val = readw(addr);
+ if (_i2c_reg_names[i].addr)
+ printf("%d: readw(%s)=%04x\n", line, _i2c_reg_names[i].name, val);
+ else
+ printf("%d: readw(%08x)=%04x\n", line, addr, val);
+ return val;
+}
+#else
+#define __my_writew(val, addr) writew((val), (addr))
+#define __my_readw(addr) readw((addr))
+#endif
+
static void wait_for_bb (void);
static u16 wait_for_pin (void);
static void flush_fifo(void);
void i2c_init (int speed, int slaveadd)
{
+#ifdef CONFIG_OMAP3_LV_SOM
+ int psc, scl=0, iclk;
+#else
u16 scl;
+#endif
- writew(0x2, I2C_SYSC); /* for ES2 after soft reset */
+ __my_writew(0x2, I2C_SYSC); /* for ES2 after soft reset */
udelay(1000);
- writew(0x0, I2C_SYSC); /* will probably self clear but */
+ __my_writew(0x0, I2C_SYSC); /* will probably self clear but */
- if (readw (I2C_CON) & I2C_CON_EN) {
- writew (0, I2C_CON);
+ if (__my_readw (I2C_CON) & I2C_CON_EN) {
+ __my_writew (0, I2C_CON);
udelay (50000);
}
+#ifdef CONFIG_OMAP3_LV_SOM
+ speed /= 1000; // Speed is in Hz, not kHz
+
+ /* compute divisors - dynamic decision based on i/p clock */
+ psc = I2C_PSC_MAX;
+ while (psc >= I2C_PSC_MIN) {
+ iclk = I2C_IP_CLK / (psc + 1);
+ switch (speed) {
+ case OMAP_I2C_STANDARD:
+ scl = (iclk * 10 / (OMAP_I2C_STANDARD * 2));
+ break;
+ case OMAP_I2C_HIGH_SPEED:
+ /* PSC ignored for HS */
+ case OMAP_I2C_FAST_MODE:
+ scl = (iclk * 10 / (OMAP_I2C_FAST_MODE * 2));
+ break;
+ /* no default case - fall thru */
+ }
+#ifdef DEBUG_I2C
+ printf("Search- speed= %d SysClk=%d, iclk=%d,psc=0x%x[%d],scl=0x%x[%d]\n",
+ speed, I2C_IP_CLK, iclk, psc, psc, scl, scl);
+#endif
+ /* Check for decimal places.. if yes, we ignore it */
+ if (scl % 10) {
+ scl = -1;
+ } else {
+ scl /= 10;
+ scl -= 7;
+ }
+ if (scl >= 0) {
+ break;
+ }
+ psc--;
+ }
+ /* Did not find an optimal config */
+ if (psc < I2C_PSC_MIN) {
+ printf
+ ("Unable to set Prescalar for i2c_clock=%d syI2C_IP_CLK=%d\n",
+ speed, I2C_IP_CLK);
+ psc = 0;
+ return;
+
+ }
+ iclk = I2C_IP_CLK / (psc + 1);
+ /* Initialize the I2C clock timers to generate an I2C bus clock
+ * frequency of i2c_clock kilohertz (default is 100 KHz).
+ */
+ switch (speed) {
+ case OMAP_I2C_STANDARD:
+ scl =
+ (((iclk / (OMAP_I2C_STANDARD * 2)) - 7) &
+ I2C_SCLL_SCLL_M) << I2C_SCLL_SCLL;
+ break;
+ case OMAP_I2C_HIGH_SPEED:
+ scl =
+ (((I2C_IP_CLK / (OMAP_I2C_HIGH_SPEED * 2)) - 7) &
+ I2C_SCLH_HSSCLL_M) << I2C_SCLL_HSSCLL;
+ /* Fall through for the FS settings */
+ case OMAP_I2C_FAST_MODE:
+ scl |=
+ (((iclk / (OMAP_I2C_FAST_MODE * 2)) - 7) &
+ I2C_SCLL_SCLL_M) << I2C_SCLL_SCLL;
+ break;
+ /* no default case */
+ }
+
+#ifdef DEBUG_I2C
+ printf(" speed= %d SysClk=%d, iclk=%d,psc=0x%x[%d],scl=0x%x[%d]\n",
+ speed, I2C_IP_CLK, iclk, psc, psc, scl, scl);
+#endif
+ __my_writew (psc, I2C_PSC);
+
+#else
/* 12MHz I2C module clock */
- writew (0, I2C_PSC);
+ __my_writew (0, I2C_PSC);
speed = speed/1000; /* 100 or 400 */
scl = ((12000/(speed*2)) - 7); /* use 7 when PSC = 0 */
- writew (scl, I2C_SCLL);
- writew (scl, I2C_SCLH);
+#endif
+ __my_writew (scl, I2C_SCLL);
+ __my_writew (scl, I2C_SCLH);
/* own address */
- writew (slaveadd, I2C_OA);
- writew (I2C_CON_EN, I2C_CON);
+ __my_writew (slaveadd, I2C_OA);
+ __my_writew (I2C_CON_EN, I2C_CON);
/* have to enable intrrupts or OMAP i2c module doesn't work */
- writew (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
+ __my_writew (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
udelay (1000);
flush_fifo();
- writew (0xFFFF, I2C_STAT);
- writew (0, I2C_CNT);
+ __my_writew (0xFFFF, I2C_STAT);
+ __my_writew (0, I2C_CNT);
}
static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
@@ -70,11 +205,11 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
wait_for_bb ();
/* one byte only */
- writew (1, I2C_CNT);
+ __my_writew (1, I2C_CNT);
/* set slave address */
- writew (devaddr, I2C_SA);
+ __my_writew (devaddr, I2C_SA);
/* no stop bit needed here */
- writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
+ __my_writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
status = wait_for_pin ();
@@ -82,7 +217,7 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
/* Important: have to use byte access */
writeb (regoffset, I2C_DATA);
udelay (20000);
- if (readw (I2C_STAT) & I2C_STAT_NACK) {
+ if (__my_readw (I2C_STAT) & I2C_STAT_NACK) {
i2c_error = 1;
}
} else {
@@ -91,20 +226,20 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
if (!i2c_error) {
/* free bus, otherwise we can't use a combined transction */
- writew (0, I2C_CON);
- while (readw (I2C_STAT) || (readw (I2C_CON) & I2C_CON_MST)) {
+ __my_writew (0, I2C_CON);
+ while (__my_readw (I2C_STAT) || (__my_readw (I2C_CON) & I2C_CON_MST)) {
udelay (10000);
/* Have to clear pending interrupt to clear I2C_STAT */
- writew (0xFFFF, I2C_STAT);
+ __my_writew (0xFFFF, I2C_STAT);
}
wait_for_bb ();
/* set slave address */
- writew (devaddr, I2C_SA);
+ __my_writew (devaddr, I2C_SA);
/* read one byte from slave */
- writew (1, I2C_CNT);
+ __my_writew (1, I2C_CNT);
/* need stop bit here */
- writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
+ __my_writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
I2C_CON);
status = wait_for_pin ();
@@ -112,7 +247,7 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
*value = readb (I2C_DATA);
#else
- *value = readw (I2C_DATA);
+ *value = __my_readw (I2C_DATA);
#endif
udelay (20000);
} else {
@@ -120,17 +255,17 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
}
if (!i2c_error) {
- writew (I2C_CON_EN, I2C_CON);
- while (readw (I2C_STAT)
- || (readw (I2C_CON) & I2C_CON_MST)) {
+ __my_writew (I2C_CON_EN, I2C_CON);
+ while (__my_readw (I2C_STAT)
+ || (__my_readw (I2C_CON) & I2C_CON_MST)) {
udelay (10000);
- writew (0xFFFF, I2C_STAT);
+ __my_writew (0xFFFF, I2C_STAT);
}
}
}
flush_fifo();
- writew (0xFFFF, I2C_STAT);
- writew (0, I2C_CNT);
+ __my_writew (0xFFFF, I2C_STAT);
+ __my_writew (0, I2C_CNT);
return i2c_error;
}
@@ -143,11 +278,11 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
wait_for_bb ();
/* two bytes */
- writew (2, I2C_CNT);
+ __my_writew (2, I2C_CNT);
/* set slave address */
- writew (devaddr, I2C_SA);
+ __my_writew (devaddr, I2C_SA);
/* stop bit needed here */
- writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+ __my_writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
I2C_CON_STP, I2C_CON);
/* wait until state change */
@@ -157,23 +292,23 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
/* send out 1 byte */
writeb (regoffset, I2C_DATA);
- writew (I2C_STAT_XRDY, I2C_STAT);
+ __my_writew (I2C_STAT_XRDY, I2C_STAT);
status = wait_for_pin ();
if ((status & I2C_STAT_XRDY)) {
/* send out next 1 byte */
writeb (value, I2C_DATA);
- writew (I2C_STAT_XRDY, I2C_STAT);
+ __my_writew (I2C_STAT_XRDY, I2C_STAT);
} else {
i2c_error = 1;
}
#else
/* send out two bytes */
- writew ((value << 8) + regoffset, I2C_DATA);
+ __my_writew ((value << 8) + regoffset, I2C_DATA);
#endif
/* must have enough delay to allow BB bit to go low */
udelay (50000);
- if (readw (I2C_STAT) & I2C_STAT_NACK) {
+ if (__my_readw (I2C_STAT) & I2C_STAT_NACK) {
i2c_error = 1;
}
} else {
@@ -181,20 +316,24 @@ static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
}
if (!i2c_error) {
+#ifdef DEBUG_I2C
+ int eout = 10;
+#else
int eout = 200;
+#endif
- writew (I2C_CON_EN, I2C_CON);
- while ((stat = readw (I2C_STAT)) || (readw (I2C_CON) & I2C_CON_MST)) {
+ __my_writew (I2C_CON_EN, I2C_CON);
+ while ((stat = __my_readw (I2C_STAT)) || (__my_readw (I2C_CON) & I2C_CON_MST)) {
udelay (1000);
/* have to read to clear intrrupt */
- writew (0xFFFF, I2C_STAT);
+ __my_writew (0xFFFF, I2C_STAT);
if(--eout == 0) /* better leave with error than hang */
break;
}
}
flush_fifo();
- writew (0xFFFF, I2C_STAT);
- writew (0, I2C_CNT);
+ __my_writew (0xFFFF, I2C_STAT);
+ __my_writew (0, I2C_CNT);
return i2c_error;
}
@@ -205,14 +344,14 @@ static void flush_fifo(void)
* you get a bus error
*/
while(1){
- stat = readw(I2C_STAT);
+ stat = __my_readw(I2C_STAT);
if(stat == I2C_STAT_RRDY){
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
readb(I2C_DATA);
#else
- readw(I2C_DATA);
+ __my_readw(I2C_DATA);
#endif
- writew(I2C_STAT_RRDY,I2C_STAT);
+ __my_writew(I2C_STAT_RRDY,I2C_STAT);
udelay(1000);
}else
break;
@@ -223,7 +362,7 @@ int i2c_probe (uchar chip)
{
int res = 1; /* default = fail */
- if (chip == readw (I2C_OA)) {
+ if (chip == __my_readw (I2C_OA)) {
return res;
}
@@ -231,27 +370,27 @@ int i2c_probe (uchar chip)
wait_for_bb ();
/* try to read one byte */
- writew (1, I2C_CNT);
+ __my_writew (1, I2C_CNT);
/* set slave address */
- writew (chip, I2C_SA);
+ __my_writew (chip, I2C_SA);
/* stop bit needed here */
- writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
+ __my_writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
/* enough delay for the NACK bit set */
udelay (50000);
- if (!(readw (I2C_STAT) & I2C_STAT_NACK)) {
+ if (!(__my_readw (I2C_STAT) & I2C_STAT_NACK)) {
res = 0; /* success case */
flush_fifo();
- writew(0xFFFF, I2C_STAT);
+ __my_writew(0xFFFF, I2C_STAT);
} else {
- writew(0xFFFF, I2C_STAT); /* failue, clear sources*/
- writew (readw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
+ __my_writew(0xFFFF, I2C_STAT); /* failue, clear sources*/
+ __my_writew (__my_readw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
udelay(20000);
wait_for_bb ();
}
flush_fifo();
- writew (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
- writew(0xFFFF, I2C_STAT);
+ __my_writew (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
+ __my_writew(0xFFFF, I2C_STAT);
return res;
}
@@ -310,17 +449,17 @@ static void wait_for_bb (void)
int timeout = 10;
u16 stat;
- writew(0xFFFF, I2C_STAT); /* clear current interruts...*/
- while ((stat = readw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
- writew (stat, I2C_STAT);
+ __my_writew(0xFFFF, I2C_STAT); /* clear current interruts...*/
+ while ((stat = __my_readw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
+ __my_writew (stat, I2C_STAT);
udelay (50000);
}
if (timeout <= 0) {
printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
- readw (I2C_STAT));
+ __my_readw (I2C_STAT));
}
- writew(0xFFFF, I2C_STAT); /* clear delayed stuff*/
+ __my_writew(0xFFFF, I2C_STAT); /* clear delayed stuff*/
}
static u16 wait_for_pin (void)
@@ -330,7 +469,7 @@ static u16 wait_for_pin (void)
do {
udelay (1000);
- status = readw (I2C_STAT);
+ status = __my_readw (I2C_STAT);
} while ( !(status &
(I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
@@ -338,8 +477,8 @@ static u16 wait_for_pin (void)
if (timeout <= 0) {
printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
- readw (I2C_STAT));
- writew(0xFFFF, I2C_STAT);
+ __my_readw (I2C_STAT));
+ __my_writew(0xFFFF, I2C_STAT);
}
return status;
}