isa module added, some bugfixes

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


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@12 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Frodo Looijaard committed 1998-11-23 22:34:34 +00:00
1 parent ed7e4c3001
commit 4d29df9f32
13 files changed
+900 -107

No files matched your search

+3 -1
View File
@@ -7,6 +7,8 @@ Document version 1.0, 19981101.
1.1, 19981111.
1.2, 19981118.
--> Never, ever change the driver struct with this technique!
Object oriented approach
========================
@@ -168,7 +170,7 @@ included in kernels around 1.2.120!).
A driver
--------
struct sensor_driver {
struct i2c_driver {
char name[32];
int id;
unsigned int flags;
+1 -1
View File
@@ -22,7 +22,7 @@ MODULE_DIR := src
# Regrettably, even 'simply expanded variables' will not put their currently
# defined value verbatim into the command-list of rules...
SRCTARGETS := $(MODULE_DIR)/smbus.o $(MODULE_DIR)/piix4.o
SRCTARGETS := $(MODULE_DIR)/smbus.o $(MODULE_DIR)/piix4.o $(MODULE_DIR)/isa.o
# Include all dependency files
INCLUDEFILES += $(SRCTARGETS:.o=.d)
+191
View File
@@ -0,0 +1,191 @@
/*
isa.c - A Linux module for reading sensor data.
Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* This implements an i2c algorithm/adapter for ISA bus. Not that this is
on first sight very useful; almost no functionality is preserved.
Except that it makes writing drivers for chips which can be on both
the SMBus and the ISA bus very much easier. See lm78.c for an example
of this. */
#include <linux/module.h>
#include <linux/kernel.h>
#include "i2c.h"
#ifdef SPINLOCK
#include <asm/spinlock.h>
#else
#include <asm/semaphore.h>
#endif
#include "version.h"
#include "isa.h"
static int isa_master_xfer (struct isa_adapter *adap,
struct i2c_msg msgs[], int num);
static int isa_slave_send (struct isa_adapter *adap, char *data, int len);
static int isa_slave_recv (struct isa_adapter *adap, char *data, int len);
static int isa_algo_control (struct isa_adapter *adap, unsigned int cmd,
unsigned long arg);
static int isa_client_register (struct isa_client *client);
static int isa_client_unregister (struct isa_client *client);
static int isa_init(void);
static int isa_cleanup(void);
#ifdef MODULE
extern int init_module(void);
extern int cleanup_module(void);
#endif /* MODULE */
/* This is the actual algorithm we define */
static struct isa_algorithm isa_algorithm = {
/* name */ "ISA bus adapter",
/* id */ ALGO_ISA,
/* master_xfer */ &isa_master_xfer,
/* slave_send */ &isa_slave_send,
/* slave_rcv */ &isa_slave_recv,
/* algo_control */ &isa_algo_control,
/* client_register */ &isa_client_register,
/* client_unregister*/&isa_client_unregister
};
/* There can only be one... */
static struct isa_adapter isa_adapter;
/* Used in isa_init/cleanup */
static int isa_initialized;
/* Algorithm master_xfer call-back implementation. Can't do that... */
int isa_master_xfer (struct isa_adapter *adap, struct i2c_msg msgs[],
int num)
{
printk("isa_master_xfer called for adapter `%s' "
"(no i2c level access possible!)\n",
adap->name);
return 0;
}
/* Algorithm slave_send call-back implementation. Can't do that... */
int isa_slave_send (struct isa_adapter *adap, char *data, int len)
{
printk("isa_slave_send called for adapter `%s' "
"(no i2c level access possible!)\n",
adap->name);
return 0;
}
/* Algorithm slave_recv call-back implementation. Can't do that... */
int isa_slave_recv (struct isa_adapter *adap, char *data, int len)
{
printk("isa_slave_recv called for adapter `%s' "
"(no i2c level access possible!)\n",
adap->name);
return 0;
}
/* Here we can put additional calls to modify the workings of the algorithm.
But right now, there is no need for that. */
int isa_algo_control (struct isa_adapter *adap, unsigned int cmd,
unsigned long arg)
{
return 0;
}
/* Ehm... This is called when a client is registered to an adapter. We could
do all kinds of neat stuff here like, ehm - returning success? */
int isa_client_register (struct isa_client *client)
{
return 0;
}
int isa_client_unregister (struct isa_client *client)
{
return 0;
}
int isa_init(void)
{
int res;
printk("isa.o version %s (%s)\n",LM_VERSION,LM_DATE);
#ifdef DEBUG
if (isa_initialized) {
printk("isa.o: Oops, isa_init called a second time!\n");
return -EBUSY;
}
#endif
isa_initialized = 0;
if ((res = isa_add_algorithm(&isa_algorithm))) {
printk("isa.o: Algorithm registration failed, module isa.o not inserted\n");
isa_cleanup();
return res;
}
isa_initialized++;
strcpy(isa_adapter.name,"ISA main adapter");
isa_adapter.id = ALGO_ISA | ISA_MAIN;
isa_adapter.algo = &isa_algorithm;
if ((res = isa_add_adapter(&isa_adapter))) {
printk("isa.o: Adapter registration failed, "
"module isa.o is not inserted\n");
isa_cleanup();
return res;
}
isa_initialized++;
printk("isa.o: ISA bus access for i2c modules initialized\n");
return 0;
}
int isa_cleanup(void)
{
int res;
if (isa_initialized >= 2)
{
if ((res = isa_del_adapter(&isa_adapter))) {
printk("isa.o: isa_del_adapter failed, module not removed\n");
return res;
} else
isa_initialized--;
}
if (isa_initialized >= 1)
{
if ((res = isa_del_algorithm(&isa_algorithm))) {
printk("isa.o: isa_del_algorithm failed, module not removed\n");
return res;
} else
isa_initialized--;
}
return 0;
}
#ifdef MODULE
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
MODULE_DESCRIPTION("ISA bus access through i2c");
int init_module(void)
{
return isa_init();
}
int cleanup_module(void)
{
return isa_cleanup();
}
#endif /* MODULE */
+153
View File
@@ -0,0 +1,153 @@
/*
isa.h - A Linux module for reading sensor data.
Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef SENSORS_SENSOR_H
#define SENSORS_SENSOR_H
/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
OK, earlier versions are not; later versions will probably give problems
too.
*/
#ifdef I2C
#include "i2c/i2c.h"
#else /* def I2C */
#include <linux/i2c.h>
#endif /* def I2C */
#include <asm/types.h>
/* SPINLOCK is defined in i2c.h. */
#ifdef SPINLOCK
#include <asm/spinlock.h>
#else
#include <asm/semaphore.h>
#endif
#include "isa.h"
/* Note that this driver is *not* built upon smbus.c, but is parallel to it.
We do not need SMBus facilities if we are on the ISA bus, after all */
/* Declarations, to keep the compiler happy */
struct isa_driver;
struct isa_client;
struct isa_algorithm;
struct isa_adapter;
/* A driver tells us how we should handle a specific kind of chip.
A specific instance of such a chip is called a client.
This structure is essentially the same as i2c_driver. */
struct isa_driver {
char name[32];
int id;
unsigned int flags;
int (* attach_adapter) (struct isa_adapter *);
int (* detach_client) (struct isa_client *);
int (* command) (struct isa_client *, unsigned int cmd, void *arg);
void (* inc_use) (struct isa_client *);
void (* dec_use) (struct isa_client *);
};
/* A client is a specifc instance of a chip: for each detected chip, there will
be a client. Its operation is controlled by a driver.
This structure is an extension of i2c_client. */
struct isa_client {
char name[32];
int id;
unsigned int flags;
unsigned char addr;
struct isa_adapter *adapter;
struct isa_driver *driver;
void *data;
/* Here ended i2c_client */
unsigned int full_address;
};
/* An algorithm describes how a certain class of busses can be accessed.
A specific instance of sucj a bus is called an adapter.
This structure is essentially the same as i2c_adapter. */
struct isa_algorithm {
char name[32];
unsigned int id;
int (* master_xfer) (struct isa_adapter *adap, struct i2c_msg msgs[],
int num);
int (* slave_send) (struct isa_adapter *,char *, int);
int (* slave_recv) (struct isa_adapter *,char *, int);
int (* algo_control) (struct isa_adapter *, unsigned int, unsigned long);
int (* client_register) (struct isa_client *);
int (* client_unregister) (struct isa_client *);
};
/* An adapter is a specifc instance of a bus: for each detected bus, there will
be an adapter. Its operation is controlled by an algorithm.
SPINLOCK must be the same as declared in i2c.h.
This structure is essentially the same as i2c_algorithm. */
struct isa_adapter {
char name[32];
unsigned int id;
struct isa_algorithm *algo;
void *data;
#ifdef SPINLOCK
spinlock_t lock;
unsigned long lockflags;
#else
struct semaphore lock;
#endif
unsigned int flags;
struct isa_client *clients[I2C_CLIENT_MAX];
int client_count;
int timeout;
int retries;
};
/* We need to mark ISA algorithms in the algorithm structure. */
#define ALGO_ISA 0x50000
/* ISA Adapter ids */
#define ISA_MAIN 1
/* Detect whether we are on the isa bus. If this returns true, all i2c
access will fail! */
#define i2c_is_isa_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_ISA)
/* Next: define ISA variants of registering. */
#define isa_add_algorithm(algoptr) \
i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
#define isa_del_algorithm(algoptr) \
i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
#define isa_add_adapter(adapptr) \
i2c_add_adapter((struct i2c_adapter *) (adapptr))
#define isa_del_adapter(adapptr) \
i2c_del_adapter((struct i2c_adapter *) (adapptr))
#define isa_add_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define isa_del_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define isa_attach_client(clientptr) \
i2c_attach_client((struct i2c_client *) (clientptr))
#define isa_detach_client(clientptr) \
i2c_detach_client((struct i2c_client *) (clientptr))
#endif /* ndef SENSORS_ISA_H */
+153
View File
@@ -0,0 +1,153 @@
/*
isa.h - A Linux module for reading sensor data.
Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef SENSORS_SENSOR_H
#define SENSORS_SENSOR_H
/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
OK, earlier versions are not; later versions will probably give problems
too.
*/
#ifdef I2C
#include "i2c/i2c.h"
#else /* def I2C */
#include <linux/i2c.h>
#endif /* def I2C */
#include <asm/types.h>
/* SPINLOCK is defined in i2c.h. */
#ifdef SPINLOCK
#include <asm/spinlock.h>
#else
#include <asm/semaphore.h>
#endif
#include "isa.h"
/* Note that this driver is *not* built upon smbus.c, but is parallel to it.
We do not need SMBus facilities if we are on the ISA bus, after all */
/* Declarations, to keep the compiler happy */
struct isa_driver;
struct isa_client;
struct isa_algorithm;
struct isa_adapter;
/* A driver tells us how we should handle a specific kind of chip.
A specific instance of such a chip is called a client.
This structure is essentially the same as i2c_driver. */
struct isa_driver {
char name[32];
int id;
unsigned int flags;
int (* attach_adapter) (struct isa_adapter *);
int (* detach_client) (struct isa_client *);
int (* command) (struct isa_client *, unsigned int cmd, void *arg);
void (* inc_use) (struct isa_client *);
void (* dec_use) (struct isa_client *);
};
/* A client is a specifc instance of a chip: for each detected chip, there will
be a client. Its operation is controlled by a driver.
This structure is an extension of i2c_client. */
struct isa_client {
char name[32];
int id;
unsigned int flags;
unsigned char addr;
struct isa_adapter *adapter;
struct isa_driver *driver;
void *data;
/* Here ended i2c_client */
unsigned int full_address;
};
/* An algorithm describes how a certain class of busses can be accessed.
A specific instance of sucj a bus is called an adapter.
This structure is essentially the same as i2c_adapter. */
struct isa_algorithm {
char name[32];
unsigned int id;
int (* master_xfer) (struct isa_adapter *adap, struct i2c_msg msgs[],
int num);
int (* slave_send) (struct isa_adapter *,char *, int);
int (* slave_recv) (struct isa_adapter *,char *, int);
int (* algo_control) (struct isa_adapter *, unsigned int, unsigned long);
int (* client_register) (struct isa_client *);
int (* client_unregister) (struct isa_client *);
};
/* An adapter is a specifc instance of a bus: for each detected bus, there will
be an adapter. Its operation is controlled by an algorithm.
SPINLOCK must be the same as declared in i2c.h.
This structure is essentially the same as i2c_algorithm. */
struct isa_adapter {
char name[32];
unsigned int id;
struct isa_algorithm *algo;
void *data;
#ifdef SPINLOCK
spinlock_t lock;
unsigned long lockflags;
#else
struct semaphore lock;
#endif
unsigned int flags;
struct isa_client *clients[I2C_CLIENT_MAX];
int client_count;
int timeout;
int retries;
};
/* We need to mark ISA algorithms in the algorithm structure. */
#define ALGO_ISA 0x50000
/* ISA Adapter ids */
#define ISA_MAIN 1
/* Detect whether we are on the isa bus. If this returns true, all i2c
access will fail! */
#define i2c_is_isa_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_ISA)
/* Next: define ISA variants of registering. */
#define isa_add_algorithm(algoptr) \
i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
#define isa_del_algorithm(algoptr) \
i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
#define isa_add_adapter(adapptr) \
i2c_add_adapter((struct i2c_adapter *) (adapptr))
#define isa_del_adapter(adapptr) \
i2c_del_adapter((struct i2c_adapter *) (adapptr))
#define isa_add_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define isa_del_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define isa_attach_client(clientptr) \
i2c_attach_client((struct i2c_client *) (clientptr))
#define isa_detach_client(clientptr) \
i2c_detach_client((struct i2c_client *) (clientptr))
#endif /* ndef SENSORS_ISA_H */
+25 -8
View File
@@ -124,6 +124,13 @@ struct smbus_adapter {
/* SMBus Adapter ids */
#define SMBUS_PIIX4 1
/* Detect whether we are on an SMBus-only bus. Note that if this returns
false, you can still use the smbus access routines, as these emulate
the SMBus on I2C. Unless they are undefined on your algorithm, of
course. */
#define i2c_is_smbus_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_SMBUS)
/* This union is used within smbus_access routines */
union smbus_data {
u8 byte;
@@ -255,18 +262,28 @@ extern inline int smbus_write_block_data(struct smbus_adapter * adapter,
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BLOCK_DATA,&data);
}
/* Next: define SMBus variants of registering. */
extern int smbus_add_algorithm(struct smbus_algorithm *algorithm);
extern int smbus_del_algorithm(struct smbus_algorithm *algorithm);
extern int smbus_add_adapter(struct smbus_adapter *adapter);
extern int smbus_del_adapter(struct smbus_adapter *adapter);
#define smbus_add_algorithm(algoptr) \
i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
#define smbus_del_algorithm(algoptr) \
i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
extern int smbus_add_driver(struct smbus_driver *driver);
extern int smbus_del_driver(struct smbus_driver *driver);
#define smbus_add_adapter(adapptr) \
i2c_add_adapter((struct i2c_adapter *) (adapptr))
#define smbus_del_adapter(adapptr) \
i2c_del_adapter((struct i2c_adapter *) (adapptr))
extern int smbus_attach_client(struct smbus_client *client);
extern int smbus_detach_client(struct smbus_client *client);
#define smbus_add_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define smbus_del_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define smbus_attach_client(clientptr) \
i2c_attach_client((struct i2c_client *) (clientptr))
#define smbus_detach_client(clientptr) \
i2c_detach_client((struct i2c_client *) (clientptr))
#endif /* ndef SENSORS_SMBUS_H */
+1 -43
View File
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include "i2c.h"
#ifdef SPINLOCK
#include <asm/spinlock.h>
#else
@@ -156,49 +157,6 @@ int smbus_client_unregister (struct smbus_client *client)
return 0;
}
/* Next: define SMBus variants of registering. Very boring. To make it possible
to change these definitions in the future without recompiling all modules,
we do not define them as inline. */
int smbus_add_algorithm(struct smbus_algorithm *algorithm)
{
return i2c_add_algorithm( (struct i2c_algorithm *) algorithm);
}
int smbus_del_algorithm(struct smbus_algorithm *algorithm)
{
return i2c_del_algorithm( (struct i2c_algorithm *) algorithm);
}
int smbus_add_adapter(struct smbus_adapter *adapter)
{
return i2c_add_adapter( (struct i2c_adapter *) adapter);
}
int smbus_del_adapter(struct smbus_adapter *adapter)
{
return i2c_del_adapter( (struct i2c_adapter *) adapter);
}
int smbus_add_driver(struct smbus_driver *driver)
{
return i2c_add_driver( (struct i2c_driver *) driver);
}
int smbus_del_driver(struct smbus_driver *driver)
{
return i2c_del_driver( (struct i2c_driver *) driver);
}
int smbus_attach_client(struct smbus_client *client)
{
return i2c_attach_client( (struct i2c_client *) client);
}
int smbus_detach_client(struct smbus_client *client)
{
return i2c_detach_client( (struct i2c_client *) client);
}
int smbus_init(void)
{
int res;
+1 -1
View File
@@ -22,7 +22,7 @@ MODULE_DIR := src
# Regrettably, even 'simply expanded variables' will not put their currently
# defined value verbatim into the command-list of rules...
SRCTARGETS := $(MODULE_DIR)/smbus.o $(MODULE_DIR)/piix4.o
SRCTARGETS := $(MODULE_DIR)/smbus.o $(MODULE_DIR)/piix4.o $(MODULE_DIR)/isa.o
# Include all dependency files
INCLUDEFILES += $(SRCTARGETS:.o=.d)
+191
View File
@@ -0,0 +1,191 @@
/*
isa.c - A Linux module for reading sensor data.
Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* This implements an i2c algorithm/adapter for ISA bus. Not that this is
on first sight very useful; almost no functionality is preserved.
Except that it makes writing drivers for chips which can be on both
the SMBus and the ISA bus very much easier. See lm78.c for an example
of this. */
#include <linux/module.h>
#include <linux/kernel.h>
#include "i2c.h"
#ifdef SPINLOCK
#include <asm/spinlock.h>
#else
#include <asm/semaphore.h>
#endif
#include "version.h"
#include "isa.h"
static int isa_master_xfer (struct isa_adapter *adap,
struct i2c_msg msgs[], int num);
static int isa_slave_send (struct isa_adapter *adap, char *data, int len);
static int isa_slave_recv (struct isa_adapter *adap, char *data, int len);
static int isa_algo_control (struct isa_adapter *adap, unsigned int cmd,
unsigned long arg);
static int isa_client_register (struct isa_client *client);
static int isa_client_unregister (struct isa_client *client);
static int isa_init(void);
static int isa_cleanup(void);
#ifdef MODULE
extern int init_module(void);
extern int cleanup_module(void);
#endif /* MODULE */
/* This is the actual algorithm we define */
static struct isa_algorithm isa_algorithm = {
/* name */ "ISA bus adapter",
/* id */ ALGO_ISA,
/* master_xfer */ &isa_master_xfer,
/* slave_send */ &isa_slave_send,
/* slave_rcv */ &isa_slave_recv,
/* algo_control */ &isa_algo_control,
/* client_register */ &isa_client_register,
/* client_unregister*/&isa_client_unregister
};
/* There can only be one... */
static struct isa_adapter isa_adapter;
/* Used in isa_init/cleanup */
static int isa_initialized;
/* Algorithm master_xfer call-back implementation. Can't do that... */
int isa_master_xfer (struct isa_adapter *adap, struct i2c_msg msgs[],
int num)
{
printk("isa_master_xfer called for adapter `%s' "
"(no i2c level access possible!)\n",
adap->name);
return 0;
}
/* Algorithm slave_send call-back implementation. Can't do that... */
int isa_slave_send (struct isa_adapter *adap, char *data, int len)
{
printk("isa_slave_send called for adapter `%s' "
"(no i2c level access possible!)\n",
adap->name);
return 0;
}
/* Algorithm slave_recv call-back implementation. Can't do that... */
int isa_slave_recv (struct isa_adapter *adap, char *data, int len)
{
printk("isa_slave_recv called for adapter `%s' "
"(no i2c level access possible!)\n",
adap->name);
return 0;
}
/* Here we can put additional calls to modify the workings of the algorithm.
But right now, there is no need for that. */
int isa_algo_control (struct isa_adapter *adap, unsigned int cmd,
unsigned long arg)
{
return 0;
}
/* Ehm... This is called when a client is registered to an adapter. We could
do all kinds of neat stuff here like, ehm - returning success? */
int isa_client_register (struct isa_client *client)
{
return 0;
}
int isa_client_unregister (struct isa_client *client)
{
return 0;
}
int isa_init(void)
{
int res;
printk("isa.o version %s (%s)\n",LM_VERSION,LM_DATE);
#ifdef DEBUG
if (isa_initialized) {
printk("isa.o: Oops, isa_init called a second time!\n");
return -EBUSY;
}
#endif
isa_initialized = 0;
if ((res = isa_add_algorithm(&isa_algorithm))) {
printk("isa.o: Algorithm registration failed, module isa.o not inserted\n");
isa_cleanup();
return res;
}
isa_initialized++;
strcpy(isa_adapter.name,"ISA main adapter");
isa_adapter.id = ALGO_ISA | ISA_MAIN;
isa_adapter.algo = &isa_algorithm;
if ((res = isa_add_adapter(&isa_adapter))) {
printk("isa.o: Adapter registration failed, "
"module isa.o is not inserted\n");
isa_cleanup();
return res;
}
isa_initialized++;
printk("isa.o: ISA bus access for i2c modules initialized\n");
return 0;
}
int isa_cleanup(void)
{
int res;
if (isa_initialized >= 2)
{
if ((res = isa_del_adapter(&isa_adapter))) {
printk("isa.o: isa_del_adapter failed, module not removed\n");
return res;
} else
isa_initialized--;
}
if (isa_initialized >= 1)
{
if ((res = isa_del_algorithm(&isa_algorithm))) {
printk("isa.o: isa_del_algorithm failed, module not removed\n");
return res;
} else
isa_initialized--;
}
return 0;
}
#ifdef MODULE
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
MODULE_DESCRIPTION("ISA bus access through i2c");
int init_module(void)
{
return isa_init();
}
int cleanup_module(void)
{
return isa_cleanup();
}
#endif /* MODULE */
+153
View File
@@ -0,0 +1,153 @@
/*
isa.h - A Linux module for reading sensor data.
Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef SENSORS_SENSOR_H
#define SENSORS_SENSOR_H
/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
OK, earlier versions are not; later versions will probably give problems
too.
*/
#ifdef I2C
#include "i2c/i2c.h"
#else /* def I2C */
#include <linux/i2c.h>
#endif /* def I2C */
#include <asm/types.h>
/* SPINLOCK is defined in i2c.h. */
#ifdef SPINLOCK
#include <asm/spinlock.h>
#else
#include <asm/semaphore.h>
#endif
#include "isa.h"
/* Note that this driver is *not* built upon smbus.c, but is parallel to it.
We do not need SMBus facilities if we are on the ISA bus, after all */
/* Declarations, to keep the compiler happy */
struct isa_driver;
struct isa_client;
struct isa_algorithm;
struct isa_adapter;
/* A driver tells us how we should handle a specific kind of chip.
A specific instance of such a chip is called a client.
This structure is essentially the same as i2c_driver. */
struct isa_driver {
char name[32];
int id;
unsigned int flags;
int (* attach_adapter) (struct isa_adapter *);
int (* detach_client) (struct isa_client *);
int (* command) (struct isa_client *, unsigned int cmd, void *arg);
void (* inc_use) (struct isa_client *);
void (* dec_use) (struct isa_client *);
};
/* A client is a specifc instance of a chip: for each detected chip, there will
be a client. Its operation is controlled by a driver.
This structure is an extension of i2c_client. */
struct isa_client {
char name[32];
int id;
unsigned int flags;
unsigned char addr;
struct isa_adapter *adapter;
struct isa_driver *driver;
void *data;
/* Here ended i2c_client */
unsigned int full_address;
};
/* An algorithm describes how a certain class of busses can be accessed.
A specific instance of sucj a bus is called an adapter.
This structure is essentially the same as i2c_adapter. */
struct isa_algorithm {
char name[32];
unsigned int id;
int (* master_xfer) (struct isa_adapter *adap, struct i2c_msg msgs[],
int num);
int (* slave_send) (struct isa_adapter *,char *, int);
int (* slave_recv) (struct isa_adapter *,char *, int);
int (* algo_control) (struct isa_adapter *, unsigned int, unsigned long);
int (* client_register) (struct isa_client *);
int (* client_unregister) (struct isa_client *);
};
/* An adapter is a specifc instance of a bus: for each detected bus, there will
be an adapter. Its operation is controlled by an algorithm.
SPINLOCK must be the same as declared in i2c.h.
This structure is essentially the same as i2c_algorithm. */
struct isa_adapter {
char name[32];
unsigned int id;
struct isa_algorithm *algo;
void *data;
#ifdef SPINLOCK
spinlock_t lock;
unsigned long lockflags;
#else
struct semaphore lock;
#endif
unsigned int flags;
struct isa_client *clients[I2C_CLIENT_MAX];
int client_count;
int timeout;
int retries;
};
/* We need to mark ISA algorithms in the algorithm structure. */
#define ALGO_ISA 0x50000
/* ISA Adapter ids */
#define ISA_MAIN 1
/* Detect whether we are on the isa bus. If this returns true, all i2c
access will fail! */
#define i2c_is_isa_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_ISA)
/* Next: define ISA variants of registering. */
#define isa_add_algorithm(algoptr) \
i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
#define isa_del_algorithm(algoptr) \
i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
#define isa_add_adapter(adapptr) \
i2c_add_adapter((struct i2c_adapter *) (adapptr))
#define isa_del_adapter(adapptr) \
i2c_del_adapter((struct i2c_adapter *) (adapptr))
#define isa_add_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define isa_del_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define isa_attach_client(clientptr) \
i2c_attach_client((struct i2c_client *) (clientptr))
#define isa_detach_client(clientptr) \
i2c_detach_client((struct i2c_client *) (clientptr))
#endif /* ndef SENSORS_ISA_H */
+1 -43
View File
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include "i2c.h"
#ifdef SPINLOCK
#include <asm/spinlock.h>
#else
@@ -156,49 +157,6 @@ int smbus_client_unregister (struct smbus_client *client)
return 0;
}
/* Next: define SMBus variants of registering. Very boring. To make it possible
to change these definitions in the future without recompiling all modules,
we do not define them as inline. */
int smbus_add_algorithm(struct smbus_algorithm *algorithm)
{
return i2c_add_algorithm( (struct i2c_algorithm *) algorithm);
}
int smbus_del_algorithm(struct smbus_algorithm *algorithm)
{
return i2c_del_algorithm( (struct i2c_algorithm *) algorithm);
}
int smbus_add_adapter(struct smbus_adapter *adapter)
{
return i2c_add_adapter( (struct i2c_adapter *) adapter);
}
int smbus_del_adapter(struct smbus_adapter *adapter)
{
return i2c_del_adapter( (struct i2c_adapter *) adapter);
}
int smbus_add_driver(struct smbus_driver *driver)
{
return i2c_add_driver( (struct i2c_driver *) driver);
}
int smbus_del_driver(struct smbus_driver *driver)
{
return i2c_del_driver( (struct i2c_driver *) driver);
}
int smbus_attach_client(struct smbus_client *client)
{
return i2c_attach_client( (struct i2c_client *) client);
}
int smbus_detach_client(struct smbus_client *client)
{
return i2c_detach_client( (struct i2c_client *) client);
}
int smbus_init(void)
{
int res;
+25 -8
View File
@@ -124,6 +124,13 @@ struct smbus_adapter {
/* SMBus Adapter ids */
#define SMBUS_PIIX4 1
/* Detect whether we are on an SMBus-only bus. Note that if this returns
false, you can still use the smbus access routines, as these emulate
the SMBus on I2C. Unless they are undefined on your algorithm, of
course. */
#define i2c_is_smbus_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_SMBUS)
/* This union is used within smbus_access routines */
union smbus_data {
u8 byte;
@@ -255,18 +262,28 @@ extern inline int smbus_write_block_data(struct smbus_adapter * adapter,
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BLOCK_DATA,&data);
}
/* Next: define SMBus variants of registering. */
extern int smbus_add_algorithm(struct smbus_algorithm *algorithm);
extern int smbus_del_algorithm(struct smbus_algorithm *algorithm);
extern int smbus_add_adapter(struct smbus_adapter *adapter);
extern int smbus_del_adapter(struct smbus_adapter *adapter);
#define smbus_add_algorithm(algoptr) \
i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
#define smbus_del_algorithm(algoptr) \
i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
extern int smbus_add_driver(struct smbus_driver *driver);
extern int smbus_del_driver(struct smbus_driver *driver);
#define smbus_add_adapter(adapptr) \
i2c_add_adapter((struct i2c_adapter *) (adapptr))
#define smbus_del_adapter(adapptr) \
i2c_del_adapter((struct i2c_adapter *) (adapptr))
extern int smbus_attach_client(struct smbus_client *client);
extern int smbus_detach_client(struct smbus_client *client);
#define smbus_add_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define smbus_del_driver(driverptr) \
i2c_add_driver((struct i2c_driver *) (driverptr))
#define smbus_attach_client(clientptr) \
i2c_attach_client((struct i2c_client *) (clientptr))
#define smbus_detach_client(clientptr) \
i2c_detach_client((struct i2c_client *) (clientptr))
#endif /* ndef SENSORS_SMBUS_H */
+2 -2
View File
@@ -1,2 +1,2 @@
#define LM_DATE "19981103"
#define LM_VERSION "2.0.0pre0"
#define LM_DATE "19981122"
#define LM_VERSION "2.0.0pre1"