root/lm-sensors/trunk/doc/developers/design

Revision 3000, 18.2 kB (checked in by khali, 3 years ago)

Fix common spelling errors.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 This is a design for version 2 of our smbus and lm_sensors module. This
2 document is Copyright (c) 1998, 1999 by Frodo Looijaard. You may freely copy and
3 distribute it, as long as you recognize me as the author, and mark any
4 changes you make as being your own, and distribute this notice with it.
5
6 Document version 1.0, 19981101.
7                  1.1, 19981111.
8                  1.2, 19981118.
9                  1.3, 19981126.
10
11 NOTE: THIS IS BY NOW SOMEWHAT OUTDATED. SORRY.
12
13
14 Object oriented approach
15 ========================
16
17 The i2c module structs contain callback functions and data fields. In the
18 i2c module, these structures are only referenced by pointers. This makes
19 it easy to extend these structs to contain additional information or
20 callback functions. For those familiar with object oriented languages,
21 you can see the smbus and isa structures as an object extension of the i2c
22 structures.
23
24 To make this clearer, I will show in an example how this is done. Note
25 that I have simplified some things here, so this example does not
26 correspond to an actual struct found in one of the modules.
27
28 In the i2c module, you can find a struct somewhat like this:
29
30 struct i2c_adapter {
31   char name[32];
32   int (*detach_client) (struct i2c_client *);
33   struct i2c_adapter *next;
34 }
35
36 We have a plain data field (name), a call-back function which needs one
37 parameter (a pointer to a i2c_client struct), and a data field which is
38 a pointer to the next adapter.
39
40 Now we want to extend this structure. We need another data field,
41 containing a number of flags. We will call this new structure smbus_adapter.
42 A few other things change too:
43
44 struct smbus_adapter {
45   char name[32];
46   int (*detach_client) (struct smbus_client *);
47   struct smbus_adapter *next;
48   unsigned int flags;
49 }
50
51 So we copy all existing fields. The next field still points to the next
52 adapter - but it is now of type smbus_adapter, not i2c_adapter. And the
53 call-back function takes now a parameter of type pointer to smbus_client.
54 And there is a new data field, called flags.
55
56 Now examine this function definition:
57
58 int fully_detach_i2c_client (struct i2c_client * client)
59 {
60   res = 0;
61   struct i2c_adapter *current_adapter = first_adapter; /* a global var. */
62   while (current_adapter) {
63     res |= (current_adapter -> detach_client) (client);
64     current_adapter = current_adapter -> next;
65   }
66   return res;
67 }
68
69 This function detaches a client from all adapters. Nice. But now comes the
70 Big Trick(tm): we can still use this function for smbus_adapters!
71
72 int fully_detach_smbus_client (struct smbus_client * client)
73 {
74   return fully_detach_i2c_client( (struct i2c_client *) client);
75 }
76
77 All we needed here was a simple typecast. Datapointers remain datapointers,
78 so this can safely be done. And because we use call-back functions, the
79 actual function called to detach a client from a single adapter might
80 be the same, or different, depending on what function was put in
81 client->detach_client!
82
83 It gets even better. The i2c module stores internally all registered
84 adapters. But it stores pointers to the i2c_adapter struct, not the
85 structs themselves! So there is an array:
86
87 #define I2C_ADAPTER_MAX 32
88 struct i2c_adapter *adapters[I2C_ADAPTER_MAX];
89 /* this is an array of pointers to structs, not vice versa! */
90
91 So, an element of this array might in fact point to a smbus_adapter, instead
92 of an i2c_adapter! If you know this for sure, you might use a typecast and
93 access the additional fields. In the meantime, the i2c internal
94 administration remains valid.
95
96 We have to thank Simon Vogl and Gerd Knorr for the way they implemented
97 their i2c module. Any other way would have made this approach impossible,
98 and basing anything upon their module much more difficult.
99
100 Limitations
101 -----------
102
103 Extending the adapter and algorithm structures in this way is quite safe.
104 They are only allocated on places where the code knows that they are
105 'special'. Extending the driver or client structures depending on a
106 specific adapter/algorithm type is *very* *dangerous*. A driver/client
107 module would need to be aware of every special adapter/algorithm in
108 order to allocate itself! For the ISA bus, it has to be aware of this
109 anyway, so it is safe to do; on other places, think twice first!
110
111
112 Module overview
113 ===============
114
115 All in all, lots of modules will be stacked on each other. Too bad, but
116 that is the only way to cleanly implement everything. Note that in a
117 specific situation, only a few modules may need to be loaded. isa.o,
118 for example, does not depend on smbus.o (in the sense that you can load
119 sensor.o without loading smbus.o). A specific bus driver, though, will
120 depend on many of them.
121
122 Generally:
123   isa.o depends on nothing (actually, on i2c.o, to keep the code small)
124   smbus.o depends on nothing (actually, on i2c.o, to keep the code small)
125   i2c.o depends on nothing.
126
127   A non-i2c SMBus bus driver depends only on smbus.o
128   A i2c bus driver depends only on i2c.o
129
130   A sensor chip driver depends either on isa.o or smbus.o, or both.
131   A SMBus chip driver depends only on smbus.o
132   A I2C chip driver depends only on i2c.o
133
134 We may need a sensor.o module, to act as a central point for sensor
135 modules. At this moment, it seems not really necessary, but this may
136 change.
137
138 We will need an enhanced i2c-dev.o module, to add SMBus access to I2C
139 /dev entries.
140
141
142 isa.o
143 ISA bus handling.
144 Encapsulates ISA bus access within the i2c structures.
145 Unites I2C adapters and the ISA bus.
146 Defines variables isa_algorithm and isa_adapter.
147
148 smbus.o
149 Main SMBus handling.
150 Encapsulates SMBus access within the smbus structures.
151 Unites I2C adapters and SMBus hosts (like the PIIX4).
152 Emulates SMBus access on pure I2C adapters.
153 Defines variable smbus_algorithm.
154
155   piix4.o
156   SMBus adapter driver for the PIIX4 SMBus host.
157   Defines variable piix4_adapter (based on smbus_algorithm).
158
159   FOO.o
160   Adapter driver for FOO SMBus host
161   Defines variable FOO_adapter (based on smbus_algorithm).
162
163 i2c-core.o (From Simon Vogl)
164 Main i2c handling.
165
166   ????.o
167   I2C adapter driver
168   Implementing a class of I2C busses
169
170
171 A chip driver (typically defined in its own module) can be hooked on all
172 these levels:
173   * If it is a sensor chip, it should be hooked to isa.o or smbus.o
174   * A pure ISA chip should be hooked to isa.o
175   * A pure SMBus chip should be hooked to smbus.o
176   * An I2C chip should be hooked to i2c.o
177 It can be difficult to decide whether a specific chip should be hooked to
178 smbus.o or i2c.o. A good deciding question is, 'could it be connected to
179 a PIIX4?'
180
181
182 Module i2c.o
183 ============
184
185 This is Simon Vogl's i2c module (this one is different from the i2c module
186 included in kernels around 2.1.120!).
187
188 A driver
189 --------
190
191 struct i2c_driver {
192   char name[32];
193   int id;
194   unsigned int flags;
195   int (* attach_adapter) (struct i2c_adapter *);
196   int (* detach_client) (struct i2c_client *);
197   int (* command) (struct i2c_client *, unsigned int cmd, void *arg);
198   void (* inc_use) (struct i2c_client *);
199   void (* dec_use) (struct i2c_client *);
200 }
201
202 A driver tells us how we should handle a specific type of i2c chip. An
203 instance of such a chip is called a 'client'. An example would be the LM75
204 module: it would contain only one driver, which tells us how to handle the
205 LM75; but each detected LM75 would be a separate client (which would be
206 dynamically allocated).
207
208
209 A description of the above struct:
210   name: The name of this driver
211   id: A unique driver identifier
212   flags: Flags to set certain kinds of behaviour. Most notably, DF_NOTIFY
213     will notify the driver when a new i2c bus is detected, so it can
214     try to detect chips on it.
215   attach_adapter: A call-back function which is called if a new adapter (bus)
216     is found. This allows us to do our detection stuff on the new adapter,
217     and register new clients.
218   detach_client: A call-back function which is called if a specific client
219     which uses this driver should be disallocated. If a specific sensor module
220     is removed, for instance, this function would be called for each registered
221     client.
222   command: A generic call-back function to communicate in a driver-dependent
223     way with a specific client. This should only be seldom needed.
224   inc_use: Can be called to add one to an internal 'use' counter. This can be
225     used to control when it is safe to remove this module, for example.
226
227
228 A client
229 --------
230
231 struct i2c_client {
232   char name[32];
233   int id;
234   unsigned int flags;
235   unsigned char addr;
236   struct i2c_adapter *adapter;
237   struct i2c_driver *driver;
238   void *data;
239 }
240
241 A client is a specific sensor chip. Its operation is controlled by a driver
242 (which describes a type of sensor chip), and it is connected to an adapter
243 (a bus).
244
245 A description of the above struct:
246   name: The name of this client
247   id: A unique client id
248   flags: Flags to set certain kinds of behaviour (not very important)
249   addr: The client address. 10-bit addresses are a bit of a kludge right now.
250   adapter: A pointer to the adapter this client is on.
251   driver: A pointer to the driver this client uses.
252   data: Additional, client-dependent data
253
254
255 An algorithm
256 ------------
257
258 struct i2c_algorithm {
259   char name[32];
260   unsigned int id;
261   int (* master_xfer) (struct i2c_adapter *adap, struct i2c_msg msgs[],
262                        int num);
263   int (* slave_send) (struct i2c_adapter *,char *, int);
264   int (* slave_recv) (struct i2c_adapter *,char *, int);
265   int (* algo_control) (struct i2c_adapter *, unsigned int, unsigned long);
266   int (* client_register) (struct i2c_client *);
267   int (* client_unregister) (struct i2c_client *);
268 }
269
270 An algorithm describes how a certain class of i2c busses can be accessed.
271
272 A description of the above struct:
273   name: The name of this algorithm
274   id: A unique algorithm id
275   master_xfer: Transfer a bunch of messages through a specific i2c bus.
276   slave_send: Send a message as if we are a slave device
277   slave_recv: Receive a message as if we are a slave device
278   client_register: Register a new client
279   client_unregister: Unregister a client
280
281
282 An adapter
283 ----------
284
285 struct i2c_adapter {
286   char name[32];
287   unsigned int id;
288   struct i2c_algorithm *algo;
289   void *data;
290 #ifdef SPINLOCK
291   spinlock_t lock;
292   unsigned long lockflags;
293 #else
294   struct semaphore lock;
295 #endif
296   unsigned int flags;
297   struct i2c_client *clients[I2C_CLIENT_MAX];
298   int client_count;
299   int timeout;
300   int retries;
301 }
302
303 An adapter is a specific i2c bus. How to access it is defined in the
304 algorithm associated with it.
305
306 A description of the above struct:
307   name: The name of this adapter
308   id: A unique adapter id
309   algo: The algorithm through which this bus must be accessed
310   data: Adapter specific data
311   lock, lockflags: To lock out simultaneous adapter access
312   flags: Modifiers for adapter operation
313   clients: All currently connected clients
314   client_count: The number of currently connected clients
315   timeout, retries: Internal variables (unimportant here).
316
317
318 Access functions
319 ----------------
320
321 All these functions are defined extern.
322
323 int i2c_master_send(struct i2c_client *,const char *, int);
324 int i2c_master_recv(struct i2c_client *,char *, int);
325 int i2c_transfer(struct i2c_adapter *,struct i2c_msg [], int num);
326
327 These function respectively send one message to a client, receive one message
328 from a client, or transmit a bunch of messages. struct i2c_msg contains
329 an i2c address to communicate with, and can both read from and write to this
330 address.
331
332
333 int i2c_slave_send(struct i2c_client *, char *, int);
334 int i2c_slave_recv(struct i2c_client *, char *, int);
335
336 Communicate with another master as if the normal master is a common slave
337 device.
338
339
340 Administration functions
341 ------------------------
342
343 int i2c_add_algorithm(struct i2c_algorithm *);
344 int i2c_del_algorithm(struct i2c_algorithm *);
345
346 The i2c_{add,del}_algorithm functions must be called whenever a new module
347 is inserted with this driver in it, by the module initialization function.
348
349
350 int i2c_add_adapter(struct i2c_adapter *);
351 int i2c_del_adapter(struct i2c_adapter *);
352
353 The i2c_{add,del}_adapter functions must be called if you have detected
354 a specific bus. It triggers driver->attach_adapter (add, for each driver
355 present) or driver->detach_client (del, for each registered client on
356 this adapter).
357
358
359 int i2c_add_driver(struct i2c_driver *);
360 int i2c_del_driver(struct i2c_driver *);
361
362 The i2c_{add,del}_driver functions must be called whenever a new module is
363 inserted with a chip driver in it, by the module initialization function.
364
365
366 int i2c_attach_client(struct i2c_client *);
367 int i2c_detach_client(struct i2c_client *);
368
369 The i2c_{attach,detach}_client functions must be called if you have detected
370 a single chip.
371
372
373 Module smbus.o
374 ==============
375
376 This module offers support for SMBus operation. An SMBus adapter can either
377 accept SMBus commands (like the PIIX4), or be in fact an I2C driver. In
378 the last case, all SMBus commands will be expressed through I2C primitives.
379 This means that any I2C adapter driver will automatically be a SMBus
380 driver.
381
382 At this point, it should be noted that there can only be one System
383 Management Bus in a given system (is this really true, by the way?). This
384 means there must be some way of selecting which of the many possible adapters
385 is in fact *the* SMBus. For now, I will ignore this problem. Later on,
386 we can add a hook somewhere in the i2c module to help us decide this.
387
388 This module consists in fact of three separate parts: first of all, it extends
389 all i2c structs to accomodate the new smbus fields. Second, it defines a
390 new algorithm (smbus_algorithm), that will be used by all non-i2c adapters.
391 Finally, it implements a new access function that sends or receives SMBus
392 commands; these are either translated into I2C commands or sent to the
393 SMBus driver.
394
395
396 A driver, client and algorithm
397 ------------------------------
398
399 We will not need to extend i2c_driver, i2c_client or i2c_adapter. This means
400 that struct smbus_driver is exactly the same as struct i2c_driver, and
401 struct smbus_client is the same as struct i2c_client, and smbus_adapter is
402 the same as struct i2c_adapter. We *will* define the smbus_* variants, and
403 use them within this module, so it should be easy to extend them after all.
404
405 Note that at this moment, 10 bit SMBus addresses seem to be only
406 partially supported by the i2c module. We will ignore this issue for
407 now.
408
409
410 An adapter
411 ------------
412
413 struct smbus_adapter {
414   char name[32];
415   unsigned int id;
416   struct smbus_algorithm *algo;
417   void *data;
418 #ifdef SPINLOCK
419   spinlock_t lock;
420   unsigned long lockflags;
421 #else
422   struct semaphore lock;
423 #endif
424   unsigned int flags;
425   struct smbus_client *clients[I2C_CLIENT_MAX];
426   int client_count;
427   int timeout;
428   int retries;
429
430   /* Here ended i2c_adapter */
431   s32 (* smbus_access) (__u8 addr, char read_write,
432                         __u8 command, int size, union smbus_data * data);
433 }
434
435 A description of the above struct:
436   smbus_access: A function to access the SMBus. It is only used for non-i2c
437       smbus adapters.
438
439
440 Access functions
441 ----------------
442
443 All these functions are defined extern.
444
445 The i2c access function should not be used within SMBus chip drivers, as
446 they might not be defined (for the PIIX4, for example). Instead, use the
447 following general access function, or one of the easier functions based
448 on it:
449
450 int smbus_access (struct i2c_adapter *, __u8 addr, char read_write,
451                   __u8 command, int size, union smbus_data * data);
452
453 There are specific SMBus registration functions too, like the i2c ones.
454 They are fully compatiable with each other; just substitute 'smbus' for
455 'i2c' everywhere in the i2c description.
456
457 int i2c_is_smbus_client(struct i2c_client *);
458 int i2c_is_smbus_adapter(struct i2c_adapter *);
459
460 Decide whether this client, or adapter, is (on) a non-I2C SMBus. Usually
461 not needed, but it is nice anyway to be able to decide this.
462
463
464 Module isa.o
465 ============
466
467 This module implements a new algorithm and a specific adapter for the
468 (single) ISA bus in your computer. This makes writing drivers for chips
469 that can be both on ISA and SMBus much easier.
470
471 Note that this module does *not* in any way depend on smbus.o (previous
472 versions of this document still assumed it would be build upon it; this
473 is no longer true).
474
475
476 A driver, adapter or algorithm
477 ------------------------------
478
479 We will not need to extend i2c_driver, i2c_adapter or i2c_algorithm. This
480 means that struct isa_driver is exactly the same as struct i2c_driver,
481 struct isa_adapter is the same as struct i2c_adapter and struct isa_algorithm
482 is the same as struct isa_driver. We *will* define the isa_* variants, and
483 use them within this module, so it should be easy to extend them after all.
484
485
486 A client
487 --------
488
489 struct isa_client {
490   char name[32];
491   int id;
492   unsigned int flags;
493   unsigned char addr;
494   struct isa_adapter *adapter;
495   struct isa_driver *driver;
496   void *data;
497
498   unsigned int isa_addr;
499 }
500
501 A client is a specific sensor chip. Its operation is controlled by a driver
502 (which describes a type of sensor chip), and it is connected to an adapter
503 (a bus, the (single) ISA bus here).
504
505 A description of the above struct:
506   isa_addr: ISA addresses do not fit in the i2c-compatible addr field, so
507     we needed a new field.
508
509
510 Access functions
511 ----------------
512
513 All these functions are defined extern.
514
515 In case of the ISA bus, the master_xfer, slave_send and slave_recv hooks
516 will be NULL, because these functions make no sense. It is regrettably
517 not easy to create an access abstraction in which both ISA bus access
518 and SMBus access are united. See below for examples how you can solve
519 this problem.
520
521 The most imporant additional access function:
522
523 int i2c_is_isa_client(struct i2c_client *);
524 int i2c_is_isa_adapter(struct i2c_adapter *);
525
526 Decide whether this client, or adapter, is (on) the ISA bus. This is
527 important, because it determines whether we can use the SMBus access
528 routines.
529
530 As an example, I will here implement our old LM78 access function:
531
532 /* The SMBus locks itself, but ISA access must be locked explicitly!
533    We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
534    would slow down the LM78 access and should not be necessary.
535    There are some ugly typecasts here, but the good new is - they should
536    nowhere else be necessary! */
537 int lm78_read_value(struct i2c_client *client, u8 reg)
538 {
539   int res;
540   if (i2c_is_isa_client(client)) {
541     down((struct semaphore *) (client->data));
542     outb_p(reg,(((struct isa_client *) client)->isa_addr) +
543                LM78_ADDR_REG_OFFSET);
544     res = inb_p((((struct isa_client *) client)->isa_addr) +
545                 LM78_DATA_REG_OFFSET);
546     up((struct semaphore *) (client->data));
547     return res;
548   } else
549     return smbus_read_byte_data(client->adapter,client->addr, reg);
550 }
Note: See TracBrowser for help on using the browser.