summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/samsung/exynos5-common/exynos-fb.c2
-rw-r--r--src/cpu/samsung/exynos5-common/i2c.c354
-rw-r--r--src/cpu/samsung/exynos5-common/i2c.h8
-rw-r--r--src/drivers/maxim/max77686/max77686.c53
-rw-r--r--src/drivers/maxim/max77686/max77686.h13
-rw-r--r--src/include/device/i2c-old.h281
-rw-r--r--src/mainboard/google/snow/bootblock.c2
-rw-r--r--src/mainboard/google/snow/romstage.c26
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();