[U-Boot] [PATCH] added i2c read function

Dear all,
The patch below adds a command i2c read which reads from i2c to memory.
That way the value read can be used in later itest commands to control the boot process.
I've tried to stay as close as possible to the i2c md command as far as command syntax concerns. main differences wrt the command syntax:
- length is mandatory - additional argument memaddr - no repeat possibility (it didn't seem too useful to me and only uses bytes)
While doing so I also have expanded the subcommand names to their full length instead of going to two character abbreviations (otherwise read and reset would clash). I saw other places also use longer commands.
(actually personally I would have used strcmp instead of strncmp, but it seems most other files in common use strncmp, so I left that part as is).
Feel free to comment.
Frans
PS: unfortunately git send-email does not pass our corp firewall and doing the patch as attachement is rejected by the mailing list. If there are problems with the patch, just drop me a note and I'll resend from home.
Frans.
From 389fa8835e397c35058a17991b380ae20b6915d1 Mon Sep 17 00:00:00 2001
From:Frans Meulenbroeks fransmeulenbroeks@gmail.com Date: Fri, 19 Feb 2010 13:39:21 +0100 Subject: [PATCH] cmd_i2c.c: added command to read to memory
Added a new function i2c read to read to memory. That way it becomes possible to test against a value and use that to influence the boot process.
Design decision was to stay close to the i2c md command with respect to command syntax.
Signed-off-by: Frans Meulenbroeks fransmeulenbroeks@gmail.com --- common/cmd_i2c.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 62cbd33..0100aa9 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -150,6 +150,64 @@ int i2c_set_bus_speed(unsigned int)
/* * Syntax: + * i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr} + */ + +int do_i2c_read ( cmd_tbl_t *cmdtp, int argc, char *argv[]) +{ + u_char chip; + uint devaddr, alen, length; + u_char *memaddr; + int j; + + if (argc != 5) { + cmd_usage(cmdtp); + return 1; + } + + /* + * I2C chip address + */ + chip = simple_strtoul(argv[1], NULL, 16); + + /* + * I2C data address within the chip. This can be 1 or + * 2 bytes long. Some day it might be 3 bytes long :-). + */ + devaddr = simple_strtoul(argv[2], NULL, 16); + alen = 1; + for (j = 0; j < 8; j++) { + if (argv[2][j] == '.') { + alen = argv[2][j+1] - '0'; + if (alen > 4) { + cmd_usage(cmdtp); + return 1; + } + break; + } else if (argv[2][j] == '\0') + break; + } + + /* + * Length is the number of objects, not number of bytes. + */ + length = simple_strtoul(argv[3], NULL, 16); + + /* + * memaddr is the address where to store things in memory + */ + memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16); + + if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) + { + puts ("Error reading the chip.\n"); + return 1; + } + return 0; +} + +/* + * Syntax: * i2c md {i2c_chip} {addr}{.0, .1, .2} {len} */ #define DISP_LINE_LEN 16 @@ -1249,15 +1306,17 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) argv++;
#if defined(CONFIG_I2C_MUX) - if (!strncmp(argv[0], "bu", 2)) + if (!strcmp(argv[0], "bus", 3)) return do_i2c_add_bus(cmdtp, flag, argc, argv); #endif /* CONFIG_I2C_MUX */ - if (!strncmp(argv[0], "sp", 2)) + if (!strncmp(argv[0], "speed", 5)) return do_i2c_bus_speed(cmdtp, flag, argc, argv); #if defined(CONFIG_I2C_MULTI_BUS) - if (!strncmp(argv[0], "de", 2)) + if (!strncmp(argv[0], "dev", 3)) return do_i2c_bus_num(cmdtp, flag, argc, argv); #endif /* CONFIG_I2C_MULTI_BUS */ + if (!strncmp(argv[0], "read", 4)) + return do_i2c_read(cmdtp, argc, argv); if (!strncmp(argv[0], "md", 2)) return do_i2c_md(cmdtp, flag, argc, argv); if (!strncmp(argv[0], "mm", 2)) @@ -1266,18 +1325,18 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return do_i2c_mw(cmdtp, flag, argc, argv); if (!strncmp(argv[0], "nm", 2)) return mod_i2c_mem (cmdtp, 0, flag, argc, argv); - if (!strncmp(argv[0], "cr", 2)) + if (!strncmp(argv[0], "crc", 3)) return do_i2c_crc(cmdtp, flag, argc, argv); - if (!strncmp(argv[0], "pr", 2)) + if (!strncmp(argv[0], "probe", 5)) return do_i2c_probe(cmdtp, flag, argc, argv); - if (!strncmp(argv[0], "re", 2)) { + if (!strncmp(argv[0], "reset", 5)) { i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); return 0; } - if (!strncmp(argv[0], "lo", 2)) + if (!strncmp(argv[0], "loop", 4)) return do_i2c_loop(cmdtp, flag, argc, argv); #if defined(CONFIG_CMD_SDRAM) - if (!strncmp(argv[0], "sd", 2)) + if (!strncmp(argv[0], "sdram", 5)) return do_sdram(cmdtp, flag, argc, argv); #endif cmd_usage(cmdtp); @@ -1296,6 +1355,7 @@ U_BOOT_CMD( #if defined(CONFIG_I2C_MULTI_BUS) "i2c dev [dev] - show or set current I2C bus\n" #endif /* CONFIG_I2C_MULTI_BUS */ + "i2c read chip address[.0, .1, .2] #_of_objects memaddr - read from I2C device to memory\n" "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n"

Hi Frans,
The patch below adds a command i2c read which reads from i2c to memory.
Thanks for picking up the hint! ;)
That way the value read can be used in later itest commands to control the boot process.
I've tried to stay as close as possible to the i2c md command as far as command syntax concerns. main differences wrt the command syntax:
- length is mandatory
- additional argument memaddr
- no repeat possibility (it didn't seem too useful to me and only uses bytes)
While doing so I also have expanded the subcommand names to their full length instead of going to two character abbreviations (otherwise read and reset would clash). I saw other places also use longer commands.
(actually personally I would have used strcmp instead of strncmp, but it seems most other files in common use strncmp, so I left that part as is).
Well actually if you _do_ touch this place, why not convert it to use cmd_tbl which does all this handling for you? For an example, look at common/cmd_bootm.c around line 465.
PS: unfortunately git send-email does not pass our corp firewall and doing the patch as attachement is rejected by the mailing list. If there are problems with the patch, just drop me a note and I'll resend from home.
Even after manually stripping the header and the introductory text, the patch is damaged:
[dzu@pollux u-boot-testing (master)]$ git am ~/p01 Applying: cmd_i2c.c: added command to read to memory fatal: corrupt patch at line 75 Patch failed at 0001 cmd_i2c.c: added command to read to memory When you have resolved this problem run "git am --resolved". If you would prefer to skip this patch, instead run "git am --skip". To restore the original branch and stop patching run "git am --abort".
Cheers Detlev
participants (2)
-
Detlev Zundel
-
Frans Meulenbroeks