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

Revision 12, 5.9 KB (checked in by frodo, 16 years ago)

isa module added, some bugfixes

'isa.o' is roughly what was called 'sensor.o' in doc/design.

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