|
|
|
@ -116,77 +116,13 @@ |
|
|
|
|
|
|
|
|
|
#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* To support VCMA9 boards and other who dont define max_i2c_num */ |
|
|
|
|
#ifndef CONFIG_MAX_I2C_NUM |
|
|
|
|
#define CONFIG_MAX_I2C_NUM 1 |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* For SPL boot some boards need i2c before SDRAM is initialised so force |
|
|
|
|
* variables to live in SRAM |
|
|
|
|
*/ |
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] |
|
|
|
|
__attribute__((section(".data"))); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
enum exynos_i2c_type { |
|
|
|
|
EXYNOS_I2C_STD, |
|
|
|
|
EXYNOS_I2C_HS, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
/**
|
|
|
|
|
* Get a pointer to the given bus index |
|
|
|
|
* |
|
|
|
|
* @bus_idx: Bus index to look up |
|
|
|
|
* @return pointer to bus, or NULL if invalid or not available |
|
|
|
|
*/ |
|
|
|
|
static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) |
|
|
|
|
{ |
|
|
|
|
if (bus_idx < ARRAY_SIZE(i2c_bus)) { |
|
|
|
|
struct s3c24x0_i2c_bus *bus; |
|
|
|
|
|
|
|
|
|
bus = &i2c_bus[bus_idx]; |
|
|
|
|
if (bus->active) |
|
|
|
|
return bus; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug("Undefined bus: %d\n", bus_idx); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) |
|
|
|
|
static int GetI2CSDA(void) |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) |
|
|
|
|
return (readl(&gpio->gpedat) & 0x8000) >> 15; |
|
|
|
|
#endif |
|
|
|
|
#ifdef CONFIG_S3C2400 |
|
|
|
|
return (readl(&gpio->pgdat) & 0x0020) >> 5; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void SetI2CSCL(int x) |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) |
|
|
|
|
writel((readl(&gpio->gpedat) & ~0x4000) | |
|
|
|
|
(x & 1) << 14, &gpio->gpedat); |
|
|
|
|
#endif |
|
|
|
|
#ifdef CONFIG_S3C2400 |
|
|
|
|
writel((readl(&gpio->pgdat) & ~0x0040) | (x & 1) << 6, &gpio->pgdat); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Wait til the byte transfer is completed. |
|
|
|
|
* |
|
|
|
@ -263,25 +199,6 @@ static void read_write_byte(struct s3c24x0_i2c *i2c) |
|
|
|
|
clrbits_le32(&i2c->iiccon, I2CCON_IRPND); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
static struct s3c24x0_i2c *get_base_i2c(int bus) |
|
|
|
|
{ |
|
|
|
|
#ifdef CONFIG_EXYNOS4 |
|
|
|
|
struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() |
|
|
|
|
+ (EXYNOS4_I2C_SPACING |
|
|
|
|
* bus)); |
|
|
|
|
return i2c; |
|
|
|
|
#elif defined CONFIG_EXYNOS5 |
|
|
|
|
struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c() |
|
|
|
|
+ (EXYNOS5_I2C_SPACING |
|
|
|
|
* bus)); |
|
|
|
|
return i2c; |
|
|
|
|
#else |
|
|
|
|
return s3c24x0_get_base_i2c(); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd) |
|
|
|
|
{ |
|
|
|
|
ulong freq, pres = 16, div; |
|
|
|
@ -412,88 +329,6 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus) |
|
|
|
|
hsi2c_ch_init(i2c_bus); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_i2c *i2c; |
|
|
|
|
struct s3c24x0_i2c_bus *bus; |
|
|
|
|
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) |
|
|
|
|
struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio(); |
|
|
|
|
#endif |
|
|
|
|
ulong start_time = get_timer(0); |
|
|
|
|
|
|
|
|
|
i2c = get_base_i2c(adap->hwadapnr); |
|
|
|
|
bus = &i2c_bus[adap->hwadapnr]; |
|
|
|
|
if (!bus) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* In case the previous transfer is still going, wait to give it a |
|
|
|
|
* chance to finish. |
|
|
|
|
*/ |
|
|
|
|
while (readl(&i2c->iicstat) & I2CSTAT_BSY) { |
|
|
|
|
if (get_timer(start_time) > I2C_TIMEOUT_MS) { |
|
|
|
|
printf("%s: I2C bus busy for %p\n", __func__, |
|
|
|
|
&i2c->iicstat); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) { |
|
|
|
|
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) |
|
|
|
|
ulong old_gpecon = readl(&gpio->gpecon); |
|
|
|
|
#endif |
|
|
|
|
#ifdef CONFIG_S3C2400 |
|
|
|
|
ulong old_gpecon = readl(&gpio->pgcon); |
|
|
|
|
#endif |
|
|
|
|
/* bus still busy probably by (most) previously interrupted
|
|
|
|
|
transfer */ |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) |
|
|
|
|
/* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */ |
|
|
|
|
writel((readl(&gpio->gpecon) & ~0xF0000000) | 0x10000000, |
|
|
|
|
&gpio->gpecon); |
|
|
|
|
#endif |
|
|
|
|
#ifdef CONFIG_S3C2400 |
|
|
|
|
/* set I2CSDA and I2CSCL (PG5, PG6) to GPIO */ |
|
|
|
|
writel((readl(&gpio->pgcon) & ~0x00003c00) | 0x00001000, |
|
|
|
|
&gpio->pgcon); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* toggle I2CSCL until bus idle */ |
|
|
|
|
SetI2CSCL(0); |
|
|
|
|
udelay(1000); |
|
|
|
|
i = 10; |
|
|
|
|
while ((i > 0) && (GetI2CSDA() != 1)) { |
|
|
|
|
SetI2CSCL(1); |
|
|
|
|
udelay(1000); |
|
|
|
|
SetI2CSCL(0); |
|
|
|
|
udelay(1000); |
|
|
|
|
i--; |
|
|
|
|
} |
|
|
|
|
SetI2CSCL(1); |
|
|
|
|
udelay(1000); |
|
|
|
|
|
|
|
|
|
/* restore pin functions */ |
|
|
|
|
#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) |
|
|
|
|
writel(old_gpecon, &gpio->gpecon); |
|
|
|
|
#endif |
|
|
|
|
#ifdef CONFIG_S3C2400 |
|
|
|
|
writel(old_gpecon, &gpio->pgcon); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
#endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */ |
|
|
|
|
|
|
|
|
|
i2c_ch_init(i2c, speed, slaveadd); |
|
|
|
|
|
|
|
|
|
bus->active = true; |
|
|
|
|
bus->regs = i2c; |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_SYS_I2C */ |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Poll the appropriate bit of the fifo status register until the interface is |
|
|
|
|
* ready to process the next byte or timeout expires. |
|
|
|
@ -715,22 +550,10 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c, |
|
|
|
|
return rv; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, |
|
|
|
|
unsigned int speed) |
|
|
|
|
#else |
|
|
|
|
static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_i2c_bus *i2c_bus; |
|
|
|
|
struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
i2c_bus = get_bus(adap->hwadapnr); |
|
|
|
|
if (!i2c_bus) |
|
|
|
|
return -EFAULT; |
|
|
|
|
#else |
|
|
|
|
i2c_bus = dev_get_priv(dev); |
|
|
|
|
#endif |
|
|
|
|
i2c_bus->clock_frequency = speed; |
|
|
|
|
|
|
|
|
|
if (i2c_bus->is_highspeed) { |
|
|
|
@ -857,23 +680,12 @@ bailout: |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip) |
|
|
|
|
#else |
|
|
|
|
static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_i2c_bus *i2c_bus; |
|
|
|
|
struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); |
|
|
|
|
uchar buf[1]; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
i2c_bus = get_bus(adap->hwadapnr); |
|
|
|
|
if (!i2c_bus) |
|
|
|
|
return -EFAULT; |
|
|
|
|
#else |
|
|
|
|
i2c_bus = dev_get_priv(dev); |
|
|
|
|
#endif |
|
|
|
|
buf[0] = 0; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -892,398 +704,6 @@ static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags) |
|
|
|
|
return ret != I2C_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_I2C |
|
|
|
|
static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, |
|
|
|
|
int alen, uchar *buffer, int len) |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_i2c_bus *i2c_bus; |
|
|
|
|
uchar xaddr[4]; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
i2c_bus = get_bus(adap->hwadapnr); |
|
|
|
|
if (!i2c_bus) |
|
|
|
|
return -EFAULT; |
|
|
|
|
|
|
|
|
|
if (alen > 4) { |
|
|
|
|
debug("I2C read: addr len %d not supported\n", alen); |
|
|
|
|
return -EADDRNOTAVAIL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (alen > 0) { |
|
|
|
|
xaddr[0] = (addr >> 24) & 0xFF; |
|
|
|
|
xaddr[1] = (addr >> 16) & 0xFF; |
|
|
|
|
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 |
|
|
|
|
if (i2c_bus->is_highspeed) |
|
|
|
|
ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen], |
|
|
|
|
alen, buffer, len); |
|
|
|
|
else |
|
|
|
|
ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1, |
|
|
|
|
&xaddr[4 - alen], alen, buffer, len); |
|
|
|
|
|
|
|
|
|
if (ret) { |
|
|
|
|
if (i2c_bus->is_highspeed) |
|
|
|
|
exynos5_i2c_reset(i2c_bus); |
|
|
|
|
debug("I2c read failed %d\n", ret); |
|
|
|
|
return -EIO; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, |
|
|
|
|
int alen, uchar *buffer, int len) |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_i2c_bus *i2c_bus; |
|
|
|
|
uchar xaddr[4]; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
i2c_bus = get_bus(adap->hwadapnr); |
|
|
|
|
if (!i2c_bus) |
|
|
|
|
return -EFAULT; |
|
|
|
|
|
|
|
|
|
if (alen > 4) { |
|
|
|
|
debug("I2C write: addr len %d not supported\n", alen); |
|
|
|
|
return -EINVAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (alen > 0) { |
|
|
|
|
xaddr[0] = (addr >> 24) & 0xFF; |
|
|
|
|
xaddr[1] = (addr >> 16) & 0xFF; |
|
|
|
|
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 |
|
|
|
|
if (i2c_bus->is_highspeed) |
|
|
|
|
ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen], |
|
|
|
|
alen, buffer, len, true); |
|
|
|
|
else |
|
|
|
|
ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, chip << 1, |
|
|
|
|
&xaddr[4 - alen], alen, buffer, len); |
|
|
|
|
|
|
|
|
|
if (ret != 0) { |
|
|
|
|
if (i2c_bus->is_highspeed) |
|
|
|
|
exynos5_i2c_reset(i2c_bus); |
|
|
|
|
return 1; |
|
|
|
|
} else { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if CONFIG_IS_ENABLED(OF_CONTROL) |
|
|
|
|
static void process_nodes(const void *blob, int node_list[], int count, |
|
|
|
|
int is_highspeed) |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_i2c_bus *bus; |
|
|
|
|
int i, flags; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) { |
|
|
|
|
int node = node_list[i]; |
|
|
|
|
|
|
|
|
|
if (node <= 0) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
bus = &i2c_bus[i]; |
|
|
|
|
bus->active = true; |
|
|
|
|
bus->is_highspeed = is_highspeed; |
|
|
|
|
|
|
|
|
|
if (is_highspeed) { |
|
|
|
|
flags = PINMUX_FLAG_HS_MODE; |
|
|
|
|
bus->hsregs = (struct exynos5_hsi2c *) |
|
|
|
|
fdtdec_get_addr(blob, node, "reg"); |
|
|
|
|
} else { |
|
|
|
|
flags = 0; |
|
|
|
|
bus->regs = (struct s3c24x0_i2c *) |
|
|
|
|
fdtdec_get_addr(blob, node, "reg"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bus->id = pinmux_decode_periph_id(blob, node); |
|
|
|
|
bus->clock_frequency = fdtdec_get_int(blob, node, |
|
|
|
|
"clock-frequency", |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED); |
|
|
|
|
bus->node = node; |
|
|
|
|
bus->bus_num = i; |
|
|
|
|
exynos_pinmux_config(bus->id, flags); |
|
|
|
|
|
|
|
|
|
/* Mark position as used */ |
|
|
|
|
node_list[i] = -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void board_i2c_init(const void *blob) |
|
|
|
|
{ |
|
|
|
|
int node_list[CONFIG_MAX_I2C_NUM]; |
|
|
|
|
int count; |
|
|
|
|
|
|
|
|
|
/* First get the normal i2c ports */ |
|
|
|
|
count = fdtdec_find_aliases_for_id(blob, "i2c", |
|
|
|
|
COMPAT_SAMSUNG_S3C2440_I2C, node_list, |
|
|
|
|
CONFIG_MAX_I2C_NUM); |
|
|
|
|
process_nodes(blob, node_list, count, 0); |
|
|
|
|
|
|
|
|
|
/* Now look for high speed i2c ports */ |
|
|
|
|
count = fdtdec_find_aliases_for_id(blob, "i2c", |
|
|
|
|
COMPAT_SAMSUNG_EXYNOS5_I2C, node_list, |
|
|
|
|
CONFIG_MAX_I2C_NUM); |
|
|
|
|
process_nodes(blob, node_list, count, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int i2c_get_bus_num_fdt(int node) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(i2c_bus); i++) { |
|
|
|
|
if (node == i2c_bus[i].node) |
|
|
|
|
return i; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug("%s: Can't find any matched I2C bus\n", __func__); |
|
|
|
|
return -EINVAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int i2c_reset_port_fdt(const void *blob, int node) |
|
|
|
|
{ |
|
|
|
|
struct s3c24x0_i2c_bus *i2c_bus; |
|
|
|
|
int bus; |
|
|
|
|
|
|
|
|
|
bus = i2c_get_bus_num_fdt(node); |
|
|
|
|
if (bus < 0) { |
|
|
|
|
debug("could not get bus for node %d\n", node); |
|
|
|
|
return bus; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
i2c_bus = get_bus(bus); |
|
|
|
|
if (!i2c_bus) { |
|
|
|
|
debug("get_bus() failed for node %d\n", node); |
|
|
|
|
return -EFAULT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (i2c_bus->is_highspeed) { |
|
|
|
|
if (hsi2c_get_clk_details(i2c_bus)) |
|
|
|
|
return -EINVAL; |
|
|
|
|
hsi2c_ch_init(i2c_bus); |
|
|
|
|
} else { |
|
|
|
|
i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_EXYNOS5 |
|
|
|
|
static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) |
|
|
|
|
{ |
|
|
|
|
/* This will override the speed selected in the fdt for that port */ |
|
|
|
|
debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); |
|
|
|
|
if (i2c_set_bus_speed(speed)) |
|
|
|
|
error("i2c_init: failed to init bus for speed = %d", speed); |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_EXYNOS5 */ |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Register s3c24x0 i2c adapters |
|
|
|
|
*/ |
|
|
|
|
#if defined(CONFIG_EXYNOS5420) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c04, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c05, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c06, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c07, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c08, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c09, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c10, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) |
|
|
|
|
#elif defined(CONFIG_EXYNOS5250) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c00, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c01, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c02, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c09, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(s3c10, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) |
|
|
|
|
#elif defined(CONFIG_EXYNOS4) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c03, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) |
|
|
|
|
#else |
|
|
|
|
U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, |
|
|
|
|
s3c24x0_i2c_read, s3c24x0_i2c_write, |
|
|
|
|
s3c24x0_i2c_set_bus_speed, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SPEED, |
|
|
|
|
CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) |
|
|
|
|
#endif |
|
|
|
|
#endif /* CONFIG_SYS_I2C */ |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_DM_I2C |
|
|
|
|
static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, |
|
|
|
|
int nmsgs) |
|
|
|
|
{ |
|
|
|
@ -1460,4 +880,3 @@ U_BOOT_DRIVER(hs_i2c) = { |
|
|
|
|
.priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus), |
|
|
|
|
.ops = &exynos_hs_i2c_ops, |
|
|
|
|
}; |
|
|
|
|
#endif /* CONFIG_DM_I2C */ |
|
|
|
|