aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-30 13:03:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-30 13:03:46 -0400
commit42fe55ce905212542426fa6407a76534a5fb696a (patch)
tree874c5984e4222ea253b78c5be4755b3d31da54e2
parent19ce0a995ff230b364c7329fd488c70e91c171d9 (diff)
parent14674e70119ea01549ce593d8901a797f8a90f74 (diff)
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
Pull i2c updates from Jean Delvare. * 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging: i2c: Split I2C_M_NOSTART support out of I2C_FUNC_PROTOCOL_MANGLING i2c-dev: Add support for I2C_M_RECV_LEN
-rw-r--r--Documentation/i2c/functionality9
-rw-r--r--Documentation/i2c/i2c-protocol9
-rw-r--r--drivers/base/regmap/regmap-i2c.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c2
-rw-r--r--drivers/i2c/busses/i2c-nuc900.c3
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c3
-rw-r--r--drivers/i2c/i2c-dev.c30
-rw-r--r--drivers/input/joystick/as5011.c1
-rw-r--r--drivers/video/matrox/matroxfb_maven.c1
-rw-r--r--include/linux/i2c.h5
10 files changed, 51 insertions, 14 deletions
diff --git a/Documentation/i2c/functionality b/Documentation/i2c/functionality
index 42c17c1fb3cd..b0ff2ab596ce 100644
--- a/Documentation/i2c/functionality
+++ b/Documentation/i2c/functionality
@@ -18,9 +18,9 @@ For the most up-to-date list of functionality constants, please check
18 adapters typically can not do these) 18 adapters typically can not do these)
19 I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions 19 I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions
20 I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK, 20 I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK,
21 I2C_M_REV_DIR_ADDR, I2C_M_NOSTART and 21 I2C_M_REV_DIR_ADDR and I2C_M_NO_RD_ACK
22 I2C_M_NO_RD_ACK flags (which modify the 22 flags (which modify the I2C protocol!)
23 I2C protocol!) 23 I2C_FUNC_NOSTART Can skip repeated start sequence
24 I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command 24 I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command
25 I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command 25 I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command
26 I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command 26 I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command
@@ -50,6 +50,9 @@ A few combinations of the above flags are also defined for your convenience:
50 emulated by a real I2C adapter (using 50 emulated by a real I2C adapter (using
51 the transparent emulation layer) 51 the transparent emulation layer)
52 52
53In kernel versions prior to 3.5 I2C_FUNC_NOSTART was implemented as
54part of I2C_FUNC_PROTOCOL_MANGLING.
55
53 56
54ADAPTER IMPLEMENTATION 57ADAPTER IMPLEMENTATION
55---------------------- 58----------------------
diff --git a/Documentation/i2c/i2c-protocol b/Documentation/i2c/i2c-protocol
index 10518dd58814..0b3e62d1f77a 100644
--- a/Documentation/i2c/i2c-protocol
+++ b/Documentation/i2c/i2c-protocol
@@ -49,7 +49,9 @@ a byte read, followed by a byte write:
49Modified transactions 49Modified transactions
50===================== 50=====================
51 51
52We have found some I2C devices that needs the following modifications: 52The following modifications to the I2C protocol can also be generated,
53with the exception of I2C_M_NOSTART these are usually only needed to
54work around device issues:
53 55
54 Flag I2C_M_NOSTART: 56 Flag I2C_M_NOSTART:
55 In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some 57 In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some
@@ -60,6 +62,11 @@ We have found some I2C devices that needs the following modifications:
60 we do not generate Addr, but we do generate the startbit S. This will 62 we do not generate Addr, but we do generate the startbit S. This will
61 probably confuse all other clients on your bus, so don't try this. 63 probably confuse all other clients on your bus, so don't try this.
62 64
65 This is often used to gather transmits from multiple data buffers in
66 system memory into something that appears as a single transfer to the
67 I2C device but may also be used between direction changes by some
68 rare devices.
69
63 Flags I2C_M_REV_DIR_ADDR 70 Flags I2C_M_REV_DIR_ADDR
64 This toggles the Rd/Wr flag. That is, if you want to do a write, but 71 This toggles the Rd/Wr flag. That is, if you want to do a write, but
65 need to emit an Rd instead of a Wr, or vice versa, you set this 72 need to emit an Rd instead of a Wr, or vice versa, you set this
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 5f6b2478bf17..fa6bf5279d28 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -42,7 +42,7 @@ static int regmap_i2c_gather_write(void *context,
42 /* If the I2C controller can't do a gather tell the core, it 42 /* If the I2C controller can't do a gather tell the core, it
43 * will substitute in a linear write for us. 43 * will substitute in a linear write for us.
44 */ 44 */
45 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_PROTOCOL_MANGLING)) 45 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_NOSTART))
46 return -ENOTSUPP; 46 return -ENOTSUPP;
47 47
48 xfer[0].addr = i2c->addr; 48 xfer[0].addr = i2c->addr;
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index 7f0b83219744..fad22b0bb5b0 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -608,7 +608,7 @@ bailout:
608 608
609static u32 bit_func(struct i2c_adapter *adap) 609static u32 bit_func(struct i2c_adapter *adap)
610{ 610{
611 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 611 return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL |
612 I2C_FUNC_SMBUS_READ_BLOCK_DATA | 612 I2C_FUNC_SMBUS_READ_BLOCK_DATA |
613 I2C_FUNC_SMBUS_BLOCK_PROC_CALL | 613 I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
614 I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; 614 I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c
index 03b615778887..a26dfb8cd586 100644
--- a/drivers/i2c/busses/i2c-nuc900.c
+++ b/drivers/i2c/busses/i2c-nuc900.c
@@ -502,7 +502,8 @@ static int nuc900_i2c_xfer(struct i2c_adapter *adap,
502/* declare our i2c functionality */ 502/* declare our i2c functionality */
503static u32 nuc900_i2c_func(struct i2c_adapter *adap) 503static u32 nuc900_i2c_func(struct i2c_adapter *adap)
504{ 504{
505 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; 505 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |
506 I2C_FUNC_PROTOCOL_MANGLING;
506} 507}
507 508
508/* i2c bus registration info */ 509/* i2c bus registration info */
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index fa0b13490873..01959154572d 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -626,7 +626,8 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
626/* declare our i2c functionality */ 626/* declare our i2c functionality */
627static u32 s3c24xx_i2c_func(struct i2c_adapter *adap) 627static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
628{ 628{
629 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; 629 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |
630 I2C_FUNC_PROTOCOL_MANGLING;
630} 631}
631 632
632/* i2c bus registration info */ 633/* i2c bus registration info */
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 45048323b75e..5ec2261574ec 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -265,19 +265,41 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
265 265
266 res = 0; 266 res = 0;
267 for (i = 0; i < rdwr_arg.nmsgs; i++) { 267 for (i = 0; i < rdwr_arg.nmsgs; i++) {
268 /* Limit the size of the message to a sane amount; 268 /* Limit the size of the message to a sane amount */
269 * and don't let length change either. */ 269 if (rdwr_pa[i].len > 8192) {
270 if ((rdwr_pa[i].len > 8192) ||
271 (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
272 res = -EINVAL; 270 res = -EINVAL;
273 break; 271 break;
274 } 272 }
273
275 data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf; 274 data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
276 rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len); 275 rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);
277 if (IS_ERR(rdwr_pa[i].buf)) { 276 if (IS_ERR(rdwr_pa[i].buf)) {
278 res = PTR_ERR(rdwr_pa[i].buf); 277 res = PTR_ERR(rdwr_pa[i].buf);
279 break; 278 break;
280 } 279 }
280
281 /*
282 * If the message length is received from the slave (similar
283 * to SMBus block read), we must ensure that the buffer will
284 * be large enough to cope with a message length of
285 * I2C_SMBUS_BLOCK_MAX as this is the maximum underlying bus
286 * drivers allow. The first byte in the buffer must be
287 * pre-filled with the number of extra bytes, which must be
288 * at least one to hold the message length, but can be
289 * greater (for example to account for a checksum byte at
290 * the end of the message.)
291 */
292 if (rdwr_pa[i].flags & I2C_M_RECV_LEN) {
293 if (!(rdwr_pa[i].flags & I2C_M_RD) ||
294 rdwr_pa[i].buf[0] < 1 ||
295 rdwr_pa[i].len < rdwr_pa[i].buf[0] +
296 I2C_SMBUS_BLOCK_MAX) {
297 res = -EINVAL;
298 break;
299 }
300
301 rdwr_pa[i].len = rdwr_pa[i].buf[0];
302 }
281 } 303 }
282 if (res < 0) { 304 if (res < 0) {
283 int j; 305 int j;
diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c
index 3063464474bf..57d19d4e0a2d 100644
--- a/drivers/input/joystick/as5011.c
+++ b/drivers/input/joystick/as5011.c
@@ -231,6 +231,7 @@ static int __devinit as5011_probe(struct i2c_client *client,
231 } 231 }
232 232
233 if (!i2c_check_functionality(client->adapter, 233 if (!i2c_check_functionality(client->adapter,
234 I2C_FUNC_NOSTART |
234 I2C_FUNC_PROTOCOL_MANGLING)) { 235 I2C_FUNC_PROTOCOL_MANGLING)) {
235 dev_err(&client->dev, 236 dev_err(&client->dev,
236 "need i2c bus that supports protocol mangling\n"); 237 "need i2c bus that supports protocol mangling\n");
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index 31b8f67477b7..217678e0b983 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -1243,6 +1243,7 @@ static int maven_probe(struct i2c_client *client,
1243 1243
1244 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA | 1244 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA |
1245 I2C_FUNC_SMBUS_BYTE_DATA | 1245 I2C_FUNC_SMBUS_BYTE_DATA |
1246 I2C_FUNC_NOSTART |
1246 I2C_FUNC_PROTOCOL_MANGLING)) 1247 I2C_FUNC_PROTOCOL_MANGLING))
1247 goto ERROR0; 1248 goto ERROR0;
1248 if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { 1249 if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index b66cb601435f..ddfa04108baf 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -541,7 +541,7 @@ struct i2c_msg {
541 __u16 flags; 541 __u16 flags;
542#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ 542#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
543#define I2C_M_RD 0x0001 /* read data, from slave to master */ 543#define I2C_M_RD 0x0001 /* read data, from slave to master */
544#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ 544#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
545#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ 545#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
546#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ 546#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
547#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ 547#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
@@ -554,8 +554,9 @@ struct i2c_msg {
554 554
555#define I2C_FUNC_I2C 0x00000001 555#define I2C_FUNC_I2C 0x00000001
556#define I2C_FUNC_10BIT_ADDR 0x00000002 556#define I2C_FUNC_10BIT_ADDR 0x00000002
557#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_NOSTART etc. */ 557#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_IGNORE_NAK etc. */
558#define I2C_FUNC_SMBUS_PEC 0x00000008 558#define I2C_FUNC_SMBUS_PEC 0x00000008
559#define I2C_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */
559#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ 560#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
560#define I2C_FUNC_SMBUS_QUICK 0x00010000 561#define I2C_FUNC_SMBUS_QUICK 0x00010000
561#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 562#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000