From c70443b5c7df82a3d9157f8ef3d01fe06d5fe1e8 Mon Sep 17 00:00:00 2001 From: Eric Bénard Date: Tue, 25 May 2010 12:01:27 +0200 Subject: commands: add i2c commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit theses commands allow low level access to i2c bus and can be useful to setup an i2c device without having to add code, compile and flash barebox. Signed-off-by: Eric Bénard Signed-off-by: Sascha Hauer --- commands/i2c.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 commands/i2c.c (limited to 'commands/i2c.c') diff --git a/commands/i2c.c b/commands/i2c.c new file mode 100644 index 0000000000..d38e779acb --- /dev/null +++ b/commands/i2c.c @@ -0,0 +1,214 @@ +/* + * i2c.c - i2c commands + * + * Copyright (c) 2010 Eric Bénard , Eukréa Electromatique + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +static int do_i2c_probe(struct command *cmdtp, int argc, char *argv[]) +{ + struct i2c_adapter *adapter; + struct i2c_client client; + int startaddr = -1, stopaddr = -1, addr, ret; + u8 reg; + + if (argc < 4) + return COMMAND_ERROR_USAGE; + + adapter = i2c_get_adapter(simple_strtoul(argv[1], NULL, 0)); + if (!adapter) + return -ENODEV; + client.adapter = adapter; + + startaddr = simple_strtol(argv[2], NULL, 0); + stopaddr = simple_strtol(argv[3], NULL, 0); + if ((startaddr == -1) || (stopaddr == -1) || (startaddr > stopaddr)) + return COMMAND_ERROR_USAGE; + + if (stopaddr > 0x7F) + stopaddr = 0x7F; + + printf("probing i2c range 0X%02x - 0x%02x :\n", startaddr, stopaddr); + for (addr = startaddr; addr <= stopaddr; addr++) { + client.addr = addr; + ret = i2c_write_reg(&client, 0x00, ®, 0); + if (ret == 0) + printf("0x%02x ", addr); + } + printf("\n"); + return 0; +} + +static const __maybe_unused char cmd_i2c_probe_help[] = +"Usage: i2c_probe bus 0xstartaddr 0xstopaddr\n" +"probe a range of i2c addresses.\n"; + +BAREBOX_CMD_START(i2c_probe) + .cmd = do_i2c_probe, + .usage = "probe for an i2c device", + BAREBOX_CMD_HELP(cmd_i2c_probe_help) +BAREBOX_CMD_END + +static int do_i2c_write(struct command *cmdtp, int argc, char *argv[]) +{ + struct i2c_adapter *adapter = NULL; + struct i2c_client client; + int addr = -1, reg = -1, count = -1, verbose = 0, ret, opt, i, bus = 0; + u8 *buf; + + while ((opt = getopt(argc, argv, "a:b:r:v")) > 0) { + switch (opt) { + case 'a': + addr = simple_strtol(optarg, NULL, 0); + break; + case 'r': + reg = simple_strtol(optarg, NULL, 0); + break; + case 'b': + bus = simple_strtoul(optarg, NULL, 0); + break; + case 'v': + verbose = 1; + break; + } + } + + count = argc - optind; + + if ((addr < 0) || (reg < 0) || (count == 0) || (addr > 0x7F)) + return COMMAND_ERROR_USAGE; + + adapter = i2c_get_adapter(bus); + if (!adapter) { + printf("i2c bus %d not found\n", bus); + return -ENODEV; + } + + client.adapter = adapter; + client.addr = addr; + + buf = xmalloc(count); + for (i = 0; i < count; i++) + *(buf + i) = (char) simple_strtol(argv[optind+i], NULL, 16); + + ret = i2c_write_reg(&client, reg, buf, count); + if (ret != count) + goto out; + ret = 0; + + if (verbose) { + printf("wrote %i bytes starting at reg 0x%02x to i2cdev 0x%02x on bus %i\n", + count, reg, addr, adapter->nr); + for (i = 0; i < count; i++) + printf("0x%02x ", *(buf + i)); + printf("\n"); + } + +out: + free(buf); + return ret; +} + +static const __maybe_unused char cmd_i2c_write_help[] = +"Usage: i2c_write [OPTION] ... hexdatas\n" +"write to i2c device.\n" +" -a 0x i2c device address\n" +" -b i2c bus number (default = 0)\n" +" -r 0x start register\n"; + +BAREBOX_CMD_START(i2c_write) + .cmd = do_i2c_write, + .usage = "write to an i2c device", + BAREBOX_CMD_HELP(cmd_i2c_write_help) +BAREBOX_CMD_END + +static int do_i2c_read(struct command *cmdtp, int argc, char *argv[]) +{ + struct i2c_adapter *adapter = NULL; + struct i2c_client client; + u8 *buf; + int count = -1, addr = -1, reg = -1, verbose = 0, ret, opt, bus = 0; + + while ((opt = getopt(argc, argv, "a:b:c:r:v")) > 0) { + switch (opt) { + case 'a': + addr = simple_strtol(optarg, NULL, 0); + break; + case 'c': + count = simple_strtoul(optarg, NULL, 0); + break; + case 'b': + bus = simple_strtoul(optarg, NULL, 0); + break; + case 'r': + reg = simple_strtol(optarg, NULL, 0); + break; + case 'v': + verbose = 1; + break; + } + } + + if ((addr < 0) || (reg < 0) || (count == 0) || (addr > 0x7F)) + return COMMAND_ERROR_USAGE; + + adapter = i2c_get_adapter(bus); + if (!adapter) { + printf("i2c bus %d not found\n", bus); + return -ENODEV; + } + + client.adapter = adapter; + client.addr = addr; + + buf = xmalloc(count); + ret = i2c_read_reg(&client, reg, buf, count); + if (ret == count) { + int i; + if (verbose) + printf("read %i bytes starting at reg 0x%02x from i2cdev 0x%02x on bus %i\n", + count, reg, addr, adapter->nr); + for (i = 0; i < count; i++) + printf("0x%02x ", *(buf + i)); + printf("\n"); + ret = 0; + } + + free(buf); + return ret; +} + +static const __maybe_unused char cmd_i2c_read_help[] = +"Usage: i2c_read [OPTION]\n" +"read i2c device.\n" +" -a 0x i2c device address\n" +" -b i2c bus number (default = 0)\n" +" -r 0x start register\n" +" -c byte count\n"; + +BAREBOX_CMD_START(i2c_read) + .cmd = do_i2c_read, + .usage = "read from an i2c device", + BAREBOX_CMD_HELP(cmd_i2c_read_help) +BAREBOX_CMD_END -- cgit v1.2.3