Also support CONFIG_I2C_MULTI_BUS for the soft_i2c and the cpu/mpc8260/i2c.c driver.
Signed-off-by: Heiko Schocher <[EMAIL PROTECTED]> --- board/keymile/mgcoge/mgcoge.c | 93 ++++++++++++++++++++++------------------- board/keymile/mgsuvd/mgsuvd.c | 13 ++++++ cpu/mpc8260/i2c.c | 36 ++++++++++++++++ drivers/i2c/soft_i2c.c | 36 ++++++++++++++++ include/configs/mgcoge.h | 25 +++++++++++ include/configs/mgsuvd.h | 42 ++++++++++++++++++ 6 files changed, 202 insertions(+), 43 deletions(-) diff --git a/board/keymile/mgcoge/mgcoge.c b/board/keymile/mgcoge/mgcoge.c index 51b6dc6..9b37959 100644 --- a/board/keymile/mgcoge/mgcoge.c +++ b/board/keymile/mgcoge/mgcoge.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007 + * (C) Copyright 2007 - 2008 * Heiko Schocher, DENX Software Engineering, [EMAIL PROTECTED] * * See file CREDITS for list of people who contributed to this @@ -24,11 +24,16 @@ #include <common.h> #include <mpc8260.h> #include <ioports.h> +#include <malloc.h> #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) #include <libfdt.h> #endif +#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) +#include <i2c.h> +#endif + /* * I/O Port configuration table * @@ -163,8 +168,13 @@ const iop_conf_t iop_conf_tab[4][32] = { /* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD18 */ /* PD17 */ { 0, 0, 0, 0, 0, 0 }, /* PD17 */ /* PD16 */ { 0, 0, 0, 0, 0, 0 }, /* PD16 */ - /* PD15 */ { 0, 0, 0, 0, 0, 0 }, /* PD15 */ - /* PD14 */ { 0, 0, 0, 0, 0, 0 }, /* PD14 */ +#if defined(CONFIG_HARD_I2C) + /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */ + /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */ +#else + /* PD15 */ { 1, 0, 0, 0, 1, 1 }, /* PD15 */ + /* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* PD14 */ +#endif /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */ /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */ /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */ @@ -243,13 +253,13 @@ static long int try_init (volatile memctl8260_t * memctl, ulong sdmr, *sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN; *base = c; - size = get_ram_size((long *)base, maxsize); + size = get_ram_size ((long *)base, maxsize); *orx_ptr = orx | ~(size - 1); return (size); } -phys_size_t initdram(int board_type) +phys_size_t initdram (int board_type) { volatile immap_t *immap = (immap_t *) CFG_IMMR; volatile memctl8260_t *memctl = &immap->im_memctl; @@ -273,7 +283,7 @@ phys_size_t initdram(int board_type) int checkboard(void) { - puts("Board: mgcoge\n"); + puts ("Board: mgcoge\n"); return 0; } @@ -281,7 +291,7 @@ int checkboard(void) /* * Early board initalization. */ -int board_early_init_r(void) +int board_early_init_r (void) { /* setup the UPIOx */ *(char *)(CFG_PIGGY_BASE + 0x02) = 0xc0; @@ -293,68 +303,65 @@ int board_early_init_r(void) /* * update "memory" property in the blob */ -void ft_blob_update(void *blob, bd_t *bd) +void ft_blob_update (void *blob, bd_t *bd) { int ret, nodeoffset = 0; ulong memory_data[2] = {0}; ulong flash_data[8] = {0}; - memory_data[0] = cpu_to_be32(bd->bi_memstart); - memory_data[1] = cpu_to_be32(bd->bi_memsize); + memory_data[0] = cpu_to_be32 (bd->bi_memstart); + memory_data[1] = cpu_to_be32 (bd->bi_memsize); nodeoffset = fdt_path_offset (blob, "/memory"); if (nodeoffset >= 0) { - ret = fdt_setprop(blob, nodeoffset, "reg", memory_data, - sizeof(memory_data)); + ret = fdt_setprop (blob, nodeoffset, "reg", memory_data, + sizeof (memory_data)); if (ret < 0) - printf("ft_blob_update(): cannot set /memory/reg " - "property err:%s\n", fdt_strerror(ret)); - } - else { + printf ("ft_blob_update(): cannot set /memory/reg " + "property err:%s\n", fdt_strerror (ret)); + } else { /* memory node is required in dts */ - printf("ft_blob_update(): cannot find /memory node " - "err:%s\n", fdt_strerror(nodeoffset)); + printf ("ft_blob_update(): cannot find /memory node " + "err:%s\n", fdt_strerror (nodeoffset)); } /* update Flash addr, size */ - flash_data[2] = cpu_to_be32(CFG_FLASH_BASE); - flash_data[3] = cpu_to_be32(CFG_FLASH_SIZE); - flash_data[4] = cpu_to_be32(1); - flash_data[5] = cpu_to_be32(0); - flash_data[6] = cpu_to_be32(CFG_FLASH_BASE_1); - flash_data[7] = cpu_to_be32(CFG_FLASH_SIZE_1); + flash_data[2] = cpu_to_be32 (CFG_FLASH_BASE); + flash_data[3] = cpu_to_be32 (CFG_FLASH_SIZE); + flash_data[4] = cpu_to_be32 (1); + flash_data[5] = cpu_to_be32 (0); + flash_data[6] = cpu_to_be32 (CFG_FLASH_BASE_1); + flash_data[7] = cpu_to_be32 (CFG_FLASH_SIZE_1); nodeoffset = fdt_path_offset (blob, "/localbus"); if (nodeoffset >= 0) { - ret = fdt_setprop(blob, nodeoffset, "ranges", flash_data, - sizeof(flash_data)); + ret = fdt_setprop (blob, nodeoffset, "ranges", flash_data, + sizeof (flash_data)); if (ret < 0) - printf("ft_blob_update(): cannot set /localbus/ranges " - "property err:%s\n", fdt_strerror(ret)); - } - else { + printf ("ft_blob_update(): cannot set /localbus/ranges " + "property err:%s\n", fdt_strerror (ret)); + } else { /* memory node is required in dts */ - printf("ft_blob_update(): cannot find /localbus node " - "err:%s\n", fdt_strerror(nodeoffset)); + printf ("ft_blob_update(): cannot find /localbus node " + "err:%s\n", fdt_strerror (nodeoffset)); } /* MAC Adresse */ nodeoffset = fdt_path_offset (blob, "/soc/cpm/ethernet"); if (nodeoffset >= 0) { - ret = fdt_setprop(blob, nodeoffset, "mac-address", bd->bi_enetaddr, - sizeof(uchar) * 6); + ret = fdt_setprop (blob, nodeoffset, "mac-address", bd->bi_enetaddr, + sizeof (uchar) * 6); if (ret < 0) - printf("ft_blob_update(): cannot set /soc/cpm/ethernet/mac-address " - "property err:%s\n", fdt_strerror(ret)); - } - else { + printf ("ft_blob_update(): cannot set /soc/cpm/ethernet/mac-address " + "property err:%s\n", fdt_strerror (ret)); + } else { /* memory node is required in dts */ - printf("ft_blob_update(): cannot find /soc/cpm/ethernet node " - "err:%s\n", fdt_strerror(nodeoffset)); + printf ("ft_blob_update(): cannot find /soc/cpm/ethernet node " + "err:%s\n", fdt_strerror (nodeoffset)); } } -void ft_board_setup(void *blob, bd_t *bd) +void ft_board_setup (void *blob, bd_t *bd) { - ft_cpu_setup( blob, bd); - ft_blob_update(blob, bd); + ft_cpu_setup (blob, bd); + ft_blob_update (blob, bd); } #endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */ diff --git a/board/keymile/mgsuvd/mgsuvd.c b/board/keymile/mgsuvd/mgsuvd.c index c51ea7e..49b43ee 100644 --- a/board/keymile/mgsuvd/mgsuvd.c +++ b/board/keymile/mgsuvd/mgsuvd.c @@ -225,3 +225,16 @@ void ft_board_setup(void *blob, bd_t *bd) ft_blob_update(blob, bd); } #endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */ + +#if defined(CONFIG_SOFT_I2C) +int i2c_mgsuvd_read (void) +{ + int val; + + *(unsigned short *)(I2C_BASE_DIR) &= ~SDA_CONF; + udelay(1); + val = *(unsigned char *)(I2C_BASE_PORT); + + return ((val & SDA_BIT) == SDA_BIT); +} +#endif diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c index c3af7b6..335177f 100644 --- a/cpu/mpc8260/i2c.c +++ b/cpu/mpc8260/i2c.c @@ -36,6 +36,10 @@ DECLARE_GLOBAL_DATA_PTR; +#if defined(CONFIG_I2C_MULTI_BUS) +static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; +#endif /* CONFIG_I2C_MULTI_BUS */ + /* uSec to wait between polls of the i2c */ #define DELAY_US 100 /* uSec to wait for the CPM to start processing the buffer */ @@ -765,4 +769,36 @@ i2c_reg_write(uchar chip, uchar reg, uchar val) i2c_write(chip, reg, 1, &val, 1); } +#if defined(CONFIG_I2C_MULTI_BUS) +/* + * Functions for multiple I2C bus handling + */ +unsigned int i2c_get_bus_num(void) +{ + return i2c_bus_num; +} + +int i2c_set_bus_num(unsigned int bus) +{ + if (bus >= CFG_MAX_I2C_BUS) + return -1; + i2c_bus_num = bus; + + return 0; +} +/* TODO: add 100/400k switching */ +unsigned int i2c_get_bus_speed(void) +{ + return CFG_I2C_SPEED; +} + +int i2c_set_bus_speed(unsigned int speed) +{ + if (speed != CFG_I2C_SPEED) + return -1; + + return 0; +} + +#endif /* CONFIG_I2C_MULTI_BUS */ #endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c index 23db2ee..57736da 100644 --- a/drivers/i2c/soft_i2c.c +++ b/drivers/i2c/soft_i2c.c @@ -68,6 +68,10 @@ DECLARE_GLOBAL_DATA_PTR; #define PRINTD(fmt,args...) #endif +#if defined(CONFIG_I2C_MULTI_BUS) +static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; +#endif /* CONFIG_I2C_MULTI_BUS */ + /*----------------------------------------------------------------------- * Local functions */ @@ -230,6 +234,38 @@ static int write_byte(uchar data) return(nack); /* not a nack is an ack */ } +#if defined(CONFIG_I2C_MULTI_BUS) +/* + * Functions for multiple I2C bus handling + */ +unsigned int i2c_get_bus_num(void) +{ + return i2c_bus_num; +} + +int i2c_set_bus_num(unsigned int bus) +{ + if (bus >= CFG_MAX_I2C_BUS) + return -1; + i2c_bus_num = bus; + + return 0; +} + +/* TODO: add 100/400k switching */ +unsigned int i2c_get_bus_speed(void) +{ + return CFG_I2C_SPEED; +} + +int i2c_set_bus_speed(unsigned int speed) +{ + if (speed != CFG_I2C_SPEED) + return -1; + + return 0; +} +#endif /*----------------------------------------------------------------------- * if ack == I2C_ACK, ACK the byte so can continue reading, else diff --git a/include/configs/mgcoge.h b/include/configs/mgcoge.h index 23af3ec..159eeae 100644 --- a/include/configs/mgcoge.h +++ b/include/configs/mgcoge.h @@ -82,6 +82,7 @@ #include <config_cmd_default.h> #define CONFIG_CMD_ECHO +#define CONFIG_CMD_I2C #define CONFIG_CMD_IMMAP #define CONFIG_CMD_MII #define CONFIG_CMD_PING @@ -176,6 +177,30 @@ #define CONFIG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) #endif /* CONFIG_ENV_IS_IN_FLASH */ +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +#define CFG_I2C_SPEED 50000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ + +#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */ +#define I2C_ACTIVE (iop->pdir |= 0x00010000) +#define I2C_TRISTATE (iop->pdir &= ~0x00010000) +#define I2C_READ ((iop->pdat & 0x00010000) != 0) +#define I2C_SDA(bit) if(bit) iop->pdat |= 0x00010000; \ + else iop->pdat &= ~0x00010000 +#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \ + else iop->pdat &= ~0x00020000 +#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */ + +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_I2C_CMD_TREE 1 +#define CFG_MAX_I2C_BUS 2 + #define CFG_IMMR 0xF0000000 #define CFG_INIT_RAM_ADDR CFG_IMMR diff --git a/include/configs/mgsuvd.h b/include/configs/mgsuvd.h index 740767e..2c30fab 100644 --- a/include/configs/mgsuvd.h +++ b/include/configs/mgsuvd.h @@ -113,6 +113,7 @@ #define CONFIG_CMD_ASKENV #define CONFIG_CMD_DHCP +#define CONFIG_CMD_I2C #define CONFIG_CMD_NFS #define CONFIG_CMD_PING @@ -330,4 +331,45 @@ #define OF_TBCLK (bd->bi_busfreq / 4) #define OF_STDOUT_PATH "/soc/cpm/[EMAIL PROTECTED]" +/* enable I2C and select the hardware/software driver */ +#undef CONFIG_HARD_I2C /* I2C with hardware support */ +#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */ +#define CFG_I2C_SPEED 50000 /* I2C speed and slave address */ +#define CFG_I2C_SLAVE 0x7F + +/* + * Software (bit-bang) I2C driver configuration + */ +#define I2C_BASE_DIR (CFG_PIGGY_BASE + 0x04) +#define I2C_BASE_PORT (CFG_PIGGY_BASE + 0x09) + +#define SDA_BIT 0x40 +#define SCL_BIT 0x80 +#define SDA_CONF 0x1000 +#define SCL_CONF 0x2000 + +#define I2C_ACTIVE do {} while (0) +#define I2C_TRISTATE do {} while (0) +#define I2C_READ i2c_mgsuvd_read () +#define I2C_SDA(bit) if(bit) { \ + *(unsigned short *)(I2C_BASE_DIR) &= ~SDA_CONF; \ + } \ + else { \ + *(unsigned char *)(I2C_BASE_PORT) &= ~SDA_BIT; \ + *(unsigned short *)(I2C_BASE_DIR) |= SDA_CONF; \ + } +#define I2C_SCL(bit) if(bit) { \ + *(unsigned short *)(I2C_BASE_DIR) &= ~SCL_CONF; \ + } \ + else { \ + *(unsigned char *)(I2C_BASE_PORT) &= ~SCL_BIT; \ + *(unsigned short *)(I2C_BASE_DIR) |= SCL_CONF; \ + } +#define I2C_DELAY udelay(50) /* 1/4 I2C clock duration */ + +#define CONFIG_I2C_MULTI_BUS 1 +#define CONFIG_I2C_CMD_TREE 1 +#define CFG_MAX_I2C_BUS 2 + + #endif /* __CONFIG_H */ -- 1.5.6.1 -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot