root/lm-sensors/trunk/src/smbus.h @ 34

Revision 34, 9.2 KB (checked in by frodo, 14 years ago)

PIIX4 update

It compiles now for 2.0 kernels; I hope it still compiles for 2.1 kernels :-)

Changes:
* The non-BIOS PCI interface was introduced in kernel 2.1.54, so I changed

all #ifdef statements to use that kernel as starting point

* I integrated everything in piix4.h into piix4.c; as no other module will

ever need to know about anything PIIX4-specific, we do not need a
separate header file (same went for lm78.c and lm75.c)

* In piix4_setup, both the 2.0 and 2.1 versions continue seeking for PCI

devices until they have found 'function 3' of the PIIX4. This is the
'function' we need for SMBus access.

* At some places in piix4_setup, even for 2.1 kernels the PCI BIOS code was

used. This was seemingly needed, probably because the wrong 'function'
was accessed. I have removed this; if there are troubles with the PIIX4 on
kernels newer than 2.1.53, we need to introduce it again.

* Renamed global things to start uniformly with piix4_
* Changed printk statements to start with piix4.o:
* Pasted in missing part of piix4_access
* No need to lock the adapter on access; this is already done by the

smbus_access function in smbus.c. I corrected a locking bug there too,
by the way.

* Added a few include files needed by 2.0 at least
* Replaced the call to schedule_timeout() in piix4_do_pause with the old

code; schedule_timeout seems to be defined nowhere?!? Phil, was this
your addition, and if so, what should it read?

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    smbus.h - A Linux module for reading sensor data.
3    Copyright (c) 1998  Frodo Looijaard <frodol@dds.nl>
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#ifndef SENSORS_SMBUS_H
21#define SENSORS_SMBUS_H
22
23#ifdef __KERNEL__
24
25/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
26   OK, earlier versions are not; later versions will probably give problems
27   too.
28*/
29#include "i2c.h"
30#include <asm/types.h>
31
32/* SPINLOCK is defined in i2c.h. */
33#ifdef SPINLOCK
34#include <asm/spinlock.h>
35#else
36#include <asm/semaphore.h>
37#endif
38
39/* Declarations, to keep the compiler happy */
40struct smbus_driver;
41struct smbus_client;
42struct smbus_algorithm;
43struct smbus_adapter;
44union smbus_data;
45
46/* A driver tells us how we should handle a specific kind of chip.
47   A specific instance of such a chip is called a client. 
48   This structure is essentially the same as i2c_driver. */
49struct smbus_driver {
50  char name[32];
51  int id;
52  unsigned int flags;
53  int (* attach_adapter) (struct smbus_adapter *);
54  int (* detach_client) (struct smbus_client *);
55  int (* command) (struct smbus_client *, unsigned int cmd, void *arg);
56  void (* inc_use) (struct smbus_client *);
57  void (* dec_use) (struct smbus_client *);
58};
59
60/* A client is a specifc instance of a chip: for each detected chip, there will
61   be a client. Its operation is controlled by a driver.
62   This structure is essentially the same as i2c_client. */
63struct smbus_client {
64  char name[32];
65  int id;
66  unsigned int flags;
67  unsigned char addr;
68  struct smbus_adapter *adapter;
69  struct smbus_driver *driver;
70  void *data;
71};
72
73/* An algorithm describes how a certain class of busses can be accessed.
74   A specific instance of sucj a bus is called an adapter.
75   This structure is essentially the same as i2c_adapter. */
76struct smbus_algorithm {
77  char name[32];
78  unsigned int id;
79  int (* master_xfer) (struct smbus_adapter *adap, struct i2c_msg msgs[],
80                       int num);
81  int (* slave_send) (struct smbus_adapter *,char *, int);
82  int (* slave_recv) (struct smbus_adapter *,char *, int);
83  int (* algo_control) (struct smbus_adapter *, unsigned int, unsigned long);
84  int (* client_register) (struct smbus_client *);
85  int (* client_unregister) (struct smbus_client *);
86};
87
88/* An adapter is a specifc instance of a bus: for each detected bus, there will
89   be an adapter. Its operation is controlled by an algorithm.
90   SPINLOCK must be the same as declared in i2c.h.
91   This structure is an extension of i2c_algorithm. */
92struct smbus_adapter {
93  char name[32];
94  unsigned int id;
95  struct smbus_algorithm *algo;
96  void *data;
97#ifdef SPINLOCK
98  spinlock_t lock;
99  unsigned long lockflags;
100#else
101  struct semaphore lock;
102#endif
103  unsigned int flags;
104  struct smbus_client *clients[I2C_CLIENT_MAX];
105  int client_count;
106  int timeout;
107  int retries;
108
109  /* Here ended i2c_adapter */
110  s32 (* smbus_access) (u8 addr, char read_write,
111                        u8 command, int size, union smbus_data * data);
112};
113
114/* We need to mark SMBus algorithms in the algorithm structure.
115   Note that any and all adapters using a non-i2c driver use in this
116   setup ALGO_SMBUS. Adapters define their own smbus access routine.
117   This also means that adapter->smbus_access is only available if
118   this flag is set! */
119#define ALGO_SMBUS 0x40000
120
121/* SMBus Adapter ids */
122#define SMBUS_PIIX4 1
123
124/* Detect whether we are on an SMBus-only bus. Note that if this returns
125   false, you can still use the smbus access routines, as these emulate
126   the SMBus on I2C. Unless they are undefined on your algorithm, of
127   course. */
128#define i2c_is_smbus_client(clientptr) \
129        ((clientptr)->adapter->algo->id == ALGO_SMBUS)
130#define i2c_is_smbus_adapter(adapptr) \
131        ((adapptr)->algo->id == ALGO_SMBUS)
132
133/* This union is used within smbus_access routines */
134union smbus_data { 
135        u8 byte;
136        u16 word;
137        u8 block[32];
138};
139
140/* smbus_access read or write markers */
141#define SMBUS_READ      1
142#define SMBUS_WRITE     0
143
144/* SMBus transaction types (size parameter in the above functions)
145   Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
146#define SMBUS_QUICK      0
147#define SMBUS_BYTE       1
148#define SMBUS_BYTE_DATA  2
149#define SMBUS_WORD_DATA  3
150#define SMBUS_PROC_CALL  4
151#define SMBUS_BLOCK_DATA 5
152
153/* Declare an algorithm structure. All SMBus derived adapters should use this
154   algorithm! */
155extern struct smbus_algorithm smbus_algorithm;
156
157/* This is the very generalized SMBus access routine. You probably do not
158   want to use this, though; one of the functions below may be much easier,
159   and probably just as fast.
160   Note that we use i2c_adapter here, because you do not need a specific
161   smbus adapter to call this function. */
162extern s32 smbus_access (struct i2c_adapter * adapter, u8 addr, 
163                         char read_write, u8 command, int size,
164                         union smbus_data * data);
165
166/* Now follow the 'nice' access routines. These also document the calling
167   conventions of smbus_access. */
168
169extern inline s32 smbus_write_quick(struct i2c_adapter * adapter, u8 addr, 
170                                    u8 value)
171{
172  return smbus_access(adapter,addr,value,0,SMBUS_QUICK,NULL);
173}
174
175extern inline s32 smbus_read_byte(struct i2c_adapter * adapter,u8 addr)
176{
177  union smbus_data data;
178  if (smbus_access(adapter,addr,SMBUS_READ,0,SMBUS_BYTE,&data))
179    return -1;
180  else
181    return data.byte;
182}
183
184extern inline s32 smbus_write_byte(struct i2c_adapter * adapter, u8 addr, 
185                                   u8 value)
186{
187  return smbus_access(adapter,addr,SMBUS_WRITE,value, SMBUS_BYTE,NULL);
188}
189
190extern inline s32 smbus_read_byte_data(struct i2c_adapter * adapter,
191                                       u8 addr, u8 command)
192{
193  union smbus_data data;
194  if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_BYTE_DATA,&data))
195    return -1;
196  else
197    return data.byte;
198}
199
200extern inline s32 smbus_write_byte_data(struct i2c_adapter * adapter,
201                                        u8 addr, u8 command, u8 value)
202{
203  union smbus_data data;
204  data.byte = value;
205  return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BYTE_DATA,&data);
206}
207
208extern inline s32 smbus_read_word_data(struct i2c_adapter * adapter,
209                                       u8 addr, u8 command)
210{
211  union smbus_data data;
212  if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_WORD_DATA,&data))
213    return -1;
214  else
215    return data.word;
216}
217
218extern inline s32 smbus_write_word_data(struct i2c_adapter * adapter,
219                                        u8 addr, u8 command, u16 value)
220{
221  union smbus_data data;
222  data.word = value;
223  return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_WORD_DATA,&data);
224}
225
226extern inline s32 smbus_process_call(struct i2c_adapter * adapter,
227                                     u8 addr, u8 command, u16 value)
228{
229  union smbus_data data;
230  data.word = value;
231  if (smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_PROC_CALL,&data))
232    return -1;
233  else
234    return data.word;
235}
236
237/* Returns the number of read bytes */
238extern inline s32 smbus_read_block_data(struct i2c_adapter * adapter,
239                                        u8 addr, u8 command, u8 *values)
240{
241  union smbus_data data;
242  int i;
243  if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_BLOCK_DATA,&data))
244    return -1;
245  else {
246    for (i = 1; i <= data.block[0]; i++)
247      values[i-1] = data.block[i];
248    return data.block[0];
249  }
250}
251
252extern inline int smbus_write_block_data(struct i2c_adapter * adapter,
253                                         u8 addr, u8 command, u8 length,
254                                         u8 *values)
255{
256  union smbus_data data;
257  int i;
258  if (length > 32)
259    length = 32;
260  for (i = 1; i <= length; i++)
261    data.block[i] = values[i-1];
262  data.block[0] = length;
263  return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BLOCK_DATA,&data);
264}
265
266
267/* Next: define SMBus variants of registering. */
268
269#define smbus_add_algorithm(algoptr) \
270        i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
271#define smbus_del_algorithm(algoptr) \
272        i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
273
274#define smbus_add_adapter(adapptr) \
275        i2c_add_adapter((struct i2c_adapter *) (adapptr))
276#define smbus_del_adapter(adapptr) \
277        i2c_del_adapter((struct i2c_adapter *) (adapptr))
278
279#define smbus_add_driver(driverptr) \
280        i2c_add_driver((struct i2c_driver *) (driverptr))
281#define smbus_del_driver(driverptr) \
282        i2c_add_driver((struct i2c_driver *) (driverptr))
283
284#define smbus_attach_client(clientptr) \
285        i2c_attach_client((struct i2c_client *) (clientptr))
286#define smbus_detach_client(clientptr) \
287        i2c_detach_client((struct i2c_client *) (clientptr))
288
289
290#endif /* def __KERNEL__ */
291
292#endif /* ndef SENSORS_SMBUS_H */
293
Note: See TracBrowser for help on using the browser.