Delete all kernel chip drivers, documentation and references. We are

moving to a user-space-only package, all the drivers are maintained in
the Linux kernel tree itself.

I tried to update the documentation a bit, but there's still a lot to
go. In fact, a complete rewrite seems to be needed.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0@4397 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare committed 2007-05-09 13:00:30 +00:00
1 parent 448c4a70e9
commit 9232f4eb43
136 files changed
+1633 -55767

No files matched your search

-550
View File
@@ -1,550 +0,0 @@
This is a design for version 2 of our smbus and lm_sensors module. This
document is Copyright (c) 1998, 1999 by Frodo Looijaard. You may freely copy and
distribute it, as long as you recognize me as the author, and mark any
changes you make as being your own, and distribute this notice with it.
Document version 1.0, 19981101.
1.1, 19981111.
1.2, 19981118.
1.3, 19981126.
NOTE: THIS IS BY NOW SOMEWHAT OUTDATED. SORRY.
Object oriented approach
========================
The i2c module structs contain callback functions and data fields. In the
i2c module, these structures are only referenced by pointers. This makes
it easy to extend these structs to contain additional information or
callback functions. For those familiar with object oriented languages,
you can see the smbus and isa structures as an object extension of the i2c
structures.
To make this clearer, I will show in an example how this is done. Note
that I have simplified some things here, so this example does not
correspond to an actual struct found in one of the modules.
In the i2c module, you can find a struct somewhat like this:
struct i2c_adapter {
char name[32];
int (*detach_client) (struct i2c_client *);
struct i2c_adapter *next;
}
We have a plain data field (name), a call-back function which needs one
parameter (a pointer to a i2c_client struct), and a data field which is
a pointer to the next adapter.
Now we want to extend this structure. We need another data field,
containing a number of flags. We will call this new structure smbus_adapter.
A few other things change too:
struct smbus_adapter {
char name[32];
int (*detach_client) (struct smbus_client *);
struct smbus_adapter *next;
unsigned int flags;
}
So we copy all existing fields. The next field still points to the next
adapter - but it is now of type smbus_adapter, not i2c_adapter. And the
call-back function takes now a parameter of type pointer to smbus_client.
And there is a new data field, called flags.
Now examine this function definition:
int fully_detach_i2c_client (struct i2c_client * client)
{
res = 0;
struct i2c_adapter *current_adapter = first_adapter; /* a global var. */
while (current_adapter) {
res |= (current_adapter -> detach_client) (client);
current_adapter = current_adapter -> next;
}
return res;
}
This function detaches a client from all adapters. Nice. But now comes the
Big Trick(tm): we can still use this function for smbus_adapters!
int fully_detach_smbus_client (struct smbus_client * client)
{
return fully_detach_i2c_client( (struct i2c_client *) client);
}
All we needed here was a simple typecast. Datapointers remain datapointers,
so this can safely be done. And because we use call-back functions, the
actual function called to detach a client from a single adapter might
be the same, or different, depending on what function was put in
client->detach_client!
It gets even better. The i2c module stores internally all registered
adapters. But it stores pointers to the i2c_adapter struct, not the
structs themselves! So there is an array:
#define I2C_ADAPTER_MAX 32
struct i2c_adapter *adapters[I2C_ADAPTER_MAX];
/* this is an array of pointers to structs, not vice versa! */
So, an element of this array might in fact point to a smbus_adapter, instead
of an i2c_adapter! If you know this for sure, you might use a typecast and
access the additional fields. In the meantime, the i2c internal
administration remains valid.
We have to thank Simon Vogl and Gerd Knorr for the way they implemented
their i2c module. Any other way would have made this approach impossible,
and basing anything upon their module much more difficult.
Limitations
-----------
Extending the adapter and algorithm structures in this way is quite safe.
They are only allocated on places where the code knows that they are
'special'. Extending the driver or client structures depending on a
specific adapter/algorithm type is *very* *dangerous*. A driver/client
module would need to be aware of every special adapter/algorithm in
order to allocate itself! For the ISA bus, it has to be aware of this
anyway, so it is safe to do; on other places, think twice first!
Module overview
===============
All in all, lots of modules will be stacked on each other. Too bad, but
that is the only way to cleanly implement everything. Note that in a
specific situation, only a few modules may need to be loaded. isa.o,
for example, does not depend on smbus.o (in the sense that you can load
sensor.o without loading smbus.o). A specific bus driver, though, will
depend on many of them.
Generally:
isa.o depends on nothing (actually, on i2c.o, to keep the code small)
smbus.o depends on nothing (actually, on i2c.o, to keep the code small)
i2c.o depends on nothing.
A non-i2c SMBus bus driver depends only on smbus.o
A i2c bus driver depends only on i2c.o
A sensor chip driver depends either on isa.o or smbus.o, or both.
A SMBus chip driver depends only on smbus.o
A I2C chip driver depends only on i2c.o
We may need a sensor.o module, to act as a central point for sensor
modules. At this moment, it seems not really necessary, but this may
change.
We will need an enhanced i2c-dev.o module, to add SMBus access to I2C
/dev entries.
isa.o
ISA bus handling.
Encapsulates ISA bus access within the i2c structures.
Unites I2C adapters and the ISA bus.
Defines variables isa_algorithm and isa_adapter.
smbus.o
Main SMBus handling.
Encapsulates SMBus access within the smbus structures.
Unites I2C adapters and SMBus hosts (like the PIIX4).
Emulates SMBus access on pure I2C adapters.
Defines variable smbus_algorithm.
piix4.o
SMBus adapter driver for the PIIX4 SMBus host.
Defines variable piix4_adapter (based on smbus_algorithm).
FOO.o
Adapter driver for FOO SMBus host
Defines variable FOO_adapter (based on smbus_algorithm).
i2c-core.o (From Simon Vogl)
Main i2c handling.
????.o
I2C adapter driver
Implementing a class of I2C busses
A chip driver (typically defined in its own module) can be hooked on all
these levels:
* If it is a sensor chip, it should be hooked to isa.o or smbus.o
* A pure ISA chip should be hooked to isa.o
* A pure SMBus chip should be hooked to smbus.o
* An I2C chip should be hooked to i2c.o
It can be difficult to decide whether a specific chip should be hooked to
smbus.o or i2c.o. A good deciding question is, 'could it be connected to
a PIIX4?'
Module i2c.o
============
This is Simon Vogl's i2c module (this one is different from the i2c module
included in kernels around 2.1.120!).
A driver
--------
struct i2c_driver {
char name[32];
int id;
unsigned int flags;
int (* attach_adapter) (struct i2c_adapter *);
int (* detach_client) (struct i2c_client *);
int (* command) (struct i2c_client *, unsigned int cmd, void *arg);
void (* inc_use) (struct i2c_client *);
void (* dec_use) (struct i2c_client *);
}
A driver tells us how we should handle a specific type of i2c chip. An
instance of such a chip is called a 'client'. An example would be the LM75
module: it would contain only one driver, which tells us how to handle the
LM75; but each detected LM75 would be a separate client (which would be
dynamically allocated).
A description of the above struct:
name: The name of this driver
id: A unique driver identifier
flags: Flags to set certain kinds of behaviour. Most notably, DF_NOTIFY
will notify the driver when a new i2c bus is detected, so it can
try to detect chips on it.
attach_adapter: A call-back function which is called if a new adapter (bus)
is found. This allows us to do our detection stuff on the new adapter,
and register new clients.
detach_client: A call-back function which is called if a specific client
which uses this driver should be disallocated. If a specific sensor module
is removed, for instance, this function would be called for each registered
client.
command: A generic call-back function to communicate in a driver-dependent
way with a specific client. This should only be seldom needed.
inc_use: Can be called to add one to an internal 'use' counter. This can be
used to control when it is safe to remove this module, for example.
A client
--------
struct i2c_client {
char name[32];
int id;
unsigned int flags;
unsigned char addr;
struct i2c_adapter *adapter;
struct i2c_driver *driver;
void *data;
}
A client is a specific sensor chip. Its operation is controlled by a driver
(which describes a type of sensor chip), and it is connected to an adapter
(a bus).
A description of the above struct:
name: The name of this client
id: A unique client id
flags: Flags to set certain kinds of behaviour (not very important)
addr: The client address. 10-bit addresses are a bit of a kludge right now.
adapter: A pointer to the adapter this client is on.
driver: A pointer to the driver this client uses.
data: Additional, client-dependent data
An algorithm
------------
struct i2c_algorithm {
char name[32];
unsigned int id;
int (* master_xfer) (struct i2c_adapter *adap, struct i2c_msg msgs[],
int num);
int (* slave_send) (struct i2c_adapter *,char *, int);
int (* slave_recv) (struct i2c_adapter *,char *, int);
int (* algo_control) (struct i2c_adapter *, unsigned int, unsigned long);
int (* client_register) (struct i2c_client *);
int (* client_unregister) (struct i2c_client *);
}
An algorithm describes how a certain class of i2c busses can be accessed.
A description of the above struct:
name: The name of this algorithm
id: A unique algorithm id
master_xfer: Transfer a bunch of messages through a specific i2c bus.
slave_send: Send a message as if we are a slave device
slave_recv: Receive a message as if we are a slave device
client_register: Register a new client
client_unregister: Unregister a client
An adapter
----------
struct i2c_adapter {
char name[32];
unsigned int id;
struct i2c_algorithm *algo;
void *data;
#ifdef SPINLOCK
spinlock_t lock;
unsigned long lockflags;
#else
struct semaphore lock;
#endif
unsigned int flags;
struct i2c_client *clients[I2C_CLIENT_MAX];
int client_count;
int timeout;
int retries;
}
An adapter is a specific i2c bus. How to access it is defined in the
algorithm associated with it.
A description of the above struct:
name: The name of this adapter
id: A unique adapter id
algo: The algorithm through which this bus must be accessed
data: Adapter specific data
lock, lockflags: To lock out simultaneous adapter access
flags: Modifiers for adapter operation
clients: All currently connected clients
client_count: The number of currently connected clients
timeout, retries: Internal variables (unimportant here).
Access functions
----------------
All these functions are defined extern.
int i2c_master_send(struct i2c_client *,const char *, int);
int i2c_master_recv(struct i2c_client *,char *, int);
int i2c_transfer(struct i2c_adapter *,struct i2c_msg [], int num);
These function respectively send one message to a client, receive one message
from a client, or transmit a bunch of messages. struct i2c_msg contains
an i2c address to communicate with, and can both read from and write to this
address.
int i2c_slave_send(struct i2c_client *, char *, int);
int i2c_slave_recv(struct i2c_client *, char *, int);
Communicate with another master as if the normal master is a common slave
device.
Administration functions
------------------------
int i2c_add_algorithm(struct i2c_algorithm *);
int i2c_del_algorithm(struct i2c_algorithm *);
The i2c_{add,del}_algorithm functions must be called whenever a new module
is inserted with this driver in it, by the module initialization function.
int i2c_add_adapter(struct i2c_adapter *);
int i2c_del_adapter(struct i2c_adapter *);
The i2c_{add,del}_adapter functions must be called if you have detected
a specific bus. It triggers driver->attach_adapter (add, for each driver
present) or driver->detach_client (del, for each registered client on
this adapter).
int i2c_add_driver(struct i2c_driver *);
int i2c_del_driver(struct i2c_driver *);
The i2c_{add,del}_driver functions must be called whenever a new module is
inserted with a chip driver in it, by the module initialization function.
int i2c_attach_client(struct i2c_client *);
int i2c_detach_client(struct i2c_client *);
The i2c_{attach,detach}_client functions must be called if you have detected
a single chip.
Module smbus.o
==============
This module offers support for SMBus operation. An SMBus adapter can either
accept SMBus commands (like the PIIX4), or be in fact an I2C driver. In
the last case, all SMBus commands will be expressed through I2C primitives.
This means that any I2C adapter driver will automatically be a SMBus
driver.
At this point, it should be noted that there can only be one System
Management Bus in a given system (is this really true, by the way?). This
means there must be some way of selecting which of the many possible adapters
is in fact *the* SMBus. For now, I will ignore this problem. Later on,
we can add a hook somewhere in the i2c module to help us decide this.
This module consists in fact of three separate parts: first of all, it extends
all i2c structs to accomodate the new smbus fields. Second, it defines a
new algorithm (smbus_algorithm), that will be used by all non-i2c adapters.
Finally, it implements a new access function that sends or receives SMBus
commands; these are either translated into I2C commands or sent to the
SMBus driver.
A driver, client and algorithm
------------------------------
We will not need to extend i2c_driver, i2c_client or i2c_adapter. This means
that struct smbus_driver is exactly the same as struct i2c_driver, and
struct smbus_client is the same as struct i2c_client, and smbus_adapter is
the same as struct i2c_adapter. We *will* define the smbus_* variants, and
use them within this module, so it should be easy to extend them after all.
Note that at this moment, 10 bit SMBus addresses seem to be only
partially supported by the i2c module. We will ignore this issue for
now.
An adapter
------------
struct smbus_adapter {
char name[32];
unsigned int id;
struct smbus_algorithm *algo;
void *data;
#ifdef SPINLOCK
spinlock_t lock;
unsigned long lockflags;
#else
struct semaphore lock;
#endif
unsigned int flags;
struct smbus_client *clients[I2C_CLIENT_MAX];
int client_count;
int timeout;
int retries;
/* Here ended i2c_adapter */
s32 (* smbus_access) (__u8 addr, char read_write,
__u8 command, int size, union smbus_data * data);
}
A description of the above struct:
smbus_access: A function to access the SMBus. It is only used for non-i2c
smbus adapters.
Access functions
----------------
All these functions are defined extern.
The i2c access function should not be used within SMBus chip drivers, as
they might not be defined (for the PIIX4, for example). Instead, use the
following general access function, or one of the easier functions based
on it:
int smbus_access (struct i2c_adapter *, __u8 addr, char read_write,
__u8 command, int size, union smbus_data * data);
There are specific SMBus registration functions too, like the i2c ones.
They are fully compatiable with each other; just substitute 'smbus' for
'i2c' everywhere in the i2c description.
int i2c_is_smbus_client(struct i2c_client *);
int i2c_is_smbus_adapter(struct i2c_adapter *);
Decide whether this client, or adapter, is (on) a non-I2C SMBus. Usually
not needed, but it is nice anyway to be able to decide this.
Module isa.o
============
This module implements a new algorithm and a specific adapter for the
(single) ISA bus in your computer. This makes writing drivers for chips
that can be both on ISA and SMBus much easier.
Note that this module does *not* in any way depend on smbus.o (previous
versions of this document still assumed it would be build upon it; this
is no longer true).
A driver, adapter or algorithm
------------------------------
We will not need to extend i2c_driver, i2c_adapter or i2c_algorithm. This
means that struct isa_driver is exactly the same as struct i2c_driver,
struct isa_adapter is the same as struct i2c_adapter and struct isa_algorithm
is the same as struct isa_driver. We *will* define the isa_* variants, and
use them within this module, so it should be easy to extend them after all.
A 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;
unsigned int isa_addr;
}
A client is a specific sensor chip. Its operation is controlled by a driver
(which describes a type of sensor chip), and it is connected to an adapter
(a bus, the (single) ISA bus here).
A description of the above struct:
isa_addr: ISA addresses do not fit in the i2c-compatible addr field, so
we needed a new field.
Access functions
----------------
All these functions are defined extern.
In case of the ISA bus, the master_xfer, slave_send and slave_recv hooks
will be NULL, because these functions make no sense. It is regrettably
not easy to create an access abstraction in which both ISA bus access
and SMBus access are united. See below for examples how you can solve
this problem.
The most imporant additional access function:
int i2c_is_isa_client(struct i2c_client *);
int i2c_is_isa_adapter(struct i2c_adapter *);
Decide whether this client, or adapter, is (on) the ISA bus. This is
important, because it determines whether we can use the SMBus access
routines.
As an example, I will here implement our old LM78 access function:
/* The SMBus locks itself, but ISA access must be locked explicitly!
We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
would slow down the LM78 access and should not be necessary.
There are some ugly typecasts here, but the good new is - they should
nowhere else be necessary! */
int lm78_read_value(struct i2c_client *client, u8 reg)
{
int res;
if (i2c_is_isa_client(client)) {
down((struct semaphore *) (client->data));
outb_p(reg,(((struct isa_client *) client)->isa_addr) +
LM78_ADDR_REG_OFFSET);
res = inb_p((((struct isa_client *) client)->isa_addr) +
LM78_DATA_REG_OFFSET);
up((struct semaphore *) (client->data));
return res;
} else
return smbus_read_byte_data(client->adapter,client->addr, reg);
}
+4 -16
View File
@@ -4,36 +4,28 @@ See doc/useful_addresses.html for a link to this article.
There is one big Makefile in the root of this package. It includes many
other files; one for each directory in which source code is found. These
included files are called 'Module.mk'. There is a separate set of Makefiles
in the i2c/ directories; these are Simon Vogl's original Makefiles, and
not referred by the main package Makefile.
included files are called 'Module.mk'.
There are several interesting targets defined through this Makefile:
* all
Create everything in all directories.
* all-i2c, all-src, ...
Create everything in the designated directory.
* install
Install everything from all directories.
* install-i2c, install-src, ...
Install everything in the designated directory.
* uninstall
Uninstall everything.
* clean
Remove anything which can be regenerated from all directories. A call
of 'make clean' (without any other targets) will ignore any .d files;
this is useful when they are out of date (and prevent the calling of
any other target).
* clean-i2c, clean-src, ...
Remove anything which can be regenerated from the designated directory.
* version
Regenerate version.h, using the current date for the date-stamp, and
a user-supplied version number.
* package
Create a .tar.gz file containing everything except the SVN directories.
* src/lm78.o, i2c/i2c-core.o, ...
You can of course also specify one or more targets to make.
The best way to understand the Module.mk subfiles is to examine one of them,
for example src/Module.mk. They are not too difficult to understand.
for example lib/Module.mk. They are not too difficult to understand.
There are several variables which can be set in the main Makefile. You can
also specify them on the command-line; this overrules any definitions
@@ -47,16 +39,12 @@ ones for developers:
only output more information, and never make the code mis-behave.
Several files are generated by Makefiles:
* .d
Dependency files for modules. Automatically generated.
* .rd
Dependency files for executables. Automatically generated.
* .ao
Dependency files for static libraries. Automatically generated.
* .lo
Dependency files for shared libraries. Automatically generated.
* .o
Generated modules
* .ro
Object files for executables. They will be linked together to create
the executable. This extension is used to distinguish them from
-166
View File
@@ -1,166 +0,0 @@
These are the steps you should follow to write a new driver and
submit it to us so that it will be applied cleanly to our package.
See at the bottom for adding new chip support to an existing driver.
Don't be intimidated by the list, it's just here so we don't
forget anything.
We are more than happy to help you with any part of the process.
There are two types of drivers, chip and bus.
Steps which apply to only one type of driver are noted.
These instructions are for 2.4-kernel-compatible drivers.
If you wish to write a driver for 2.6 only, not all of the following
steps apply.
---------------------------------------------------------------------
* Check our "New Drivers" page for status!!
* Contact us.
You are of course free to write your own drivers, but it is smart to
check first nobody else is already working on it, in case the
New Drivers page is out of date.
Tell us it's OK to put your name on the "New Drivers" page.
* Consider subscribing to the mailing list.
* Check out our latest code from SVN.
You should use this as a base for your development.
See instructions on our download page.
* Write the new driver.
If you write a driver for a device that is similar to one we already
support, use the other device driver as a template. If you don't know
which one to use, either ask us or use the following defaults.
For a chip driver, use lm78.c as template. For an SMBus-only adapter,
use i2c-piix4.c. Use i2c-via.c for an I2C-level adapter ('bit banger').
Usually, we make all prefixes start with the driver name. This is not
really necessary, as these symbols will not be exported anyway. But by
doing this, you are sure you do not shadow any global kernel names.
* A quick note about conversions. The conversions which are specified
in the sensor chip datasheet and which *cannot* vary from one board to
the next are performed by the driver. If other conversions are
necessary, they are performed in user-space.
* Meet Kernel coding standards.
See Documentation/CodingStyle in the kernel source.
Be sure and use 8 column tabs.
Also, please do not use // comments.
Also, please do not go past column 80.
Also, please use C99 struct initializers {.foo = blat}
Please do this _before_ you check in your driver.
* Meet /proc naming standards in the ctl_table (for chip drivers only).
See doc/developers/proc for information. Please do not deviate from
this without discussion.
* Add the driver to the Module.mk (the makefile).
Usually, you can just add it to KERNEL{CHIPS,DRIVERS}TARGETS in the
Module.mk file in the directory itself.
* Make sure it compiles cleanly.
Check compilation with 'make DEBUG=1' if you use debugging
information. Remember, things put between #ifdef DEBUG #endif may never
stop the driver from functioning; they should just output additional
information.
* Check for external symbols.
'nm --extern --defined' should only output symbols starting with __module,
cleanup_module, init_module and some kernel versioning symbols. Mark all
other symbols as static in your source file.
* Test the module.
Test with a recent 2.4 kernel.
For bus drivers, use i2cdetect and i2cdump. For i2cdump, test all supported
bus access modes (see i2cdump man page).
For chip drivers, cat all files in applicable /proc or /sys directory
and check for problems. Write all supported settings.
Check ALARM indications.
* Add detection information to prog/detect/sensors-detect.
This is a perl script that automatically detects what chips and adapters
are present. Contact us if you need help.
* Add chip information to lib/chips.{c,h} (for chip drivers only).
Until you have done this, the chip will be invisible for user-level
programs which use libsensors. Use standard names in lib/chips.c;
see also the comments in etc/sensors.conf.eg for help.
Contact us if you need more assistance.
* Be sure that SYSCTL and ALARM definitions in the driver are bracketed
by the special comments so that the kernel/include/sensors.h
file, which is generated automatically, contains your definitions.
(for chip drivers only)
* Add a procedure to prog/sensors/chips.[ch] (for chip drivers only).
This is a function specific for your driver that
makes the included 'sensors' program pretty-print your chip information.
* Add an line for the procedure in the matches[] table in
prog/sensors/main.c (for chip drivers only).
This tells sensors to call your new procedure when the chip name matches.
* Add entries to etc/sensors.conf.eg (for chip drivers only).
If needed, you can set defaults here.
* Test the userspace apps (sensors-detect and sensors).
Test setting limits with sensors -s.
* Add the name of the device to the README file.
* Add your name to the CONTRIBUTORS file.
* Add entries to the CHANGES file. Please keep in alphabetical order.
* Write a doc/chips/xxx or doc/busses/xxx file.
* Add entry to doc/chips/SUMMARY (for chip drivers only).
* Clearly specify licensing and copyright.
Make sure the GPL boilerplate and your name
(or if applicable your company's name) is at the top of the
new driver so we know you are giving it to us under the GPL.
* Submit the changes to us.
Do a 'svn update' to get in sync (things will have changed since
you started), then submit the changes to us as a patch against SVN.
* If you want to have your driver integrated to Linux 2.6, you have to
port your driver to the new sysfs interface. Once done and preferably
after testing, submit a patch to our mailing list: see
http://www.lm-sensors.org/wiki/AuthorsAndContributors
Make sure to check the current status for your driver first:
http://www.lm-sensors.org/wiki/Kernel2.6
http://www.lm-sensors.org/wiki/Devices
---------------------------------------------------------------------
Checklist for us to do on the webpage:
* Add entry to 'supported drivers' page
* Update entry on 'new drivers' page
---------------------------------------------------------------------
Checklist for _adding_ support for a chip to an _existing_ driver:
* Make the changes to the driver itself.
* Add detection information to prog/detect/sensors-detect.
* Add a strncmp() call for the new prefix in prog/sensors/main.c
(chip drivers only).
* Add entries for the new prefix to etc/sensors.conf.eg (chip drivers only).
* Update doc/[chips,busses]/xxx file
* Update doc/chips/SUMMARY file (chip drivers only)
* Update list in README
* Submit the changes as a patch or check them in
* Update entry on 'new drivers' page
-145
View File
@@ -1,145 +0,0 @@
Naming and data format standards under /proc
--------------------------------------------
The libsensors library offers an interface to the raw sensors data
through the sysctl interface. See the doc/developers/sysctl
and the libsensors source for further information.
An alternative method that some programs use is to access the /proc
files directly. This document briefly describes the standards that
the drivers follow, so that an application program can scan for
entries and access this data in a simple and consistent way.
Note that not all chip drivers adhere to this standard.
We will attempt to migrate older drivers to this standard,
and ensure that new drivers follow this standard wherever possible.
If you are developing a userspace application please send us
feedback on this standard.
Note that motherboards vary widely in the connections to sensor chips.
There is no standard that ensures, for example, that the second
temperature sensor is connected to the CPU, or that the second
fan is on the CPU. Therefore, programs must provide a facility
for the user to label or bind /proc entries for display.
Sensor chips often have unused inputs that should be ignored
by user programs.
Each chip gets its own directory under /proc/sys/dev/sensors.
The format is either chip-i2c-bus-hexaddress or chip-isa-hexaddress.
(Exception - chip lm78-j has a '-' in it - should this be changed??)
New dummy drivers may present chips as chip-busname-hexaddress.
All /proc values are integers or floating point numbers.
There is no facility in the lm_sensors package for drivers
to output general strings via /proc. This facility may be added
in the future.
Alarms are direct indications read from the chips. The drivers do NOT make
comparisons of readings to thresholds. This allows violations
between readings to be caught and alarmed. The exact definition of
an alarm (for example, whether a threshold must be met or must be
exceeded to cause an alarm) is chip-dependent.
Guidelines for new entries:
- If there are multiple values, some r/w and some r/o,
put the r/w ones first.
- Additional non-standard values should be after the standard values.
-------------------------------------------------------------------------
/proc entries are as follows:
Entry Values Function
----- ------ --------
alarms 1 Alarm bitmask.
Read only.
Integer representation of one to four bytes.
A '1' bit means an alarm.
Chips should be programmed for 'comparator' mode so that
the alarm will 'come back' after you read the register
if it is still valid.
Generally a direct representation of a chip's internal
alarm registers; there is no standard for the position
of individual bits.
Bits are defined in kernel/include/sensors.h.
beep 2 Beep/interrupt enable and bitmask.
The first value is 0 or 1 to globally disable
or enable the beeps.
The second value is a bitmask, with the
same format as 'alarms' with same bit locations.
curr[1-n] 3 Current max, min or hysteresis, and input value.
Floating point values XX.X or XX.XX in Amps.
The second value is preferably a hysteresis value,
reported as a absolute current, NOT a delta from
the max value.
First two values are read/write and third is read only.
fan[1-3] 2 Fan minimum and input value.
Two integers indicating RPM.
First value is read/write and second is read only.
fan_div 3 Fan divisor.
Integers in powers of two (1,2,4,8,16,32,64,128).
Some chips only support values 1,2,4,8.
Entries correspond to the fans[1-3].
See doc/fan-divisors for details.
in[0-8] 3 Voltage min, max, and input value.
Floating point values X.XX in volts from 0 to 4.01 volts.
Actual voltage depends on the scaling resistors on the
motherboard, as recommended in the chip datasheet.
This varies by chip and by motherboard.
Because of this variation, values are generally NOT scaled
by the chip driver, and must be done by the application.
However, some drivers (notably lm87 and via686a)
do scale, with various degrees of success.
These drivers will output the actual voltage.
First two values are read/write and third is read only.
Typical usage:
in0 CPU #1 voltage (not scaled)
in1 CPU #1 voltage (not scaled)
in2 3.3V nominal (not scaled)
in3 5.0V nominal (scaled)
in4 12.0V nominal (scaled)
in5 -12.0V nominal (scaled)
in6 -5.0V nominal (scaled)
in7 varies
in8 varies
pwm[1-3] 1-2 Pulse width modulation fan control.
Integer 0 - 255, read/write.
255 is max or 100%.
Corresponds to the fans 1-3.
Second value, if present, is an enable (0 or 1)
sensor[1-3] 1 Sensor type selection.
Integers 1,2,3, or thermistor Beta value (3435); read/write.
temp,
temp[1-4] 3 Temperature max, min or hysteresis, and input value.
Floating point values XXX.X or XXX.XX in degrees Celsius.
'temp' is used if there is only one temperature sensor on the
chip; for multiple temps. start with 'temp1'.
Temp1 is generally the sensor inside the chip itself,
generally reported as "motherboard temperature".
Temp2 to temp4 are generally sensors external to the chip
itself, for example the thermal diode inside the CPU or a
termistor nearby. The second value is preferably a hysteresis
value, reported as a absolute temperature, NOT a delta from
the max value.
First two values are read/write and third is read only.
vid 1 CPU core voltage.
Read only.
Floating point X.XX or X.XXX corresponding to CPU core voltage
as told to the sensor chip. Not always correct.
vrm 1 Voltage Regulator Module version number.
"Floating point" X.X. Default 8.2.
Affects the way the driver calculates the core voltage from
the vid pins. See doc/vid for details.
+5 -7
View File
@@ -2,18 +2,16 @@ CHECKLIST FOR NEW RELEASES
==========================
Release steps:
- Check out i2c and lm-sensors
- Check out lm-sensors
- Update if necessary, the version number of libsensors
(edit lib/Module.mk and change LIBMAINVER and/or LIBMINORVER)
Remember: update main number when interface changes, minor if new
functionality is added, and patch if only bugs are fixed.
`svn diff -r Vx-y-z lib' is your friend.
- Update both CHANGES files (add the release date)
- Verify i2c dependency instructions in README, QUICKSTART, and INSTALL,
update if necessary
- Update the CHANGES file (add the release date)
- Update lm_sensors.lsm and send it to the LSM by mailing it to
lsm@execpc.com with the subject `add' (no quotes).
- Update lm_sensors2/version.h and i2c/kernel/i2c.h
- Update version.h
- Commit
- Tag the release using SVN:
svn copy http://lm-sensors.org/svn/lm-sensors/trunk \
@@ -21,9 +19,9 @@ Release steps:
-m "Create tag 'V2-x-x'."
- Remove empty directories (e.g. rmdir `find . -type d`)
- Remove 'SVN' related files/directories (e.g. rm -fR `find . -name .svn`)
- Rename i2c and lm_sensors2 to i2c-#.#.# and lm_sensors-#.#.#
- Rename lm_sensors2 to lm_sensors-#.#.#
- Tar it up and post it (sign it)
- Make sure the file permissions on both the archives and the signatures
- Make sure the file permissions on both the archive and the signature
are correct (664)
After release, remember to:
-16
View File
@@ -1,16 +0,0 @@
You can access everything under /proc/sys through the sysctl interface. This
is mostly useful for C programs, which can use the sysctl function. Try
'man 2 sysctl' for more information.
As each chip gets its own directory under /proc/sys/dev/sensors, you must
somehow know the sysctl id of these directories to access the sensor data.
This is done through the file /proc/sys/dev/sensors/chips (see sensors.h
for the corresponding SYSCTL ids). You can only read this file; it
returns an array of struct sensors_chips_data, as defined in sensors.h.
Each chip will have its own entry here, with both its sysctl id and
the corresponding /proc name.
Generally, it is a better idea to use the new libsensors to access this
data. If you feel you need more than the library offers, please mail us,
so we can either add the new functionality to the library, or explain how
you can work around it.