diff options
author | Daniel Schaeffer <daniel.schaeffer@timesys.com> | 2009-10-08 13:30:58 -0400 |
---|---|---|
committer | Daniel Schaeffer <daniel.schaeffer@timesys.com> | 2009-10-08 13:30:58 -0400 |
commit | 954237a65dc8fd061892b84c79b31beccf1cc3a6 (patch) | |
tree | 49456fe0e4fcf52c48c8fdd4e2a2b9bec09162d6 | |
parent | 0d67e29725ba728344fe829689104e21b24e8aa3 (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/Makefile | 2 | ||||
-rw-r--r-- | board/omap3/common/power-lv_som.c | 76 | ||||
-rw-r--r-- | board/omap3/lv_som/lv_som.c | 2 | ||||
-rw-r--r-- | drivers/i2c/omap24xx_i2c.c | 263 |
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; } |