Commit 31d178bffcff4c468c8c65bc42d9f4c0a7b8e3ec
Committed by
Jean Delvare
1 parent
e657e078d3
Exists in
master
and in
20 other branches
i2c-stub: Move to drivers/i2c
Move the i2c-stub driver to drivers/i2c, to match the Kconfig entry. This is less confusing that way. I also fixed all checkpatch warnings and errors. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Peter Huewe <peterhuewe@gmx.de>
Showing 4 changed files with 221 additions and 223 deletions Side-by-side Diff
drivers/i2c/Makefile
drivers/i2c/busses/Makefile
... | ... | @@ -85,7 +85,6 @@ |
85 | 85 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o |
86 | 86 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o |
87 | 87 | obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o |
88 | -obj-$(CONFIG_I2C_STUB) += i2c-stub.o | |
89 | 88 | obj-$(CONFIG_SCx200_ACB) += scx200_acb.o |
90 | 89 | obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o |
91 | 90 |
drivers/i2c/busses/i2c-stub.c
1 | -/* | |
2 | - i2c-stub.c - I2C/SMBus chip emulator | |
3 | - | |
4 | - Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> | |
5 | - Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> | |
6 | - | |
7 | - This program is free software; you can redistribute it and/or modify | |
8 | - it under the terms of the GNU General Public License as published by | |
9 | - the Free Software Foundation; either version 2 of the License, or | |
10 | - (at your option) any later version. | |
11 | - | |
12 | - This program is distributed in the hope that it will be useful, | |
13 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | - GNU General Public License for more details. | |
16 | - | |
17 | - You should have received a copy of the GNU General Public License | |
18 | - along with this program; if not, write to the Free Software | |
19 | - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
20 | -*/ | |
21 | - | |
22 | -#define DEBUG 1 | |
23 | - | |
24 | -#include <linux/init.h> | |
25 | -#include <linux/module.h> | |
26 | -#include <linux/kernel.h> | |
27 | -#include <linux/slab.h> | |
28 | -#include <linux/errno.h> | |
29 | -#include <linux/i2c.h> | |
30 | - | |
31 | -#define MAX_CHIPS 10 | |
32 | -#define STUB_FUNC (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | \ | |
33 | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | \ | |
34 | - I2C_FUNC_SMBUS_I2C_BLOCK) | |
35 | - | |
36 | -static unsigned short chip_addr[MAX_CHIPS]; | |
37 | -module_param_array(chip_addr, ushort, NULL, S_IRUGO); | |
38 | -MODULE_PARM_DESC(chip_addr, | |
39 | - "Chip addresses (up to 10, between 0x03 and 0x77)"); | |
40 | - | |
41 | -static unsigned long functionality = STUB_FUNC; | |
42 | -module_param(functionality, ulong, S_IRUGO | S_IWUSR); | |
43 | -MODULE_PARM_DESC(functionality, "Override functionality bitfield"); | |
44 | - | |
45 | -struct stub_chip { | |
46 | - u8 pointer; | |
47 | - u16 words[256]; /* Byte operations use the LSB as per SMBus | |
48 | - specification */ | |
49 | -}; | |
50 | - | |
51 | -static struct stub_chip *stub_chips; | |
52 | - | |
53 | -/* Return negative errno on error. */ | |
54 | -static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |
55 | - char read_write, u8 command, int size, union i2c_smbus_data * data) | |
56 | -{ | |
57 | - s32 ret; | |
58 | - int i, len; | |
59 | - struct stub_chip *chip = NULL; | |
60 | - | |
61 | - /* Search for the right chip */ | |
62 | - for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { | |
63 | - if (addr == chip_addr[i]) { | |
64 | - chip = stub_chips + i; | |
65 | - break; | |
66 | - } | |
67 | - } | |
68 | - if (!chip) | |
69 | - return -ENODEV; | |
70 | - | |
71 | - switch (size) { | |
72 | - | |
73 | - case I2C_SMBUS_QUICK: | |
74 | - dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr); | |
75 | - ret = 0; | |
76 | - break; | |
77 | - | |
78 | - case I2C_SMBUS_BYTE: | |
79 | - if (read_write == I2C_SMBUS_WRITE) { | |
80 | - chip->pointer = command; | |
81 | - dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " | |
82 | - "wrote 0x%02x.\n", | |
83 | - addr, command); | |
84 | - } else { | |
85 | - data->byte = chip->words[chip->pointer++] & 0xff; | |
86 | - dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " | |
87 | - "read 0x%02x.\n", | |
88 | - addr, data->byte); | |
89 | - } | |
90 | - | |
91 | - ret = 0; | |
92 | - break; | |
93 | - | |
94 | - case I2C_SMBUS_BYTE_DATA: | |
95 | - if (read_write == I2C_SMBUS_WRITE) { | |
96 | - chip->words[command] &= 0xff00; | |
97 | - chip->words[command] |= data->byte; | |
98 | - dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | |
99 | - "wrote 0x%02x at 0x%02x.\n", | |
100 | - addr, data->byte, command); | |
101 | - } else { | |
102 | - data->byte = chip->words[command] & 0xff; | |
103 | - dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | |
104 | - "read 0x%02x at 0x%02x.\n", | |
105 | - addr, data->byte, command); | |
106 | - } | |
107 | - chip->pointer = command + 1; | |
108 | - | |
109 | - ret = 0; | |
110 | - break; | |
111 | - | |
112 | - case I2C_SMBUS_WORD_DATA: | |
113 | - if (read_write == I2C_SMBUS_WRITE) { | |
114 | - chip->words[command] = data->word; | |
115 | - dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " | |
116 | - "wrote 0x%04x at 0x%02x.\n", | |
117 | - addr, data->word, command); | |
118 | - } else { | |
119 | - data->word = chip->words[command]; | |
120 | - dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " | |
121 | - "read 0x%04x at 0x%02x.\n", | |
122 | - addr, data->word, command); | |
123 | - } | |
124 | - | |
125 | - ret = 0; | |
126 | - break; | |
127 | - | |
128 | - case I2C_SMBUS_I2C_BLOCK_DATA: | |
129 | - len = data->block[0]; | |
130 | - if (read_write == I2C_SMBUS_WRITE) { | |
131 | - for (i = 0; i < len; i++) { | |
132 | - chip->words[command + i] &= 0xff00; | |
133 | - chip->words[command + i] |= data->block[1 + i]; | |
134 | - } | |
135 | - dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | |
136 | - "wrote %d bytes at 0x%02x.\n", | |
137 | - addr, len, command); | |
138 | - } else { | |
139 | - for (i = 0; i < len; i++) { | |
140 | - data->block[1 + i] = | |
141 | - chip->words[command + i] & 0xff; | |
142 | - } | |
143 | - dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | |
144 | - "read %d bytes at 0x%02x.\n", | |
145 | - addr, len, command); | |
146 | - } | |
147 | - | |
148 | - ret = 0; | |
149 | - break; | |
150 | - | |
151 | - default: | |
152 | - dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); | |
153 | - ret = -EOPNOTSUPP; | |
154 | - break; | |
155 | - } /* switch (size) */ | |
156 | - | |
157 | - return ret; | |
158 | -} | |
159 | - | |
160 | -static u32 stub_func(struct i2c_adapter *adapter) | |
161 | -{ | |
162 | - return STUB_FUNC & functionality; | |
163 | -} | |
164 | - | |
165 | -static const struct i2c_algorithm smbus_algorithm = { | |
166 | - .functionality = stub_func, | |
167 | - .smbus_xfer = stub_xfer, | |
168 | -}; | |
169 | - | |
170 | -static struct i2c_adapter stub_adapter = { | |
171 | - .owner = THIS_MODULE, | |
172 | - .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, | |
173 | - .algo = &smbus_algorithm, | |
174 | - .name = "SMBus stub driver", | |
175 | -}; | |
176 | - | |
177 | -static int __init i2c_stub_init(void) | |
178 | -{ | |
179 | - int i, ret; | |
180 | - | |
181 | - if (!chip_addr[0]) { | |
182 | - printk(KERN_ERR "i2c-stub: Please specify a chip address\n"); | |
183 | - return -ENODEV; | |
184 | - } | |
185 | - | |
186 | - for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { | |
187 | - if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { | |
188 | - printk(KERN_ERR "i2c-stub: Invalid chip address " | |
189 | - "0x%02x\n", chip_addr[i]); | |
190 | - return -EINVAL; | |
191 | - } | |
192 | - | |
193 | - printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", | |
194 | - chip_addr[i]); | |
195 | - } | |
196 | - | |
197 | - /* Allocate memory for all chips at once */ | |
198 | - stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); | |
199 | - if (!stub_chips) { | |
200 | - printk(KERN_ERR "i2c-stub: Out of memory\n"); | |
201 | - return -ENOMEM; | |
202 | - } | |
203 | - | |
204 | - ret = i2c_add_adapter(&stub_adapter); | |
205 | - if (ret) | |
206 | - kfree(stub_chips); | |
207 | - return ret; | |
208 | -} | |
209 | - | |
210 | -static void __exit i2c_stub_exit(void) | |
211 | -{ | |
212 | - i2c_del_adapter(&stub_adapter); | |
213 | - kfree(stub_chips); | |
214 | -} | |
215 | - | |
216 | -MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); | |
217 | -MODULE_DESCRIPTION("I2C stub driver"); | |
218 | -MODULE_LICENSE("GPL"); | |
219 | - | |
220 | -module_init(i2c_stub_init); | |
221 | -module_exit(i2c_stub_exit); |
drivers/i2c/i2c-stub.c
1 | +/* | |
2 | + i2c-stub.c - I2C/SMBus chip emulator | |
3 | + | |
4 | + Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> | |
5 | + Copyright (C) 2007, 2012 Jean Delvare <khali@linux-fr.org> | |
6 | + | |
7 | + This program is free software; you can redistribute it and/or modify | |
8 | + it under the terms of the GNU General Public License as published by | |
9 | + the Free Software Foundation; either version 2 of the License, or | |
10 | + (at your option) any later version. | |
11 | + | |
12 | + This program is distributed in the hope that it will be useful, | |
13 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | + GNU General Public License for more details. | |
16 | + | |
17 | + You should have received a copy of the GNU General Public License | |
18 | + along with this program; if not, write to the Free Software | |
19 | + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
20 | +*/ | |
21 | + | |
22 | +#define DEBUG 1 | |
23 | + | |
24 | +#include <linux/init.h> | |
25 | +#include <linux/module.h> | |
26 | +#include <linux/kernel.h> | |
27 | +#include <linux/slab.h> | |
28 | +#include <linux/errno.h> | |
29 | +#include <linux/i2c.h> | |
30 | + | |
31 | +#define MAX_CHIPS 10 | |
32 | +#define STUB_FUNC (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | \ | |
33 | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | \ | |
34 | + I2C_FUNC_SMBUS_I2C_BLOCK) | |
35 | + | |
36 | +static unsigned short chip_addr[MAX_CHIPS]; | |
37 | +module_param_array(chip_addr, ushort, NULL, S_IRUGO); | |
38 | +MODULE_PARM_DESC(chip_addr, | |
39 | + "Chip addresses (up to 10, between 0x03 and 0x77)"); | |
40 | + | |
41 | +static unsigned long functionality = STUB_FUNC; | |
42 | +module_param(functionality, ulong, S_IRUGO | S_IWUSR); | |
43 | +MODULE_PARM_DESC(functionality, "Override functionality bitfield"); | |
44 | + | |
45 | +struct stub_chip { | |
46 | + u8 pointer; | |
47 | + u16 words[256]; /* Byte operations use the LSB as per SMBus | |
48 | + specification */ | |
49 | +}; | |
50 | + | |
51 | +static struct stub_chip *stub_chips; | |
52 | + | |
53 | +/* Return negative errno on error. */ | |
54 | +static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, | |
55 | + char read_write, u8 command, int size, union i2c_smbus_data *data) | |
56 | +{ | |
57 | + s32 ret; | |
58 | + int i, len; | |
59 | + struct stub_chip *chip = NULL; | |
60 | + | |
61 | + /* Search for the right chip */ | |
62 | + for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { | |
63 | + if (addr == chip_addr[i]) { | |
64 | + chip = stub_chips + i; | |
65 | + break; | |
66 | + } | |
67 | + } | |
68 | + if (!chip) | |
69 | + return -ENODEV; | |
70 | + | |
71 | + switch (size) { | |
72 | + | |
73 | + case I2C_SMBUS_QUICK: | |
74 | + dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr); | |
75 | + ret = 0; | |
76 | + break; | |
77 | + | |
78 | + case I2C_SMBUS_BYTE: | |
79 | + if (read_write == I2C_SMBUS_WRITE) { | |
80 | + chip->pointer = command; | |
81 | + dev_dbg(&adap->dev, | |
82 | + "smbus byte - addr 0x%02x, wrote 0x%02x.\n", | |
83 | + addr, command); | |
84 | + } else { | |
85 | + data->byte = chip->words[chip->pointer++] & 0xff; | |
86 | + dev_dbg(&adap->dev, | |
87 | + "smbus byte - addr 0x%02x, read 0x%02x.\n", | |
88 | + addr, data->byte); | |
89 | + } | |
90 | + | |
91 | + ret = 0; | |
92 | + break; | |
93 | + | |
94 | + case I2C_SMBUS_BYTE_DATA: | |
95 | + if (read_write == I2C_SMBUS_WRITE) { | |
96 | + chip->words[command] &= 0xff00; | |
97 | + chip->words[command] |= data->byte; | |
98 | + dev_dbg(&adap->dev, | |
99 | + "smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n", | |
100 | + addr, data->byte, command); | |
101 | + } else { | |
102 | + data->byte = chip->words[command] & 0xff; | |
103 | + dev_dbg(&adap->dev, | |
104 | + "smbus byte data - addr 0x%02x, read 0x%02x at 0x%02x.\n", | |
105 | + addr, data->byte, command); | |
106 | + } | |
107 | + chip->pointer = command + 1; | |
108 | + | |
109 | + ret = 0; | |
110 | + break; | |
111 | + | |
112 | + case I2C_SMBUS_WORD_DATA: | |
113 | + if (read_write == I2C_SMBUS_WRITE) { | |
114 | + chip->words[command] = data->word; | |
115 | + dev_dbg(&adap->dev, | |
116 | + "smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n", | |
117 | + addr, data->word, command); | |
118 | + } else { | |
119 | + data->word = chip->words[command]; | |
120 | + dev_dbg(&adap->dev, | |
121 | + "smbus word data - addr 0x%02x, read 0x%04x at 0x%02x.\n", | |
122 | + addr, data->word, command); | |
123 | + } | |
124 | + | |
125 | + ret = 0; | |
126 | + break; | |
127 | + | |
128 | + case I2C_SMBUS_I2C_BLOCK_DATA: | |
129 | + len = data->block[0]; | |
130 | + if (read_write == I2C_SMBUS_WRITE) { | |
131 | + for (i = 0; i < len; i++) { | |
132 | + chip->words[command + i] &= 0xff00; | |
133 | + chip->words[command + i] |= data->block[1 + i]; | |
134 | + } | |
135 | + dev_dbg(&adap->dev, | |
136 | + "i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", | |
137 | + addr, len, command); | |
138 | + } else { | |
139 | + for (i = 0; i < len; i++) { | |
140 | + data->block[1 + i] = | |
141 | + chip->words[command + i] & 0xff; | |
142 | + } | |
143 | + dev_dbg(&adap->dev, | |
144 | + "i2c block data - addr 0x%02x, read %d bytes at 0x%02x.\n", | |
145 | + addr, len, command); | |
146 | + } | |
147 | + | |
148 | + ret = 0; | |
149 | + break; | |
150 | + | |
151 | + default: | |
152 | + dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); | |
153 | + ret = -EOPNOTSUPP; | |
154 | + break; | |
155 | + } /* switch (size) */ | |
156 | + | |
157 | + return ret; | |
158 | +} | |
159 | + | |
160 | +static u32 stub_func(struct i2c_adapter *adapter) | |
161 | +{ | |
162 | + return STUB_FUNC & functionality; | |
163 | +} | |
164 | + | |
165 | +static const struct i2c_algorithm smbus_algorithm = { | |
166 | + .functionality = stub_func, | |
167 | + .smbus_xfer = stub_xfer, | |
168 | +}; | |
169 | + | |
170 | +static struct i2c_adapter stub_adapter = { | |
171 | + .owner = THIS_MODULE, | |
172 | + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, | |
173 | + .algo = &smbus_algorithm, | |
174 | + .name = "SMBus stub driver", | |
175 | +}; | |
176 | + | |
177 | +static int __init i2c_stub_init(void) | |
178 | +{ | |
179 | + int i, ret; | |
180 | + | |
181 | + if (!chip_addr[0]) { | |
182 | + pr_err("i2c-stub: Please specify a chip address\n"); | |
183 | + return -ENODEV; | |
184 | + } | |
185 | + | |
186 | + for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { | |
187 | + if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { | |
188 | + pr_err("i2c-stub: Invalid chip address 0x%02x\n", | |
189 | + chip_addr[i]); | |
190 | + return -EINVAL; | |
191 | + } | |
192 | + | |
193 | + pr_info("i2c-stub: Virtual chip at 0x%02x\n", chip_addr[i]); | |
194 | + } | |
195 | + | |
196 | + /* Allocate memory for all chips at once */ | |
197 | + stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); | |
198 | + if (!stub_chips) { | |
199 | + pr_err("i2c-stub: Out of memory\n"); | |
200 | + return -ENOMEM; | |
201 | + } | |
202 | + | |
203 | + ret = i2c_add_adapter(&stub_adapter); | |
204 | + if (ret) | |
205 | + kfree(stub_chips); | |
206 | + return ret; | |
207 | +} | |
208 | + | |
209 | +static void __exit i2c_stub_exit(void) | |
210 | +{ | |
211 | + i2c_del_adapter(&stub_adapter); | |
212 | + kfree(stub_chips); | |
213 | +} | |
214 | + | |
215 | +MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); | |
216 | +MODULE_DESCRIPTION("I2C stub driver"); | |
217 | +MODULE_LICENSE("GPL"); | |
218 | + | |
219 | +module_init(i2c_stub_init); | |
220 | +module_exit(i2c_stub_exit); |