diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/Kconfig | 56 | ||||
-rw-r--r-- | drivers/i2c/Makefile | 1 | ||||
-rw-r--r-- | drivers/i2c/i2c-gpio.c | 346 | ||||
-rw-r--r-- | drivers/i2c/i2c-uclass.c | 6 | ||||
-rw-r--r-- | drivers/i2c/i2c-uniphier-f.c | 1 | ||||
-rw-r--r-- | drivers/i2c/i2c-uniphier.c | 1 | ||||
-rw-r--r-- | drivers/i2c/mvtwsi.c | 128 | ||||
-rw-r--r-- | drivers/i2c/mxc_i2c.c | 17 | ||||
-rw-r--r-- | drivers/i2c/s3c24x0_i2c.c | 2 | ||||
-rw-r--r-- | drivers/i2c/sandbox_i2c.c | 2 | ||||
-rw-r--r-- | drivers/i2c/tegra_i2c.c | 6 |
11 files changed, 516 insertions, 50 deletions
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 692810d057e..ba43019ab99 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -2,16 +2,13 @@ config DM_I2C bool "Enable Driver Model for I2C drivers" depends on DM help - Enable driver model for I2C. This SPI flash interface - (spi_flash_probe(), spi_flash_write(), etc.) is then - implemented by the SPI flash uclass. There is one standard - SPI flash driver which knows how to probe most chips - supported by U-Boot. The uclass interface is defined in - include/spi_flash.h, but is currently fully compatible - with the old interface to avoid confusion and duplication - during the transition parent. SPI and SPI flash must be - enabled together (it is not possible to use driver model - for one and not the other). + Enable driver model for I2C. The I2C uclass interface: probe, read, + write and speed, is implemented with the bus drivers operations, + which provide methods for bus setting and data transfer. Each chip + device (bus child) info is kept as parent platdata. The interface + is defined in include/i2c.h. When i2c bus driver supports the i2c + uclass, but the device drivers not, then DM_I2C_COMPAT config can + be used as compatibility layer. config DM_I2C_COMPAT bool "Enable I2C compatibility layer" @@ -22,6 +19,45 @@ config DM_I2C_COMPAT to convert all code for a board in a single commit. It should not be enabled for any board in an official release. +config DM_I2C_GPIO + bool "Enable Driver Model for software emulated I2C bus driver" + depends on DM_I2C && DM_GPIO + help + Enable the i2c bus driver emulation by using the GPIOs. The bus GPIO + configuration is given by the device tree. Kernel-style device tree + bindings are supported. + Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt + +config SYS_I2C_SANDBOX + bool "Sandbox I2C driver" + depends on SANDBOX && DM_I2C + help + Enable I2C support for sandbox. This is an emulation of a real I2C + bus. Devices can be attached to the bus using the device tree + which specifies the driver to use. As an example, see this device + tree fragment from sandbox.dts. It shows that the I2C bus has a + single EEPROM at address 0x2c (7-bit address) which is emulated by + the driver for "sandbox,i2c-eeprom", which is in + drivers/misc/i2c_eeprom_emul.c. + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + compatible = "sandbox,i2c"; + clock-frequency = <400000>; + eeprom@2c { + reg = <0x2c>; + compatible = "i2c-eeprom"; + emul { + compatible = "sandbox,i2c-eeprom"; + sandbox,filename = "i2c.bin"; + sandbox,size = <128>; + }; + }; + }; + + config SYS_I2C_UNIPHIER bool "UniPhier I2C driver" depends on ARCH_UNIPHIER && DM_I2C diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 26ea854ec8d..d9e912f7864 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -6,6 +6,7 @@ # obj-$(CONFIG_DM_I2C) += i2c-uclass.o obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o +obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o obj-$(CONFIG_I2C_MV) += mv_i2c.o diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c new file mode 100644 index 00000000000..ed899d47770 --- /dev/null +++ b/drivers/i2c/i2c-gpio.c @@ -0,0 +1,346 @@ +/* + * (C) Copyright 2015, Samsung Electronics + * Przemyslaw Marczak <p.marczak@samsung.com> + * + * This file is based on: drivers/i2c/soft-i2c.c, + * with added driver-model support and code cleanup. + */ +#include <common.h> +#include <errno.h> +#include <dm.h> +#include <i2c.h> +#include <asm/gpio.h> + +#define DEFAULT_UDELAY 5 +#define RETRIES 0 +#define I2C_ACK 0 +#define I2C_NOACK 1 + +DECLARE_GLOBAL_DATA_PTR; + +enum { + PIN_SDA = 0, + PIN_SCL, + PIN_COUNT, +}; + +struct i2c_gpio_bus { + /** + * udelay - delay [us] between GPIO toggle operations, + * which is 1/4 of I2C speed clock period. + */ + int udelay; + /* sda, scl */ + struct gpio_desc gpios[PIN_COUNT]; +}; + +static int i2c_gpio_sda_get(struct gpio_desc *sda) +{ + return dm_gpio_get_value(sda); +} + +static void i2c_gpio_sda_set(struct gpio_desc *sda, int bit) +{ + if (bit) { + dm_gpio_set_dir_flags(sda, GPIOD_IS_IN); + } else { + dm_gpio_set_dir_flags(sda, GPIOD_IS_OUT); + dm_gpio_set_value(sda, 0); + } +} + +static void i2c_gpio_scl_set(struct gpio_desc *scl, int bit) +{ + dm_gpio_set_dir_flags(scl, GPIOD_IS_OUT); + dm_gpio_set_value(scl, bit); +} + +static void i2c_gpio_write_bit(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, uchar bit) +{ + i2c_gpio_scl_set(scl, 0); + udelay(delay); + i2c_gpio_sda_set(sda, bit); + udelay(delay); + i2c_gpio_scl_set(scl, 1); + udelay(2 * delay); +} + +static int i2c_gpio_read_bit(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + int value; + + i2c_gpio_scl_set(scl, 1); + udelay(delay); + value = i2c_gpio_sda_get(sda); + udelay(delay); + i2c_gpio_scl_set(scl, 0); + udelay(2 * delay); + + return value; +} + +/* START: High -> Low on SDA while SCL is High */ +static void i2c_gpio_send_start(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + udelay(delay); + i2c_gpio_sda_set(sda, 1); + udelay(delay); + i2c_gpio_scl_set(scl, 1); + udelay(delay); + i2c_gpio_sda_set(sda, 0); + udelay(delay); +} + +/* STOP: Low -> High on SDA while SCL is High */ +static void i2c_gpio_send_stop(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + i2c_gpio_scl_set(scl, 0); + udelay(delay); + i2c_gpio_sda_set(sda, 0); + udelay(delay); + i2c_gpio_scl_set(scl, 1); + udelay(delay); + i2c_gpio_sda_set(sda, 1); + udelay(delay); +} + +/* ack should be I2C_ACK or I2C_NOACK */ +static void i2c_gpio_send_ack(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, int ack) +{ + i2c_gpio_write_bit(scl, sda, delay, ack); + i2c_gpio_scl_set(scl, 0); + udelay(delay); +} + +/** + * Send a reset sequence consisting of 9 clocks with the data signal high + * to clock any confused device back into an idle state. Also send a + * <stop> at the end of the sequence for belts & suspenders. + */ +static void i2c_gpio_send_reset(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + int j; + + for (j = 0; j < 9; j++) + i2c_gpio_write_bit(scl, sda, delay, 1); + + i2c_gpio_send_stop(scl, sda, delay); +} + +/* Set sda high with low clock, before reading slave data */ +static void i2c_gpio_sda_high(struct gpio_desc *scl, struct gpio_desc *sda, + int delay) +{ + i2c_gpio_scl_set(scl, 0); + udelay(delay); + i2c_gpio_sda_set(sda, 1); + udelay(delay); +} + +/* Send 8 bits and look for an acknowledgement */ +static int i2c_gpio_write_byte(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, uchar data) +{ + int j; + int nack; + + for (j = 0; j < 8; j++) { + i2c_gpio_write_bit(scl, sda, delay, data & 0x80); + data <<= 1; + } + + udelay(delay); + + /* Look for an <ACK>(negative logic) and return it */ + i2c_gpio_sda_high(scl, sda, delay); + nack = i2c_gpio_read_bit(scl, sda, delay); + + return nack; /* not a nack is an ack */ +} + +/** + * if ack == I2C_ACK, ACK the byte so can continue reading, else + * send I2C_NOACK to end the read. + */ +static uchar i2c_gpio_read_byte(struct gpio_desc *scl, struct gpio_desc *sda, + int delay, int ack) +{ + int data; + int j; + + i2c_gpio_sda_high(scl, sda, delay); + data = 0; + for (j = 0; j < 8; j++) { + data <<= 1; + data |= i2c_gpio_read_bit(scl, sda, delay); + } + i2c_gpio_send_ack(scl, sda, delay, ack); + + return data; +} + +/* send start and the slave chip address */ +int i2c_send_slave_addr(struct gpio_desc *scl, struct gpio_desc *sda, int delay, + uchar chip) +{ + i2c_gpio_send_start(scl, sda, delay); + + if (i2c_gpio_write_byte(scl, sda, delay, chip)) { + i2c_gpio_send_stop(scl, sda, delay); + return -EIO; + } + + return 0; +} + +static int i2c_gpio_write_data(struct i2c_gpio_bus *bus, uchar chip, + uchar *buffer, int len, + bool end_with_repeated_start) +{ + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + unsigned int delay = bus->udelay; + int failures = 0; + + debug("%s: chip %x buffer %p len %d\n", __func__, chip, buffer, len); + + if (i2c_send_slave_addr(scl, sda, delay, chip << 1)) { + debug("i2c_write, no chip responded %02X\n", chip); + return -EIO; + } + + while (len-- > 0) { + if (i2c_gpio_write_byte(scl, sda, delay, *buffer++)) + failures++; + } + + if (!end_with_repeated_start) { + i2c_gpio_send_stop(scl, sda, delay); + return failures; + } + + if (i2c_send_slave_addr(scl, sda, delay, (chip << 1) | 0x1)) { + debug("i2c_write, no chip responded %02X\n", chip); + return -EIO; + } + + return failures; +} + +static int i2c_gpio_read_data(struct i2c_gpio_bus *bus, uchar chip, + uchar *buffer, int len) +{ + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + unsigned int delay = bus->udelay; + + debug("%s: chip %x buffer: %p len %d\n", __func__, chip, buffer, len); + + while (len-- > 0) + *buffer++ = i2c_gpio_read_byte(scl, sda, delay, len == 0); + + i2c_gpio_send_stop(scl, sda, delay); + + return 0; +} + +static int i2c_gpio_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + int ret; + + for (; nmsgs > 0; nmsgs--, msg++) { + bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD); + + if (msg->flags & I2C_M_RD) { + ret = i2c_gpio_read_data(bus, msg->addr, msg->buf, + msg->len); + } else { + ret = i2c_gpio_write_data(bus, msg->addr, msg->buf, + msg->len, next_is_read); + } + + if (ret) + return -EREMOTEIO; + } + + return 0; +} + +static int i2c_gpio_probe(struct udevice *dev, uint chip, uint chip_flags) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + unsigned int delay = bus->udelay; + int ret; + + i2c_gpio_send_start(scl, sda, delay); + ret = i2c_gpio_write_byte(scl, sda, delay, (chip << 1) | 0); + i2c_gpio_send_stop(scl, sda, delay); + + debug("%s: bus: %d (%s) chip: %x flags: %x ret: %d\n", + __func__, dev->seq, dev->name, chip, chip_flags, ret); + + return ret; +} + +static int i2c_gpio_set_bus_speed(struct udevice *dev, unsigned int speed_hz) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + struct gpio_desc *scl = &bus->gpios[PIN_SCL]; + struct gpio_desc *sda = &bus->gpios[PIN_SDA]; + + bus->udelay = 1000000 / (speed_hz << 2); + + i2c_gpio_send_reset(scl, sda, bus->udelay); + + return 0; +} + +static int i2c_gpio_ofdata_to_platdata(struct udevice *dev) +{ + struct i2c_gpio_bus *bus = dev_get_priv(dev); + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + int ret; + + ret = gpio_request_list_by_name(dev, "gpios", bus->gpios, + ARRAY_SIZE(bus->gpios), 0); + if (ret < 0) + goto error; + + bus->udelay = fdtdec_get_int(blob, node, "i2c-gpio,delay-us", + DEFAULT_UDELAY); + + return 0; +error: + error("Can't get %s gpios! Error: %d", dev->name, ret); + return ret; +} + +static const struct dm_i2c_ops i2c_gpio_ops = { + .xfer = i2c_gpio_xfer, + .probe_chip = i2c_gpio_probe, + .set_bus_speed = i2c_gpio_set_bus_speed, +}; + +static const struct udevice_id i2c_gpio_ids[] = { + { .compatible = "i2c-gpio" }, + { } +}; + +U_BOOT_DRIVER(i2c_gpio) = { + .name = "i2c-gpio", + .id = UCLASS_I2C, + .of_match = i2c_gpio_ids, + .ofdata_to_platdata = i2c_gpio_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct i2c_gpio_bus), + .ops = &i2c_gpio_ops, +}; diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index b890806a44a..f2e95c0881a 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -330,7 +330,7 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags, int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) { struct dm_i2c_ops *ops = i2c_get_ops(bus); - struct dm_i2c_bus *i2c = bus->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); int ret; /* @@ -351,7 +351,7 @@ int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) int dm_i2c_get_bus_speed(struct udevice *bus) { struct dm_i2c_ops *ops = i2c_get_ops(bus); - struct dm_i2c_bus *i2c = bus->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); if (!ops->get_bus_speed) return i2c->speed_hz; @@ -432,7 +432,7 @@ int i2c_chip_ofdata_to_platdata(const void *blob, int node, static int i2c_post_probe(struct udevice *dev) { - struct dm_i2c_bus *i2c = dev->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev); i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "clock-frequency", 100000); diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c index fd28c173998..d29dd4565d7 100644 --- a/drivers/i2c/i2c-uniphier-f.c +++ b/drivers/i2c/i2c-uniphier-f.c @@ -14,6 +14,7 @@ #include <dm/root.h> #include <i2c.h> #include <fdtdec.h> +#include <mapmem.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c index 666272dd0d7..c4972ff5012 100644 --- a/drivers/i2c/i2c-uniphier.c +++ b/drivers/i2c/i2c-uniphier.c @@ -14,6 +14,7 @@ #include <dm/root.h> #include <i2c.h> #include <fdtdec.h> +#include <mapmem.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 6f6edd5e519..f20d1b22915 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -14,7 +14,7 @@ #include <asm/io.h> /* - * include a file that will provide CONFIG_I2C_MVTWSI_BASE + * include a file that will provide CONFIG_I2C_MVTWSI_BASE* * and possibly other settings */ @@ -91,11 +91,39 @@ struct mvtwsi_registers { #define MVTWSI_STATUS_IDLE 0xF8 /* - * The single instance of the controller we'll be dealing with + * MVTWSI controller base */ -static struct mvtwsi_registers *twsi = - (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE; +static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap) +{ + switch (adap->hwadapnr) { +#ifdef CONFIG_I2C_MVTWSI_BASE0 + case 0: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE0; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE1 + case 1: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE1; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE2 + case 2: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE2; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE3 + case 3: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE3; +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE4 + case 4: + return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4; +#endif + default: + printf("Missing mvtwsi controller %d base\n", adap->hwadapnr); + break; + } + + return NULL; +} /* * Returned statuses are 0 for success and nonzero otherwise. @@ -117,8 +145,9 @@ static struct mvtwsi_registers *twsi = * Wait for IFLG to raise, or return 'timeout'; then if status is as expected, * return 0 (ok) or return 'wrong status'. */ -static int twsi_wait(int expected_status) +static int twsi_wait(struct i2c_adapter *adap, int expected_status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); int control, status; int timeout = 1000; @@ -153,35 +182,40 @@ static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN; * Assert the START condition, either in a single I2C transaction * or inside back-to-back ones (repeated starts). */ -static int twsi_start(int expected_status) +static int twsi_start(struct i2c_adapter *adap, int expected_status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); + /* globally set TWSIEN in case it was not */ twsi_control_flags |= MVTWSI_CONTROL_TWSIEN; /* assert START */ writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control); /* wait for controller to process START */ - return twsi_wait(expected_status); + return twsi_wait(adap, expected_status); } /* * Send a byte (i2c address or data). */ -static int twsi_send(u8 byte, int expected_status) +static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); + /* put byte in data register for sending */ writel(byte, &twsi->data); /* clear any pending interrupt -- that'll cause sending */ writel(twsi_control_flags, &twsi->control); /* wait for controller to receive byte and check ACK */ - return twsi_wait(expected_status); + return twsi_wait(adap, expected_status); } /* * Receive a byte. * Global mvtwsi_control_flags variable says if we should ack or nak. */ -static int twsi_recv(u8 *byte) +static int twsi_recv(struct i2c_adapter *adap, u8 *byte) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); int expected_status, status; /* compute expected status based on ACK bit in global control flags */ @@ -192,7 +226,7 @@ static int twsi_recv(u8 *byte) /* acknowledge *previous state* and launch receive */ writel(twsi_control_flags, &twsi->control); /* wait for controller to receive byte and assert ACK or NAK */ - status = twsi_wait(expected_status); + status = twsi_wait(adap, expected_status); /* if we did receive expected byte then store it */ if (status == 0) *byte = readl(&twsi->data); @@ -204,8 +238,9 @@ static int twsi_recv(u8 *byte) * Assert the STOP condition. * This is also used to force the bus back in idle (SDA=SCL=1). */ -static int twsi_stop(int status) +static int twsi_stop(struct i2c_adapter *adap, int status) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); int control, stop_status; int timeout = 1000; @@ -244,6 +279,7 @@ static unsigned int twsi_calc_freq(const int n, const int m) */ static void twsi_reset(struct i2c_adapter *adap) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); /* ensure controller will be enabled by any twsi*() function */ twsi_control_flags = MVTWSI_CONTROL_TWSIEN; /* reset controller */ @@ -259,6 +295,7 @@ static void twsi_reset(struct i2c_adapter *adap) static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap, unsigned int requested_speed) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); unsigned int tmp_speed, highest_speed, n, m; unsigned int baud = 0x44; /* baudrate at controller reset */ @@ -281,6 +318,8 @@ static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap, static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) { + struct mvtwsi_registers *twsi = twsi_get_base(adap); + /* reset controller */ twsi_reset(adap); /* set speed */ @@ -289,7 +328,7 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) writel(slaveadd, &twsi->slave_address); writel(0, &twsi->xtnd_slave_addr); /* assert STOP but don't care for the result */ - (void) twsi_stop(0); + (void) twsi_stop(adap, 0); } /* @@ -297,7 +336,8 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) * Common to i2c_probe, i2c_read and i2c_write. * Expected address status will derive from direction bit (bit 0) in addr. */ -static int i2c_begin(int expected_start_status, u8 addr) +static int i2c_begin(struct i2c_adapter *adap, int expected_start_status, + u8 addr) { int status, expected_addr_status; @@ -307,10 +347,10 @@ static int i2c_begin(int expected_start_status, u8 addr) else /* writing */ expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK; /* assert START */ - status = twsi_start(expected_start_status); + status = twsi_start(adap, expected_start_status); /* send out the address if the start went well */ if (status == 0) - status = twsi_send(addr, expected_addr_status); + status = twsi_send(adap, addr, expected_addr_status); /* return ok or status of first failure to caller */ return status; } @@ -325,12 +365,12 @@ static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip) int status; /* begin i2c read */ - status = i2c_begin(MVTWSI_STATUS_START, (chip << 1) | 1); + status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1); /* dummy read was accepted: receive byte but NAK it. */ if (status == 0) - status = twsi_recv(&dummy_byte); + status = twsi_recv(adap, &dummy_byte); /* Stop transaction */ - twsi_stop(0); + twsi_stop(adap, 0); /* return 0 or status of first failure */ return status; } @@ -351,15 +391,15 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, int status; /* begin i2c write to send the address bytes */ - status = i2c_begin(MVTWSI_STATUS_START, (chip << 1)); + status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--) - status = twsi_send(addr >> (8*alen), + status = twsi_send(adap, addr >> (8*alen), MVTWSI_STATUS_DATA_W_ACK); /* begin i2c read to receive eeprom data bytes */ if (status == 0) - status = i2c_begin( - MVTWSI_STATUS_REPEATED_START, (chip << 1) | 1); + status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START, + (chip << 1) | 1); /* prepare ACK if at least one byte must be received */ if (length > 0) twsi_control_flags |= MVTWSI_CONTROL_ACK; @@ -369,10 +409,10 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, if (length == 0) twsi_control_flags &= ~MVTWSI_CONTROL_ACK; /* read current byte */ - status = twsi_recv(data++); + status = twsi_recv(adap, data++); } /* Stop transaction */ - status = twsi_stop(status); + status = twsi_stop(adap, status); /* return 0 or status of first failure */ return status; } @@ -387,21 +427,51 @@ static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, int status; /* begin i2c write to send the eeprom adress bytes then data bytes */ - status = i2c_begin(MVTWSI_STATUS_START, (chip << 1)); + status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--) - status = twsi_send(addr >> (8*alen), + status = twsi_send(adap, addr >> (8*alen), MVTWSI_STATUS_DATA_W_ACK); /* send data bytes */ while ((status == 0) && (length-- > 0)) - status = twsi_send(*(data++), MVTWSI_STATUS_DATA_W_ACK); + status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK); /* Stop transaction */ - status = twsi_stop(status); + status = twsi_stop(adap, status); /* return 0 or status of first failure */ return status; } +#ifdef CONFIG_I2C_MVTWSI_BASE0 U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe, twsi_i2c_read, twsi_i2c_write, twsi_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0) +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE1 +U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1) + +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE2 +U_BOOT_I2C_ADAP_COMPLETE(twsi2, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 2) + +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE3 +U_BOOT_I2C_ADAP_COMPLETE(twsi3, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 3) + +#endif +#ifdef CONFIG_I2C_MVTWSI_BASE4 +U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe, + twsi_i2c_read, twsi_i2c_write, + twsi_i2c_set_bus_speed, + CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4) + +#endif diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index fc5ee35a1ad..42782cb1ace 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -114,6 +114,9 @@ static u16 i2c_clk_div[50][2] = { #ifndef CONFIG_SYS_MXC_I2C3_SPEED #define CONFIG_SYS_MXC_I2C3_SPEED 100000 #endif +#ifndef CONFIG_SYS_MXC_I2C4_SPEED +#define CONFIG_SYS_MXC_I2C4_SPEED 100000 +#endif #ifndef CONFIG_SYS_MXC_I2C1_SLAVE #define CONFIG_SYS_MXC_I2C1_SLAVE 0 @@ -124,6 +127,9 @@ static u16 i2c_clk_div[50][2] = { #ifndef CONFIG_SYS_MXC_I2C3_SLAVE #define CONFIG_SYS_MXC_I2C3_SLAVE 0 #endif +#ifndef CONFIG_SYS_MXC_I2C4_SLAVE +#define CONFIG_SYS_MXC_I2C4_SLAVE 0 +#endif /* @@ -543,12 +549,17 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe, mxc_i2c_set_bus_speed, CONFIG_SYS_MXC_I2C2_SPEED, CONFIG_SYS_MXC_I2C2_SLAVE, 1) -#if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\ - defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\ - defined(CONFIG_MX6) || defined(CONFIG_LS102XA) +#ifdef CONFIG_SYS_I2C_MXC_I2C3 U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe, mxc_i2c_read, mxc_i2c_write, mxc_i2c_set_bus_speed, CONFIG_SYS_MXC_I2C3_SPEED, CONFIG_SYS_MXC_I2C3_SLAVE, 2) #endif +#ifdef CONFIG_SYS_I2C_MXC_I2C4 +U_BOOT_I2C_ADAP_COMPLETE(mxc3, mxc_i2c_init, mxc_i2c_probe, + mxc_i2c_read, mxc_i2c_write, + mxc_i2c_set_bus_speed, + CONFIG_SYS_MXC_I2C4_SPEED, + CONFIG_SYS_MXC_I2C4_SLAVE, 3) +#endif diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index b4ee33f7dac..27ff5874407 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -1348,7 +1348,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev) struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev); int node, flags; - i2c_bus->is_highspeed = dev->of_id->data; + i2c_bus->is_highspeed = dev_get_driver_data(dev); node = dev->of_offset; if (i2c_bus->is_highspeed) { diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c index a943aa63821..d6adc0f721b 100644 --- a/drivers/i2c/sandbox_i2c.c +++ b/drivers/i2c/sandbox_i2c.c @@ -50,7 +50,7 @@ static int get_emul(struct udevice *dev, struct udevice **devp, static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) { - struct dm_i2c_bus *i2c = bus->uclass_priv; + struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus); struct dm_i2c_ops *ops; struct udevice *emul, *dev; bool is_read; diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c index f4142870b30..fc956469948 100644 --- a/drivers/i2c/tegra_i2c.c +++ b/drivers/i2c/tegra_i2c.c @@ -338,7 +338,7 @@ static int tegra_i2c_probe(struct udevice *dev) bool is_dvc; i2c_bus->id = dev->seq; - i2c_bus->type = dev_get_of_data(dev); + i2c_bus->type = dev_get_driver_data(dev); i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg"); /* @@ -360,7 +360,7 @@ static int tegra_i2c_probe(struct udevice *dev) if (i2c_bus->periph_id == -1) return -EINVAL; - is_dvc = dev_get_of_data(dev) == TYPE_DVC; + is_dvc = dev_get_driver_data(dev) == TYPE_DVC; if (is_dvc) { i2c_bus->control = &((struct dvc_ctlr *)i2c_bus->regs)->control; @@ -469,7 +469,7 @@ int tegra_i2c_get_dvc_bus(struct udevice **busp) for (uclass_first_device(UCLASS_I2C, &bus); bus; uclass_next_device(&bus)) { - if (dev_get_of_data(bus) == TYPE_DVC) { + if (dev_get_driver_data(bus) == TYPE_DVC) { *busp = bus; return 0; } |