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:
17
TODO
17
TODO
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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) {
|
||||
|
@@ -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) \
|
||||
|
@@ -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) \
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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 */
|
||||
|
@@ -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)
|
||||
|
@@ -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) \
|
||||
|
@@ -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) {
|
||||
|
@@ -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 */
|
||||
|
28
src/smbus.h
28
src/smbus.h
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user