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

Revision 22, 6.0 KB (checked in by frodo, 15 years ago)

Fixes to make code compile with 2.1 kernels

Everything now compiles cleanly (except for warnings in kernel header files)
against 2.1.122. As I do not run 2.1 kernels, loading them could not be
tested.

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