diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-stub.c')
-rw-r--r-- | drivers/i2c/busses/i2c-stub.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c index 1b7b2af94036..0c770eabe85e 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/busses/i2c-stub.c | |||
@@ -35,6 +35,10 @@ module_param_array(chip_addr, ushort, NULL, S_IRUGO); | |||
35 | MODULE_PARM_DESC(chip_addr, | 35 | MODULE_PARM_DESC(chip_addr, |
36 | "Chip addresses (up to 10, between 0x03 and 0x77)"); | 36 | "Chip addresses (up to 10, between 0x03 and 0x77)"); |
37 | 37 | ||
38 | static unsigned long functionality = ~0UL; | ||
39 | module_param(functionality, ulong, S_IRUGO | S_IWUSR); | ||
40 | MODULE_PARM_DESC(functionality, "Override functionality bitfield"); | ||
41 | |||
38 | struct stub_chip { | 42 | struct stub_chip { |
39 | u8 pointer; | 43 | u8 pointer; |
40 | u16 words[256]; /* Byte operations use the LSB as per SMBus | 44 | u16 words[256]; /* Byte operations use the LSB as per SMBus |
@@ -48,7 +52,7 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
48 | char read_write, u8 command, int size, union i2c_smbus_data * data) | 52 | char read_write, u8 command, int size, union i2c_smbus_data * data) |
49 | { | 53 | { |
50 | s32 ret; | 54 | s32 ret; |
51 | int i; | 55 | int i, len; |
52 | struct stub_chip *chip = NULL; | 56 | struct stub_chip *chip = NULL; |
53 | 57 | ||
54 | /* Search for the right chip */ | 58 | /* Search for the right chip */ |
@@ -118,6 +122,29 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
118 | ret = 0; | 122 | ret = 0; |
119 | break; | 123 | break; |
120 | 124 | ||
125 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
126 | len = data->block[0]; | ||
127 | if (read_write == I2C_SMBUS_WRITE) { | ||
128 | for (i = 0; i < len; i++) { | ||
129 | chip->words[command + i] &= 0xff00; | ||
130 | chip->words[command + i] |= data->block[1 + i]; | ||
131 | } | ||
132 | dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | ||
133 | "wrote %d bytes at 0x%02x.\n", | ||
134 | addr, len, command); | ||
135 | } else { | ||
136 | for (i = 0; i < len; i++) { | ||
137 | data->block[1 + i] = | ||
138 | chip->words[command + i] & 0xff; | ||
139 | } | ||
140 | dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | ||
141 | "read %d bytes at 0x%02x.\n", | ||
142 | addr, len, command); | ||
143 | } | ||
144 | |||
145 | ret = 0; | ||
146 | break; | ||
147 | |||
121 | default: | 148 | default: |
122 | dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); | 149 | dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); |
123 | ret = -EOPNOTSUPP; | 150 | ret = -EOPNOTSUPP; |
@@ -129,8 +156,9 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
129 | 156 | ||
130 | static u32 stub_func(struct i2c_adapter *adapter) | 157 | static u32 stub_func(struct i2c_adapter *adapter) |
131 | { | 158 | { |
132 | return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | 159 | return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
133 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA; | 160 | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
161 | I2C_FUNC_SMBUS_I2C_BLOCK) & functionality; | ||
134 | } | 162 | } |
135 | 163 | ||
136 | static const struct i2c_algorithm smbus_algorithm = { | 164 | static const struct i2c_algorithm smbus_algorithm = { |