root/lm-sensors/trunk/src/smbus.c @ 9

Revision 9, 6.9 KB (checked in by frodo, 15 years ago)

piix4.c basic skeleton

The real PIIX4 access code must still be written; perhaps somebody else could
do this? Most of it could be copied from the old piix4.c. But check carefully
what you are doing, as some things *have* changed (like the SMBUS_{BYTE,...}
variables!).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    smbus.c - 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#include <linux/module.h>
21#include <linux/kernel.h>
22
23#ifdef SPINLOCK
24#include <asm/spinlock.h>
25#else
26#include <asm/semaphore.h>
27#endif
28
29#include "smbus.h"
30
31static s32 smbus_access_i2c (struct smbus_adapter * adapter, u8 addr,
32                             char read_write, u8 command, int size,
33                             union smbus_data * data);
34
35static int smbus_master_xfer (struct smbus_adapter *adap,
36                              struct i2c_msg msgs[], int num);
37static int smbus_slave_send (struct smbus_adapter *adap, char *data, int len);
38static int smbus_slave_recv (struct smbus_adapter *adap, char *data, int len);
39static int smbus_algo_control (struct smbus_adapter *adap, unsigned int cmd, 
40                               unsigned long arg);
41static int smbus_client_register (struct smbus_client *client);
42static int smbus_client_unregister (struct smbus_client *client);
43
44static int smbus_init(void);
45static int smbus_cleanup(void);
46
47#ifdef MODULE
48extern int init_module(void);
49extern int cleanup_module(void);
50#endif /* MODULE */
51
52/* This is the actual algorithm we define */
53struct smbus_algorithm smbus_algorithm = {
54  /* name */            "Non-I2C SMBus adapter",
55  /* id */              ALGO_SMBUS,
56  /* master_xfer */     &smbus_master_xfer,
57  /* slave_send */      &smbus_slave_send,
58  /* slave_rcv */       &smbus_slave_recv,
59  /* algo_control */    &smbus_algo_control,
60  /* client_register */ &smbus_client_register,
61  /* client_unregister*/&smbus_client_unregister
62};
63
64
65/* OK, so you want to access a bus using the SMBus protocols. Well, it either
66   is registered as a SMBus-only adapter (like the PIIX4), or we need to
67   simulate the SMBus commands using the i2c access routines.
68   We do all locking here, so you can ignore that in the adapter-specific
69   smbus_accesss routine. */
70s32 smbus_access (struct smbus_adapter * adapter, u8 addr, char read_write,
71                  u8 command, int size, union smbus_data * data)
72{
73  int res;
74#ifdef SPINLOCK
75  spin_lock_irqsave(&adapter->lock,adapter->lockflags);
76#else
77  down(&adapter->lock);
78#endif
79  if (adapter->id & ALGO_SMBUS) 
80    res = adapter->smbus_access(addr,read_write,command,size,data);
81  else
82    res = smbus_access_i2c(adapter,addr,read_write,command,size,data);
83#ifdef SPINLOCK
84  spin_unlock_irqrestore(&adapter->lock,adapter->lockflags);
85#else
86  up(&adapter->lock);
87#endif
88  return res;
89}
90 
91/* Simulate a SMBus command using the i2c protocol
92   No checking of paramters is done!
93   For SMBUS_QUICK: Use addr, read_write
94   For SMBUS_BYTE: Use addr, read_write, command
95   ....  */
96s32 smbus_access_i2c(struct smbus_adapter * adapter, u8 addr, char read_write,
97                     u8 command, int size, union smbus_data * data)
98{
99  /* So we need to generate a series of msgs */
100  struct i2c_msg msg[2];
101  char msgbuf0[2];
102  char msgbuf1[32];
103  msg[0].addr = addr;
104  msg[0].flags = read_write;
105  msg[0].len = 0;
106  msg[0].buf = msgbuf0;
107  /* WHATEVER */
108}
109
110/* Algorithm master_xfer call-back implementation. Can't do that... */
111int smbus_master_xfer (struct smbus_adapter *adap, struct i2c_msg msgs[], 
112                       int num)
113{
114  printk("smbus_master_xfer called for adapter `%s' "
115         "(no i2c level access possible!)\n",
116         adap->name);
117  return 0;
118}
119
120/* Algorithm slave_send call-back implementation. Can't do that... */
121int smbus_slave_send (struct smbus_adapter *adap, char *data, int len)
122{
123  printk("smbus_slave_send called for adapter `%s' "
124         "(no i2c level access possible!)\n",
125         adap->name);
126  return 0;
127}
128
129/* Algorithm slave_recv call-back implementation. Can't do that... */
130int smbus_slave_recv (struct smbus_adapter *adap, char *data, int len)
131{
132  printk("smbus_slave_recv called for adapter `%s' "
133         "(no i2c level access possible!)\n",
134         adap->name);
135  return 0;
136}
137
138/* Here we can put additional calls to modify the workings of the algorithm.
139   But right now, there is no need for that. */
140int smbus_algo_control (struct smbus_adapter *adap, unsigned int cmd, 
141                         unsigned long arg)
142{
143  return 0;
144}
145
146/* Ehm... This is called when a client is registered to an adapter. We could
147   do all kinds of neat stuff here like, ehm - returning success? */
148int smbus_client_register (struct smbus_client *client)
149{
150  return 0;
151}
152 
153int smbus_client_unregister (struct smbus_client *client)
154{
155  return 0;
156}
157
158/* Next: define SMBus variants of registering. Very boring. To make it possible
159   to change these definitions in the future without recompiling all modules,
160   we do not define them as inline. */
161int smbus_add_algorithm(struct smbus_algorithm *algorithm)
162{
163  return i2c_add_algorithm( (struct i2c_algorithm *) algorithm);
164}
165
166int smbus_del_algorithm(struct smbus_algorithm *algorithm)
167{
168  return i2c_del_algorithm( (struct i2c_algorithm *) algorithm);
169}
170
171int smbus_add_adapter(struct smbus_adapter *adapter)
172{
173  return i2c_add_adapter( (struct i2c_adapter *) adapter);
174}
175
176int smbus_del_adapter(struct smbus_adapter *adapter)
177{
178  return i2c_del_adapter( (struct i2c_adapter *) adapter);
179}
180
181int smbus_add_driver(struct smbus_driver *driver)
182{
183  return i2c_add_driver( (struct i2c_driver *) driver);
184}
185
186int smbus_del_driver(struct smbus_driver *driver)
187{
188  return i2c_del_driver( (struct i2c_driver *) driver);
189}
190
191int smbus_attach_client(struct smbus_client *client)
192{
193  return i2c_attach_client( (struct i2c_client *) client);
194}
195
196int smbus_detach_client(struct smbus_client *client)
197{
198  return i2c_detach_client( (struct i2c_client *) client);
199}
200
201int smbus_init(void)
202{
203  int res;
204  if ((res = smbus_add_algorithm(&smbus_algorithm)))
205    printk("Module smbus.o not inserted!\n");
206  else
207    printk("smbus.o initialized");
208  return res;
209}
210
211int smbus_cleanup(void)
212{
213  int res;
214  if ((res = smbus_del_algorithm(&smbus_algorithm)))
215    printk("Module smbus.o could not be removed cleanly!\n");
216  return res;
217}
218
219/* OK, this will for now _only_ compile as a module, but this is neat for
220   later, if we want to compile it straight into the kernel */
221#ifdef MODULE
222
223MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
224MODULE_DESCRIPTION("System Management Bus (SMBus) access");
225
226int init_module(void)
227{
228  return smbus_init();
229}
230
231int cleanup_module(void)
232{
233  return smbus_cleanup();
234}
235
236#endif /* MODULE */
Note: See TracBrowser for help on using the browser.