2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-08-30 13:57:41 +00:00

Example lm_sensors-2 driver

Though it is called the LM78 driver, there is not too much LM78 specific
code in it; it can better be seen as an example code skeleton for other
drivers. Right now, it creats a file /proc/sensors-test, which contains
a list of busses it registered itself on. Stupid, but very useful for
testing purposes!

You need a 2.0 kernel for lm78.o to insert (or hack the /proc system
specific parts; see lm78.c of lm_sensors version 1 how to do this).
Other parts of lm_sensors-2 are not tested for 2.1 kernels either, but
I am certain it won't work in this case :-).

See the TODO list to get some idea what is left to do, choose something
and implement it. Or not :-). But please, send a note to the mailing
list when you start on something, to avoid duplicate work...

Other notable changes:
  the smbus_access routines now use (the more logical) i2c_adapter
  structure, instead of smbus_adapter.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@13 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Frodo Looijaard
1998-11-26 10:16:08 +00:00
parent 4d29df9f32
commit 45d6e40e75
12 changed files with 75 additions and 46 deletions

17
TODO
View File

@@ -1,5 +1,16 @@
Many, many things. Most notably:
* Write s32 smbus_access_i2c in smbus.c
* Check out whether we can use the dev interface for smbus (like i2c)
* Write all other modules
* Write smbus_access_i2c in smbus.c
* Write piix4_* in piix4.c
* Complete lm78 driver
* Extend dev interface for SMBus
* Create entries in /proc/bus: a list of all registered busses, and for
each bus, a file with registered clients.
* Write all other drivers
* How to make drivers detect thing *not*; for example, if a Winbond is
present, the LM75 driver should not try to access its simulated
LM75 chips!
* Write a userland-library for SMBus/i2c access (through the /dev interface)
* Write a userland detection program for busses (clients are less important;
but perhaps needed too).
* Bring doc/design up-to-date (it is horribly out of date right now)

View File

@@ -22,7 +22,8 @@ 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 $(MODULE_DIR)/isa.o
SRCTARGETS := $(MODULE_DIR)/smbus.o $(MODULE_DIR)/piix4.o $(MODULE_DIR)/isa.o \
$(MODULE_DIR)/lm78.o
# Include all dependency files
INCLUDEFILES += $(SRCTARGETS:.o=.d)

View File

@@ -49,6 +49,7 @@ s32 piix4_access(u8 addr, char read_write,
u8 command, int size, union smbus_data * data)
{
/* TO BE WRITTEN! */
return -1;
}
@@ -89,10 +90,9 @@ int piix4_cleanup(void)
if (piix4_initialized >= 2)
{
if ((res = smbus_del_adapter(&piix4_adapter))) {
printk("piix4.o: smbus_del_adapter failed, module not removed");
printk("piix4.o: smbus_del_adapter failed, module not removed\n");
return res;
}
else
} else
piix4_initialized--;
}
if (piix4_initialized >= 1) {

View File

@@ -77,7 +77,7 @@ struct isa_client {
void *data;
/* Here ended i2c_client */
unsigned int full_address;
unsigned int isa_addr;
};
/* An algorithm describes how a certain class of busses can be accessed.
@@ -127,6 +127,8 @@ struct isa_adapter {
access will fail! */
#define i2c_is_isa_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_ISA)
#define i2c_is_isa_adapter(adapptr) \
((adapptr)->algo->id == ALGO_ISA)
/* Next: define ISA variants of registering. */
#define isa_add_algorithm(algoptr) \

View File

@@ -77,7 +77,7 @@ struct isa_client {
void *data;
/* Here ended i2c_client */
unsigned int full_address;
unsigned int isa_addr;
};
/* An algorithm describes how a certain class of busses can be accessed.
@@ -127,6 +127,8 @@ struct isa_adapter {
access will fail! */
#define i2c_is_isa_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_ISA)
#define i2c_is_isa_adapter(adapptr) \
((adapptr)->algo->id == ALGO_ISA)
/* Next: define ISA variants of registering. */
#define isa_add_algorithm(algoptr) \

View File

@@ -130,6 +130,8 @@ struct smbus_adapter {
course. */
#define i2c_is_smbus_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_SMBUS)
#define i2c_is_smbus_adapter(adapptr) \
((adapptr)->algo->id == ALGO_SMBUS)
/* This union is used within smbus_access routines */
union smbus_data {
@@ -157,21 +159,23 @@ extern struct smbus_algorithm smbus_algorithm;
/* This is the very generalized SMBus access routine. You probably do not
want to use this, though; one of the functions below may be much easier,
and probably just as fast. */
extern s32 smbus_access (struct smbus_adapter * adapter, u8 addr,
and probably just as fast.
Note that we use i2c_adapter here, because you do not need a specific
smbus adapter to call this function. */
extern s32 smbus_access (struct i2c_adapter * adapter, u8 addr,
char read_write, u8 command, int size,
union smbus_data * data);
/* Now follow the 'nice' access routines. These also document the calling
conventions of smbus_access. */
extern inline s32 smbus_write_quick(struct smbus_adapter * adapter, u8 addr,
extern inline s32 smbus_write_quick(struct i2c_adapter * adapter, u8 addr,
u8 value)
{
return smbus_access(adapter,addr,value,0,SMBUS_QUICK,NULL);
}
extern inline s32 smbus_read_byte(struct smbus_adapter * adapter,u8 addr)
extern inline s32 smbus_read_byte(struct i2c_adapter * adapter,u8 addr)
{
union smbus_data data;
if (smbus_access(adapter,addr,SMBUS_READ,0,SMBUS_BYTE,&data))
@@ -180,13 +184,13 @@ extern inline s32 smbus_read_byte(struct smbus_adapter * adapter,u8 addr)
return data.byte;
}
extern inline s32 smbus_write_byte(struct smbus_adapter * adapter, u8 addr,
extern inline s32 smbus_write_byte(struct i2c_adapter * adapter, u8 addr,
u8 value)
{
return smbus_access(adapter,addr,SMBUS_WRITE,value, SMBUS_BYTE,NULL);
}
extern inline s32 smbus_read_byte_data(struct smbus_adapter * adapter,
extern inline s32 smbus_read_byte_data(struct i2c_adapter * adapter,
u8 addr, u8 command)
{
union smbus_data data;
@@ -196,7 +200,7 @@ extern inline s32 smbus_read_byte_data(struct smbus_adapter * adapter,
return data.byte;
}
extern inline s32 smbus_write_byte_data(struct smbus_adapter * adapter,
extern inline s32 smbus_write_byte_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u8 value)
{
union smbus_data data;
@@ -204,7 +208,7 @@ extern inline s32 smbus_write_byte_data(struct smbus_adapter * adapter,
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BYTE_DATA,&data);
}
extern inline s32 smbus_read_word_data(struct smbus_adapter * adapter,
extern inline s32 smbus_read_word_data(struct i2c_adapter * adapter,
u8 addr, u8 command)
{
union smbus_data data;
@@ -214,7 +218,7 @@ extern inline s32 smbus_read_word_data(struct smbus_adapter * adapter,
return data.word;
}
extern inline s32 smbus_write_word_data(struct smbus_adapter * adapter,
extern inline s32 smbus_write_word_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u16 value)
{
union smbus_data data;
@@ -222,7 +226,7 @@ extern inline s32 smbus_write_word_data(struct smbus_adapter * adapter,
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_WORD_DATA,&data);
}
extern inline s32 smbus_process_call(struct smbus_adapter * adapter,
extern inline s32 smbus_process_call(struct i2c_adapter * adapter,
u8 addr, u8 command, u16 value)
{
union smbus_data data;
@@ -234,7 +238,7 @@ extern inline s32 smbus_process_call(struct smbus_adapter * adapter,
}
/* Returns the number of read bytes */
extern inline s32 smbus_read_block_data(struct smbus_adapter * adapter,
extern inline s32 smbus_read_block_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u8 *values)
{
union smbus_data data;
@@ -248,7 +252,7 @@ extern inline s32 smbus_read_block_data(struct smbus_adapter * adapter,
}
}
extern inline int smbus_write_block_data(struct smbus_adapter * adapter,
extern inline int smbus_write_block_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u8 length,
u8 *values)
{

View File

@@ -30,7 +30,7 @@
#include "version.h"
#include "smbus.h"
static s32 smbus_access_i2c (struct smbus_adapter * adapter, u8 addr,
static s32 smbus_access_i2c (struct i2c_adapter * adapter, u8 addr,
char read_write, u8 command, int size,
union smbus_data * data);
@@ -69,7 +69,7 @@ struct smbus_algorithm smbus_algorithm = {
simulate the SMBus commands using the i2c access routines.
We do all locking here, so you can ignore that in the adapter-specific
smbus_accesss routine. */
s32 smbus_access (struct smbus_adapter * adapter, u8 addr, char read_write,
s32 smbus_access (struct i2c_adapter * adapter, u8 addr, char read_write,
u8 command, int size, union smbus_data * data)
{
int res;
@@ -79,7 +79,8 @@ s32 smbus_access (struct smbus_adapter * adapter, u8 addr, char read_write,
down(&adapter->lock);
#endif
if (adapter->id & ALGO_SMBUS)
res = adapter->smbus_access(addr,read_write,command,size,data);
res = ((struct smbus_adapter *) adapter) ->
smbus_access(addr,read_write,command,size,data);
else
res = smbus_access_i2c(adapter,addr,read_write,command,size,data);
#ifdef SPINLOCK
@@ -95,7 +96,7 @@ s32 smbus_access (struct smbus_adapter * adapter, u8 addr, char read_write,
For SMBUS_QUICK: Use addr, read_write
For SMBUS_BYTE: Use addr, read_write, command
.... */
s32 smbus_access_i2c(struct smbus_adapter * adapter, u8 addr, char read_write,
s32 smbus_access_i2c(struct i2c_adapter * adapter, u8 addr, char read_write,
u8 command, int size, union smbus_data * data)
{
/* So we need to generate a series of msgs */

View File

@@ -22,7 +22,8 @@ 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 $(MODULE_DIR)/isa.o
SRCTARGETS := $(MODULE_DIR)/smbus.o $(MODULE_DIR)/piix4.o $(MODULE_DIR)/isa.o \
$(MODULE_DIR)/lm78.o
# Include all dependency files
INCLUDEFILES += $(SRCTARGETS:.o=.d)

View File

@@ -77,7 +77,7 @@ struct isa_client {
void *data;
/* Here ended i2c_client */
unsigned int full_address;
unsigned int isa_addr;
};
/* An algorithm describes how a certain class of busses can be accessed.
@@ -127,6 +127,8 @@ struct isa_adapter {
access will fail! */
#define i2c_is_isa_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_ISA)
#define i2c_is_isa_adapter(adapptr) \
((adapptr)->algo->id == ALGO_ISA)
/* Next: define ISA variants of registering. */
#define isa_add_algorithm(algoptr) \

View File

@@ -49,6 +49,7 @@ s32 piix4_access(u8 addr, char read_write,
u8 command, int size, union smbus_data * data)
{
/* TO BE WRITTEN! */
return -1;
}
@@ -89,10 +90,9 @@ int piix4_cleanup(void)
if (piix4_initialized >= 2)
{
if ((res = smbus_del_adapter(&piix4_adapter))) {
printk("piix4.o: smbus_del_adapter failed, module not removed");
printk("piix4.o: smbus_del_adapter failed, module not removed\n");
return res;
}
else
} else
piix4_initialized--;
}
if (piix4_initialized >= 1) {

View File

@@ -30,7 +30,7 @@
#include "version.h"
#include "smbus.h"
static s32 smbus_access_i2c (struct smbus_adapter * adapter, u8 addr,
static s32 smbus_access_i2c (struct i2c_adapter * adapter, u8 addr,
char read_write, u8 command, int size,
union smbus_data * data);
@@ -69,7 +69,7 @@ struct smbus_algorithm smbus_algorithm = {
simulate the SMBus commands using the i2c access routines.
We do all locking here, so you can ignore that in the adapter-specific
smbus_accesss routine. */
s32 smbus_access (struct smbus_adapter * adapter, u8 addr, char read_write,
s32 smbus_access (struct i2c_adapter * adapter, u8 addr, char read_write,
u8 command, int size, union smbus_data * data)
{
int res;
@@ -79,7 +79,8 @@ s32 smbus_access (struct smbus_adapter * adapter, u8 addr, char read_write,
down(&adapter->lock);
#endif
if (adapter->id & ALGO_SMBUS)
res = adapter->smbus_access(addr,read_write,command,size,data);
res = ((struct smbus_adapter *) adapter) ->
smbus_access(addr,read_write,command,size,data);
else
res = smbus_access_i2c(adapter,addr,read_write,command,size,data);
#ifdef SPINLOCK
@@ -95,7 +96,7 @@ s32 smbus_access (struct smbus_adapter * adapter, u8 addr, char read_write,
For SMBUS_QUICK: Use addr, read_write
For SMBUS_BYTE: Use addr, read_write, command
.... */
s32 smbus_access_i2c(struct smbus_adapter * adapter, u8 addr, char read_write,
s32 smbus_access_i2c(struct i2c_adapter * adapter, u8 addr, char read_write,
u8 command, int size, union smbus_data * data)
{
/* So we need to generate a series of msgs */

View File

@@ -130,6 +130,8 @@ struct smbus_adapter {
course. */
#define i2c_is_smbus_client(clientptr) \
((clientptr)->adapter->algo->id == ALGO_SMBUS)
#define i2c_is_smbus_adapter(adapptr) \
((adapptr)->algo->id == ALGO_SMBUS)
/* This union is used within smbus_access routines */
union smbus_data {
@@ -157,21 +159,23 @@ extern struct smbus_algorithm smbus_algorithm;
/* This is the very generalized SMBus access routine. You probably do not
want to use this, though; one of the functions below may be much easier,
and probably just as fast. */
extern s32 smbus_access (struct smbus_adapter * adapter, u8 addr,
and probably just as fast.
Note that we use i2c_adapter here, because you do not need a specific
smbus adapter to call this function. */
extern s32 smbus_access (struct i2c_adapter * adapter, u8 addr,
char read_write, u8 command, int size,
union smbus_data * data);
/* Now follow the 'nice' access routines. These also document the calling
conventions of smbus_access. */
extern inline s32 smbus_write_quick(struct smbus_adapter * adapter, u8 addr,
extern inline s32 smbus_write_quick(struct i2c_adapter * adapter, u8 addr,
u8 value)
{
return smbus_access(adapter,addr,value,0,SMBUS_QUICK,NULL);
}
extern inline s32 smbus_read_byte(struct smbus_adapter * adapter,u8 addr)
extern inline s32 smbus_read_byte(struct i2c_adapter * adapter,u8 addr)
{
union smbus_data data;
if (smbus_access(adapter,addr,SMBUS_READ,0,SMBUS_BYTE,&data))
@@ -180,13 +184,13 @@ extern inline s32 smbus_read_byte(struct smbus_adapter * adapter,u8 addr)
return data.byte;
}
extern inline s32 smbus_write_byte(struct smbus_adapter * adapter, u8 addr,
extern inline s32 smbus_write_byte(struct i2c_adapter * adapter, u8 addr,
u8 value)
{
return smbus_access(adapter,addr,SMBUS_WRITE,value, SMBUS_BYTE,NULL);
}
extern inline s32 smbus_read_byte_data(struct smbus_adapter * adapter,
extern inline s32 smbus_read_byte_data(struct i2c_adapter * adapter,
u8 addr, u8 command)
{
union smbus_data data;
@@ -196,7 +200,7 @@ extern inline s32 smbus_read_byte_data(struct smbus_adapter * adapter,
return data.byte;
}
extern inline s32 smbus_write_byte_data(struct smbus_adapter * adapter,
extern inline s32 smbus_write_byte_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u8 value)
{
union smbus_data data;
@@ -204,7 +208,7 @@ extern inline s32 smbus_write_byte_data(struct smbus_adapter * adapter,
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BYTE_DATA,&data);
}
extern inline s32 smbus_read_word_data(struct smbus_adapter * adapter,
extern inline s32 smbus_read_word_data(struct i2c_adapter * adapter,
u8 addr, u8 command)
{
union smbus_data data;
@@ -214,7 +218,7 @@ extern inline s32 smbus_read_word_data(struct smbus_adapter * adapter,
return data.word;
}
extern inline s32 smbus_write_word_data(struct smbus_adapter * adapter,
extern inline s32 smbus_write_word_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u16 value)
{
union smbus_data data;
@@ -222,7 +226,7 @@ extern inline s32 smbus_write_word_data(struct smbus_adapter * adapter,
return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_WORD_DATA,&data);
}
extern inline s32 smbus_process_call(struct smbus_adapter * adapter,
extern inline s32 smbus_process_call(struct i2c_adapter * adapter,
u8 addr, u8 command, u16 value)
{
union smbus_data data;
@@ -234,7 +238,7 @@ extern inline s32 smbus_process_call(struct smbus_adapter * adapter,
}
/* Returns the number of read bytes */
extern inline s32 smbus_read_block_data(struct smbus_adapter * adapter,
extern inline s32 smbus_read_block_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u8 *values)
{
union smbus_data data;
@@ -248,7 +252,7 @@ extern inline s32 smbus_read_block_data(struct smbus_adapter * adapter,
}
}
extern inline int smbus_write_block_data(struct smbus_adapter * adapter,
extern inline int smbus_write_block_data(struct i2c_adapter * adapter,
u8 addr, u8 command, u8 length,
u8 *values)
{