diff options
-rw-r--r-- | src/cpu/samsung/exynos5-common/exynos-fb.c | 2 | ||||
-rw-r--r-- | src/cpu/samsung/exynos5-common/i2c.c | 354 | ||||
-rw-r--r-- | src/cpu/samsung/exynos5-common/i2c.h | 8 | ||||
-rw-r--r-- | src/drivers/maxim/max77686/max77686.c | 53 | ||||
-rw-r--r-- | src/drivers/maxim/max77686/max77686.h | 13 | ||||
-rw-r--r-- | src/include/device/i2c-old.h | 281 | ||||
-rw-r--r-- | src/mainboard/google/snow/bootblock.c | 2 | ||||
-rw-r--r-- | src/mainboard/google/snow/romstage.c | 26 |
8 files changed, 126 insertions, 613 deletions
diff --git a/src/cpu/samsung/exynos5-common/exynos-fb.c b/src/cpu/samsung/exynos5-common/exynos-fb.c index d3710a3a6d..30d0767923 100644 --- a/src/cpu/samsung/exynos5-common/exynos-fb.c +++ b/src/cpu/samsung/exynos5-common/exynos-fb.c @@ -33,7 +33,7 @@ #include <cpu/samsung/exynos5250/sysreg.h> #include <drivers/maxim/max77686/max77686.h> -#include "device/i2c-old.h" +#include "device/i2c.h" #include "cpu/samsung/exynos5-common/i2c.h" #include "cpu/samsung/exynos5250/dsim.h" #include "cpu/samsung/exynos5250/fimd.h" diff --git a/src/cpu/samsung/exynos5-common/i2c.c b/src/cpu/samsung/exynos5-common/i2c.c index c5315304b8..30fabe1659 100644 --- a/src/cpu/samsung/exynos5-common/i2c.c +++ b/src/cpu/samsung/exynos5-common/i2c.c @@ -26,19 +26,14 @@ * The different address mapping is handled by the s3c24xx.h files below. */ -#include <common.h> +#include <delay.h> #include <arch/io.h> -#include "clk.h" +#include <console/console.h> +#include <device/i2c.h> #include "cpu/samsung/exynos5-common/clk.h" -#include "cpu/samsung/exynos5250/cpu.h" -#include "gpio.h" -#include "cpu/samsung/exynos5250/gpio.h" +#include "cpu/samsung/exynos5-common/i2c.h" #include "cpu/samsung/exynos5250/pinmux.h" -//#include <fdtdec.h> -#include "device/i2c-old.h" -#include "i2c.h" - #define I2C_WRITE 0 #define I2C_READ 1 @@ -65,54 +60,49 @@ enum { I2C_STOP_TIMEOUT_US = 200, /* waiting for stop events */ }; -/* We should not rely on any particular ordering of these IDs */ -#if 0 -#ifndef CONFIG_OF_CONTROL -static enum periph_id periph_for_dev[EXYNOS_I2C_MAX_CONTROLLERS] = { - PERIPH_ID_I2C0, - PERIPH_ID_I2C1, - PERIPH_ID_I2C2, - PERIPH_ID_I2C3, - PERIPH_ID_I2C4, - PERIPH_ID_I2C5, - PERIPH_ID_I2C6, - PERIPH_ID_I2C7, +static struct s3c24x0_i2c_bus i2c_buses[] = { + /* FIXME: exynos5250-specific? */ + { + .bus_num = 0, + .regs = (struct s3c24x0_i2c *)0x12c60000, + .periph_id = PERIPH_ID_I2C0, + }, + { + .bus_num = 1, + .regs = (struct s3c24x0_i2c *)0x12c70000, + .periph_id = PERIPH_ID_I2C1, + }, + { + .bus_num = 2, + .regs = (struct s3c24x0_i2c *)0x12c80000, + .periph_id = PERIPH_ID_I2C2, + }, + { + .bus_num = 3, + .regs = (struct s3c24x0_i2c *)0x12c90000, + .periph_id = PERIPH_ID_I2C3, + }, + { + .bus_num = 4, + .regs = (struct s3c24x0_i2c *)0x12ca0000, + .periph_id = PERIPH_ID_I2C4, + }, + { + .bus_num = 5, + .regs = (struct s3c24x0_i2c *)0x12cb0000, + .periph_id = PERIPH_ID_I2C5, + }, + { + .bus_num = 6, + .regs = (struct s3c24x0_i2c *)0x12cc0000, + .periph_id = PERIPH_ID_I2C6, + }, + { + .bus_num = 7, + .regs = (struct s3c24x0_i2c *)0x12cd0000, + .periph_id = PERIPH_ID_I2C7, + }, }; -#endif -#endif - -static unsigned int g_current_bus __attribute__((section(".data"))); -static struct s3c24x0_i2c *g_early_i2c_config __attribute__((section(".data"))); - -static struct s3c24x0_i2c_bus i2c_bus[EXYNOS_I2C_MAX_CONTROLLERS] - __attribute__((section(".data"))); -static int i2c_busses __attribute__((section(".data"))); - -void i2c_set_early_reg(unsigned int base) -{ - g_early_i2c_config = (struct s3c24x0_i2c *)base; -} - -static struct s3c24x0_i2c_bus *get_bus(int bus_idx) -{ - /* If an early i2c config exists we just use that */ - if (g_early_i2c_config) { - /* FIXME: value not retained from i2c_set_early_reg()? (but then, how - * did if (!i2c) check pass earlier on? Corrupt value? */ - i2c_bus[0].regs = g_early_i2c_config; - return &i2c_bus[0]; - } - - if (bus_idx < i2c_busses) - return &i2c_bus[bus_idx]; - debug("Undefined bus: %d\n", bus_idx); - return NULL; -} - -static inline struct exynos5_gpio_part1 *exynos_get_base_gpio1(void) -{ - return (struct exynos5_gpio_part1 *)(EXYNOS5_GPIO_PART1_BASE); -} static int WaitForXfer(struct s3c24x0_i2c *i2c) { @@ -121,7 +111,7 @@ static int WaitForXfer(struct s3c24x0_i2c *i2c) i = I2C_XFER_TIMEOUT_MS * 20; while (!(readl(&i2c->iiccon) & I2CCON_IRPND)) { if (i == 0) { - debug("%s: i2c xfer timeout\n", __func__); + printk(BIOS_ERR, "%s: i2c xfer timeout\n", __func__); return I2C_NOK_TOUT; } udelay(50); @@ -142,15 +132,14 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c) x = readl(&i2c->iiccon); writel(x & ~I2CCON_IRPND, &i2c->iiccon); - /* FIXME(dhendrix): cannot use nested macro (compilation failure) */ -// writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon); } -static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) +static void i2c_ch_init(struct s3c24x0_i2c_bus *bus, int speed, int slaveadd) { unsigned long freq, pres = 16, div; + unsigned long val; - freq = clock_get_periph_rate(PERIPH_ID_I2C0); + freq = clock_get_periph_rate(bus->periph_id); /* calculate prescaler and divisor values */ if ((freq / pres / (16 + 1)) > speed) /* set prescaler to 512 */ @@ -162,136 +151,25 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) div++; /* set prescaler, divisor according to freq, also set ACKGEN, IRQ */ - writel((div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0), &i2c->iiccon); + val = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0); + writel(val, &bus->regs->iiccon); - /* init to SLAVE REVEIVE and set slaveaddr */ - writel(0, &i2c->iicstat); - writel(slaveadd, &i2c->iicadd); + /* init to SLAVE RECEIVE mode and clear I2CADDn */ + writel(0, &bus->regs->iicstat); + writel(slaveadd, &bus->regs->iicadd); /* program Master Transmit (and implicit STOP) */ - writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat); -} - -/* TODO: determine if this is necessary to init board using FDT-provided info */ -#if 0 -void board_i2c_init(const void *blob) -{ - /* - * Turn off the early i2c configuration and init the i2c properly, - * this is done here to enable the use of i2c configs from FDT. - */ - i2c_set_early_reg(0); - -#ifdef CONFIG_OF_CONTROL - int node_list[EXYNOS_I2C_MAX_CONTROLLERS]; - int i, count; - - count = fdtdec_find_aliases_for_id(blob, "i2c", - COMPAT_SAMSUNG_S3C2440_I2C, node_list, - EXYNOS_I2C_MAX_CONTROLLERS); - - for (i = 0; i < count; i++) { - struct s3c24x0_i2c_bus *bus; - int node = node_list[i]; - - if (node < 0) - continue; - bus = &i2c_bus[i2c_busses]; - bus->regs = (struct s3c24x0_i2c *) - fdtdec_get_addr(blob, node, "reg"); - bus->id = (enum periph_id) - fdtdec_get_int(blob, node, "samsung,periph-id", -1); - bus->node = node; - bus->bus_num = i2c_busses++; - } -#else - int i; - - for (i = 0; i < EXYNOS_I2C_MAX_CONTROLLERS; i++) { - unsigned intptr_t reg_addr = samsung_get_base_i2c() + - EXYNOS_I2C_SPACING * i; - - i2c_bus[i].regs = (struct s3c24x0_i2c_bus *)reg_addr; - i2c_bus[i].id = periph_for_dev[i]; - } - i2c_busses = EXYNOS_I2C_MAX_CONTROLLERS; -#endif + writel(I2C_MODE_MT | I2C_TXRX_ENA, &bus->regs->iicstat); } -#endif /* * MULTI BUS I2C support */ -static void i2c_bus_init(struct s3c24x0_i2c_bus *i2c, unsigned int bus) -{ - exynos_pinmux_config(i2c->id, 0); - i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -} - -#ifdef CONFIG_I2C_MULTI_BUS -int i2c_set_bus_num(unsigned int bus) +static void i2c_bus_init(struct s3c24x0_i2c_bus *bus, int speed, int slaveadd) { - struct s3c24x0_i2c_bus *i2c; - - i2c = get_bus(bus); - if (!i2c) - return -1; - g_current_bus = bus; - i2c_bus_init(i2c, g_current_bus); - - return 0; + exynos_pinmux_config(bus->periph_id, 0); + i2c_ch_init(bus, speed, slaveadd); } -unsigned int i2c_get_bus_num(void) -{ - return g_current_bus; -} -#endif - -#ifdef CONFIG_OF_CONTROL -int i2c_get_bus_num_fdt(const void *blob, int node) -{ - enum fdt_compat_id compat; - fdt_addr_t reg; - int i; - - compat = fdtdec_lookup(blob, node); - if (compat != COMPAT_SAMSUNG_S3C2440_I2C) { - debug("%s: Not a supported I2C node\n", __func__); - return -1; - } - - reg = fdtdec_get_addr(blob, node, "reg"); - for (i = 0; i < i2c_busses; i++) - if (reg == (fdt_addr_t)(unsigned intptr_t)i2c_bus[i].regs) - return i; - - debug("%s: Can't find any matched I2C bus\n", __func__); - return -1; -} - -int i2c_reset_port_fdt(const void *blob, int node) -{ - struct s3c24x0_i2c_bus *i2c; - - int bus; - - bus = i2c_get_bus_num_fdt(blob, node); - if (bus < 0) { - printf("could not get bus for node %d\n", node); - return -1; - } - i2c = get_bus(bus); - if (!i2c) { - printf("get_bus() failed for node node %d\n", node); - return -1; - } - - i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - - return 0; -} -#endif - /* * Verify the whether I2C ACK was received or not * @@ -321,21 +199,13 @@ static int i2c_send_verify(struct s3c24x0_i2c *i2c, unsigned char buf[], return result; } -void i2c_init(int speed, int slaveadd) +void i2c_init(unsigned bus_num, int speed, int slaveadd) { struct s3c24x0_i2c_bus *i2c; - struct exynos5_gpio_part1 *gpio; int i; - uint32_t x; - - /* By default i2c channel 0 is the current bus */ - g_current_bus = 0; - i2c = get_bus(g_current_bus); - if (!i2c) - return; - - i2c_bus_init(i2c, g_current_bus); + i2c = &i2c_buses[bus_num]; + i2c_bus_init(i2c, speed, slaveadd); /* wait for some time to give previous transfer a chance to finish */ i = I2C_INIT_TIMEOUT_MS * 20; @@ -344,13 +214,7 @@ void i2c_init(int speed, int slaveadd) i--; } - gpio = exynos_get_base_gpio1(); - /* FIXME(dhendrix): cannot use nested macro (compilation failure) */ -// writel((readl(&gpio->b3.con) & ~0x00FF) | 0x0022, &gpio->b3.con); - x = readl(&gpio->b3.con); - writel((x & ~0x00FF) | 0x0022, &gpio->b3.con); - - i2c_ch_init(i2c->regs, speed, slaveadd); + i2c_ch_init(i2c, speed, slaveadd); } /* @@ -397,7 +261,7 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, if (data == 0 || data_len == 0) { /* Don't support data transfer of no length or to address 0 */ - debug("i2c_transfer: bad call\n"); + printk(BIOS_ERR, "i2c_transfer: bad call\n"); return I2C_NOK; } @@ -409,12 +273,10 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, } if (readl(&i2c->iicstat) & I2CSTAT_BSY) { - debug("%s: bus busy\n", __func__); + printk(BIOS_ERR, "%s: bus busy\n", __func__); return I2C_NOK_TOUT; } - /* FIXME(dhendrix): cannot use nested macro (compilation failure) */ - //writel(readl(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon); x = readl(&i2c->iiccon); writel(x | I2CCON_ACKGEN, &i2c->iiccon); @@ -465,12 +327,6 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, while ((i < data_len) && (result == I2C_OK)) { /* disable ACK for final READ */ if (i == data_len - 1) { - /* FIXME(dhendrix): nested macro */ -#if 0 - writel(readl(&i2c->iiccon) & - ~I2CCON_ACKGEN, - &i2c->iiccon); -#endif x = readl(&i2c->iiccon) & ~I2CCON_ACKGEN; writel(x, &i2c->iiccon); } @@ -488,7 +344,7 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, } default: - debug("i2c_transfer: bad call\n"); + printk(BIOS_ERR, "i2c_transfer: bad call\n"); result = stop_bit_result = I2C_NOK; break; } @@ -501,35 +357,15 @@ static int i2c_transfer(struct s3c24x0_i2c *i2c, return (result == I2C_OK) ? stop_bit_result : result; } -int i2c_probe(unsigned char chip) -{ - struct s3c24x0_i2c_bus *i2c; - unsigned char buf[1]; - int ret; - - i2c = get_bus(g_current_bus); - if (!i2c) - return -1; - buf[0] = 0; - - /* - * What is needed is to send the chip address and verify that the - * address was <ACK>ed (i.e. there was a chip at that address which - * drove the data line low). - */ - ret = i2c_transfer(i2c->regs, I2C_READ, chip << 1, 0, 0, buf, 1); - - return ret != I2C_OK; -} - -int i2c_read(unsigned char chip, unsigned int addr, int alen, unsigned char *buffer, int len) +int i2c_read(unsigned bus, unsigned chip, unsigned addr, + unsigned alen, unsigned char *buf, unsigned len) { struct s3c24x0_i2c_bus *i2c; unsigned char xaddr[4]; int ret; if (alen > 4) { - debug("I2C read: addr len %d not supported\n", alen); + printk(BIOS_ERR, "I2C read: addr len %d not supported\n", alen); return 1; } @@ -540,42 +376,26 @@ int i2c_read(unsigned char chip, unsigned int addr, int alen, unsigned char *buf xaddr[3] = addr & 0xFF; } -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - /* - * EEPROM chips that implement "address overflow" are ones - * like Catalyst 24WC04/08/16 which has 9/10/11 bits of - * address and the extra bits end up in the "chip address" - * bit slots. This makes a 24WC08 (1Kbyte) chip look like - * four 256 byte chips. - * - * Note that we consider the length of the address field to - * still be one byte because the extra address bits are - * hidden in the chip address. - */ - if (alen > 0) - chip |= ((addr >> (alen * 8)) & - CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); -#endif - i2c = get_bus(g_current_bus); - if (!i2c) - return -1; + i2c = &i2c_buses[bus]; ret = i2c_transfer(i2c->regs, I2C_READ, chip << 1, &xaddr[4 - alen], - alen, buffer, len); + alen, buf, len); if (ret) { - debug("I2c read: failed %d\n", ret); + printk(BIOS_ERR, "I2c read: failed %d\n", ret); return 1; } return 0; } -int i2c_write(unsigned char chip, unsigned int addr, int alen, unsigned char *buffer, int len) +int i2c_write(unsigned bus, unsigned chip, unsigned addr, + unsigned alen, unsigned char *buf, unsigned len) { struct s3c24x0_i2c_bus *i2c; unsigned char xaddr[4]; int ret; if (alen > 4) { - debug("I2C write: addr len %d not supported\n", alen); + printk(BIOS_ERR, "I2C write: addr len %d not supported\n", + alen); return 1; } @@ -585,28 +405,10 @@ int i2c_write(unsigned char chip, unsigned int addr, int alen, unsigned char *bu xaddr[2] = (addr >> 8) & 0xFF; xaddr[3] = addr & 0xFF; } -#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW - /* - * EEPROM chips that implement "address overflow" are ones - * like Catalyst 24WC04/08/16 which has 9/10/11 bits of - * address and the extra bits end up in the "chip address" - * bit slots. This makes a 24WC08 (1Kbyte) chip look like - * four 256 byte chips. - * - * Note that we consider the length of the address field to - * still be one byte because the extra address bits are - * hidden in the chip address. - */ - if (alen > 0) - chip |= ((addr >> (alen * 8)) & - CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); -#endif - i2c = get_bus(g_current_bus); - if (!i2c) - return -1; + i2c = &i2c_buses[bus]; ret = i2c_transfer(i2c->regs, I2C_WRITE, chip << 1, &xaddr[4 - alen], - alen, buffer, len); + alen, buf, len); return ret != 0; } diff --git a/src/cpu/samsung/exynos5-common/i2c.h b/src/cpu/samsung/exynos5-common/i2c.h index eb68af78f0..0bfee340e1 100644 --- a/src/cpu/samsung/exynos5-common/i2c.h +++ b/src/cpu/samsung/exynos5-common/i2c.h @@ -35,9 +35,11 @@ struct s3c24x0_i2c { }; struct s3c24x0_i2c_bus { - int node; /* device tree node */ - int bus_num; /* i2c bus number */ + int bus_num; struct s3c24x0_i2c *regs; - enum periph_id id; + enum periph_id periph_id; }; + +void i2c_init(unsigned bus, int speed, int slaveadd); + #endif /* _S3C24X0_I2C_H */ diff --git a/src/drivers/maxim/max77686/max77686.c b/src/drivers/maxim/max77686/max77686.c index 2cac4dfc12..5760d4223d 100644 --- a/src/drivers/maxim/max77686/max77686.c +++ b/src/drivers/maxim/max77686/max77686.c @@ -23,8 +23,7 @@ #include <arch/io.h> #include <common.h> -//#include <smbus.h> -#include <device/i2c-old.h> +#include <device/i2c.h> #include "max77686.h" @@ -91,10 +90,10 @@ struct max77686_para max77686_param[] = {/*{vol_addr, vol_bitpos, * @param val value to be written * */ -static inline int max77686_i2c_write(unsigned char chip_addr, +static inline int max77686_i2c_write(unsigned int bus, unsigned char chip_addr, unsigned int reg, unsigned char val) { - return i2c_write(chip_addr, reg, 1, &val, 1); + return i2c_write(bus, chip_addr, reg, 1, &val, 1); } /* @@ -105,10 +104,10 @@ static inline int max77686_i2c_write(unsigned char chip_addr, * @param val value to be written * */ -static inline int max77686_i2c_read(unsigned char chip_addr, +static inline int max77686_i2c_read(unsigned int bus, unsigned char chip_addr, unsigned int reg, unsigned char *val) { - return i2c_read(chip_addr, reg, 1, val, 1); + return i2c_read(bus, chip_addr, reg, 1, val, 1); } /* @@ -121,7 +120,7 @@ static inline int max77686_i2c_read(unsigned char chip_addr, needed to set the buck/ldo enable bit OFF * @return Return 0 if ok, else -1 */ -static int max77686_enablereg(enum max77686_regnum reg, int enable) +static int max77686_enablereg(unsigned int bus, enum max77686_regnum reg, int enable) { struct max77686_para *pmic; unsigned char read_data; @@ -129,7 +128,7 @@ static int max77686_enablereg(enum max77686_regnum reg, int enable) pmic = &max77686_param[reg]; - ret = max77686_i2c_read(MAX77686_I2C_ADDR, pmic->reg_enaddr, + ret = max77686_i2c_read(bus, MAX77686_I2C_ADDR, pmic->reg_enaddr, &read_data); if (ret != 0) { debug("max77686 i2c read failed.\n"); @@ -145,7 +144,7 @@ static int max77686_enablereg(enum max77686_regnum reg, int enable) pmic->reg_enbiton << pmic->reg_enbitpos); } - ret = max77686_i2c_write(MAX77686_I2C_ADDR, + ret = max77686_i2c_write(bus, MAX77686_I2C_ADDR, pmic->reg_enaddr, read_data); if (ret != 0) { debug("max77686 i2c write failed.\n"); @@ -155,8 +154,8 @@ static int max77686_enablereg(enum max77686_regnum reg, int enable) return 0; } -static int max77686_do_volsetting(enum max77686_regnum reg, unsigned int volt, - int enable, int volt_units) +int max77686_volsetting(unsigned int bus, enum max77686_regnum reg, + unsigned int volt, int enable, int volt_units) { struct max77686_para *pmic; unsigned char read_data; @@ -170,7 +169,7 @@ static int max77686_do_volsetting(enum max77686_regnum reg, unsigned int volt, return -1; } - ret = max77686_i2c_read(MAX77686_I2C_ADDR, pmic->vol_addr, &read_data); + ret = max77686_i2c_read(bus, MAX77686_I2C_ADDR, pmic->vol_addr, &read_data); if (ret != 0) { debug("max77686 i2c read failed.\n"); return -1; @@ -190,13 +189,13 @@ static int max77686_do_volsetting(enum max77686_regnum reg, unsigned int volt, clrsetbits_8(&read_data, pmic->vol_bitmask << pmic->vol_bitpos, vol_level << pmic->vol_bitpos); - ret = max77686_i2c_write(MAX77686_I2C_ADDR, pmic->vol_addr, read_data); + ret = max77686_i2c_write(bus, MAX77686_I2C_ADDR, pmic->vol_addr, read_data); if (ret != 0) { debug("max77686 i2c write failed.\n"); return -1; } - ret = max77686_enablereg(reg, enable); + ret = max77686_enablereg(bus, reg, enable); if (ret != 0) { debug("Failed to enable buck/ldo.\n"); return -1; @@ -204,31 +203,17 @@ static int max77686_do_volsetting(enum max77686_regnum reg, unsigned int volt, return 0; } -int max77686_volsetting(enum max77686_regnum reg, unsigned int volt, - int enable, int volt_units) +int max77686_enable_32khz_cp(unsigned int bus) { - int old_bus = i2c_get_bus_num(); - int ret; - - i2c_set_bus_num(0); - ret = max77686_do_volsetting(reg, volt, enable, volt_units); - i2c_set_bus_num(old_bus); - return ret; -} - -int max77686_enable_32khz_cp(void) -{ - i2c_set_bus_num(0); - return max77686_enablereg(PMIC_EN32KHZ_CP, REG_ENABLE); + return max77686_enablereg(bus, PMIC_EN32KHZ_CP, REG_ENABLE); } -int max77686_disable_backup_batt(void) +int max77686_disable_backup_batt(unsigned int bus) { unsigned char val; int ret; - i2c_set_bus_num(0); - ret = max77686_i2c_read(MAX77686_I2C_ADDR, REG_BBAT, &val); + ret = max77686_i2c_read(bus, MAX77686_I2C_ADDR, REG_BBAT, &val); if (ret) { debug("max77686 i2c read failed\n"); return ret; @@ -241,7 +226,7 @@ int max77686_disable_backup_batt(void) /* First disable charging */ val &= ~BBAT_BBCHOSTEN_MASK; - ret = max77686_i2c_write(MAX77686_I2C_ADDR, REG_BBAT, val); + ret = max77686_i2c_write(bus, MAX77686_I2C_ADDR, REG_BBAT, val); if (ret) { debug("max77686 i2c write failed\n"); return -1; @@ -249,7 +234,7 @@ int max77686_disable_backup_batt(void) /* Finally select 3.5V to minimize power consumption */ val |= BBAT_BBCVS_MASK; - ret = max77686_i2c_write(MAX77686_I2C_ADDR, REG_BBAT, val); + ret = max77686_i2c_write(bus, MAX77686_I2C_ADDR, REG_BBAT, val); if (ret) { debug("max77686 i2c write failed\n"); return -1; diff --git a/src/drivers/maxim/max77686/max77686.h b/src/drivers/maxim/max77686/max77686.h index ee53e27a81..cebd2d9a1c 100644 --- a/src/drivers/maxim/max77686/max77686.h +++ b/src/drivers/maxim/max77686/max77686.h @@ -105,13 +105,16 @@ enum { /** * This function enables the 32KHz coprocessor clock. * + * @param bus i2c bus + * * Return 0 if ok, else -1 */ -int max77686_enable_32khz_cp(void); +int max77686_enable_32khz_cp(unsigned int bus); /** * Set the required voltage level of pmic * + * @param bus i2c bus * @param reg register number of buck/ldo to be set * @param volt voltage level to be set * @param enable enable or disable bit @@ -120,14 +123,16 @@ int max77686_enable_32khz_cp(void); * * @return Return 0 if ok, else -1 */ -int max77686_volsetting(enum max77686_regnum reg, unsigned int volt, - int enable, int volt_units); +int max77686_volsetting(unsigned int bus, enum max77686_regnum reg, + unsigned int volt, int enable, int volt_units); /** * Disable charging of the RTC backup battery * + * @param bus i2c bus + * * @return Return 0 if ok, else -1 */ -int max77686_disable_backup_batt(void); +int max77686_disable_backup_batt(unsigned int bus); #endif /* __MAX77686_PMIC_H_ */ diff --git a/src/include/device/i2c-old.h b/src/include/device/i2c-old.h deleted file mode 100644 index bd6dd0c231..0000000000 --- a/src/include/device/i2c-old.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * (C) Copyright 2001 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.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 - * - * The original I2C interface was - * (C) 2000 by Paolo Scaffardi (arsenio@tin.it) - * AIRVENT SAM s.p.a - RIMINI(ITALY) - * but has been changed substantially. - */ - -#ifndef _I2C_H_ -#define _I2C_H_ - -/* - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - * - * The implementation MUST NOT use static or global variables if the - * I2C routines are used to read SDRAM configuration information - * because this is done before the memories are initialized. Limited - * use of stack-based variables are OK (the initial stack size is - * limited). - * - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - */ - -/* - * Configuration items. - */ -#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ - -#ifdef CONFIG_I2C_MULTI_BUS -#define MAX_I2C_BUS 2 -#define I2C_MULTI_BUS 1 -#else -#define MAX_I2C_BUS 1 -#define I2C_MULTI_BUS 0 -#endif - -#if !defined(CONFIG_SYS_MAX_I2C_BUS) -#define CONFIG_SYS_MAX_I2C_BUS MAX_I2C_BUS -#endif - -/* define the I2C bus number for RTC and DTT if not already done */ -#if !defined(CONFIG_SYS_RTC_BUS_NUM) -#define CONFIG_SYS_RTC_BUS_NUM 0 -#endif -#if !defined(CONFIG_SYS_DTT_BUS_NUM) -#define CONFIG_SYS_DTT_BUS_NUM 0 -#endif -#if !defined(CONFIG_SYS_SPD_BUS_NUM) -#define CONFIG_SYS_SPD_BUS_NUM 0 -#endif - -#ifndef I2C_SOFT_DECLARATIONS -# if defined(CONFIG_MPC8260) -# define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT); -# elif defined(CONFIG_8xx) -# define I2C_SOFT_DECLARATIONS volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; - -# elif (defined(CONFIG_AT91RM9200) || \ - defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) || \ - defined(CONFIG_AT91SAM9263)) && !defined(CONFIG_AT91_LEGACY) -# define I2C_SOFT_DECLARATIONS at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; -# else -# define I2C_SOFT_DECLARATIONS -# endif -#endif - -#ifdef CONFIG_8xx -/* Set default value for the I2C bus speed on 8xx. In the - * future, we'll define these in all 8xx board config files. - */ -#ifndef CONFIG_SYS_I2C_SPEED -#define CONFIG_SYS_I2C_SPEED 50000 -#endif -#endif - -/* - * Many boards/controllers/drivers don't support an I2C slave interface so - * provide a default slave address for them for use in common code. A real - * value for CONFIG_SYS_I2C_SLAVE should be defined for any board which does - * support a slave interface. - */ -#ifndef CONFIG_SYS_I2C_SLAVE -#define CONFIG_SYS_I2C_SLAVE 0xfe -#endif - -/* - * Initialization, must be called once on start up, may be called - * repeatedly to change the speed and slave addresses. - */ -void i2c_init(int speed, int slaveaddr); -void i2c_init_board(void); -#ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT -void i2c_board_late_init(void); -#endif - -#if defined(CONFIG_I2C_MUX) - -typedef struct _mux { - unsigned char chip; - unsigned char channel; - char *name; - struct _mux *next; -} I2C_MUX; - -typedef struct _mux_device { - int busid; - I2C_MUX *mux; /* List of muxes, to reach the device */ - struct _mux_device *next; -} I2C_MUX_DEVICE; - -I2C_MUX_DEVICE *i2c_mux_search_device(int id); -I2C_MUX_DEVICE *i2c_mux_ident_muxstring (unsigned char *buf); -int i2x_mux_select_mux(int bus); -int i2c_mux_ident_muxstring_f (unsigned char *buf); -#endif - -/* - * Probe the given I2C chip address. Returns 0 if a chip responded, - * not 0 on failure. - */ -int i2c_probe(unsigned char chip); - -/* - * Read/Write interface: - * chip: I2C chip address, range 0..127 - * addr: Memory (register) address within the chip - * alen: Number of bytes to use for addr (typically 1, 2 for larger - * memories, 0 for register type devices with only one - * register) - * buffer: Where to read/write the data - * len: How many bytes to read/write - * - * Returns: 0 on success, not 0 on failure - */ -int i2c_read(unsigned char chip, unsigned int addr, int alen, - unsigned char *buffer, int len); -int i2c_write(unsigned char chip, unsigned int addr, int alen, - unsigned char *buffer, int len); - -/* - * Utility routines to read/write registers. - */ -static inline u8 i2c_reg_read(u8 addr, u8 reg) -{ - u8 buf; - -#ifdef CONFIG_8xx - /* MPC8xx needs this. Maybe one day we can get rid of it. */ - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -#endif - -#ifdef DEBUG - printf("%s: addr=0x%02x, reg=0x%02x\n", __func__, addr, reg); -#endif - - i2c_read(addr, reg, 1, &buf, 1); - - return buf; -} - -static inline void i2c_reg_write(u8 addr, u8 reg, u8 val) -{ -#ifdef CONFIG_8xx - /* MPC8xx needs this. Maybe one day we can get rid of it. */ - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); -#endif - -#ifdef DEBUG - printf("%s: addr=0x%02x, reg=0x%02x, val=0x%02x\n", - __func__, addr, reg, val); -#endif - - i2c_write(addr, reg, 1, &val, 1); -} - -/* - * Functions for setting the current I2C bus and its speed - */ - -/* - * i2c_set_bus_num: - * - * Change the active I2C bus. Subsequent read/write calls will - * go to this one. - * - * bus - bus index, zero based - * - * Returns: 0 on success, not 0 on failure - * - */ -int i2c_set_bus_num(unsigned int bus); - -/* - * i2c_get_bus_num: - * - * Returns index of currently active I2C bus. Zero-based. - */ - -unsigned int i2c_get_bus_num(void); - -/* - * i2c_set_bus_speed: - * - * Change the speed of the active I2C bus - * - * speed - bus speed in Hz - * - * Returns: 0 on success, not 0 on failure - * - */ -int i2c_set_bus_speed(unsigned int); - -/* - * i2c_get_bus_speed: - * - * Returns speed of currently active I2C bus in Hz - */ - -unsigned int i2c_get_bus_speed(void); - -/* NOTE: These two functions MUST be always_inline to avoid code growth! */ -static inline unsigned int I2C_GET_BUS(void) __attribute__((always_inline)); -static inline unsigned int I2C_GET_BUS(void) -{ - return I2C_MULTI_BUS ? i2c_get_bus_num() : 0; -} - -static inline void I2C_SET_BUS(unsigned int bus) __attribute__((always_inline)); -static inline void I2C_SET_BUS(unsigned int bus) -{ - if (I2C_MULTI_BUS) - i2c_set_bus_num(bus); -} - -/* - * Set an early register base for a given i2c peripheral. - * This is used to access a single i2c bus early on in the boot sequence. - * - * @param base: The base address of the i2c peripheral's register map - */ -void i2c_set_early_reg(unsigned int base); - -/** - * Find the I2C bus number by given a FDT I2C node. - * - * @param blob Device tree blbo - * @param node FDT I2C node to find - * @return the number of I2C bus (zero based), or -1 on error - */ -int i2c_get_bus_num_fdt(const void *blob, int node); - -/** - * Reset the I2C bus represented by the given a FDT I2C node. - * - * @param blob Device tree blbo - * @param node FDT I2C node to find - * @return 0 if port was reset, -1 if not found - */ -int i2c_reset_port_fdt(const void *blob, int node); - -#endif /* _I2C_H_ */ diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c index 17a3267a6e..2df0e4ef61 100644 --- a/src/mainboard/google/snow/bootblock.c +++ b/src/mainboard/google/snow/bootblock.c @@ -25,8 +25,6 @@ #include <cpu/samsung/exynos5250/periph.h> #include <cpu/samsung/exynos5250/pinmux.h> -#define I2C0_BASE 0x12c60000 - void bootblock_mainboard_init(void); void bootblock_mainboard_init(void) { diff --git a/src/mainboard/google/snow/romstage.c b/src/mainboard/google/snow/romstage.c index 94ca222b71..d34c379d32 100644 --- a/src/mainboard/google/snow/romstage.c +++ b/src/mainboard/google/snow/romstage.c @@ -25,6 +25,7 @@ #include <arch/cache.h> #include <arch/gpio.h> +#include <cpu/samsung/exynos5-common/i2c.h> #include <cpu/samsung/exynos5250/clk.h> #include <cpu/samsung/exynos5250/dmc.h> #include <cpu/samsung/exynos5250/gpio.h> @@ -36,10 +37,11 @@ #include <arch/stages.h> #include <drivers/maxim/max77686/max77686.h> -#include <device/i2c-old.h> +#include <device/i2c.h> #include "mainboard.h" +#define PMIC_BUS 0 #define MMC0_GPIO_PIN (58) #if 0 @@ -69,23 +71,23 @@ static int setup_pmic(void) * * Disable Coin BATT Charging */ - error = max77686_disable_backup_batt(); + error = max77686_disable_backup_batt(PMIC_BUS); - error |= max77686_volsetting(PMIC_BUCK2, CONFIG_VDD_ARM_MV, + error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK2, CONFIG_VDD_ARM_MV, REG_ENABLE, MAX77686_MV); - error |= max77686_volsetting(PMIC_BUCK3, CONFIG_VDD_INT_UV, + error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK3, CONFIG_VDD_INT_UV, REG_ENABLE, MAX77686_UV); - error |= max77686_volsetting(PMIC_BUCK1, CONFIG_VDD_MIF_MV, + error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK1, CONFIG_VDD_MIF_MV, REG_ENABLE, MAX77686_MV); - error |= max77686_volsetting(PMIC_BUCK4, CONFIG_VDD_G3D_MV, + error |= max77686_volsetting(PMIC_BUS, PMIC_BUCK4, CONFIG_VDD_G3D_MV, REG_ENABLE, MAX77686_MV); - error |= max77686_volsetting(PMIC_LDO2, CONFIG_VDD_LDO2_MV, + error |= max77686_volsetting(PMIC_BUS, PMIC_LDO2, CONFIG_VDD_LDO2_MV, REG_ENABLE, MAX77686_MV); - error |= max77686_volsetting(PMIC_LDO3, CONFIG_VDD_LDO3_MV, + error |= max77686_volsetting(PMIC_BUS, PMIC_LDO3, CONFIG_VDD_LDO3_MV, REG_ENABLE, MAX77686_MV); - error |= max77686_volsetting(PMIC_LDO5, CONFIG_VDD_LDO5_MV, + error |= max77686_volsetting(PMIC_BUS, PMIC_LDO5, CONFIG_VDD_LDO5_MV, REG_ENABLE, MAX77686_MV); - error |= max77686_volsetting(PMIC_LDO10, CONFIG_VDD_LDO10_MV, + error |= max77686_volsetting(PMIC_BUS, PMIC_LDO10, CONFIG_VDD_LDO10_MV, REG_ENABLE, MAX77686_MV); if (error) @@ -133,10 +135,10 @@ void main(void) console_init(); - i2c_set_early_reg(0x12c60000); - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + i2c_init(0, CONFIG_SYS_I2C_SPEED, 0x00); if (power_init()) power_shutdown(); + printk(BIOS_DEBUG, "%s: setting up pmic...\n", __func__); if (setup_pmic()) power_shutdown(); |