diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/i2c/i2c-core.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 1272 |
1 files changed, 1272 insertions, 0 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c new file mode 100644 index 000000000000..9011627d7eb0 --- /dev/null +++ b/drivers/i2c/i2c-core.c | |||
@@ -0,0 +1,1272 @@ | |||
1 | /* i2c-core.c - a device driver for the iic-bus interface */ | ||
2 | /* ------------------------------------------------------------------------- */ | ||
3 | /* Copyright (C) 1995-99 Simon G. Vogl | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
18 | /* ------------------------------------------------------------------------- */ | ||
19 | |||
20 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>. | ||
21 | All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> | ||
22 | SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> */ | ||
23 | |||
24 | #include <linux/config.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/idr.h> | ||
32 | #include <linux/seq_file.h> | ||
33 | #include <asm/uaccess.h> | ||
34 | |||
35 | |||
36 | static LIST_HEAD(adapters); | ||
37 | static LIST_HEAD(drivers); | ||
38 | static DECLARE_MUTEX(core_lists); | ||
39 | static DEFINE_IDR(i2c_adapter_idr); | ||
40 | |||
41 | /* match always succeeds, as we want the probe() to tell if we really accept this match */ | ||
42 | static int i2c_device_match(struct device *dev, struct device_driver *drv) | ||
43 | { | ||
44 | return 1; | ||
45 | } | ||
46 | |||
47 | static int i2c_bus_suspend(struct device * dev, pm_message_t state) | ||
48 | { | ||
49 | int rc = 0; | ||
50 | |||
51 | if (dev->driver && dev->driver->suspend) | ||
52 | rc = dev->driver->suspend(dev,state,0); | ||
53 | return rc; | ||
54 | } | ||
55 | |||
56 | static int i2c_bus_resume(struct device * dev) | ||
57 | { | ||
58 | int rc = 0; | ||
59 | |||
60 | if (dev->driver && dev->driver->resume) | ||
61 | rc = dev->driver->resume(dev,0); | ||
62 | return rc; | ||
63 | } | ||
64 | |||
65 | static struct bus_type i2c_bus_type = { | ||
66 | .name = "i2c", | ||
67 | .match = i2c_device_match, | ||
68 | .suspend = i2c_bus_suspend, | ||
69 | .resume = i2c_bus_resume, | ||
70 | }; | ||
71 | |||
72 | static int i2c_device_probe(struct device *dev) | ||
73 | { | ||
74 | return -ENODEV; | ||
75 | } | ||
76 | |||
77 | static int i2c_device_remove(struct device *dev) | ||
78 | { | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static void i2c_adapter_dev_release(struct device *dev) | ||
83 | { | ||
84 | struct i2c_adapter *adap = dev_to_i2c_adapter(dev); | ||
85 | complete(&adap->dev_released); | ||
86 | } | ||
87 | |||
88 | static struct device_driver i2c_adapter_driver = { | ||
89 | .name = "i2c_adapter", | ||
90 | .bus = &i2c_bus_type, | ||
91 | .probe = i2c_device_probe, | ||
92 | .remove = i2c_device_remove, | ||
93 | }; | ||
94 | |||
95 | static void i2c_adapter_class_dev_release(struct class_device *dev) | ||
96 | { | ||
97 | struct i2c_adapter *adap = class_dev_to_i2c_adapter(dev); | ||
98 | complete(&adap->class_dev_released); | ||
99 | } | ||
100 | |||
101 | static struct class i2c_adapter_class = { | ||
102 | .name = "i2c-adapter", | ||
103 | .release = &i2c_adapter_class_dev_release, | ||
104 | }; | ||
105 | |||
106 | static ssize_t show_adapter_name(struct device *dev, char *buf) | ||
107 | { | ||
108 | struct i2c_adapter *adap = dev_to_i2c_adapter(dev); | ||
109 | return sprintf(buf, "%s\n", adap->name); | ||
110 | } | ||
111 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | ||
112 | |||
113 | |||
114 | static void i2c_client_release(struct device *dev) | ||
115 | { | ||
116 | struct i2c_client *client = to_i2c_client(dev); | ||
117 | complete(&client->released); | ||
118 | } | ||
119 | |||
120 | static ssize_t show_client_name(struct device *dev, char *buf) | ||
121 | { | ||
122 | struct i2c_client *client = to_i2c_client(dev); | ||
123 | return sprintf(buf, "%s\n", client->name); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * We can't use the DEVICE_ATTR() macro here as we want the same filename for a | ||
128 | * different type of a device. So beware if the DEVICE_ATTR() macro ever | ||
129 | * changes, this definition will also have to change. | ||
130 | */ | ||
131 | static struct device_attribute dev_attr_client_name = { | ||
132 | .attr = {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE }, | ||
133 | .show = &show_client_name, | ||
134 | }; | ||
135 | |||
136 | |||
137 | /* --------------------------------------------------- | ||
138 | * registering functions | ||
139 | * --------------------------------------------------- | ||
140 | */ | ||
141 | |||
142 | /* ----- | ||
143 | * i2c_add_adapter is called from within the algorithm layer, | ||
144 | * when a new hw adapter registers. A new device is register to be | ||
145 | * available for clients. | ||
146 | */ | ||
147 | int i2c_add_adapter(struct i2c_adapter *adap) | ||
148 | { | ||
149 | int id, res = 0; | ||
150 | struct list_head *item; | ||
151 | struct i2c_driver *driver; | ||
152 | |||
153 | down(&core_lists); | ||
154 | |||
155 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) { | ||
156 | res = -ENOMEM; | ||
157 | goto out_unlock; | ||
158 | } | ||
159 | |||
160 | res = idr_get_new(&i2c_adapter_idr, NULL, &id); | ||
161 | if (res < 0) { | ||
162 | if (res == -EAGAIN) | ||
163 | res = -ENOMEM; | ||
164 | goto out_unlock; | ||
165 | } | ||
166 | |||
167 | adap->nr = id & MAX_ID_MASK; | ||
168 | init_MUTEX(&adap->bus_lock); | ||
169 | init_MUTEX(&adap->clist_lock); | ||
170 | list_add_tail(&adap->list,&adapters); | ||
171 | INIT_LIST_HEAD(&adap->clients); | ||
172 | |||
173 | /* Add the adapter to the driver core. | ||
174 | * If the parent pointer is not set up, | ||
175 | * we add this adapter to the host bus. | ||
176 | */ | ||
177 | if (adap->dev.parent == NULL) | ||
178 | adap->dev.parent = &platform_bus; | ||
179 | sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); | ||
180 | adap->dev.driver = &i2c_adapter_driver; | ||
181 | adap->dev.release = &i2c_adapter_dev_release; | ||
182 | device_register(&adap->dev); | ||
183 | device_create_file(&adap->dev, &dev_attr_name); | ||
184 | |||
185 | /* Add this adapter to the i2c_adapter class */ | ||
186 | memset(&adap->class_dev, 0x00, sizeof(struct class_device)); | ||
187 | adap->class_dev.dev = &adap->dev; | ||
188 | adap->class_dev.class = &i2c_adapter_class; | ||
189 | strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE); | ||
190 | class_device_register(&adap->class_dev); | ||
191 | |||
192 | /* inform drivers of new adapters */ | ||
193 | list_for_each(item,&drivers) { | ||
194 | driver = list_entry(item, struct i2c_driver, list); | ||
195 | if (driver->flags & I2C_DF_NOTIFY) | ||
196 | /* We ignore the return code; if it fails, too bad */ | ||
197 | driver->attach_adapter(adap); | ||
198 | } | ||
199 | |||
200 | dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr); | ||
201 | |||
202 | out_unlock: | ||
203 | up(&core_lists); | ||
204 | return res; | ||
205 | } | ||
206 | |||
207 | |||
208 | int i2c_del_adapter(struct i2c_adapter *adap) | ||
209 | { | ||
210 | struct list_head *item, *_n; | ||
211 | struct i2c_adapter *adap_from_list; | ||
212 | struct i2c_driver *driver; | ||
213 | struct i2c_client *client; | ||
214 | int res = 0; | ||
215 | |||
216 | down(&core_lists); | ||
217 | |||
218 | /* First make sure that this adapter was ever added */ | ||
219 | list_for_each_entry(adap_from_list, &adapters, list) { | ||
220 | if (adap_from_list == adap) | ||
221 | break; | ||
222 | } | ||
223 | if (adap_from_list != adap) { | ||
224 | pr_debug("I2C: Attempting to delete an unregistered " | ||
225 | "adapter\n"); | ||
226 | res = -EINVAL; | ||
227 | goto out_unlock; | ||
228 | } | ||
229 | |||
230 | list_for_each(item,&drivers) { | ||
231 | driver = list_entry(item, struct i2c_driver, list); | ||
232 | if (driver->detach_adapter) | ||
233 | if ((res = driver->detach_adapter(adap))) { | ||
234 | dev_warn(&adap->dev, "can't detach adapter " | ||
235 | "while detaching driver %s: driver not " | ||
236 | "detached!", driver->name); | ||
237 | goto out_unlock; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /* detach any active clients. This must be done first, because | ||
242 | * it can fail; in which case we give upp. */ | ||
243 | list_for_each_safe(item, _n, &adap->clients) { | ||
244 | client = list_entry(item, struct i2c_client, list); | ||
245 | |||
246 | /* detaching devices is unconditional of the set notify | ||
247 | * flag, as _all_ clients that reside on the adapter | ||
248 | * must be deleted, as this would cause invalid states. | ||
249 | */ | ||
250 | if ((res=client->driver->detach_client(client))) { | ||
251 | dev_err(&adap->dev, "adapter not " | ||
252 | "unregistered, because client at " | ||
253 | "address %02x can't be detached. ", | ||
254 | client->addr); | ||
255 | goto out_unlock; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | /* clean up the sysfs representation */ | ||
260 | init_completion(&adap->dev_released); | ||
261 | init_completion(&adap->class_dev_released); | ||
262 | class_device_unregister(&adap->class_dev); | ||
263 | device_remove_file(&adap->dev, &dev_attr_name); | ||
264 | device_unregister(&adap->dev); | ||
265 | list_del(&adap->list); | ||
266 | |||
267 | /* wait for sysfs to drop all references */ | ||
268 | wait_for_completion(&adap->dev_released); | ||
269 | wait_for_completion(&adap->class_dev_released); | ||
270 | |||
271 | /* free dynamically allocated bus id */ | ||
272 | idr_remove(&i2c_adapter_idr, adap->nr); | ||
273 | |||
274 | dev_dbg(&adap->dev, "adapter unregistered\n"); | ||
275 | |||
276 | out_unlock: | ||
277 | up(&core_lists); | ||
278 | return res; | ||
279 | } | ||
280 | |||
281 | |||
282 | /* ----- | ||
283 | * What follows is the "upwards" interface: commands for talking to clients, | ||
284 | * which implement the functions to access the physical information of the | ||
285 | * chips. | ||
286 | */ | ||
287 | |||
288 | int i2c_add_driver(struct i2c_driver *driver) | ||
289 | { | ||
290 | struct list_head *item; | ||
291 | struct i2c_adapter *adapter; | ||
292 | int res = 0; | ||
293 | |||
294 | down(&core_lists); | ||
295 | |||
296 | /* add the driver to the list of i2c drivers in the driver core */ | ||
297 | driver->driver.name = driver->name; | ||
298 | driver->driver.bus = &i2c_bus_type; | ||
299 | driver->driver.probe = i2c_device_probe; | ||
300 | driver->driver.remove = i2c_device_remove; | ||
301 | |||
302 | res = driver_register(&driver->driver); | ||
303 | if (res) | ||
304 | goto out_unlock; | ||
305 | |||
306 | list_add_tail(&driver->list,&drivers); | ||
307 | pr_debug("i2c-core: driver %s registered.\n", driver->name); | ||
308 | |||
309 | /* now look for instances of driver on our adapters */ | ||
310 | if (driver->flags & I2C_DF_NOTIFY) { | ||
311 | list_for_each(item,&adapters) { | ||
312 | adapter = list_entry(item, struct i2c_adapter, list); | ||
313 | driver->attach_adapter(adapter); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | out_unlock: | ||
318 | up(&core_lists); | ||
319 | return res; | ||
320 | } | ||
321 | |||
322 | int i2c_del_driver(struct i2c_driver *driver) | ||
323 | { | ||
324 | struct list_head *item1, *item2, *_n; | ||
325 | struct i2c_client *client; | ||
326 | struct i2c_adapter *adap; | ||
327 | |||
328 | int res = 0; | ||
329 | |||
330 | down(&core_lists); | ||
331 | |||
332 | /* Have a look at each adapter, if clients of this driver are still | ||
333 | * attached. If so, detach them to be able to kill the driver | ||
334 | * afterwards. | ||
335 | */ | ||
336 | pr_debug("i2c-core: unregister_driver - looking for clients.\n"); | ||
337 | /* removing clients does not depend on the notify flag, else | ||
338 | * invalid operation might (will!) result, when using stale client | ||
339 | * pointers. | ||
340 | */ | ||
341 | list_for_each(item1,&adapters) { | ||
342 | adap = list_entry(item1, struct i2c_adapter, list); | ||
343 | dev_dbg(&adap->dev, "examining adapter\n"); | ||
344 | if (driver->detach_adapter) { | ||
345 | if ((res = driver->detach_adapter(adap))) { | ||
346 | dev_warn(&adap->dev, "while unregistering " | ||
347 | "dummy driver %s, adapter could " | ||
348 | "not be detached properly; driver " | ||
349 | "not unloaded!",driver->name); | ||
350 | goto out_unlock; | ||
351 | } | ||
352 | } else { | ||
353 | list_for_each_safe(item2, _n, &adap->clients) { | ||
354 | client = list_entry(item2, struct i2c_client, list); | ||
355 | if (client->driver != driver) | ||
356 | continue; | ||
357 | pr_debug("i2c-core.o: detaching client %s:\n", client->name); | ||
358 | if ((res = driver->detach_client(client))) { | ||
359 | dev_err(&adap->dev, "while " | ||
360 | "unregistering driver " | ||
361 | "`%s', the client at " | ||
362 | "address %02x of " | ||
363 | "adapter could not " | ||
364 | "be detached; driver " | ||
365 | "not unloaded!", | ||
366 | driver->name, | ||
367 | client->addr); | ||
368 | goto out_unlock; | ||
369 | } | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | |||
374 | driver_unregister(&driver->driver); | ||
375 | list_del(&driver->list); | ||
376 | pr_debug("i2c-core: driver unregistered: %s\n", driver->name); | ||
377 | |||
378 | out_unlock: | ||
379 | up(&core_lists); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr) | ||
384 | { | ||
385 | struct list_head *item; | ||
386 | struct i2c_client *client; | ||
387 | |||
388 | list_for_each(item,&adapter->clients) { | ||
389 | client = list_entry(item, struct i2c_client, list); | ||
390 | if (client->addr == addr) | ||
391 | return -EBUSY; | ||
392 | } | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | int i2c_check_addr(struct i2c_adapter *adapter, int addr) | ||
397 | { | ||
398 | int rval; | ||
399 | |||
400 | down(&adapter->clist_lock); | ||
401 | rval = __i2c_check_addr(adapter, addr); | ||
402 | up(&adapter->clist_lock); | ||
403 | |||
404 | return rval; | ||
405 | } | ||
406 | |||
407 | int i2c_attach_client(struct i2c_client *client) | ||
408 | { | ||
409 | struct i2c_adapter *adapter = client->adapter; | ||
410 | |||
411 | down(&adapter->clist_lock); | ||
412 | if (__i2c_check_addr(client->adapter, client->addr)) { | ||
413 | up(&adapter->clist_lock); | ||
414 | return -EBUSY; | ||
415 | } | ||
416 | list_add_tail(&client->list,&adapter->clients); | ||
417 | up(&adapter->clist_lock); | ||
418 | |||
419 | if (adapter->client_register) { | ||
420 | if (adapter->client_register(client)) { | ||
421 | dev_warn(&adapter->dev, "warning: client_register " | ||
422 | "seems to have failed for client %02x\n", | ||
423 | client->addr); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | dev_dbg(&adapter->dev, "client [%s] registered to adapter\n", | ||
428 | client->name); | ||
429 | |||
430 | if (client->flags & I2C_CLIENT_ALLOW_USE) | ||
431 | client->usage_count = 0; | ||
432 | |||
433 | client->dev.parent = &client->adapter->dev; | ||
434 | client->dev.driver = &client->driver->driver; | ||
435 | client->dev.bus = &i2c_bus_type; | ||
436 | client->dev.release = &i2c_client_release; | ||
437 | |||
438 | snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), | ||
439 | "%d-%04x", i2c_adapter_id(adapter), client->addr); | ||
440 | pr_debug("registering %s\n", client->dev.bus_id); | ||
441 | device_register(&client->dev); | ||
442 | device_create_file(&client->dev, &dev_attr_client_name); | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | |||
448 | int i2c_detach_client(struct i2c_client *client) | ||
449 | { | ||
450 | struct i2c_adapter *adapter = client->adapter; | ||
451 | int res = 0; | ||
452 | |||
453 | if ((client->flags & I2C_CLIENT_ALLOW_USE) && (client->usage_count > 0)) | ||
454 | return -EBUSY; | ||
455 | |||
456 | if (adapter->client_unregister) { | ||
457 | res = adapter->client_unregister(client); | ||
458 | if (res) { | ||
459 | dev_err(&client->dev, | ||
460 | "client_unregister [%s] failed, " | ||
461 | "client not detached", client->name); | ||
462 | goto out; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | down(&adapter->clist_lock); | ||
467 | list_del(&client->list); | ||
468 | init_completion(&client->released); | ||
469 | device_remove_file(&client->dev, &dev_attr_client_name); | ||
470 | device_unregister(&client->dev); | ||
471 | up(&adapter->clist_lock); | ||
472 | wait_for_completion(&client->released); | ||
473 | |||
474 | out: | ||
475 | return res; | ||
476 | } | ||
477 | |||
478 | static int i2c_inc_use_client(struct i2c_client *client) | ||
479 | { | ||
480 | |||
481 | if (!try_module_get(client->driver->owner)) | ||
482 | return -ENODEV; | ||
483 | if (!try_module_get(client->adapter->owner)) { | ||
484 | module_put(client->driver->owner); | ||
485 | return -ENODEV; | ||
486 | } | ||
487 | |||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | static void i2c_dec_use_client(struct i2c_client *client) | ||
492 | { | ||
493 | module_put(client->driver->owner); | ||
494 | module_put(client->adapter->owner); | ||
495 | } | ||
496 | |||
497 | int i2c_use_client(struct i2c_client *client) | ||
498 | { | ||
499 | int ret; | ||
500 | |||
501 | ret = i2c_inc_use_client(client); | ||
502 | if (ret) | ||
503 | return ret; | ||
504 | |||
505 | if (client->flags & I2C_CLIENT_ALLOW_USE) { | ||
506 | if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) | ||
507 | client->usage_count++; | ||
508 | else if (client->usage_count > 0) | ||
509 | goto busy; | ||
510 | else | ||
511 | client->usage_count++; | ||
512 | } | ||
513 | |||
514 | return 0; | ||
515 | busy: | ||
516 | i2c_dec_use_client(client); | ||
517 | return -EBUSY; | ||
518 | } | ||
519 | |||
520 | int i2c_release_client(struct i2c_client *client) | ||
521 | { | ||
522 | if(client->flags & I2C_CLIENT_ALLOW_USE) { | ||
523 | if(client->usage_count>0) | ||
524 | client->usage_count--; | ||
525 | else { | ||
526 | pr_debug("i2c-core: %s used one too many times\n", | ||
527 | __FUNCTION__); | ||
528 | return -EPERM; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | i2c_dec_use_client(client); | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) | ||
538 | { | ||
539 | struct list_head *item; | ||
540 | struct i2c_client *client; | ||
541 | |||
542 | down(&adap->clist_lock); | ||
543 | list_for_each(item,&adap->clients) { | ||
544 | client = list_entry(item, struct i2c_client, list); | ||
545 | if (!try_module_get(client->driver->owner)) | ||
546 | continue; | ||
547 | if (NULL != client->driver->command) { | ||
548 | up(&adap->clist_lock); | ||
549 | client->driver->command(client,cmd,arg); | ||
550 | down(&adap->clist_lock); | ||
551 | } | ||
552 | module_put(client->driver->owner); | ||
553 | } | ||
554 | up(&adap->clist_lock); | ||
555 | } | ||
556 | |||
557 | static int __init i2c_init(void) | ||
558 | { | ||
559 | int retval; | ||
560 | |||
561 | retval = bus_register(&i2c_bus_type); | ||
562 | if (retval) | ||
563 | return retval; | ||
564 | retval = driver_register(&i2c_adapter_driver); | ||
565 | if (retval) | ||
566 | return retval; | ||
567 | return class_register(&i2c_adapter_class); | ||
568 | } | ||
569 | |||
570 | static void __exit i2c_exit(void) | ||
571 | { | ||
572 | class_unregister(&i2c_adapter_class); | ||
573 | driver_unregister(&i2c_adapter_driver); | ||
574 | bus_unregister(&i2c_bus_type); | ||
575 | } | ||
576 | |||
577 | subsys_initcall(i2c_init); | ||
578 | module_exit(i2c_exit); | ||
579 | |||
580 | /* ---------------------------------------------------- | ||
581 | * the functional interface to the i2c busses. | ||
582 | * ---------------------------------------------------- | ||
583 | */ | ||
584 | |||
585 | int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) | ||
586 | { | ||
587 | int ret; | ||
588 | |||
589 | if (adap->algo->master_xfer) { | ||
590 | #ifdef DEBUG | ||
591 | for (ret = 0; ret < num; ret++) { | ||
592 | dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, " | ||
593 | "len=%d\n", ret, msgs[ret].flags & I2C_M_RD ? | ||
594 | 'R' : 'W', msgs[ret].addr, msgs[ret].len); | ||
595 | } | ||
596 | #endif | ||
597 | |||
598 | down(&adap->bus_lock); | ||
599 | ret = adap->algo->master_xfer(adap,msgs,num); | ||
600 | up(&adap->bus_lock); | ||
601 | |||
602 | return ret; | ||
603 | } else { | ||
604 | dev_dbg(&adap->dev, "I2C level transfers not supported\n"); | ||
605 | return -ENOSYS; | ||
606 | } | ||
607 | } | ||
608 | |||
609 | int i2c_master_send(struct i2c_client *client,const char *buf ,int count) | ||
610 | { | ||
611 | int ret; | ||
612 | struct i2c_adapter *adap=client->adapter; | ||
613 | struct i2c_msg msg; | ||
614 | |||
615 | if (client->adapter->algo->master_xfer) { | ||
616 | msg.addr = client->addr; | ||
617 | msg.flags = client->flags & I2C_M_TEN; | ||
618 | msg.len = count; | ||
619 | msg.buf = (char *)buf; | ||
620 | |||
621 | dev_dbg(&client->adapter->dev, "master_send: writing %d bytes.\n", | ||
622 | count); | ||
623 | |||
624 | down(&adap->bus_lock); | ||
625 | ret = adap->algo->master_xfer(adap,&msg,1); | ||
626 | up(&adap->bus_lock); | ||
627 | |||
628 | /* if everything went ok (i.e. 1 msg transmitted), return #bytes | ||
629 | * transmitted, else error code. | ||
630 | */ | ||
631 | return (ret == 1 )? count : ret; | ||
632 | } else { | ||
633 | dev_err(&client->adapter->dev, "I2C level transfers not supported\n"); | ||
634 | return -ENOSYS; | ||
635 | } | ||
636 | } | ||
637 | |||
638 | int i2c_master_recv(struct i2c_client *client, char *buf ,int count) | ||
639 | { | ||
640 | struct i2c_adapter *adap=client->adapter; | ||
641 | struct i2c_msg msg; | ||
642 | int ret; | ||
643 | if (client->adapter->algo->master_xfer) { | ||
644 | msg.addr = client->addr; | ||
645 | msg.flags = client->flags & I2C_M_TEN; | ||
646 | msg.flags |= I2C_M_RD; | ||
647 | msg.len = count; | ||
648 | msg.buf = buf; | ||
649 | |||
650 | dev_dbg(&client->adapter->dev, "master_recv: reading %d bytes.\n", | ||
651 | count); | ||
652 | |||
653 | down(&adap->bus_lock); | ||
654 | ret = adap->algo->master_xfer(adap,&msg,1); | ||
655 | up(&adap->bus_lock); | ||
656 | |||
657 | dev_dbg(&client->adapter->dev, "master_recv: return:%d (count:%d, addr:0x%02x)\n", | ||
658 | ret, count, client->addr); | ||
659 | |||
660 | /* if everything went ok (i.e. 1 msg transmitted), return #bytes | ||
661 | * transmitted, else error code. | ||
662 | */ | ||
663 | return (ret == 1 )? count : ret; | ||
664 | } else { | ||
665 | dev_err(&client->adapter->dev, "I2C level transfers not supported\n"); | ||
666 | return -ENOSYS; | ||
667 | } | ||
668 | } | ||
669 | |||
670 | |||
671 | int i2c_control(struct i2c_client *client, | ||
672 | unsigned int cmd, unsigned long arg) | ||
673 | { | ||
674 | int ret = 0; | ||
675 | struct i2c_adapter *adap = client->adapter; | ||
676 | |||
677 | dev_dbg(&client->adapter->dev, "i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg); | ||
678 | switch (cmd) { | ||
679 | case I2C_RETRIES: | ||
680 | adap->retries = arg; | ||
681 | break; | ||
682 | case I2C_TIMEOUT: | ||
683 | adap->timeout = arg; | ||
684 | break; | ||
685 | default: | ||
686 | if (adap->algo->algo_control!=NULL) | ||
687 | ret = adap->algo->algo_control(adap,cmd,arg); | ||
688 | } | ||
689 | return ret; | ||
690 | } | ||
691 | |||
692 | /* ---------------------------------------------------- | ||
693 | * the i2c address scanning function | ||
694 | * Will not work for 10-bit addresses! | ||
695 | * ---------------------------------------------------- | ||
696 | */ | ||
697 | int i2c_probe(struct i2c_adapter *adapter, | ||
698 | struct i2c_client_address_data *address_data, | ||
699 | int (*found_proc) (struct i2c_adapter *, int, int)) | ||
700 | { | ||
701 | int addr,i,found,err; | ||
702 | int adap_id = i2c_adapter_id(adapter); | ||
703 | |||
704 | /* Forget it if we can't probe using SMBUS_QUICK */ | ||
705 | if (! i2c_check_functionality(adapter,I2C_FUNC_SMBUS_QUICK)) | ||
706 | return -1; | ||
707 | |||
708 | for (addr = 0x00; addr <= 0x7f; addr++) { | ||
709 | |||
710 | /* Skip if already in use */ | ||
711 | if (i2c_check_addr(adapter,addr)) | ||
712 | continue; | ||
713 | |||
714 | /* If it is in one of the force entries, we don't do any detection | ||
715 | at all */ | ||
716 | found = 0; | ||
717 | |||
718 | for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 2) { | ||
719 | if (((adap_id == address_data->force[i]) || | ||
720 | (address_data->force[i] == ANY_I2C_BUS)) && | ||
721 | (addr == address_data->force[i+1])) { | ||
722 | dev_dbg(&adapter->dev, "found force parameter for adapter %d, addr %04x\n", | ||
723 | adap_id, addr); | ||
724 | if ((err = found_proc(adapter,addr,0))) | ||
725 | return err; | ||
726 | found = 1; | ||
727 | } | ||
728 | } | ||
729 | if (found) | ||
730 | continue; | ||
731 | |||
732 | /* If this address is in one of the ignores, we can forget about | ||
733 | it right now */ | ||
734 | for (i = 0; | ||
735 | !found && (address_data->ignore[i] != I2C_CLIENT_END); | ||
736 | i += 2) { | ||
737 | if (((adap_id == address_data->ignore[i]) || | ||
738 | ((address_data->ignore[i] == ANY_I2C_BUS))) && | ||
739 | (addr == address_data->ignore[i+1])) { | ||
740 | dev_dbg(&adapter->dev, "found ignore parameter for adapter %d, " | ||
741 | "addr %04x\n", adap_id ,addr); | ||
742 | found = 1; | ||
743 | } | ||
744 | } | ||
745 | for (i = 0; | ||
746 | !found && (address_data->ignore_range[i] != I2C_CLIENT_END); | ||
747 | i += 3) { | ||
748 | if (((adap_id == address_data->ignore_range[i]) || | ||
749 | ((address_data->ignore_range[i]==ANY_I2C_BUS))) && | ||
750 | (addr >= address_data->ignore_range[i+1]) && | ||
751 | (addr <= address_data->ignore_range[i+2])) { | ||
752 | dev_dbg(&adapter->dev, "found ignore_range parameter for adapter %d, " | ||
753 | "addr %04x\n", adap_id,addr); | ||
754 | found = 1; | ||
755 | } | ||
756 | } | ||
757 | if (found) | ||
758 | continue; | ||
759 | |||
760 | /* Now, we will do a detection, but only if it is in the normal or | ||
761 | probe entries */ | ||
762 | for (i = 0; | ||
763 | !found && (address_data->normal_i2c[i] != I2C_CLIENT_END); | ||
764 | i += 1) { | ||
765 | if (addr == address_data->normal_i2c[i]) { | ||
766 | found = 1; | ||
767 | dev_dbg(&adapter->dev, "found normal i2c entry for adapter %d, " | ||
768 | "addr %02x\n", adap_id, addr); | ||
769 | } | ||
770 | } | ||
771 | |||
772 | for (i = 0; | ||
773 | !found && (address_data->normal_i2c_range[i] != I2C_CLIENT_END); | ||
774 | i += 2) { | ||
775 | if ((addr >= address_data->normal_i2c_range[i]) && | ||
776 | (addr <= address_data->normal_i2c_range[i+1])) { | ||
777 | found = 1; | ||
778 | dev_dbg(&adapter->dev, "found normal i2c_range entry for adapter %d, " | ||
779 | "addr %04x\n", adap_id,addr); | ||
780 | } | ||
781 | } | ||
782 | |||
783 | for (i = 0; | ||
784 | !found && (address_data->probe[i] != I2C_CLIENT_END); | ||
785 | i += 2) { | ||
786 | if (((adap_id == address_data->probe[i]) || | ||
787 | ((address_data->probe[i] == ANY_I2C_BUS))) && | ||
788 | (addr == address_data->probe[i+1])) { | ||
789 | found = 1; | ||
790 | dev_dbg(&adapter->dev, "found probe parameter for adapter %d, " | ||
791 | "addr %04x\n", adap_id,addr); | ||
792 | } | ||
793 | } | ||
794 | for (i = 0; | ||
795 | !found && (address_data->probe_range[i] != I2C_CLIENT_END); | ||
796 | i += 3) { | ||
797 | if (((adap_id == address_data->probe_range[i]) || | ||
798 | (address_data->probe_range[i] == ANY_I2C_BUS)) && | ||
799 | (addr >= address_data->probe_range[i+1]) && | ||
800 | (addr <= address_data->probe_range[i+2])) { | ||
801 | found = 1; | ||
802 | dev_dbg(&adapter->dev, "found probe_range parameter for adapter %d, " | ||
803 | "addr %04x\n", adap_id,addr); | ||
804 | } | ||
805 | } | ||
806 | if (!found) | ||
807 | continue; | ||
808 | |||
809 | /* OK, so we really should examine this address. First check | ||
810 | whether there is some client here at all! */ | ||
811 | if (i2c_smbus_xfer(adapter,addr,0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) | ||
812 | if ((err = found_proc(adapter,addr,-1))) | ||
813 | return err; | ||
814 | } | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | /* | ||
819 | * return id number for a specific adapter | ||
820 | */ | ||
821 | int i2c_adapter_id(struct i2c_adapter *adap) | ||
822 | { | ||
823 | return adap->nr; | ||
824 | } | ||
825 | |||
826 | struct i2c_adapter* i2c_get_adapter(int id) | ||
827 | { | ||
828 | struct list_head *item; | ||
829 | struct i2c_adapter *adapter; | ||
830 | |||
831 | down(&core_lists); | ||
832 | list_for_each(item,&adapters) { | ||
833 | adapter = list_entry(item, struct i2c_adapter, list); | ||
834 | if (id == adapter->nr && | ||
835 | try_module_get(adapter->owner)) { | ||
836 | up(&core_lists); | ||
837 | return adapter; | ||
838 | } | ||
839 | } | ||
840 | up(&core_lists); | ||
841 | return NULL; | ||
842 | } | ||
843 | |||
844 | void i2c_put_adapter(struct i2c_adapter *adap) | ||
845 | { | ||
846 | module_put(adap->owner); | ||
847 | } | ||
848 | |||
849 | /* The SMBus parts */ | ||
850 | |||
851 | #define POLY (0x1070U << 3) | ||
852 | static u8 | ||
853 | crc8(u16 data) | ||
854 | { | ||
855 | int i; | ||
856 | |||
857 | for(i = 0; i < 8; i++) { | ||
858 | if (data & 0x8000) | ||
859 | data = data ^ POLY; | ||
860 | data = data << 1; | ||
861 | } | ||
862 | return (u8)(data >> 8); | ||
863 | } | ||
864 | |||
865 | /* CRC over count bytes in the first array plus the bytes in the rest | ||
866 | array if it is non-null. rest[0] is the (length of rest) - 1 | ||
867 | and is included. */ | ||
868 | static u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest) | ||
869 | { | ||
870 | int i; | ||
871 | |||
872 | for(i = 0; i < count; i++) | ||
873 | crc = crc8((crc ^ first[i]) << 8); | ||
874 | if(rest != NULL) | ||
875 | for(i = 0; i <= rest[0]; i++) | ||
876 | crc = crc8((crc ^ rest[i]) << 8); | ||
877 | return crc; | ||
878 | } | ||
879 | |||
880 | static u8 i2c_smbus_pec(int count, u8 *first, u8 *rest) | ||
881 | { | ||
882 | return i2c_smbus_partial_pec(0, count, first, rest); | ||
883 | } | ||
884 | |||
885 | /* Returns new "size" (transaction type) | ||
886 | Note that we convert byte to byte_data and byte_data to word_data | ||
887 | rather than invent new xxx_PEC transactions. */ | ||
888 | static int i2c_smbus_add_pec(u16 addr, u8 command, int size, | ||
889 | union i2c_smbus_data *data) | ||
890 | { | ||
891 | u8 buf[3]; | ||
892 | |||
893 | buf[0] = addr << 1; | ||
894 | buf[1] = command; | ||
895 | switch(size) { | ||
896 | case I2C_SMBUS_BYTE: | ||
897 | data->byte = i2c_smbus_pec(2, buf, NULL); | ||
898 | size = I2C_SMBUS_BYTE_DATA; | ||
899 | break; | ||
900 | case I2C_SMBUS_BYTE_DATA: | ||
901 | buf[2] = data->byte; | ||
902 | data->word = buf[2] || | ||
903 | (i2c_smbus_pec(3, buf, NULL) << 8); | ||
904 | size = I2C_SMBUS_WORD_DATA; | ||
905 | break; | ||
906 | case I2C_SMBUS_WORD_DATA: | ||
907 | /* unsupported */ | ||
908 | break; | ||
909 | case I2C_SMBUS_BLOCK_DATA: | ||
910 | data->block[data->block[0] + 1] = | ||
911 | i2c_smbus_pec(2, buf, data->block); | ||
912 | size = I2C_SMBUS_BLOCK_DATA_PEC; | ||
913 | break; | ||
914 | } | ||
915 | return size; | ||
916 | } | ||
917 | |||
918 | static int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial, | ||
919 | union i2c_smbus_data *data) | ||
920 | { | ||
921 | u8 buf[3], rpec, cpec; | ||
922 | |||
923 | buf[1] = command; | ||
924 | switch(size) { | ||
925 | case I2C_SMBUS_BYTE_DATA: | ||
926 | buf[0] = (addr << 1) | 1; | ||
927 | cpec = i2c_smbus_pec(2, buf, NULL); | ||
928 | rpec = data->byte; | ||
929 | break; | ||
930 | case I2C_SMBUS_WORD_DATA: | ||
931 | buf[0] = (addr << 1) | 1; | ||
932 | buf[2] = data->word & 0xff; | ||
933 | cpec = i2c_smbus_pec(3, buf, NULL); | ||
934 | rpec = data->word >> 8; | ||
935 | break; | ||
936 | case I2C_SMBUS_WORD_DATA_PEC: | ||
937 | /* unsupported */ | ||
938 | cpec = rpec = 0; | ||
939 | break; | ||
940 | case I2C_SMBUS_PROC_CALL_PEC: | ||
941 | /* unsupported */ | ||
942 | cpec = rpec = 0; | ||
943 | break; | ||
944 | case I2C_SMBUS_BLOCK_DATA_PEC: | ||
945 | buf[0] = (addr << 1); | ||
946 | buf[2] = (addr << 1) | 1; | ||
947 | cpec = i2c_smbus_pec(3, buf, data->block); | ||
948 | rpec = data->block[data->block[0] + 1]; | ||
949 | break; | ||
950 | case I2C_SMBUS_BLOCK_PROC_CALL_PEC: | ||
951 | buf[0] = (addr << 1) | 1; | ||
952 | rpec = i2c_smbus_partial_pec(partial, 1, | ||
953 | buf, data->block); | ||
954 | cpec = data->block[data->block[0] + 1]; | ||
955 | break; | ||
956 | default: | ||
957 | cpec = rpec = 0; | ||
958 | break; | ||
959 | } | ||
960 | if (rpec != cpec) { | ||
961 | pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n", | ||
962 | rpec, cpec); | ||
963 | return -1; | ||
964 | } | ||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value) | ||
969 | { | ||
970 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
971 | value,0,I2C_SMBUS_QUICK,NULL); | ||
972 | } | ||
973 | |||
974 | s32 i2c_smbus_read_byte(struct i2c_client *client) | ||
975 | { | ||
976 | union i2c_smbus_data data; | ||
977 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
978 | I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data)) | ||
979 | return -1; | ||
980 | else | ||
981 | return 0x0FF & data.byte; | ||
982 | } | ||
983 | |||
984 | s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) | ||
985 | { | ||
986 | union i2c_smbus_data data; /* only for PEC */ | ||
987 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
988 | I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,&data); | ||
989 | } | ||
990 | |||
991 | s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) | ||
992 | { | ||
993 | union i2c_smbus_data data; | ||
994 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
995 | I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data)) | ||
996 | return -1; | ||
997 | else | ||
998 | return 0x0FF & data.byte; | ||
999 | } | ||
1000 | |||
1001 | s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) | ||
1002 | { | ||
1003 | union i2c_smbus_data data; | ||
1004 | data.byte = value; | ||
1005 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
1006 | I2C_SMBUS_WRITE,command, | ||
1007 | I2C_SMBUS_BYTE_DATA,&data); | ||
1008 | } | ||
1009 | |||
1010 | s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) | ||
1011 | { | ||
1012 | union i2c_smbus_data data; | ||
1013 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
1014 | I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data)) | ||
1015 | return -1; | ||
1016 | else | ||
1017 | return 0x0FFFF & data.word; | ||
1018 | } | ||
1019 | |||
1020 | s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) | ||
1021 | { | ||
1022 | union i2c_smbus_data data; | ||
1023 | data.word = value; | ||
1024 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
1025 | I2C_SMBUS_WRITE,command, | ||
1026 | I2C_SMBUS_WORD_DATA,&data); | ||
1027 | } | ||
1028 | |||
1029 | s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, | ||
1030 | u8 length, u8 *values) | ||
1031 | { | ||
1032 | union i2c_smbus_data data; | ||
1033 | int i; | ||
1034 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
1035 | length = I2C_SMBUS_BLOCK_MAX; | ||
1036 | for (i = 1; i <= length; i++) | ||
1037 | data.block[i] = values[i-1]; | ||
1038 | data.block[0] = length; | ||
1039 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
1040 | I2C_SMBUS_WRITE,command, | ||
1041 | I2C_SMBUS_BLOCK_DATA,&data); | ||
1042 | } | ||
1043 | |||
1044 | /* Returns the number of read bytes */ | ||
1045 | s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values) | ||
1046 | { | ||
1047 | union i2c_smbus_data data; | ||
1048 | int i; | ||
1049 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, | ||
1050 | I2C_SMBUS_READ,command, | ||
1051 | I2C_SMBUS_I2C_BLOCK_DATA,&data)) | ||
1052 | return -1; | ||
1053 | else { | ||
1054 | for (i = 1; i <= data.block[0]; i++) | ||
1055 | values[i-1] = data.block[i]; | ||
1056 | return data.block[0]; | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | /* Simulate a SMBus command using the i2c protocol | ||
1061 | No checking of parameters is done! */ | ||
1062 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, | ||
1063 | unsigned short flags, | ||
1064 | char read_write, u8 command, int size, | ||
1065 | union i2c_smbus_data * data) | ||
1066 | { | ||
1067 | /* So we need to generate a series of msgs. In the case of writing, we | ||
1068 | need to use only one message; when reading, we need two. We initialize | ||
1069 | most things with sane defaults, to keep the code below somewhat | ||
1070 | simpler. */ | ||
1071 | unsigned char msgbuf0[34]; | ||
1072 | unsigned char msgbuf1[34]; | ||
1073 | int num = read_write == I2C_SMBUS_READ?2:1; | ||
1074 | struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, | ||
1075 | { addr, flags | I2C_M_RD, 0, msgbuf1 } | ||
1076 | }; | ||
1077 | int i; | ||
1078 | |||
1079 | msgbuf0[0] = command; | ||
1080 | switch(size) { | ||
1081 | case I2C_SMBUS_QUICK: | ||
1082 | msg[0].len = 0; | ||
1083 | /* Special case: The read/write field is used as data */ | ||
1084 | msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; | ||
1085 | num = 1; | ||
1086 | break; | ||
1087 | case I2C_SMBUS_BYTE: | ||
1088 | if (read_write == I2C_SMBUS_READ) { | ||
1089 | /* Special case: only a read! */ | ||
1090 | msg[0].flags = I2C_M_RD | flags; | ||
1091 | num = 1; | ||
1092 | } | ||
1093 | break; | ||
1094 | case I2C_SMBUS_BYTE_DATA: | ||
1095 | if (read_write == I2C_SMBUS_READ) | ||
1096 | msg[1].len = 1; | ||
1097 | else { | ||
1098 | msg[0].len = 2; | ||
1099 | msgbuf0[1] = data->byte; | ||
1100 | } | ||
1101 | break; | ||
1102 | case I2C_SMBUS_WORD_DATA: | ||
1103 | if (read_write == I2C_SMBUS_READ) | ||
1104 | msg[1].len = 2; | ||
1105 | else { | ||
1106 | msg[0].len=3; | ||
1107 | msgbuf0[1] = data->word & 0xff; | ||
1108 | msgbuf0[2] = (data->word >> 8) & 0xff; | ||
1109 | } | ||
1110 | break; | ||
1111 | case I2C_SMBUS_PROC_CALL: | ||
1112 | num = 2; /* Special case */ | ||
1113 | read_write = I2C_SMBUS_READ; | ||
1114 | msg[0].len = 3; | ||
1115 | msg[1].len = 2; | ||
1116 | msgbuf0[1] = data->word & 0xff; | ||
1117 | msgbuf0[2] = (data->word >> 8) & 0xff; | ||
1118 | break; | ||
1119 | case I2C_SMBUS_BLOCK_DATA: | ||
1120 | case I2C_SMBUS_BLOCK_DATA_PEC: | ||
1121 | if (read_write == I2C_SMBUS_READ) { | ||
1122 | dev_err(&adapter->dev, "Block read not supported " | ||
1123 | "under I2C emulation!\n"); | ||
1124 | return -1; | ||
1125 | } else { | ||
1126 | msg[0].len = data->block[0] + 2; | ||
1127 | if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { | ||
1128 | dev_err(&adapter->dev, "smbus_access called with " | ||
1129 | "invalid block write size (%d)\n", | ||
1130 | data->block[0]); | ||
1131 | return -1; | ||
1132 | } | ||
1133 | if(size == I2C_SMBUS_BLOCK_DATA_PEC) | ||
1134 | (msg[0].len)++; | ||
1135 | for (i = 1; i <= msg[0].len; i++) | ||
1136 | msgbuf0[i] = data->block[i-1]; | ||
1137 | } | ||
1138 | break; | ||
1139 | case I2C_SMBUS_BLOCK_PROC_CALL: | ||
1140 | case I2C_SMBUS_BLOCK_PROC_CALL_PEC: | ||
1141 | dev_dbg(&adapter->dev, "Block process call not supported " | ||
1142 | "under I2C emulation!\n"); | ||
1143 | return -1; | ||
1144 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
1145 | if (read_write == I2C_SMBUS_READ) { | ||
1146 | msg[1].len = I2C_SMBUS_I2C_BLOCK_MAX; | ||
1147 | } else { | ||
1148 | msg[0].len = data->block[0] + 1; | ||
1149 | if (msg[0].len > I2C_SMBUS_I2C_BLOCK_MAX + 1) { | ||
1150 | dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with " | ||
1151 | "invalid block write size (%d)\n", | ||
1152 | data->block[0]); | ||
1153 | return -1; | ||
1154 | } | ||
1155 | for (i = 1; i <= data->block[0]; i++) | ||
1156 | msgbuf0[i] = data->block[i]; | ||
1157 | } | ||
1158 | break; | ||
1159 | default: | ||
1160 | dev_err(&adapter->dev, "smbus_access called with invalid size (%d)\n", | ||
1161 | size); | ||
1162 | return -1; | ||
1163 | } | ||
1164 | |||
1165 | if (i2c_transfer(adapter, msg, num) < 0) | ||
1166 | return -1; | ||
1167 | |||
1168 | if (read_write == I2C_SMBUS_READ) | ||
1169 | switch(size) { | ||
1170 | case I2C_SMBUS_BYTE: | ||
1171 | data->byte = msgbuf0[0]; | ||
1172 | break; | ||
1173 | case I2C_SMBUS_BYTE_DATA: | ||
1174 | data->byte = msgbuf1[0]; | ||
1175 | break; | ||
1176 | case I2C_SMBUS_WORD_DATA: | ||
1177 | case I2C_SMBUS_PROC_CALL: | ||
1178 | data->word = msgbuf1[0] | (msgbuf1[1] << 8); | ||
1179 | break; | ||
1180 | case I2C_SMBUS_I2C_BLOCK_DATA: | ||
1181 | /* fixed at 32 for now */ | ||
1182 | data->block[0] = I2C_SMBUS_I2C_BLOCK_MAX; | ||
1183 | for (i = 0; i < I2C_SMBUS_I2C_BLOCK_MAX; i++) | ||
1184 | data->block[i+1] = msgbuf1[i]; | ||
1185 | break; | ||
1186 | } | ||
1187 | return 0; | ||
1188 | } | ||
1189 | |||
1190 | |||
1191 | s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, | ||
1192 | char read_write, u8 command, int size, | ||
1193 | union i2c_smbus_data * data) | ||
1194 | { | ||
1195 | s32 res; | ||
1196 | int swpec = 0; | ||
1197 | u8 partial = 0; | ||
1198 | |||
1199 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; | ||
1200 | if((flags & I2C_CLIENT_PEC) && | ||
1201 | !(i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HWPEC_CALC))) { | ||
1202 | swpec = 1; | ||
1203 | if(read_write == I2C_SMBUS_READ && | ||
1204 | size == I2C_SMBUS_BLOCK_DATA) | ||
1205 | size = I2C_SMBUS_BLOCK_DATA_PEC; | ||
1206 | else if(size == I2C_SMBUS_PROC_CALL) | ||
1207 | size = I2C_SMBUS_PROC_CALL_PEC; | ||
1208 | else if(size == I2C_SMBUS_BLOCK_PROC_CALL) { | ||
1209 | i2c_smbus_add_pec(addr, command, | ||
1210 | I2C_SMBUS_BLOCK_DATA, data); | ||
1211 | partial = data->block[data->block[0] + 1]; | ||
1212 | size = I2C_SMBUS_BLOCK_PROC_CALL_PEC; | ||
1213 | } else if(read_write == I2C_SMBUS_WRITE && | ||
1214 | size != I2C_SMBUS_QUICK && | ||
1215 | size != I2C_SMBUS_I2C_BLOCK_DATA) | ||
1216 | size = i2c_smbus_add_pec(addr, command, size, data); | ||
1217 | } | ||
1218 | |||
1219 | if (adapter->algo->smbus_xfer) { | ||
1220 | down(&adapter->bus_lock); | ||
1221 | res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, | ||
1222 | command,size,data); | ||
1223 | up(&adapter->bus_lock); | ||
1224 | } else | ||
1225 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, | ||
1226 | command,size,data); | ||
1227 | |||
1228 | if(res >= 0 && swpec && | ||
1229 | size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA && | ||
1230 | (read_write == I2C_SMBUS_READ || size == I2C_SMBUS_PROC_CALL_PEC || | ||
1231 | size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) { | ||
1232 | if(i2c_smbus_check_pec(addr, command, size, partial, data)) | ||
1233 | return -1; | ||
1234 | } | ||
1235 | return res; | ||
1236 | } | ||
1237 | |||
1238 | |||
1239 | EXPORT_SYMBOL(i2c_add_adapter); | ||
1240 | EXPORT_SYMBOL(i2c_del_adapter); | ||
1241 | EXPORT_SYMBOL(i2c_add_driver); | ||
1242 | EXPORT_SYMBOL(i2c_del_driver); | ||
1243 | EXPORT_SYMBOL(i2c_attach_client); | ||
1244 | EXPORT_SYMBOL(i2c_detach_client); | ||
1245 | EXPORT_SYMBOL(i2c_use_client); | ||
1246 | EXPORT_SYMBOL(i2c_release_client); | ||
1247 | EXPORT_SYMBOL(i2c_clients_command); | ||
1248 | EXPORT_SYMBOL(i2c_check_addr); | ||
1249 | |||
1250 | EXPORT_SYMBOL(i2c_master_send); | ||
1251 | EXPORT_SYMBOL(i2c_master_recv); | ||
1252 | EXPORT_SYMBOL(i2c_control); | ||
1253 | EXPORT_SYMBOL(i2c_transfer); | ||
1254 | EXPORT_SYMBOL(i2c_adapter_id); | ||
1255 | EXPORT_SYMBOL(i2c_get_adapter); | ||
1256 | EXPORT_SYMBOL(i2c_put_adapter); | ||
1257 | EXPORT_SYMBOL(i2c_probe); | ||
1258 | |||
1259 | EXPORT_SYMBOL(i2c_smbus_xfer); | ||
1260 | EXPORT_SYMBOL(i2c_smbus_write_quick); | ||
1261 | EXPORT_SYMBOL(i2c_smbus_read_byte); | ||
1262 | EXPORT_SYMBOL(i2c_smbus_write_byte); | ||
1263 | EXPORT_SYMBOL(i2c_smbus_read_byte_data); | ||
1264 | EXPORT_SYMBOL(i2c_smbus_write_byte_data); | ||
1265 | EXPORT_SYMBOL(i2c_smbus_read_word_data); | ||
1266 | EXPORT_SYMBOL(i2c_smbus_write_word_data); | ||
1267 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | ||
1268 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | ||
1269 | |||
1270 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); | ||
1271 | MODULE_DESCRIPTION("I2C-Bus main module"); | ||
1272 | MODULE_LICENSE("GPL"); | ||