Re: [U-Boot] [RFC PATCH 04/12] dm: i2c: Implement driver model support in the i2c command
Hello Simon, Am 13.10.2014 07:39, schrieb Simon Glass: The concept of a 'current bus' is now implemented in the command line rather than in the uclass. Also the address length does not need to be specified with each command - really we should consider dropping this from most commands but it works OK for now. Signed-off-by: Simon Glass s...@chromium.org --- common/cmd_i2c.c | 312 +++ 1 file changed, 267 insertions(+), 45 deletions(-) diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index c266b88..6766856 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -69,8 +69,10 @@ #include bootretry.h #include cli.h #include command.h +#include dm.h #include edid.h #include environment.h +#include errno.h #include i2c.h #include malloc.h #include asm/byteorder.h @@ -117,6 +119,60 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; #define DISP_LINE_LEN 16 +/* + * Default for driver model is to use the chip's existing address length. + * For legacy code, this is not stored, so we need to use a suitable + * default. + */ +#ifdef CONFIG_DM_I2C +#define DEFAULT_ADDR_LEN (-1) +#else +#define DEFAULT_ADDR_LEN 1 +#endif + +#ifdef CONFIG_DM_I2C +static struct udevice *i2c_cur_bus; + +static int i2c_set_bus_num(unsigned int busnum) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, bus); + if (ret) { + debug(%s: No bus %d\n, __func__, busnum); + return ret; + } + i2c_cur_bus = bus; + + return 0; +} + +static int i2c_get_cur_bus(struct udevice **busp) +{ + if (!i2c_cur_bus) { + puts(No I2C bus selected\n); + return -ENODEV; + } + *busp = i2c_cur_bus; + + return 0; +} + +static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp) +{ + struct udevice *bus; + int ret; + + ret = i2c_get_cur_bus(bus); + if (ret) + return ret; + + return i2c_get_chip(bus, chip_addr, devp); +} + +#endif + /** * i2c_init_board() - Board-specific I2C bus init * @@ -143,7 +199,7 @@ void i2c_init_board(void) * * Returns I2C bus speed in Hz. */ -#if !defined(CONFIG_SYS_I2C) +#if !defined(CONFIG_SYS_I2C) !defined(CONFIG_DM_I2C) /* * TODO: Implement architecture-specific get/set functions * Should go away, if we switched completely to new multibus support @@ -182,12 +238,12 @@ int i2c_set_bus_speed(unsigned int speed) * * Returns the address length. */ -static uint get_alen(char *arg) +static uint get_alen(char *arg, int default_len) { int j; int alen; - alen = 1; + alen = default_len; for (j = 0; j 8; j++) { if (arg[j] == '.') { alen = arg[j+1] - '0'; @@ -229,6 +285,10 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv u_char chip; uintdevaddr, alen, length; u_char *memaddr; + int ret; +#ifdef CONFIG_DM_I2C + struct udevice *dev; +#endif if (argc != 5) return CMD_RET_USAGE; @@ -243,7 +303,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv * 2 bytes long. Some day it might be 3 bytes long :-). */ devaddr = simple_strtoul(argv[2], NULL, 16); - alen = get_alen(argv[2]); + alen = get_alen(argv[2], DEFAULT_ADDR_LEN); if (alen 3) return CMD_RET_USAGE; @@ -257,10 +317,18 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv */ memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16); - if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) { - i2c_report_err(-1, I2C_ERR_READ); - return 1; - } +#ifdef CONFIG_DM_I2C + ret = i2c_get_cur_bus_chip(chip, dev); + if (!ret alen != -1) + ret = i2c_set_addr_len(dev, alen); + if (!ret) + ret = i2c_read(dev, devaddr, memaddr, length); +#else + ret = i2c_read(chip, devaddr, alen, memaddr, length); +#endif + if (ret) + return i2c_report_err(ret, I2C_ERR_READ); + return 0; } @@ -269,6 +337,10 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ u_char chip; uintdevaddr, alen, length; u_char *memaddr; + int ret; +#ifdef CONFIG_DM_I2C + struct udevice *dev; +#endif if (argc != 5) return cmd_usage(cmdtp); @@ -288,7 +360,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ * 2 bytes long. Some day it might be 3 bytes long :-). */ devaddr = simple_strtoul(argv[3], NULL, 16); - alen = get_alen(argv[3]); + alen = get_alen(argv[3], DEFAULT_ADDR_LEN); if
[U-Boot] [RFC PATCH 04/12] dm: i2c: Implement driver model support in the i2c command
The concept of a 'current bus' is now implemented in the command line rather than in the uclass. Also the address length does not need to be specified with each command - really we should consider dropping this from most commands but it works OK for now. Signed-off-by: Simon Glass s...@chromium.org --- common/cmd_i2c.c | 312 +++ 1 file changed, 267 insertions(+), 45 deletions(-) diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index c266b88..6766856 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -69,8 +69,10 @@ #include bootretry.h #include cli.h #include command.h +#include dm.h #include edid.h #include environment.h +#include errno.h #include i2c.h #include malloc.h #include asm/byteorder.h @@ -117,6 +119,60 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; #define DISP_LINE_LEN 16 +/* + * Default for driver model is to use the chip's existing address length. + * For legacy code, this is not stored, so we need to use a suitable + * default. + */ +#ifdef CONFIG_DM_I2C +#define DEFAULT_ADDR_LEN (-1) +#else +#define DEFAULT_ADDR_LEN 1 +#endif + +#ifdef CONFIG_DM_I2C +static struct udevice *i2c_cur_bus; + +static int i2c_set_bus_num(unsigned int busnum) +{ + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, bus); + if (ret) { + debug(%s: No bus %d\n, __func__, busnum); + return ret; + } + i2c_cur_bus = bus; + + return 0; +} + +static int i2c_get_cur_bus(struct udevice **busp) +{ + if (!i2c_cur_bus) { + puts(No I2C bus selected\n); + return -ENODEV; + } + *busp = i2c_cur_bus; + + return 0; +} + +static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp) +{ + struct udevice *bus; + int ret; + + ret = i2c_get_cur_bus(bus); + if (ret) + return ret; + + return i2c_get_chip(bus, chip_addr, devp); +} + +#endif + /** * i2c_init_board() - Board-specific I2C bus init * @@ -143,7 +199,7 @@ void i2c_init_board(void) * * Returns I2C bus speed in Hz. */ -#if !defined(CONFIG_SYS_I2C) +#if !defined(CONFIG_SYS_I2C) !defined(CONFIG_DM_I2C) /* * TODO: Implement architecture-specific get/set functions * Should go away, if we switched completely to new multibus support @@ -182,12 +238,12 @@ int i2c_set_bus_speed(unsigned int speed) * * Returns the address length. */ -static uint get_alen(char *arg) +static uint get_alen(char *arg, int default_len) { int j; int alen; - alen = 1; + alen = default_len; for (j = 0; j 8; j++) { if (arg[j] == '.') { alen = arg[j+1] - '0'; @@ -229,6 +285,10 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv u_char chip; uintdevaddr, alen, length; u_char *memaddr; + int ret; +#ifdef CONFIG_DM_I2C + struct udevice *dev; +#endif if (argc != 5) return CMD_RET_USAGE; @@ -243,7 +303,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv * 2 bytes long. Some day it might be 3 bytes long :-). */ devaddr = simple_strtoul(argv[2], NULL, 16); - alen = get_alen(argv[2]); + alen = get_alen(argv[2], DEFAULT_ADDR_LEN); if (alen 3) return CMD_RET_USAGE; @@ -257,10 +317,18 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv */ memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16); - if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) { - i2c_report_err(-1, I2C_ERR_READ); - return 1; - } +#ifdef CONFIG_DM_I2C + ret = i2c_get_cur_bus_chip(chip, dev); + if (!ret alen != -1) + ret = i2c_set_addr_len(dev, alen); + if (!ret) + ret = i2c_read(dev, devaddr, memaddr, length); +#else + ret = i2c_read(chip, devaddr, alen, memaddr, length); +#endif + if (ret) + return i2c_report_err(ret, I2C_ERR_READ); + return 0; } @@ -269,6 +337,10 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ u_char chip; uintdevaddr, alen, length; u_char *memaddr; + int ret; +#ifdef CONFIG_DM_I2C + struct udevice *dev; +#endif if (argc != 5) return cmd_usage(cmdtp); @@ -288,7 +360,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ * 2 bytes long. Some day it might be 3 bytes long :-). */ devaddr = simple_strtoul(argv[3], NULL, 16); - alen = get_alen(argv[3]); + alen = get_alen(argv[3], DEFAULT_ADDR_LEN); if (alen 3) return cmd_usage(cmdtp); @@ -297,10 +369,22 @@