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>
11 #define pr_fmt(fmt) "i2c-stub: " fmt
48 module_param_array(bank_reg, byte, NULL, S_IRUGO);
52 module_param_array(bank_mask, byte, NULL, S_IRUGO);
56 module_param_array(bank_start, byte, NULL, S_IRUGO);
60 module_param_array(bank_end, byte, NULL, S_IRUGO);
66 u8 len; member
72 u16 words[256]; /* Byte operations use the LSB as per SMBus
96 list_for_each_entry(b, &chip->smbus_blocks, node) { in stub_find_block()
97 if (b->command == command) { in stub_find_block()
106 rb->command = command; in stub_find_block()
107 list_add(&rb->node, &chip->smbus_blocks); in stub_find_block()
114 if (chip->bank_sel && in stub_get_wordp()
115 offset >= chip->bank_start && offset <= chip->bank_end) in stub_get_wordp()
116 return chip->bank_words + in stub_get_wordp()
117 (chip->bank_sel - 1) * chip->bank_size + in stub_get_wordp()
118 offset - chip->bank_start; in stub_get_wordp()
120 return chip->words + offset; in stub_get_wordp()
128 int i, len; in stub_xfer() local
141 return -ENODEV; in stub_xfer()
146 dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr); in stub_xfer()
152 chip->pointer = command; in stub_xfer()
153 dev_dbg(&adap->dev, in stub_xfer()
154 "smbus byte - addr 0x%02x, wrote 0x%02x.\n", in stub_xfer()
157 wordp = stub_get_wordp(chip, chip->pointer++); in stub_xfer()
158 data->byte = *wordp & 0xff; in stub_xfer()
159 dev_dbg(&adap->dev, in stub_xfer()
160 "smbus byte - addr 0x%02x, read 0x%02x.\n", in stub_xfer()
161 addr, data->byte); in stub_xfer()
171 *wordp |= data->byte; in stub_xfer()
172 dev_dbg(&adap->dev, in stub_xfer()
173 "smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n", in stub_xfer()
174 addr, data->byte, command); in stub_xfer()
177 if (chip->bank_words && command == chip->bank_reg) { in stub_xfer()
178 chip->bank_sel = in stub_xfer()
179 (data->byte >> chip->bank_shift) in stub_xfer()
180 & chip->bank_mask; in stub_xfer()
181 dev_dbg(&adap->dev, in stub_xfer()
183 chip->bank_sel); in stub_xfer()
186 data->byte = *wordp & 0xff; in stub_xfer()
187 dev_dbg(&adap->dev, in stub_xfer()
188 "smbus byte data - addr 0x%02x, read 0x%02x at 0x%02x.\n", in stub_xfer()
189 addr, data->byte, command); in stub_xfer()
191 chip->pointer = command + 1; in stub_xfer()
199 *wordp = data->word; in stub_xfer()
200 dev_dbg(&adap->dev, in stub_xfer()
201 "smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n", in stub_xfer()
202 addr, data->word, command); in stub_xfer()
204 data->word = *wordp; in stub_xfer()
205 dev_dbg(&adap->dev, in stub_xfer()
206 "smbus word data - addr 0x%02x, read 0x%04x at 0x%02x.\n", in stub_xfer()
207 addr, data->word, command); in stub_xfer()
218 if (data->block[0] > 256 - command) /* Avoid overrun */ in stub_xfer()
219 data->block[0] = 256 - command; in stub_xfer()
220 len = data->block[0]; in stub_xfer()
222 for (i = 0; i < len; i++) { in stub_xfer()
223 chip->words[command + i] &= 0xff00; in stub_xfer()
224 chip->words[command + i] |= data->block[1 + i]; in stub_xfer()
226 dev_dbg(&adap->dev, in stub_xfer()
227 "i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", in stub_xfer()
228 addr, len, command); in stub_xfer()
230 for (i = 0; i < len; i++) { in stub_xfer()
231 data->block[1 + i] = in stub_xfer()
232 chip->words[command + i] & 0xff; in stub_xfer()
234 dev_dbg(&adap->dev, in stub_xfer()
235 "i2c block data - addr 0x%02x, read %d bytes at 0x%02x.\n", in stub_xfer()
236 addr, len, command); in stub_xfer()
247 b = stub_find_block(&adap->dev, chip, command, false); in stub_xfer()
249 len = data->block[0]; in stub_xfer()
250 if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) { in stub_xfer()
251 ret = -EINVAL; in stub_xfer()
255 b = stub_find_block(&adap->dev, chip, command, in stub_xfer()
258 ret = -ENOMEM; in stub_xfer()
263 if (len > b->len) in stub_xfer()
264 b->len = len; in stub_xfer()
265 for (i = 0; i < len; i++) in stub_xfer()
266 b->block[i] = data->block[i + 1]; in stub_xfer()
267 /* update for byte and word commands */ in stub_xfer()
268 chip->words[command] = (b->block[0] << 8) | b->len; in stub_xfer()
269 dev_dbg(&adap->dev, in stub_xfer()
270 "smbus block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", in stub_xfer()
271 addr, len, command); in stub_xfer()
274 dev_dbg(&adap->dev, in stub_xfer()
276 ret = -EOPNOTSUPP; in stub_xfer()
279 len = b->len; in stub_xfer()
280 data->block[0] = len; in stub_xfer()
281 for (i = 0; i < len; i++) in stub_xfer()
282 data->block[i + 1] = b->block[i]; in stub_xfer()
283 dev_dbg(&adap->dev, in stub_xfer()
284 "smbus block data - addr 0x%02x, read %d bytes at 0x%02x.\n", in stub_xfer()
285 addr, len, command); in stub_xfer()
292 dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); in stub_xfer()
293 ret = -EOPNOTSUPP; in stub_xfer()
321 chip->bank_reg = bank_reg[i]; in i2c_stub_allocate_banks()
322 chip->bank_start = bank_start[i]; in i2c_stub_allocate_banks()
323 chip->bank_end = bank_end[i]; in i2c_stub_allocate_banks()
324 chip->bank_size = bank_end[i] - bank_start[i] + 1; in i2c_stub_allocate_banks()
327 chip->bank_mask = bank_mask[i]; in i2c_stub_allocate_banks()
328 while (!(chip->bank_mask & 1)) { in i2c_stub_allocate_banks()
329 chip->bank_shift++; in i2c_stub_allocate_banks()
330 chip->bank_mask >>= 1; in i2c_stub_allocate_banks()
333 chip->bank_words = kcalloc(chip->bank_mask * chip->bank_size, in i2c_stub_allocate_banks()
336 if (!chip->bank_words) in i2c_stub_allocate_banks()
337 return -ENOMEM; in i2c_stub_allocate_banks()
340 chip->bank_mask, chip->bank_size, chip->bank_start, in i2c_stub_allocate_banks()
341 chip->bank_end); in i2c_stub_allocate_banks()
361 return -ENODEV; in i2c_stub_init()
368 return -EINVAL; in i2c_stub_init()
379 return -ENOMEM; in i2c_stub_init()