Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
170 | giacomo | 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 | /* SHARK version by Giacomo Guidi <giacomo@gandalf.sssup.it> */ |
||
21 | |||
22 | #include <stdio.h> |
||
23 | #include <stdlib.h> |
||
24 | #include <stdio.h> |
||
25 | |||
26 | #include <kernel/log.h> |
||
27 | #include <asm/errno.h> |
||
28 | |||
29 | #include "drivers/i2c.h" |
||
30 | |||
31 | #define DEB(x) if (i2c_debug>=1) x; |
||
32 | #define DEB2(x) if (i2c_debug>=2) x; |
||
33 | |||
34 | /* ----- global variables -------------------------------------------------- */ |
||
35 | |||
36 | /**** adapter list */ |
||
37 | static struct i2c_adapter *adapters[I2C_ADAP_MAX]; |
||
38 | static int adap_count; |
||
39 | |||
40 | /**** drivers list */ |
||
41 | static struct i2c_driver *drivers[I2C_DRIVER_MAX]; |
||
42 | static int driver_count; |
||
43 | |||
44 | /**** debug level */ |
||
45 | static int i2c_debug = 0; |
||
46 | |||
47 | #define i2cproc_init() 0 |
||
48 | #define i2cproc_cleanup() 0 |
||
49 | |||
50 | /* --------------------------------------------------- |
||
51 | * registering functions |
||
52 | * --------------------------------------------------- |
||
53 | */ |
||
54 | |||
55 | /* ----- |
||
56 | * i2c_add_adapter is called from within the algorithm layer, |
||
57 | * when a new hw adapter registers. A new device is register to be |
||
58 | * available for clients. |
||
59 | */ |
||
60 | int i2c_add_adapter(struct i2c_adapter *adap) |
||
61 | { |
||
62 | int i,j,res; |
||
63 | |||
64 | for (i = 0; i < I2C_ADAP_MAX; i++) |
||
65 | if (NULL == adapters[i]) |
||
66 | break; |
||
67 | if (I2C_ADAP_MAX == i) { |
||
68 | printk(KERN_INFO"i2c-core.o: register_adapter(%s) - enlarge I2C_ADAP_MAX.\n", adap->name); |
||
69 | res = -ENOMEM; |
||
70 | goto ERROR0; |
||
71 | } |
||
72 | |||
73 | adapters[i] = adap; |
||
74 | adap_count++; |
||
75 | |||
76 | /* inform drivers of new adapters */ |
||
77 | for (j=0;j<I2C_DRIVER_MAX;j++) |
||
78 | if (drivers[j]!=NULL && |
||
79 | (drivers[j]->flags&(I2C_DF_NOTIFY|I2C_DF_DUMMY))) |
||
80 | /* We ignore the return code; if it fails, too bad */ |
||
81 | drivers[j]->attach_adapter(adap); |
||
82 | |||
83 | printk(KERN_INFO "i2c-core.o: adapter %s registered as adapter %d.\n", adap->name,i); |
||
84 | |||
85 | return 0; |
||
86 | |||
87 | ERROR0: |
||
88 | return res; |
||
89 | } |
||
90 | |||
91 | |||
92 | int i2c_del_adapter(struct i2c_adapter *adap) |
||
93 | { |
||
94 | int i,j,res; |
||
95 | |||
96 | for (i = 0; i < I2C_ADAP_MAX; i++) |
||
97 | if (adap == adapters[i]) |
||
98 | break; |
||
99 | if (I2C_ADAP_MAX == i) { |
||
100 | printk(KERN_INFO "i2c-core.o: unregister_adapter adap [%s] not found.\n", |
||
101 | adap->name); |
||
102 | res = -ENODEV; |
||
103 | goto ERROR0; |
||
104 | } |
||
105 | |||
106 | /* DUMMY drivers do not register their clients, so we have to |
||
107 | * use a trick here: we call driver->attach_adapter to |
||
108 | * *detach* it! Of course, each dummy driver should know about |
||
109 | * this or hell will break loose... |
||
110 | */ |
||
111 | for (j = 0; j < I2C_DRIVER_MAX; j++) |
||
112 | if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY)) |
||
113 | if ((res = drivers[j]->attach_adapter(adap))) { |
||
114 | cprintf("i2c-core.o: can't detach adapter %s " |
||
115 | "while detaching driver %s: driver not " |
||
116 | "detached!",adap->name,drivers[j]->name); |
||
117 | goto ERROR1; |
||
118 | } |
||
119 | |||
120 | /* detach any active clients. This must be done first, because |
||
121 | * it can fail; in which case we give upp. */ |
||
122 | for (j=0;j<I2C_CLIENT_MAX;j++) { |
||
123 | struct i2c_client *client = adap->clients[j]; |
||
124 | if (client!=NULL) |
||
125 | /* detaching devices is unconditional of the set notify |
||
126 | * flag, as _all_ clients that reside on the adapter |
||
127 | * must be deleted, as this would cause invalid states. |
||
128 | */ |
||
129 | if ((res=client->driver->detach_client(client))) { |
||
130 | cprintf("i2c-core.o: adapter %s not " |
||
131 | "unregistered, because client at " |
||
132 | "address %02x can't be detached. ", |
||
133 | adap->name, client->addr); |
||
134 | goto ERROR0; |
||
135 | } |
||
136 | } |
||
137 | |||
138 | adapters[i] = NULL; |
||
139 | adap_count--; |
||
140 | |||
141 | DEB(cprintf("i2c-core.o: adapter unregistered: %s\n",adap->name)); |
||
142 | |||
143 | return 0; |
||
144 | |||
145 | ERROR0: |
||
146 | return res; |
||
147 | ERROR1: |
||
148 | return res; |
||
149 | } |
||
150 | |||
151 | |||
152 | /* ----- |
||
153 | * What follows is the "upwards" interface: commands for talking to clients, |
||
154 | * which implement the functions to access the physical information of the |
||
155 | * chips. |
||
156 | */ |
||
157 | |||
158 | int i2c_add_driver(struct i2c_driver *driver) |
||
159 | { |
||
160 | int i; |
||
161 | for (i = 0; i < I2C_DRIVER_MAX; i++) |
||
162 | if (NULL == drivers[i]) |
||
163 | break; |
||
164 | if (I2C_DRIVER_MAX == i) { |
||
165 | printk(KERN_INFO "i2c-core.o: register_driver(%s) " |
||
166 | "- enlarge I2C_DRIVER_MAX.\n", |
||
167 | driver->name); |
||
168 | return -ENOMEM; |
||
169 | } |
||
170 | |||
171 | drivers[i] = driver; |
||
172 | driver_count++; |
||
173 | |||
174 | DEB(cprintf("i2c-core.o: driver %s registered.\n",driver->name)); |
||
175 | |||
176 | /* now look for instances of driver on our adapters |
||
177 | */ |
||
178 | if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) { |
||
179 | for (i=0;i<I2C_ADAP_MAX;i++) |
||
180 | if (adapters[i]!=NULL) |
||
181 | /* Ignore errors */ |
||
182 | driver->attach_adapter(adapters[i]); |
||
183 | } |
||
184 | return 0; |
||
185 | } |
||
186 | |||
187 | int i2c_del_driver(struct i2c_driver *driver) |
||
188 | { |
||
189 | int i,j,k,res; |
||
190 | |||
191 | for (i = 0; i < I2C_DRIVER_MAX; i++) |
||
192 | if (driver == drivers[i]) |
||
193 | break; |
||
194 | if (I2C_DRIVER_MAX == i) { |
||
195 | printk(KERN_INFO "i2c-core.o: unregister_driver: " |
||
196 | "[%s] not found\n", |
||
197 | driver->name); |
||
198 | return -ENODEV; |
||
199 | } |
||
200 | /* Have a look at each adapter, if clients of this driver are still |
||
201 | * attached. If so, detach them to be able to kill the driver |
||
202 | * afterwards. |
||
203 | */ |
||
204 | DEB2(cprintf("i2c-core.o: unregister_driver - looking for clients.\n")); |
||
205 | /* removing clients does not depend on the notify flag, else |
||
206 | * invalid operation might (will!) result, when using stale client |
||
207 | * pointers. |
||
208 | */ |
||
209 | for (k=0;k<I2C_ADAP_MAX;k++) { |
||
210 | struct i2c_adapter *adap = adapters[k]; |
||
211 | if (adap == NULL) /* skip empty entries. */ |
||
212 | continue; |
||
213 | DEB2(cprintf("i2c-core.o: examining adapter %s:\n", |
||
214 | adap->name)); |
||
215 | if (driver->flags & I2C_DF_DUMMY) { |
||
216 | /* DUMMY drivers do not register their clients, so we have to |
||
217 | * use a trick here: we call driver->attach_adapter to |
||
218 | * *detach* it! Of course, each dummy driver should know about |
||
219 | * this or hell will break loose... |
||
220 | */ |
||
221 | if ((res = driver->attach_adapter(adap))) { |
||
222 | cprintf("i2c-core.o: while unregistering " |
||
223 | "dummy driver %s, adapter %s could " |
||
224 | "not be detached properly; driver " |
||
225 | "not unloaded!",driver->name, |
||
226 | adap->name); |
||
227 | return res; |
||
228 | } |
||
229 | } else { |
||
230 | for (j=0;j<I2C_CLIENT_MAX;j++) { |
||
231 | struct i2c_client *client = adap->clients[j]; |
||
232 | if (client != NULL && |
||
233 | client->driver == driver) { |
||
234 | DEB2(cprintf("i2c-core.o: " |
||
235 | "detaching client %s:\n", |
||
236 | client->name)); |
||
237 | if ((res = driver-> |
||
238 | detach_client(client))) |
||
239 | { |
||
240 | cprintf("i2c-core.o: while " |
||
241 | "unregistering driver " |
||
242 | "`%s', the client at " |
||
243 | "address %02x of " |
||
244 | "adapter `%s' could not" |
||
245 | "be detached; driver" |
||
246 | "not unloaded!", |
||
247 | driver->name, |
||
248 | client->addr, |
||
249 | adap->name); |
||
250 | return res; |
||
251 | } |
||
252 | } |
||
253 | } |
||
254 | } |
||
255 | } |
||
256 | drivers[i] = NULL; |
||
257 | driver_count--; |
||
258 | |||
259 | DEB(cprintf("i2c-core.o: driver unregistered: %s\n",driver->name)); |
||
260 | return 0; |
||
261 | } |
||
262 | |||
263 | int i2c_check_addr (struct i2c_adapter *adapter, int addr) |
||
264 | { |
||
265 | int i; |
||
266 | for (i = 0; i < I2C_CLIENT_MAX ; i++) |
||
267 | if (adapter->clients[i] && (adapter->clients[i]->addr == addr)) |
||
268 | return -EBUSY; |
||
269 | return 0; |
||
270 | } |
||
271 | |||
272 | int i2c_attach_client(struct i2c_client *client) |
||
273 | { |
||
274 | struct i2c_adapter *adapter = client->adapter; |
||
275 | int i; |
||
276 | |||
277 | if (i2c_check_addr(client->adapter,client->addr)) |
||
278 | return -EBUSY; |
||
279 | |||
280 | for (i = 0; i < I2C_CLIENT_MAX; i++) |
||
281 | if (NULL == adapter->clients[i]) |
||
282 | break; |
||
283 | if (I2C_CLIENT_MAX == i) { |
||
284 | printk(KERN_INFO "i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n", |
||
285 | client->name); |
||
286 | return -ENOMEM; |
||
287 | } |
||
288 | |||
289 | adapter->clients[i] = client; |
||
290 | adapter->client_count++; |
||
291 | |||
292 | if (adapter->client_register) |
||
293 | if (adapter->client_register(client)) |
||
294 | cprintf("i2c-core.o: warning: client_register seems " |
||
295 | "to have failed for client %02x at adapter %s\n", |
||
296 | client->addr,adapter->name); |
||
297 | DEB(cprintf("i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n", |
||
298 | client->name, adapter->name,i)); |
||
299 | |||
300 | if(client->flags & I2C_CLIENT_ALLOW_USE) |
||
301 | client->usage_count = 0; |
||
302 | |||
303 | return 0; |
||
304 | } |
||
305 | |||
306 | |||
307 | int i2c_detach_client(struct i2c_client *client) |
||
308 | { |
||
309 | struct i2c_adapter *adapter = client->adapter; |
||
310 | int i,res; |
||
311 | |||
312 | for (i = 0; i < I2C_CLIENT_MAX; i++) |
||
313 | if (client == adapter->clients[i]) |
||
314 | break; |
||
315 | if (I2C_CLIENT_MAX == i) { |
||
316 | cprintf("i2c-core.o: unregister_client " |
||
317 | "[%s] not found\n", |
||
318 | client->name); |
||
319 | return -ENODEV; |
||
320 | } |
||
321 | |||
322 | if( (client->flags & I2C_CLIENT_ALLOW_USE) && |
||
323 | (client->usage_count>0)) |
||
324 | return -EBUSY; |
||
325 | |||
326 | if (adapter->client_unregister != NULL) |
||
327 | if ((res = adapter->client_unregister(client))) { |
||
328 | cprintf("i2c-core.o: client_unregister [%s] failed, " |
||
329 | "client not detached",client->name); |
||
330 | return res; |
||
331 | } |
||
332 | |||
333 | adapter->clients[i] = NULL; |
||
334 | adapter->client_count--; |
||
335 | |||
336 | DEB(cprintf("i2c-core.o: client [%s] unregistered.\n",client->name)); |
||
337 | return 0; |
||
338 | } |
||
339 | |||
340 | void i2c_inc_use_client(struct i2c_client *client) |
||
341 | { |
||
342 | |||
343 | if (client->driver->inc_use != NULL) |
||
344 | client->driver->inc_use(client); |
||
345 | |||
346 | if (client->adapter->inc_use != NULL) |
||
347 | client->adapter->inc_use(client->adapter); |
||
348 | } |
||
349 | |||
350 | void i2c_dec_use_client(struct i2c_client *client) |
||
351 | { |
||
352 | |||
353 | if (client->driver->dec_use != NULL) |
||
354 | client->driver->dec_use(client); |
||
355 | |||
356 | if (client->adapter->dec_use != NULL) |
||
357 | client->adapter->dec_use(client->adapter); |
||
358 | } |
||
359 | |||
360 | struct i2c_client *i2c_get_client(int driver_id, int adapter_id, |
||
361 | struct i2c_client *prev) |
||
362 | { |
||
363 | int i,j; |
||
364 | |||
365 | /* Will iterate through the list of clients in each adapter of adapters-list |
||
366 | in search for a client that matches the search criteria. driver_id or |
||
367 | adapter_id are ignored if set to 0. If both are ignored this returns |
||
368 | first client found. */ |
||
369 | |||
370 | i = j = 0; |
||
371 | |||
372 | /* set starting point */ |
||
373 | if(prev) |
||
374 | { |
||
375 | if(!(prev->adapter)) |
||
376 | return (struct i2c_client *) -EINVAL; |
||
377 | |||
378 | for(j=0; j < I2C_ADAP_MAX; j++) |
||
379 | if(prev->adapter == adapters[j]) |
||
380 | break; |
||
381 | |||
382 | /* invalid starting point? */ |
||
383 | if (I2C_ADAP_MAX == j) { |
||
384 | printk(KERN_INFO "i2c-core.o: get_client adapter for client:[%s] not found\n", |
||
385 | prev->name); |
||
386 | return (struct i2c_client *) -ENODEV; |
||
387 | } |
||
388 | |||
389 | for(i=0; i < I2C_CLIENT_MAX; i++) |
||
390 | if(prev == adapters[j]->clients[i]) |
||
391 | break; |
||
392 | |||
393 | /* invalid starting point? */ |
||
394 | if (I2C_CLIENT_MAX == i) { |
||
395 | printk(KERN_INFO "i2c-core.o: get_client client:[%s] not found\n", |
||
396 | prev->name); |
||
397 | return (struct i2c_client *) -ENODEV; |
||
398 | } |
||
399 | |||
400 | i++; /* start from one after prev */ |
||
401 | } |
||
402 | |||
403 | for(; j < I2C_ADAP_MAX; j++) |
||
404 | { |
||
405 | if(!adapters[j]) |
||
406 | continue; |
||
407 | |||
408 | if(adapter_id && (adapters[j]->id != adapter_id)) |
||
409 | continue; |
||
410 | |||
411 | for(; i < I2C_CLIENT_MAX; i++) |
||
412 | { |
||
413 | if(!adapters[j]->clients[i]) |
||
414 | continue; |
||
415 | |||
416 | if(driver_id && (adapters[j]->clients[i]->driver->id != driver_id)) |
||
417 | continue; |
||
418 | if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE) |
||
419 | return adapters[j]->clients[i]; |
||
420 | } |
||
421 | i = 0; |
||
422 | } |
||
423 | |||
424 | return 0; |
||
425 | } |
||
426 | |||
427 | int i2c_use_client(struct i2c_client *client) |
||
428 | { |
||
429 | if(client->flags & I2C_CLIENT_ALLOW_USE) { |
||
430 | if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) |
||
431 | client->usage_count++; |
||
432 | else { |
||
433 | if(client->usage_count > 0) |
||
434 | return -EBUSY; |
||
435 | else |
||
436 | client->usage_count++; |
||
437 | } |
||
438 | } |
||
439 | |||
440 | i2c_inc_use_client(client); |
||
441 | |||
442 | return 0; |
||
443 | } |
||
444 | |||
445 | int i2c_release_client(struct i2c_client *client) |
||
446 | { |
||
447 | if(client->flags & I2C_CLIENT_ALLOW_USE) { |
||
448 | if(client->usage_count>0) |
||
449 | client->usage_count--; |
||
450 | else |
||
451 | { |
||
452 | cprintf("i2c-core.o: dec_use_client used one too many times\n"); |
||
453 | return -EPERM; |
||
454 | } |
||
455 | } |
||
456 | |||
457 | i2c_dec_use_client(client); |
||
458 | |||
459 | return 0; |
||
460 | } |
||
461 | |||
462 | /* ---------------------------------------------------- |
||
463 | * the functional interface to the i2c busses. |
||
464 | * ---------------------------------------------------- |
||
465 | */ |
||
466 | |||
467 | int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg msgs[],int num) |
||
468 | { |
||
469 | int ret; |
||
470 | |||
471 | if (adap->algo->master_xfer) { |
||
472 | DEB2(cprintf("i2c-core.o: master_xfer: %s with %d msgs.\n", |
||
473 | adap->name,num)); |
||
474 | |||
475 | ret = adap->algo->master_xfer(adap,msgs,num); |
||
476 | |||
477 | return ret; |
||
478 | } else { |
||
479 | printk(KERN_INFO "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", |
||
480 | adap->id); |
||
481 | return -ENOSYS; |
||
482 | } |
||
483 | } |
||
484 | |||
485 | int i2c_master_send(struct i2c_client *client,const char *buf ,int count) |
||
486 | { |
||
487 | int ret; |
||
488 | struct i2c_adapter *adap=client->adapter; |
||
489 | struct i2c_msg msg; |
||
490 | |||
491 | if (client->adapter->algo->master_xfer) { |
||
492 | msg.addr = client->addr; |
||
493 | msg.flags = client->flags & I2C_M_TEN; |
||
494 | msg.len = count; |
||
495 | (const char *)msg.buf = buf; |
||
496 | |||
497 | DEB2(cprintf("i2c-core.o: master_send: writing %d bytes on %s.\n", |
||
498 | count,client->adapter->name)); |
||
499 | |||
500 | ret = adap->algo->master_xfer(adap,&msg,1); |
||
501 | |||
502 | /* if everything went ok (i.e. 1 msg transmitted), return #bytes |
||
503 | * transmitted, else error code. |
||
504 | */ |
||
505 | return (ret == 1 )? count : ret; |
||
506 | } else { |
||
507 | printk(KERN_INFO "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", |
||
508 | client->adapter->id); |
||
509 | return -ENOSYS; |
||
510 | } |
||
511 | } |
||
512 | |||
513 | int i2c_master_recv(struct i2c_client *client, char *buf ,int count) |
||
514 | { |
||
515 | struct i2c_adapter *adap=client->adapter; |
||
516 | struct i2c_msg msg; |
||
517 | int ret; |
||
518 | if (client->adapter->algo->master_xfer) { |
||
519 | msg.addr = client->addr; |
||
520 | msg.flags = client->flags & I2C_M_TEN; |
||
521 | msg.flags |= I2C_M_RD; |
||
522 | msg.len = count; |
||
523 | msg.buf = buf; |
||
524 | |||
525 | DEB2(cprintf("i2c-core.o: master_recv: reading %d bytes on %s.\n", |
||
526 | count,client->adapter->name)); |
||
527 | |||
528 | ret = adap->algo->master_xfer(adap,&msg,1); |
||
529 | |||
530 | DEB2(cprintf("i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n", |
||
531 | ret, count, client->addr)); |
||
532 | |||
533 | /* if everything went ok (i.e. 1 msg transmitted), return #bytes |
||
534 | * transmitted, else error code. |
||
535 | */ |
||
536 | return (ret == 1 )? count : ret; |
||
537 | } else { |
||
538 | printk(KERN_INFO "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n", |
||
539 | client->adapter->id); |
||
540 | return -ENOSYS; |
||
541 | } |
||
542 | } |
||
543 | |||
544 | |||
545 | int i2c_control(struct i2c_client *client, |
||
546 | unsigned int cmd, unsigned long arg) |
||
547 | { |
||
548 | int ret = 0; |
||
549 | struct i2c_adapter *adap = client->adapter; |
||
550 | |||
551 | DEB2(cprintf("i2c-core.o: i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg)); |
||
552 | switch ( cmd ) { |
||
553 | case I2C_RETRIES: |
||
554 | adap->retries = arg; |
||
555 | break; |
||
556 | case I2C_TIMEOUT: |
||
557 | adap->timeout = arg; |
||
558 | break; |
||
559 | default: |
||
560 | if (adap->algo->algo_control!=NULL) |
||
561 | ret = adap->algo->algo_control(adap,cmd,arg); |
||
562 | } |
||
563 | return ret; |
||
564 | } |
||
565 | |||
566 | /* ---------------------------------------------------- |
||
567 | * the i2c address scanning function |
||
568 | * Will not work for 10-bit addresses! |
||
569 | * ---------------------------------------------------- |
||
570 | */ |
||
571 | int i2c_probe(struct i2c_adapter *adapter, |
||
572 | struct i2c_client_address_data *address_data, |
||
573 | i2c_client_found_addr_proc *found_proc) |
||
574 | { |
||
575 | int addr,i,found,err; |
||
576 | int adap_id = i2c_adapter_id(adapter); |
||
577 | |||
578 | /* Forget it if we can't probe using SMBUS_QUICK */ |
||
579 | if (! i2c_check_functionality(adapter,I2C_FUNC_SMBUS_QUICK)) |
||
580 | return -1; |
||
581 | |||
582 | for (addr = 0x00; addr <= 0x7f; addr++) { |
||
583 | |||
584 | /* Skip if already in use */ |
||
585 | if (i2c_check_addr(adapter,addr)) |
||
586 | continue; |
||
587 | |||
588 | /* If it is in one of the force entries, we don't do any detection |
||
589 | at all */ |
||
590 | found = 0; |
||
591 | |||
592 | for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 3) { |
||
593 | if (((adap_id == address_data->force[i]) || |
||
594 | (address_data->force[i] == ANY_I2C_BUS)) && |
||
595 | (addr == address_data->force[i+1])) { |
||
596 | DEB2(cprintf("i2c-core.o: found force parameter for adapter %d, addr %04x\n", |
||
597 | adap_id,addr)); |
||
598 | if ((err = found_proc(adapter,addr,0,0))) |
||
599 | return err; |
||
600 | found = 1; |
||
601 | } |
||
602 | } |
||
603 | if (found) |
||
604 | continue; |
||
605 | |||
606 | /* If this address is in one of the ignores, we can forget about |
||
607 | it right now */ |
||
608 | for (i = 0; |
||
609 | !found && (address_data->ignore[i] != I2C_CLIENT_END); |
||
610 | i += 2) { |
||
611 | if (((adap_id == address_data->ignore[i]) || |
||
612 | ((address_data->ignore[i] == ANY_I2C_BUS))) && |
||
613 | (addr == address_data->ignore[i+1])) { |
||
614 | DEB2(cprintf("i2c-core.o: found ignore parameter for adapter %d, " |
||
615 | "addr %04x\n", adap_id ,addr)); |
||
616 | found = 1; |
||
617 | } |
||
618 | } |
||
619 | for (i = 0; |
||
620 | !found && (address_data->ignore_range[i] != I2C_CLIENT_END); |
||
621 | i += 3) { |
||
622 | if (((adap_id == address_data->ignore_range[i]) || |
||
623 | ((address_data->ignore_range[i]==ANY_I2C_BUS))) && |
||
624 | (addr >= address_data->ignore_range[i+1]) && |
||
625 | (addr <= address_data->ignore_range[i+2])) { |
||
626 | DEB2(cprintf("i2c-core.o: found ignore_range parameter for adapter %d, " |
||
627 | "addr %04x\n", adap_id,addr)); |
||
628 | found = 1; |
||
629 | } |
||
630 | } |
||
631 | if (found) |
||
632 | continue; |
||
633 | |||
634 | /* Now, we will do a detection, but only if it is in the normal or |
||
635 | probe entries */ |
||
636 | for (i = 0; |
||
637 | !found && (address_data->normal_i2c[i] != I2C_CLIENT_END); |
||
638 | i += 1) { |
||
639 | if (addr == address_data->normal_i2c[i]) { |
||
640 | found = 1; |
||
641 | DEB2(cprintf("i2c-core.o: found normal i2c entry for adapter %d, " |
||
642 | "addr %02x", adap_id,addr)); |
||
643 | } |
||
644 | } |
||
645 | |||
646 | for (i = 0; |
||
647 | !found && (address_data->normal_i2c_range[i] != I2C_CLIENT_END); |
||
648 | i += 2) { |
||
649 | if ((addr >= address_data->normal_i2c_range[i]) && |
||
650 | (addr <= address_data->normal_i2c_range[i+1])) { |
||
651 | found = 1; |
||
652 | DEB2(cprintf("i2c-core.o: found normal i2c_range entry for adapter %d, " |
||
653 | "addr %04x\n", adap_id,addr)); |
||
654 | } |
||
655 | } |
||
656 | |||
657 | for (i = 0; |
||
658 | !found && (address_data->probe[i] != I2C_CLIENT_END); |
||
659 | i += 2) { |
||
660 | if (((adap_id == address_data->probe[i]) || |
||
661 | ((address_data->probe[i] == ANY_I2C_BUS))) && |
||
662 | (addr == address_data->probe[i+1])) { |
||
663 | found = 1; |
||
664 | DEB2(cprintf("i2c-core.o: found probe parameter for adapter %d, " |
||
665 | "addr %04x\n", adap_id,addr)); |
||
666 | } |
||
667 | } |
||
668 | for (i = 0; |
||
669 | !found && (address_data->probe_range[i] != I2C_CLIENT_END); |
||
670 | i += 3) { |
||
671 | if (((adap_id == address_data->probe_range[i]) || |
||
672 | (address_data->probe_range[i] == ANY_I2C_BUS)) && |
||
673 | (addr >= address_data->probe_range[i+1]) && |
||
674 | (addr <= address_data->probe_range[i+2])) { |
||
675 | found = 1; |
||
676 | DEB2(cprintf("i2c-core.o: found probe_range parameter for adapter %d, " |
||
677 | "addr %04x\n", adap_id,addr)); |
||
678 | } |
||
679 | } |
||
680 | if (!found) |
||
681 | continue; |
||
682 | |||
683 | /* OK, so we really should examine this address. First check |
||
684 | whether there is some client here at all! */ |
||
685 | if (i2c_smbus_xfer(adapter,addr,0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) |
||
686 | if ((err = found_proc(adapter,addr,0,-1))) |
||
687 | return err; |
||
688 | } |
||
689 | return 0; |
||
690 | } |
||
691 | |||
692 | /* |
||
693 | * return id number for a specific adapter |
||
694 | */ |
||
695 | int i2c_adapter_id(struct i2c_adapter *adap) |
||
696 | { |
||
697 | int i; |
||
698 | for (i = 0; i < I2C_ADAP_MAX; i++) |
||
699 | if (adap == adapters[i]) |
||
700 | return i; |
||
701 | return -1; |
||
702 | } |
||
703 | |||
704 | /* The SMBus parts */ |
||
705 | |||
706 | extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value) |
||
707 | { |
||
708 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
709 | value,0,I2C_SMBUS_QUICK,NULL); |
||
710 | } |
||
711 | |||
712 | extern s32 i2c_smbus_read_byte(struct i2c_client * client) |
||
713 | { |
||
714 | union i2c_smbus_data data; |
||
715 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
716 | I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data)) |
||
717 | return -1; |
||
718 | else |
||
719 | return 0x0FF & data.byte; |
||
720 | } |
||
721 | |||
722 | extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value) |
||
723 | { |
||
724 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
725 | I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,NULL); |
||
726 | } |
||
727 | |||
728 | extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command) |
||
729 | { |
||
730 | union i2c_smbus_data data; |
||
731 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
732 | I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data)) |
||
733 | return -1; |
||
734 | else |
||
735 | return 0x0FF & data.byte; |
||
736 | } |
||
737 | |||
738 | extern s32 i2c_smbus_write_byte_data(struct i2c_client * client, u8 command, |
||
739 | u8 value) |
||
740 | { |
||
741 | union i2c_smbus_data data; |
||
742 | data.byte = value; |
||
743 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
744 | I2C_SMBUS_WRITE,command, |
||
745 | I2C_SMBUS_BYTE_DATA,&data); |
||
746 | } |
||
747 | |||
748 | extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command) |
||
749 | { |
||
750 | union i2c_smbus_data data; |
||
751 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
752 | I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data)) |
||
753 | return -1; |
||
754 | else |
||
755 | return 0x0FFFF & data.word; |
||
756 | } |
||
757 | |||
758 | extern s32 i2c_smbus_write_word_data(struct i2c_client * client, |
||
759 | u8 command, u16 value) |
||
760 | { |
||
761 | union i2c_smbus_data data; |
||
762 | data.word = value; |
||
763 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
764 | I2C_SMBUS_WRITE,command, |
||
765 | I2C_SMBUS_WORD_DATA,&data); |
||
766 | } |
||
767 | |||
768 | extern s32 i2c_smbus_process_call(struct i2c_client * client, |
||
769 | u8 command, u16 value) |
||
770 | { |
||
771 | union i2c_smbus_data data; |
||
772 | data.word = value; |
||
773 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
774 | I2C_SMBUS_WRITE,command, |
||
775 | I2C_SMBUS_PROC_CALL, &data)) |
||
776 | return -1; |
||
777 | else |
||
778 | return 0x0FFFF & data.word; |
||
779 | } |
||
780 | |||
781 | /* Returns the number of read bytes */ |
||
782 | extern s32 i2c_smbus_read_block_data(struct i2c_client * client, |
||
783 | u8 command, u8 *values) |
||
784 | { |
||
785 | union i2c_smbus_data data; |
||
786 | int i; |
||
787 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
788 | I2C_SMBUS_READ,command, |
||
789 | I2C_SMBUS_BLOCK_DATA,&data)) |
||
790 | return -1; |
||
791 | else { |
||
792 | for (i = 1; i <= data.block[0]; i++) |
||
793 | values[i-1] = data.block[i]; |
||
794 | return data.block[0]; |
||
795 | } |
||
796 | } |
||
797 | |||
798 | extern s32 i2c_smbus_write_block_data(struct i2c_client * client, |
||
799 | u8 command, u8 length, u8 *values) |
||
800 | { |
||
801 | union i2c_smbus_data data; |
||
802 | int i; |
||
803 | if (length > 32) |
||
804 | length = 32; |
||
805 | for (i = 1; i <= length; i++) |
||
806 | data.block[i] = values[i-1]; |
||
807 | data.block[0] = length; |
||
808 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
809 | I2C_SMBUS_WRITE,command, |
||
810 | I2C_SMBUS_BLOCK_DATA,&data); |
||
811 | } |
||
812 | |||
813 | extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, |
||
814 | u8 command, u8 length, u8 *values) |
||
815 | { |
||
816 | union i2c_smbus_data data; |
||
817 | int i; |
||
818 | if (length > 32) |
||
819 | length = 32; |
||
820 | for (i = 1; i <= length; i++) |
||
821 | data.block[i] = values[i-1]; |
||
822 | data.block[0] = length; |
||
823 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
||
824 | I2C_SMBUS_WRITE,command, |
||
825 | I2C_SMBUS_I2C_BLOCK_DATA,&data); |
||
826 | } |
||
827 | |||
828 | /* Simulate a SMBus command using the i2c protocol |
||
829 | No checking of parameters is done! */ |
||
830 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, |
||
831 | unsigned short flags, |
||
832 | char read_write, u8 command, int size, |
||
833 | union i2c_smbus_data * data) |
||
834 | { |
||
835 | /* So we need to generate a series of msgs. In the case of writing, we |
||
836 | need to use only one message; when reading, we need two. We initialize |
||
837 | most things with sane defaults, to keep the code below somewhat |
||
838 | simpler. */ |
||
839 | unsigned char msgbuf0[34]; |
||
840 | unsigned char msgbuf1[34]; |
||
841 | int num = read_write == I2C_SMBUS_READ?2:1; |
||
842 | struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, |
||
843 | { addr, flags | I2C_M_RD, 0, msgbuf1 } |
||
844 | }; |
||
845 | int i; |
||
846 | |||
847 | msgbuf0[0] = command; |
||
848 | switch(size) { |
||
849 | case I2C_SMBUS_QUICK: |
||
850 | msg[0].len = 0; |
||
851 | /* Special case: The read/write field is used as data */ |
||
852 | msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; |
||
853 | num = 1; |
||
854 | break; |
||
855 | case I2C_SMBUS_BYTE: |
||
856 | if (read_write == I2C_SMBUS_READ) { |
||
857 | /* Special case: only a read! */ |
||
858 | msg[0].flags = I2C_M_RD | flags; |
||
859 | num = 1; |
||
860 | } |
||
861 | break; |
||
862 | case I2C_SMBUS_BYTE_DATA: |
||
863 | if (read_write == I2C_SMBUS_READ) |
||
864 | msg[1].len = 1; |
||
865 | else { |
||
866 | msg[0].len = 2; |
||
867 | msgbuf0[1] = data->byte; |
||
868 | } |
||
869 | break; |
||
870 | case I2C_SMBUS_WORD_DATA: |
||
871 | if (read_write == I2C_SMBUS_READ) |
||
872 | msg[1].len = 2; |
||
873 | else { |
||
874 | msg[0].len=3; |
||
875 | msgbuf0[1] = data->word & 0xff; |
||
876 | msgbuf0[2] = (data->word >> 8) & 0xff; |
||
877 | } |
||
878 | break; |
||
879 | case I2C_SMBUS_PROC_CALL: |
||
880 | num = 2; /* Special case */ |
||
881 | msg[0].len = 3; |
||
882 | msg[1].len = 2; |
||
883 | msgbuf0[1] = data->word & 0xff; |
||
884 | msgbuf0[2] = (data->word >> 8) & 0xff; |
||
885 | break; |
||
886 | case I2C_SMBUS_BLOCK_DATA: |
||
887 | if (read_write == I2C_SMBUS_READ) { |
||
888 | cprintf("i2c-core.o: Block read not supported under " |
||
889 | "I2C emulation!\n"); |
||
890 | return -1; |
||
891 | } else { |
||
892 | msg[0].len = data->block[0] + 2; |
||
893 | if (msg[0].len > 34) { |
||
894 | cprintf("i2c-core.o: smbus_access called with " |
||
895 | "invalid block write size (%d)\n", |
||
896 | msg[0].len); |
||
897 | return -1; |
||
898 | } |
||
899 | for (i = 1; i <= msg[0].len; i++) |
||
900 | msgbuf0[i] = data->block[i-1]; |
||
901 | } |
||
902 | break; |
||
903 | default: |
||
904 | cprintf("i2c-core.o: smbus_access called with invalid size (%d)\n", |
||
905 | size); |
||
906 | return -1; |
||
907 | } |
||
908 | |||
909 | if (i2c_transfer(adapter, msg, num) < 0) |
||
910 | return -1; |
||
911 | |||
912 | if (read_write == I2C_SMBUS_READ) |
||
913 | switch(size) { |
||
914 | case I2C_SMBUS_BYTE: |
||
915 | data->byte = msgbuf0[0]; |
||
916 | break; |
||
917 | case I2C_SMBUS_BYTE_DATA: |
||
918 | data->byte = msgbuf1[0]; |
||
919 | break; |
||
920 | case I2C_SMBUS_WORD_DATA: |
||
921 | case I2C_SMBUS_PROC_CALL: |
||
922 | data->word = msgbuf1[0] | (msgbuf1[1] << 8); |
||
923 | break; |
||
924 | } |
||
925 | return 0; |
||
926 | } |
||
927 | |||
928 | |||
929 | s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, |
||
930 | char read_write, u8 command, int size, |
||
931 | union i2c_smbus_data * data) |
||
932 | { |
||
933 | s32 res; |
||
934 | flags = flags & I2C_M_TEN; |
||
935 | if (adapter->algo->smbus_xfer) { |
||
936 | res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, |
||
937 | command,size,data); |
||
938 | } else |
||
939 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, |
||
940 | command,size,data); |
||
941 | return res; |
||
942 | } |
||
943 | |||
944 | |||
945 | /* You should always define `functionality'; the 'else' is just for |
||
946 | backward compatibility. */ |
||
947 | u32 i2c_get_functionality (struct i2c_adapter *adap) |
||
948 | { |
||
949 | if (adap->algo->functionality) |
||
950 | return adap->algo->functionality(adap); |
||
951 | else |
||
952 | return 0xffffffff; |
||
953 | } |
||
954 | |||
955 | int i2c_check_functionality (struct i2c_adapter *adap, u32 func) |
||
956 | { |
||
957 | u32 adap_func = i2c_get_functionality (adap); |
||
958 | return (func & adap_func) == func; |
||
959 | } |
||
960 | |||
961 | |||
962 | static int i2c_init(void) |
||
963 | { |
||
964 | printk(KERN_INFO "i2c-core.o: i2c core module\n"); |
||
965 | memset(adapters,0,sizeof(adapters)); |
||
966 | memset(drivers,0,sizeof(drivers)); |
||
967 | adap_count=0; |
||
968 | driver_count=0; |
||
969 | |||
970 | return 0; |
||
971 | } |
||
972 | |||
973 | extern void i2c_algo_bit_init(void); |
||
974 | |||
975 | int i2c_init_all(void) |
||
976 | { |
||
977 | /* --------------------- global ----- */ |
||
978 | i2c_init(); |
||
979 | |||
980 | i2c_algo_bit_init(); |
||
981 | |||
982 | return 0; |
||
983 | } |
||
984 |