All of lore.kernel.org
 help / color / mirror / Atom feed
From: Guenter Roeck <guenter.roeck-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
To: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
Cc: Linux I2C <linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: [PATCH v2] i2ctools: Add capability to write block command
Date: Thu, 27 Jan 2011 11:58:42 -0800	[thread overview]
Message-ID: <20110127195842.GA17775@ericsson.com> (raw)
In-Reply-To: <20110127175908.488edda3-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>

Add support to write SMBus and I2C block data to i2cset.

Rev 2: Included review feedback

--
Index: tools/i2cset.8
===================================================================
--- tools/i2cset.8	(revision 5909)
+++ tools/i2cset.8	(working copy)
@@ -12,6 +12,7 @@
 .I chip-address
 .I data-address
 .RI [ value ]
+.RI ...
 .RI [ mode ]
 .br
 .B i2cset
@@ -62,18 +63,24 @@
 integer between 0x00 and 0xFF.
 .PP
 The \fIvalue\fR parameter, if specified, is the value to write to that
-location on the chip. If this parameter is omited, then a short write is
+location on the chip. If this parameter is omitted, then a short write is
 issued. For most chips, it simply sets an internal pointer to the target
 location, but doesn't actually write to that location. For a few chips
 though, in particular simple ones with a single register, this short write
-is an actual write.
+is an actual write. If the mode parameter is \fBs\fP or \fBi\fP, multiple
+values can be specified.
 .PP
-The \fImode\fR parameter, if specified, is one of the letters \fBb\fP or
-\fBw\fP, corresponding to a write size of a single byte or a 16-bit word,
-respectively. A \fBp\fP can also be appended to the \fImode\fR parameter to
-enable PEC. If the \fImode\fR parameter is omitted, i2cset defaults to byte
+The \fImode\fR parameter, if specified, is one of the letters \fBb\fP,
+\fBw\fP, \fBs\fP, or \fBi\fP, corresponding to a write size of a single byte,
+a 16-bit word, a SMBus block write, or an I2C block write, respectively.
+For SMBus and I2C block writes, the write size is determined by the number
+of \fIvalue\fR parameters.
+Except for I2C block writes, a \fBp\fP can also be appended to the \fImode\fR
+parameter to enable PEC.
+If the \fImode\fR parameter is omitted, i2cset defaults to byte
 mode without PEC. The \fIvalue\fR provided must be within range for the
-specified data type (0x00-0xFF for bytes, 0x0000-0xFFFF for words).
+specified data type (0x00-0xFF for byte and block writes, 0x0000-0xFFFF
+for words).
 Another possible mode is \fBc\fP, which doesn't write any value (so-called
 short write). You usually don't have to specify this mode, as it is the
 default when no value is provided, unless you also want to enable PEC.
Index: tools/i2cset.c
===================================================================
--- tools/i2cset.c	(revision 5909)
+++ tools/i2cset.c	(working copy)
@@ -35,13 +35,15 @@
 static void help(void)
 {
 	fprintf(stderr,
-	        "Usage: i2cset [-f] [-y] [-m MASK] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] [MODE]\n"
+	        "Usage: i2cset [-f] [-y] [-m MASK] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]\n"
 		"  I2CBUS is an integer or an I2C bus name\n"
 		"  ADDRESS is an integer (0x03 - 0x77)\n"
 		"  MODE is one of:\n"
 		"    c (byte, no value)\n"
 		"    b (byte data, default)\n"
 		"    w (word data)\n"
+		"    i (I2C block data)\n"
+		"    s (SMBus block data)\n"
 		"    Append p for SMBus PEC\n");
 	exit(1);
 }
@@ -78,6 +80,19 @@
 			return -1;
 		}
 		break;
+
+	case I2C_SMBUS_BLOCK_DATA:
+		if (!(funcs & I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)) {
+			fprintf(stderr, MISSING_FUNC_FMT, "SMBus block read");
+			return -1;
+		}
+		break;
+	case I2C_SMBUS_I2C_BLOCK_DATA:
+		if (!(funcs & I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
+			fprintf(stderr, MISSING_FUNC_FMT, "I2C block read");
+			return -1;
+		}
+		break;
 	}
 
 	if (pec
@@ -90,7 +105,8 @@
 }
 
 static int confirm(const char *filename, int address, int size, int daddress,
-		   int value, int vmask, int pec)
+		   int value, int vmask, const unsigned char *block, int len,
+		   int pec)
 {
 	int dont = 0;
 
@@ -109,7 +125,16 @@
 		"0x%02x, data address\n0x%02x, ", filename, address, daddress);
 	if (size == I2C_SMBUS_BYTE)
 		fprintf(stderr, "no data.\n");
-	else
+	else if (size == I2C_SMBUS_BLOCK_DATA ||
+		 size == I2C_SMBUS_I2C_BLOCK_DATA) {
+		int i;
+
+		fprintf(stderr, "data");
+		for (i = 0; i < len; i++)
+			fprintf(stderr, " 0x%02x", block[i]);
+		fprintf(stderr, ", mode %s.\n", size == I2C_SMBUS_BLOCK_DATA
+			? "smbus block" : "i2c block");
+	} else
 		fprintf(stderr, "data 0x%02x%s, mode %s.\n", value,
 			vmask ? " (masked)" : "",
 			size == I2C_SMBUS_BYTE_DATA ? "byte" : "word");
@@ -136,6 +161,8 @@
 	int pec = 0;
 	int flags = 0;
 	int force = 0, yes = 0, version = 0, readback = 0;
+	unsigned char block[I2C_SMBUS_BLOCK_MAX];
+	int len;
 
 	/* handle (optional) flags first */
 	while (1+flags < argc && argv[1+flags][0] == '-') {
@@ -180,6 +207,34 @@
 		help();
 	}
 
+	/* check for block data */
+	len = 0;
+	if (argc > flags + 5) {
+		switch (argv[argc-1][0]) {
+		case 's': size = I2C_SMBUS_BLOCK_DATA; break;
+		case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break;
+		default:
+			size = 0;
+			break;
+		}
+		if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) {
+			pec = argv[argc-1][1] == 'p';
+			if (pec && size == I2C_SMBUS_I2C_BLOCK_DATA) {
+				fprintf(stderr, "Error: PEC not supported for I2C block writes!\n");
+				help();
+			}
+			for (len = 0; len < (int)sizeof(block) && len + flags + 5 < argc; len++) {
+				value = strtol(argv[flags + len + 4], &end, 0);
+				if (*end || value < 0 || value > 0xff) {
+                                	fprintf(stderr, "Error: Block data value invalid!\n");
+                                	help();
+                        	}
+				block[len] = value;
+			}
+			goto dofile;
+		}
+	}
+
 	if (argc > flags + 4) {
 		if (!strcmp(argv[flags+4], "c")
 		 || !strcmp(argv[flags+4], "cp")) {
@@ -236,6 +291,7 @@
 		help();
 	}
 
+dofile:
 	file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0);
 	if (file < 0
 	 || check_funcs(file, size, pec)
@@ -243,7 +299,7 @@
 		exit(1);
 
 	if (!yes && !confirm(filename, address, size, daddress,
-			     value, vmask, pec))
+			     value, vmask, block, len, pec))
 		exit(0);
 
 	if (vmask) {
@@ -299,8 +355,15 @@
 	case I2C_SMBUS_WORD_DATA:
 		res = i2c_smbus_write_word_data(file, daddress, value);
 		break;
+	case I2C_SMBUS_BLOCK_DATA:
+		res = i2c_smbus_write_block_data(file, daddress, len, block);
+		break;
+	case I2C_SMBUS_I2C_BLOCK_DATA:
+		res = i2c_smbus_write_i2c_block_data(file, daddress, len, block);
+		break;
 	default: /* I2C_SMBUS_BYTE_DATA */
 		res = i2c_smbus_write_byte_data(file, daddress, value);
+		break;
 	}
 	if (res < 0) {
 		fprintf(stderr, "Error: Write failed\n");
Index: CHANGES
===================================================================
--- CHANGES	(revision 5909)
+++ CHANGES	(working copy)
@@ -3,6 +3,7 @@
 
 SVN
   i2c-dev.h: Make value arrays const for block write functions
+  i2cset: Add support for SMBus and I2C block writes
 
 3.0.3 (2010-12-12)
   Makefile: Let the environment set CC and CFLAGS

  parent reply	other threads:[~2011-01-27 19:58 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-25 16:21 [lm-sensors] i2ctools: Need capability to write SMBus block command Guenter Roeck
     [not found] ` <20110125162106.GA8024-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
2011-01-25 16:43   ` Guenter Roeck
2011-01-25 16:43     ` [lm-sensors] i2ctools: Need capability to write SMBus block Guenter Roeck
2011-01-25 16:49   ` i2ctools: Need capability to write SMBus block command Jean Delvare
     [not found]     ` <20110125174922.4c802f49-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2011-01-25 17:14       ` Guenter Roeck
2011-01-27 16:00       ` [PATCH] i2ctools: Add capability to write " Guenter Roeck
     [not found]         ` <20110127160058.GA16853-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
2011-01-27 16:59           ` Jean Delvare
     [not found]             ` <20110127175908.488edda3-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2011-01-27 18:36               ` Guenter Roeck
2011-01-27 19:58               ` Guenter Roeck [this message]
     [not found]                 ` <20110127195842.GA17775-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
2011-01-29 16:43                   ` [PATCH v2] " Jean Delvare
     [not found]                     ` <20110129174354.2b146a19-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2011-01-29 17:39                       ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110127195842.GA17775@ericsson.com \
    --to=guenter.roeck-izefyvvap7pwk0htik3j/w@public.gmane.org \
    --cc=khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org \
    --cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.