blob: cae7428f8d4f49d3172a3cb4fef91b6237f1fee9 [file] [log] [blame]
Brad Bishop94ad3b22019-01-15 16:01:53 -05001From b5e7f70c9c43d9a0f819ac2f9942cefca5a79875 Mon Sep 17 00:00:00 2001
Matt Spinlerf5930452017-01-25 15:08:00 -06002From: Crestez Dan Leonard <leonard.crestez@intel.com>
3Date: Fri, 13 May 2016 21:54:25 +0300
4Subject: [PATCH] i2cget: Add support for i2c block data
5
6This adds mode 'i' for I2C_SMBUS_I2C_BLOCK_DATA. This is the same mode
7letter from i2cdump.
8
9Length is optional and defaults to 32 (maximum).
10
11The indended use is debugging i2c devices with shell commands.
12
13Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com>
Brad Bishop94ad3b22019-01-15 16:01:53 -050014Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Matt Spinlerf5930452017-01-25 15:08:00 -060015---
Brad Bishop94ad3b22019-01-15 16:01:53 -050016 tools/i2cget.c | 61 +++++++++++++++++++++++++++++++++++++++++---------
Matt Spinlerf5930452017-01-25 15:08:00 -060017 1 file changed, 51 insertions(+), 10 deletions(-)
18
19diff --git a/tools/i2cget.c b/tools/i2cget.c
Brad Bishop94ad3b22019-01-15 16:01:53 -050020index d2ed56a..83e57f7 100644
Matt Spinlerf5930452017-01-25 15:08:00 -060021--- a/tools/i2cget.c
22+++ b/tools/i2cget.c
23@@ -41,14 +41,16 @@ static void help(void) __attribute__ ((noreturn));
24 static void help(void)
25 {
26 fprintf(stderr,
Brad Bishop94ad3b22019-01-15 16:01:53 -050027- "Usage: i2cget [-f] [-y] [-a] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]\n"
28+ "Usage: i2cget [-f] [-y] [-a] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE] [LENGTH]]\n"
Matt Spinlerf5930452017-01-25 15:08:00 -060029 " I2CBUS is an integer or an I2C bus name\n"
Brad Bishop94ad3b22019-01-15 16:01:53 -050030 " ADDRESS is an integer (0x03 - 0x77, or 0x00 - 0x7f if -a is given)\n"
Matt Spinlerf5930452017-01-25 15:08:00 -060031 " MODE is one of:\n"
32 " b (read byte data, default)\n"
33 " w (read word data)\n"
34 " c (write byte/read byte)\n"
35- " Append p for SMBus PEC\n");
36+ " i (read I2C block data)\n"
37+ " Append p for SMBus PEC\n"
38+ " LENGTH is length for block data reads\n");
39 exit(1);
40 }
41
42@@ -89,6 +91,13 @@ static int check_funcs(int file, int size, int daddress, int pec)
43 return -1;
44 }
45 break;
46+
47+ case I2C_SMBUS_I2C_BLOCK_DATA:
48+ if (!(funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
49+ fprintf(stderr, MISSING_FUNC_FMT, "SMBus read I2C block data");
50+ return -1;
51+ }
52+ break;
53 }
54
55 if (pec
56@@ -101,7 +110,7 @@ static int check_funcs(int file, int size, int daddress, int pec)
57 }
58
59 static int confirm(const char *filename, int address, int size, int daddress,
60- int pec)
61+ int length, int pec)
62 {
63 int dont = 0;
64
65@@ -132,11 +141,14 @@ static int confirm(const char *filename, int address, int size, int daddress,
66 fprintf(stderr, "current data\naddress");
67 else
68 fprintf(stderr, "data address\n0x%02x", daddress);
69- fprintf(stderr, ", using %s.\n",
70- size == I2C_SMBUS_BYTE ? (daddress < 0 ?
71- "read byte" : "write byte/read byte") :
72- size == I2C_SMBUS_BYTE_DATA ? "read byte data" :
73- "read word data");
74+ if (size == I2C_SMBUS_I2C_BLOCK_DATA)
75+ fprintf(stderr, ", %d bytes using read I2C block data.\n", length);
76+ else
77+ fprintf(stderr, ", using %s.\n",
78+ size == I2C_SMBUS_BYTE ? (daddress < 0 ?
79+ "read byte" : "write byte/read byte") :
80+ size == I2C_SMBUS_BYTE_DATA ? "read byte data" :
81+ "read word data");
82 if (pec)
83 fprintf(stderr, "PEC checking enabled.\n");
84
85@@ -159,6 +171,8 @@ int main(int argc, char *argv[])
86 int pec = 0;
87 int flags = 0;
Brad Bishop94ad3b22019-01-15 16:01:53 -050088 int force = 0, yes = 0, version = 0, all_addrs = 0;
Matt Spinlerf5930452017-01-25 15:08:00 -060089+ int length;
90+ __u8 block_data[I2C_SMBUS_BLOCK_MAX];
91
92 /* handle (optional) flags first */
93 while (1+flags < argc && argv[1+flags][0] == '-') {
Brad Bishop94ad3b22019-01-15 16:01:53 -050094@@ -209,6 +223,7 @@ int main(int argc, char *argv[])
Matt Spinlerf5930452017-01-25 15:08:00 -060095 case 'b': size = I2C_SMBUS_BYTE_DATA; break;
96 case 'w': size = I2C_SMBUS_WORD_DATA; break;
97 case 'c': size = I2C_SMBUS_BYTE; break;
98+ case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break;
99 default:
100 fprintf(stderr, "Error: Invalid mode!\n");
101 help();
Brad Bishop94ad3b22019-01-15 16:01:53 -0500102@@ -216,13 +231,27 @@ int main(int argc, char *argv[])
Matt Spinlerf5930452017-01-25 15:08:00 -0600103 pec = argv[flags+4][1] == 'p';
104 }
105
106+ if (argc > flags + 5) {
107+ if (size != I2C_SMBUS_I2C_BLOCK_DATA) {
108+ fprintf(stderr, "Error: Length only valid for I2C block data!\n");
109+ help();
110+ }
111+ length = strtol(argv[flags+5], &end, 0);
112+ if (*end || length < 1 || length > I2C_SMBUS_BLOCK_MAX) {
113+ fprintf(stderr, "Error: Length invalid!\n");
114+ help();
115+ }
116+ } else {
117+ length = I2C_SMBUS_BLOCK_MAX;
118+ }
119+
120 file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0);
121 if (file < 0
122 || check_funcs(file, size, daddress, pec)
123 || set_slave_addr(file, address, force))
124 exit(1);
125
126- if (!yes && !confirm(filename, address, size, daddress, pec))
127+ if (!yes && !confirm(filename, address, size, daddress, length, pec))
128 exit(0);
129
130 if (pec && ioctl(file, I2C_PEC, 1) < 0) {
Brad Bishop94ad3b22019-01-15 16:01:53 -0500131@@ -244,6 +273,9 @@ int main(int argc, char *argv[])
Matt Spinlerf5930452017-01-25 15:08:00 -0600132 case I2C_SMBUS_WORD_DATA:
133 res = i2c_smbus_read_word_data(file, daddress);
134 break;
135+ case I2C_SMBUS_I2C_BLOCK_DATA:
136+ res = i2c_smbus_read_i2c_block_data(file, daddress, length, block_data);
137+ break;
138 default: /* I2C_SMBUS_BYTE_DATA */
139 res = i2c_smbus_read_byte_data(file, daddress);
140 }
Brad Bishop94ad3b22019-01-15 16:01:53 -0500141@@ -254,7 +286,16 @@ int main(int argc, char *argv[])
Matt Spinlerf5930452017-01-25 15:08:00 -0600142 exit(2);
143 }
144
145- printf("0x%0*x\n", size == I2C_SMBUS_WORD_DATA ? 4 : 2, res);
146+ if (size == I2C_SMBUS_I2C_BLOCK_DATA) {
147+ int i;
148+ printf("%d:", res);
149+ for (i = 0; i < res; ++i) {
150+ printf(" 0x%02hhx", block_data[i]);
151+ }
152+ printf("\n");
153+ } else {
154+ printf("0x%0*x\n", size == I2C_SMBUS_WORD_DATA ? 4 : 2, res);
155+ }
156
157 exit(0);
158 }
159--
Brad Bishop94ad3b22019-01-15 16:01:53 -05001602.20.1
Matt Spinlerf5930452017-01-25 15:08:00 -0600161