From 73845350b6281a7afeeb279475e6eb613d7a89f9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 12 Jan 2015 18:02:08 -0700 Subject: dm: i2c: Add a compatbility layer For boards which use multiple I2C devices, or for SOCs which support multiple boards, we might want to convert these to driver model at different times. At present this is difficult because we need to either use CONFIG_DM_I2C for a board or not. Add a compatibility layer which implements the old API, thus allowing a board to move to driver model for I2C without requiring that everything it uses is moved in the same commit. Signed-off-by: Simon Glass --- drivers/i2c/i2c-uclass-compat.c | 98 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 drivers/i2c/i2c-uclass-compat.c (limited to 'drivers/i2c/i2c-uclass-compat.c') diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c new file mode 100644 index 0000000..c29fc89 --- /dev/null +++ b/drivers/i2c/i2c-uclass-compat.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static int cur_busnum; + +static int i2c_compat_get_device(uint chip_addr, int alen, + struct udevice **devp) +{ + struct dm_i2c_chip *chip; + int ret; + + ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp); + if (ret) + return ret; + chip = dev_get_parentdata(*devp); + if (chip->offset_len != alen) { + printf("Requested alen %d does not match chip offset_len %d\n", + alen, chip->offset_len); + return -EADDRNOTAVAIL; + } + + return 0; +} + +int i2c_probe(uint8_t chip_addr) +{ + struct udevice *bus, *dev; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, cur_busnum, &bus); + if (ret) { + debug("Cannot find I2C bus %d: err=%d\n", cur_busnum, ret); + return ret; + } + + if (!bus) + return -ENOENT; + + return dm_i2c_probe(bus, chip_addr, 0, &dev); +} + +int i2c_read(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer, + int len) +{ + struct udevice *dev; + int ret; + + ret = i2c_compat_get_device(chip_addr, alen, &dev); + if (ret) + return ret; + + return dm_i2c_read(dev, addr, buffer, len); +} + +int i2c_write(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer, + int len) +{ + struct udevice *dev; + int ret; + + ret = i2c_compat_get_device(chip_addr, alen, &dev); + if (ret) + return ret; + + return dm_i2c_write(dev, addr, buffer, len); +} + +int i2c_get_bus_num_fdt(int node) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_of_offset(UCLASS_I2C, node, &bus); + if (ret) + return ret; + + return bus->seq; +} + +unsigned int i2c_get_bus_num(void) +{ + return cur_busnum; +} + +int i2c_set_bus_num(unsigned int bus) +{ + cur_busnum = bus; + + return 0; +} -- cgit v1.1 From e6f66ec0e757b49d39885303a94784a342803dd2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Jan 2015 08:27:13 -0700 Subject: dm: i2c: Move slave details to child platdata At present we go through various contortions to store the I2C's chip address in its private data. This only exists when the chip is active so must be set up when it is probed. Until the device is probed we don't actually record what address it will appear on. However, now that we can support per-child platform data, we can use that instead. This allows us to set up the address when the child is bound, and avoid the messy contortions. Unfortunately this is a fairly large change and it seems to be difficult to break it down further. Signed-off-by: Simon Glass Reviewed-by: Masahiro Yamada --- drivers/i2c/i2c-uclass-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/i2c/i2c-uclass-compat.c') diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index c29fc89..11239da 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -20,7 +20,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen, ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp); if (ret) return ret; - chip = dev_get_parentdata(*devp); + chip = dev_get_parent_platdata(*devp); if (chip->offset_len != alen) { printf("Requested alen %d does not match chip offset_len %d\n", alen, chip->offset_len); -- cgit v1.1 From 18a7f6aa2dcac7e78436cba148b25779f25f5c16 Mon Sep 17 00:00:00 2001 From: Przemyslaw Marczak Date: Tue, 27 Jan 2015 13:36:28 +0100 Subject: dm: i2c-uclass-compat: fix missed argument This patch fixes build error for CONFIG_DM_I2C_COMPAT. In i2c_get_chip_for_busnum() call, one of argument was missed, which was offset_len. Now it is set to 'alen' as previous. Signed-off-by: Przemyslaw Marczak Acked-by: Simon Glass --- drivers/i2c/i2c-uclass-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/i2c/i2c-uclass-compat.c') diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index 11239da..841ce05 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -17,7 +17,7 @@ static int i2c_compat_get_device(uint chip_addr, int alen, struct dm_i2c_chip *chip; int ret; - ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, devp); + ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, alen, devp); if (ret) return ret; chip = dev_get_parent_platdata(*devp); -- cgit v1.1 From d744d5613639088246b27edb9ce91ccbd663e5a5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 26 Jan 2015 20:29:39 -0700 Subject: dm: i2c: Add two more I2C init functions to the compatibility layer These functions are useful in case the board calls them. Also fix a missing parameter caused by applying the wrong patch (actually I failed to send v2 and applied v1 by mistake). Signed-off-by: Simon Glass --- drivers/i2c/i2c-uclass-compat.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/i2c/i2c-uclass-compat.c') diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c index 841ce05..223f238 100644 --- a/drivers/i2c/i2c-uclass-compat.c +++ b/drivers/i2c/i2c-uclass-compat.c @@ -22,8 +22,8 @@ static int i2c_compat_get_device(uint chip_addr, int alen, return ret; chip = dev_get_parent_platdata(*devp); if (chip->offset_len != alen) { - printf("Requested alen %d does not match chip offset_len %d\n", - alen, chip->offset_len); + printf("I2C chip %x: requested alen %d does not match chip offset_len %d\n", + chip_addr, alen, chip->offset_len); return -EADDRNOTAVAIL; } @@ -96,3 +96,13 @@ int i2c_set_bus_num(unsigned int bus) return 0; } + +void i2c_init(int speed, int slaveaddr) +{ + /* Nothing to do here - the init happens through driver model */ +} + +void board_i2c_init(const void *blob) +{ + /* Nothing to do here - the init happens through driver model */ +} -- cgit v1.1