diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/chips/max6875.c | 445 |
1 files changed, 123 insertions, 322 deletions
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index 0230375f72e5..4d4ace4b805f 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c | |||
@@ -5,97 +5,62 @@ | |||
5 | 5 | ||
6 | Based on i2c/chips/eeprom.c | 6 | Based on i2c/chips/eeprom.c |
7 | 7 | ||
8 | The MAX6875 has two EEPROM sections: config and user. | 8 | The MAX6875 has a bank of registers and two banks of EEPROM. |
9 | At reset, the config EEPROM is read into the registers. | 9 | Address ranges are defined as follows: |
10 | * 0x0000 - 0x0046 = configuration registers | ||
11 | * 0x8000 - 0x8046 = configuration EEPROM | ||
12 | * 0x8100 - 0x82FF = user EEPROM | ||
10 | 13 | ||
11 | This driver make 3 binary files available in sysfs: | 14 | This driver makes the user EEPROM available for read. |
12 | reg_config - direct access to the registers | ||
13 | eeprom_config - acesses configuration eeprom space | ||
14 | eeprom_user - free for application use | ||
15 | 15 | ||
16 | In our application, we put device serial & model numbers in user eeprom. | 16 | The registers & config EEPROM should be accessed via i2c-dev. |
17 | 17 | ||
18 | Notes: | 18 | The MAX6875 ignores the lowest address bit, so each chip responds to |
19 | 1) The datasheet says that register 0x44 / EEPROM 0x8044 should NOT | 19 | two addresses - 0x50/0x51 and 0x52/0x53. |
20 | be overwritten, so the driver explicitly prevents that. | 20 | |
21 | 2) It's a good idea to keep the config (0x45) locked in config EEPROM. | 21 | Note that the MAX6875 uses i2c_smbus_write_byte_data() to set the read |
22 | You can temporarily enable config writes by changing register 0x45. | 22 | address, so this driver is destructive if loaded for the wrong EEPROM chip. |
23 | 23 | ||
24 | This program is free software; you can redistribute it and/or modify | 24 | This program is free software; you can redistribute it and/or modify |
25 | it under the terms of the GNU General Public License as published by | 25 | it under the terms of the GNU General Public License as published by |
26 | the Free Software Foundation; version 2 of the License. | 26 | the Free Software Foundation; version 2 of the License. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/config.h> | ||
30 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/module.h> | 31 | #include <linux/module.h> |
33 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
34 | #include <linux/sched.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
37 | #include <linux/i2c-sensor.h> | 34 | #include <linux/i2c-sensor.h> |
35 | #include <asm/semaphore.h> | ||
38 | 36 | ||
39 | /* Addresses to scan */ | 37 | /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ |
40 | /* No address scanned by default, as this could corrupt standard EEPROMS. */ | ||
41 | static unsigned short normal_i2c[] = {I2C_CLIENT_END}; | 38 | static unsigned short normal_i2c[] = {I2C_CLIENT_END}; |
42 | static unsigned int normal_isa[] = {I2C_CLIENT_ISA_END}; | 39 | static unsigned int normal_isa[] = {I2C_CLIENT_ISA_END}; |
43 | 40 | ||
44 | /* Insmod parameters */ | 41 | /* Insmod parameters */ |
45 | SENSORS_INSMOD_1(max6875); | 42 | SENSORS_INSMOD_1(max6875); |
46 | 43 | ||
47 | /* this param will prevent 'accidental' writes to the eeprom */ | ||
48 | static int allow_write = 0; | ||
49 | module_param(allow_write, int, 0); | ||
50 | MODULE_PARM_DESC(allow_write, | ||
51 | "Enable write access:\n" | ||
52 | "*0: Read only\n" | ||
53 | " 1: Read/Write access"); | ||
54 | |||
55 | /* The MAX6875 can only read/write 16 bytes at a time */ | 44 | /* The MAX6875 can only read/write 16 bytes at a time */ |
56 | #define SLICE_SIZE 16 | 45 | #define SLICE_SIZE 16 |
57 | #define SLICE_BITS 4 | 46 | #define SLICE_BITS 4 |
58 | 47 | ||
59 | /* CONFIG EEPROM is at addresses 0x8000 - 0x8045, registers are at 0 - 0x45 */ | ||
60 | #define CONFIG_EEPROM_BASE 0x8000 | ||
61 | #define CONFIG_EEPROM_SIZE 0x0046 | ||
62 | #define CONFIG_EEPROM_SLICES 5 | ||
63 | |||
64 | /* USER EEPROM is at addresses 0x8100 - 0x82FF */ | 48 | /* USER EEPROM is at addresses 0x8100 - 0x82FF */ |
65 | #define USER_EEPROM_BASE 0x8100 | 49 | #define USER_EEPROM_BASE 0x8100 |
66 | #define USER_EEPROM_SIZE 0x0200 | 50 | #define USER_EEPROM_SIZE 0x0200 |
67 | #define USER_EEPROM_SLICES 32 | 51 | #define USER_EEPROM_SLICES 32 |
68 | 52 | ||
69 | /* MAX6875 commands */ | 53 | /* MAX6875 commands */ |
70 | #define MAX6875_CMD_BLOCK_WRITE 0x83 | 54 | #define MAX6875_CMD_BLK_READ 0x84 |
71 | #define MAX6875_CMD_BLOCK_READ 0x84 | ||
72 | #define MAX6875_CMD_REBOOT 0x88 | ||
73 | |||
74 | enum max6875_area_type { | ||
75 | max6875_register_config=0, | ||
76 | max6875_eeprom_config, | ||
77 | max6875_eeprom_user, | ||
78 | max6857_max | ||
79 | }; | ||
80 | |||
81 | struct eeprom_block { | ||
82 | enum max6875_area_type type; | ||
83 | u8 slices; | ||
84 | u32 size; | ||
85 | u32 valid; | ||
86 | u32 base; | ||
87 | unsigned long *updated; | ||
88 | u8 *data; | ||
89 | }; | ||
90 | 55 | ||
91 | /* Each client has this additional data */ | 56 | /* Each client has this additional data */ |
92 | struct max6875_data { | 57 | struct max6875_data { |
93 | struct i2c_client client; | 58 | struct i2c_client client; |
94 | struct semaphore update_lock; | 59 | struct semaphore update_lock; |
95 | struct eeprom_block blocks[max6857_max]; | 60 | |
96 | /* the above structs point into the arrays below */ | 61 | u32 valid; |
97 | u8 data[USER_EEPROM_SIZE + (CONFIG_EEPROM_SIZE*2)]; | 62 | u8 data[USER_EEPROM_SIZE]; |
98 | unsigned long last_updated[USER_EEPROM_SLICES + (CONFIG_EEPROM_SLICES*2)]; | 63 | unsigned long last_updated[USER_EEPROM_SLICES]; |
99 | }; | 64 | }; |
100 | 65 | ||
101 | static int max6875_attach_adapter(struct i2c_adapter *adapter); | 66 | static int max6875_attach_adapter(struct i2c_adapter *adapter); |
@@ -111,224 +76,98 @@ static struct i2c_driver max6875_driver = { | |||
111 | .detach_client = max6875_detach_client, | 76 | .detach_client = max6875_detach_client, |
112 | }; | 77 | }; |
113 | 78 | ||
114 | static int max6875_update_slice(struct i2c_client *client, | 79 | static void max6875_update_slice(struct i2c_client *client, int slice) |
115 | struct eeprom_block *blk, | ||
116 | int slice) | ||
117 | { | 80 | { |
118 | struct max6875_data *data = i2c_get_clientdata(client); | 81 | struct max6875_data *data = i2c_get_clientdata(client); |
119 | int i, j, addr, count; | 82 | int i, j, addr; |
120 | u8 rdbuf[SLICE_SIZE]; | 83 | u8 *buf; |
121 | int retval = 0; | 84 | int retval = 0; |
122 | 85 | ||
123 | if (slice >= blk->slices) | 86 | if (slice >= USER_EEPROM_SLICES) |
124 | return -1; | 87 | return; |
125 | 88 | ||
126 | down(&data->update_lock); | 89 | down(&data->update_lock); |
127 | 90 | ||
128 | if (!(blk->valid & (1 << slice)) || | 91 | buf = &data->data[slice << SLICE_BITS]; |
129 | (jiffies - blk->updated[slice] > 300 * HZ) || | 92 | |
130 | (jiffies < blk->updated[slice])) { | 93 | if (!(data->valid & (1 << slice)) || |
131 | dev_dbg(&client->dev, "Starting eeprom update, slice %u, base %u\n", | 94 | time_after(jiffies, data->last_updated[slice])) { |
95 | |||
96 | dev_dbg(&client->dev, "Starting update of slice %u\n", | ||
132 | slice, blk->base); | 97 | slice, blk->base); |
133 | 98 | ||
134 | addr = blk->base + (slice << SLICE_BITS); | 99 | data->valid &= ~(1 << slice); |
135 | count = blk->size - (slice << SLICE_BITS); | ||
136 | if (count > SLICE_SIZE) { | ||
137 | count = SLICE_SIZE; | ||
138 | } | ||
139 | 100 | ||
140 | /* Preset the read address */ | 101 | addr = USER_EEPROM_BASE + (slice << SLICE_BITS); |
141 | if (addr < 0x100) { | 102 | |
142 | /* select the register */ | 103 | /* select the eeprom address */ |
143 | if (i2c_smbus_write_byte(client, addr & 0xFF)) { | 104 | if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) { |
144 | dev_dbg(&client->dev, "max6875 register select has failed!\n"); | 105 | dev_err(&client->dev, "address set failed\n"); |
145 | retval = -1; | 106 | retval = -1; |
146 | goto exit; | 107 | goto exit_up; |
147 | } | ||
148 | } else { | ||
149 | /* select the eeprom */ | ||
150 | if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) { | ||
151 | dev_dbg(&client->dev, "max6875 address set has failed!\n"); | ||
152 | retval = -1; | ||
153 | goto exit; | ||
154 | } | ||
155 | } | 108 | } |
156 | 109 | ||
157 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { | 110 | if (i2c_check_functionality(client->adapter, |
158 | if (i2c_smbus_read_i2c_block_data(client, MAX6875_CMD_BLOCK_READ, | 111 | I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { |
159 | rdbuf) != SLICE_SIZE) | 112 | if (i2c_smbus_read_i2c_block_data(client, |
160 | { | 113 | MAX6875_CMD_BLK_READ, |
114 | buf) != SLICE_SIZE) { | ||
161 | retval = -1; | 115 | retval = -1; |
162 | goto exit; | 116 | goto exit_up; |
163 | } | 117 | } |
164 | |||
165 | memcpy(&blk->data[slice << SLICE_BITS], rdbuf, count); | ||
166 | } else { | 118 | } else { |
167 | for (i = 0; i < count; i++) { | 119 | for (i = 0; i < SLICE_SIZE; i++) { |
168 | j = i2c_smbus_read_byte(client); | 120 | j = i2c_smbus_read_byte(client); |
169 | if (j < 0) | 121 | if (j < 0) { |
170 | { | ||
171 | retval = -1; | 122 | retval = -1; |
172 | goto exit; | 123 | goto exit_up; |
173 | } | 124 | } |
174 | blk->data[(slice << SLICE_BITS) + i] = (u8) j; | 125 | buf[i] = j; |
175 | } | 126 | } |
176 | } | 127 | } |
177 | blk->updated[slice] = jiffies; | 128 | data->last_updated[slice] = jiffies; |
178 | blk->valid |= (1 << slice); | 129 | data->valid |= (1 << slice); |
179 | } | 130 | } |
180 | exit: | 131 | exit_up: |
181 | up(&data->update_lock); | 132 | up(&data->update_lock); |
182 | return retval; | ||
183 | } | ||
184 | |||
185 | static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off, size_t count, | ||
186 | enum max6875_area_type area_type) | ||
187 | { | ||
188 | struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); | ||
189 | struct max6875_data *data = i2c_get_clientdata(client); | ||
190 | struct eeprom_block *blk; | ||
191 | int slice; | ||
192 | |||
193 | blk = &data->blocks[area_type]; | ||
194 | |||
195 | if (off > blk->size) | ||
196 | return 0; | ||
197 | if (off + count > blk->size) | ||
198 | count = blk->size - off; | ||
199 | |||
200 | /* Only refresh slices which contain requested bytes */ | ||
201 | for (slice = (off >> SLICE_BITS); slice <= ((off + count - 1) >> SLICE_BITS); slice++) | ||
202 | max6875_update_slice(client, blk, slice); | ||
203 | |||
204 | memcpy(buf, &blk->data[off], count); | ||
205 | |||
206 | return count; | ||
207 | } | ||
208 | |||
209 | static ssize_t max6875_user_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
210 | { | ||
211 | return max6875_read(kobj, buf, off, count, max6875_eeprom_user); | ||
212 | } | 133 | } |
213 | 134 | ||
214 | static ssize_t max6875_config_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | 135 | static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) |
215 | { | 136 | { |
216 | return max6875_read(kobj, buf, off, count, max6875_eeprom_config); | 137 | return to_i2c_client(container_of(kobj, struct device, kobj)); |
217 | } | 138 | } |
218 | 139 | ||
219 | static ssize_t max6875_cfgreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | 140 | static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off, |
141 | size_t count) | ||
220 | { | 142 | { |
221 | return max6875_read(kobj, buf, off, count, max6875_register_config); | 143 | struct i2c_client *client = kobj_to_i2c_client(kobj); |
222 | } | ||
223 | |||
224 | |||
225 | static ssize_t max6875_write(struct kobject *kobj, char *buf, loff_t off, size_t count, | ||
226 | enum max6875_area_type area_type) | ||
227 | { | ||
228 | struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); | ||
229 | struct max6875_data *data = i2c_get_clientdata(client); | 144 | struct max6875_data *data = i2c_get_clientdata(client); |
230 | struct eeprom_block *blk; | 145 | int slice, max_slice; |
231 | int slice, addr, retval; | ||
232 | ssize_t sent = 0; | ||
233 | |||
234 | blk = &data->blocks[area_type]; | ||
235 | 146 | ||
236 | if (off > blk->size) | 147 | if (off > USER_EEPROM_SIZE) |
237 | return 0; | 148 | return 0; |
238 | if ((off + count) > blk->size) | ||
239 | count = blk->size - off; | ||
240 | 149 | ||
241 | if (down_interruptible(&data->update_lock)) | 150 | if (off + count > USER_EEPROM_SIZE) |
242 | return -EAGAIN; | 151 | count = USER_EEPROM_SIZE - off; |
243 | 152 | ||
244 | /* writing to a register is done with i2c_smbus_write_byte_data() */ | 153 | /* refresh slices which contain requested bytes */ |
245 | if (blk->type == max6875_register_config) { | 154 | max_slice = (off + count - 1) >> SLICE_BITS; |
246 | for (sent = 0; sent < count; sent++) { | 155 | for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++) |
247 | addr = off + sent; | 156 | max6875_update_slice(client, slice); |
248 | if (addr == 0x44) | ||
249 | continue; | ||
250 | 157 | ||
251 | retval = i2c_smbus_write_byte_data(client, addr, buf[sent]); | 158 | memcpy(buf, &data->data[off], count); |
252 | } | ||
253 | } else { | ||
254 | int cmd, val; | ||
255 | |||
256 | /* We are writing to EEPROM */ | ||
257 | for (sent = 0; sent < count; sent++) { | ||
258 | addr = blk->base + off + sent; | ||
259 | cmd = addr >> 8; | ||
260 | val = (addr & 0xff) | (buf[sent] << 8); // reversed | ||
261 | |||
262 | if (addr == 0x8044) | ||
263 | continue; | ||
264 | |||
265 | retval = i2c_smbus_write_word_data(client, cmd, val); | ||
266 | |||
267 | if (retval) { | ||
268 | goto error_exit; | ||
269 | } | ||
270 | 159 | ||
271 | /* A write takes up to 11 ms */ | 160 | return count; |
272 | msleep(11); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /* Invalidate the scratch buffer */ | ||
277 | for (slice = (off >> SLICE_BITS); slice <= ((off + count - 1) >> SLICE_BITS); slice++) | ||
278 | blk->valid &= ~(1 << slice); | ||
279 | |||
280 | error_exit: | ||
281 | up(&data->update_lock); | ||
282 | |||
283 | return sent; | ||
284 | } | ||
285 | |||
286 | static ssize_t max6875_user_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
287 | { | ||
288 | return max6875_write(kobj, buf, off, count, max6875_eeprom_user); | ||
289 | } | ||
290 | |||
291 | static ssize_t max6875_config_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
292 | { | ||
293 | return max6875_write(kobj, buf, off, count, max6875_eeprom_config); | ||
294 | } | ||
295 | |||
296 | static ssize_t max6875_cfgreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
297 | { | ||
298 | return max6875_write(kobj, buf, off, count, max6875_register_config); | ||
299 | } | 161 | } |
300 | 162 | ||
301 | static struct bin_attribute user_eeprom_attr = { | 163 | static struct bin_attribute user_eeprom_attr = { |
302 | .attr = { | 164 | .attr = { |
303 | .name = "eeprom_user", | 165 | .name = "eeprom", |
304 | .mode = S_IRUGO | S_IWUSR | S_IWGRP, | 166 | .mode = S_IRUGO, |
305 | .owner = THIS_MODULE, | 167 | .owner = THIS_MODULE, |
306 | }, | 168 | }, |
307 | .size = USER_EEPROM_SIZE, | 169 | .size = USER_EEPROM_SIZE, |
308 | .read = max6875_user_read, | 170 | .read = max6875_read, |
309 | .write = max6875_user_write, | ||
310 | }; | ||
311 | |||
312 | static struct bin_attribute config_eeprom_attr = { | ||
313 | .attr = { | ||
314 | .name = "eeprom_config", | ||
315 | .mode = S_IRUGO | S_IWUSR, | ||
316 | .owner = THIS_MODULE, | ||
317 | }, | ||
318 | .size = CONFIG_EEPROM_SIZE, | ||
319 | .read = max6875_config_read, | ||
320 | .write = max6875_config_write, | ||
321 | }; | ||
322 | |||
323 | static struct bin_attribute config_register_attr = { | ||
324 | .attr = { | ||
325 | .name = "reg_config", | ||
326 | .mode = S_IRUGO | S_IWUSR, | ||
327 | .owner = THIS_MODULE, | ||
328 | }, | ||
329 | .size = CONFIG_EEPROM_SIZE, | ||
330 | .read = max6875_cfgreg_read, | ||
331 | .write = max6875_cfgreg_write, | ||
332 | }; | 171 | }; |
333 | 172 | ||
334 | static int max6875_attach_adapter(struct i2c_adapter *adapter) | 173 | static int max6875_attach_adapter(struct i2c_adapter *adapter) |
@@ -339,109 +178,73 @@ static int max6875_attach_adapter(struct i2c_adapter *adapter) | |||
339 | /* This function is called by i2c_detect */ | 178 | /* This function is called by i2c_detect */ |
340 | static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) | 179 | static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) |
341 | { | 180 | { |
342 | struct i2c_client *new_client; | 181 | struct i2c_client *real_client; |
182 | struct i2c_client *fake_client; | ||
343 | struct max6875_data *data; | 183 | struct max6875_data *data; |
344 | int err = 0; | 184 | int err = 0; |
345 | 185 | ||
346 | /* Prevent 24RF08 corruption (in case of user error) */ | 186 | /* Prevent 24rf08 corruption (in case of user error) */ |
347 | if (kind < 0) | 187 | if (kind < 0) |
348 | i2c_smbus_xfer(adapter, address, 0, 0, 0, | 188 | i2c_smbus_xfer(adapter, address, 0, 0, 0, |
349 | I2C_SMBUS_QUICK, NULL); | 189 | I2C_SMBUS_QUICK, NULL); |
350 | 190 | ||
351 | /* There are three ways we can read the EEPROM data: | 191 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
352 | (1) I2C block reads (faster, but unsupported by most adapters) | 192 | | I2C_FUNC_SMBUS_READ_BYTE)) |
353 | (2) Consecutive byte reads (100% overhead) | 193 | return 0; |
354 | (3) Regular byte data reads (200% overhead) | 194 | |
355 | The third method is not implemented by this driver because all | 195 | /* Only check even addresses */ |
356 | known adapters support at least the second. */ | 196 | if (address & 1) |
357 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA | | 197 | return 0; |
358 | I2C_FUNC_SMBUS_BYTE | | 198 | |
359 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 199 | if (!(data = kmalloc(sizeof(struct max6875_data), GFP_KERNEL))) |
360 | goto exit; | 200 | return -ENOMEM; |
361 | |||
362 | /* OK. For now, we presume we have a valid client. We now create the | ||
363 | client structure, even though we cannot fill it completely yet. | ||
364 | But it allows us to access eeprom_{read,write}_value. */ | ||
365 | if (!(data = kmalloc(sizeof(struct max6875_data), GFP_KERNEL))) { | ||
366 | err = -ENOMEM; | ||
367 | goto exit; | ||
368 | } | ||
369 | memset(data, 0, sizeof(struct max6875_data)); | 201 | memset(data, 0, sizeof(struct max6875_data)); |
370 | 202 | ||
371 | new_client = &data->client; | 203 | /* A fake client is created on the odd address */ |
372 | i2c_set_clientdata(new_client, data); | 204 | if (!(fake_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) { |
373 | new_client->addr = address; | 205 | err = -ENOMEM; |
374 | new_client->adapter = adapter; | 206 | goto exit_kfree1; |
375 | new_client->driver = &max6875_driver; | 207 | } |
376 | new_client->flags = 0; | 208 | memset(fake_client, 0, sizeof(struct i2c_client)); |
377 | 209 | ||
378 | /* Setup the user section */ | 210 | /* Init real i2c_client */ |
379 | data->blocks[max6875_eeprom_user].type = max6875_eeprom_user; | 211 | real_client = &data->client; |
380 | data->blocks[max6875_eeprom_user].slices = USER_EEPROM_SLICES; | 212 | i2c_set_clientdata(real_client, data); |
381 | data->blocks[max6875_eeprom_user].size = USER_EEPROM_SIZE; | 213 | real_client->addr = address; |
382 | data->blocks[max6875_eeprom_user].base = USER_EEPROM_BASE; | 214 | real_client->adapter = adapter; |
383 | data->blocks[max6875_eeprom_user].data = data->data; | 215 | real_client->driver = &max6875_driver; |
384 | data->blocks[max6875_eeprom_user].updated = data->last_updated; | 216 | real_client->flags = 0; |
385 | 217 | strlcpy(real_client->name, "max6875", I2C_NAME_SIZE); | |
386 | /* Setup the config section */ | ||
387 | data->blocks[max6875_eeprom_config].type = max6875_eeprom_config; | ||
388 | data->blocks[max6875_eeprom_config].slices = CONFIG_EEPROM_SLICES; | ||
389 | data->blocks[max6875_eeprom_config].size = CONFIG_EEPROM_SIZE; | ||
390 | data->blocks[max6875_eeprom_config].base = CONFIG_EEPROM_BASE; | ||
391 | data->blocks[max6875_eeprom_config].data = &data->data[USER_EEPROM_SIZE]; | ||
392 | data->blocks[max6875_eeprom_config].updated = &data->last_updated[USER_EEPROM_SLICES]; | ||
393 | |||
394 | /* Setup the register section */ | ||
395 | data->blocks[max6875_register_config].type = max6875_register_config; | ||
396 | data->blocks[max6875_register_config].slices = CONFIG_EEPROM_SLICES; | ||
397 | data->blocks[max6875_register_config].size = CONFIG_EEPROM_SIZE; | ||
398 | data->blocks[max6875_register_config].base = 0; | ||
399 | data->blocks[max6875_register_config].data = &data->data[USER_EEPROM_SIZE+CONFIG_EEPROM_SIZE]; | ||
400 | data->blocks[max6875_register_config].updated = &data->last_updated[USER_EEPROM_SLICES+CONFIG_EEPROM_SLICES]; | ||
401 | |||
402 | /* Init the data */ | ||
403 | memset(data->data, 0xff, sizeof(data->data)); | ||
404 | |||
405 | /* Fill in the remaining client fields */ | ||
406 | strlcpy(new_client->name, "max6875", I2C_NAME_SIZE); | ||
407 | init_MUTEX(&data->update_lock); | 218 | init_MUTEX(&data->update_lock); |
408 | 219 | ||
409 | /* Verify that the chip is really what we think it is */ | 220 | /* Init fake client data */ |
410 | if ((max6875_update_slice(new_client, &data->blocks[max6875_eeprom_config], 4) < 0) || | 221 | /* set the client data to the i2c_client so that it will get freed */ |
411 | (max6875_update_slice(new_client, &data->blocks[max6875_register_config], 4) < 0)) | 222 | i2c_set_clientdata(fake_client, fake_client); |
412 | goto exit_kfree; | 223 | fake_client->addr = address | 1; |
413 | 224 | fake_client->adapter = adapter; | |
414 | /* 0x41,0x42 must be zero and 0x40 must match in eeprom and registers */ | 225 | fake_client->driver = &max6875_driver; |
415 | if ((data->blocks[max6875_eeprom_config].data[0x41] != 0) || | 226 | fake_client->flags = 0; |
416 | (data->blocks[max6875_eeprom_config].data[0x42] != 0) || | 227 | strlcpy(fake_client->name, "max6875-dummy", I2C_NAME_SIZE); |
417 | (data->blocks[max6875_register_config].data[0x41] != 0) || | 228 | |
418 | (data->blocks[max6875_register_config].data[0x42] != 0) || | 229 | /* Prevent 24RF08 corruption (in case of user error) */ |
419 | (data->blocks[max6875_eeprom_config].data[0x40] != | 230 | i2c_smbus_write_quick(real_client, 0); |
420 | data->blocks[max6875_register_config].data[0x40])) | 231 | |
421 | goto exit_kfree; | 232 | if ((err = i2c_attach_client(real_client)) != 0) |
422 | 233 | goto exit_kfree2; | |
423 | /* Tell the I2C layer a new client has arrived */ | 234 | |
424 | if ((err = i2c_attach_client(new_client))) | 235 | if ((err = i2c_attach_client(fake_client)) != 0) |
425 | goto exit_kfree; | 236 | goto exit_detach; |
426 | 237 | ||
427 | /* create the sysfs eeprom files with the correct permissions */ | 238 | sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr); |
428 | if (allow_write == 0) { | ||
429 | user_eeprom_attr.attr.mode &= ~S_IWUGO; | ||
430 | user_eeprom_attr.write = NULL; | ||
431 | config_eeprom_attr.attr.mode &= ~S_IWUGO; | ||
432 | config_eeprom_attr.write = NULL; | ||
433 | config_register_attr.attr.mode &= ~S_IWUGO; | ||
434 | config_register_attr.write = NULL; | ||
435 | } | ||
436 | sysfs_create_bin_file(&new_client->dev.kobj, &user_eeprom_attr); | ||
437 | sysfs_create_bin_file(&new_client->dev.kobj, &config_eeprom_attr); | ||
438 | sysfs_create_bin_file(&new_client->dev.kobj, &config_register_attr); | ||
439 | 239 | ||
440 | return 0; | 240 | return 0; |
441 | 241 | ||
442 | exit_kfree: | 242 | exit_detach: |
243 | i2c_detach_client(real_client); | ||
244 | exit_kfree2: | ||
245 | kfree(fake_client); | ||
246 | exit_kfree1: | ||
443 | kfree(data); | 247 | kfree(data); |
444 | exit: | ||
445 | return err; | 248 | return err; |
446 | } | 249 | } |
447 | 250 | ||
@@ -451,12 +254,10 @@ static int max6875_detach_client(struct i2c_client *client) | |||
451 | 254 | ||
452 | err = i2c_detach_client(client); | 255 | err = i2c_detach_client(client); |
453 | if (err) { | 256 | if (err) { |
454 | dev_err(&client->dev, "Client deregistration failed, client not detached.\n"); | 257 | dev_err(&client->dev, "i2c_detach_client() failed\n"); |
455 | return err; | 258 | return err; |
456 | } | 259 | } |
457 | |||
458 | kfree(i2c_get_clientdata(client)); | 260 | kfree(i2c_get_clientdata(client)); |
459 | |||
460 | return 0; | 261 | return 0; |
461 | } | 262 | } |
462 | 263 | ||