diff options
-rw-r--r-- | Documentation/i2c/i2c-stub | 15 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-stub.c | 19 |
2 files changed, 31 insertions, 3 deletions
diff --git a/Documentation/i2c/i2c-stub b/Documentation/i2c/i2c-stub index d6dcb138abf5..9cc081e69764 100644 --- a/Documentation/i2c/i2c-stub +++ b/Documentation/i2c/i2c-stub | |||
@@ -6,9 +6,12 @@ This module is a very simple fake I2C/SMBus driver. It implements four | |||
6 | types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, and | 6 | types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, and |
7 | (r/w) word data. | 7 | (r/w) word data. |
8 | 8 | ||
9 | You need to provide a chip address as a module parameter when loading | ||
10 | this driver, which will then only react to SMBus commands to this address. | ||
11 | |||
9 | No hardware is needed nor associated with this module. It will accept write | 12 | No hardware is needed nor associated with this module. It will accept write |
10 | quick commands to all addresses; it will respond to the other commands (also | 13 | quick commands to one address; it will respond to the other commands (also |
11 | to all addresses) by reading from or writing to an array in memory. It will | 14 | to one address) by reading from or writing to an array in memory. It will |
12 | also spam the kernel logs for every command it handles. | 15 | also spam the kernel logs for every command it handles. |
13 | 16 | ||
14 | A pointer register with auto-increment is implemented for all byte | 17 | A pointer register with auto-increment is implemented for all byte |
@@ -21,6 +24,11 @@ The typical use-case is like this: | |||
21 | 3. load the target sensors chip driver module | 24 | 3. load the target sensors chip driver module |
22 | 4. observe its behavior in the kernel log | 25 | 4. observe its behavior in the kernel log |
23 | 26 | ||
27 | PARAMETERS: | ||
28 | |||
29 | int chip_addr: | ||
30 | The SMBus address to emulate a chip at. | ||
31 | |||
24 | CAVEATS: | 32 | CAVEATS: |
25 | 33 | ||
26 | There are independent arrays for byte/data and word/data commands. Depending | 34 | There are independent arrays for byte/data and word/data commands. Depending |
@@ -33,6 +41,9 @@ If the hardware for your driver has banked registers (e.g. Winbond sensors | |||
33 | chips) this module will not work well - although it could be extended to | 41 | chips) this module will not work well - although it could be extended to |
34 | support that pretty easily. | 42 | support that pretty easily. |
35 | 43 | ||
44 | Only one chip address is supported - although this module could be | ||
45 | extended to support more. | ||
46 | |||
36 | If you spam it hard enough, printk can be lossy. This module really wants | 47 | If you spam it hard enough, printk can be lossy. This module really wants |
37 | something like relayfs. | 48 | something like relayfs. |
38 | 49 | ||
diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c index 73f481e93a36..8cf374ddd989 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/busses/i2c-stub.c | |||
@@ -27,6 +27,10 @@ | |||
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | 29 | ||
30 | static unsigned short chip_addr; | ||
31 | module_param(chip_addr, ushort, S_IRUGO); | ||
32 | MODULE_PARM_DESC(chip_addr, "Chip address (between 0x03 and 0x77)\n"); | ||
33 | |||
30 | static u8 stub_pointer; | 34 | static u8 stub_pointer; |
31 | static u8 stub_bytes[256]; | 35 | static u8 stub_bytes[256]; |
32 | static u16 stub_words[256]; | 36 | static u16 stub_words[256]; |
@@ -37,6 +41,9 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |||
37 | { | 41 | { |
38 | s32 ret; | 42 | s32 ret; |
39 | 43 | ||
44 | if (addr != chip_addr) | ||
45 | return -ENODEV; | ||
46 | |||
40 | switch (size) { | 47 | switch (size) { |
41 | 48 | ||
42 | case I2C_SMBUS_QUICK: | 49 | case I2C_SMBUS_QUICK: |
@@ -122,7 +129,17 @@ static struct i2c_adapter stub_adapter = { | |||
122 | 129 | ||
123 | static int __init i2c_stub_init(void) | 130 | static int __init i2c_stub_init(void) |
124 | { | 131 | { |
125 | printk(KERN_INFO "i2c-stub loaded\n"); | 132 | if (!chip_addr) { |
133 | printk(KERN_ERR "i2c-stub: Please specify a chip address\n"); | ||
134 | return -ENODEV; | ||
135 | } | ||
136 | if (chip_addr < 0x03 || chip_addr > 0x77) { | ||
137 | printk(KERN_ERR "i2c-stub: Invalid chip address 0x%02x\n", | ||
138 | chip_addr); | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | |||
142 | printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", chip_addr); | ||
126 | return i2c_add_adapter(&stub_adapter); | 143 | return i2c_add_adapter(&stub_adapter); |
127 | } | 144 | } |
128 | 145 | ||