Lines Matching +full:byte +full:- +full:len
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 i2c-stub.c - I2C/SMBus chip emulator
6 Copyright (C) 2007-2014 Jean Delvare <jdelvare@suse.de>
10 #define pr_fmt(fmt) "i2c-stub: " fmt
47 module_param_array(bank_reg, byte, NULL, S_IRUGO);
51 module_param_array(bank_mask, byte, NULL, S_IRUGO);
55 module_param_array(bank_start, byte, NULL, S_IRUGO);
59 module_param_array(bank_end, byte, NULL, S_IRUGO);
65 u8 len; member
71 u16 words[256]; /* Byte operations use the LSB as per SMBus
95 list_for_each_entry(b, &chip->smbus_blocks, node) { in stub_find_block()
96 if (b->command == command) { in stub_find_block()
105 rb->command = command; in stub_find_block()
106 list_add(&rb->node, &chip->smbus_blocks); in stub_find_block()
113 if (chip->bank_sel && in stub_get_wordp()
114 offset >= chip->bank_start && offset <= chip->bank_end) in stub_get_wordp()
115 return chip->bank_words + in stub_get_wordp()
116 (chip->bank_sel - 1) * chip->bank_size + in stub_get_wordp()
117 offset - chip->bank_start; in stub_get_wordp()
119 return chip->words + offset; in stub_get_wordp()
127 int i, len; in stub_xfer() local
140 return -ENODEV; in stub_xfer()
145 dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr); in stub_xfer()
151 chip->pointer = command; in stub_xfer()
152 dev_dbg(&adap->dev, in stub_xfer()
153 "smbus byte - addr 0x%02x, wrote 0x%02x.\n", in stub_xfer()
156 wordp = stub_get_wordp(chip, chip->pointer++); in stub_xfer()
157 data->byte = *wordp & 0xff; in stub_xfer()
158 dev_dbg(&adap->dev, in stub_xfer()
159 "smbus byte - addr 0x%02x, read 0x%02x.\n", in stub_xfer()
160 addr, data->byte); in stub_xfer()
170 *wordp |= data->byte; in stub_xfer()
171 dev_dbg(&adap->dev, in stub_xfer()
172 "smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n", in stub_xfer()
173 addr, data->byte, command); in stub_xfer()
176 if (chip->bank_words && command == chip->bank_reg) { in stub_xfer()
177 chip->bank_sel = in stub_xfer()
178 (data->byte >> chip->bank_shift) in stub_xfer()
179 & chip->bank_mask; in stub_xfer()
180 dev_dbg(&adap->dev, in stub_xfer()
182 chip->bank_sel); in stub_xfer()
185 data->byte = *wordp & 0xff; in stub_xfer()
186 dev_dbg(&adap->dev, in stub_xfer()
187 "smbus byte data - addr 0x%02x, read 0x%02x at 0x%02x.\n", in stub_xfer()
188 addr, data->byte, command); in stub_xfer()
190 chip->pointer = command + 1; in stub_xfer()
198 *wordp = data->word; in stub_xfer()
199 dev_dbg(&adap->dev, in stub_xfer()
200 "smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n", in stub_xfer()
201 addr, data->word, command); in stub_xfer()
203 data->word = *wordp; in stub_xfer()
204 dev_dbg(&adap->dev, in stub_xfer()
205 "smbus word data - addr 0x%02x, read 0x%04x at 0x%02x.\n", in stub_xfer()
206 addr, data->word, command); in stub_xfer()
217 if (data->block[0] > 256 - command) /* Avoid overrun */ in stub_xfer()
218 data->block[0] = 256 - command; in stub_xfer()
219 len = data->block[0]; in stub_xfer()
221 for (i = 0; i < len; i++) { in stub_xfer()
222 chip->words[command + i] &= 0xff00; in stub_xfer()
223 chip->words[command + i] |= data->block[1 + i]; in stub_xfer()
225 dev_dbg(&adap->dev, in stub_xfer()
226 "i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", in stub_xfer()
227 addr, len, command); in stub_xfer()
229 for (i = 0; i < len; i++) { in stub_xfer()
230 data->block[1 + i] = in stub_xfer()
231 chip->words[command + i] & 0xff; in stub_xfer()
233 dev_dbg(&adap->dev, in stub_xfer()
234 "i2c block data - addr 0x%02x, read %d bytes at 0x%02x.\n", in stub_xfer()
235 addr, len, command); in stub_xfer()
246 b = stub_find_block(&adap->dev, chip, command, false); in stub_xfer()
248 len = data->block[0]; in stub_xfer()
249 if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) { in stub_xfer()
250 ret = -EINVAL; in stub_xfer()
254 b = stub_find_block(&adap->dev, chip, command, in stub_xfer()
257 ret = -ENOMEM; in stub_xfer()
262 if (len > b->len) in stub_xfer()
263 b->len = len; in stub_xfer()
264 for (i = 0; i < len; i++) in stub_xfer()
265 b->block[i] = data->block[i + 1]; in stub_xfer()
266 /* update for byte and word commands */ in stub_xfer()
267 chip->words[command] = (b->block[0] << 8) | b->len; in stub_xfer()
268 dev_dbg(&adap->dev, in stub_xfer()
269 "smbus block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", in stub_xfer()
270 addr, len, command); in stub_xfer()
273 dev_dbg(&adap->dev, in stub_xfer()
275 ret = -EOPNOTSUPP; in stub_xfer()
278 len = b->len; in stub_xfer()
279 data->block[0] = len; in stub_xfer()
280 for (i = 0; i < len; i++) in stub_xfer()
281 data->block[i + 1] = b->block[i]; in stub_xfer()
282 dev_dbg(&adap->dev, in stub_xfer()
283 "smbus block data - addr 0x%02x, read %d bytes at 0x%02x.\n", in stub_xfer()
284 addr, len, command); in stub_xfer()
291 dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); in stub_xfer()
292 ret = -EOPNOTSUPP; in stub_xfer()
320 chip->bank_reg = bank_reg[i]; in i2c_stub_allocate_banks()
321 chip->bank_start = bank_start[i]; in i2c_stub_allocate_banks()
322 chip->bank_end = bank_end[i]; in i2c_stub_allocate_banks()
323 chip->bank_size = bank_end[i] - bank_start[i] + 1; in i2c_stub_allocate_banks()
326 chip->bank_mask = bank_mask[i]; in i2c_stub_allocate_banks()
327 while (!(chip->bank_mask & 1)) { in i2c_stub_allocate_banks()
328 chip->bank_shift++; in i2c_stub_allocate_banks()
329 chip->bank_mask >>= 1; in i2c_stub_allocate_banks()
332 chip->bank_words = kcalloc(chip->bank_mask * chip->bank_size, in i2c_stub_allocate_banks()
335 if (!chip->bank_words) in i2c_stub_allocate_banks()
336 return -ENOMEM; in i2c_stub_allocate_banks()
339 chip->bank_mask, chip->bank_size, chip->bank_start, in i2c_stub_allocate_banks()
340 chip->bank_end); in i2c_stub_allocate_banks()
360 return -ENODEV; in i2c_stub_init()
367 return -EINVAL; in i2c_stub_init()
378 return -ENOMEM; in i2c_stub_init()