Commit 14674e70 authored by Mark Brown's avatar Mark Brown Committed by Jean Delvare

i2c: Split I2C_M_NOSTART support out of I2C_FUNC_PROTOCOL_MANGLING

Since there are uses for I2C_M_NOSTART which are much more sensible and
standard than most of the protocol mangling functionality (the main one
being gather writes to devices where something like a register address
needs to be inserted before a block of data) create a new I2C_FUNC_NOSTART
for this feature and update all the users to use it.

Also strengthen the disrecommendation of the protocol mangling while we're
at it.

In the case of regmap-i2c we remove the requirement for mangling as
I2C_M_NOSTART is the only mangling feature which is being used.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarWolfram Sang <w.sang@pengutronix.de>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 838bfa60
...@@ -18,9 +18,9 @@ For the most up-to-date list of functionality constants, please check ...@@ -18,9 +18,9 @@ For the most up-to-date list of functionality constants, please check
adapters typically can not do these) adapters typically can not do these)
I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions
I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK, I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK,
I2C_M_REV_DIR_ADDR, I2C_M_NOSTART and I2C_M_REV_DIR_ADDR and I2C_M_NO_RD_ACK
I2C_M_NO_RD_ACK flags (which modify the flags (which modify the I2C protocol!)
I2C protocol!) I2C_FUNC_NOSTART Can skip repeated start sequence
I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command
I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command
I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command 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,6 +50,9 @@ A few combinations of the above flags are also defined for your convenience:
emulated by a real I2C adapter (using emulated by a real I2C adapter (using
the transparent emulation layer) the transparent emulation layer)
In kernel versions prior to 3.5 I2C_FUNC_NOSTART was implemented as
part of I2C_FUNC_PROTOCOL_MANGLING.
ADAPTER IMPLEMENTATION ADAPTER IMPLEMENTATION
---------------------- ----------------------
......
...@@ -49,7 +49,9 @@ a byte read, followed by a byte write: ...@@ -49,7 +49,9 @@ a byte read, followed by a byte write:
Modified transactions Modified transactions
===================== =====================
We have found some I2C devices that needs the following modifications: The following modifications to the I2C protocol can also be generated,
with the exception of I2C_M_NOSTART these are usually only needed to
work around device issues:
Flag I2C_M_NOSTART: Flag I2C_M_NOSTART:
In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some 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,6 +62,11 @@ We have found some I2C devices that needs the following modifications:
we do not generate Addr, but we do generate the startbit S. This will we do not generate Addr, but we do generate the startbit S. This will
probably confuse all other clients on your bus, so don't try this. probably confuse all other clients on your bus, so don't try this.
This is often used to gather transmits from multiple data buffers in
system memory into something that appears as a single transfer to the
I2C device but may also be used between direction changes by some
rare devices.
Flags I2C_M_REV_DIR_ADDR Flags I2C_M_REV_DIR_ADDR
This toggles the Rd/Wr flag. That is, if you want to do a write, but This toggles the Rd/Wr flag. That is, if you want to do a write, but
need to emit an Rd instead of a Wr, or vice versa, you set this need to emit an Rd instead of a Wr, or vice versa, you set this
......
...@@ -42,7 +42,7 @@ static int regmap_i2c_gather_write(void *context, ...@@ -42,7 +42,7 @@ static int regmap_i2c_gather_write(void *context,
/* If the I2C controller can't do a gather tell the core, it /* If the I2C controller can't do a gather tell the core, it
* will substitute in a linear write for us. * will substitute in a linear write for us.
*/ */
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_PROTOCOL_MANGLING)) if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_NOSTART))
return -ENOTSUPP; return -ENOTSUPP;
xfer[0].addr = i2c->addr; xfer[0].addr = i2c->addr;
......
...@@ -608,7 +608,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, ...@@ -608,7 +608,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
static u32 bit_func(struct i2c_adapter *adap) static u32 bit_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_READ_BLOCK_DATA |
I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
......
...@@ -502,7 +502,8 @@ static int nuc900_i2c_xfer(struct i2c_adapter *adap, ...@@ -502,7 +502,8 @@ static int nuc900_i2c_xfer(struct i2c_adapter *adap,
/* declare our i2c functionality */ /* declare our i2c functionality */
static u32 nuc900_i2c_func(struct i2c_adapter *adap) static u32 nuc900_i2c_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |
I2C_FUNC_PROTOCOL_MANGLING;
} }
/* i2c bus registration info */ /* i2c bus registration info */
......
...@@ -626,7 +626,8 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, ...@@ -626,7 +626,8 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
/* declare our i2c functionality */ /* declare our i2c functionality */
static u32 s3c24xx_i2c_func(struct i2c_adapter *adap) static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART |
I2C_FUNC_PROTOCOL_MANGLING;
} }
/* i2c bus registration info */ /* i2c bus registration info */
......
...@@ -231,6 +231,7 @@ static int __devinit as5011_probe(struct i2c_client *client, ...@@ -231,6 +231,7 @@ static int __devinit as5011_probe(struct i2c_client *client,
} }
if (!i2c_check_functionality(client->adapter, if (!i2c_check_functionality(client->adapter,
I2C_FUNC_NOSTART |
I2C_FUNC_PROTOCOL_MANGLING)) { I2C_FUNC_PROTOCOL_MANGLING)) {
dev_err(&client->dev, dev_err(&client->dev,
"need i2c bus that supports protocol mangling\n"); "need i2c bus that supports protocol mangling\n");
......
...@@ -1243,6 +1243,7 @@ static int maven_probe(struct i2c_client *client, ...@@ -1243,6 +1243,7 @@ static int maven_probe(struct i2c_client *client,
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_NOSTART |
I2C_FUNC_PROTOCOL_MANGLING)) I2C_FUNC_PROTOCOL_MANGLING))
goto ERROR0; goto ERROR0;
if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
......
...@@ -541,7 +541,7 @@ struct i2c_msg { ...@@ -541,7 +541,7 @@ struct i2c_msg {
__u16 flags; __u16 flags;
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
#define I2C_M_RD 0x0001 /* read data, from slave to master */ #define I2C_M_RD 0x0001 /* read data, from slave to master */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
...@@ -554,8 +554,9 @@ struct i2c_msg { ...@@ -554,8 +554,9 @@ struct i2c_msg {
#define I2C_FUNC_I2C 0x00000001 #define I2C_FUNC_I2C 0x00000001
#define I2C_FUNC_10BIT_ADDR 0x00000002 #define I2C_FUNC_10BIT_ADDR 0x00000002
#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_NOSTART etc. */ #define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_IGNORE_NAK etc. */
#define I2C_FUNC_SMBUS_PEC 0x00000008 #define I2C_FUNC_SMBUS_PEC 0x00000008
#define I2C_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */
#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
#define I2C_FUNC_SMBUS_QUICK 0x00010000 #define I2C_FUNC_SMBUS_QUICK 0x00010000
#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 #define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment