/*
 * i2c.c - i2c commands
 *
 * Copyright (c) 2010 Eric Bénard <eric@eukrea.Com>, 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 <common.h>
#include <command.h>
#include <errno.h>
#include <malloc.h>
#include <getopt.h>
#include <i2c/i2c.h>

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, &reg, 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<addr>   i2c device address\n"
"  -b <bus_num>  i2c bus number (default = 0)\n"
"  -r 0x<reg>    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<addr>   i2c device address\n"
"  -b <bus_num>  i2c bus number (default = 0)\n"
"  -r 0x<reg>    start register\n"
"  -c <count>    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
