#define DEBUG 1
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/i2c.h>
+static unsigned short chip_addr;
+module_param(chip_addr, ushort, S_IRUGO);
+MODULE_PARM_DESC(chip_addr, "Chip address (between 0x03 and 0x77)\n");
+
+static u8 stub_pointer;
static u8 stub_bytes[256];
static u16 stub_words[256];
{
s32 ret;
+ if (addr != chip_addr)
+ return -ENODEV;
+
switch (size) {
case I2C_SMBUS_QUICK:
ret = 0;
break;
+ case I2C_SMBUS_BYTE:
+ if (read_write == I2C_SMBUS_WRITE) {
+ stub_pointer = command;
+ dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
+ "wrote 0x%02x.\n",
+ addr, command);
+ } else {
+ data->byte = stub_bytes[stub_pointer++];
+ dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
+ "read 0x%02x.\n",
+ addr, data->byte);
+ }
+
+ ret = 0;
+ break;
+
case I2C_SMBUS_BYTE_DATA:
if (read_write == I2C_SMBUS_WRITE) {
stub_bytes[command] = data->byte;
"read 0x%02x at 0x%02x.\n",
addr, data->byte, command);
}
+ stub_pointer = command + 1;
ret = 0;
break;
static u32 stub_func(struct i2c_adapter *adapter)
{
- return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE_DATA |
- I2C_FUNC_SMBUS_WORD_DATA;
+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
}
-static struct i2c_algorithm smbus_algorithm = {
- .name = "Non-I2C SMBus adapter",
- .id = I2C_ALGO_SMBUS,
+static const struct i2c_algorithm smbus_algorithm = {
.functionality = stub_func,
.smbus_xfer = stub_xfer,
};
static int __init i2c_stub_init(void)
{
- printk(KERN_INFO "i2c-stub loaded\n");
+ if (!chip_addr) {
+ printk(KERN_ERR "i2c-stub: Please specify a chip address\n");
+ return -ENODEV;
+ }
+ if (chip_addr < 0x03 || chip_addr > 0x77) {
+ printk(KERN_ERR "i2c-stub: Invalid chip address 0x%02x\n",
+ chip_addr);
+ return -EINVAL;
+ }
+
+ printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", chip_addr);
return i2c_add_adapter(&stub_adapter);
}