aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-stub.c')
-rw-r--r--drivers/i2c/busses/i2c-stub.c34
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);
35MODULE_PARM_DESC(chip_addr, 35MODULE_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
38static unsigned long functionality = ~0UL;
39module_param(functionality, ulong, S_IRUGO | S_IWUSR);
40MODULE_PARM_DESC(functionality, "Override functionality bitfield");
41
38struct stub_chip { 42struct 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
130static u32 stub_func(struct i2c_adapter *adapter) 157static 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
136static const struct i2c_algorithm smbus_algorithm = { 164static const struct i2c_algorithm smbus_algorithm = {