Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
This commit is contained in:
commit
ea0daab4ae
12
CREDITS
12
CREDITS
|
@ -1880,6 +1880,13 @@ S: Schlehenweg 9
|
||||||
S: D-91080 Uttenreuth
|
S: D-91080 Uttenreuth
|
||||||
S: Germany
|
S: Germany
|
||||||
|
|
||||||
|
N: Jaya Kumar
|
||||||
|
E: jayalk@intworks.biz
|
||||||
|
W: http://www.intworks.biz
|
||||||
|
D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
|
||||||
|
S: Gurgaon, India
|
||||||
|
S: Kuala Lumpur, Malaysia
|
||||||
|
|
||||||
N: Gabor Kuti
|
N: Gabor Kuti
|
||||||
M: seasons@falcon.sch.bme.hu
|
M: seasons@falcon.sch.bme.hu
|
||||||
M: seasons@makosteszta.sote.hu
|
M: seasons@makosteszta.sote.hu
|
||||||
|
@ -2373,9 +2380,10 @@ E: tmolina@cablespeed.com
|
||||||
D: bug fixes, documentation, minor hackery
|
D: bug fixes, documentation, minor hackery
|
||||||
|
|
||||||
N: James Morris
|
N: James Morris
|
||||||
E: jmorris@intercode.com.au
|
E: jmorris@redhat.com
|
||||||
W: http://www.intercode.com.au/jmorris/
|
W: http://www.intercode.com.au/jmorris/
|
||||||
D: Netfilter, Linux Security Modules (LSM).
|
D: Netfilter, Linux Security Modules (LSM), SELinux, IPSec,
|
||||||
|
D: Crypto API, general networking, miscellaneous.
|
||||||
S: PO Box 707
|
S: PO Box 707
|
||||||
S: Spit Junction NSW 2088
|
S: Spit Junction NSW 2088
|
||||||
S: Australia
|
S: Australia
|
||||||
|
|
|
@ -338,7 +338,6 @@ X!Earch/i386/kernel/mca.c
|
||||||
X!Iinclude/linux/device.h
|
X!Iinclude/linux/device.h
|
||||||
-->
|
-->
|
||||||
!Edrivers/base/driver.c
|
!Edrivers/base/driver.c
|
||||||
!Edrivers/base/class_simple.c
|
|
||||||
!Edrivers/base/core.c
|
!Edrivers/base/core.c
|
||||||
!Edrivers/base/firmware_class.c
|
!Edrivers/base/firmware_class.c
|
||||||
!Edrivers/base/transport_class.c
|
!Edrivers/base/transport_class.c
|
||||||
|
|
|
@ -76,6 +76,14 @@ driver_data: Driver-specific data.
|
||||||
|
|
||||||
platform_data: Platform data specific to the device.
|
platform_data: Platform data specific to the device.
|
||||||
|
|
||||||
|
Example: for devices on custom boards, as typical of embedded
|
||||||
|
and SOC based hardware, Linux often uses platform_data to point
|
||||||
|
to board-specific structures describing devices and how they
|
||||||
|
are wired. That can include what ports are available, chip
|
||||||
|
variants, which GPIO pins act in what additional roles, and so
|
||||||
|
on. This shrinks the "Board Support Packages" (BSPs) and
|
||||||
|
minimizes board-specific #ifdefs in drivers.
|
||||||
|
|
||||||
current_state: Current power state of the device.
|
current_state: Current power state of the device.
|
||||||
|
|
||||||
saved_state: Pointer to saved state of the device. This is usable by
|
saved_state: Pointer to saved state of the device. This is usable by
|
||||||
|
|
|
@ -5,21 +5,17 @@ struct device_driver {
|
||||||
char * name;
|
char * name;
|
||||||
struct bus_type * bus;
|
struct bus_type * bus;
|
||||||
|
|
||||||
rwlock_t lock;
|
struct completion unloaded;
|
||||||
atomic_t refcount;
|
struct kobject kobj;
|
||||||
|
|
||||||
list_t bus_list;
|
|
||||||
list_t devices;
|
list_t devices;
|
||||||
|
|
||||||
struct driver_dir_entry dir;
|
struct module *owner;
|
||||||
|
|
||||||
int (*probe) (struct device * dev);
|
int (*probe) (struct device * dev);
|
||||||
int (*remove) (struct device * dev);
|
int (*remove) (struct device * dev);
|
||||||
|
|
||||||
int (*suspend) (struct device * dev, pm_message_t state, u32 level);
|
int (*suspend) (struct device * dev, pm_message_t state, u32 level);
|
||||||
int (*resume) (struct device * dev, u32 level);
|
int (*resume) (struct device * dev, u32 level);
|
||||||
|
|
||||||
void (*release) (struct device_driver * drv);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +47,6 @@ being converted completely to the new model.
|
||||||
static struct device_driver eepro100_driver = {
|
static struct device_driver eepro100_driver = {
|
||||||
.name = "eepro100",
|
.name = "eepro100",
|
||||||
.bus = &pci_bus_type,
|
.bus = &pci_bus_type,
|
||||||
.devclass = ðernet_devclass, /* when it's implemented */
|
|
||||||
|
|
||||||
.probe = eepro100_probe,
|
.probe = eepro100_probe,
|
||||||
.remove = eepro100_remove,
|
.remove = eepro100_remove,
|
||||||
|
@ -85,7 +80,6 @@ static struct pci_driver eepro100_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "eepro100",
|
.name = "eepro100",
|
||||||
.bus = &pci_bus_type,
|
.bus = &pci_bus_type,
|
||||||
.devclass = ðernet_devclass, /* when it's implemented */
|
|
||||||
.probe = eepro100_probe,
|
.probe = eepro100_probe,
|
||||||
.remove = eepro100_remove,
|
.remove = eepro100_remove,
|
||||||
.suspend = eepro100_suspend,
|
.suspend = eepro100_suspend,
|
||||||
|
@ -166,27 +160,32 @@ Callbacks
|
||||||
|
|
||||||
int (*probe) (struct device * dev);
|
int (*probe) (struct device * dev);
|
||||||
|
|
||||||
probe is called to verify the existence of a certain type of
|
The probe() entry is called in task context, with the bus's rwsem locked
|
||||||
hardware. This is called during the driver binding process, after the
|
and the driver partially bound to the device. Drivers commonly use
|
||||||
bus has verified that the device ID of a device matches one of the
|
container_of() to convert "dev" to a bus-specific type, both in probe()
|
||||||
device IDs supported by the driver.
|
and other routines. That type often provides device resource data, such
|
||||||
|
as pci_dev.resource[] or platform_device.resources, which is used in
|
||||||
|
addition to dev->platform_data to initialize the driver.
|
||||||
|
|
||||||
This callback only verifies that there actually is supported hardware
|
This callback holds the driver-specific logic to bind the driver to a
|
||||||
present. It may allocate a driver-specific structure, but it should
|
given device. That includes verifying that the device is present, that
|
||||||
not do any initialization of the hardware itself. The device-specific
|
it's a version the driver can handle, that driver data structures can
|
||||||
structure may be stored in the device's driver_data field.
|
be allocated and initialized, and that any hardware can be initialized.
|
||||||
|
Drivers often store a pointer to their state with dev_set_drvdata().
|
||||||
|
When the driver has successfully bound itself to that device, then probe()
|
||||||
|
returns zero and the driver model code will finish its part of binding
|
||||||
|
the driver to that device.
|
||||||
|
|
||||||
int (*init) (struct device * dev);
|
A driver's probe() may return a negative errno value to indicate that
|
||||||
|
the driver did not bind to this device, in which case it should have
|
||||||
init is called during the binding stage. It is called after probe has
|
released all reasources it allocated.
|
||||||
successfully returned and the device has been registered with its
|
|
||||||
class. It is responsible for initializing the hardware.
|
|
||||||
|
|
||||||
int (*remove) (struct device * dev);
|
int (*remove) (struct device * dev);
|
||||||
|
|
||||||
remove is called to dissociate a driver with a device. This may be
|
remove is called to unbind a driver from a device. This may be
|
||||||
called if a device is physically removed from the system, if the
|
called if a device is physically removed from the system, if the
|
||||||
driver module is being unloaded, or during a reboot sequence.
|
driver module is being unloaded, during a reboot sequence, or
|
||||||
|
in other cases.
|
||||||
|
|
||||||
It is up to the driver to determine if the device is present or
|
It is up to the driver to determine if the device is present or
|
||||||
not. It should free any resources allocated specifically for the
|
not. It should free any resources allocated specifically for the
|
||||||
|
|
135
Documentation/fb/intelfb.txt
Normal file
135
Documentation/fb/intelfb.txt
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
A. Introduction
|
||||||
|
This is a framebuffer driver for various Intel 810/815 compatible
|
||||||
|
graphics devices. These would include:
|
||||||
|
|
||||||
|
Intel 830M
|
||||||
|
Intel 810E845G
|
||||||
|
Intel 852GM
|
||||||
|
Intel 855GM
|
||||||
|
Intel 865G
|
||||||
|
Intel 915G
|
||||||
|
|
||||||
|
B. List of available options
|
||||||
|
|
||||||
|
a. "video=intelfb"
|
||||||
|
enables the intelfb driver
|
||||||
|
|
||||||
|
Recommendation: required
|
||||||
|
|
||||||
|
b. "mode=<xres>x<yres>[-<bpp>][@<refresh>]"
|
||||||
|
select mode
|
||||||
|
|
||||||
|
Recommendation: user preference
|
||||||
|
(default = 1024x768-32@70)
|
||||||
|
|
||||||
|
c. "vram=<value>"
|
||||||
|
select amount of system RAM in MB to allocate for the video memory
|
||||||
|
if not enough RAM was already allocated by the BIOS.
|
||||||
|
|
||||||
|
Recommendation: 1 - 4 MB.
|
||||||
|
(default = 4 MB)
|
||||||
|
|
||||||
|
d. "voffset=<value>"
|
||||||
|
select at what offset in MB of the logical memory to allocate the
|
||||||
|
framebuffer memory. The intent is to avoid the memory blocks
|
||||||
|
used by standard graphics applications (XFree86). Depending on your
|
||||||
|
usage, adjust the value up or down, (0 for maximum usage, 63/127 MB
|
||||||
|
for the least amount). Note, an arbitrary setting may conflict
|
||||||
|
with XFree86.
|
||||||
|
|
||||||
|
Recommendation: do not set
|
||||||
|
(default = 48 MB)
|
||||||
|
|
||||||
|
e. "accel"
|
||||||
|
enable text acceleration. This can be enabled/reenabled anytime
|
||||||
|
by using 'fbset -accel true/false'.
|
||||||
|
|
||||||
|
Recommendation: enable
|
||||||
|
(default = set)
|
||||||
|
|
||||||
|
f. "hwcursor"
|
||||||
|
enable cursor acceleration.
|
||||||
|
|
||||||
|
Recommendation: enable
|
||||||
|
(default = set)
|
||||||
|
|
||||||
|
g. "mtrr"
|
||||||
|
enable MTRR. This allows data transfers to the framebuffer memory
|
||||||
|
to occur in bursts which can significantly increase performance.
|
||||||
|
Not very helpful with the intel chips because of 'shared memory'.
|
||||||
|
|
||||||
|
Recommendation: set
|
||||||
|
(default = set)
|
||||||
|
|
||||||
|
h. "fixed"
|
||||||
|
disable mode switching.
|
||||||
|
|
||||||
|
Recommendation: do not set
|
||||||
|
(default = not set)
|
||||||
|
|
||||||
|
The binary parameters can be unset with a "no" prefix, example "noaccel".
|
||||||
|
The default parameter (not named) is the mode.
|
||||||
|
|
||||||
|
C. Kernel booting
|
||||||
|
|
||||||
|
Separate each option/option-pair by commas (,) and the option from its value
|
||||||
|
with an equals sign (=) as in the following:
|
||||||
|
|
||||||
|
video=i810fb:option1,option2=value2
|
||||||
|
|
||||||
|
Sample Usage
|
||||||
|
------------
|
||||||
|
|
||||||
|
In /etc/lilo.conf, add the line:
|
||||||
|
|
||||||
|
append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8"
|
||||||
|
|
||||||
|
This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The
|
||||||
|
framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor
|
||||||
|
will be enabled.
|
||||||
|
|
||||||
|
D. Module options
|
||||||
|
|
||||||
|
The module parameters are essentially similar to the kernel
|
||||||
|
parameters. The main difference is that you need to include a Boolean value
|
||||||
|
(1 for TRUE, and 0 for FALSE) for those options which don't need a value.
|
||||||
|
|
||||||
|
Example, to enable MTRR, include "mtrr=1".
|
||||||
|
|
||||||
|
Sample Usage
|
||||||
|
------------
|
||||||
|
|
||||||
|
Using the same setup as described above, load the module like this:
|
||||||
|
|
||||||
|
modprobe intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1
|
||||||
|
|
||||||
|
Or just add the following to /etc/modprobe.conf
|
||||||
|
|
||||||
|
options intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1
|
||||||
|
|
||||||
|
and just do a
|
||||||
|
|
||||||
|
modprobe intelfb
|
||||||
|
|
||||||
|
|
||||||
|
E. Acknowledgment:
|
||||||
|
|
||||||
|
1. Geert Uytterhoeven - his excellent howto and the virtual
|
||||||
|
framebuffer driver code made this possible.
|
||||||
|
|
||||||
|
2. Jeff Hartmann for his agpgart code.
|
||||||
|
|
||||||
|
3. David Dawes for his original kernel 2.4 code.
|
||||||
|
|
||||||
|
4. The X developers. Insights were provided just by reading the
|
||||||
|
XFree86 source code.
|
||||||
|
|
||||||
|
5. Antonino A. Daplas for his inspiring i810fb driver.
|
||||||
|
|
||||||
|
6. Andrew Morton for his kernel patches maintenance.
|
||||||
|
|
||||||
|
###########################
|
||||||
|
Sylvain
|
|
@ -83,3 +83,13 @@ Why: Deprecated in favour of the new ioctl-based rawiso interface, which is
|
||||||
more efficient. You should really be using libraw1394 for raw1394
|
more efficient. You should really be using libraw1394 for raw1394
|
||||||
access anyway.
|
access anyway.
|
||||||
Who: Jody McIntyre <scjody@steamballoon.com>
|
Who: Jody McIntyre <scjody@steamballoon.com>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
|
||||||
|
When: November 2005
|
||||||
|
Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
|
||||||
|
Why: Match the other drivers' name for the same function, duplicate names
|
||||||
|
will be available until removal of old names.
|
||||||
|
Who: Grant Coady <gcoady@gmail.com>
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,11 @@ Mount options unique to the isofs filesystem.
|
||||||
mode=xxx Sets the permissions on files to xxx
|
mode=xxx Sets the permissions on files to xxx
|
||||||
nojoliet Ignore Joliet extensions if they are present.
|
nojoliet Ignore Joliet extensions if they are present.
|
||||||
norock Ignore Rock Ridge extensions if they are present.
|
norock Ignore Rock Ridge extensions if they are present.
|
||||||
unhide Show hidden files.
|
hide Completely strip hidden files from the file system.
|
||||||
|
showassoc Show files marked with the 'associated' bit
|
||||||
|
unhide Deprecated; showing hidden files is now default;
|
||||||
|
If given, it is a synonym for 'showassoc' which will
|
||||||
|
recreate previous unhide behavior
|
||||||
session=x Select number of session on multisession CD
|
session=x Select number of session on multisession CD
|
||||||
sbsector=xxx Session begins from sector xxx
|
sbsector=xxx Session begins from sector xxx
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,7 @@ Other notes:
|
||||||
|
|
||||||
A very simple (and naive) implementation of a device attribute is:
|
A very simple (and naive) implementation of a device attribute is:
|
||||||
|
|
||||||
static ssize_t show_name(struct device * dev, char * buf)
|
static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
return sprintf(buf,"%s\n",dev->name);
|
return sprintf(buf,"%s\n",dev->name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,8 +71,8 @@ can be changed on remount. The size parameter also accepts a suffix %
|
||||||
to limit this tmpfs instance to that percentage of your physical RAM:
|
to limit this tmpfs instance to that percentage of your physical RAM:
|
||||||
the default, when neither size nor nr_blocks is specified, is size=50%
|
the default, when neither size nor nr_blocks is specified, is size=50%
|
||||||
|
|
||||||
If both nr_blocks (or size) and nr_inodes are set to 0, neither blocks
|
If nr_blocks=0 (or size=0), blocks will not be limited in that instance;
|
||||||
nor inodes will be limited in that instance. It is generally unwise to
|
if nr_inodes=0, inodes will not be limited. It is generally unwise to
|
||||||
mount with such options, since it allows any user with write access to
|
mount with such options, since it allows any user with write access to
|
||||||
use up all the memory on the machine; but enhances the scalability of
|
use up all the memory on the machine; but enhances the scalability of
|
||||||
that instance in a system with many cpus making intensive use of it.
|
that instance in a system with many cpus making intensive use of it.
|
||||||
|
@ -97,4 +97,4 @@ RAM/SWAP in 10240 inodes and it is only accessible by root.
|
||||||
Author:
|
Author:
|
||||||
Christoph Rohland <cr@sap.com>, 1.12.01
|
Christoph Rohland <cr@sap.com>, 1.12.01
|
||||||
Updated:
|
Updated:
|
||||||
Hugh Dickins <hugh@veritas.com>, 01 September 2004
|
Hugh Dickins <hugh@veritas.com>, 13 March 2005
|
||||||
|
|
|
@ -42,7 +42,7 @@ I suspect that this driver could be made to work for the following SiS
|
||||||
chipsets as well: 635, and 635T. If anyone owns a board with those chips
|
chipsets as well: 635, and 635T. If anyone owns a board with those chips
|
||||||
AND is willing to risk crashing & burning an otherwise well-behaved kernel
|
AND is willing to risk crashing & burning an otherwise well-behaved kernel
|
||||||
in the name of progress... please contact me at <mhoffman@lightlink.com> or
|
in the name of progress... please contact me at <mhoffman@lightlink.com> or
|
||||||
via the project's mailing list: <sensors@stimpy.netroedge.com>. Please
|
via the project's mailing list: <lm-sensors@lm-sensors.org>. Please
|
||||||
send bug reports and/or success stories as well.
|
send bug reports and/or success stories as well.
|
||||||
|
|
||||||
|
|
||||||
|
|
111
Documentation/i2c/chips/adm1021
Normal file
111
Documentation/i2c/chips/adm1021
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
Kernel driver adm1021
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Analog Devices ADM1021
|
||||||
|
Prefix: 'adm1021'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
* Analog Devices ADM1021A/ADM1023
|
||||||
|
Prefix: 'adm1023'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
* Genesys Logic GL523SM
|
||||||
|
Prefix: 'gl523sm'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet:
|
||||||
|
* Intel Xeon Processor
|
||||||
|
Prefix: - any other - may require 'force_adm1021' parameter
|
||||||
|
Addresses scanned: none
|
||||||
|
Datasheet: Publicly available at Intel website
|
||||||
|
* Maxim MAX1617
|
||||||
|
Prefix: 'max1617'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the Maxim website
|
||||||
|
* Maxim MAX1617A
|
||||||
|
Prefix: 'max1617a'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the Maxim website
|
||||||
|
* National Semiconductor LM84
|
||||||
|
Prefix: 'lm84'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
* Philips NE1617
|
||||||
|
Prefix: 'max1617' (probably detected as a max1617)
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the Philips website
|
||||||
|
* Philips NE1617A
|
||||||
|
Prefix: 'max1617' (probably detected as a max1617)
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the Philips website
|
||||||
|
* TI THMC10
|
||||||
|
Prefix: 'thmc10'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the TI website
|
||||||
|
* Onsemi MC1066
|
||||||
|
Prefix: 'mc1066'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the Onsemi website
|
||||||
|
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* read_only: int
|
||||||
|
Don't set any values, read only mode
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The chips supported by this driver are very similar. The Maxim MAX1617 is
|
||||||
|
the oldest; it has the problem that it is not very well detectable. The
|
||||||
|
MAX1617A solves that. The ADM1021 is a straight clone of the MAX1617A.
|
||||||
|
Ditto for the THMC10. From here on, we will refer to all these chips as
|
||||||
|
ADM1021-clones.
|
||||||
|
|
||||||
|
The ADM1021 and MAX1617A reports a die code, which is a sort of revision
|
||||||
|
code. This can help us pinpoint problems; it is not very useful
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
ADM1021-clones implement two temperature sensors. One of them is internal,
|
||||||
|
and measures the temperature of the chip itself; the other is external and
|
||||||
|
is realised in the form of a transistor-like device. A special alarm
|
||||||
|
indicates whether the remote sensor is connected.
|
||||||
|
|
||||||
|
Each sensor has its own low and high limits. When they are crossed, the
|
||||||
|
corresponding alarm is set and remains on as long as the temperature stays
|
||||||
|
out of range. Temperatures are measured in degrees Celsius. Measurements
|
||||||
|
are possible between -65 and +127 degrees, with a resolution of one degree.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may already
|
||||||
|
have disappeared!
|
||||||
|
|
||||||
|
This driver only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values. It is possible to make
|
||||||
|
ADM1021-clones do faster measurements, but there is really no good reason
|
||||||
|
for that.
|
||||||
|
|
||||||
|
Xeon support
|
||||||
|
------------
|
||||||
|
|
||||||
|
Some Xeon processors have real max1617, adm1021, or compatible chips
|
||||||
|
within them, with two temperature sensors.
|
||||||
|
|
||||||
|
Other Xeons have chips with only one sensor.
|
||||||
|
|
||||||
|
If you have a Xeon, and the adm1021 module loads, and both temperatures
|
||||||
|
appear valid, then things are good.
|
||||||
|
|
||||||
|
If the adm1021 module doesn't load, you should try this:
|
||||||
|
modprobe adm1021 force_adm1021=BUS,ADDRESS
|
||||||
|
ADDRESS can only be 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e.
|
||||||
|
|
||||||
|
If you have dual Xeons you may have appear to have two separate
|
||||||
|
adm1021-compatible chips, or two single-temperature sensors, at distinct
|
||||||
|
addresses.
|
51
Documentation/i2c/chips/adm1025
Normal file
51
Documentation/i2c/chips/adm1025
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
Kernel driver adm1025
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Analog Devices ADM1025, ADM1025A
|
||||||
|
Prefix: 'adm1025'
|
||||||
|
Addresses scanned: I2C 0x2c - 0x2e
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
* Philips NE1619
|
||||||
|
Prefix: 'ne1619'
|
||||||
|
Addresses scanned: I2C 0x2c - 0x2d
|
||||||
|
Datasheet: Publicly available at the Philips website
|
||||||
|
|
||||||
|
The NE1619 presents some differences with the original ADM1025:
|
||||||
|
* Only two possible addresses (0x2c - 0x2d).
|
||||||
|
* No temperature offset register, but we don't use it anyway.
|
||||||
|
* No INT mode for pin 16. We don't play with it anyway.
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Chen-Yuan Wu <gwu@esoft.com>,
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
(This is from Analog Devices.) The ADM1025 is a complete system hardware
|
||||||
|
monitor for microprocessor-based systems, providing measurement and limit
|
||||||
|
comparison of various system parameters. Five voltage measurement inputs
|
||||||
|
are provided, for monitoring +2.5V, +3.3V, +5V and +12V power supplies and
|
||||||
|
the processor core voltage. The ADM1025 can monitor a sixth power-supply
|
||||||
|
voltage by measuring its own VCC. One input (two pins) is dedicated to a
|
||||||
|
remote temperature-sensing diode and an on-chip temperature sensor allows
|
||||||
|
ambient temperature to be monitored.
|
||||||
|
|
||||||
|
One specificity of this chip is that the pin 11 can be hardwired in two
|
||||||
|
different manners. It can act as the +12V power-supply voltage analog
|
||||||
|
input, or as the a fifth digital entry for the VID reading (bit 4). It's
|
||||||
|
kind of strange since both are useful, and the reason for designing the
|
||||||
|
chip that way is obscure at least to me. The bit 5 of the configuration
|
||||||
|
register can be used to define how the chip is hardwired. Please note that
|
||||||
|
it is not a choice you have to make as the user. The choice was already
|
||||||
|
made by your motherboard's maker. If the configuration bit isn't set
|
||||||
|
properly, you'll have a wrong +12V reading or a wrong VID reading. The way
|
||||||
|
the driver handles that is to preserve this bit through the initialization
|
||||||
|
process, assuming that the BIOS set it up properly beforehand. If it turns
|
||||||
|
out not to be true in some cases, we'll provide a module parameter to force
|
||||||
|
modes.
|
||||||
|
|
||||||
|
This driver also supports the ADM1025A, which differs from the ADM1025
|
||||||
|
only in that it has "open-drain VID inputs while the ADM1025 has on-chip
|
||||||
|
100k pull-ups on the VID inputs". It doesn't make any difference for us.
|
93
Documentation/i2c/chips/adm1026
Normal file
93
Documentation/i2c/chips/adm1026
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
Kernel driver adm1026
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Analog Devices ADM1026
|
||||||
|
Prefix: 'adm1026'
|
||||||
|
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
http://www.analog.com/en/prod/0,,766_825_ADM1026,00.html
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Philip Pokorny <ppokorny@penguincomputing.com> for Penguin Computing
|
||||||
|
Justin Thiessen <jthiessen@penguincomputing.com>
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* gpio_input: int array (min = 1, max = 17)
|
||||||
|
List of GPIO pins (0-16) to program as inputs
|
||||||
|
* gpio_output: int array (min = 1, max = 17)
|
||||||
|
List of GPIO pins (0-16) to program as outputs
|
||||||
|
* gpio_inverted: int array (min = 1, max = 17)
|
||||||
|
List of GPIO pins (0-16) to program as inverted
|
||||||
|
* gpio_normal: int array (min = 1, max = 17)
|
||||||
|
List of GPIO pins (0-16) to program as normal/non-inverted
|
||||||
|
* gpio_fan: int array (min = 1, max = 8)
|
||||||
|
List of GPIO pins (0-7) to program as fan tachs
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the Analog Devices ADM1026. Analog
|
||||||
|
Devices calls it a "complete thermal system management controller."
|
||||||
|
|
||||||
|
The ADM1026 implements three (3) temperature sensors, 17 voltage sensors,
|
||||||
|
16 general purpose digital I/O lines, eight (8) fan speed sensors (8-bit),
|
||||||
|
an analog output and a PWM output along with limit, alarm and mask bits for
|
||||||
|
all of the above. There is even 8k bytes of EEPROM memory on chip.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. There are two external
|
||||||
|
sensor inputs and one internal sensor. Each sensor has a high and low
|
||||||
|
limit. If the limit is exceeded, an interrupt (#SMBALERT) can be
|
||||||
|
generated. The interrupts can be masked. In addition, there are over-temp
|
||||||
|
limits for each sensor. If this limit is exceeded, the #THERM output will
|
||||||
|
be asserted. The current temperature and limits have a resolution of 1
|
||||||
|
degree.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute) but measured
|
||||||
|
in counts of a 22.5kHz internal clock. Each fan has a high limit which
|
||||||
|
corresponds to a minimum fan speed. If the limit is exceeded, an interrupt
|
||||||
|
can be generated. Each fan can be programmed to divide the reference clock
|
||||||
|
by 1, 2, 4 or 8. Not all RPM values can accurately be represented, so some
|
||||||
|
rounding is done. With a divider of 8, the slowest measurable speed of a
|
||||||
|
two pulse per revolution fan is 661 RPM.
|
||||||
|
|
||||||
|
There are 17 voltage sensors. An alarm is triggered if the voltage has
|
||||||
|
crossed a programmable minimum or maximum limit. Note that minimum in this
|
||||||
|
case always means 'closest to zero'; this is important for negative voltage
|
||||||
|
measurements. Several inputs have integrated attenuators so they can measure
|
||||||
|
higher voltages directly. 3.3V, 5V, 12V, -12V and battery voltage all have
|
||||||
|
dedicated inputs. There are several inputs scaled to 0-3V full-scale range
|
||||||
|
for SCSI terminator power. The remaining inputs are not scaled and have
|
||||||
|
a 0-2.5V full-scale range. A 2.5V or 1.82V reference voltage is provided
|
||||||
|
for negative voltage measurements.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may already
|
||||||
|
have disappeared! Note that in the current implementation, all hardware
|
||||||
|
registers are read whenever any data is read (unless it is less than 2.0
|
||||||
|
seconds since the last update). This means that you can easily miss
|
||||||
|
once-only alarms.
|
||||||
|
|
||||||
|
The ADM1026 measures continuously. Analog inputs are measured about 4
|
||||||
|
times a second. Fan speed measurement time depends on fan speed and
|
||||||
|
divisor. It can take as long as 1.5 seconds to measure all fan speeds.
|
||||||
|
|
||||||
|
The ADM1026 has the ability to automatically control fan speed based on the
|
||||||
|
temperature sensor inputs. Both the PWM output and the DAC output can be
|
||||||
|
used to control fan speed. Usually only one of these two outputs will be
|
||||||
|
used. Write the minimum PWM or DAC value to the appropriate control
|
||||||
|
register. Then set the low temperature limit in the tmin values for each
|
||||||
|
temperature sensor. The range of control is fixed at 20 °C, and the
|
||||||
|
largest difference between current and tmin of the temperature sensors sets
|
||||||
|
the control output. See the datasheet for several example circuits for
|
||||||
|
controlling fan speed with the PWM and DAC outputs. The fan speed sensors
|
||||||
|
do not have PWM compensation, so it is probably best to control the fan
|
||||||
|
voltage from the power lead rather than on the ground lead.
|
||||||
|
|
||||||
|
The datasheet shows an example application with VID signals attached to
|
||||||
|
GPIO lines. Unfortunately, the chip may not be connected to the VID lines
|
||||||
|
in this way. The driver assumes that the chips *is* connected this way to
|
||||||
|
get a VID voltage.
|
35
Documentation/i2c/chips/adm1031
Normal file
35
Documentation/i2c/chips/adm1031
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
Kernel driver adm1031
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Analog Devices ADM1030
|
||||||
|
Prefix: 'adm1030'
|
||||||
|
Addresses scanned: I2C 0x2c to 0x2e
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
http://products.analog.com/products/info.asp?product=ADM1030
|
||||||
|
|
||||||
|
* Analog Devices ADM1031
|
||||||
|
Prefix: 'adm1031'
|
||||||
|
Addresses scanned: I2C 0x2c to 0x2e
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
http://products.analog.com/products/info.asp?product=ADM1031
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Alexandre d'Alton <alex@alexdalton.org>
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The ADM1030 and ADM1031 are digital temperature sensors and fan controllers.
|
||||||
|
They sense their own temperature as well as the temperature of up to one
|
||||||
|
(ADM1030) or two (ADM1031) external diodes.
|
||||||
|
|
||||||
|
All temperature values are given in degrees Celsius. Resolution is 0.5
|
||||||
|
degree for the local temperature, 0.125 degree for the remote temperatures.
|
||||||
|
|
||||||
|
Each temperature channel has its own high and low limits, plus a critical
|
||||||
|
limit.
|
||||||
|
|
||||||
|
The ADM1030 monitors a single fan speed, while the ADM1031 monitors up to
|
||||||
|
two. Each fan channel has its own low speed limit.
|
177
Documentation/i2c/chips/adm9240
Normal file
177
Documentation/i2c/chips/adm9240
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
Kernel driver adm9240
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Analog Devices ADM9240
|
||||||
|
Prefix: 'adm9240'
|
||||||
|
Addresses scanned: I2C 0x2c - 0x2f
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
http://www.analog.com/UploadedFiles/Data_Sheets/79857778ADM9240_0.pdf
|
||||||
|
|
||||||
|
* Dallas Semiconductor DS1780
|
||||||
|
Prefix: 'ds1780'
|
||||||
|
Addresses scanned: I2C 0x2c - 0x2f
|
||||||
|
Datasheet: Publicly available at the Dallas Semiconductor (Maxim) website
|
||||||
|
http://pdfserv.maxim-ic.com/en/ds/DS1780.pdf
|
||||||
|
|
||||||
|
* National Semiconductor LM81
|
||||||
|
Prefix: 'lm81'
|
||||||
|
Addresses scanned: I2C 0x2c - 0x2f
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/ds.cgi/LM/LM81.pdf
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>,
|
||||||
|
Michiel Rook <michiel@grendelproject.nl>,
|
||||||
|
Grant Coady <gcoady@gmail.com> with guidance
|
||||||
|
from Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Interface
|
||||||
|
---------
|
||||||
|
The I2C addresses listed above assume BIOS has not changed the
|
||||||
|
chip MSB 5-bit address. Each chip reports a unique manufacturer
|
||||||
|
identification code as well as the chip revision/stepping level.
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
[From ADM9240] The ADM9240 is a complete system hardware monitor for
|
||||||
|
microprocessor-based systems, providing measurement and limit comparison
|
||||||
|
of up to four power supplies and two processor core voltages, plus
|
||||||
|
temperature, two fan speeds and chassis intrusion. Measured values can
|
||||||
|
be read out via an I2C-compatible serial System Management Bus, and values
|
||||||
|
for limit comparisons can be programmed in over the same serial bus. The
|
||||||
|
high speed successive approximation ADC allows frequent sampling of all
|
||||||
|
analog channels to ensure a fast interrupt response to any out-of-limit
|
||||||
|
measurement.
|
||||||
|
|
||||||
|
The ADM9240, DS1780 and LM81 are register compatible, the following
|
||||||
|
details are common to the three chips. Chip differences are described
|
||||||
|
after this section.
|
||||||
|
|
||||||
|
|
||||||
|
Measurements
|
||||||
|
------------
|
||||||
|
The measurement cycle
|
||||||
|
|
||||||
|
The adm9240 driver will take a measurement reading no faster than once
|
||||||
|
each two seconds. User-space may read sysfs interface faster than the
|
||||||
|
measurement update rate and will receive cached data from the most
|
||||||
|
recent measurement.
|
||||||
|
|
||||||
|
ADM9240 has a very fast 320us temperature and voltage measurement cycle
|
||||||
|
with independent fan speed measurement cycles counting alternating rising
|
||||||
|
edges of the fan tacho inputs.
|
||||||
|
|
||||||
|
DS1780 measurement cycle is about once per second including fan speed.
|
||||||
|
|
||||||
|
LM81 measurement cycle is about once per 400ms including fan speed.
|
||||||
|
The LM81 12-bit extended temperature measurement mode is not supported.
|
||||||
|
|
||||||
|
Temperature
|
||||||
|
-----------
|
||||||
|
On chip temperature is reported as degrees Celsius as 9-bit signed data
|
||||||
|
with resolution of 0.5 degrees Celsius. High and low temperature limits
|
||||||
|
are 8-bit signed data with resolution of one degree Celsius.
|
||||||
|
|
||||||
|
Temperature alarm is asserted once the temperature exceeds the high limit,
|
||||||
|
and is cleared when the temperature falls below the temp1_max_hyst value.
|
||||||
|
|
||||||
|
Fan Speed
|
||||||
|
---------
|
||||||
|
Two fan tacho inputs are provided, the ADM9240 gates an internal 22.5kHz
|
||||||
|
clock via a divider to an 8-bit counter. Fan speed (rpm) is calculated by:
|
||||||
|
|
||||||
|
rpm = (22500 * 60) / (count * divider)
|
||||||
|
|
||||||
|
Automatic fan clock divider
|
||||||
|
|
||||||
|
* User sets 0 to fan_min limit
|
||||||
|
- low speed alarm is disabled
|
||||||
|
- fan clock divider not changed
|
||||||
|
- auto fan clock adjuster enabled for valid fan speed reading
|
||||||
|
|
||||||
|
* User sets fan_min limit too low
|
||||||
|
- low speed alarm is enabled
|
||||||
|
- fan clock divider set to max
|
||||||
|
- fan_min set to register value 254 which corresponds
|
||||||
|
to 664 rpm on adm9240
|
||||||
|
- low speed alarm will be asserted if fan speed is
|
||||||
|
less than minimum measurable speed
|
||||||
|
- auto fan clock adjuster disabled
|
||||||
|
|
||||||
|
* User sets reasonable fan speed
|
||||||
|
- low speed alarm is enabled
|
||||||
|
- fan clock divider set to suit fan_min
|
||||||
|
- auto fan clock adjuster enabled: adjusts fan_min
|
||||||
|
|
||||||
|
* User sets unreasonably high low fan speed limit
|
||||||
|
- resolution of the low speed limit may be reduced
|
||||||
|
- alarm will be asserted
|
||||||
|
- auto fan clock adjuster enabled: adjusts fan_min
|
||||||
|
|
||||||
|
* fan speed may be displayed as zero until the auto fan clock divider
|
||||||
|
adjuster brings fan speed clock divider back into chip measurement
|
||||||
|
range, this will occur within a few measurement cycles.
|
||||||
|
|
||||||
|
Analog Output
|
||||||
|
-------------
|
||||||
|
An analog output provides a 0 to 1.25 volt signal intended for an external
|
||||||
|
fan speed amplifier circuit. The analog output is set to maximum value on
|
||||||
|
power up or reset. This doesn't do much on the test Intel SE440BX-2.
|
||||||
|
|
||||||
|
Voltage Monitor
|
||||||
|
|
||||||
|
Voltage (IN) measurement is internally scaled:
|
||||||
|
|
||||||
|
nr label nominal maximum resolution
|
||||||
|
mV mV mV
|
||||||
|
0 +2.5V 2500 3320 13.0
|
||||||
|
1 Vccp1 2700 3600 14.1
|
||||||
|
2 +3.3V 3300 4380 17.2
|
||||||
|
3 +5V 5000 6640 26.0
|
||||||
|
4 +12V 12000 15940 62.5
|
||||||
|
5 Vccp2 2700 3600 14.1
|
||||||
|
|
||||||
|
The reading is an unsigned 8-bit value, nominal voltage measurement is
|
||||||
|
represented by a reading of 192, being 3/4 of the measurement range.
|
||||||
|
|
||||||
|
An alarm is asserted for any voltage going below or above the set limits.
|
||||||
|
|
||||||
|
The driver reports and accepts voltage limits scaled to the above table.
|
||||||
|
|
||||||
|
VID Monitor
|
||||||
|
-----------
|
||||||
|
The chip has five inputs to read the 5-bit VID and reports the mV value
|
||||||
|
based on detected CPU type.
|
||||||
|
|
||||||
|
Chassis Intrusion
|
||||||
|
-----------------
|
||||||
|
An alarm is asserted when the CI pin goes active high. The ADM9240
|
||||||
|
Datasheet has an example of an external temperature sensor driving
|
||||||
|
this pin. On an Intel SE440BX-2 the Chassis Intrusion header is
|
||||||
|
connected to a normally open switch.
|
||||||
|
|
||||||
|
The ADM9240 provides an internal open drain on this line, and may output
|
||||||
|
a 20 ms active low pulse to reset an external Chassis Intrusion latch.
|
||||||
|
|
||||||
|
Clear the CI latch by writing value 1 to the sysfs chassis_clear file.
|
||||||
|
|
||||||
|
Alarm flags reported as 16-bit word
|
||||||
|
|
||||||
|
bit label comment
|
||||||
|
--- ------------- --------------------------
|
||||||
|
0 +2.5 V_Error high or low limit exceeded
|
||||||
|
1 VCCP_Error high or low limit exceeded
|
||||||
|
2 +3.3 V_Error high or low limit exceeded
|
||||||
|
3 +5 V_Error high or low limit exceeded
|
||||||
|
4 Temp_Error temperature error
|
||||||
|
6 FAN1_Error fan low limit exceeded
|
||||||
|
7 FAN2_Error fan low limit exceeded
|
||||||
|
8 +12 V_Error high or low limit exceeded
|
||||||
|
9 VCCP2_Error high or low limit exceeded
|
||||||
|
12 Chassis_Error CI pin went high
|
||||||
|
|
||||||
|
Remaining bits are reserved and thus undefined. It is important to note
|
||||||
|
that alarm bits may be cleared on read, user-space may latch alarms and
|
||||||
|
provide the end-user with a method to clear alarm memory.
|
72
Documentation/i2c/chips/asb100
Normal file
72
Documentation/i2c/chips/asb100
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
Kernel driver asb100
|
||||||
|
====================
|
||||||
|
|
||||||
|
Supported Chips:
|
||||||
|
* Asus ASB100 and ASB100-A "Bach"
|
||||||
|
Prefix: 'asb100'
|
||||||
|
Addresses scanned: I2C 0x2d
|
||||||
|
Datasheet: none released
|
||||||
|
|
||||||
|
Author: Mark M. Hoffman <mhoffman@lightlink.com>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the Asus ASB100 and ASB100-A "Bach".
|
||||||
|
These are custom ASICs available only on Asus mainboards. Asus refuses to
|
||||||
|
supply a datasheet for these chips. Thanks go to many people who helped
|
||||||
|
investigate their hardware, including:
|
||||||
|
|
||||||
|
Vitaly V. Bursov
|
||||||
|
Alexander van Kaam (author of MBM for Windows)
|
||||||
|
Bertrik Sikken
|
||||||
|
|
||||||
|
The ASB100 implements seven voltage sensors, three fan rotation speed
|
||||||
|
sensors, four temperature sensors, VID lines and alarms. In addition to
|
||||||
|
these, the ASB100-A also implements a single PWM controller for fans 2 and
|
||||||
|
3 (i.e. one setting controls both.) If you have a plain ASB100, the PWM
|
||||||
|
controller will simply not work (or maybe it will for you... it doesn't for
|
||||||
|
me).
|
||||||
|
|
||||||
|
Temperatures are measured and reported in degrees Celsius.
|
||||||
|
|
||||||
|
Fan speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report values in volts.
|
||||||
|
|
||||||
|
The VID lines encode the core voltage value: the voltage level your
|
||||||
|
processor should work with. This is hardcoded by the mainboard and/or
|
||||||
|
processor itself. It is a value in volts.
|
||||||
|
|
||||||
|
Alarms: (TODO question marks indicate may or may not work)
|
||||||
|
|
||||||
|
0x0001 => in0 (?)
|
||||||
|
0x0002 => in1 (?)
|
||||||
|
0x0004 => in2
|
||||||
|
0x0008 => in3
|
||||||
|
0x0010 => temp1 (1)
|
||||||
|
0x0020 => temp2
|
||||||
|
0x0040 => fan1
|
||||||
|
0x0080 => fan2
|
||||||
|
0x0100 => in4
|
||||||
|
0x0200 => in5 (?) (2)
|
||||||
|
0x0400 => in6 (?) (2)
|
||||||
|
0x0800 => fan3
|
||||||
|
0x1000 => chassis switch
|
||||||
|
0x2000 => temp3
|
||||||
|
|
||||||
|
Alarm Notes:
|
||||||
|
|
||||||
|
(1) This alarm will only trigger if the hysteresis value is 127C.
|
||||||
|
I.e. it behaves the same as w83781d.
|
||||||
|
|
||||||
|
(2) The min and max registers for these values appear to
|
||||||
|
be read-only or otherwise stuck at 0x00.
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
* Experiment with fan divisors > 8.
|
||||||
|
* Experiment with temp. sensor types.
|
||||||
|
* Are there really 13 voltage inputs? Probably not...
|
||||||
|
* Cleanups, no doubt...
|
||||||
|
|
108
Documentation/i2c/chips/ds1621
Normal file
108
Documentation/i2c/chips/ds1621
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
Kernel driver ds1621
|
||||||
|
====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Dallas Semiconductor DS1621
|
||||||
|
Prefix: 'ds1621'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4f
|
||||||
|
Datasheet: Publicly available at the Dallas Semiconductor website
|
||||||
|
http://www.dalsemi.com/
|
||||||
|
* Dallas Semiconductor DS1625
|
||||||
|
Prefix: 'ds1621'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4f
|
||||||
|
Datasheet: Publicly available at the Dallas Semiconductor website
|
||||||
|
http://www.dalsemi.com/
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Christian W. Zuckschwerdt <zany@triq.net>
|
||||||
|
valuable contributions by Jan M. Sendler <sendler@sendler.de>
|
||||||
|
ported to 2.6 by Aurelien Jarno <aurelien@aurel32.net>
|
||||||
|
with the help of Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* polarity int
|
||||||
|
Output's polarity: 0 = active high, 1 = active low
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The DS1621 is a (one instance) digital thermometer and thermostat. It has
|
||||||
|
both high and low temperature limits which can be user defined (i.e.
|
||||||
|
programmed into non-volatile on-chip registers). Temperature range is -55
|
||||||
|
degree Celsius to +125 in 0.5 increments. You may convert this into a
|
||||||
|
Fahrenheit range of -67 to +257 degrees with 0.9 steps. If polarity
|
||||||
|
parameter is not provided, original value is used.
|
||||||
|
|
||||||
|
As for the thermostat, behavior can also be programmed using the polarity
|
||||||
|
toggle. On the one hand ("heater"), the thermostat output of the chip,
|
||||||
|
Tout, will trigger when the low limit temperature is met or underrun and
|
||||||
|
stays high until the high limit is met or exceeded. On the other hand
|
||||||
|
("cooler"), vice versa. That way "heater" equals "active low", whereas
|
||||||
|
"conditioner" equals "active high". Please note that the DS1621 data sheet
|
||||||
|
is somewhat misleading in this point since setting the polarity bit does
|
||||||
|
not simply invert Tout.
|
||||||
|
|
||||||
|
A second thing is that, during extensive testing, Tout showed a tolerance
|
||||||
|
of up to +/- 0.5 degrees even when compared against precise temperature
|
||||||
|
readings. Be sure to have a high vs. low temperature limit gap of al least
|
||||||
|
1.0 degree Celsius to avoid Tout "bouncing", though!
|
||||||
|
|
||||||
|
As for alarms, you can read the alarm status of the DS1621 via the 'alarms'
|
||||||
|
/sys file interface. The result consists mainly of bit 6 and 5 of the
|
||||||
|
configuration register of the chip; bit 6 (0x40 or 64) is the high alarm
|
||||||
|
bit and bit 5 (0x20 or 32) the low one. These bits are set when the high or
|
||||||
|
low limits are met or exceeded and are reset by the module as soon as the
|
||||||
|
respective temperature ranges are left.
|
||||||
|
|
||||||
|
The alarm registers are in no way suitable to find out about the actual
|
||||||
|
status of Tout. They will only tell you about its history, whether or not
|
||||||
|
any of the limits have ever been met or exceeded since last power-up or
|
||||||
|
reset. Be aware: When testing, it showed that the status of Tout can change
|
||||||
|
with neither of the alarms set.
|
||||||
|
|
||||||
|
Temperature conversion of the DS1621 takes up to 1000ms; internal access to
|
||||||
|
non-volatile registers may last for 10ms or below.
|
||||||
|
|
||||||
|
High Accuracy Temperature Reading
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
As said before, the temperature issued via the 9-bit i2c-bus data is
|
||||||
|
somewhat arbitrary. Internally, the temperature conversion is of a
|
||||||
|
different kind that is explained (not so...) well in the DS1621 data sheet.
|
||||||
|
To cut the long story short: Inside the DS1621 there are two oscillators,
|
||||||
|
both of them biassed by a temperature coefficient.
|
||||||
|
|
||||||
|
Higher resolution of the temperature reading can be achieved using the
|
||||||
|
internal projection, which means taking account of REG_COUNT and REG_SLOPE
|
||||||
|
(the driver manages them):
|
||||||
|
|
||||||
|
Taken from Dallas Semiconductors App Note 068: 'Increasing Temperature
|
||||||
|
Resolution on the DS1620' and App Note 105: 'High Resolution Temperature
|
||||||
|
Measurement with Dallas Direct-to-Digital Temperature Sensors'
|
||||||
|
|
||||||
|
- Read the 9-bit temperature and strip the LSB (Truncate the .5 degs)
|
||||||
|
- The resulting value is TEMP_READ.
|
||||||
|
- Then, read REG_COUNT.
|
||||||
|
- And then, REG_SLOPE.
|
||||||
|
|
||||||
|
TEMP = TEMP_READ - 0.25 + ((REG_SLOPE - REG_COUNT) / REG_SLOPE)
|
||||||
|
|
||||||
|
Note that this is what the DONE bit in the DS1621 configuration register is
|
||||||
|
good for: Internally, one temperature conversion takes up to 1000ms. Before
|
||||||
|
that conversion is complete you will not be able to read valid things out
|
||||||
|
of REG_COUNT and REG_SLOPE. The DONE bit, as you may have guessed by now,
|
||||||
|
tells you whether the conversion is complete ("done", in plain English) and
|
||||||
|
thus, whether the values you read are good or not.
|
||||||
|
|
||||||
|
The DS1621 has two modes of operation: "Continuous" conversion, which can
|
||||||
|
be understood as the default stand-alone mode where the chip gets the
|
||||||
|
temperature and controls external devices via its Tout pin or tells other
|
||||||
|
i2c's about it if they care. The other mode is called "1SHOT", that means
|
||||||
|
that it only figures out about the temperature when it is explicitly told
|
||||||
|
to do so; this can be seen as power saving mode.
|
||||||
|
|
||||||
|
Now if you want to read REG_COUNT and REG_SLOPE, you have to either stop
|
||||||
|
the continuous conversions until the contents of these registers are valid,
|
||||||
|
or, in 1SHOT mode, you have to have one conversion made.
|
96
Documentation/i2c/chips/eeprom
Normal file
96
Documentation/i2c/chips/eeprom
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
Kernel driver eeprom
|
||||||
|
====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Any EEPROM chip in the designated address range
|
||||||
|
Prefix: 'eeprom'
|
||||||
|
Addresses scanned: I2C 0x50 - 0x57
|
||||||
|
Datasheets: Publicly available from:
|
||||||
|
Atmel (www.atmel.com),
|
||||||
|
Catalyst (www.catsemi.com),
|
||||||
|
Fairchild (www.fairchildsemi.com),
|
||||||
|
Microchip (www.microchip.com),
|
||||||
|
Philips (www.semiconductor.philips.com),
|
||||||
|
Rohm (www.rohm.com),
|
||||||
|
ST (www.st.com),
|
||||||
|
Xicor (www.xicor.com),
|
||||||
|
and others.
|
||||||
|
|
||||||
|
Chip Size (bits) Address
|
||||||
|
24C01 1K 0x50 (shadows at 0x51 - 0x57)
|
||||||
|
24C01A 1K 0x50 - 0x57 (Typical device on DIMMs)
|
||||||
|
24C02 2K 0x50 - 0x57
|
||||||
|
24C04 4K 0x50, 0x52, 0x54, 0x56
|
||||||
|
(additional data at 0x51, 0x53, 0x55, 0x57)
|
||||||
|
24C08 8K 0x50, 0x54 (additional data at 0x51, 0x52,
|
||||||
|
0x53, 0x55, 0x56, 0x57)
|
||||||
|
24C16 16K 0x50 (additional data at 0x51 - 0x57)
|
||||||
|
Sony 2K 0x57
|
||||||
|
|
||||||
|
Atmel 34C02B 2K 0x50 - 0x57, SW write protect at 0x30-37
|
||||||
|
Catalyst 34FC02 2K 0x50 - 0x57, SW write protect at 0x30-37
|
||||||
|
Catalyst 34RC02 2K 0x50 - 0x57, SW write protect at 0x30-37
|
||||||
|
Fairchild 34W02 2K 0x50 - 0x57, SW write protect at 0x30-37
|
||||||
|
Microchip 24AA52 2K 0x50 - 0x57, SW write protect at 0x30-37
|
||||||
|
ST M34C02 2K 0x50 - 0x57, SW write protect at 0x30-37
|
||||||
|
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>,
|
||||||
|
Jean Delvare <khali@linux-fr.org>,
|
||||||
|
Greg Kroah-Hartman <greg@kroah.com>,
|
||||||
|
IBM Corp.
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This is a simple EEPROM module meant to enable reading the first 256 bytes
|
||||||
|
of an EEPROM (on a SDRAM DIMM for example). However, it will access serial
|
||||||
|
EEPROMs on any I2C adapter. The supported devices are generically called
|
||||||
|
24Cxx, and are listed above; however the numbering for these
|
||||||
|
industry-standard devices may vary by manufacturer.
|
||||||
|
|
||||||
|
This module was a programming exercise to get used to the new project
|
||||||
|
organization laid out by Frodo, but it should be at least completely
|
||||||
|
effective for decoding the contents of EEPROMs on DIMMs.
|
||||||
|
|
||||||
|
DIMMS will typically contain a 24C01A or 24C02, or the 34C02 variants.
|
||||||
|
The other devices will not be found on a DIMM because they respond to more
|
||||||
|
than one address.
|
||||||
|
|
||||||
|
DDC Monitors may contain any device. Often a 24C01, which responds to all 8
|
||||||
|
addresses, is found.
|
||||||
|
|
||||||
|
Recent Sony Vaio laptops have an EEPROM at 0x57. We couldn't get the
|
||||||
|
specification, so it is guess work and far from being complete.
|
||||||
|
|
||||||
|
The Microchip 24AA52/24LCS52, ST M34C02, and others support an additional
|
||||||
|
software write protect register at 0x30 - 0x37 (0x20 less than the memory
|
||||||
|
location). The chip responds to "write quick" detection at this address but
|
||||||
|
does not respond to byte reads. If this register is present, the lower 128
|
||||||
|
bytes of the memory array are not write protected. Any byte data write to
|
||||||
|
this address will write protect the memory array permanently, and the
|
||||||
|
device will no longer respond at the 0x30-37 address. The eeprom driver
|
||||||
|
does not support this register.
|
||||||
|
|
||||||
|
Lacking functionality:
|
||||||
|
|
||||||
|
* Full support for larger devices (24C04, 24C08, 24C16). These are not
|
||||||
|
typically found on a PC. These devices will appear as separate devices at
|
||||||
|
multiple addresses.
|
||||||
|
|
||||||
|
* Support for really large devices (24C32, 24C64, 24C128, 24C256, 24C512).
|
||||||
|
These devices require two-byte address fields and are not supported.
|
||||||
|
|
||||||
|
* Enable Writing. Again, no technical reason why not, but making it easy
|
||||||
|
to change the contents of the EEPROMs (on DIMMs anyway) also makes it easy
|
||||||
|
to disable the DIMMs (potentially preventing the computer from booting)
|
||||||
|
until the values are restored somehow.
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
After inserting the module (and any other required SMBus/i2c modules), you
|
||||||
|
should have some EEPROM directories in /sys/bus/i2c/devices/* of names such
|
||||||
|
as "0-0050". Inside each of these is a series of files, the eeprom file
|
||||||
|
contains the binary data from EEPROM.
|
169
Documentation/i2c/chips/fscher
Normal file
169
Documentation/i2c/chips/fscher
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
Kernel driver fscher
|
||||||
|
====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Fujitsu-Siemens Hermes chip
|
||||||
|
Prefix: 'fscher'
|
||||||
|
Addresses scanned: I2C 0x73
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Reinhard Nissl <rnissl@gmx.de> based on work
|
||||||
|
from Hermann Jung <hej@odn.de>,
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the Fujitsu-Siemens Hermes chip. It is
|
||||||
|
described in the 'Register Set Specification BMC Hermes based Systemboard'
|
||||||
|
from Fujitsu-Siemens.
|
||||||
|
|
||||||
|
The Hermes chip implements a hardware-based system management, e.g. for
|
||||||
|
controlling fan speed and core voltage. There is also a watchdog counter on
|
||||||
|
the chip which can trigger an alarm and even shut the system down.
|
||||||
|
|
||||||
|
The chip provides three temperature values (CPU, motherboard and
|
||||||
|
auxiliary), three voltage values (+12V, +5V and battery) and three fans
|
||||||
|
(power supply, CPU and auxiliary).
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. The resolution is 1 degree.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). The value
|
||||||
|
can be divided by a programmable divider (1, 2 or 4) which is stored on
|
||||||
|
the chip.
|
||||||
|
|
||||||
|
Voltage sensors (also known as "in" sensors) report their values in volts.
|
||||||
|
|
||||||
|
All values are reported as final values from the driver. There is no need
|
||||||
|
for further calculations.
|
||||||
|
|
||||||
|
|
||||||
|
Detailed description
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Below you'll find a single line description of all the bit values. With
|
||||||
|
this information, you're able to decode e. g. alarms, wdog, etc. To make
|
||||||
|
use of the watchdog, you'll need to set the watchdog time and enable the
|
||||||
|
watchdog. After that it is necessary to restart the watchdog time within
|
||||||
|
the specified period of time, or a system reset will occur.
|
||||||
|
|
||||||
|
* revision
|
||||||
|
READING & 0xff = 0x??: HERMES revision identification
|
||||||
|
|
||||||
|
* alarms
|
||||||
|
READING & 0x80 = 0x80: CPU throttling active
|
||||||
|
READING & 0x80 = 0x00: CPU running at full speed
|
||||||
|
|
||||||
|
READING & 0x10 = 0x10: software event (see control:1)
|
||||||
|
READING & 0x10 = 0x00: no software event
|
||||||
|
|
||||||
|
READING & 0x08 = 0x08: watchdog event (see wdog:2)
|
||||||
|
READING & 0x08 = 0x00: no watchdog event
|
||||||
|
|
||||||
|
READING & 0x02 = 0x02: thermal event (see temp*:1)
|
||||||
|
READING & 0x02 = 0x00: no thermal event
|
||||||
|
|
||||||
|
READING & 0x01 = 0x01: fan event (see fan*:1)
|
||||||
|
READING & 0x01 = 0x00: no fan event
|
||||||
|
|
||||||
|
READING & 0x13 ! 0x00: ALERT LED is flashing
|
||||||
|
|
||||||
|
* control
|
||||||
|
READING & 0x01 = 0x01: software event
|
||||||
|
READING & 0x01 = 0x00: no software event
|
||||||
|
|
||||||
|
WRITING & 0x01 = 0x01: set software event
|
||||||
|
WRITING & 0x01 = 0x00: clear software event
|
||||||
|
|
||||||
|
* watchdog_control
|
||||||
|
READING & 0x80 = 0x80: power off on watchdog event while thermal event
|
||||||
|
READING & 0x80 = 0x00: watchdog power off disabled (just system reset enabled)
|
||||||
|
|
||||||
|
READING & 0x40 = 0x40: watchdog timebase 60 seconds (see also wdog:1)
|
||||||
|
READING & 0x40 = 0x00: watchdog timebase 2 seconds
|
||||||
|
|
||||||
|
READING & 0x10 = 0x10: watchdog enabled
|
||||||
|
READING & 0x10 = 0x00: watchdog disabled
|
||||||
|
|
||||||
|
WRITING & 0x80 = 0x80: enable "power off on watchdog event while thermal event"
|
||||||
|
WRITING & 0x80 = 0x00: disable "power off on watchdog event while thermal event"
|
||||||
|
|
||||||
|
WRITING & 0x40 = 0x40: set watchdog timebase to 60 seconds
|
||||||
|
WRITING & 0x40 = 0x00: set watchdog timebase to 2 seconds
|
||||||
|
|
||||||
|
WRITING & 0x20 = 0x20: disable watchdog
|
||||||
|
|
||||||
|
WRITING & 0x10 = 0x10: enable watchdog / restart watchdog time
|
||||||
|
|
||||||
|
* watchdog_state
|
||||||
|
READING & 0x02 = 0x02: watchdog system reset occurred
|
||||||
|
READING & 0x02 = 0x00: no watchdog system reset occurred
|
||||||
|
|
||||||
|
WRITING & 0x02 = 0x02: clear watchdog event
|
||||||
|
|
||||||
|
* watchdog_preset
|
||||||
|
READING & 0xff = 0x??: configured watch dog time in units (see wdog:3 0x40)
|
||||||
|
|
||||||
|
WRITING & 0xff = 0x??: configure watch dog time in units
|
||||||
|
|
||||||
|
* in* (0: +5V, 1: +12V, 2: onboard 3V battery)
|
||||||
|
READING: actual voltage value
|
||||||
|
|
||||||
|
* temp*_status (1: CPU sensor, 2: onboard sensor, 3: auxiliary sensor)
|
||||||
|
READING & 0x02 = 0x02: thermal event (overtemperature)
|
||||||
|
READING & 0x02 = 0x00: no thermal event
|
||||||
|
|
||||||
|
READING & 0x01 = 0x01: sensor is working
|
||||||
|
READING & 0x01 = 0x00: sensor is faulty
|
||||||
|
|
||||||
|
WRITING & 0x02 = 0x02: clear thermal event
|
||||||
|
|
||||||
|
* temp*_input (1: CPU sensor, 2: onboard sensor, 3: auxiliary sensor)
|
||||||
|
READING: actual temperature value
|
||||||
|
|
||||||
|
* fan*_status (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
|
||||||
|
READING & 0x04 = 0x04: fan event (fan fault)
|
||||||
|
READING & 0x04 = 0x00: no fan event
|
||||||
|
|
||||||
|
WRITING & 0x04 = 0x04: clear fan event
|
||||||
|
|
||||||
|
* fan*_div (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
|
||||||
|
Divisors 2,4 and 8 are supported, both for reading and writing
|
||||||
|
|
||||||
|
* fan*_pwm (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
|
||||||
|
READING & 0xff = 0x00: fan may be switched off
|
||||||
|
READING & 0xff = 0x01: fan must run at least at minimum speed (supply: 6V)
|
||||||
|
READING & 0xff = 0xff: fan must run at maximum speed (supply: 12V)
|
||||||
|
READING & 0xff = 0x??: fan must run at least at given speed (supply: 6V..12V)
|
||||||
|
|
||||||
|
WRITING & 0xff = 0x00: fan may be switched off
|
||||||
|
WRITING & 0xff = 0x01: fan must run at least at minimum speed (supply: 6V)
|
||||||
|
WRITING & 0xff = 0xff: fan must run at maximum speed (supply: 12V)
|
||||||
|
WRITING & 0xff = 0x??: fan must run at least at given speed (supply: 6V..12V)
|
||||||
|
|
||||||
|
* fan*_input (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
|
||||||
|
READING: actual RPM value
|
||||||
|
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* Measuring fan speed
|
||||||
|
It seems that the chip counts "ripples" (typical fans produce 2 ripples per
|
||||||
|
rotation while VERAX fans produce 18) in a 9-bit register. This register is
|
||||||
|
read out every second, then the ripple prescaler (2, 4 or 8) is applied and
|
||||||
|
the result is stored in the 8 bit output register. Due to the limitation of
|
||||||
|
the counting register to 9 bits, it is impossible to measure a VERAX fan
|
||||||
|
properly (even with a prescaler of 8). At its maximum speed of 3500 RPM the
|
||||||
|
fan produces 1080 ripples per second which causes the counting register to
|
||||||
|
overflow twice, leading to only 186 RPM.
|
||||||
|
|
||||||
|
* Measuring input voltages
|
||||||
|
in2 ("battery") reports the voltage of the onboard lithium battery and not
|
||||||
|
+3.3V from the power supply.
|
||||||
|
|
||||||
|
* Undocumented features
|
||||||
|
Fujitsu-Siemens Computers has not documented all features of the chip so
|
||||||
|
far. Their software, System Guard, shows that there are a still some
|
||||||
|
features which cannot be controlled by this implementation.
|
74
Documentation/i2c/chips/gl518sm
Normal file
74
Documentation/i2c/chips/gl518sm
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
Kernel driver gl518sm
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Genesys Logic GL518SM release 0x00
|
||||||
|
Prefix: 'gl518sm'
|
||||||
|
Addresses scanned: I2C 0x2c and 0x2d
|
||||||
|
Datasheet: http://www.genesyslogic.com/pdf
|
||||||
|
* Genesys Logic GL518SM release 0x80
|
||||||
|
Prefix: 'gl518sm'
|
||||||
|
Addresses scanned: I2C 0x2c and 0x2d
|
||||||
|
Datasheet: http://www.genesyslogic.com/pdf
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Kyösti Mälkki <kmalkki@cc.hut.fi>
|
||||||
|
Hong-Gunn Chew <hglinux@gunnet.org>
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
IMPORTANT:
|
||||||
|
|
||||||
|
For the revision 0x00 chip, the in0, in1, and in2 values (+5V, +3V,
|
||||||
|
and +12V) CANNOT be read. This is a limitation of the chip, not the driver.
|
||||||
|
|
||||||
|
This driver supports the Genesys Logic GL518SM chip. There are at least
|
||||||
|
two revision of this chip, which we call revision 0x00 and 0x80. Revision
|
||||||
|
0x80 chips support the reading of all voltages and revision 0x00 only
|
||||||
|
for VIN3.
|
||||||
|
|
||||||
|
The GL518SM implements one temperature sensor, two fan rotation speed
|
||||||
|
sensors, and four voltage sensors. It can report alarms through the
|
||||||
|
computer speakers.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. An alarm goes off while the
|
||||||
|
temperature is above the over temperature limit, and has not yet dropped
|
||||||
|
below the hysteresis limit. The alarm always reflects the current
|
||||||
|
situation. Measurements are guaranteed between -10 degrees and +110
|
||||||
|
degrees, with a accuracy of +/-3 degrees.
|
||||||
|
|
||||||
|
Rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. In
|
||||||
|
case when you have selected to turn fan1 off, no fan1 alarm is triggered.
|
||||||
|
|
||||||
|
Fan readings can be divided by a programmable divider (1, 2, 4 or 8) to
|
||||||
|
give the readings more range or accuracy. Not all RPM values can
|
||||||
|
accurately be represented, so some rounding is done. With a divider
|
||||||
|
of 2, the lowest representable value is around 1900 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as VIN sensors) report their values in volts.
|
||||||
|
An alarm is triggered if the voltage has crossed a programmable minimum or
|
||||||
|
maximum limit. Note that minimum in this case always means 'closest to
|
||||||
|
zero'; this is important for negative voltage measurements. The VDD input
|
||||||
|
measures voltages between 0.000 and 5.865 volt, with a resolution of 0.023
|
||||||
|
volt. The other inputs measure voltages between 0.000 and 4.845 volt, with
|
||||||
|
a resolution of 0.019 volt. Note that revision 0x00 chips do not support
|
||||||
|
reading the current voltage of any input except for VIN3; limit setting and
|
||||||
|
alarms work fine, though.
|
||||||
|
|
||||||
|
When an alarm is triggered, you can be warned by a beeping signal through your
|
||||||
|
computer speaker. It is possible to enable all beeping globally, or only the
|
||||||
|
beeping for some alarms.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once (except for temperature alarms). This means that the
|
||||||
|
cause for the alarm may already have disappeared! Note that in the current
|
||||||
|
implementation, all hardware registers are read whenever any data is read
|
||||||
|
(unless it is less than 1.5 seconds since the last update). This means that
|
||||||
|
you can easily miss once-only alarms.
|
||||||
|
|
||||||
|
The GL518SM only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values.
|
96
Documentation/i2c/chips/it87
Normal file
96
Documentation/i2c/chips/it87
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
Kernel driver it87
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* IT8705F
|
||||||
|
Prefix: 'it87'
|
||||||
|
Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: Publicly available at the ITE website
|
||||||
|
http://www.ite.com.tw/
|
||||||
|
* IT8712F
|
||||||
|
Prefix: 'it8712'
|
||||||
|
Addresses scanned: I2C 0x28 - 0x2f
|
||||||
|
from Super I/O config space, or default ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: Publicly available at the ITE website
|
||||||
|
http://www.ite.com.tw/
|
||||||
|
* SiS950 [clone of IT8705F]
|
||||||
|
Prefix: 'sis950'
|
||||||
|
Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: No longer be available
|
||||||
|
|
||||||
|
Author: Christophe Gauthron <chrisg@0-in.com>
|
||||||
|
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* update_vbat: int
|
||||||
|
|
||||||
|
0 if vbat should report power on value, 1 if vbat should be updated after
|
||||||
|
each read. Default is 0. On some boards the battery voltage is provided
|
||||||
|
by either the battery or the onboard power supply. Only the first reading
|
||||||
|
at power on will be the actual battery voltage (which the chip does
|
||||||
|
automatically). On other boards the battery voltage is always fed to
|
||||||
|
the chip so can be read at any time. Excessive reading may decrease
|
||||||
|
battery life but no information is given in the datasheet.
|
||||||
|
|
||||||
|
* fix_pwm_polarity int
|
||||||
|
|
||||||
|
Force PWM polarity to active high (DANGEROUS). Some chips are
|
||||||
|
misconfigured by BIOS - PWM values would be inverted. This option tries
|
||||||
|
to fix this. Please contact your BIOS manufacturer and ask him for fix.
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the IT8705F, IT8712F and SiS950 chips.
|
||||||
|
|
||||||
|
This driver also supports IT8712F, which adds SMBus access, and a VID
|
||||||
|
input, used to report the Vcore voltage of the Pentium processor.
|
||||||
|
The IT8712F additionally features VID inputs.
|
||||||
|
|
||||||
|
These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
|
||||||
|
joysticks and other miscellaneous stuff. For hardware monitoring, they
|
||||||
|
include an 'environment controller' with 3 temperature sensors, 3 fan
|
||||||
|
rotation speed sensors, 8 voltage sensors, and associated alarms.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. An alarm is triggered once
|
||||||
|
when the Overtemperature Shutdown limit is crossed.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8) to give the
|
||||||
|
readings more range or accuracy. Not all RPM values can accurately be
|
||||||
|
represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report their values in volts. An
|
||||||
|
alarm is triggered if the voltage has crossed a programmable minimum or
|
||||||
|
maximum limit. Note that minimum in this case always means 'closest to
|
||||||
|
zero'; this is important for negative voltage measurements. All voltage
|
||||||
|
inputs can measure voltages between 0 and 4.08 volts, with a resolution of
|
||||||
|
0.016 volt. The battery voltage in8 does not have limit registers.
|
||||||
|
|
||||||
|
The VID lines (IT8712F only) encode the core voltage value: the voltage
|
||||||
|
level your processor should work with. This is hardcoded by the mainboard
|
||||||
|
and/or processor itself. It is a value in volts.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may already
|
||||||
|
have disappeared! Note that in the current implementation, all hardware
|
||||||
|
registers are read whenever any data is read (unless it is less than 1.5
|
||||||
|
seconds since the last update). This means that you can easily miss
|
||||||
|
once-only alarms.
|
||||||
|
|
||||||
|
The IT87xx only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values.
|
||||||
|
|
||||||
|
To change sensor N to a thermistor, 'echo 2 > tempN_type' where N is 1, 2,
|
||||||
|
or 3. To change sensor N to a thermal diode, 'echo 3 > tempN_type'.
|
||||||
|
Give 0 for unused sensor. Any other value is invalid. To configure this at
|
||||||
|
startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor;
|
||||||
|
3 = thermal diode)
|
||||||
|
|
||||||
|
The fan speed control features are limited to manual PWM mode. Automatic
|
||||||
|
"Smart Guardian" mode control handling is not implemented. However
|
||||||
|
if you want to go for "manual mode" just write 1 to pwmN_enable.
|
57
Documentation/i2c/chips/lm63
Normal file
57
Documentation/i2c/chips/lm63
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
Kernel driver lm63
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM63
|
||||||
|
Prefix: 'lm63'
|
||||||
|
Addresses scanned: I2C 0x4c
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/pf/LM/LM63.html
|
||||||
|
|
||||||
|
Author: Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Thanks go to Tyan and especially Alex Buckingham for setting up a remote
|
||||||
|
access to their S4882 test platform for this driver.
|
||||||
|
http://www.tyan.com/
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The LM63 is a digital temperature sensor with integrated fan monitoring
|
||||||
|
and control.
|
||||||
|
|
||||||
|
The LM63 is basically an LM86 with fan speed monitoring and control
|
||||||
|
capabilities added. It misses some of the LM86 features though:
|
||||||
|
- No low limit for local temperature.
|
||||||
|
- No critical limit for local temperature.
|
||||||
|
- Critical limit for remote temperature can be changed only once. We
|
||||||
|
will consider that the critical limit is read-only.
|
||||||
|
|
||||||
|
The datasheet isn't very clear about what the tachometer reading is.
|
||||||
|
|
||||||
|
An explanation from National Semiconductor: The two lower bits of the read
|
||||||
|
value have to be masked out. The value is still 16 bit in width.
|
||||||
|
|
||||||
|
All temperature values are given in degrees Celsius. Resolution is 1.0
|
||||||
|
degree for the local temperature, 0.125 degree for the remote temperature.
|
||||||
|
|
||||||
|
The fan speed is measured using a tachometer. Contrary to most chips which
|
||||||
|
store the value in an 8-bit register and have a selectable clock divider
|
||||||
|
to make sure that the result will fit in the register, the LM63 uses 16-bit
|
||||||
|
value for measuring the speed of the fan. It can measure fan speeds down to
|
||||||
|
83 RPM, at least in theory.
|
||||||
|
|
||||||
|
Note that the pin used for fan monitoring is shared with an alert out
|
||||||
|
function. Depending on how the board designer wanted to use the chip, fan
|
||||||
|
speed monitoring will or will not be possible. The proper chip configuration
|
||||||
|
is left to the BIOS, and the driver will blindly trust it.
|
||||||
|
|
||||||
|
A PWM output can be used to control the speed of the fan. The LM63 has two
|
||||||
|
PWM modes: manual and automatic. Automatic mode is not fully implemented yet
|
||||||
|
(you cannot define your custom PWM/temperature curve), and mode change isn't
|
||||||
|
supported either.
|
||||||
|
|
||||||
|
The lm63 driver will not update its values more frequently than every
|
||||||
|
second; reading them more often will do no harm, but will return 'old'
|
||||||
|
values.
|
||||||
|
|
65
Documentation/i2c/chips/lm75
Normal file
65
Documentation/i2c/chips/lm75
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
Kernel driver lm75
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM75
|
||||||
|
Prefix: 'lm75'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4f
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/
|
||||||
|
* Dallas Semiconductor DS75
|
||||||
|
Prefix: 'lm75'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4f
|
||||||
|
Datasheet: Publicly available at the Dallas Semiconductor website
|
||||||
|
http://www.maxim-ic.com/
|
||||||
|
* Dallas Semiconductor DS1775
|
||||||
|
Prefix: 'lm75'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4f
|
||||||
|
Datasheet: Publicly available at the Dallas Semiconductor website
|
||||||
|
http://www.maxim-ic.com/
|
||||||
|
* Maxim MAX6625, MAX6626
|
||||||
|
Prefix: 'lm75'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4b
|
||||||
|
Datasheet: Publicly available at the Maxim website
|
||||||
|
http://www.maxim-ic.com/
|
||||||
|
* Microchip (TelCom) TCN75
|
||||||
|
Prefix: 'lm75'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4f
|
||||||
|
Datasheet: Publicly available at the Microchip website
|
||||||
|
http://www.microchip.com/
|
||||||
|
|
||||||
|
Author: Frodo Looijaard <frodol@dds.nl>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The LM75 implements one temperature sensor. Limits can be set through the
|
||||||
|
Overtemperature Shutdown register and Hysteresis register. Each value can be
|
||||||
|
set and read to half-degree accuracy.
|
||||||
|
An alarm is issued (usually to a connected LM78) when the temperature
|
||||||
|
gets higher then the Overtemperature Shutdown value; it stays on until
|
||||||
|
the temperature falls below the Hysteresis value.
|
||||||
|
All temperatures are in degrees Celsius, and are guaranteed within a
|
||||||
|
range of -55 to +125 degrees.
|
||||||
|
|
||||||
|
The LM75 only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values.
|
||||||
|
|
||||||
|
The LM75 is usually used in combination with LM78-like chips, to measure
|
||||||
|
the temperature of the processor(s).
|
||||||
|
|
||||||
|
The DS75, DS1775, MAX6625, and MAX6626 are supported as well.
|
||||||
|
They are not distinguished from an LM75. While most of these chips
|
||||||
|
have three additional bits of accuracy (12 vs. 9 for the LM75),
|
||||||
|
the additional bits are not supported. Not only that, but these chips will
|
||||||
|
not be detected if not in 9-bit precision mode (use the force parameter if
|
||||||
|
needed).
|
||||||
|
|
||||||
|
The TCN75 is supported as well, and is not distinguished from an LM75.
|
||||||
|
|
||||||
|
The LM75 is essentially an industry standard; there may be other
|
||||||
|
LM75 clones not listed here, with or without various enhancements,
|
||||||
|
that are supported.
|
||||||
|
|
||||||
|
The LM77 is not supported, contrary to what we pretended for a long time.
|
||||||
|
Both chips are simply not compatible, value encoding differs.
|
22
Documentation/i2c/chips/lm77
Normal file
22
Documentation/i2c/chips/lm77
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Kernel driver lm77
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM77
|
||||||
|
Prefix: 'lm77'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4b
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/
|
||||||
|
|
||||||
|
Author: Andras BALI <drewie@freemail.hu>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The LM77 implements one temperature sensor. The temperature
|
||||||
|
sensor incorporates a band-gap type temperature sensor,
|
||||||
|
10-bit ADC, and a digital comparator with user-programmable upper
|
||||||
|
and lower limit values.
|
||||||
|
|
||||||
|
Limits can be set through the Overtemperature Shutdown register and
|
||||||
|
Hysteresis register.
|
82
Documentation/i2c/chips/lm78
Normal file
82
Documentation/i2c/chips/lm78
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
Kernel driver lm78
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM78
|
||||||
|
Prefix: 'lm78'
|
||||||
|
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/
|
||||||
|
* National Semiconductor LM78-J
|
||||||
|
Prefix: 'lm78-j'
|
||||||
|
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/
|
||||||
|
* National Semiconductor LM79
|
||||||
|
Prefix: 'lm79'
|
||||||
|
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/
|
||||||
|
|
||||||
|
Author: Frodo Looijaard <frodol@dds.nl>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the National Semiconductor LM78, LM78-J
|
||||||
|
and LM79. They are described as 'Microprocessor System Hardware Monitors'.
|
||||||
|
|
||||||
|
There is almost no difference between the three supported chips. Functionally,
|
||||||
|
the LM78 and LM78-J are exactly identical. The LM79 has one more VID line,
|
||||||
|
which is used to report the lower voltages newer Pentium processors use.
|
||||||
|
From here on, LM7* means either of these three types.
|
||||||
|
|
||||||
|
The LM7* implements one temperature sensor, three fan rotation speed sensors,
|
||||||
|
seven voltage sensors, VID lines, alarms, and some miscellaneous stuff.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. An alarm is triggered once
|
||||||
|
when the Overtemperature Shutdown limit is crossed; it is triggered again
|
||||||
|
as soon as it drops below the Hysteresis value. A more useful behavior
|
||||||
|
can be found by setting the Hysteresis value to +127 degrees Celsius; in
|
||||||
|
this case, alarms are issued during all the time when the actual temperature
|
||||||
|
is above the Overtemperature Shutdown value. Measurements are guaranteed
|
||||||
|
between -55 and +125 degrees, with a resolution of 1 degree.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8) to give
|
||||||
|
the readings more range or accuracy. Not all RPM values can accurately be
|
||||||
|
represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report their values in volts.
|
||||||
|
An alarm is triggered if the voltage has crossed a programmable minimum
|
||||||
|
or maximum limit. Note that minimum in this case always means 'closest to
|
||||||
|
zero'; this is important for negative voltage measurements. All voltage
|
||||||
|
inputs can measure voltages between 0 and 4.08 volts, with a resolution
|
||||||
|
of 0.016 volt.
|
||||||
|
|
||||||
|
The VID lines encode the core voltage value: the voltage level your processor
|
||||||
|
should work with. This is hardcoded by the mainboard and/or processor itself.
|
||||||
|
It is a value in volts. When it is unconnected, you will often find the
|
||||||
|
value 3.50 V here.
|
||||||
|
|
||||||
|
In addition to the alarms described above, there are a couple of additional
|
||||||
|
ones. There is a BTI alarm, which gets triggered when an external chip has
|
||||||
|
crossed its limits. Usually, this is connected to all LM75 chips; if at
|
||||||
|
least one crosses its limits, this bit gets set. The CHAS alarm triggers
|
||||||
|
if your computer case is open. The FIFO alarms should never trigger; it
|
||||||
|
indicates an internal error. The SMI_IN alarm indicates some other chip
|
||||||
|
has triggered an SMI interrupt. As we do not use SMI interrupts at all,
|
||||||
|
this condition usually indicates there is a problem with some other
|
||||||
|
device.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may
|
||||||
|
already have disappeared! Note that in the current implementation, all
|
||||||
|
hardware registers are read whenever any data is read (unless it is less
|
||||||
|
than 1.5 seconds since the last update). This means that you can easily
|
||||||
|
miss once-only alarms.
|
||||||
|
|
||||||
|
The LM7* only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values.
|
56
Documentation/i2c/chips/lm80
Normal file
56
Documentation/i2c/chips/lm80
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
Kernel driver lm80
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM80
|
||||||
|
Prefix: 'lm80'
|
||||||
|
Addresses scanned: I2C 0x28 - 0x2f
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the National Semiconductor LM80.
|
||||||
|
It is described as a 'Serial Interface ACPI-Compatible Microprocessor
|
||||||
|
System Hardware Monitor'.
|
||||||
|
|
||||||
|
The LM80 implements one temperature sensor, two fan rotation speed sensors,
|
||||||
|
seven voltage sensors, alarms, and some miscellaneous stuff.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. There are two sets of limits
|
||||||
|
which operate independently. When the HOT Temperature Limit is crossed,
|
||||||
|
this will cause an alarm that will be reasserted until the temperature
|
||||||
|
drops below the HOT Hysteresis. The Overtemperature Shutdown (OS) limits
|
||||||
|
should work in the same way (but this must be checked; the datasheet
|
||||||
|
is unclear about this). Measurements are guaranteed between -55 and
|
||||||
|
+125 degrees. The current temperature measurement has a resolution of
|
||||||
|
0.0625 degrees; the limits have a resolution of 1 degree.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8) to give
|
||||||
|
the readings more range or accuracy. Not all RPM values can accurately be
|
||||||
|
represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report their values in volts.
|
||||||
|
An alarm is triggered if the voltage has crossed a programmable minimum
|
||||||
|
or maximum limit. Note that minimum in this case always means 'closest to
|
||||||
|
zero'; this is important for negative voltage measurements. All voltage
|
||||||
|
inputs can measure voltages between 0 and 2.55 volts, with a resolution
|
||||||
|
of 0.01 volt.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may
|
||||||
|
already have disappeared! Note that in the current implementation, all
|
||||||
|
hardware registers are read whenever any data is read (unless it is less
|
||||||
|
than 2.0 seconds since the last update). This means that you can easily
|
||||||
|
miss once-only alarms.
|
||||||
|
|
||||||
|
The LM80 only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values.
|
76
Documentation/i2c/chips/lm83
Normal file
76
Documentation/i2c/chips/lm83
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
Kernel driver lm83
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM83
|
||||||
|
Prefix: 'lm83'
|
||||||
|
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/pf/LM/LM83.html
|
||||||
|
|
||||||
|
|
||||||
|
Author: Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The LM83 is a digital temperature sensor. It senses its own temperature as
|
||||||
|
well as the temperature of up to three external diodes. It is compatible
|
||||||
|
with many other devices such as the LM84 and all other ADM1021 clones.
|
||||||
|
The main difference between the LM83 and the LM84 in that the later can
|
||||||
|
only sense the temperature of one external diode.
|
||||||
|
|
||||||
|
Using the adm1021 driver for a LM83 should work, but only two temperatures
|
||||||
|
will be reported instead of four.
|
||||||
|
|
||||||
|
The LM83 is only found on a handful of motherboards. Both a confirmed
|
||||||
|
list and an unconfirmed list follow. If you can confirm or infirm the
|
||||||
|
fact that any of these motherboards do actually have an LM83, please
|
||||||
|
contact us. Note that the LM90 can easily be misdetected as a LM83.
|
||||||
|
|
||||||
|
Confirmed motherboards:
|
||||||
|
SBS P014
|
||||||
|
|
||||||
|
Unconfirmed motherboards:
|
||||||
|
Gigabyte GA-8IK1100
|
||||||
|
Iwill MPX2
|
||||||
|
Soltek SL-75DRV5
|
||||||
|
|
||||||
|
The driver has been successfully tested by Magnus Forsström, who I'd
|
||||||
|
like to thank here. More testers will be of course welcome.
|
||||||
|
|
||||||
|
The fact that the LM83 is only scarcely used can be easily explained.
|
||||||
|
Most motherboards come with more than just temperature sensors for
|
||||||
|
health monitoring. They also have voltage and fan rotation speed
|
||||||
|
sensors. This means that temperature-only chips are usually used as
|
||||||
|
secondary chips coupled with another chip such as an IT8705F or similar
|
||||||
|
chip, which provides more features. Since systems usually need three
|
||||||
|
temperature sensors (motherboard, processor, power supply) and primary
|
||||||
|
chips provide some temperature sensors, the secondary chip, if needed,
|
||||||
|
won't have to handle more than two temperatures. Thus, ADM1021 clones
|
||||||
|
are sufficient, and there is no need for a four temperatures sensor
|
||||||
|
chip such as the LM83. The only case where using an LM83 would make
|
||||||
|
sense is on SMP systems, such as the above-mentioned Iwill MPX2,
|
||||||
|
because you want an additional temperature sensor for each additional
|
||||||
|
CPU.
|
||||||
|
|
||||||
|
On the SBS P014, this is different, since the LM83 is the only hardware
|
||||||
|
monitoring chipset. One temperature sensor is used for the motherboard
|
||||||
|
(actually measuring the LM83's own temperature), one is used for the
|
||||||
|
CPU. The two other sensors must be used to measure the temperature of
|
||||||
|
two other points of the motherboard. We suspect these points to be the
|
||||||
|
north and south bridges, but this couldn't be confirmed.
|
||||||
|
|
||||||
|
All temperature values are given in degrees Celsius. Local temperature
|
||||||
|
is given within a range of 0 to +85 degrees. Remote temperatures are
|
||||||
|
given within a range of 0 to +125 degrees. Resolution is 1.0 degree,
|
||||||
|
accuracy is guaranteed to 3.0 degrees (see the datasheet for more
|
||||||
|
details).
|
||||||
|
|
||||||
|
Each sensor has its own high limit, but the critical limit is common to
|
||||||
|
all four sensors. There is no hysteresis mechanism as found on most
|
||||||
|
recent temperature sensors.
|
||||||
|
|
||||||
|
The lm83 driver will not update its values more frequently than every
|
||||||
|
other second; reading them more often will do no harm, but will return
|
||||||
|
'old' values.
|
221
Documentation/i2c/chips/lm85
Normal file
221
Documentation/i2c/chips/lm85
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
Kernel driver lm85
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM85 (B and C versions)
|
||||||
|
Prefix: 'lm85'
|
||||||
|
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
|
||||||
|
Datasheet: http://www.national.com/pf/LM/LM85.html
|
||||||
|
* Analog Devices ADM1027
|
||||||
|
Prefix: 'adm1027'
|
||||||
|
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
|
||||||
|
Datasheet: http://www.analog.com/en/prod/0,,766_825_ADM1027,00.html
|
||||||
|
* Analog Devices ADT7463
|
||||||
|
Prefix: 'adt7463'
|
||||||
|
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
|
||||||
|
Datasheet: http://www.analog.com/en/prod/0,,766_825_ADT7463,00.html
|
||||||
|
* SMSC EMC6D100, SMSC EMC6D101
|
||||||
|
Prefix: 'emc6d100'
|
||||||
|
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
|
||||||
|
Datasheet: http://www.smsc.com/main/tools/discontinued/6d100.pdf
|
||||||
|
* SMSC EMC6D102
|
||||||
|
Prefix: 'emc6d102'
|
||||||
|
Addresses scanned: I2C 0x2c, 0x2d, 0x2e
|
||||||
|
Datasheet: http://www.smsc.com/main/catalog/emc6d102.html
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Philip Pokorny <ppokorny@penguincomputing.com>,
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Richard Barrington <rich_b_nz@clear.net.nz>,
|
||||||
|
Margit Schubert-While <margitsw@t-online.de>,
|
||||||
|
Justin Thiessen <jthiessen@penguincomputing.com>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the National Semiconductor LM85 and
|
||||||
|
compatible chips including the Analog Devices ADM1027, ADT7463 and
|
||||||
|
SMSC EMC6D10x chips family.
|
||||||
|
|
||||||
|
The LM85 uses the 2-wire interface compatible with the SMBUS 2.0
|
||||||
|
specification. Using an analog to digital converter it measures three (3)
|
||||||
|
temperatures and five (5) voltages. It has four (4) 16-bit counters for
|
||||||
|
measuring fan speed. Five (5) digital inputs are provided for sampling the
|
||||||
|
VID signals from the processor to the VRM. Lastly, there are three (3) PWM
|
||||||
|
outputs that can be used to control fan speed.
|
||||||
|
|
||||||
|
The voltage inputs have internal scaling resistors so that the following
|
||||||
|
voltage can be measured without external resistors:
|
||||||
|
|
||||||
|
2.5V, 3.3V, 5V, 12V, and CPU core voltage (2.25V)
|
||||||
|
|
||||||
|
The temperatures measured are one internal diode, and two remote diodes.
|
||||||
|
Remote 1 is generally the CPU temperature. These inputs are designed to
|
||||||
|
measure a thermal diode like the one in a Pentium 4 processor in a socket
|
||||||
|
423 or socket 478 package. They can also measure temperature using a
|
||||||
|
transistor like the 2N3904.
|
||||||
|
|
||||||
|
A sophisticated control system for the PWM outputs is designed into the
|
||||||
|
LM85 that allows fan speed to be adjusted automatically based on any of the
|
||||||
|
three temperature sensors. Each PWM output is individually adjustable and
|
||||||
|
programmable. Once configured, the LM85 will adjust the PWM outputs in
|
||||||
|
response to the measured temperatures without further host intervention.
|
||||||
|
This feature can also be disabled for manual control of the PWM's.
|
||||||
|
|
||||||
|
Each of the measured inputs (voltage, temperature, fan speed) has
|
||||||
|
corresponding high/low limit values. The LM85 will signal an ALARM if any
|
||||||
|
measured value exceeds either limit.
|
||||||
|
|
||||||
|
The LM85 samples all inputs continuously. The lm85 driver will not read
|
||||||
|
the registers more often than once a second. Further, configuration data is
|
||||||
|
only read once each 5 minutes. There is twice as much config data as
|
||||||
|
measurements, so this would seem to be a worthwhile optimization.
|
||||||
|
|
||||||
|
Special Features
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The LM85 has four fan speed monitoring modes. The ADM1027 has only two.
|
||||||
|
Both have special circuitry to compensate for PWM interactions with the
|
||||||
|
TACH signal from the fans. The ADM1027 can be configured to measure the
|
||||||
|
speed of a two wire fan, but the input conditioning circuitry is different
|
||||||
|
for 3-wire and 2-wire mode. For this reason, the 2-wire fan modes are not
|
||||||
|
exposed to user control. The BIOS should initialize them to the correct
|
||||||
|
mode. If you've designed your own ADM1027, you'll have to modify the
|
||||||
|
init_client function and add an insmod parameter to set this up.
|
||||||
|
|
||||||
|
To smooth the response of fans to changes in temperature, the LM85 has an
|
||||||
|
optional filter for smoothing temperatures. The ADM1027 has the same
|
||||||
|
config option but uses it to rate limit the changes to fan speed instead.
|
||||||
|
|
||||||
|
The ADM1027 and ADT7463 have a 10-bit ADC and can therefore measure
|
||||||
|
temperatures with 0.25 degC resolution. They also provide an offset to the
|
||||||
|
temperature readings that is automatically applied during measurement.
|
||||||
|
This offset can be used to zero out any errors due to traces and placement.
|
||||||
|
The documentation says that the offset is in 0.25 degC steps, but in
|
||||||
|
initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has
|
||||||
|
confirmed this "bug". The ADT7463 is reported to work as described in the
|
||||||
|
documentation. The current lm85 driver does not show the offset register.
|
||||||
|
|
||||||
|
The ADT7463 has a THERM asserted counter. This counter has a 22.76ms
|
||||||
|
resolution and a range of 5.8 seconds. The driver implements a 32-bit
|
||||||
|
accumulator of the counter value to extend the range to over a year. The
|
||||||
|
counter will stay at it's max value until read.
|
||||||
|
|
||||||
|
See the vendor datasheets for more information. There is application note
|
||||||
|
from National (AN-1260) with some additional information about the LM85.
|
||||||
|
The Analog Devices datasheet is very detailed and describes a procedure for
|
||||||
|
determining an optimal configuration for the automatic PWM control.
|
||||||
|
|
||||||
|
The SMSC EMC6D100 & EMC6D101 monitor external voltages, temperatures, and
|
||||||
|
fan speeds. They use this monitoring capability to alert the system to out
|
||||||
|
of limit conditions and can automatically control the speeds of multiple
|
||||||
|
fans in a PC or embedded system. The EMC6D101, available in a 24-pin SSOP
|
||||||
|
package, and the EMC6D100, available in a 28-pin SSOP package, are designed
|
||||||
|
to be register compatible. The EMC6D100 offers all the features of the
|
||||||
|
EMC6D101 plus additional voltage monitoring and system control features.
|
||||||
|
Unfortunately it is not possible to distinguish between the package
|
||||||
|
versions on register level so these additional voltage inputs may read
|
||||||
|
zero. The EMC6D102 features addtional ADC bits thus extending precision
|
||||||
|
of voltage and temperature channels.
|
||||||
|
|
||||||
|
|
||||||
|
Hardware Configurations
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The LM85 can be jumpered for 3 different SMBus addresses. There are
|
||||||
|
no other hardware configuration options for the LM85.
|
||||||
|
|
||||||
|
The lm85 driver detects both LM85B and LM85C revisions of the chip. See the
|
||||||
|
datasheet for a complete description of the differences. Other than
|
||||||
|
identifying the chip, the driver behaves no differently with regard to
|
||||||
|
these two chips. The LM85B is recommended for new designs.
|
||||||
|
|
||||||
|
The ADM1027 and ADT7463 chips have an optional SMBALERT output that can be
|
||||||
|
used to signal the chipset in case a limit is exceeded or the temperature
|
||||||
|
sensors fail. Individual sensor interrupts can be masked so they won't
|
||||||
|
trigger SMBALERT. The SMBALERT output if configured replaces one of the other
|
||||||
|
functions (PWM2 or IN0). This functionality is not implemented in current
|
||||||
|
driver.
|
||||||
|
|
||||||
|
The ADT7463 also has an optional THERM output/input which can be connected
|
||||||
|
to the processor PROC_HOT output. If available, the autofan control
|
||||||
|
dynamic Tmin feature can be enabled to keep the system temperature within
|
||||||
|
spec (just?!) with the least possible fan noise.
|
||||||
|
|
||||||
|
Configuration Notes
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Besides standard interfaces driver adds following:
|
||||||
|
|
||||||
|
* Temperatures and Zones
|
||||||
|
|
||||||
|
Each temperature sensor is associated with a Zone. There are three
|
||||||
|
sensors and therefore three zones (# 1, 2 and 3). Each zone has the following
|
||||||
|
temperature configuration points:
|
||||||
|
|
||||||
|
* temp#_auto_temp_off - temperature below which fans should be off or spinning very low.
|
||||||
|
* temp#_auto_temp_min - temperature over which fans start to spin.
|
||||||
|
* temp#_auto_temp_max - temperature when fans spin at full speed.
|
||||||
|
* temp#_auto_temp_crit - temperature when all fans will run full speed.
|
||||||
|
|
||||||
|
* PWM Control
|
||||||
|
|
||||||
|
There are three PWM outputs. The LM85 datasheet suggests that the
|
||||||
|
pwm3 output control both fan3 and fan4. Each PWM can be individually
|
||||||
|
configured and assigned to a zone for it's control value. Each PWM can be
|
||||||
|
configured individually according to the following options.
|
||||||
|
|
||||||
|
* pwm#_auto_pwm_min - this specifies the PWM value for temp#_auto_temp_off
|
||||||
|
temperature. (PWM value from 0 to 255)
|
||||||
|
|
||||||
|
* pwm#_auto_pwm_freq - select base frequency of PWM output. You can select
|
||||||
|
in range of 10.0 to 94.0 Hz in .1 Hz units.
|
||||||
|
(Values 100 to 940).
|
||||||
|
|
||||||
|
The pwm#_auto_pwm_freq can be set to one of the following 8 values. Setting the
|
||||||
|
frequency to a value not on this list, will result in the next higher frequency
|
||||||
|
being selected. The actual device frequency may vary slightly from this
|
||||||
|
specification as designed by the manufacturer. Consult the datasheet for more
|
||||||
|
details. (PWM Frequency values: 100, 150, 230, 300, 380, 470, 620, 940)
|
||||||
|
|
||||||
|
* pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature
|
||||||
|
the bahaviour of fans. Write 1 to let fans spinning at
|
||||||
|
pwm#_auto_pwm_min or write 0 to let them off.
|
||||||
|
|
||||||
|
NOTE: It has been reported that there is a bug in the LM85 that causes the flag
|
||||||
|
to be associated with the zones not the PWMs. This contradicts all the
|
||||||
|
published documentation. Setting pwm#_min_ctl in this case actually affects all
|
||||||
|
PWMs controlled by zone '#'.
|
||||||
|
|
||||||
|
* PWM Controlling Zone selection
|
||||||
|
|
||||||
|
* pwm#_auto_channels - controls zone that is associated with PWM
|
||||||
|
|
||||||
|
Configuration choices:
|
||||||
|
|
||||||
|
Value Meaning
|
||||||
|
------ ------------------------------------------------
|
||||||
|
1 Controlled by Zone 1
|
||||||
|
2 Controlled by Zone 2
|
||||||
|
3 Controlled by Zone 3
|
||||||
|
23 Controlled by higher temp of Zone 2 or 3
|
||||||
|
123 Controlled by highest temp of Zone 1, 2 or 3
|
||||||
|
0 PWM always 0% (off)
|
||||||
|
-1 PWM always 100% (full on)
|
||||||
|
-2 Manual control (write to 'pwm#' to set)
|
||||||
|
|
||||||
|
The National LM85's have two vendor specific configuration
|
||||||
|
features. Tach. mode and Spinup Control. For more details on these,
|
||||||
|
see the LM85 datasheet or Application Note AN-1260.
|
||||||
|
|
||||||
|
The Analog Devices ADM1027 has several vendor specific enhancements.
|
||||||
|
The number of pulses-per-rev of the fans can be set, Tach monitoring
|
||||||
|
can be optimized for PWM operation, and an offset can be applied to
|
||||||
|
the temperatures to compensate for systemic errors in the
|
||||||
|
measurements.
|
||||||
|
|
||||||
|
In addition to the ADM1027 features, the ADT7463 also has Tmin control
|
||||||
|
and THERM asserted counts. Automatic Tmin control acts to adjust the
|
||||||
|
Tmin value to maintain the measured temperature sensor at a specified
|
||||||
|
temperature. There isn't much documentation on this feature in the
|
||||||
|
ADT7463 data sheet. This is not supported by current driver.
|
73
Documentation/i2c/chips/lm87
Normal file
73
Documentation/i2c/chips/lm87
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
Kernel driver lm87
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM87
|
||||||
|
Prefix: 'lm87'
|
||||||
|
Addresses scanned: I2C 0x2c - 0x2f
|
||||||
|
Datasheet: http://www.national.com/pf/LM/LM87.html
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>,
|
||||||
|
Mark Studebaker <mdsxyz123@yahoo.com>,
|
||||||
|
Stephen Rousset <stephen.rousset@rocketlogix.com>,
|
||||||
|
Dan Eaton <dan.eaton@rocketlogix.com>,
|
||||||
|
Jean Delvare <khali@linux-fr.org>,
|
||||||
|
Original 2.6 port Jeff Oliver
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the National Semiconductor LM87.
|
||||||
|
|
||||||
|
The LM87 implements up to three temperature sensors, up to two fan
|
||||||
|
rotation speed sensors, up to seven voltage sensors, alarms, and some
|
||||||
|
miscellaneous stuff.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. Each input has a high
|
||||||
|
and low alarm settings. A high limit produces an alarm when the value
|
||||||
|
goes above it, and an alarm is also produced when the value goes below
|
||||||
|
the low limit.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8) to give
|
||||||
|
the readings more range or accuracy. Not all RPM values can accurately be
|
||||||
|
represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report their values in
|
||||||
|
volts. An alarm is triggered if the voltage has crossed a programmable
|
||||||
|
minimum or maximum limit. Note that minimum in this case always means
|
||||||
|
'closest to zero'; this is important for negative voltage measurements.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may
|
||||||
|
already have disappeared! Note that in the current implementation, all
|
||||||
|
hardware registers are read whenever any data is read (unless it is less
|
||||||
|
than 1.0 seconds since the last update). This means that you can easily
|
||||||
|
miss once-only alarms.
|
||||||
|
|
||||||
|
The lm87 driver only updates its values each 1.0 seconds; reading it more
|
||||||
|
often will do no harm, but will return 'old' values.
|
||||||
|
|
||||||
|
|
||||||
|
Hardware Configurations
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The LM87 has four pins which can serve one of two possible functions,
|
||||||
|
depending on the hardware configuration.
|
||||||
|
|
||||||
|
Some functions share pins, so not all functions are available at the same
|
||||||
|
time. Which are depends on the hardware setup. This driver assumes that
|
||||||
|
the BIOS configured the chip correctly. In that respect, it differs from
|
||||||
|
the original driver (from lm_sensors for Linux 2.4), which would force the
|
||||||
|
LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
|
||||||
|
chipset wiring.
|
||||||
|
|
||||||
|
For reference, here is the list of exclusive functions:
|
||||||
|
- in0+in5 (default) or temp3
|
||||||
|
- fan1 (default) or in6
|
||||||
|
- fan2 (default) or in7
|
||||||
|
- VID lines (default) or IRQ lines (not handled by this driver)
|
121
Documentation/i2c/chips/lm90
Normal file
121
Documentation/i2c/chips/lm90
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
Kernel driver lm90
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM90
|
||||||
|
Prefix: 'lm90'
|
||||||
|
Addresses scanned: I2C 0x4c
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/pf/LM/LM90.html
|
||||||
|
* National Semiconductor LM89
|
||||||
|
Prefix: 'lm99'
|
||||||
|
Addresses scanned: I2C 0x4c and 0x4d
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/pf/LM/LM89.html
|
||||||
|
* National Semiconductor LM99
|
||||||
|
Prefix: 'lm99'
|
||||||
|
Addresses scanned: I2C 0x4c and 0x4d
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/pf/LM/LM99.html
|
||||||
|
* National Semiconductor LM86
|
||||||
|
Prefix: 'lm86'
|
||||||
|
Addresses scanned: I2C 0x4c
|
||||||
|
Datasheet: Publicly available at the National Semiconductor website
|
||||||
|
http://www.national.com/pf/LM/LM86.html
|
||||||
|
* Analog Devices ADM1032
|
||||||
|
Prefix: 'adm1032'
|
||||||
|
Addresses scanned: I2C 0x4c
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
http://products.analog.com/products/info.asp?product=ADM1032
|
||||||
|
* Analog Devices ADT7461
|
||||||
|
Prefix: 'adt7461'
|
||||||
|
Addresses scanned: I2C 0x4c
|
||||||
|
Datasheet: Publicly available at the Analog Devices website
|
||||||
|
http://products.analog.com/products/info.asp?product=ADT7461
|
||||||
|
Note: Only if in ADM1032 compatibility mode
|
||||||
|
* Maxim MAX6657
|
||||||
|
Prefix: 'max6657'
|
||||||
|
Addresses scanned: I2C 0x4c
|
||||||
|
Datasheet: Publicly available at the Maxim website
|
||||||
|
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
|
||||||
|
* Maxim MAX6658
|
||||||
|
Prefix: 'max6657'
|
||||||
|
Addresses scanned: I2C 0x4c
|
||||||
|
Datasheet: Publicly available at the Maxim website
|
||||||
|
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
|
||||||
|
* Maxim MAX6659
|
||||||
|
Prefix: 'max6657'
|
||||||
|
Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e)
|
||||||
|
Datasheet: Publicly available at the Maxim website
|
||||||
|
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
|
||||||
|
|
||||||
|
|
||||||
|
Author: Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The LM90 is a digital temperature sensor. It senses its own temperature as
|
||||||
|
well as the temperature of up to one external diode. It is compatible
|
||||||
|
with many other devices such as the LM86, the LM89, the LM99, the ADM1032,
|
||||||
|
the MAX6657, MAX6658 and the MAX6659 all of which are supported by this driver.
|
||||||
|
Note that there is no easy way to differentiate between the last three
|
||||||
|
variants. The extra address and features of the MAX6659 are not supported by
|
||||||
|
this driver. Additionally, the ADT7461 is supported if found in ADM1032
|
||||||
|
compatibility mode.
|
||||||
|
|
||||||
|
The specificity of this family of chipsets over the ADM1021/LM84
|
||||||
|
family is that it features critical limits with hysteresis, and an
|
||||||
|
increased resolution of the remote temperature measurement.
|
||||||
|
|
||||||
|
The different chipsets of the family are not strictly identical, although
|
||||||
|
very similar. This driver doesn't handle any specific feature for now,
|
||||||
|
but could if there ever was a need for it. For reference, here comes a
|
||||||
|
non-exhaustive list of specific features:
|
||||||
|
|
||||||
|
LM90:
|
||||||
|
* Filter and alert configuration register at 0xBF.
|
||||||
|
* ALERT is triggered by temperatures over critical limits.
|
||||||
|
|
||||||
|
LM86 and LM89:
|
||||||
|
* Same as LM90
|
||||||
|
* Better external channel accuracy
|
||||||
|
|
||||||
|
LM99:
|
||||||
|
* Same as LM89
|
||||||
|
* External temperature shifted by 16 degrees down
|
||||||
|
|
||||||
|
ADM1032:
|
||||||
|
* Consecutive alert register at 0x22.
|
||||||
|
* Conversion averaging.
|
||||||
|
* Up to 64 conversions/s.
|
||||||
|
* ALERT is triggered by open remote sensor.
|
||||||
|
|
||||||
|
ADT7461
|
||||||
|
* Extended temperature range (breaks compatibility)
|
||||||
|
* Lower resolution for remote temperature
|
||||||
|
|
||||||
|
MAX6657 and MAX6658:
|
||||||
|
* Remote sensor type selection
|
||||||
|
|
||||||
|
MAX6659
|
||||||
|
* Selectable address
|
||||||
|
* Second critical temperature limit
|
||||||
|
* Remote sensor type selection
|
||||||
|
|
||||||
|
All temperature values are given in degrees Celsius. Resolution
|
||||||
|
is 1.0 degree for the local temperature, 0.125 degree for the remote
|
||||||
|
temperature.
|
||||||
|
|
||||||
|
Each sensor has its own high and low limits, plus a critical limit.
|
||||||
|
Additionally, there is a relative hysteresis value common to both critical
|
||||||
|
values. To make life easier to user-space applications, two absolute values
|
||||||
|
are exported, one for each channel, but these values are of course linked.
|
||||||
|
Only the local hysteresis can be set from user-space, and the same delta
|
||||||
|
applies to the remote hysteresis.
|
||||||
|
|
||||||
|
The lm90 driver will not update its values more frequently than every
|
||||||
|
other second; reading them more often will do no harm, but will return
|
||||||
|
'old' values.
|
||||||
|
|
37
Documentation/i2c/chips/lm92
Normal file
37
Documentation/i2c/chips/lm92
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
Kernel driver lm92
|
||||||
|
==================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor LM92
|
||||||
|
Prefix: 'lm92'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4b
|
||||||
|
Datasheet: http://www.national.com/pf/LM/LM92.html
|
||||||
|
* National Semiconductor LM76
|
||||||
|
Prefix: 'lm92'
|
||||||
|
Addresses scanned: none, force parameter needed
|
||||||
|
Datasheet: http://www.national.com/pf/LM/LM76.html
|
||||||
|
* Maxim MAX6633/MAX6634/MAX6635
|
||||||
|
Prefix: 'lm92'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4b
|
||||||
|
MAX6633 with address in 0x40 - 0x47, 0x4c - 0x4f needs force parameter
|
||||||
|
and MAX6634 with address in 0x4c - 0x4f needs force parameter
|
||||||
|
Datasheet: http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3074
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Abraham van der Merwe <abraham@2d3d.co.za>
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the National Semiconductor LM92
|
||||||
|
temperature sensor.
|
||||||
|
|
||||||
|
Each LM92 temperature sensor supports a single temperature sensor. There are
|
||||||
|
alarms for high, low, and critical thresholds. There's also an hysteresis to
|
||||||
|
control the thresholds for resetting alarms.
|
||||||
|
|
||||||
|
Support was added later for the LM76 and Maxim MAX6633/MAX6634/MAX6635,
|
||||||
|
which are mostly compatible. They have not all been tested, so you
|
||||||
|
may need to use the force parameter.
|
29
Documentation/i2c/chips/max1619
Normal file
29
Documentation/i2c/chips/max1619
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
Kernel driver max1619
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Maxim MAX1619
|
||||||
|
Prefix: 'max1619'
|
||||||
|
Addresses scanned: I2C 0x18-0x1a, 0x29-0x2b, 0x4c-0x4e
|
||||||
|
Datasheet: Publicly available at the Maxim website
|
||||||
|
http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Alexey Fisher <fishor@mail.ru>,
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The MAX1619 is a digital temperature sensor. It senses its own temperature as
|
||||||
|
well as the temperature of up to one external diode.
|
||||||
|
|
||||||
|
All temperature values are given in degrees Celsius. Resolution
|
||||||
|
is 1.0 degree for the local temperature and for the remote temperature.
|
||||||
|
|
||||||
|
Only the external sensor has high and low limits.
|
||||||
|
|
||||||
|
The max1619 driver will not update its values more frequently than every
|
||||||
|
other second; reading them more often will do no harm, but will return
|
||||||
|
'old' values.
|
||||||
|
|
54
Documentation/i2c/chips/max6875
Normal file
54
Documentation/i2c/chips/max6875
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
Kernel driver max6875
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Maxim max6874, max6875
|
||||||
|
Prefixes: 'max6875'
|
||||||
|
Addresses scanned: 0x50, 0x52
|
||||||
|
Datasheets:
|
||||||
|
http://pdfserv.maxim-ic.com/en/ds/MAX6874-MAX6875.pdf
|
||||||
|
|
||||||
|
Author: Ben Gardner <bgardner@wabtec.com>
|
||||||
|
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* allow_write int
|
||||||
|
Set to non-zero to enable write permission:
|
||||||
|
*0: Read only
|
||||||
|
1: Read and write
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The MAXIM max6875 is a EEPROM-programmable power-supply sequencer/supervisor.
|
||||||
|
It provides timed outputs that can be used as a watchdog, if properly wired.
|
||||||
|
It also provides 512 bytes of user EEPROM.
|
||||||
|
|
||||||
|
At reset, the max6875 reads the configuration eeprom into its configuration
|
||||||
|
registers. The chip then begins to operate according to the values in the
|
||||||
|
registers.
|
||||||
|
|
||||||
|
See the datasheet for details on how to program the EEPROM.
|
||||||
|
|
||||||
|
|
||||||
|
Sysfs entries
|
||||||
|
-------------
|
||||||
|
|
||||||
|
eeprom_user - 512 bytes of user-defined EEPROM space. Only writable if
|
||||||
|
allow_write was set and register 0x43 is 0.
|
||||||
|
|
||||||
|
eeprom_config - 70 bytes of config EEPROM. Note that changes will not get
|
||||||
|
loaded into register space until a power cycle or device reset.
|
||||||
|
|
||||||
|
reg_config - 70 bytes of register space. Any changes take affect immediately.
|
||||||
|
|
||||||
|
|
||||||
|
General Remarks
|
||||||
|
---------------
|
||||||
|
|
||||||
|
A typical application will require that the EEPROMs be programmed once and
|
||||||
|
never altered afterwards.
|
||||||
|
|
189
Documentation/i2c/chips/pc87360
Normal file
189
Documentation/i2c/chips/pc87360
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
Kernel driver pc87360
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* National Semiconductor PC87360, PC87363, PC87364, PC87365 and PC87366
|
||||||
|
Prefixes: 'pc87360', 'pc87363', 'pc87364', 'pc87365', 'pc87366'
|
||||||
|
Addresses scanned: none, address read from Super I/O config space
|
||||||
|
Datasheets:
|
||||||
|
http://www.national.com/pf/PC/PC87360.html
|
||||||
|
http://www.national.com/pf/PC/PC87363.html
|
||||||
|
http://www.national.com/pf/PC/PC87364.html
|
||||||
|
http://www.national.com/pf/PC/PC87365.html
|
||||||
|
http://www.national.com/pf/PC/PC87366.html
|
||||||
|
|
||||||
|
Authors: Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Thanks to Sandeep Mehta, Tonko de Rooy and Daniel Ceregatti for testing.
|
||||||
|
Thanks to Rudolf Marek for helping me investigate conversion issues.
|
||||||
|
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* init int
|
||||||
|
Chip initialization level:
|
||||||
|
0: None
|
||||||
|
*1: Forcibly enable internal voltage and temperature channels, except in9
|
||||||
|
2: Forcibly enable all voltage and temperature channels, except in9
|
||||||
|
3: Forcibly enable all voltage and temperature channels, including in9
|
||||||
|
|
||||||
|
Note that this parameter has no effect for the PC87360, PC87363 and PC87364
|
||||||
|
chips.
|
||||||
|
|
||||||
|
Also note that for the PC87366, initialization levels 2 and 3 don't enable
|
||||||
|
all temperature channels, because some of them share pins with each other,
|
||||||
|
so they can't be used at the same time.
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The National Semiconductor PC87360 Super I/O chip contains monitoring and
|
||||||
|
PWM control circuitry for two fans. The PC87363 chip is similar, and the
|
||||||
|
PC87364 chip has monitoring and PWM control for a third fan.
|
||||||
|
|
||||||
|
The National Semiconductor PC87365 and PC87366 Super I/O chips are complete
|
||||||
|
hardware monitoring chipsets, not only controlling and monitoring three fans,
|
||||||
|
but also monitoring eleven voltage inputs and two (PC87365) or up to four
|
||||||
|
(PC87366) temperatures.
|
||||||
|
|
||||||
|
Chip #vin #fan #pwm #temp devid
|
||||||
|
|
||||||
|
PC87360 - 2 2 - 0xE1
|
||||||
|
PC87363 - 2 2 - 0xE8
|
||||||
|
PC87364 - 3 3 - 0xE4
|
||||||
|
PC87365 11 3 3 2 0xE5
|
||||||
|
PC87366 11 3 3 3-4 0xE9
|
||||||
|
|
||||||
|
The driver assumes that no more than one chip is present, and one of the
|
||||||
|
standard Super I/O addresses is used (0x2E/0x2F or 0x4E/0x4F)
|
||||||
|
|
||||||
|
Fan Monitoring
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (revolutions per minute). An alarm
|
||||||
|
is triggered if the rotation speed has dropped below a programmable limit.
|
||||||
|
A different alarm is triggered if the fan speed is too low to be measured.
|
||||||
|
|
||||||
|
Fan readings are affected by a programmable clock divider, giving the
|
||||||
|
readings more range or accuracy. Usually, users have to learn how it works,
|
||||||
|
but this driver implements dynamic clock divider selection, so you don't
|
||||||
|
have to care no more.
|
||||||
|
|
||||||
|
For reference, here are a few values about clock dividers:
|
||||||
|
|
||||||
|
slowest accuracy highest
|
||||||
|
measurable around 3000 accurate
|
||||||
|
divider speed (RPM) RPM (RPM) speed (RPM)
|
||||||
|
1 1882 18 6928
|
||||||
|
2 941 37 4898
|
||||||
|
4 470 74 3464
|
||||||
|
8 235 150 2449
|
||||||
|
|
||||||
|
For the curious, here is how the values above were computed:
|
||||||
|
* slowest measurable speed: clock/(255*divider)
|
||||||
|
* accuracy around 3000 RPM: 3000^2/clock
|
||||||
|
* highest accurate speed: sqrt(clock*100)
|
||||||
|
The clock speed for the PC87360 family is 480 kHz. I arbitrarily chose 100
|
||||||
|
RPM as the lowest acceptable accuracy.
|
||||||
|
|
||||||
|
As mentioned above, you don't have to care about this no more.
|
||||||
|
|
||||||
|
Note that not all RPM values can be represented, even when the best clock
|
||||||
|
divider is selected. This is not only true for the measured speeds, but
|
||||||
|
also for the programmable low limits, so don't be surprised if you try to
|
||||||
|
set, say, fan1_min to 2900 and it finally reads 2909.
|
||||||
|
|
||||||
|
|
||||||
|
Fan Control
|
||||||
|
-----------
|
||||||
|
|
||||||
|
PWM (pulse width modulation) values range from 0 to 255, with 0 meaning
|
||||||
|
that the fan is stopped, and 255 meaning that the fan goes at full speed.
|
||||||
|
|
||||||
|
Be extremely careful when changing PWM values. Low PWM values, even
|
||||||
|
non-zero, can stop the fan, which may cause irreversible damage to your
|
||||||
|
hardware if temperature increases too much. When changing PWM values, go
|
||||||
|
step by step and keep an eye on temperatures.
|
||||||
|
|
||||||
|
One user reported problems with PWM. Changing PWM values would break fan
|
||||||
|
speed readings. No explanation nor fix could be found.
|
||||||
|
|
||||||
|
|
||||||
|
Temperature Monitoring
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Temperatures are reported in degrees Celsius. Each temperature measured has
|
||||||
|
associated low, high and overtemperature limits, each of which triggers an
|
||||||
|
alarm when crossed.
|
||||||
|
|
||||||
|
The first two temperature channels are external. The third one (PC87366
|
||||||
|
only) is internal.
|
||||||
|
|
||||||
|
The PC87366 has three additional temperature channels, based on
|
||||||
|
thermistors (as opposed to thermal diodes for the first three temperature
|
||||||
|
channels). For technical reasons, these channels are held by the VLM
|
||||||
|
(voltage level monitor) logical device, not the TMS (temperature
|
||||||
|
measurement) one. As a consequence, these temperatures are exported as
|
||||||
|
voltages, and converted into temperatures in user-space.
|
||||||
|
|
||||||
|
Note that these three additional channels share their pins with the
|
||||||
|
external thermal diode channels, so you (physically) can't use them all at
|
||||||
|
the same time. Although it should be possible to mix the two sensor types,
|
||||||
|
the documents from National Semiconductor suggest that motherboard
|
||||||
|
manufacturers should choose one type and stick to it. So you will more
|
||||||
|
likely have either channels 1 to 3 (thermal diodes) or 3 to 6 (internal
|
||||||
|
thermal diode, and thermistors).
|
||||||
|
|
||||||
|
|
||||||
|
Voltage Monitoring
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Voltages are reported relatively to a reference voltage, either internal or
|
||||||
|
external. Some of them (in7:Vsb, in8:Vdd and in10:AVdd) are divided by two
|
||||||
|
internally, you will have to compensate in sensors.conf. Others (in0 to in6)
|
||||||
|
are likely to be divided externally. The meaning of each of these inputs as
|
||||||
|
well as the values of the resistors used for division is left to the
|
||||||
|
motherboard manufacturers, so you will have to document yourself and edit
|
||||||
|
sensors.conf accordingly. National Semiconductor has a document with
|
||||||
|
recommended resistor values for some voltages, but this still leaves much
|
||||||
|
room for per motherboard specificities, unfortunately. Even worse,
|
||||||
|
motherboard manufacturers don't seem to care about National Semiconductor's
|
||||||
|
recommendations.
|
||||||
|
|
||||||
|
Each voltage measured has associated low and high limits, each of which
|
||||||
|
triggers an alarm when crossed.
|
||||||
|
|
||||||
|
When available, VID inputs are used to provide the nominal CPU Core voltage.
|
||||||
|
The driver will default to VRM 9.0, but this can be changed from user-space.
|
||||||
|
The chipsets can handle two sets of VID inputs (on dual-CPU systems), but
|
||||||
|
the driver will only export one for now. This may change later if there is
|
||||||
|
a need.
|
||||||
|
|
||||||
|
|
||||||
|
General Remarks
|
||||||
|
---------------
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may already
|
||||||
|
have disappeared! Note that all hardware registers are read whenever any
|
||||||
|
data is read (unless it is less than 2 seconds since the last update, in
|
||||||
|
which case cached values are returned instead). As a consequence, when
|
||||||
|
a once-only alarm triggers, it may take 2 seconds for it to show, and 2
|
||||||
|
more seconds for it to disappear.
|
||||||
|
|
||||||
|
Monitoring of in9 isn't enabled at lower init levels (<3) because that
|
||||||
|
channel measures the battery voltage (Vbat). It is a known fact that
|
||||||
|
repeatedly sampling the battery voltage reduces its lifetime. National
|
||||||
|
Semiconductor smartly designed their chipset so that in9 is sampled only
|
||||||
|
once every 1024 sampling cycles (that is every 34 minutes at the default
|
||||||
|
sampling rate), so the effect is attenuated, but still present.
|
||||||
|
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The datasheets suggests that some values (fan mins, fan dividers)
|
||||||
|
shouldn't be changed once the monitoring has started, but we ignore that
|
||||||
|
recommendation. We'll reconsider if it actually causes trouble.
|
47
Documentation/i2c/chips/pca9539
Normal file
47
Documentation/i2c/chips/pca9539
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
Kernel driver pca9539
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Philips PCA9539
|
||||||
|
Prefix: 'pca9539'
|
||||||
|
Addresses scanned: 0x74 - 0x77
|
||||||
|
Datasheet:
|
||||||
|
http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf
|
||||||
|
|
||||||
|
Author: Ben Gardner <bgardner@wabtec.com>
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The Philips PCA9539 is a 16 bit low power I/O device.
|
||||||
|
All 16 lines can be individually configured as an input or output.
|
||||||
|
The input sense can also be inverted.
|
||||||
|
The 16 lines are split between two bytes.
|
||||||
|
|
||||||
|
|
||||||
|
Sysfs entries
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Each is a byte that maps to the 8 I/O bits.
|
||||||
|
A '0' suffix is for bits 0-7, while '1' is for bits 8-15.
|
||||||
|
|
||||||
|
input[01] - read the current value
|
||||||
|
output[01] - sets the output value
|
||||||
|
direction[01] - direction of each bit: 1=input, 0=output
|
||||||
|
invert[01] - toggle the input bit sense
|
||||||
|
|
||||||
|
input reads the actual state of the line and is always available.
|
||||||
|
The direction defaults to input for all channels.
|
||||||
|
|
||||||
|
|
||||||
|
General Remarks
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Note that each output, direction, and invert entry controls 8 lines.
|
||||||
|
You should use the read, modify, write sequence.
|
||||||
|
For example. to set output bit 0 of 1.
|
||||||
|
val=$(cat output0)
|
||||||
|
val=$(( $val | 1 ))
|
||||||
|
echo $val > output0
|
||||||
|
|
69
Documentation/i2c/chips/pcf8574
Normal file
69
Documentation/i2c/chips/pcf8574
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
Kernel driver pcf8574
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Philips PCF8574
|
||||||
|
Prefix: 'pcf8574'
|
||||||
|
Addresses scanned: I2C 0x20 - 0x27
|
||||||
|
Datasheet: Publicly available at the Philips Semiconductors website
|
||||||
|
http://www.semiconductors.philips.com/pip/PCF8574P.html
|
||||||
|
|
||||||
|
* Philips PCF8574A
|
||||||
|
Prefix: 'pcf8574a'
|
||||||
|
Addresses scanned: I2C 0x38 - 0x3f
|
||||||
|
Datasheet: Publicly available at the Philips Semiconductors website
|
||||||
|
http://www.semiconductors.philips.com/pip/PCF8574P.html
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>,
|
||||||
|
Dan Eaton <dan.eaton@rocketlogix.com>,
|
||||||
|
Aurelien Jarno <aurelien@aurel32.net>,
|
||||||
|
Jean Delvare <khali@linux-fr.org>,
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
The PCF8574(A) is an 8-bit I/O expander for the I2C bus produced by Philips
|
||||||
|
Semiconductors. It is designed to provide a byte I2C interface to up to 16
|
||||||
|
separate devices (8 x PCF8574 and 8 x PCF8574A).
|
||||||
|
|
||||||
|
This device consists of a quasi-bidirectional port. Each of the eight I/Os
|
||||||
|
can be independently used as an input or output. To setup an I/O as an
|
||||||
|
input, you have to write a 1 to the corresponding output.
|
||||||
|
|
||||||
|
For more informations see the datasheet.
|
||||||
|
|
||||||
|
|
||||||
|
Accessing PCF8574(A) via /sys interface
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
! Be careful !
|
||||||
|
The PCF8574(A) is plainly impossible to detect ! Stupid chip.
|
||||||
|
So every chip with address in the interval [20..27] and [38..3f] are
|
||||||
|
detected as PCF8574(A). If you have other chips in this address
|
||||||
|
range, the workaround is to load this module after the one
|
||||||
|
for your others chips.
|
||||||
|
|
||||||
|
On detection (i.e. insmod, modprobe et al.), directories are being
|
||||||
|
created for each detected PCF8574(A):
|
||||||
|
|
||||||
|
/sys/bus/i2c/devices/<0>-<1>/
|
||||||
|
where <0> is the bus the chip was detected on (e. g. i2c-0)
|
||||||
|
and <1> the chip address ([20..27] or [38..3f]):
|
||||||
|
|
||||||
|
(example: /sys/bus/i2c/devices/1-0020/)
|
||||||
|
|
||||||
|
Inside these directories, there are two files each:
|
||||||
|
read and write (and one file with chip name).
|
||||||
|
|
||||||
|
The read file is read-only. Reading gives you the current I/O input
|
||||||
|
if the corresponding output is set as 1, otherwise the current output
|
||||||
|
value, that is to say 0.
|
||||||
|
|
||||||
|
The write file is read/write. Writing a value outputs it on the I/O
|
||||||
|
port. Reading returns the last written value.
|
||||||
|
|
||||||
|
On module initialization the chip is configured as eight inputs (all
|
||||||
|
outputs to 1), so you can connect any circuit to the PCF8574(A) without
|
||||||
|
being afraid of short-circuit.
|
90
Documentation/i2c/chips/pcf8591
Normal file
90
Documentation/i2c/chips/pcf8591
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
Kernel driver pcf8591
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Philips PCF8591
|
||||||
|
Prefix: 'pcf8591'
|
||||||
|
Addresses scanned: I2C 0x48 - 0x4f
|
||||||
|
Datasheet: Publicly available at the Philips Semiconductor website
|
||||||
|
http://www.semiconductors.philips.com/pip/PCF8591P.html
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Aurelien Jarno <aurelien@aurel32.net>
|
||||||
|
valuable contributions by Jan M. Sendler <sendler@sendler.de>,
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
|
||||||
|
analog output) for the I2C bus produced by Philips Semiconductors. It
|
||||||
|
is designed to provide a byte I2C interface to up to 4 separate devices.
|
||||||
|
|
||||||
|
The PCF8591 has 4 analog inputs programmable as single-ended or
|
||||||
|
differential inputs :
|
||||||
|
- mode 0 : four single ended inputs
|
||||||
|
Pins AIN0 to AIN3 are single ended inputs for channels 0 to 3
|
||||||
|
|
||||||
|
- mode 1 : three differential inputs
|
||||||
|
Pins AIN3 is the common negative differential input
|
||||||
|
Pins AIN0 to AIN2 are positive differential inputs for channels 0 to 2
|
||||||
|
|
||||||
|
- mode 2 : single ended and differential mixed
|
||||||
|
Pins AIN0 and AIN1 are single ended inputs for channels 0 and 1
|
||||||
|
Pins AIN2 is the positive differential input for channel 3
|
||||||
|
Pins AIN3 is the negative differential input for channel 3
|
||||||
|
|
||||||
|
- mode 3 : two differential inputs
|
||||||
|
Pins AIN0 is the positive differential input for channel 0
|
||||||
|
Pins AIN1 is the negative differential input for channel 0
|
||||||
|
Pins AIN2 is the positive differential input for channel 1
|
||||||
|
Pins AIN3 is the negative differential input for channel 1
|
||||||
|
|
||||||
|
See the datasheet for details.
|
||||||
|
|
||||||
|
Module parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* input_mode int
|
||||||
|
|
||||||
|
Analog input mode:
|
||||||
|
0 = four single ended inputs
|
||||||
|
1 = three differential inputs
|
||||||
|
2 = single ended and differential mixed
|
||||||
|
3 = two differential inputs
|
||||||
|
|
||||||
|
|
||||||
|
Accessing PCF8591 via /sys interface
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
! Be careful !
|
||||||
|
The PCF8591 is plainly impossible to detect ! Stupid chip.
|
||||||
|
So every chip with address in the interval [48..4f] is
|
||||||
|
detected as PCF8591. If you have other chips in this address
|
||||||
|
range, the workaround is to load this module after the one
|
||||||
|
for your others chips.
|
||||||
|
|
||||||
|
On detection (i.e. insmod, modprobe et al.), directories are being
|
||||||
|
created for each detected PCF8591:
|
||||||
|
|
||||||
|
/sys/bus/devices/<0>-<1>/
|
||||||
|
where <0> is the bus the chip was detected on (e. g. i2c-0)
|
||||||
|
and <1> the chip address ([48..4f])
|
||||||
|
|
||||||
|
Inside these directories, there are such files:
|
||||||
|
in0, in1, in2, in3, out0_enable, out0_output, name
|
||||||
|
|
||||||
|
Name contains chip name.
|
||||||
|
|
||||||
|
The in0, in1, in2 and in3 files are RO. Reading gives the value of the
|
||||||
|
corresponding channel. Depending on the current analog inputs configuration,
|
||||||
|
files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
|
||||||
|
ended inputs and -128 to +127 for differential inputs (8-bit ADC).
|
||||||
|
|
||||||
|
The out0_enable file is RW. Reading gives "1" for analog output enabled and
|
||||||
|
"0" for analog output disabled. Writing accepts "0" and "1" accordingly.
|
||||||
|
|
||||||
|
The out0_output file is RW. Writing a number between 0 and 255 (8-bit DAC), send
|
||||||
|
the value to the digital-to-analog converter. Note that a voltage will
|
||||||
|
only appears on AOUT pin if aout0_enable equals 1. Reading returns the last
|
||||||
|
value written.
|
106
Documentation/i2c/chips/sis5595
Normal file
106
Documentation/i2c/chips/sis5595
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
Kernel driver sis5595
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Silicon Integrated Systems Corp. SiS5595 Southbridge Hardware Monitor
|
||||||
|
Prefix: 'sis5595'
|
||||||
|
Addresses scanned: ISA in PCI-space encoded address
|
||||||
|
Datasheet: Publicly available at the Silicon Integrated Systems Corp. site.
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Kyösti Mälkki <kmalkki@cc.hut.fi>,
|
||||||
|
Mark D. Studebaker <mdsxyz123@yahoo.com>,
|
||||||
|
Aurelien Jarno <aurelien@aurel32.net> 2.6 port
|
||||||
|
|
||||||
|
SiS southbridge has a LM78-like chip integrated on the same IC.
|
||||||
|
This driver is a customized copy of lm78.c
|
||||||
|
|
||||||
|
Supports following revisions:
|
||||||
|
Version PCI ID PCI Revision
|
||||||
|
1 1039/0008 AF or less
|
||||||
|
2 1039/0008 B0 or greater
|
||||||
|
|
||||||
|
Note: these chips contain a 0008 device which is incompatible with the
|
||||||
|
5595. We recognize these by the presence of the listed
|
||||||
|
"blacklist" PCI ID and refuse to load.
|
||||||
|
|
||||||
|
NOT SUPPORTED PCI ID BLACKLIST PCI ID
|
||||||
|
540 0008 0540
|
||||||
|
550 0008 0550
|
||||||
|
5513 0008 5511
|
||||||
|
5581 0008 5597
|
||||||
|
5582 0008 5597
|
||||||
|
5597 0008 5597
|
||||||
|
630 0008 0630
|
||||||
|
645 0008 0645
|
||||||
|
730 0008 0730
|
||||||
|
735 0008 0735
|
||||||
|
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
force_addr=0xaddr Set the I/O base address. Useful for boards
|
||||||
|
that don't set the address in the BIOS. Does not do a
|
||||||
|
PCI force; the device must still be present in lspci.
|
||||||
|
Don't use this unless the driver complains that the
|
||||||
|
base address is not set.
|
||||||
|
Example: 'modprobe sis5595 force_addr=0x290'
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The SiS5595 southbridge has integrated hardware monitor functions. It also
|
||||||
|
has an I2C bus, but this driver only supports the hardware monitor. For the
|
||||||
|
I2C bus driver see i2c-sis5595.
|
||||||
|
|
||||||
|
The SiS5595 implements zero or one temperature sensor, two fan speed
|
||||||
|
sensors, four or five voltage sensors, and alarms.
|
||||||
|
|
||||||
|
On the first version of the chip, there are four voltage sensors and one
|
||||||
|
temperature sensor.
|
||||||
|
|
||||||
|
On the second version of the chip, the temperature sensor (temp) and the
|
||||||
|
fifth voltage sensor (in4) share a pin which is configurable, but not
|
||||||
|
through the driver. Sorry. The driver senses the configuration of the pin,
|
||||||
|
which was hopefully set by the BIOS.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. An alarm is triggered once
|
||||||
|
when the max is crossed; it is also triggered when it drops below the min
|
||||||
|
value. Measurements are guaranteed between -55 and +125 degrees, with a
|
||||||
|
resolution of 1 degree.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8) to give
|
||||||
|
the readings more range or accuracy. Not all RPM values can accurately be
|
||||||
|
represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report their values in volts. An
|
||||||
|
alarm is triggered if the voltage has crossed a programmable minimum or
|
||||||
|
maximum limit. Note that minimum in this case always means 'closest to
|
||||||
|
zero'; this is important for negative voltage measurements. All voltage
|
||||||
|
inputs can measure voltages between 0 and 4.08 volts, with a resolution of
|
||||||
|
0.016 volt.
|
||||||
|
|
||||||
|
In addition to the alarms described above, there is a BTI alarm, which gets
|
||||||
|
triggered when an external chip has crossed its limits. Usually, this is
|
||||||
|
connected to some LM75-like chip; if at least one crosses its limits, this
|
||||||
|
bit gets set.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may already
|
||||||
|
have disappeared! Note that in the current implementation, all hardware
|
||||||
|
registers are read whenever any data is read (unless it is less than 1.5
|
||||||
|
seconds since the last update). This means that you can easily miss
|
||||||
|
once-only alarms.
|
||||||
|
|
||||||
|
The SiS5595 only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values.
|
||||||
|
|
||||||
|
Problems
|
||||||
|
--------
|
||||||
|
Some chips refuse to be enabled. We don't know why.
|
||||||
|
The driver will recognize this and print a message in dmesg.
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
|
Kernel driver smsc47b397
|
||||||
|
========================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* SMSC LPC47B397-NC
|
||||||
|
Prefix: 'smsc47b397'
|
||||||
|
Addresses scanned: none, address read from Super I/O config space
|
||||||
|
Datasheet: In this file
|
||||||
|
|
||||||
|
Authors: Mark M. Hoffman <mhoffman@lightlink.com>
|
||||||
|
Utilitek Systems, Inc.
|
||||||
|
|
||||||
November 23, 2004
|
November 23, 2004
|
||||||
|
|
||||||
The following specification describes the SMSC LPC47B397-NC sensor chip
|
The following specification describes the SMSC LPC47B397-NC sensor chip
|
||||||
(for which there is no public datasheet available). This document was
|
(for which there is no public datasheet available). This document was
|
||||||
provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected
|
provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected
|
||||||
by Mark M. Hoffman <mhoffman@lightlink.com>.
|
by Mark M. Hoffman <mhoffman@lightlink.com>.
|
||||||
|
|
||||||
|
@ -10,10 +22,10 @@ by Mark M. Hoffman <mhoffman@lightlink.com>.
|
||||||
Methods for detecting the HP SIO and reading the thermal data on a dc7100.
|
Methods for detecting the HP SIO and reading the thermal data on a dc7100.
|
||||||
|
|
||||||
The thermal information on the dc7100 is contained in the SIO Hardware Monitor
|
The thermal information on the dc7100 is contained in the SIO Hardware Monitor
|
||||||
(HWM). The information is accessed through an index/data pair. The index/data
|
(HWM). The information is accessed through an index/data pair. The index/data
|
||||||
pair is located at the HWM Base Address + 0 and the HWM Base Address + 1. The
|
pair is located at the HWM Base Address + 0 and the HWM Base Address + 1. The
|
||||||
HWM Base address can be obtained from Logical Device 8, registers 0x60 (MSB)
|
HWM Base address can be obtained from Logical Device 8, registers 0x60 (MSB)
|
||||||
and 0x61 (LSB). Currently we are using 0x480 for the HWM Base Address and
|
and 0x61 (LSB). Currently we are using 0x480 for the HWM Base Address and
|
||||||
0x480 and 0x481 for the index/data pair.
|
0x480 and 0x481 for the index/data pair.
|
||||||
|
|
||||||
Reading temperature information.
|
Reading temperature information.
|
||||||
|
@ -50,7 +62,7 @@ Reading the tach LSB locks the tach MSB.
|
||||||
The LSB Must be read first.
|
The LSB Must be read first.
|
||||||
|
|
||||||
How to convert the tach reading to RPM.
|
How to convert the tach reading to RPM.
|
||||||
The tach reading (TCount) is given by: (Tach MSB * 256) + (Tach LSB)
|
The tach reading (TCount) is given by: (Tach MSB * 256) + (Tach LSB)
|
||||||
The SIO counts the number of 90kHz (11.111us) pulses per revolution.
|
The SIO counts the number of 90kHz (11.111us) pulses per revolution.
|
||||||
RPM = 60/(TCount * 11.111us)
|
RPM = 60/(TCount * 11.111us)
|
||||||
|
|
||||||
|
@ -72,20 +84,20 @@ To program the configuration registers, the following sequence must be followed:
|
||||||
|
|
||||||
Enter Configuration Mode
|
Enter Configuration Mode
|
||||||
To place the chip into the Configuration State The config key (0x55) is written
|
To place the chip into the Configuration State The config key (0x55) is written
|
||||||
to the CONFIG PORT (0x2E).
|
to the CONFIG PORT (0x2E).
|
||||||
|
|
||||||
Configuration Mode
|
Configuration Mode
|
||||||
In configuration mode, the INDEX PORT is located at the CONFIG PORT address and
|
In configuration mode, the INDEX PORT is located at the CONFIG PORT address and
|
||||||
the DATA PORT is at INDEX PORT address + 1.
|
the DATA PORT is at INDEX PORT address + 1.
|
||||||
|
|
||||||
The desired configuration registers are accessed in two steps:
|
The desired configuration registers are accessed in two steps:
|
||||||
a. Write the index of the Logical Device Number Configuration Register
|
a. Write the index of the Logical Device Number Configuration Register
|
||||||
(i.e., 0x07) to the INDEX PORT and then write the number of the
|
(i.e., 0x07) to the INDEX PORT and then write the number of the
|
||||||
desired logical device to the DATA PORT.
|
desired logical device to the DATA PORT.
|
||||||
|
|
||||||
b. Write the address of the desired configuration register within the
|
b. Write the address of the desired configuration register within the
|
||||||
logical device to the INDEX PORT and then write or read the config-
|
logical device to the INDEX PORT and then write or read the config-
|
||||||
uration register through the DATA PORT.
|
uration register through the DATA PORT.
|
||||||
|
|
||||||
Note: If accessing the Global Configuration Registers, step (a) is not required.
|
Note: If accessing the Global Configuration Registers, step (a) is not required.
|
||||||
|
|
||||||
|
@ -96,18 +108,18 @@ The chip returns to the RUN State. (This is important).
|
||||||
Programming Example
|
Programming Example
|
||||||
The following is an example of how to read the SIO Device ID located at 0x20
|
The following is an example of how to read the SIO Device ID located at 0x20
|
||||||
|
|
||||||
; ENTER CONFIGURATION MODE
|
; ENTER CONFIGURATION MODE
|
||||||
MOV DX,02EH
|
MOV DX,02EH
|
||||||
MOV AX,055H
|
MOV AX,055H
|
||||||
OUT DX,AL
|
OUT DX,AL
|
||||||
; GLOBAL CONFIGURATION REGISTER
|
; GLOBAL CONFIGURATION REGISTER
|
||||||
MOV DX,02EH
|
MOV DX,02EH
|
||||||
MOV AL,20H
|
MOV AL,20H
|
||||||
OUT DX,AL
|
OUT DX,AL
|
||||||
; READ THE DATA
|
; READ THE DATA
|
||||||
MOV DX,02FH
|
MOV DX,02FH
|
||||||
IN AL,DX
|
IN AL,DX
|
||||||
; EXIT CONFIGURATION MODE
|
; EXIT CONFIGURATION MODE
|
||||||
MOV DX,02EH
|
MOV DX,02EH
|
||||||
MOV AX,0AAH
|
MOV AX,0AAH
|
||||||
OUT DX,AL
|
OUT DX,AL
|
||||||
|
@ -122,12 +134,12 @@ Obtaining the HWM Base Address.
|
||||||
The following is an example of how to read the HWM Base Address located in
|
The following is an example of how to read the HWM Base Address located in
|
||||||
Logical Device 8.
|
Logical Device 8.
|
||||||
|
|
||||||
; ENTER CONFIGURATION MODE
|
; ENTER CONFIGURATION MODE
|
||||||
MOV DX,02EH
|
MOV DX,02EH
|
||||||
MOV AX,055H
|
MOV AX,055H
|
||||||
OUT DX,AL
|
OUT DX,AL
|
||||||
; CONFIGURE REGISTER CRE0,
|
; CONFIGURE REGISTER CRE0,
|
||||||
; LOGICAL DEVICE 8
|
; LOGICAL DEVICE 8
|
||||||
MOV DX,02EH
|
MOV DX,02EH
|
||||||
MOV AL,07H
|
MOV AL,07H
|
||||||
OUT DX,AL ;Point to LD# Config Reg
|
OUT DX,AL ;Point to LD# Config Reg
|
||||||
|
@ -135,12 +147,12 @@ MOV DX,02FH
|
||||||
MOV AL, 08H
|
MOV AL, 08H
|
||||||
OUT DX,AL;Point to Logical Device 8
|
OUT DX,AL;Point to Logical Device 8
|
||||||
;
|
;
|
||||||
MOV DX,02EH
|
MOV DX,02EH
|
||||||
MOV AL,60H
|
MOV AL,60H
|
||||||
OUT DX,AL ; Point to HWM Base Addr MSB
|
OUT DX,AL ; Point to HWM Base Addr MSB
|
||||||
MOV DX,02FH
|
MOV DX,02FH
|
||||||
IN AL,DX ; Get MSB of HWM Base Addr
|
IN AL,DX ; Get MSB of HWM Base Addr
|
||||||
; EXIT CONFIGURATION MODE
|
; EXIT CONFIGURATION MODE
|
||||||
MOV DX,02EH
|
MOV DX,02EH
|
||||||
MOV AX,0AAH
|
MOV AX,0AAH
|
||||||
OUT DX,AL
|
OUT DX,AL
|
52
Documentation/i2c/chips/smsc47m1
Normal file
52
Documentation/i2c/chips/smsc47m1
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
Kernel driver smsc47m1
|
||||||
|
======================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192
|
||||||
|
Addresses scanned: none, address read from Super I/O config space
|
||||||
|
Prefix: 'smsc47m1'
|
||||||
|
Datasheets:
|
||||||
|
http://www.smsc.com/main/datasheets/47b27x.pdf
|
||||||
|
http://www.smsc.com/main/datasheets/47m10x.pdf
|
||||||
|
http://www.smsc.com/main/tools/discontinued/47m13x.pdf
|
||||||
|
http://www.smsc.com/main/datasheets/47m14x.pdf
|
||||||
|
http://www.smsc.com/main/tools/discontinued/47m15x.pdf
|
||||||
|
http://www.smsc.com/main/datasheets/47m192.pdf
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Mark D. Studebaker <mdsxyz123@yahoo.com>,
|
||||||
|
With assistance from Bruce Allen <ballen@uwm.edu>, and his
|
||||||
|
fan.c program: http://www.lsc-group.phys.uwm.edu/%7Eballen/driver/
|
||||||
|
Gabriele Gorla <gorlik@yahoo.com>,
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The Standard Microsystems Corporation (SMSC) 47M1xx Super I/O chips
|
||||||
|
contain monitoring and PWM control circuitry for two fans.
|
||||||
|
|
||||||
|
The 47M15x and 47M192 chips contain a full 'hardware monitoring block'
|
||||||
|
in addition to the fan monitoring and control. The hardware monitoring
|
||||||
|
block is not supported by the driver.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8) to give
|
||||||
|
the readings more range or accuracy. Not all RPM values can accurately be
|
||||||
|
represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
PWM values are from 0 to 255.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may
|
||||||
|
already have disappeared! Note that in the current implementation, all
|
||||||
|
hardware registers are read whenever any data is read (unless it is less
|
||||||
|
than 1.5 seconds since the last update). This means that you can easily
|
||||||
|
miss once-only alarms.
|
||||||
|
|
||||||
|
|
||||||
|
**********************
|
||||||
|
The lm_sensors project gratefully acknowledges the support of
|
||||||
|
Intel in the development of this driver.
|
65
Documentation/i2c/chips/via686a
Normal file
65
Documentation/i2c/chips/via686a
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
Kernel driver via686a
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Via VT82C686A, VT82C686B Southbridge Integrated Hardware Monitor
|
||||||
|
Prefix: 'via686a'
|
||||||
|
Addresses scanned: ISA in PCI-space encoded address
|
||||||
|
Datasheet: On request through web form (http://www.via.com.tw/en/support/datasheets/)
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Kyösti Mälkki <kmalkki@cc.hut.fi>,
|
||||||
|
Mark D. Studebaker <mdsxyz123@yahoo.com>
|
||||||
|
Bob Dougherty <bobd@stanford.edu>
|
||||||
|
(Some conversion-factor data were contributed by
|
||||||
|
Jonathan Teh Soon Yew <j.teh@iname.com>
|
||||||
|
and Alex van Kaam <darkside@chello.nl>.)
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
force_addr=0xaddr Set the I/O base address. Useful for Asus A7V boards
|
||||||
|
that don't set the address in the BIOS. Does not do a
|
||||||
|
PCI force; the via686a must still be present in lspci.
|
||||||
|
Don't use this unless the driver complains that the
|
||||||
|
base address is not set.
|
||||||
|
Example: 'modprobe via686a force_addr=0x6000'
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The driver does not distinguish between the chips and reports
|
||||||
|
all as a 686A.
|
||||||
|
|
||||||
|
The Via 686a southbridge has integrated hardware monitor functionality.
|
||||||
|
It also has an I2C bus, but this driver only supports the hardware monitor.
|
||||||
|
For the I2C bus driver, see <file:Documentation/i2c/busses/i2c-viapro>
|
||||||
|
|
||||||
|
The Via 686a implements three temperature sensors, two fan rotation speed
|
||||||
|
sensors, five voltage sensors and alarms.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. An alarm is triggered once
|
||||||
|
when the Overtemperature Shutdown limit is crossed; it is triggered again
|
||||||
|
as soon as it drops below the hysteresis value.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8) to give
|
||||||
|
the readings more range or accuracy. Not all RPM values can accurately be
|
||||||
|
represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report their values in volts.
|
||||||
|
An alarm is triggered if the voltage has crossed a programmable minimum
|
||||||
|
or maximum limit. Voltages are internally scalled, so each voltage channel
|
||||||
|
has a different resolution and range.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may
|
||||||
|
already have disappeared! Note that in the current implementation, all
|
||||||
|
hardware registers are read whenever any data is read (unless it is less
|
||||||
|
than 1.5 seconds since the last update). This means that you can easily
|
||||||
|
miss once-only alarms.
|
||||||
|
|
||||||
|
The driver only updates its values each 1.5 seconds; reading it more often
|
||||||
|
will do no harm, but will return 'old' values.
|
66
Documentation/i2c/chips/w83627hf
Normal file
66
Documentation/i2c/chips/w83627hf
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
Kernel driver w83627hf
|
||||||
|
======================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Winbond W83627HF (ISA accesses ONLY)
|
||||||
|
Prefix: 'w83627hf'
|
||||||
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
Datasheet: http://www.winbond.com/PDF/sheet/w83627hf.pdf
|
||||||
|
* Winbond W83627THF
|
||||||
|
Prefix: 'w83627thf'
|
||||||
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
Datasheet: http://www.winbond.com/PDF/sheet/w83627thf.pdf
|
||||||
|
* Winbond W83697HF
|
||||||
|
Prefix: 'w83697hf'
|
||||||
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
Datasheet: http://www.winbond.com/PDF/sheet/697hf.pdf
|
||||||
|
* Winbond W83637HF
|
||||||
|
Prefix: 'w83637hf'
|
||||||
|
Addresses scanned: ISA address retrieved from Super I/O registers
|
||||||
|
Datasheet: http://www.winbond.com/PDF/sheet/w83637hf.pdf
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>,
|
||||||
|
Mark Studebaker <mdsxyz123@yahoo.com>,
|
||||||
|
Bernhard C. Schrenk <clemy@clemy.org>
|
||||||
|
|
||||||
|
Module Parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* force_addr: int
|
||||||
|
Initialize the ISA address of the sensors
|
||||||
|
* force_i2c: int
|
||||||
|
Initialize the I2C address of the sensors
|
||||||
|
* init: int
|
||||||
|
(default is 1)
|
||||||
|
Use 'init=0' to bypass initializing the chip.
|
||||||
|
Try this if your computer crashes when you load the module.
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for ISA accesses *only* for
|
||||||
|
the Winbond W83627HF, W83627THF, W83697HF and W83637HF Super I/O chips.
|
||||||
|
We will refer to them collectively as Winbond chips.
|
||||||
|
|
||||||
|
This driver supports ISA accesses, which should be more reliable
|
||||||
|
than i2c accesses. Also, for Tyan boards which contain both a
|
||||||
|
Super I/O chip and a second i2c-only Winbond chip (often a W83782D),
|
||||||
|
using this driver will avoid i2c address conflicts and complex
|
||||||
|
initialization that were required in the w83781d driver.
|
||||||
|
|
||||||
|
If you really want i2c accesses for these Super I/O chips,
|
||||||
|
use the w83781d driver. However this is not the preferred method
|
||||||
|
now that this ISA driver has been developed.
|
||||||
|
|
||||||
|
Technically, the w83627thf does not support a VID reading. However, it's
|
||||||
|
possible or even likely that your mainboard maker has routed these signals
|
||||||
|
to a specific set of general purpose IO pins (the Asus P4C800-E is one such
|
||||||
|
board). The w83627thf driver now interprets these as VID. If the VID on
|
||||||
|
your board doesn't work, first see doc/vid in the lm_sensors package. If
|
||||||
|
that still doesn't help, email us at lm-sensors@lm-sensors.org.
|
||||||
|
|
||||||
|
For further information on this driver see the w83781d driver
|
||||||
|
documentation.
|
||||||
|
|
402
Documentation/i2c/chips/w83781d
Normal file
402
Documentation/i2c/chips/w83781d
Normal file
|
@ -0,0 +1,402 @@
|
||||||
|
Kernel driver w83781d
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Winbond W83781D
|
||||||
|
Prefix: 'w83781d'
|
||||||
|
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/w83781d.pdf
|
||||||
|
* Winbond W83782D
|
||||||
|
Prefix: 'w83782d'
|
||||||
|
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: http://www.winbond.com/PDF/sheet/w83782d.pdf
|
||||||
|
* Winbond W83783S
|
||||||
|
Prefix: 'w83783s'
|
||||||
|
Addresses scanned: I2C 0x2d
|
||||||
|
Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/w83783s.pdf
|
||||||
|
* Winbond W83627HF
|
||||||
|
Prefix: 'w83627hf'
|
||||||
|
Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
|
||||||
|
Datasheet: http://www.winbond.com/PDF/sheet/w83627hf.pdf
|
||||||
|
* Asus AS99127F
|
||||||
|
Prefix: 'as99127f'
|
||||||
|
Addresses scanned: I2C 0x28 - 0x2f
|
||||||
|
Datasheet: Unavailable from Asus
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
|
Philip Edelbrock <phil@netroedge.com>,
|
||||||
|
Mark Studebaker <mdsxyz123@yahoo.com>
|
||||||
|
|
||||||
|
Module parameters
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* init int
|
||||||
|
(default 1)
|
||||||
|
Use 'init=0' to bypass initializing the chip.
|
||||||
|
Try this if your computer crashes when you load the module.
|
||||||
|
|
||||||
|
force_subclients=bus,caddr,saddr,saddr
|
||||||
|
This is used to force the i2c addresses for subclients of
|
||||||
|
a certain chip. Typical usage is `force_subclients=0,0x2d,0x4a,0x4b'
|
||||||
|
to force the subclients of chip 0x2d on bus 0 to i2c addresses
|
||||||
|
0x4a and 0x4b. This parameter is useful for certain Tyan boards.
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This driver implements support for the Winbond W83781D, W83782D, W83783S,
|
||||||
|
W83627HF chips, and the Asus AS99127F chips. We will refer to them
|
||||||
|
collectively as W8378* chips.
|
||||||
|
|
||||||
|
There is quite some difference between these chips, but they are similar
|
||||||
|
enough that it was sensible to put them together in one driver.
|
||||||
|
The W83627HF chip is assumed to be identical to the ISA W83782D.
|
||||||
|
The Asus chips are similar to an I2C-only W83782D.
|
||||||
|
|
||||||
|
Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
|
||||||
|
as99127f 7 3 0 3 0x31 0x12c3 yes no
|
||||||
|
as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no
|
||||||
|
w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes
|
||||||
|
w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC)
|
||||||
|
w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes
|
||||||
|
w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no
|
||||||
|
|
||||||
|
Detection of these chips can sometimes be foiled because they can be in
|
||||||
|
an internal state that allows no clean access. If you know the address
|
||||||
|
of the chip, use a 'force' parameter; this will put them into a more
|
||||||
|
well-behaved state first.
|
||||||
|
|
||||||
|
The W8378* implements temperature sensors (three on the W83781D and W83782D,
|
||||||
|
two on the W83783S), three fan rotation speed sensors, voltage sensors
|
||||||
|
(seven on the W83781D, nine on the W83782D and six on the W83783S), VID
|
||||||
|
lines, alarms with beep warnings, and some miscellaneous stuff.
|
||||||
|
|
||||||
|
Temperatures are measured in degrees Celsius. There is always one main
|
||||||
|
temperature sensor, and one (W83783S) or two (W83781D and W83782D) other
|
||||||
|
sensors. An alarm is triggered for the main sensor once when the
|
||||||
|
Overtemperature Shutdown limit is crossed; it is triggered again as soon as
|
||||||
|
it drops below the Hysteresis value. A more useful behavior
|
||||||
|
can be found by setting the Hysteresis value to +127 degrees Celsius; in
|
||||||
|
this case, alarms are issued during all the time when the actual temperature
|
||||||
|
is above the Overtemperature Shutdown value. The driver sets the
|
||||||
|
hysteresis value for temp1 to 127 at initialization.
|
||||||
|
|
||||||
|
For the other temperature sensor(s), an alarm is triggered when the
|
||||||
|
temperature gets higher then the Overtemperature Shutdown value; it stays
|
||||||
|
on until the temperature falls below the Hysteresis value. But on the
|
||||||
|
W83781D, there is only one alarm that functions for both other sensors!
|
||||||
|
Temperatures are guaranteed within a range of -55 to +125 degrees. The
|
||||||
|
main temperature sensors has a resolution of 1 degree; the other sensor(s)
|
||||||
|
of 0.5 degree.
|
||||||
|
|
||||||
|
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
|
||||||
|
triggered if the rotation speed has dropped below a programmable limit. Fan
|
||||||
|
readings can be divided by a programmable divider (1, 2, 4 or 8 for the
|
||||||
|
W83781D; 1, 2, 4, 8, 16, 32, 64 or 128 for the others) to give
|
||||||
|
the readings more range or accuracy. Not all RPM values can accurately
|
||||||
|
be represented, so some rounding is done. With a divider of 2, the lowest
|
||||||
|
representable value is around 2600 RPM.
|
||||||
|
|
||||||
|
Voltage sensors (also known as IN sensors) report their values in volts.
|
||||||
|
An alarm is triggered if the voltage has crossed a programmable minimum
|
||||||
|
or maximum limit. Note that minimum in this case always means 'closest to
|
||||||
|
zero'; this is important for negative voltage measurements. All voltage
|
||||||
|
inputs can measure voltages between 0 and 4.08 volts, with a resolution
|
||||||
|
of 0.016 volt.
|
||||||
|
|
||||||
|
The VID lines encode the core voltage value: the voltage level your processor
|
||||||
|
should work with. This is hardcoded by the mainboard and/or processor itself.
|
||||||
|
It is a value in volts. When it is unconnected, you will often find the
|
||||||
|
value 3.50 V here.
|
||||||
|
|
||||||
|
The W83782D and W83783S temperature conversion machine understands about
|
||||||
|
several kinds of temperature probes. You can program the so-called
|
||||||
|
beta value in the sensor files. '1' is the PII/Celeron diode, '2' is the
|
||||||
|
TN3904 transistor, and 3435 the default thermistor value. Other values
|
||||||
|
are (not yet) supported.
|
||||||
|
|
||||||
|
In addition to the alarms described above, there is a CHAS alarm on the
|
||||||
|
chips which triggers if your computer case is open.
|
||||||
|
|
||||||
|
When an alarm goes off, you can be warned by a beeping signal through
|
||||||
|
your computer speaker. It is possible to enable all beeping globally,
|
||||||
|
or only the beeping for some alarms.
|
||||||
|
|
||||||
|
If an alarm triggers, it will remain triggered until the hardware register
|
||||||
|
is read at least once. This means that the cause for the alarm may
|
||||||
|
already have disappeared! Note that in the current implementation, all
|
||||||
|
hardware registers are read whenever any data is read (unless it is less
|
||||||
|
than 1.5 seconds since the last update). This means that you can easily
|
||||||
|
miss once-only alarms.
|
||||||
|
|
||||||
|
The chips only update values each 1.5 seconds; reading them more often
|
||||||
|
will do no harm, but will return 'old' values.
|
||||||
|
|
||||||
|
AS99127F PROBLEMS
|
||||||
|
-----------------
|
||||||
|
The as99127f support was developed without the benefit of a datasheet.
|
||||||
|
In most cases it is treated as a w83781d (although revision 2 of the
|
||||||
|
AS99127F looks more like a w83782d).
|
||||||
|
This support will be BETA until a datasheet is released.
|
||||||
|
One user has reported problems with fans stopping
|
||||||
|
occasionally.
|
||||||
|
|
||||||
|
Note that the individual beep bits are inverted from the other chips.
|
||||||
|
The driver now takes care of this so that user-space applications
|
||||||
|
don't have to know about it.
|
||||||
|
|
||||||
|
Known problems:
|
||||||
|
- Problems with diode/thermistor settings (supported?)
|
||||||
|
- One user reports fans stopping under high server load.
|
||||||
|
- Revision 2 seems to have 2 PWM registers but we don't know
|
||||||
|
how to handle them. More details below.
|
||||||
|
|
||||||
|
These will not be fixed unless we get a datasheet.
|
||||||
|
If you have problems, please lobby Asus to release a datasheet.
|
||||||
|
Unfortunately several others have without success.
|
||||||
|
Please do not send mail to us asking for better as99127f support.
|
||||||
|
We have done the best we can without a datasheet.
|
||||||
|
Please do not send mail to the author or the sensors group asking for
|
||||||
|
a datasheet or ideas on how to convince Asus. We can't help.
|
||||||
|
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
-----
|
||||||
|
783s has no in1 so that in[2-6] are compatible with the 781d/782d.
|
||||||
|
|
||||||
|
783s pin is programmable for -5V or temp1; defaults to -5V,
|
||||||
|
no control in driver so temp1 doesn't work.
|
||||||
|
|
||||||
|
782d and 783s datasheets differ on which is pwm1 and which is pwm2.
|
||||||
|
We chose to follow 782d.
|
||||||
|
|
||||||
|
782d and 783s pin is programmable for fan3 input or pwm2 output;
|
||||||
|
defaults to fan3 input.
|
||||||
|
If pwm2 is enabled (with echo 255 1 > pwm2), then
|
||||||
|
fan3 will report 0.
|
||||||
|
|
||||||
|
782d has pwm1-2 for ISA, pwm1-4 for i2c. (pwm3-4 share pins with
|
||||||
|
the ISA pins)
|
||||||
|
|
||||||
|
Data sheet updates:
|
||||||
|
------------------
|
||||||
|
- PWM clock registers:
|
||||||
|
|
||||||
|
000: master / 512
|
||||||
|
001: master / 1024
|
||||||
|
010: master / 2048
|
||||||
|
011: master / 4096
|
||||||
|
100: master / 8192
|
||||||
|
|
||||||
|
|
||||||
|
Answers from Winbond tech support
|
||||||
|
---------------------------------
|
||||||
|
>
|
||||||
|
> 1) In the W83781D data sheet section 7.2 last paragraph, it talks about
|
||||||
|
> reprogramming the R-T table if the Beta of the thermistor is not
|
||||||
|
> 3435K. The R-T table is described briefly in section 8.20.
|
||||||
|
> What formulas do I use to program a new R-T table for a given Beta?
|
||||||
|
>
|
||||||
|
We are sorry that the calculation for R-T table value is
|
||||||
|
confidential. If you have another Beta value of thermistor, we can help
|
||||||
|
to calculate the R-T table for you. But you should give us real R-T
|
||||||
|
Table which can be gotten by thermistor vendor. Therefore we will calculate
|
||||||
|
them and obtain 32-byte data, and you can fill the 32-byte data to the
|
||||||
|
register in Bank0.CR51 of W83781D.
|
||||||
|
|
||||||
|
|
||||||
|
> 2) In the W83782D data sheet, it mentions that pins 38, 39, and 40 are
|
||||||
|
> programmable to be either thermistor or Pentium II diode inputs.
|
||||||
|
> How do I program them for diode inputs? I can't find any register
|
||||||
|
> to program these to be diode inputs.
|
||||||
|
--> You may program Bank0 CR[5Dh] and CR[59h] registers.
|
||||||
|
|
||||||
|
CR[5Dh] bit 1(VTIN1) bit 2(VTIN2) bit 3(VTIN3)
|
||||||
|
|
||||||
|
thermistor 0 0 0
|
||||||
|
diode 1 1 1
|
||||||
|
|
||||||
|
|
||||||
|
(error) CR[59h] bit 4(VTIN1) bit 2(VTIN2) bit 3(VTIN3)
|
||||||
|
(right) CR[59h] bit 4(VTIN1) bit 5(VTIN2) bit 6(VTIN3)
|
||||||
|
|
||||||
|
PII thermal diode 1 1 1
|
||||||
|
2N3904 diode 0 0 0
|
||||||
|
|
||||||
|
|
||||||
|
Asus Clones
|
||||||
|
-----------
|
||||||
|
|
||||||
|
We have no datasheets for the Asus clones (AS99127F and ASB100 Bach).
|
||||||
|
Here are some very useful information that were given to us by Alex Van
|
||||||
|
Kaam about how to detect these chips, and how to read their values. He
|
||||||
|
also gives advice for another Asus chipset, the Mozart-2 (which we
|
||||||
|
don't support yet). Thanks Alex!
|
||||||
|
I reworded some parts and added personal comments.
|
||||||
|
|
||||||
|
# Detection:
|
||||||
|
|
||||||
|
AS99127F rev.1, AS99127F rev.2 and ASB100:
|
||||||
|
- I2C address range: 0x29 - 0x2F
|
||||||
|
- If register 0x58 holds 0x31 then we have an Asus (either ASB100 or
|
||||||
|
AS99127F)
|
||||||
|
- Which one depends on register 0x4F (manufacturer ID):
|
||||||
|
0x06 or 0x94: ASB100
|
||||||
|
0x12 or 0xC3: AS99127F rev.1
|
||||||
|
0x5C or 0xA3: AS99127F rev.2
|
||||||
|
Note that 0x5CA3 is Winbond's ID (WEC), which let us think Asus get their
|
||||||
|
AS99127F rev.2 direct from Winbond. The other codes mean ATT and DVC,
|
||||||
|
respectively. ATT could stand for Asustek something (although it would be
|
||||||
|
very badly chosen IMHO), I don't know what DVC could stand for. Maybe
|
||||||
|
these codes simply aren't meant to be decoded that way.
|
||||||
|
|
||||||
|
Mozart-2:
|
||||||
|
- I2C address: 0x77
|
||||||
|
- If register 0x58 holds 0x56 or 0x10 then we have a Mozart-2
|
||||||
|
- Of the Mozart there are 3 types:
|
||||||
|
0x58=0x56, 0x4E=0x94, 0x4F=0x36: Asus ASM58 Mozart-2
|
||||||
|
0x58=0x56, 0x4E=0x94, 0x4F=0x06: Asus AS2K129R Mozart-2
|
||||||
|
0x58=0x10, 0x4E=0x5C, 0x4F=0xA3: Asus ??? Mozart-2
|
||||||
|
You can handle all 3 the exact same way :)
|
||||||
|
|
||||||
|
# Temperature sensors:
|
||||||
|
|
||||||
|
ASB100:
|
||||||
|
- sensor 1: register 0x27
|
||||||
|
- sensor 2 & 3 are the 2 LM75's on the SMBus
|
||||||
|
- sensor 4: register 0x17
|
||||||
|
Remark: I noticed that on Intel boards sensor 2 is used for the CPU
|
||||||
|
and 4 is ignored/stuck, on AMD boards sensor 4 is the CPU and sensor 2 is
|
||||||
|
either ignored or a socket temperature.
|
||||||
|
|
||||||
|
AS99127F (rev.1 and 2 alike):
|
||||||
|
- sensor 1: register 0x27
|
||||||
|
- sensor 2 & 3 are the 2 LM75's on the SMBus
|
||||||
|
Remark: Register 0x5b is suspected to be temperature type selector. Bit 1
|
||||||
|
would control temp1, bit 3 temp2 and bit 5 temp3.
|
||||||
|
|
||||||
|
Mozart-2:
|
||||||
|
- sensor 1: register 0x27
|
||||||
|
- sensor 2: register 0x13
|
||||||
|
|
||||||
|
# Fan sensors:
|
||||||
|
|
||||||
|
ASB100, AS99127F (rev.1 and 2 alike):
|
||||||
|
- 3 fans, identical to the W83781D
|
||||||
|
|
||||||
|
Mozart-2:
|
||||||
|
- 2 fans only, 1350000/RPM/div
|
||||||
|
- fan 1: register 0x28, divisor on register 0xA1 (bits 4-5)
|
||||||
|
- fan 2: register 0x29, divisor on register 0xA1 (bits 6-7)
|
||||||
|
|
||||||
|
# Voltages:
|
||||||
|
|
||||||
|
This is where there is a difference between AS99127F rev.1 and 2.
|
||||||
|
Remark: The difference is similar to the difference between
|
||||||
|
W83781D and W83782D.
|
||||||
|
|
||||||
|
ASB100:
|
||||||
|
in0=r(0x20)*0.016
|
||||||
|
in1=r(0x21)*0.016
|
||||||
|
in2=r(0x22)*0.016
|
||||||
|
in3=r(0x23)*0.016*1.68
|
||||||
|
in4=r(0x24)*0.016*3.8
|
||||||
|
in5=r(0x25)*(-0.016)*3.97
|
||||||
|
in6=r(0x26)*(-0.016)*1.666
|
||||||
|
|
||||||
|
AS99127F rev.1:
|
||||||
|
in0=r(0x20)*0.016
|
||||||
|
in1=r(0x21)*0.016
|
||||||
|
in2=r(0x22)*0.016
|
||||||
|
in3=r(0x23)*0.016*1.68
|
||||||
|
in4=r(0x24)*0.016*3.8
|
||||||
|
in5=r(0x25)*(-0.016)*3.97
|
||||||
|
in6=r(0x26)*(-0.016)*1.503
|
||||||
|
|
||||||
|
AS99127F rev.2:
|
||||||
|
in0=r(0x20)*0.016
|
||||||
|
in1=r(0x21)*0.016
|
||||||
|
in2=r(0x22)*0.016
|
||||||
|
in3=r(0x23)*0.016*1.68
|
||||||
|
in4=r(0x24)*0.016*3.8
|
||||||
|
in5=(r(0x25)*0.016-3.6)*5.14+3.6
|
||||||
|
in6=(r(0x26)*0.016-3.6)*3.14+3.6
|
||||||
|
|
||||||
|
Mozart-2:
|
||||||
|
in0=r(0x20)*0.016
|
||||||
|
in1=255
|
||||||
|
in2=r(0x22)*0.016
|
||||||
|
in3=r(0x23)*0.016*1.68
|
||||||
|
in4=r(0x24)*0.016*4
|
||||||
|
in5=255
|
||||||
|
in6=255
|
||||||
|
|
||||||
|
|
||||||
|
# PWM
|
||||||
|
|
||||||
|
Additional info about PWM on the AS99127F (may apply to other Asus
|
||||||
|
chips as well) by Jean Delvare as of 2004-04-09:
|
||||||
|
|
||||||
|
AS99127F revision 2 seems to have two PWM registers at 0x59 and 0x5A,
|
||||||
|
and a temperature sensor type selector at 0x5B (which basically means
|
||||||
|
that they swapped registers 0x59 and 0x5B when you compare with Winbond
|
||||||
|
chips).
|
||||||
|
Revision 1 of the chip also has the temperature sensor type selector at
|
||||||
|
0x5B, but PWM registers have no effect.
|
||||||
|
|
||||||
|
We don't know exactly how the temperature sensor type selection works.
|
||||||
|
Looks like bits 1-0 are for temp1, bits 3-2 for temp2 and bits 5-4 for
|
||||||
|
temp3, although it is possible that only the most significant bit matters
|
||||||
|
each time. So far, values other than 0 always broke the readings.
|
||||||
|
|
||||||
|
PWM registers seem to be split in two parts: bit 7 is a mode selector,
|
||||||
|
while the other bits seem to define a value or threshold.
|
||||||
|
|
||||||
|
When bit 7 is clear, bits 6-0 seem to hold a threshold value. If the value
|
||||||
|
is below a given limit, the fan runs at low speed. If the value is above
|
||||||
|
the limit, the fan runs at full speed. We have no clue as to what the limit
|
||||||
|
represents. Note that there seem to be some inertia in this mode, speed
|
||||||
|
changes may need some time to trigger. Also, an hysteresis mechanism is
|
||||||
|
suspected since walking through all the values increasingly and then
|
||||||
|
decreasingly led to slightly different limits.
|
||||||
|
|
||||||
|
When bit 7 is set, bits 3-0 seem to hold a threshold value, while bits 6-4
|
||||||
|
would not be significant. If the value is below a given limit, the fan runs
|
||||||
|
at full speed, while if it is above the limit it runs at low speed (so this
|
||||||
|
is the contrary of the other mode, in a way). Here again, we don't know
|
||||||
|
what the limit is supposed to represent.
|
||||||
|
|
||||||
|
One remarkable thing is that the fans would only have two or three
|
||||||
|
different speeds (transitional states left apart), not a whole range as
|
||||||
|
you usually get with PWM.
|
||||||
|
|
||||||
|
As a conclusion, you can write 0x00 or 0x8F to the PWM registers to make
|
||||||
|
fans run at low speed, and 0x7F or 0x80 to make them run at full speed.
|
||||||
|
|
||||||
|
Please contact us if you can figure out how it is supposed to work. As
|
||||||
|
long as we don't know more, the w83781d driver doesn't handle PWM on
|
||||||
|
AS99127F chips at all.
|
||||||
|
|
||||||
|
Additional info about PWM on the AS99127F rev.1 by Hector Martin:
|
||||||
|
|
||||||
|
I've been fiddling around with the (in)famous 0x59 register and
|
||||||
|
found out the following values do work as a form of coarse pwm:
|
||||||
|
|
||||||
|
0x80 - seems to turn fans off after some time(1-2 minutes)... might be
|
||||||
|
some form of auto-fan-control based on temp? hmm (Qfan? this mobo is an
|
||||||
|
old ASUS, it isn't marketed as Qfan. Maybe some beta pre-attemp at Qfan
|
||||||
|
that was dropped at the BIOS)
|
||||||
|
0x81 - off
|
||||||
|
0x82 - slightly "on-ner" than off, but my fans do not get to move. I can
|
||||||
|
hear the high-pitched PWM sound that motors give off at too-low-pwm.
|
||||||
|
0x83 - now they do move. Estimate about 70% speed or so.
|
||||||
|
0x84-0x8f - full on
|
||||||
|
|
||||||
|
Changing the high nibble doesn't seem to do much except the high bit
|
||||||
|
(0x80) must be set for PWM to work, else the current pwm doesn't seem to
|
||||||
|
change.
|
||||||
|
|
||||||
|
My mobo is an ASUS A7V266-E. This behavior is similar to what I got
|
||||||
|
with speedfan under Windows, where 0-15% would be off, 15-2x% (can't
|
||||||
|
remember the exact value) would be 70% and higher would be full on.
|
39
Documentation/i2c/chips/w83l785ts
Normal file
39
Documentation/i2c/chips/w83l785ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
Kernel driver w83l785ts
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* Winbond W83L785TS-S
|
||||||
|
Prefix: 'w83l785ts'
|
||||||
|
Addresses scanned: I2C 0x2e
|
||||||
|
Datasheet: Publicly available at the Winbond USA website
|
||||||
|
http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83L785TS-S.pdf
|
||||||
|
|
||||||
|
Authors:
|
||||||
|
Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The W83L785TS-S is a digital temperature sensor. It senses the
|
||||||
|
temperature of a single external diode. The high limit is
|
||||||
|
theoretically defined as 85 or 100 degrees C through a combination
|
||||||
|
of external resistors, so the user cannot change it. Values seen so
|
||||||
|
far suggest that the two possible limits are actually 95 and 110
|
||||||
|
degrees C. The datasheet is rather poor and obviously inaccurate
|
||||||
|
on several points including this one.
|
||||||
|
|
||||||
|
All temperature values are given in degrees Celsius. Resolution
|
||||||
|
is 1.0 degree. See the datasheet for details.
|
||||||
|
|
||||||
|
The w83l785ts driver will not update its values more frequently than
|
||||||
|
every other second; reading them more often will do no harm, but will
|
||||||
|
return 'old' values.
|
||||||
|
|
||||||
|
Known Issues
|
||||||
|
------------
|
||||||
|
|
||||||
|
On some systems (Asus), the BIOS is known to interfere with the driver
|
||||||
|
and cause read errors. The driver will retry a given number of times
|
||||||
|
(5 by default) and then give up, returning the old value (or 0 if
|
||||||
|
there is no old value). It seems to work well enough so that you should
|
||||||
|
not notice anything. Thanks to James Bolt for helping test this feature.
|
|
@ -57,7 +57,7 @@ Technical changes:
|
||||||
Documentation/i2c/sysfs-interface for the individual files. Also
|
Documentation/i2c/sysfs-interface for the individual files. Also
|
||||||
convert the units these files read and write to the specified ones.
|
convert the units these files read and write to the specified ones.
|
||||||
If you need to add a new type of file, please discuss it on the
|
If you need to add a new type of file, please discuss it on the
|
||||||
sensors mailing list <sensors@stimpy.netroedge.com> by providing a
|
sensors mailing list <lm-sensors@lm-sensors.org> by providing a
|
||||||
patch to the Documentation/i2c/sysfs-interface file.
|
patch to the Documentation/i2c/sysfs-interface file.
|
||||||
|
|
||||||
* [Attach] For I2C drivers, the attach function should make sure
|
* [Attach] For I2C drivers, the attach function should make sure
|
||||||
|
|
39
Documentation/i2c/userspace-tools
Normal file
39
Documentation/i2c/userspace-tools
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
Most mainboards have sensor chips to monitor system health (like temperatures,
|
||||||
|
voltages, fans speed). They are often connected through an I2C bus, but some
|
||||||
|
are also connected directly through the ISA bus.
|
||||||
|
|
||||||
|
The kernel drivers make the data from the sensor chips available in the /sys
|
||||||
|
virtual filesystem. Userspace tools are then used to display or set or the
|
||||||
|
data in a more friendly manner.
|
||||||
|
|
||||||
|
Lm-sensors
|
||||||
|
----------
|
||||||
|
|
||||||
|
Core set of utilites that will allow you to obtain health information,
|
||||||
|
setup monitoring limits etc. You can get them on their homepage
|
||||||
|
http://www.lm-sensors.nu/ or as a package from your Linux distribution.
|
||||||
|
|
||||||
|
If from website:
|
||||||
|
Get lmsensors from project web site. Please note, you need only userspace
|
||||||
|
part, so compile with "make user_install" target.
|
||||||
|
|
||||||
|
General hints to get things working:
|
||||||
|
|
||||||
|
0) get lm-sensors userspace utils
|
||||||
|
1) compile all drivers in I2C section as modules in your kernel
|
||||||
|
2) run sensors-detect script, it will tell you what modules you need to load.
|
||||||
|
3) load them and run "sensors" command, you should see some results.
|
||||||
|
4) fix sensors.conf, labels, limits, fan divisors
|
||||||
|
5) if any more problems consult FAQ, or documentation
|
||||||
|
|
||||||
|
Other utilites
|
||||||
|
--------------
|
||||||
|
|
||||||
|
If you want some graphical indicators of system health look for applications
|
||||||
|
like: gkrellm, ksensors, xsensors, wmtemp, wmsensors, wmgtemp, ksysguardd,
|
||||||
|
hardware-monitor
|
||||||
|
|
||||||
|
If you are server administrator you can try snmpd or mrtgutils.
|
|
@ -171,45 +171,31 @@ The following lists are used internally:
|
||||||
|
|
||||||
normal_i2c: filled in by the module writer.
|
normal_i2c: filled in by the module writer.
|
||||||
A list of I2C addresses which should normally be examined.
|
A list of I2C addresses which should normally be examined.
|
||||||
normal_i2c_range: filled in by the module writer.
|
|
||||||
A list of pairs of I2C addresses, each pair being an inclusive range of
|
|
||||||
addresses which should normally be examined.
|
|
||||||
probe: insmod parameter.
|
probe: insmod parameter.
|
||||||
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
||||||
the second is the address. These addresses are also probed, as if they
|
the second is the address. These addresses are also probed, as if they
|
||||||
were in the 'normal' list.
|
were in the 'normal' list.
|
||||||
probe_range: insmod parameter.
|
|
||||||
A list of triples. The first value is a bus number (-1 for any I2C bus),
|
|
||||||
the second and third are addresses. These form an inclusive range of
|
|
||||||
addresses that are also probed, as if they were in the 'normal' list.
|
|
||||||
ignore: insmod parameter.
|
ignore: insmod parameter.
|
||||||
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
||||||
the second is the I2C address. These addresses are never probed.
|
the second is the I2C address. These addresses are never probed.
|
||||||
This parameter overrules 'normal' and 'probe', but not the 'force' lists.
|
This parameter overrules 'normal' and 'probe', but not the 'force' lists.
|
||||||
ignore_range: insmod parameter.
|
|
||||||
A list of triples. The first value is a bus number (-1 for any I2C bus),
|
|
||||||
the second and third are addresses. These form an inclusive range of
|
|
||||||
I2C addresses that are never probed.
|
|
||||||
This parameter overrules 'normal' and 'probe', but not the 'force' lists.
|
|
||||||
force: insmod parameter.
|
force: insmod parameter.
|
||||||
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
A list of pairs. The first value is a bus number (-1 for any I2C bus),
|
||||||
the second is the I2C address. A device is blindly assumed to be on
|
the second is the I2C address. A device is blindly assumed to be on
|
||||||
the given address, no probing is done.
|
the given address, no probing is done.
|
||||||
|
|
||||||
Fortunately, as a module writer, you just have to define the `normal'
|
Fortunately, as a module writer, you just have to define the `normal_i2c'
|
||||||
and/or `normal_range' parameters. The complete declaration could look
|
parameter. The complete declaration could look like this:
|
||||||
like this:
|
|
||||||
|
|
||||||
/* Scan 0x20 to 0x2f, 0x37, and 0x40 to 0x4f */
|
/* Scan 0x37, and 0x48 to 0x4f */
|
||||||
static unsigned short normal_i2c[] = { 0x37,I2C_CLIENT_END };
|
static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
|
||||||
static unsigned short normal_i2c_range[] = { 0x20, 0x2f, 0x40, 0x4f,
|
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
|
||||||
I2C_CLIENT_END };
|
|
||||||
|
|
||||||
/* Magic definition of all other variables and things */
|
/* Magic definition of all other variables and things */
|
||||||
I2C_CLIENT_INSMOD;
|
I2C_CLIENT_INSMOD;
|
||||||
|
|
||||||
Note that you *have* to call the two defined variables `normal_i2c' and
|
Note that you *have* to call the defined variable `normal_i2c',
|
||||||
`normal_i2c_range', without any prefix!
|
without any prefix!
|
||||||
|
|
||||||
|
|
||||||
Probing classes (sensors)
|
Probing classes (sensors)
|
||||||
|
@ -223,39 +209,17 @@ The following lists are used internally. They are all lists of integers.
|
||||||
|
|
||||||
normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
|
normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
|
||||||
A list of I2C addresses which should normally be examined.
|
A list of I2C addresses which should normally be examined.
|
||||||
normal_i2c_range: filled in by the module writer. Terminated by
|
|
||||||
SENSORS_I2C_END
|
|
||||||
A list of pairs of I2C addresses, each pair being an inclusive range of
|
|
||||||
addresses which should normally be examined.
|
|
||||||
normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
|
normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
|
||||||
A list of ISA addresses which should normally be examined.
|
A list of ISA addresses which should normally be examined.
|
||||||
normal_isa_range: filled in by the module writer. Terminated by
|
|
||||||
SENSORS_ISA_END
|
|
||||||
A list of triples. The first two elements are ISA addresses, being an
|
|
||||||
range of addresses which should normally be examined. The third is the
|
|
||||||
modulo parameter: only addresses which are 0 module this value relative
|
|
||||||
to the first address of the range are actually considered.
|
|
||||||
probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
|
probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
|
||||||
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
|
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
|
||||||
the ISA bus, -1 for any I2C bus), the second is the address. These
|
the ISA bus, -1 for any I2C bus), the second is the address. These
|
||||||
addresses are also probed, as if they were in the 'normal' list.
|
addresses are also probed, as if they were in the 'normal' list.
|
||||||
probe_range: insmod parameter. Initialize this list with SENSORS_I2C_END
|
|
||||||
values.
|
|
||||||
A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
|
|
||||||
the ISA bus, -1 for any I2C bus), the second and third are addresses.
|
|
||||||
These form an inclusive range of addresses that are also probed, as
|
|
||||||
if they were in the 'normal' list.
|
|
||||||
ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
|
ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
|
||||||
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
|
A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
|
||||||
the ISA bus, -1 for any I2C bus), the second is the I2C address. These
|
the ISA bus, -1 for any I2C bus), the second is the I2C address. These
|
||||||
addresses are never probed. This parameter overrules 'normal' and
|
addresses are never probed. This parameter overrules 'normal' and
|
||||||
'probe', but not the 'force' lists.
|
'probe', but not the 'force' lists.
|
||||||
ignore_range: insmod parameter. Initialize this list with SENSORS_I2C_END
|
|
||||||
values.
|
|
||||||
A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
|
|
||||||
the ISA bus, -1 for any I2C bus), the second and third are addresses.
|
|
||||||
These form an inclusive range of I2C addresses that are never probed.
|
|
||||||
This parameter overrules 'normal' and 'probe', but not the 'force' lists.
|
|
||||||
|
|
||||||
Also used is a list of pointers to sensors_force_data structures:
|
Also used is a list of pointers to sensors_force_data structures:
|
||||||
force_data: insmod parameters. A list, ending with an element of which
|
force_data: insmod parameters. A list, ending with an element of which
|
||||||
|
@ -269,16 +233,14 @@ Also used is a list of pointers to sensors_force_data structures:
|
||||||
So we have a generic insmod variabled `force', and chip-specific variables
|
So we have a generic insmod variabled `force', and chip-specific variables
|
||||||
`force_CHIPNAME'.
|
`force_CHIPNAME'.
|
||||||
|
|
||||||
Fortunately, as a module writer, you just have to define the `normal'
|
Fortunately, as a module writer, you just have to define the `normal_i2c'
|
||||||
and/or `normal_range' parameters, and define what chip names are used.
|
and `normal_isa' parameters, and define what chip names are used.
|
||||||
The complete declaration could look like this:
|
The complete declaration could look like this:
|
||||||
/* Scan i2c addresses 0x20 to 0x2f, 0x37, and 0x40 to 0x4f
|
/* Scan i2c addresses 0x37, and 0x48 to 0x4f */
|
||||||
static unsigned short normal_i2c[] = {0x37,SENSORS_I2C_END};
|
static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
|
||||||
static unsigned short normal_i2c_range[] = {0x20,0x2f,0x40,0x4f,
|
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
|
||||||
SENSORS_I2C_END};
|
|
||||||
/* Scan ISA address 0x290 */
|
/* Scan ISA address 0x290 */
|
||||||
static unsigned int normal_isa[] = {0x0290,SENSORS_ISA_END};
|
static unsigned int normal_isa[] = {0x0290,SENSORS_ISA_END};
|
||||||
static unsigned int normal_isa_range[] = {SENSORS_ISA_END};
|
|
||||||
|
|
||||||
/* Define chips foo and bar, as well as all module parameters and things */
|
/* Define chips foo and bar, as well as all module parameters and things */
|
||||||
SENSORS_INSMOD_2(foo,bar);
|
SENSORS_INSMOD_2(foo,bar);
|
||||||
|
|
|
@ -30,7 +30,7 @@ Command line parameters
|
||||||
device numbers (0xabcd or abcd, for 2.4 backward compatibility).
|
device numbers (0xabcd or abcd, for 2.4 backward compatibility).
|
||||||
You can use the 'all' keyword to ignore all devices.
|
You can use the 'all' keyword to ignore all devices.
|
||||||
The '!' operator will cause the I/O-layer to _not_ ignore a device.
|
The '!' operator will cause the I/O-layer to _not_ ignore a device.
|
||||||
The order on the command line is not important.
|
The command line is parsed from left to right.
|
||||||
|
|
||||||
For example,
|
For example,
|
||||||
cio_ignore=0.0.0023-0.0.0042,0.0.4711
|
cio_ignore=0.0.0023-0.0.0042,0.0.4711
|
||||||
|
@ -72,13 +72,14 @@ Command line parameters
|
||||||
/proc/cio_ignore; "add <device range>, <device range>, ..." will ignore the
|
/proc/cio_ignore; "add <device range>, <device range>, ..." will ignore the
|
||||||
specified devices.
|
specified devices.
|
||||||
|
|
||||||
Note: Already known devices cannot be ignored.
|
Note: While already known devices can be added to the list of devices to be
|
||||||
|
ignored, there will be no effect on then. However, if such a device
|
||||||
|
disappears and then reappeares, it will then be ignored.
|
||||||
|
|
||||||
For example, if device 0.0.abcd is already known and all other devices
|
For example,
|
||||||
0.0.a000-0.0.afff are not known,
|
|
||||||
"echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore"
|
"echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore"
|
||||||
will add 0.0.a000-0.0.abcc, 0.0.abce-0.0.accc and 0.0.af00-0.0.afff to the
|
will add 0.0.a000-0.0.accc and 0.0.af00-0.0.afff to the list of ignored
|
||||||
list of ignored devices and skip 0.0.abcd.
|
devices.
|
||||||
|
|
||||||
The devices can be specified either by bus id (0.0.abcd) or, for 2.4 backward
|
The devices can be specified either by bus id (0.0.abcd) or, for 2.4 backward
|
||||||
compatibilty, by the device number in hexadecimal (0xabcd or abcd).
|
compatibilty, by the device number in hexadecimal (0xabcd or abcd).
|
||||||
|
@ -98,7 +99,8 @@ Command line parameters
|
||||||
|
|
||||||
- /proc/s390dbf/cio_trace/hex_ascii
|
- /proc/s390dbf/cio_trace/hex_ascii
|
||||||
Logs the calling of functions in the common I/O-layer and, if applicable,
|
Logs the calling of functions in the common I/O-layer and, if applicable,
|
||||||
which subchannel they were called for.
|
which subchannel they were called for, as well as dumps of some data
|
||||||
|
structures (like irb in an error case).
|
||||||
|
|
||||||
The level of logging can be changed to be more or less verbose by piping to
|
The level of logging can be changed to be more or less verbose by piping to
|
||||||
/proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on
|
/proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on
|
||||||
|
|
45
Documentation/sgi-ioc4.txt
Normal file
45
Documentation/sgi-ioc4.txt
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
The SGI IOC4 PCI device is a bit of a strange beast, so some notes on
|
||||||
|
it are in order.
|
||||||
|
|
||||||
|
First, even though the IOC4 performs multiple functions, such as an
|
||||||
|
IDE controller, a serial controller, a PS/2 keyboard/mouse controller,
|
||||||
|
and an external interrupt mechanism, it's not implemented as a
|
||||||
|
multifunction device. The consequence of this from a software
|
||||||
|
standpoint is that all these functions share a single IRQ, and
|
||||||
|
they can't all register to own the same PCI device ID. To make
|
||||||
|
matters a bit worse, some of the register blocks (and even registers
|
||||||
|
themselves) present in IOC4 are mixed-purpose between these several
|
||||||
|
functions, meaning that there's no clear "owning" device driver.
|
||||||
|
|
||||||
|
The solution is to organize the IOC4 driver into several independent
|
||||||
|
drivers, "ioc4", "sgiioc4", and "ioc4_serial". Note that there is no
|
||||||
|
PS/2 controller driver as this functionality has never been wired up
|
||||||
|
on a shipping IO card.
|
||||||
|
|
||||||
|
ioc4
|
||||||
|
====
|
||||||
|
This is the core (or shim) driver for IOC4. It is responsible for
|
||||||
|
initializing the basic functionality of the chip, and allocating
|
||||||
|
the PCI resources that are shared between the IOC4 functions.
|
||||||
|
|
||||||
|
This driver also provides registration functions that the other
|
||||||
|
IOC4 drivers can call to make their presence known. Each driver
|
||||||
|
needs to provide a probe and remove function, which are invoked
|
||||||
|
by the core driver at appropriate times. The interface of these
|
||||||
|
IOC4 function probe and remove operations isn't precisely the same
|
||||||
|
as PCI device probe and remove operations, but is logically the
|
||||||
|
same operation.
|
||||||
|
|
||||||
|
sgiioc4
|
||||||
|
=======
|
||||||
|
This is the IDE driver for IOC4. Its name isn't very descriptive
|
||||||
|
simply for historical reasons (it used to be the only IOC4 driver
|
||||||
|
component). There's not much to say about it other than it hooks
|
||||||
|
up to the ioc4 driver via the appropriate registration, probe, and
|
||||||
|
remove functions.
|
||||||
|
|
||||||
|
ioc4_serial
|
||||||
|
===========
|
||||||
|
This is the serial driver for IOC4. There's not much to say about it
|
||||||
|
other than it hooks up to the ioc4 driver via the appropriate registration,
|
||||||
|
probe, and remove functions.
|
|
@ -615,9 +615,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
Module snd-hda-intel
|
Module snd-hda-intel
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Module for Intel HD Audio (ICH6, ICH6M, ICH7)
|
Module for Intel HD Audio (ICH6, ICH6M, ICH7), ATI SB450,
|
||||||
|
VIA VT8251/VT8237A
|
||||||
|
|
||||||
model - force the model name
|
model - force the model name
|
||||||
|
position_fix - Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF)
|
||||||
|
|
||||||
Module supports up to 8 cards.
|
Module supports up to 8 cards.
|
||||||
|
|
||||||
|
@ -635,6 +637,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
5stack 5-jack in back, 2-jack in front
|
5stack 5-jack in back, 2-jack in front
|
||||||
5stack-digout 5-jack in back, 2-jack in front, a SPDIF out
|
5stack-digout 5-jack in back, 2-jack in front, a SPDIF out
|
||||||
w810 3-jack
|
w810 3-jack
|
||||||
|
z71v 3-jack (HP shared SPDIF)
|
||||||
|
asus 3-jack
|
||||||
|
uniwill 3-jack
|
||||||
|
F1734 2-jack
|
||||||
|
|
||||||
CMI9880
|
CMI9880
|
||||||
minimal 3-jack in back
|
minimal 3-jack in back
|
||||||
|
@ -642,6 +648,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
full 6-jack in back, 2-jack in front
|
full 6-jack in back, 2-jack in front
|
||||||
full_dig 6-jack in back, 2-jack in front, SPDIF I/O
|
full_dig 6-jack in back, 2-jack in front, SPDIF I/O
|
||||||
allout 5-jack in back, 2-jack in front, SPDIF out
|
allout 5-jack in back, 2-jack in front, SPDIF out
|
||||||
|
auto auto-config reading BIOS (default)
|
||||||
|
|
||||||
|
Note 2: If you get click noises on output, try the module option
|
||||||
|
position_fix=1 or 2. position_fix=1 will use the SD_LPIB
|
||||||
|
register value without FIFO size correction as the current
|
||||||
|
DMA pointer. position_fix=2 will make the driver to use
|
||||||
|
the position buffer instead of reading SD_LPIB register.
|
||||||
|
(Usually SD_LPLIB register is more accurate than the
|
||||||
|
position buffer.)
|
||||||
|
|
||||||
Module snd-hdsp
|
Module snd-hdsp
|
||||||
---------------
|
---------------
|
||||||
|
@ -660,7 +675,19 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
module did formerly. It will allocate the buffers in advance
|
module did formerly. It will allocate the buffers in advance
|
||||||
when any HDSP cards are found. To make the buffer
|
when any HDSP cards are found. To make the buffer
|
||||||
allocation sure, load snd-page-alloc module in the early
|
allocation sure, load snd-page-alloc module in the early
|
||||||
stage of boot sequence.
|
stage of boot sequence. See "Early Buffer Allocation"
|
||||||
|
section.
|
||||||
|
|
||||||
|
Module snd-hdspm
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Module for RME HDSP MADI board.
|
||||||
|
|
||||||
|
precise_ptr - Enable precise pointer, or disable.
|
||||||
|
line_outs_monitor - Send playback streams to analog outs by default.
|
||||||
|
enable_monitor - Enable Analog Out on Channel 63/64 by default.
|
||||||
|
|
||||||
|
See hdspm.txt for details.
|
||||||
|
|
||||||
Module snd-ice1712
|
Module snd-ice1712
|
||||||
------------------
|
------------------
|
||||||
|
@ -677,15 +704,19 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
* TerraTec EWS 88D
|
* TerraTec EWS 88D
|
||||||
* TerraTec EWX 24/96
|
* TerraTec EWX 24/96
|
||||||
* TerraTec DMX 6Fire
|
* TerraTec DMX 6Fire
|
||||||
|
* TerraTec Phase 88
|
||||||
* Hoontech SoundTrack DSP 24
|
* Hoontech SoundTrack DSP 24
|
||||||
* Hoontech SoundTrack DSP 24 Value
|
* Hoontech SoundTrack DSP 24 Value
|
||||||
* Hoontech SoundTrack DSP 24 Media 7.1
|
* Hoontech SoundTrack DSP 24 Media 7.1
|
||||||
|
* Event Electronics, EZ8
|
||||||
* Digigram VX442
|
* Digigram VX442
|
||||||
|
* Lionstracs, Mediastaton
|
||||||
|
|
||||||
model - Use the given board model, one of the following:
|
model - Use the given board model, one of the following:
|
||||||
delta1010, dio2496, delta66, delta44, audiophile, delta410,
|
delta1010, dio2496, delta66, delta44, audiophile, delta410,
|
||||||
delta1010lt, vx442, ewx2496, ews88mt, ews88mt_new, ews88d,
|
delta1010lt, vx442, ewx2496, ews88mt, ews88mt_new, ews88d,
|
||||||
dmx6fire, dsp24, dsp24_value, dsp24_71, ez8
|
dmx6fire, dsp24, dsp24_value, dsp24_71, ez8,
|
||||||
|
phase88, mediastation
|
||||||
omni - Omni I/O support for MidiMan M-Audio Delta44/66
|
omni - Omni I/O support for MidiMan M-Audio Delta44/66
|
||||||
cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
|
cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
|
||||||
in msec resolution, default value is 500 (0.5 sec)
|
in msec resolution, default value is 500 (0.5 sec)
|
||||||
|
@ -694,20 +725,46 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
is not used with all Envy24 based cards (for example in the MidiMan Delta
|
is not used with all Envy24 based cards (for example in the MidiMan Delta
|
||||||
serie).
|
serie).
|
||||||
|
|
||||||
|
Note: The supported board is detected by reading EEPROM or PCI
|
||||||
|
SSID (if EEPROM isn't available). You can override the
|
||||||
|
model by passing "model" module option in case that the
|
||||||
|
driver isn't configured properly or you want to try another
|
||||||
|
type for testing.
|
||||||
|
|
||||||
Module snd-ice1724
|
Module snd-ice1724
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Module for Envy24HT (VT/ICE1724) based PCI sound cards.
|
Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards.
|
||||||
* MidiMan M Audio Revolution 7.1
|
* MidiMan M Audio Revolution 7.1
|
||||||
* AMP Ltd AUDIO2000
|
* AMP Ltd AUDIO2000
|
||||||
* TerraTec Aureon Sky-5.1, Space-7.1
|
* TerraTec Aureon 5.1 Sky
|
||||||
|
* TerraTec Aureon 7.1 Space
|
||||||
|
* TerraTec Aureon 7.1 Universe
|
||||||
|
* TerraTec Phase 22
|
||||||
|
* TerraTec Phase 28
|
||||||
|
* AudioTrak Prodigy 7.1
|
||||||
|
* AudioTrak Prodigy 192
|
||||||
|
* Pontis MS300
|
||||||
|
* Albatron K8X800 Pro II
|
||||||
|
* Chaintech ZNF3-150
|
||||||
|
* Chaintech ZNF3-250
|
||||||
|
* Chaintech 9CJS
|
||||||
|
* Chaintech AV-710
|
||||||
|
* Shuttle SN25P
|
||||||
|
|
||||||
model - Use the given board model, one of the following:
|
model - Use the given board model, one of the following:
|
||||||
revo71, amp2000, prodigy71, aureon51, aureon71,
|
revo71, amp2000, prodigy71, prodigy192, aureon51,
|
||||||
k8x800
|
aureon71, universe, k8x800, phase22, phase28, ms300,
|
||||||
|
av710
|
||||||
|
|
||||||
Module supports up to 8 cards and autoprobe.
|
Module supports up to 8 cards and autoprobe.
|
||||||
|
|
||||||
|
Note: The supported board is detected by reading EEPROM or PCI
|
||||||
|
SSID (if EEPROM isn't available). You can override the
|
||||||
|
model by passing "model" module option in case that the
|
||||||
|
driver isn't configured properly or you want to try another
|
||||||
|
type for testing.
|
||||||
|
|
||||||
Module snd-intel8x0
|
Module snd-intel8x0
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -1026,7 +1083,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
module did formerly. It will allocate the buffers in advance
|
module did formerly. It will allocate the buffers in advance
|
||||||
when any RME9652 cards are found. To make the buffer
|
when any RME9652 cards are found. To make the buffer
|
||||||
allocation sure, load snd-page-alloc module in the early
|
allocation sure, load snd-page-alloc module in the early
|
||||||
stage of boot sequence.
|
stage of boot sequence. See "Early Buffer Allocation"
|
||||||
|
section.
|
||||||
|
|
||||||
Module snd-sa11xx-uda1341 (on arm only)
|
Module snd-sa11xx-uda1341 (on arm only)
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
@ -1211,16 +1269,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Module for AC'97 motherboards based on VIA 82C686A/686B, 8233,
|
Module for AC'97 motherboards based on VIA 82C686A/686B, 8233,
|
||||||
8233A, 8233C, 8235 (south) bridge.
|
8233A, 8233C, 8235, 8237 (south) bridge.
|
||||||
|
|
||||||
mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
|
mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
|
||||||
[VIA686A/686B only]
|
[VIA686A/686B only]
|
||||||
joystick - Enable joystick (default off) [VIA686A/686B only]
|
joystick - Enable joystick (default off) [VIA686A/686B only]
|
||||||
ac97_clock - AC'97 codec clock base (default 48000Hz)
|
ac97_clock - AC'97 codec clock base (default 48000Hz)
|
||||||
dxs_support - support DXS channels,
|
dxs_support - support DXS channels,
|
||||||
0 = auto (defalut), 1 = enable, 2 = disable,
|
0 = auto (default), 1 = enable, 2 = disable,
|
||||||
3 = 48k only, 4 = no VRA
|
3 = 48k only, 4 = no VRA, 5 = enable any sample
|
||||||
[VIA8233/C,8235 only]
|
rate and different sample rates on different
|
||||||
|
channels
|
||||||
|
[VIA8233/C, 8235, 8237 only]
|
||||||
ac97_quirk - AC'97 workaround for strange hardware
|
ac97_quirk - AC'97 workaround for strange hardware
|
||||||
See the description of intel8x0 module for details.
|
See the description of intel8x0 module for details.
|
||||||
|
|
||||||
|
@ -1232,18 +1292,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||||
default value 1.4. Then the interrupt number will be
|
default value 1.4. Then the interrupt number will be
|
||||||
assigned under 15. You might also upgrade your BIOS.
|
assigned under 15. You might also upgrade your BIOS.
|
||||||
|
|
||||||
Note: VIA8233/5 (not VIA8233A) can support DXS (direct sound)
|
Note: VIA8233/5/7 (not VIA8233A) can support DXS (direct sound)
|
||||||
channels as the first PCM. On these channels, up to 4
|
channels as the first PCM. On these channels, up to 4
|
||||||
streams can be played at the same time.
|
streams can be played at the same time, and the controller
|
||||||
|
can perform sample rate conversion with separate rates for
|
||||||
|
each channel.
|
||||||
As default (dxs_support = 0), 48k fixed rate is chosen
|
As default (dxs_support = 0), 48k fixed rate is chosen
|
||||||
except for the known devices since the output is often
|
except for the known devices since the output is often
|
||||||
noisy except for 48k on some mother boards due to the
|
noisy except for 48k on some mother boards due to the
|
||||||
bug of BIOS.
|
bug of BIOS.
|
||||||
Please try once dxs_support=1 and if it works on other
|
Please try once dxs_support=5 and if it works on other
|
||||||
sample rates (e.g. 44.1kHz of mp3 playback), please let us
|
sample rates (e.g. 44.1kHz of mp3 playback), please let us
|
||||||
know the PCI subsystem vendor/device id's (output of
|
know the PCI subsystem vendor/device id's (output of
|
||||||
"lspci -nv").
|
"lspci -nv").
|
||||||
If it doesn't work, try dxs_support=4. If it still doesn't
|
If dxs_support=5 does not work, try dxs_support=4; if it
|
||||||
|
doesn't work too, try dxs_support=1. (dxs_support=1 is
|
||||||
|
usually for old motherboards. The correct implementated
|
||||||
|
board should work with 4 or 5.) If it still doesn't
|
||||||
work and the default setting is ok, dxs_support=3 is the
|
work and the default setting is ok, dxs_support=3 is the
|
||||||
right choice. If the default setting doesn't work at all,
|
right choice. If the default setting doesn't work at all,
|
||||||
try dxs_support=2 to disable the DXS channels.
|
try dxs_support=2 to disable the DXS channels.
|
||||||
|
@ -1497,6 +1562,36 @@ Proc interfaces (/proc/asound)
|
||||||
echo "rvplayer 0 0 block" > /proc/asound/card0/pcm0p/oss
|
echo "rvplayer 0 0 block" > /proc/asound/card0/pcm0p/oss
|
||||||
|
|
||||||
|
|
||||||
|
Early Buffer Allocation
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Some drivers (e.g. hdsp) require the large contiguous buffers, and
|
||||||
|
sometimes it's too late to find such spaces when the driver module is
|
||||||
|
actually loaded due to memory fragmentation. You can pre-allocate the
|
||||||
|
PCM buffers by loading snd-page-alloc module and write commands to its
|
||||||
|
proc file in prior, for example, in the early boot stage like
|
||||||
|
/etc/init.d/*.local scripts.
|
||||||
|
|
||||||
|
Reading the proc file /proc/drivers/snd-page-alloc shows the current
|
||||||
|
usage of page allocation. In writing, you can send the following
|
||||||
|
commands to the snd-page-alloc driver:
|
||||||
|
|
||||||
|
- add VENDOR DEVICE MASK SIZE BUFFERS
|
||||||
|
|
||||||
|
VENDOR and DEVICE are PCI vendor and device IDs. They take
|
||||||
|
integer numbers (0x prefix is needed for the hex).
|
||||||
|
MASK is the PCI DMA mask. Pass 0 if not restricted.
|
||||||
|
SIZE is the size of each buffer to allocate. You can pass
|
||||||
|
k and m suffix for KB and MB. The max number is 16MB.
|
||||||
|
BUFFERS is the number of buffers to allocate. It must be greater
|
||||||
|
than 0. The max number is 4.
|
||||||
|
|
||||||
|
- erase
|
||||||
|
|
||||||
|
This will erase the all pre-allocated buffers which are not in
|
||||||
|
use.
|
||||||
|
|
||||||
|
|
||||||
Links
|
Links
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|
|
@ -89,19 +89,22 @@ and use the interleaved 4 channel data.
|
||||||
|
|
||||||
There are some control switchs affecting to the speaker connections:
|
There are some control switchs affecting to the speaker connections:
|
||||||
|
|
||||||
"Line-In As Rear" - As mentioned above, the line-in jack is used
|
"Line-In Mode" - an enum control to change the behavior of line-in
|
||||||
for the rear (3th and 4th channels) output.
|
jack. Either "Line-In", "Rear Output" or "Bass Output" can
|
||||||
"Line-In As Bass" - The line-in jack is used for the bass (5th
|
be selected. The last item is available only with model 039
|
||||||
and 6th channels) output.
|
or newer.
|
||||||
"Mic As Center/LFE" - The mic jack is used for the bass output.
|
When "Rear Output" is chosen, the surround channels 3 and 4
|
||||||
If this switch is on, you cannot use a microphone as a capture
|
are output to line-in jack.
|
||||||
source, of course.
|
"Mic-In Mode" - an enum control to change the behavior of mic-in
|
||||||
|
jack. Either "Mic-In" or "Center/LFE Output" can be
|
||||||
|
selected.
|
||||||
|
When "Center/LFE Output" is chosen, the center and bass
|
||||||
|
channels (channels 5 and 6) are output to mic-in jack.
|
||||||
|
|
||||||
Digital I/O
|
Digital I/O
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
The CM8x38 provides the excellent SPDIF capability with very chip
|
The CM8x38 provides the excellent SPDIF capability with very cheap
|
||||||
price (yes, that's the reason I bought the card :)
|
price (yes, that's the reason I bought the card :)
|
||||||
|
|
||||||
The SPDIF playback and capture are done via the third PCM device
|
The SPDIF playback and capture are done via the third PCM device
|
||||||
|
@ -122,8 +125,9 @@ respectively, so you cannot playback both analog and digital streams
|
||||||
simultaneously.
|
simultaneously.
|
||||||
|
|
||||||
To enable SPDIF output, you need to turn on "IEC958 Output Switch"
|
To enable SPDIF output, you need to turn on "IEC958 Output Switch"
|
||||||
control via mixer or alsactl. Then you'll see the red light on from
|
control via mixer or alsactl ("IEC958" is the official name of
|
||||||
the card so you know that's working obviously :)
|
so-called S/PDIF). Then you'll see the red light on from the card so
|
||||||
|
you know that's working obviously :)
|
||||||
The SPDIF input is always enabled, so you can hear SPDIF input data
|
The SPDIF input is always enabled, so you can hear SPDIF input data
|
||||||
from line-out with "IEC958 In Monitor" switch at any time (see
|
from line-out with "IEC958 In Monitor" switch at any time (see
|
||||||
below).
|
below).
|
||||||
|
@ -205,9 +209,10 @@ In addition to the standard SB mixer, CM8x38 provides more functions.
|
||||||
MIDI CONTROLLER
|
MIDI CONTROLLER
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The MPU401-UART interface is enabled as default only for the first
|
The MPU401-UART interface is disabled as default. You need to set
|
||||||
(CMIPCI) card. You need to set module option "midi_port" properly
|
module option "mpu_port" with a valid I/O port address to enable the
|
||||||
for the 2nd (CMIPCI) card.
|
MIDI support. The valid I/O ports are 0x300, 0x310, 0x320 and 0x330.
|
||||||
|
Choose the value which doesn't conflict with other cards.
|
||||||
|
|
||||||
There is _no_ hardware wavetable function on this chip (except for
|
There is _no_ hardware wavetable function on this chip (except for
|
||||||
OPL3 synth below).
|
OPL3 synth below).
|
||||||
|
@ -229,9 +234,11 @@ I don't know why..
|
||||||
Joystick and Modem
|
Joystick and Modem
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
The joystick and modem should be available by enabling the control
|
The legacy joystick is supported. To enable the joystick support, pass
|
||||||
switch "Joystick" and "Modem" respectively. But I myself have never
|
joystick_port=1 module option. The value 1 means the auto-detection.
|
||||||
tested them yet.
|
If the auto-detection fails, try to pass the exact I/O address.
|
||||||
|
|
||||||
|
The modem is enabled dynamically via a card control switch "Modem".
|
||||||
|
|
||||||
|
|
||||||
Debugging Information
|
Debugging Information
|
||||||
|
|
|
@ -371,7 +371,7 @@
|
||||||
<listitem><para>create <function>probe()</function> callback.</para></listitem>
|
<listitem><para>create <function>probe()</function> callback.</para></listitem>
|
||||||
<listitem><para>create <function>remove()</function> callback.</para></listitem>
|
<listitem><para>create <function>remove()</function> callback.</para></listitem>
|
||||||
<listitem><para>create pci_driver table which contains the three pointers above.</para></listitem>
|
<listitem><para>create pci_driver table which contains the three pointers above.</para></listitem>
|
||||||
<listitem><para>create <function>init()</function> function just calling <function>pci_module_init()</function> to register the pci_driver table defined above.</para></listitem>
|
<listitem><para>create <function>init()</function> function just calling <function>pci_register_driver()</function> to register the pci_driver table defined above.</para></listitem>
|
||||||
<listitem><para>create <function>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem>
|
<listitem><para>create <function>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
|
@ -1198,7 +1198,7 @@
|
||||||
/* initialization of the module */
|
/* initialization of the module */
|
||||||
static int __init alsa_card_mychip_init(void)
|
static int __init alsa_card_mychip_init(void)
|
||||||
{
|
{
|
||||||
return pci_module_init(&driver);
|
return pci_register_driver(&driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up the module */
|
/* clean up the module */
|
||||||
|
@ -1654,7 +1654,7 @@
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
static int __init alsa_card_mychip_init(void)
|
static int __init alsa_card_mychip_init(void)
|
||||||
{
|
{
|
||||||
return pci_module_init(&driver);
|
return pci_register_driver(&driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit alsa_card_mychip_exit(void)
|
static void __exit alsa_card_mychip_exit(void)
|
||||||
|
|
74
Documentation/sound/alsa/emu10k1-jack.txt
Normal file
74
Documentation/sound/alsa/emu10k1-jack.txt
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
This document is a guide to using the emu10k1 based devices with JACK for low
|
||||||
|
latency, multichannel recording functionality. All of my recent work to allow
|
||||||
|
Linux users to use the full capabilities of their hardware has been inspired
|
||||||
|
by the kX Project. Without their work I never would have discovered the true
|
||||||
|
power of this hardware.
|
||||||
|
|
||||||
|
http://www.kxproject.com
|
||||||
|
- Lee Revell, 2005.03.30
|
||||||
|
|
||||||
|
Low latency, multichannel audio with JACK and the emu10k1/emu10k2
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
Until recently, emu10k1 users on Linux did not have access to the same low
|
||||||
|
latency, multichannel features offered by the "kX ASIO" feature of their
|
||||||
|
Windows driver. As of ALSA 1.0.9 this is no more!
|
||||||
|
|
||||||
|
For those unfamiliar with kX ASIO, this consists of 16 capture and 16 playback
|
||||||
|
channels. With a post 2.6.9 Linux kernel, latencies down to 64 (1.33 ms) or
|
||||||
|
even 32 (0.66ms) frames should work well.
|
||||||
|
|
||||||
|
The configuration is slightly more involved than on Windows, as you have to
|
||||||
|
select the correct device for JACK to use. Actually, for qjackctl users it's
|
||||||
|
fairly self explanatory - select Duplex, then for capture and playback select
|
||||||
|
the multichannel devices, set the in and out channels to 16, and the sample
|
||||||
|
rate to 48000Hz. The command line looks like this:
|
||||||
|
|
||||||
|
/usr/local/bin/jackd -R -dalsa -r48000 -p64 -n2 -D -Chw:0,2 -Phw:0,3 -S
|
||||||
|
|
||||||
|
This will give you 16 input ports and 16 output ports.
|
||||||
|
|
||||||
|
The 16 output ports map onto the 16 FX buses (or the first 16 of 64, for the
|
||||||
|
Audigy). The mapping from FX bus to physical output is described in
|
||||||
|
SB-Live-mixer.txt (or Audigy-mixer.txt).
|
||||||
|
|
||||||
|
The 16 input ports are connected to the 16 physical inputs. Contrary to
|
||||||
|
popular belief, all emu10k1 cards are multichannel cards. Which of these
|
||||||
|
input channels have physical inputs connected to them depends on the card
|
||||||
|
model. Trial and error is highly recommended; the pinout diagrams
|
||||||
|
for the card have been reverse engineered by some enterprising kX users and are
|
||||||
|
available on the internet. Meterbridge is helpful here, and the kX forums are
|
||||||
|
packed with useful information.
|
||||||
|
|
||||||
|
Each input port will either correspond to a digital (SPDIF) input, an analog
|
||||||
|
input, or nothing. The one exception is the SBLive! 5.1. On these devices,
|
||||||
|
the second and third input ports are wired to the center/LFE output. You will
|
||||||
|
still see 16 capture channels, but only 14 are available for recording inputs.
|
||||||
|
|
||||||
|
This chart, borrowed from kxfxlib/da_asio51.cpp, describes the mapping of JACK
|
||||||
|
ports to FXBUS2 (multitrack recording input) and EXTOUT (physical output)
|
||||||
|
channels.
|
||||||
|
|
||||||
|
/*JACK (& ASIO) mappings on 10k1 5.1 SBLive cards:
|
||||||
|
--------------------------------------------
|
||||||
|
JACK Epilog FXBUS2(nr)
|
||||||
|
--------------------------------------------
|
||||||
|
capture_1 asio14 FXBUS2(0xe)
|
||||||
|
capture_2 asio15 FXBUS2(0xf)
|
||||||
|
capture_3 asio0 FXBUS2(0x0)
|
||||||
|
~capture_4 Center EXTOUT(0x11) // mapped to by Center
|
||||||
|
~capture_5 LFE EXTOUT(0x12) // mapped to by LFE
|
||||||
|
capture_6 asio3 FXBUS2(0x3)
|
||||||
|
capture_7 asio4 FXBUS2(0x4)
|
||||||
|
capture_8 asio5 FXBUS2(0x5)
|
||||||
|
capture_9 asio6 FXBUS2(0x6)
|
||||||
|
capture_10 asio7 FXBUS2(0x7)
|
||||||
|
capture_11 asio8 FXBUS2(0x8)
|
||||||
|
capture_12 asio9 FXBUS2(0x9)
|
||||||
|
capture_13 asio10 FXBUS2(0xa)
|
||||||
|
capture_14 asio11 FXBUS2(0xb)
|
||||||
|
capture_15 asio12 FXBUS2(0xc)
|
||||||
|
capture_16 asio13 FXBUS2(0xd)
|
||||||
|
*/
|
||||||
|
|
||||||
|
TODO: describe use of ld10k1/qlo10k1 in conjunction with JACK
|
362
Documentation/sound/alsa/hdspm.txt
Normal file
362
Documentation/sound/alsa/hdspm.txt
Normal file
|
@ -0,0 +1,362 @@
|
||||||
|
Software Interface ALSA-DSP MADI Driver
|
||||||
|
|
||||||
|
(translated from German, so no good English ;-),
|
||||||
|
2004 - winfried ritsch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Full functionality has been added to the driver. Since some of
|
||||||
|
the Controls and startup-options are ALSA-Standard and only the
|
||||||
|
special Controls are described and discussed below.
|
||||||
|
|
||||||
|
|
||||||
|
hardware functionality:
|
||||||
|
|
||||||
|
|
||||||
|
Audio transmission:
|
||||||
|
|
||||||
|
number of channels -- depends on transmission mode
|
||||||
|
|
||||||
|
The number of channels chosen is from 1..Nmax. The reason to
|
||||||
|
use for a lower number of channels is only resource allocation,
|
||||||
|
since unused DMA channels are disabled and less memory is
|
||||||
|
allocated. So also the throughput of the PCI system can be
|
||||||
|
scaled. (Only important for low performance boards).
|
||||||
|
|
||||||
|
Single Speed -- 1..64 channels
|
||||||
|
|
||||||
|
(Note: Choosing the 56channel mode for transmission or as
|
||||||
|
receiver, only 56 are transmitted/received over the MADI, but
|
||||||
|
all 64 channels are available for the mixer, so channel count
|
||||||
|
for the driver)
|
||||||
|
|
||||||
|
Double Speed -- 1..32 channels
|
||||||
|
|
||||||
|
Note: Choosing the 56-channel mode for
|
||||||
|
transmission/receive-mode , only 28 are transmitted/received
|
||||||
|
over the MADI, but all 32 channels are available for the mixer,
|
||||||
|
so channel count for the driver
|
||||||
|
|
||||||
|
|
||||||
|
Quad Speed -- 1..16 channels
|
||||||
|
|
||||||
|
Note: Choosing the 56-channel mode for
|
||||||
|
transmission/receive-mode , only 14 are transmitted/received
|
||||||
|
over the MADI, but all 16 channels are available for the mixer,
|
||||||
|
so channel count for the driver
|
||||||
|
|
||||||
|
Format -- signed 32 Bit Little Endian (SNDRV_PCM_FMTBIT_S32_LE)
|
||||||
|
|
||||||
|
Sample Rates --
|
||||||
|
|
||||||
|
Single Speed -- 32000, 44100, 48000
|
||||||
|
|
||||||
|
Double Speed -- 64000, 88200, 96000 (untested)
|
||||||
|
|
||||||
|
Quad Speed -- 128000, 176400, 192000 (untested)
|
||||||
|
|
||||||
|
access-mode -- MMAP (memory mapped), Not interleaved
|
||||||
|
(PCM_NON-INTERLEAVED)
|
||||||
|
|
||||||
|
buffer-sizes -- 64,128,256,512,1024,2048,8192 Samples
|
||||||
|
|
||||||
|
fragments -- 2
|
||||||
|
|
||||||
|
Hardware-pointer -- 2 Modi
|
||||||
|
|
||||||
|
|
||||||
|
The Card supports the readout of the actual Buffer-pointer,
|
||||||
|
where DMA reads/writes. Since of the bulk mode of PCI it is only
|
||||||
|
64 Byte accurate. SO it is not really usable for the
|
||||||
|
ALSA-mid-level functions (here the buffer-ID gives a better
|
||||||
|
result), but if MMAP is used by the application. Therefore it
|
||||||
|
can be configured at load-time with the parameter
|
||||||
|
precise-pointer.
|
||||||
|
|
||||||
|
|
||||||
|
(Hint: Experimenting I found that the pointer is maximum 64 to
|
||||||
|
large never to small. So if you subtract 64 you always have a
|
||||||
|
safe pointer for writing, which is used on this mode inside
|
||||||
|
ALSA. In theory now you can get now a latency as low as 16
|
||||||
|
Samples, which is a quarter of the interrupt possibilities.)
|
||||||
|
|
||||||
|
Precise Pointer -- off
|
||||||
|
interrupt used for pointer-calculation
|
||||||
|
|
||||||
|
Precise Pointer -- on
|
||||||
|
hardware pointer used.
|
||||||
|
|
||||||
|
Controller:
|
||||||
|
|
||||||
|
|
||||||
|
Since DSP-MADI-Mixer has 8152 Fader, it does not make sense to
|
||||||
|
use the standard mixer-controls, since this would break most of
|
||||||
|
(especially graphic) ALSA-Mixer GUIs. So Mixer control has be
|
||||||
|
provided by a 2-dimensional controller using the
|
||||||
|
hwdep-interface.
|
||||||
|
|
||||||
|
Also all 128+256 Peak and RMS-Meter can be accessed via the
|
||||||
|
hwdep-interface. Since it could be a performance problem always
|
||||||
|
copying and converting Peak and RMS-Levels even if you just need
|
||||||
|
one, I decided to export the hardware structure, so that of
|
||||||
|
needed some driver-guru can implement a memory-mapping of mixer
|
||||||
|
or peak-meters over ioctl, or also to do only copying and no
|
||||||
|
conversion. A test-application shows the usage of the controller.
|
||||||
|
|
||||||
|
Latency Controls --- not implemented !!!
|
||||||
|
|
||||||
|
|
||||||
|
Note: Within the windows-driver the latency is accessible of a
|
||||||
|
control-panel, but buffer-sizes are controlled with ALSA from
|
||||||
|
hwparams-calls and should not be changed in run-state, I did not
|
||||||
|
implement it here.
|
||||||
|
|
||||||
|
|
||||||
|
System Clock -- suspended !!!!
|
||||||
|
|
||||||
|
Name -- "System Clock Mode"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- "Master" "Slave"
|
||||||
|
|
||||||
|
|
||||||
|
!!!! This is a hardware-function but is in conflict with the
|
||||||
|
Clock-source controller, which is a kind of ALSA-standard. I
|
||||||
|
makes sense to set the card to a special mode (master at some
|
||||||
|
frequency or slave), since even not using an Audio-application
|
||||||
|
a studio should have working synchronisations setup. So use
|
||||||
|
Clock-source-controller instead !!!!
|
||||||
|
|
||||||
|
Clock Source
|
||||||
|
|
||||||
|
Name -- "Sample Clock Source"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- "AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz",
|
||||||
|
"Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz",
|
||||||
|
"Internal 96.0 kHz"
|
||||||
|
|
||||||
|
Choose between Master at a specific Frequency and so also the
|
||||||
|
Speed-mode or Slave (Autosync). Also see "Preferred Sync Ref"
|
||||||
|
|
||||||
|
|
||||||
|
!!!! This is no pure hardware function but was implemented by
|
||||||
|
ALSA by some ALSA-drivers before, so I use it also. !!!
|
||||||
|
|
||||||
|
|
||||||
|
Preferred Sync Ref
|
||||||
|
|
||||||
|
Name -- "Preferred Sync Reference"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- "Word" "MADI"
|
||||||
|
|
||||||
|
|
||||||
|
Within the Auto-sync-Mode the preferred Sync Source can be
|
||||||
|
chosen. If it is not available another is used if possible.
|
||||||
|
|
||||||
|
Note: Since MADI has a much higher bit-rate than word-clock, the
|
||||||
|
card should synchronise better in MADI Mode. But since the
|
||||||
|
RME-PLL is very good, there are almost no problems with
|
||||||
|
word-clock too. I never found a difference.
|
||||||
|
|
||||||
|
|
||||||
|
TX 64 channel ---
|
||||||
|
|
||||||
|
Name -- "TX 64 channels mode"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- 0 1
|
||||||
|
|
||||||
|
Using 64-channel-modus (1) or 56-channel-modus for
|
||||||
|
MADI-transmission (0).
|
||||||
|
|
||||||
|
|
||||||
|
Note: This control is for output only. Input-mode is detected
|
||||||
|
automatically from hardware sending MADI.
|
||||||
|
|
||||||
|
|
||||||
|
Clear TMS ---
|
||||||
|
|
||||||
|
Name -- "Clear Track Marker"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- 0 1
|
||||||
|
|
||||||
|
|
||||||
|
Don't use to lower 5 Audio-bits on AES as additional Bits.
|
||||||
|
|
||||||
|
|
||||||
|
Safe Mode oder Auto Input ---
|
||||||
|
|
||||||
|
Name -- "Safe Mode"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- 0 1
|
||||||
|
|
||||||
|
(default on)
|
||||||
|
|
||||||
|
If on (1), then if either the optical or coaxial connection
|
||||||
|
has a failure, there is a takeover to the working one, with no
|
||||||
|
sample failure. Its only useful if you use the second as a
|
||||||
|
backup connection.
|
||||||
|
|
||||||
|
Input ---
|
||||||
|
|
||||||
|
Name -- "Input Select"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- optical coaxial
|
||||||
|
|
||||||
|
|
||||||
|
Choosing the Input, optical or coaxial. If Safe-mode is active,
|
||||||
|
this is the preferred Input.
|
||||||
|
|
||||||
|
-------------- Mixer ----------------------
|
||||||
|
|
||||||
|
Mixer
|
||||||
|
|
||||||
|
Name -- "Mixer"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values - <channel-number 0-127> <Value 0-65535>
|
||||||
|
|
||||||
|
|
||||||
|
Here as a first value the channel-index is taken to get/set the
|
||||||
|
corresponding mixer channel, where 0-63 are the input to output
|
||||||
|
fader and 64-127 the playback to outputs fader. Value 0
|
||||||
|
is channel muted 0 and 32768 an amplification of 1.
|
||||||
|
|
||||||
|
Chn 1-64
|
||||||
|
|
||||||
|
fast mixer for the ALSA-mixer utils. The diagonal of the
|
||||||
|
mixer-matrix is implemented from playback to output.
|
||||||
|
|
||||||
|
|
||||||
|
Line Out
|
||||||
|
|
||||||
|
Name -- "Line Out"
|
||||||
|
|
||||||
|
Access -- Read Write
|
||||||
|
|
||||||
|
Values -- 0 1
|
||||||
|
|
||||||
|
Switching on and off the analog out, which has nothing to do
|
||||||
|
with mixing or routing. the analog outs reflects channel 63,64.
|
||||||
|
|
||||||
|
|
||||||
|
--- information (only read access):
|
||||||
|
|
||||||
|
Sample Rate
|
||||||
|
|
||||||
|
Name -- "System Sample Rate"
|
||||||
|
|
||||||
|
Access -- Read-only
|
||||||
|
|
||||||
|
getting the sample rate.
|
||||||
|
|
||||||
|
|
||||||
|
External Rate measured
|
||||||
|
|
||||||
|
Name -- "External Rate"
|
||||||
|
|
||||||
|
Access -- Read only
|
||||||
|
|
||||||
|
|
||||||
|
Should be "Autosync Rate", but Name used is
|
||||||
|
ALSA-Scheme. External Sample frequency liked used on Autosync is
|
||||||
|
reported.
|
||||||
|
|
||||||
|
|
||||||
|
MADI Sync Status
|
||||||
|
|
||||||
|
Name -- "MADI Sync Lock Status"
|
||||||
|
|
||||||
|
Access -- Read
|
||||||
|
|
||||||
|
Values -- 0,1,2
|
||||||
|
|
||||||
|
MADI-Input is 0=Unlocked, 1=Locked, or 2=Synced.
|
||||||
|
|
||||||
|
|
||||||
|
Word Clock Sync Status
|
||||||
|
|
||||||
|
Name -- "Word Clock Lock Status"
|
||||||
|
|
||||||
|
Access -- Read
|
||||||
|
|
||||||
|
Values -- 0,1,2
|
||||||
|
|
||||||
|
Word Clock Input is 0=Unlocked, 1=Locked, or 2=Synced.
|
||||||
|
|
||||||
|
AutoSync
|
||||||
|
|
||||||
|
Name -- "AutoSync Reference"
|
||||||
|
|
||||||
|
Access -- Read
|
||||||
|
|
||||||
|
Values -- "WordClock", "MADI", "None"
|
||||||
|
|
||||||
|
Sync-Reference is either "WordClock", "MADI" or none.
|
||||||
|
|
||||||
|
RX 64ch --- noch nicht implementiert
|
||||||
|
|
||||||
|
MADI-Receiver is in 64 channel mode oder 56 channel mode.
|
||||||
|
|
||||||
|
|
||||||
|
AB_inp --- not tested
|
||||||
|
|
||||||
|
Used input for Auto-Input.
|
||||||
|
|
||||||
|
|
||||||
|
actual Buffer Position --- not implemented
|
||||||
|
|
||||||
|
!!! this is a ALSA internal function, so no control is used !!!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Calling Parameter:
|
||||||
|
|
||||||
|
index int array (min = 1, max = 8),
|
||||||
|
"Index value for RME HDSPM interface." card-index within ALSA
|
||||||
|
|
||||||
|
note: ALSA-standard
|
||||||
|
|
||||||
|
id string array (min = 1, max = 8),
|
||||||
|
"ID string for RME HDSPM interface."
|
||||||
|
|
||||||
|
note: ALSA-standard
|
||||||
|
|
||||||
|
enable int array (min = 1, max = 8),
|
||||||
|
"Enable/disable specific HDSPM sound-cards."
|
||||||
|
|
||||||
|
note: ALSA-standard
|
||||||
|
|
||||||
|
precise_ptr int array (min = 1, max = 8),
|
||||||
|
"Enable precise pointer, or disable."
|
||||||
|
|
||||||
|
note: Use only when the application supports this (which is a special case).
|
||||||
|
|
||||||
|
line_outs_monitor int array (min = 1, max = 8),
|
||||||
|
"Send playback streams to analog outs by default."
|
||||||
|
|
||||||
|
|
||||||
|
note: each playback channel is mixed to the same numbered output
|
||||||
|
channel (routed). This is against the ALSA-convention, where all
|
||||||
|
channels have to be muted on after loading the driver, but was
|
||||||
|
used before on other cards, so i historically use it again)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enable_monitor int array (min = 1, max = 8),
|
||||||
|
"Enable Analog Out on Channel 63/64 by default."
|
||||||
|
|
||||||
|
note: here the analog output is enabled (but not routed).
|
|
@ -1,19 +1,92 @@
|
||||||
Any w1 device must be connected to w1 bus master device - for example
|
The 1-wire (w1) subsystem
|
||||||
ds9490 usb device or w1-over-GPIO or RS232 converter.
|
------------------------------------------------------------------
|
||||||
Driver for w1 bus master must provide several functions(you can find
|
The 1-wire bus is a simple master-slave bus that communicates via a single
|
||||||
them in struct w1_bus_master definition in w1.h) which then will be
|
signal wire (plus ground, so two wires).
|
||||||
called by w1 core to send various commands over w1 bus(by default it is
|
|
||||||
reset and search commands). When some device is found on the bus, w1 core
|
Devices communicate on the bus by pulling the signal to ground via an open
|
||||||
checks if driver for it's family is loaded.
|
drain output and by sampling the logic level of the signal line.
|
||||||
If driver is loaded w1 core creates new w1_slave object and registers it
|
|
||||||
in the system(creates some generic sysfs files(struct w1_family_ops in
|
The w1 subsystem provides the framework for managing w1 masters and
|
||||||
w1_family.h), notifies any registered listener and so on...).
|
communication with slaves.
|
||||||
It is device driver's business to provide any communication method
|
|
||||||
upstream.
|
All w1 slave devices must be connected to a w1 bus master device.
|
||||||
For example w1_therm driver(ds18?20 thermal sensor family driver)
|
|
||||||
provides temperature reading function which is bound to ->rbin() method
|
Example w1 master devices:
|
||||||
of the above w1_family_ops structure.
|
DS9490 usb device
|
||||||
w1_smem - driver for simple 64bit memory cell provides ID reading
|
W1-over-GPIO
|
||||||
method.
|
DS2482 (i2c to w1 bridge)
|
||||||
|
Emulated devices, such as a RS232 converter, parallel port adapter, etc
|
||||||
|
|
||||||
|
|
||||||
|
What does the w1 subsystem do?
|
||||||
|
------------------------------------------------------------------
|
||||||
|
When a w1 master driver registers with the w1 subsystem, the following occurs:
|
||||||
|
|
||||||
|
- sysfs entries for that w1 master are created
|
||||||
|
- the w1 bus is periodically searched for new slave devices
|
||||||
|
|
||||||
|
When a device is found on the bus, w1 core checks if driver for it's family is
|
||||||
|
loaded. If so, the family driver is attached to the slave.
|
||||||
|
If there is no driver for the family, a simple sysfs entry is created
|
||||||
|
for the slave device.
|
||||||
|
|
||||||
|
|
||||||
|
W1 device families
|
||||||
|
------------------------------------------------------------------
|
||||||
|
Slave devices are handled by a driver written for a family of w1 devices.
|
||||||
|
|
||||||
|
A family driver populates a struct w1_family_ops (see w1_family.h) and
|
||||||
|
registers with the w1 subsystem.
|
||||||
|
|
||||||
|
Current family drivers:
|
||||||
|
w1_therm - (ds18?20 thermal sensor family driver)
|
||||||
|
provides temperature reading function which is bound to ->rbin() method
|
||||||
|
of the above w1_family_ops structure.
|
||||||
|
|
||||||
|
w1_smem - driver for simple 64bit memory cell provides ID reading method.
|
||||||
|
|
||||||
You can call above methods by reading appropriate sysfs files.
|
You can call above methods by reading appropriate sysfs files.
|
||||||
|
|
||||||
|
|
||||||
|
What does a w1 master driver need to implement?
|
||||||
|
------------------------------------------------------------------
|
||||||
|
|
||||||
|
The driver for w1 bus master must provide at minimum two functions.
|
||||||
|
|
||||||
|
Emulated devices must provide the ability to set the output signal level
|
||||||
|
(write_bit) and sample the signal level (read_bit).
|
||||||
|
|
||||||
|
Devices that support the 1-wire natively must provide the ability to write and
|
||||||
|
sample a bit (touch_bit) and reset the bus (reset_bus).
|
||||||
|
|
||||||
|
Most hardware provides higher-level functions that offload w1 handling.
|
||||||
|
See struct w1_bus_master definition in w1.h for details.
|
||||||
|
|
||||||
|
|
||||||
|
w1 master sysfs interface
|
||||||
|
------------------------------------------------------------------
|
||||||
|
<xx-xxxxxxxxxxxxx> - a directory for a found device. The format is family-serial
|
||||||
|
bus - (standard) symlink to the w1 bus
|
||||||
|
driver - (standard) symlink to the w1 driver
|
||||||
|
w1_master_attempts - the number of times a search was attempted
|
||||||
|
w1_master_max_slave_count
|
||||||
|
- the maximum slaves that may be attached to a master
|
||||||
|
w1_master_name - the name of the device (w1_bus_masterX)
|
||||||
|
w1_master_search - the number of searches left to do, -1=continual (default)
|
||||||
|
w1_master_slave_count
|
||||||
|
- the number of slaves found
|
||||||
|
w1_master_slaves - the names of the slaves, one per line
|
||||||
|
w1_master_timeout - the delay in seconds between searches
|
||||||
|
|
||||||
|
If you have a w1 bus that never changes (you don't add or remove devices),
|
||||||
|
you can set w1_master_search to a positive value to disable searches.
|
||||||
|
|
||||||
|
|
||||||
|
w1 slave sysfs interface
|
||||||
|
------------------------------------------------------------------
|
||||||
|
bus - (standard) symlink to the w1 bus
|
||||||
|
driver - (standard) symlink to the w1 driver
|
||||||
|
name - the device name, usually the same as the directory name
|
||||||
|
w1_slave - (optional) a binary file whose meaning depends on the
|
||||||
|
family driver
|
||||||
|
|
||||||
|
|
21
MAINTAINERS
21
MAINTAINERS
|
@ -194,7 +194,7 @@ S: Maintained
|
||||||
ADM1025 HARDWARE MONITOR DRIVER
|
ADM1025 HARDWARE MONITOR DRIVER
|
||||||
P: Jean Delvare
|
P: Jean Delvare
|
||||||
M: khali@linux-fr.org
|
M: khali@linux-fr.org
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
ADT746X FAN DRIVER
|
ADT746X FAN DRIVER
|
||||||
|
@ -242,7 +242,7 @@ S: Maintained
|
||||||
ALI1563 I2C DRIVER
|
ALI1563 I2C DRIVER
|
||||||
P: Rudolf Marek
|
P: Rudolf Marek
|
||||||
M: r.marek@sh.cvut.cz
|
M: r.marek@sh.cvut.cz
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
ALPHA PORT
|
ALPHA PORT
|
||||||
|
@ -265,6 +265,11 @@ P: Arnaldo Carvalho de Melo
|
||||||
M: acme@conectiva.com.br
|
M: acme@conectiva.com.br
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ARC FRAMEBUFFER DRIVER
|
||||||
|
P: Jaya Kumar
|
||||||
|
M: jayalk@intworks.biz
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
ARM26 ARCHITECTURE
|
ARM26 ARCHITECTURE
|
||||||
P: Ian Molton
|
P: Ian Molton
|
||||||
M: spyro@f2s.com
|
M: spyro@f2s.com
|
||||||
|
@ -997,7 +1002,7 @@ P: Greg Kroah-Hartman
|
||||||
M: greg@kroah.com
|
M: greg@kroah.com
|
||||||
P: Jean Delvare
|
P: Jean Delvare
|
||||||
M: khali@linux-fr.org
|
M: khali@linux-fr.org
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
W: http://www.lm-sensors.nu/
|
W: http://www.lm-sensors.nu/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
@ -1425,13 +1430,13 @@ S: Supported
|
||||||
LM83 HARDWARE MONITOR DRIVER
|
LM83 HARDWARE MONITOR DRIVER
|
||||||
P: Jean Delvare
|
P: Jean Delvare
|
||||||
M: khali@linux-fr.org
|
M: khali@linux-fr.org
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
LM90 HARDWARE MONITOR DRIVER
|
LM90 HARDWARE MONITOR DRIVER
|
||||||
P: Jean Delvare
|
P: Jean Delvare
|
||||||
M: khali@linux-fr.org
|
M: khali@linux-fr.org
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
|
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
|
||||||
|
@ -2070,7 +2075,7 @@ S: Maintained
|
||||||
SMSC47M1 HARDWARE MONITOR DRIVER
|
SMSC47M1 HARDWARE MONITOR DRIVER
|
||||||
P: Jean Delvare
|
P: Jean Delvare
|
||||||
M: khali@linux-fr.org
|
M: khali@linux-fr.org
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
|
|
||||||
SMB FILESYSTEM
|
SMB FILESYSTEM
|
||||||
|
@ -2609,7 +2614,7 @@ S: Orphan
|
||||||
W1 DALLAS'S 1-WIRE BUS
|
W1 DALLAS'S 1-WIRE BUS
|
||||||
P: Evgeniy Polyakov
|
P: Evgeniy Polyakov
|
||||||
M: johnpol@2ka.mipt.ru
|
M: johnpol@2ka.mipt.ru
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
W83L51xD SD/MMC CARD INTERFACE DRIVER
|
W83L51xD SD/MMC CARD INTERFACE DRIVER
|
||||||
|
@ -2622,7 +2627,7 @@ S: Maintained
|
||||||
W83L785TS HARDWARE MONITOR DRIVER
|
W83L785TS HARDWARE MONITOR DRIVER
|
||||||
P: Jean Delvare
|
P: Jean Delvare
|
||||||
M: khali@linux-fr.org
|
M: khali@linux-fr.org
|
||||||
L: sensors@stimpy.netroedge.com
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
|
|
||||||
WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
|
WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
|
||||||
|
|
|
@ -67,10 +67,6 @@ config GENERIC_BUST_SPINLOCK
|
||||||
config GENERIC_ISA_DMA
|
config GENERIC_ISA_DMA
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config GENERIC_IOMAP
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config FIQ
|
config FIQ
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
@ -202,6 +198,11 @@ config ARCH_H720X
|
||||||
help
|
help
|
||||||
This enables support for systems based on the Hynix HMS720x
|
This enables support for systems based on the Hynix HMS720x
|
||||||
|
|
||||||
|
config ARCH_AAEC2000
|
||||||
|
bool "Agilent AAEC-2000 based"
|
||||||
|
help
|
||||||
|
This enables support for systems based on the Agilent AAEC-2000
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
source "arch/arm/mach-clps711x/Kconfig"
|
source "arch/arm/mach-clps711x/Kconfig"
|
||||||
|
@ -234,6 +235,8 @@ source "arch/arm/mach-h720x/Kconfig"
|
||||||
|
|
||||||
source "arch/arm/mach-versatile/Kconfig"
|
source "arch/arm/mach-versatile/Kconfig"
|
||||||
|
|
||||||
|
source "arch/arm/mach-aaec2000/Kconfig"
|
||||||
|
|
||||||
# Definitions to make life easier
|
# Definitions to make life easier
|
||||||
config ARCH_ACORN
|
config ARCH_ACORN
|
||||||
bool
|
bool
|
||||||
|
@ -277,7 +280,7 @@ config ISA_DMA_API
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config PCI
|
config PCI
|
||||||
bool "PCI support" if ARCH_INTEGRATOR_AP
|
bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB
|
||||||
help
|
help
|
||||||
Find out whether you have a PCI motherboard. PCI is the name of a
|
Find out whether you have a PCI motherboard. PCI is the name of a
|
||||||
bus system, i.e. the way the CPU talks to the other stuff inside
|
bus system, i.e. the way the CPU talks to the other stuff inside
|
||||||
|
|
|
@ -97,6 +97,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
|
||||||
machine-$(CONFIG_ARCH_VERSATILE) := versatile
|
machine-$(CONFIG_ARCH_VERSATILE) := versatile
|
||||||
machine-$(CONFIG_ARCH_IMX) := imx
|
machine-$(CONFIG_ARCH_IMX) := imx
|
||||||
machine-$(CONFIG_ARCH_H720X) := h720x
|
machine-$(CONFIG_ARCH_H720X) := h720x
|
||||||
|
machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_EBSA110),y)
|
ifeq ($(CONFIG_ARCH_EBSA110),y)
|
||||||
# This is what happens if you forget the IOCS16 line.
|
# This is what happens if you forget the IOCS16 line.
|
||||||
|
|
|
@ -169,7 +169,7 @@ static void amba_device_release(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define amba_attr(name,fmt,arg...) \
|
#define amba_attr(name,fmt,arg...) \
|
||||||
static ssize_t show_##name(struct device *_dev, char *buf) \
|
static ssize_t show_##name(struct device *_dev, struct device_attribute *attr, char *buf) \
|
||||||
{ \
|
{ \
|
||||||
struct amba_device *dev = to_amba_device(_dev); \
|
struct amba_device *dev = to_amba_device(_dev); \
|
||||||
return sprintf(buf, fmt, arg); \
|
return sprintf(buf, fmt, arg); \
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include <linux/dmapool.h>
|
#include <linux/dmapool.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
|
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
#undef STATS
|
#undef STATS
|
||||||
|
@ -91,15 +93,12 @@ static void print_alloc_stats(struct dmabounce_device_info *device_info)
|
||||||
static inline struct dmabounce_device_info *
|
static inline struct dmabounce_device_info *
|
||||||
find_dmabounce_dev(struct device *dev)
|
find_dmabounce_dev(struct device *dev)
|
||||||
{
|
{
|
||||||
struct list_head *entry;
|
struct dmabounce_device_info *d;
|
||||||
|
|
||||||
list_for_each(entry, &dmabounce_devs) {
|
|
||||||
struct dmabounce_device_info *d =
|
|
||||||
list_entry(entry, struct dmabounce_device_info, node);
|
|
||||||
|
|
||||||
|
list_for_each_entry(d, &dmabounce_devs, node)
|
||||||
if (d->dev == dev)
|
if (d->dev == dev)
|
||||||
return d;
|
return d;
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,15 +169,11 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
|
||||||
static inline struct safe_buffer *
|
static inline struct safe_buffer *
|
||||||
find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
|
find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
|
||||||
{
|
{
|
||||||
struct list_head *entry;
|
struct safe_buffer *b;
|
||||||
|
|
||||||
list_for_each(entry, &device_info->safe_buffers) {
|
|
||||||
struct safe_buffer *b =
|
|
||||||
list_entry(entry, struct safe_buffer, node);
|
|
||||||
|
|
||||||
|
list_for_each_entry(b, &device_info->safe_buffers, node)
|
||||||
if (b->safe_dma_addr == safe_dma_addr)
|
if (b->safe_dma_addr == safe_dma_addr)
|
||||||
return b;
|
return b;
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -299,15 +294,26 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||||
__func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr),
|
__func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr),
|
||||||
buf->safe, (void *) buf->safe_dma_addr);
|
buf->safe, (void *) buf->safe_dma_addr);
|
||||||
|
|
||||||
|
|
||||||
DO_STATS ( device_info->bounce_count++ );
|
DO_STATS ( device_info->bounce_count++ );
|
||||||
|
|
||||||
if ((dir == DMA_FROM_DEVICE) ||
|
if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
|
||||||
(dir == DMA_BIDIRECTIONAL)) {
|
unsigned long ptr;
|
||||||
|
|
||||||
dev_dbg(dev,
|
dev_dbg(dev,
|
||||||
"%s: copy back safe %p to unsafe %p size %d\n",
|
"%s: copy back safe %p to unsafe %p size %d\n",
|
||||||
__func__, buf->safe, buf->ptr, size);
|
__func__, buf->safe, buf->ptr, size);
|
||||||
memcpy(buf->ptr, buf->safe, size);
|
memcpy(buf->ptr, buf->safe, size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA buffers must have the same cache properties
|
||||||
|
* as if they were really used for DMA - which means
|
||||||
|
* data must be written back to RAM. Note that
|
||||||
|
* we don't use dmac_flush_range() here for the
|
||||||
|
* bidirectional case because we know the cache
|
||||||
|
* lines will be coherent with the data written.
|
||||||
|
*/
|
||||||
|
ptr = (unsigned long)buf->ptr;
|
||||||
|
dmac_clean_range(ptr, ptr + size);
|
||||||
}
|
}
|
||||||
free_safe_buffer(device_info, buf);
|
free_safe_buffer(device_info, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -721,16 +721,17 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sa1111_remove_one(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
device_unregister(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void __sa1111_remove(struct sa1111 *sachip)
|
static void __sa1111_remove(struct sa1111 *sachip)
|
||||||
{
|
{
|
||||||
struct list_head *l, *n;
|
|
||||||
void __iomem *irqbase = sachip->base + SA1111_INTC;
|
void __iomem *irqbase = sachip->base + SA1111_INTC;
|
||||||
|
|
||||||
list_for_each_safe(l, n, &sachip->dev->children) {
|
device_for_each_child(sachip->dev, NULL, sa1111_remove_one);
|
||||||
struct device *d = list_to_dev(l);
|
|
||||||
|
|
||||||
device_unregister(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* disable all IRQs */
|
/* disable all IRQs */
|
||||||
sa1111_writel(0, irqbase + SA1111_INTEN0);
|
sa1111_writel(0, irqbase + SA1111_INTEN0);
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
* them early in the boot process, then pass them to the appropriate drivers.
|
* them early in the boot process, then pass them to the appropriate drivers.
|
||||||
* Not all devices use all paramaters but the format is common to all.
|
* Not all devices use all paramaters but the format is common to all.
|
||||||
*/
|
*/
|
||||||
#ifdef ARCH_SA1100
|
#ifdef CONFIG_ARCH_SA1100
|
||||||
#define PARAM_BASE 0xe8ffc000
|
#define PARAM_BASE 0xe8ffc000
|
||||||
#else
|
#else
|
||||||
#define PARAM_BASE 0xa0000a00
|
#define PARAM_BASE 0xa0000a00
|
||||||
|
|
|
@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
|
||||||
#
|
#
|
||||||
# Loadable module support
|
# Loadable module support
|
||||||
#
|
#
|
||||||
# CONFIG_MODULES is not set
|
CONFIG_MODULES=y
|
||||||
|
CONFIG_MODULE_UNLOAD=y
|
||||||
|
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||||
|
CONFIG_OBSOLETE_MODPARM=y
|
||||||
|
# CONFIG_MODVERSIONS is not set
|
||||||
|
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||||
|
CONFIG_KMOD=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Type
|
# System Type
|
||||||
|
|
|
@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
|
||||||
#
|
#
|
||||||
# Loadable module support
|
# Loadable module support
|
||||||
#
|
#
|
||||||
# CONFIG_MODULES is not set
|
CONFIG_MODULES=y
|
||||||
|
CONFIG_MODULE_UNLOAD=y
|
||||||
|
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||||
|
CONFIG_OBSOLETE_MODPARM=y
|
||||||
|
# CONFIG_MODVERSIONS is not set
|
||||||
|
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||||
|
CONFIG_KMOD=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Type
|
# System Type
|
||||||
|
|
|
@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
|
||||||
#
|
#
|
||||||
# Loadable module support
|
# Loadable module support
|
||||||
#
|
#
|
||||||
# CONFIG_MODULES is not set
|
CONFIG_MODULES=y
|
||||||
|
CONFIG_MODULE_UNLOAD=y
|
||||||
|
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||||
|
CONFIG_OBSOLETE_MODPARM=y
|
||||||
|
# CONFIG_MODVERSIONS is not set
|
||||||
|
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||||
|
CONFIG_KMOD=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Type
|
# System Type
|
||||||
|
|
|
@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
|
||||||
#
|
#
|
||||||
# Loadable module support
|
# Loadable module support
|
||||||
#
|
#
|
||||||
# CONFIG_MODULES is not set
|
CONFIG_MODULES=y
|
||||||
|
CONFIG_MODULE_UNLOAD=y
|
||||||
|
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||||
|
CONFIG_OBSOLETE_MODPARM=y
|
||||||
|
# CONFIG_MODVERSIONS is not set
|
||||||
|
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||||
|
CONFIG_KMOD=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Type
|
# System Type
|
||||||
|
|
|
@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
|
||||||
#
|
#
|
||||||
# Loadable module support
|
# Loadable module support
|
||||||
#
|
#
|
||||||
# CONFIG_MODULES is not set
|
CONFIG_MODULES=y
|
||||||
|
CONFIG_MODULE_UNLOAD=y
|
||||||
|
# CONFIG_MODULE_FORCE_UNLOAD is not set
|
||||||
|
CONFIG_OBSOLETE_MODPARM=y
|
||||||
|
# CONFIG_MODVERSIONS is not set
|
||||||
|
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||||
|
CONFIG_KMOD=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# System Type
|
# System Type
|
||||||
|
|
|
@ -6,7 +6,7 @@ AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
|
||||||
|
|
||||||
# Object file lists.
|
# Object file lists.
|
||||||
|
|
||||||
obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \
|
obj-y := compat.o dma.o entry-armv.o entry-common.o irq.o \
|
||||||
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
|
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
|
||||||
time.o traps.o
|
time.o traps.o
|
||||||
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* linux/arch/arm/kernel/arch.c
|
|
||||||
*
|
|
||||||
* Architecture specific fixups.
|
|
||||||
*/
|
|
||||||
#include <linux/config.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
#include <asm/elf.h>
|
|
||||||
#include <asm/page.h>
|
|
||||||
#include <asm/setup.h>
|
|
||||||
#include <asm/mach/arch.h>
|
|
||||||
|
|
||||||
unsigned int vram_size;
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ACORN
|
|
||||||
|
|
||||||
unsigned int memc_ctrl_reg;
|
|
||||||
unsigned int number_mfm_drives;
|
|
||||||
|
|
||||||
static int __init parse_tag_acorn(const struct tag *tag)
|
|
||||||
{
|
|
||||||
memc_ctrl_reg = tag->u.acorn.memc_control_reg;
|
|
||||||
number_mfm_drives = tag->u.acorn.adfsdrives;
|
|
||||||
|
|
||||||
switch (tag->u.acorn.vram_pages) {
|
|
||||||
case 512:
|
|
||||||
vram_size += PAGE_SIZE * 256;
|
|
||||||
case 256:
|
|
||||||
vram_size += PAGE_SIZE * 256;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
if (vram_size) {
|
|
||||||
desc->video_start = 0x02000000;
|
|
||||||
desc->video_end = 0x02000000 + vram_size;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__tagtable(ATAG_ACORN, parse_tag_acorn);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -866,19 +866,19 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ecard_show_irq(struct device *dev, char *buf)
|
static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct expansion_card *ec = ECARD_DEV(dev);
|
struct expansion_card *ec = ECARD_DEV(dev);
|
||||||
return sprintf(buf, "%u\n", ec->irq);
|
return sprintf(buf, "%u\n", ec->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ecard_show_dma(struct device *dev, char *buf)
|
static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct expansion_card *ec = ECARD_DEV(dev);
|
struct expansion_card *ec = ECARD_DEV(dev);
|
||||||
return sprintf(buf, "%u\n", ec->dma);
|
return sprintf(buf, "%u\n", ec->dma);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ecard_show_resources(struct device *dev, char *buf)
|
static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct expansion_card *ec = ECARD_DEV(dev);
|
struct expansion_card *ec = ECARD_DEV(dev);
|
||||||
char *str = buf;
|
char *str = buf;
|
||||||
|
@ -893,19 +893,19 @@ static ssize_t ecard_show_resources(struct device *dev, char *buf)
|
||||||
return str - buf;
|
return str - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ecard_show_vendor(struct device *dev, char *buf)
|
static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct expansion_card *ec = ECARD_DEV(dev);
|
struct expansion_card *ec = ECARD_DEV(dev);
|
||||||
return sprintf(buf, "%u\n", ec->cid.manufacturer);
|
return sprintf(buf, "%u\n", ec->cid.manufacturer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ecard_show_device(struct device *dev, char *buf)
|
static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct expansion_card *ec = ECARD_DEV(dev);
|
struct expansion_card *ec = ECARD_DEV(dev);
|
||||||
return sprintf(buf, "%u\n", ec->cid.product);
|
return sprintf(buf, "%u\n", ec->cid.product);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ecard_show_type(struct device *dev, char *buf)
|
static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct expansion_card *ec = ECARD_DEV(dev);
|
struct expansion_card *ec = ECARD_DEV(dev);
|
||||||
return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
|
return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
|
||||||
|
|
|
@ -395,6 +395,20 @@ static void __init early_initrd(char **p)
|
||||||
}
|
}
|
||||||
__early_param("initrd=", early_initrd);
|
__early_param("initrd=", early_initrd);
|
||||||
|
|
||||||
|
static void __init add_memory(unsigned long start, unsigned long size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Ensure that start/size are aligned to a page boundary.
|
||||||
|
* Size is appropriately rounded down, start is rounded up.
|
||||||
|
*/
|
||||||
|
size -= start & ~PAGE_MASK;
|
||||||
|
|
||||||
|
meminfo.bank[meminfo.nr_banks].start = PAGE_ALIGN(start);
|
||||||
|
meminfo.bank[meminfo.nr_banks].size = size & PAGE_MASK;
|
||||||
|
meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start);
|
||||||
|
meminfo.nr_banks += 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pick out the memory size. We look for mem=size@start,
|
* Pick out the memory size. We look for mem=size@start,
|
||||||
* where start and size are "size[KkMm]"
|
* where start and size are "size[KkMm]"
|
||||||
|
@ -419,10 +433,7 @@ static void __init early_mem(char **p)
|
||||||
if (**p == '@')
|
if (**p == '@')
|
||||||
start = memparse(*p + 1, p);
|
start = memparse(*p + 1, p);
|
||||||
|
|
||||||
meminfo.bank[meminfo.nr_banks].start = start;
|
add_memory(start, size);
|
||||||
meminfo.bank[meminfo.nr_banks].size = size;
|
|
||||||
meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start);
|
|
||||||
meminfo.nr_banks += 1;
|
|
||||||
}
|
}
|
||||||
__early_param("mem=", early_mem);
|
__early_param("mem=", early_mem);
|
||||||
|
|
||||||
|
@ -564,11 +575,7 @@ static int __init parse_tag_mem32(const struct tag *tag)
|
||||||
tag->u.mem.start, tag->u.mem.size / 1024);
|
tag->u.mem.start, tag->u.mem.size / 1024);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
|
add_memory(tag->u.mem.start, tag->u.mem.size);
|
||||||
meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size;
|
|
||||||
meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start);
|
|
||||||
meminfo.nr_banks += 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
|
|
||||||
#include "ptrace.h"
|
#include "ptrace.h"
|
||||||
|
#include "signal.h"
|
||||||
|
|
||||||
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@
|
||||||
#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
|
#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
|
||||||
#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
|
#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
|
||||||
|
|
||||||
static const unsigned long retcodes[4] = {
|
const unsigned long sigreturn_codes[4] = {
|
||||||
SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
|
SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
|
||||||
SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
|
SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
|
||||||
};
|
};
|
||||||
|
@ -500,17 +501,25 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
|
||||||
if (ka->sa.sa_flags & SA_SIGINFO)
|
if (ka->sa.sa_flags & SA_SIGINFO)
|
||||||
idx += 2;
|
idx += 2;
|
||||||
|
|
||||||
if (__put_user(retcodes[idx], rc))
|
if (__put_user(sigreturn_codes[idx], rc))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/*
|
if (cpsr & MODE32_BIT) {
|
||||||
* Ensure that the instruction cache sees
|
/*
|
||||||
* the return code written onto the stack.
|
* 32-bit code can use the new high-page
|
||||||
*/
|
* signal return code support.
|
||||||
flush_icache_range((unsigned long)rc,
|
*/
|
||||||
(unsigned long)(rc + 1));
|
retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Ensure that the instruction cache sees
|
||||||
|
* the return code written onto the stack.
|
||||||
|
*/
|
||||||
|
flush_icache_range((unsigned long)rc,
|
||||||
|
(unsigned long)(rc + 1));
|
||||||
|
|
||||||
retcode = ((unsigned long)rc) + thumb;
|
retcode = ((unsigned long)rc) + thumb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
regs->ARM_r0 = usig;
|
regs->ARM_r0 = usig;
|
||||||
|
|
12
arch/arm/kernel/signal.h
Normal file
12
arch/arm/kernel/signal.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/kernel/signal.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 Russell King.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#define KERN_SIGRETURN_CODE 0xffff0500
|
||||||
|
|
||||||
|
extern const unsigned long sigreturn_codes[4];
|
|
@ -145,7 +145,8 @@ int __init __cpu_up(unsigned int cpu)
|
||||||
pgd_free(pgd);
|
pgd_free(pgd);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu);
|
printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: We need to clean up the new idle thread. --rmk
|
* FIXME: We need to clean up the new idle thread. --rmk
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <asm/traps.h>
|
#include <asm/traps.h>
|
||||||
|
|
||||||
#include "ptrace.h"
|
#include "ptrace.h"
|
||||||
|
#include "signal.h"
|
||||||
|
|
||||||
const char *processor_modes[]=
|
const char *processor_modes[]=
|
||||||
{ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
|
{ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
|
||||||
|
@ -683,6 +684,14 @@ void __init trap_init(void)
|
||||||
memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
|
memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
|
||||||
memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
|
memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
|
||||||
memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
|
memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy signal return handlers into the vector page, and
|
||||||
|
* set sigreturn to be a pointer to these.
|
||||||
|
*/
|
||||||
|
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
|
||||||
|
sizeof(sigreturn_codes));
|
||||||
|
|
||||||
flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
|
flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
|
||||||
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
|
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include "gcclib.h"
|
#include "gcclib.h"
|
||||||
|
|
||||||
DItype
|
s64 __ashldi3(s64 u, int b)
|
||||||
__ashldi3 (DItype u, word_type b)
|
|
||||||
{
|
{
|
||||||
DIunion w;
|
DIunion w;
|
||||||
word_type bm;
|
int bm;
|
||||||
DIunion uu;
|
DIunion uu;
|
||||||
|
|
||||||
if (b == 0)
|
if (b == 0)
|
||||||
return u;
|
return u;
|
||||||
|
|
||||||
uu.ll = u;
|
uu.ll = u;
|
||||||
|
|
||||||
bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
|
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
|
||||||
if (bm <= 0)
|
if (bm <= 0) {
|
||||||
{
|
w.s.low = 0;
|
||||||
w.s.low = 0;
|
w.s.high = (u32) uu.s.low << -bm;
|
||||||
w.s.high = (USItype)uu.s.low << -bm;
|
} else {
|
||||||
}
|
u32 carries = (u32) uu.s.low >> bm;
|
||||||
else
|
w.s.low = (u32) uu.s.low << b;
|
||||||
{
|
w.s.high = ((u32) uu.s.high << b) | carries;
|
||||||
USItype carries = (USItype)uu.s.low >> bm;
|
}
|
||||||
w.s.low = (USItype)uu.s.low << b;
|
|
||||||
w.s.high = ((USItype)uu.s.high << b) | carries;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.ll;
|
return w.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,31 +31,27 @@ Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include "gcclib.h"
|
#include "gcclib.h"
|
||||||
|
|
||||||
DItype
|
s64 __ashrdi3(s64 u, int b)
|
||||||
__ashrdi3 (DItype u, word_type b)
|
|
||||||
{
|
{
|
||||||
DIunion w;
|
DIunion w;
|
||||||
word_type bm;
|
int bm;
|
||||||
DIunion uu;
|
DIunion uu;
|
||||||
|
|
||||||
if (b == 0)
|
if (b == 0)
|
||||||
return u;
|
return u;
|
||||||
|
|
||||||
uu.ll = u;
|
uu.ll = u;
|
||||||
|
|
||||||
bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
|
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
|
||||||
if (bm <= 0)
|
if (bm <= 0) {
|
||||||
{
|
/* w.s.high = 1..1 or 0..0 */
|
||||||
/* w.s.high = 1..1 or 0..0 */
|
w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
|
||||||
w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
|
w.s.low = uu.s.high >> -bm;
|
||||||
w.s.low = uu.s.high >> -bm;
|
} else {
|
||||||
}
|
u32 carries = (u32) uu.s.high << bm;
|
||||||
else
|
w.s.high = uu.s.high >> b;
|
||||||
{
|
w.s.low = ((u32) uu.s.low >> b) | carries;
|
||||||
USItype carries = (USItype)uu.s.high << bm;
|
}
|
||||||
w.s.high = uu.s.high >> b;
|
|
||||||
w.s.low = ((USItype)uu.s.low >> b) | carries;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.ll;
|
return w.ll;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
|
/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
|
||||||
/* I Molton 29/07/01 */
|
/* I Molton 29/07/01 */
|
||||||
|
|
||||||
#define BITS_PER_UNIT 8
|
#include <linux/types.h>
|
||||||
#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
|
|
||||||
|
|
||||||
typedef unsigned int UQItype __attribute__ ((mode (QI)));
|
#define BITS_PER_UNIT 8
|
||||||
typedef int SItype __attribute__ ((mode (SI)));
|
#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
|
||||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
|
||||||
typedef int DItype __attribute__ ((mode (DI)));
|
|
||||||
typedef int word_type __attribute__ ((mode (__word__)));
|
|
||||||
typedef unsigned int UDItype __attribute__ ((mode (DI)));
|
|
||||||
|
|
||||||
#ifdef __ARMEB__
|
#ifdef __ARMEB__
|
||||||
struct DIstruct {SItype high, low;};
|
struct DIstruct {
|
||||||
|
s32 high, low;
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
struct DIstruct {SItype low, high;};
|
struct DIstruct {
|
||||||
|
s32 low, high;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef union
|
typedef union {
|
||||||
{
|
struct DIstruct s;
|
||||||
struct DIstruct s;
|
s64 ll;
|
||||||
DItype ll;
|
|
||||||
} DIunion;
|
} DIunion;
|
||||||
|
|
||||||
|
|
|
@ -26,18 +26,18 @@
|
||||||
|
|
||||||
#define __BITS4 (SI_TYPE_SIZE / 4)
|
#define __BITS4 (SI_TYPE_SIZE / 4)
|
||||||
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
|
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
|
||||||
#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
|
#define __ll_lowpart(t) ((u32) (t) % __ll_B)
|
||||||
#define __ll_highpart(t) ((USItype) (t) / __ll_B)
|
#define __ll_highpart(t) ((u32) (t) / __ll_B)
|
||||||
|
|
||||||
/* Define auxiliary asm macros.
|
/* Define auxiliary asm macros.
|
||||||
|
|
||||||
1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
|
1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
|
||||||
multiplies two USItype integers MULTIPLER and MULTIPLICAND,
|
multiplies two u32 integers MULTIPLER and MULTIPLICAND,
|
||||||
and generates a two-part USItype product in HIGH_PROD and
|
and generates a two-part u32 product in HIGH_PROD and
|
||||||
LOW_PROD.
|
LOW_PROD.
|
||||||
|
|
||||||
2) __umulsidi3(a,b) multiplies two USItype integers A and B,
|
2) __umulsidi3(a,b) multiplies two u32 integers A and B,
|
||||||
and returns a UDItype product. This is just a variant of umul_ppmm.
|
and returns a u64 product. This is just a variant of umul_ppmm.
|
||||||
|
|
||||||
3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
|
3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
|
||||||
denominator) divides a two-word unsigned integer, composed by the
|
denominator) divides a two-word unsigned integer, composed by the
|
||||||
|
@ -77,23 +77,23 @@
|
||||||
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
|
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
|
||||||
__asm__ ("adds %1, %4, %5 \n\
|
__asm__ ("adds %1, %4, %5 \n\
|
||||||
adc %0, %2, %3" \
|
adc %0, %2, %3" \
|
||||||
: "=r" ((USItype) (sh)), \
|
: "=r" ((u32) (sh)), \
|
||||||
"=&r" ((USItype) (sl)) \
|
"=&r" ((u32) (sl)) \
|
||||||
: "%r" ((USItype) (ah)), \
|
: "%r" ((u32) (ah)), \
|
||||||
"rI" ((USItype) (bh)), \
|
"rI" ((u32) (bh)), \
|
||||||
"%r" ((USItype) (al)), \
|
"%r" ((u32) (al)), \
|
||||||
"rI" ((USItype) (bl)))
|
"rI" ((u32) (bl)))
|
||||||
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
||||||
__asm__ ("subs %1, %4, %5 \n\
|
__asm__ ("subs %1, %4, %5 \n\
|
||||||
sbc %0, %2, %3" \
|
sbc %0, %2, %3" \
|
||||||
: "=r" ((USItype) (sh)), \
|
: "=r" ((u32) (sh)), \
|
||||||
"=&r" ((USItype) (sl)) \
|
"=&r" ((u32) (sl)) \
|
||||||
: "r" ((USItype) (ah)), \
|
: "r" ((u32) (ah)), \
|
||||||
"rI" ((USItype) (bh)), \
|
"rI" ((u32) (bh)), \
|
||||||
"r" ((USItype) (al)), \
|
"r" ((u32) (al)), \
|
||||||
"rI" ((USItype) (bl)))
|
"rI" ((u32) (bl)))
|
||||||
#define umul_ppmm(xh, xl, a, b) \
|
#define umul_ppmm(xh, xl, a, b) \
|
||||||
{register USItype __t0, __t1, __t2; \
|
{register u32 __t0, __t1, __t2; \
|
||||||
__asm__ ("%@ Inlined umul_ppmm \n\
|
__asm__ ("%@ Inlined umul_ppmm \n\
|
||||||
mov %2, %5, lsr #16 \n\
|
mov %2, %5, lsr #16 \n\
|
||||||
mov %0, %6, lsr #16 \n\
|
mov %0, %6, lsr #16 \n\
|
||||||
|
@ -107,14 +107,14 @@
|
||||||
addcs %0, %0, #65536 \n\
|
addcs %0, %0, #65536 \n\
|
||||||
adds %1, %1, %3, lsl #16 \n\
|
adds %1, %1, %3, lsl #16 \n\
|
||||||
adc %0, %0, %3, lsr #16" \
|
adc %0, %0, %3, lsr #16" \
|
||||||
: "=&r" ((USItype) (xh)), \
|
: "=&r" ((u32) (xh)), \
|
||||||
"=r" ((USItype) (xl)), \
|
"=r" ((u32) (xl)), \
|
||||||
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
|
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
|
||||||
: "r" ((USItype) (a)), \
|
: "r" ((u32) (a)), \
|
||||||
"r" ((USItype) (b)));}
|
"r" ((u32) (b)));}
|
||||||
#define UMUL_TIME 20
|
#define UMUL_TIME 20
|
||||||
#define UDIV_TIME 100
|
#define UDIV_TIME 100
|
||||||
#endif /* __arm__ */
|
#endif /* __arm__ */
|
||||||
|
|
||||||
#define __umulsidi3(u, v) \
|
#define __umulsidi3(u, v) \
|
||||||
({DIunion __w; \
|
({DIunion __w; \
|
||||||
|
@ -123,14 +123,14 @@
|
||||||
|
|
||||||
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
|
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
|
||||||
do { \
|
do { \
|
||||||
USItype __d1, __d0, __q1, __q0; \
|
u32 __d1, __d0, __q1, __q0; \
|
||||||
USItype __r1, __r0, __m; \
|
u32 __r1, __r0, __m; \
|
||||||
__d1 = __ll_highpart (d); \
|
__d1 = __ll_highpart (d); \
|
||||||
__d0 = __ll_lowpart (d); \
|
__d0 = __ll_lowpart (d); \
|
||||||
\
|
\
|
||||||
__r1 = (n1) % __d1; \
|
__r1 = (n1) % __d1; \
|
||||||
__q1 = (n1) / __d1; \
|
__q1 = (n1) / __d1; \
|
||||||
__m = (USItype) __q1 * __d0; \
|
__m = (u32) __q1 * __d0; \
|
||||||
__r1 = __r1 * __ll_B | __ll_highpart (n0); \
|
__r1 = __r1 * __ll_B | __ll_highpart (n0); \
|
||||||
if (__r1 < __m) \
|
if (__r1 < __m) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
\
|
\
|
||||||
__r0 = __r1 % __d1; \
|
__r0 = __r1 % __d1; \
|
||||||
__q0 = __r1 / __d1; \
|
__q0 = __r1 / __d1; \
|
||||||
__m = (USItype) __q0 * __d0; \
|
__m = (u32) __q0 * __d0; \
|
||||||
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \
|
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \
|
||||||
if (__r0 < __m) \
|
if (__r0 < __m) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -154,7 +154,7 @@
|
||||||
} \
|
} \
|
||||||
__r0 -= __m; \
|
__r0 -= __m; \
|
||||||
\
|
\
|
||||||
(q) = (USItype) __q1 * __ll_B | __q0; \
|
(q) = (u32) __q1 * __ll_B | __q0; \
|
||||||
(r) = __r0; \
|
(r) = __r0; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -163,14 +163,14 @@
|
||||||
|
|
||||||
#define count_leading_zeros(count, x) \
|
#define count_leading_zeros(count, x) \
|
||||||
do { \
|
do { \
|
||||||
USItype __xr = (x); \
|
u32 __xr = (x); \
|
||||||
USItype __a; \
|
u32 __a; \
|
||||||
\
|
\
|
||||||
if (SI_TYPE_SIZE <= 32) \
|
if (SI_TYPE_SIZE <= 32) \
|
||||||
{ \
|
{ \
|
||||||
__a = __xr < ((USItype)1<<2*__BITS4) \
|
__a = __xr < ((u32)1<<2*__BITS4) \
|
||||||
? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \
|
? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \
|
||||||
: (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
|
: (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include "gcclib.h"
|
#include "gcclib.h"
|
||||||
|
|
||||||
DItype
|
s64 __lshrdi3(s64 u, int b)
|
||||||
__lshrdi3 (DItype u, word_type b)
|
|
||||||
{
|
{
|
||||||
DIunion w;
|
DIunion w;
|
||||||
word_type bm;
|
int bm;
|
||||||
DIunion uu;
|
DIunion uu;
|
||||||
|
|
||||||
if (b == 0)
|
if (b == 0)
|
||||||
return u;
|
return u;
|
||||||
|
|
||||||
uu.ll = u;
|
uu.ll = u;
|
||||||
|
|
||||||
bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
|
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
|
||||||
if (bm <= 0)
|
if (bm <= 0) {
|
||||||
{
|
w.s.high = 0;
|
||||||
w.s.high = 0;
|
w.s.low = (u32) uu.s.high >> -bm;
|
||||||
w.s.low = (USItype)uu.s.high >> -bm;
|
} else {
|
||||||
}
|
u32 carries = (u32) uu.s.high << bm;
|
||||||
else
|
w.s.high = (u32) uu.s.high >> b;
|
||||||
{
|
w.s.low = ((u32) uu.s.low >> b) | carries;
|
||||||
USItype carries = (USItype)uu.s.high << bm;
|
}
|
||||||
w.s.high = (USItype)uu.s.high >> b;
|
|
||||||
w.s.low = ((USItype)uu.s.low >> b) | carries;
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.ll;
|
return w.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
|
||||||
#include "gcclib.h"
|
#include "gcclib.h"
|
||||||
|
|
||||||
#define umul_ppmm(xh, xl, a, b) \
|
#define umul_ppmm(xh, xl, a, b) \
|
||||||
{register USItype __t0, __t1, __t2; \
|
{register u32 __t0, __t1, __t2; \
|
||||||
__asm__ ("%@ Inlined umul_ppmm \n\
|
__asm__ ("%@ Inlined umul_ppmm \n\
|
||||||
mov %2, %5, lsr #16 \n\
|
mov %2, %5, lsr #16 \n\
|
||||||
mov %0, %6, lsr #16 \n\
|
mov %0, %6, lsr #16 \n\
|
||||||
|
@ -46,32 +46,27 @@ Boston, MA 02111-1307, USA. */
|
||||||
addcs %0, %0, #65536 \n\
|
addcs %0, %0, #65536 \n\
|
||||||
adds %1, %1, %3, lsl #16 \n\
|
adds %1, %1, %3, lsl #16 \n\
|
||||||
adc %0, %0, %3, lsr #16" \
|
adc %0, %0, %3, lsr #16" \
|
||||||
: "=&r" ((USItype) (xh)), \
|
: "=&r" ((u32) (xh)), \
|
||||||
"=r" ((USItype) (xl)), \
|
"=r" ((u32) (xl)), \
|
||||||
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
|
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
|
||||||
: "r" ((USItype) (a)), \
|
: "r" ((u32) (a)), \
|
||||||
"r" ((USItype) (b)));}
|
"r" ((u32) (b)));}
|
||||||
|
|
||||||
|
|
||||||
#define __umulsidi3(u, v) \
|
#define __umulsidi3(u, v) \
|
||||||
({DIunion __w; \
|
({DIunion __w; \
|
||||||
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
||||||
__w.ll; })
|
__w.ll; })
|
||||||
|
|
||||||
|
s64 __muldi3(s64 u, s64 v)
|
||||||
DItype
|
|
||||||
__muldi3 (DItype u, DItype v)
|
|
||||||
{
|
{
|
||||||
DIunion w;
|
DIunion w;
|
||||||
DIunion uu, vv;
|
DIunion uu, vv;
|
||||||
|
|
||||||
uu.ll = u,
|
uu.ll = u, vv.ll = v;
|
||||||
vv.ll = v;
|
|
||||||
|
|
||||||
w.ll = __umulsidi3 (uu.s.low, vv.s.low);
|
w.ll = __umulsidi3(uu.s.low, vv.s.low);
|
||||||
w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
|
w.s.high += ((u32) uu.s.low * (u32) vv.s.high
|
||||||
+ (USItype) uu.s.high * (USItype) vv.s.low);
|
+ (u32) uu.s.high * (u32) vv.s.low);
|
||||||
|
|
||||||
return w.ll;
|
return w.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,21 +31,19 @@ Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include "gcclib.h"
|
#include "gcclib.h"
|
||||||
|
|
||||||
word_type
|
int __ucmpdi2(s64 a, s64 b)
|
||||||
__ucmpdi2 (DItype a, DItype b)
|
|
||||||
{
|
{
|
||||||
DIunion au, bu;
|
DIunion au, bu;
|
||||||
|
|
||||||
au.ll = a, bu.ll = b;
|
au.ll = a, bu.ll = b;
|
||||||
|
|
||||||
if ((USItype) au.s.high < (USItype) bu.s.high)
|
if ((u32) au.s.high < (u32) bu.s.high)
|
||||||
return 0;
|
return 0;
|
||||||
else if ((USItype) au.s.high > (USItype) bu.s.high)
|
else if ((u32) au.s.high > (u32) bu.s.high)
|
||||||
return 2;
|
return 2;
|
||||||
if ((USItype) au.s.low < (USItype) bu.s.low)
|
if ((u32) au.s.low < (u32) bu.s.low)
|
||||||
return 0;
|
return 0;
|
||||||
else if ((USItype) au.s.low > (USItype) bu.s.low)
|
else if ((u32) au.s.low > (u32) bu.s.low)
|
||||||
return 2;
|
return 2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,211 +32,191 @@ Boston, MA 02111-1307, USA. */
|
||||||
#include "gcclib.h"
|
#include "gcclib.h"
|
||||||
#include "longlong.h"
|
#include "longlong.h"
|
||||||
|
|
||||||
static const UQItype __clz_tab[] =
|
static const u8 __clz_tab[] = {
|
||||||
{
|
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
UDItype
|
u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
|
||||||
__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
|
|
||||||
{
|
{
|
||||||
DIunion ww;
|
DIunion ww;
|
||||||
DIunion nn, dd;
|
DIunion nn, dd;
|
||||||
DIunion rr;
|
DIunion rr;
|
||||||
USItype d0, d1, n0, n1, n2;
|
u32 d0, d1, n0, n1, n2;
|
||||||
USItype q0, q1;
|
u32 q0, q1;
|
||||||
USItype b, bm;
|
u32 b, bm;
|
||||||
|
|
||||||
nn.ll = n;
|
nn.ll = n;
|
||||||
dd.ll = d;
|
dd.ll = d;
|
||||||
|
|
||||||
d0 = dd.s.low;
|
d0 = dd.s.low;
|
||||||
d1 = dd.s.high;
|
d1 = dd.s.high;
|
||||||
n0 = nn.s.low;
|
n0 = nn.s.low;
|
||||||
n1 = nn.s.high;
|
n1 = nn.s.high;
|
||||||
|
|
||||||
if (d1 == 0)
|
if (d1 == 0) {
|
||||||
{
|
if (d0 > n1) {
|
||||||
if (d0 > n1)
|
/* 0q = nn / 0D */
|
||||||
{
|
|
||||||
/* 0q = nn / 0D */
|
|
||||||
|
|
||||||
count_leading_zeros (bm, d0);
|
count_leading_zeros(bm, d0);
|
||||||
|
|
||||||
if (bm != 0)
|
if (bm != 0) {
|
||||||
{
|
/* Normalize, i.e. make the most significant bit of the
|
||||||
/* Normalize, i.e. make the most significant bit of the
|
denominator set. */
|
||||||
denominator set. */
|
|
||||||
|
|
||||||
d0 = d0 << bm;
|
d0 = d0 << bm;
|
||||||
n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
|
n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
|
||||||
n0 = n0 << bm;
|
n0 = n0 << bm;
|
||||||
}
|
}
|
||||||
|
|
||||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
udiv_qrnnd(q0, n0, n1, n0, d0);
|
||||||
q1 = 0;
|
q1 = 0;
|
||||||
|
|
||||||
/* Remainder in n0 >> bm. */
|
/* Remainder in n0 >> bm. */
|
||||||
}
|
} else {
|
||||||
else
|
/* qq = NN / 0d */
|
||||||
{
|
|
||||||
/* qq = NN / 0d */
|
|
||||||
|
|
||||||
if (d0 == 0)
|
if (d0 == 0)
|
||||||
d0 = 1 / d0; /* Divide intentionally by zero. */
|
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||||
|
|
||||||
count_leading_zeros (bm, d0);
|
count_leading_zeros(bm, d0);
|
||||||
|
|
||||||
if (bm == 0)
|
if (bm == 0) {
|
||||||
{
|
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
|
||||||
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
|
conclude (the most significant bit of n1 is set) /\ (the
|
||||||
conclude (the most significant bit of n1 is set) /\ (the
|
leading quotient digit q1 = 1).
|
||||||
leading quotient digit q1 = 1).
|
|
||||||
|
|
||||||
This special case is necessary, not an optimization.
|
This special case is necessary, not an optimization.
|
||||||
(Shifts counts of SI_TYPE_SIZE are undefined.) */
|
(Shifts counts of SI_TYPE_SIZE are undefined.) */
|
||||||
|
|
||||||
n1 -= d0;
|
n1 -= d0;
|
||||||
q1 = 1;
|
q1 = 1;
|
||||||
}
|
} else {
|
||||||
else
|
/* Normalize. */
|
||||||
{
|
|
||||||
/* Normalize. */
|
|
||||||
|
|
||||||
b = SI_TYPE_SIZE - bm;
|
b = SI_TYPE_SIZE - bm;
|
||||||
|
|
||||||
d0 = d0 << bm;
|
d0 = d0 << bm;
|
||||||
n2 = n1 >> b;
|
n2 = n1 >> b;
|
||||||
n1 = (n1 << bm) | (n0 >> b);
|
n1 = (n1 << bm) | (n0 >> b);
|
||||||
n0 = n0 << bm;
|
n0 = n0 << bm;
|
||||||
|
|
||||||
udiv_qrnnd (q1, n1, n2, n1, d0);
|
udiv_qrnnd(q1, n1, n2, n1, d0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* n1 != d0... */
|
/* n1 != d0... */
|
||||||
|
|
||||||
udiv_qrnnd (q0, n0, n1, n0, d0);
|
udiv_qrnnd(q0, n0, n1, n0, d0);
|
||||||
|
|
||||||
/* Remainder in n0 >> bm. */
|
/* Remainder in n0 >> bm. */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rp != 0)
|
if (rp != 0) {
|
||||||
{
|
rr.s.low = n0 >> bm;
|
||||||
rr.s.low = n0 >> bm;
|
rr.s.high = 0;
|
||||||
rr.s.high = 0;
|
*rp = rr.ll;
|
||||||
*rp = rr.ll;
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if (d1 > n1) {
|
||||||
else
|
/* 00 = nn / DD */
|
||||||
{
|
|
||||||
if (d1 > n1)
|
|
||||||
{
|
|
||||||
/* 00 = nn / DD */
|
|
||||||
|
|
||||||
q0 = 0;
|
q0 = 0;
|
||||||
q1 = 0;
|
q1 = 0;
|
||||||
|
|
||||||
/* Remainder in n1n0. */
|
/* Remainder in n1n0. */
|
||||||
if (rp != 0)
|
if (rp != 0) {
|
||||||
{
|
rr.s.low = n0;
|
||||||
rr.s.low = n0;
|
rr.s.high = n1;
|
||||||
rr.s.high = n1;
|
*rp = rr.ll;
|
||||||
*rp = rr.ll;
|
}
|
||||||
}
|
} else {
|
||||||
}
|
/* 0q = NN / dd */
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 0q = NN / dd */
|
|
||||||
|
|
||||||
count_leading_zeros (bm, d1);
|
count_leading_zeros(bm, d1);
|
||||||
if (bm == 0)
|
if (bm == 0) {
|
||||||
{
|
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
|
||||||
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
|
conclude (the most significant bit of n1 is set) /\ (the
|
||||||
conclude (the most significant bit of n1 is set) /\ (the
|
quotient digit q0 = 0 or 1).
|
||||||
quotient digit q0 = 0 or 1).
|
|
||||||
|
|
||||||
This special case is necessary, not an optimization. */
|
This special case is necessary, not an optimization. */
|
||||||
|
|
||||||
/* The condition on the next line takes advantage of that
|
/* The condition on the next line takes advantage of that
|
||||||
n1 >= d1 (true due to program flow). */
|
n1 >= d1 (true due to program flow). */
|
||||||
if (n1 > d1 || n0 >= d0)
|
if (n1 > d1 || n0 >= d0) {
|
||||||
{
|
q0 = 1;
|
||||||
q0 = 1;
|
sub_ddmmss(n1, n0, n1, n0, d1, d0);
|
||||||
sub_ddmmss (n1, n0, n1, n0, d1, d0);
|
} else
|
||||||
}
|
q0 = 0;
|
||||||
else
|
|
||||||
q0 = 0;
|
|
||||||
|
|
||||||
q1 = 0;
|
q1 = 0;
|
||||||
|
|
||||||
if (rp != 0)
|
if (rp != 0) {
|
||||||
{
|
rr.s.low = n0;
|
||||||
rr.s.low = n0;
|
rr.s.high = n1;
|
||||||
rr.s.high = n1;
|
*rp = rr.ll;
|
||||||
*rp = rr.ll;
|
}
|
||||||
}
|
} else {
|
||||||
}
|
u32 m1, m0;
|
||||||
else
|
/* Normalize. */
|
||||||
{
|
|
||||||
USItype m1, m0;
|
|
||||||
/* Normalize. */
|
|
||||||
|
|
||||||
b = SI_TYPE_SIZE - bm;
|
b = SI_TYPE_SIZE - bm;
|
||||||
|
|
||||||
d1 = (d1 << bm) | (d0 >> b);
|
d1 = (d1 << bm) | (d0 >> b);
|
||||||
d0 = d0 << bm;
|
d0 = d0 << bm;
|
||||||
n2 = n1 >> b;
|
n2 = n1 >> b;
|
||||||
n1 = (n1 << bm) | (n0 >> b);
|
n1 = (n1 << bm) | (n0 >> b);
|
||||||
n0 = n0 << bm;
|
n0 = n0 << bm;
|
||||||
|
|
||||||
udiv_qrnnd (q0, n1, n2, n1, d1);
|
udiv_qrnnd(q0, n1, n2, n1, d1);
|
||||||
umul_ppmm (m1, m0, q0, d0);
|
umul_ppmm(m1, m0, q0, d0);
|
||||||
|
|
||||||
if (m1 > n1 || (m1 == n1 && m0 > n0))
|
if (m1 > n1 || (m1 == n1 && m0 > n0)) {
|
||||||
{
|
q0--;
|
||||||
q0--;
|
sub_ddmmss(m1, m0, m1, m0, d1, d0);
|
||||||
sub_ddmmss (m1, m0, m1, m0, d1, d0);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
q1 = 0;
|
q1 = 0;
|
||||||
|
|
||||||
/* Remainder in (n1n0 - m1m0) >> bm. */
|
/* Remainder in (n1n0 - m1m0) >> bm. */
|
||||||
if (rp != 0)
|
if (rp != 0) {
|
||||||
{
|
sub_ddmmss(n1, n0, n1, n0, m1, m0);
|
||||||
sub_ddmmss (n1, n0, n1, n0, m1, m0);
|
rr.s.low = (n1 << b) | (n0 >> bm);
|
||||||
rr.s.low = (n1 << b) | (n0 >> bm);
|
rr.s.high = n1 >> bm;
|
||||||
rr.s.high = n1 >> bm;
|
*rp = rr.ll;
|
||||||
*rp = rr.ll;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ww.s.low = q0;
|
ww.s.low = q0;
|
||||||
ww.s.high = q1;
|
ww.s.high = q1;
|
||||||
return ww.ll;
|
return ww.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
UDItype
|
u64 __udivdi3(u64 n, u64 d)
|
||||||
__udivdi3 (UDItype n, UDItype d)
|
|
||||||
{
|
{
|
||||||
return __udivmoddi4 (n, d, (UDItype *) 0);
|
return __udivmoddi4(n, d, (u64 *) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
UDItype
|
u64 __umoddi3(u64 u, u64 v)
|
||||||
__umoddi3 (UDItype u, UDItype v)
|
|
||||||
{
|
{
|
||||||
UDItype w;
|
u64 w;
|
||||||
|
|
||||||
(void) __udivmoddi4 (u ,v, &w);
|
(void)__udivmoddi4(u, v, &w);
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
arch/arm/mach-aaec2000/Kconfig
Normal file
11
arch/arm/mach-aaec2000/Kconfig
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
if ARCH_AAEC2000
|
||||||
|
|
||||||
|
menu "Agilent AAEC-2000 Implementations"
|
||||||
|
|
||||||
|
config MACH_AAED2000
|
||||||
|
bool "Agilent AAED-2000 Development Platform"
|
||||||
|
select CPU_ARM920T
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif
|
9
arch/arm/mach-aaec2000/Makefile
Normal file
9
arch/arm/mach-aaec2000/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#
|
||||||
|
# Makefile for the linux kernel.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Common support (must be linked before board specific support)
|
||||||
|
obj-y += core.o
|
||||||
|
|
||||||
|
# Specific board support
|
||||||
|
obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
|
48
arch/arm/mach-aaec2000/aaed2000.c
Normal file
48
arch/arm/mach-aaec2000/aaed2000.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/mach-aaec2000/aaed2000.c
|
||||||
|
*
|
||||||
|
* Support for the Agilent AAED-2000 Development Platform.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005 Nicolas Bellido Y Ortega
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/major.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <asm/memory.h>
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
static void __init aaed2000_init_irq(void)
|
||||||
|
{
|
||||||
|
aaec2000_init_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init aaed2000_map_io(void)
|
||||||
|
{
|
||||||
|
aaec2000_map_io();
|
||||||
|
}
|
||||||
|
|
||||||
|
MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
|
||||||
|
MAINTAINER("Nicolas Bellido Y Ortega")
|
||||||
|
BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE)
|
||||||
|
MAPIO(aaed2000_map_io)
|
||||||
|
INITIRQ(aaed2000_init_irq)
|
||||||
|
.timer = &aaec2000_timer,
|
||||||
|
MACHINE_END
|
157
arch/arm/mach-aaec2000/core.c
Normal file
157
arch/arm/mach-aaec2000/core.c
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/mach-aaec2000/core.c
|
||||||
|
*
|
||||||
|
* Code common to all AAEC-2000 machines
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005 Nicolas Bellido Y Ortega
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
#include <linux/config.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
|
#include <linux/signal.h>
|
||||||
|
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
|
||||||
|
#include <asm/mach/irq.h>
|
||||||
|
#include <asm/mach/time.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common I/O mapping:
|
||||||
|
*
|
||||||
|
* Static virtual address mappings are as follow:
|
||||||
|
*
|
||||||
|
* 0xf8000000-0xf8001ffff: Devices connected to APB bus
|
||||||
|
* 0xf8002000-0xf8003ffff: Devices connected to AHB bus
|
||||||
|
*
|
||||||
|
* Below 0xe8000000 is reserved for vm allocation.
|
||||||
|
*
|
||||||
|
* The machine specific code must provide the extra mapping beside the
|
||||||
|
* default mapping provided here.
|
||||||
|
*/
|
||||||
|
static struct map_desc standard_io_desc[] __initdata = {
|
||||||
|
/* virtual physical length type */
|
||||||
|
{ VIO_APB_BASE, PIO_APB_BASE, IO_APB_LENGTH, MT_DEVICE },
|
||||||
|
{ VIO_AHB_BASE, PIO_AHB_BASE, IO_AHB_LENGTH, MT_DEVICE }
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init aaec2000_map_io(void)
|
||||||
|
{
|
||||||
|
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt handling routines
|
||||||
|
*/
|
||||||
|
static void aaec2000_int_ack(unsigned int irq)
|
||||||
|
{
|
||||||
|
IRQ_INTSR = 1 << irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aaec2000_int_mask(unsigned int irq)
|
||||||
|
{
|
||||||
|
IRQ_INTENC |= (1 << irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aaec2000_int_unmask(unsigned int irq)
|
||||||
|
{
|
||||||
|
IRQ_INTENS |= (1 << irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irqchip aaec2000_irq_chip = {
|
||||||
|
.ack = aaec2000_int_ack,
|
||||||
|
.mask = aaec2000_int_mask,
|
||||||
|
.unmask = aaec2000_int_unmask,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init aaec2000_init_irq(void)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NR_IRQS; i++) {
|
||||||
|
set_irq_handler(i, do_level_IRQ);
|
||||||
|
set_irq_chip(i, &aaec2000_irq_chip);
|
||||||
|
set_irq_flags(i, IRQF_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable all interrupts */
|
||||||
|
IRQ_INTENC = 0xffffffff;
|
||||||
|
|
||||||
|
/* Clear any pending interrupts */
|
||||||
|
IRQ_INTSR = IRQ_INTSR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time keeping
|
||||||
|
*/
|
||||||
|
/* IRQs are disabled before entering here from do_gettimeofday() */
|
||||||
|
static unsigned long aaec2000_gettimeoffset(void)
|
||||||
|
{
|
||||||
|
unsigned long ticks_to_match, elapsed, usec;
|
||||||
|
|
||||||
|
/* Get ticks before next timer match */
|
||||||
|
ticks_to_match = TIMER1_LOAD - TIMER1_VAL;
|
||||||
|
|
||||||
|
/* We need elapsed ticks since last match */
|
||||||
|
elapsed = LATCH - ticks_to_match;
|
||||||
|
|
||||||
|
/* Now, convert them to usec */
|
||||||
|
usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
|
||||||
|
|
||||||
|
return usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We enter here with IRQs enabled */
|
||||||
|
static irqreturn_t
|
||||||
|
aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
/* TODO: Check timer accuracy */
|
||||||
|
write_seqlock(&xtime_lock);
|
||||||
|
|
||||||
|
timer_tick(regs);
|
||||||
|
TIMER1_CLEAR = 1;
|
||||||
|
|
||||||
|
write_sequnlock(&xtime_lock);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irqaction aaec2000_timer_irq = {
|
||||||
|
.name = "AAEC-2000 Timer Tick",
|
||||||
|
.flags = SA_INTERRUPT,
|
||||||
|
.handler = aaec2000_timer_interrupt
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init aaec2000_timer_init(void)
|
||||||
|
{
|
||||||
|
/* Disable timer 1 */
|
||||||
|
TIMER1_CTRL = 0;
|
||||||
|
|
||||||
|
/* We have somehow to generate a 100Hz clock.
|
||||||
|
* We then use the 508KHz timer in periodic mode.
|
||||||
|
*/
|
||||||
|
TIMER1_LOAD = LATCH;
|
||||||
|
TIMER1_CLEAR = 1; /* Clear interrupt */
|
||||||
|
|
||||||
|
setup_irq(INT_TMR1_OFL, &aaec2000_timer_irq);
|
||||||
|
|
||||||
|
TIMER1_CTRL = TIMER_CTRL_ENABLE |
|
||||||
|
TIMER_CTRL_PERIODIC |
|
||||||
|
TIMER_CTRL_CLKSEL_508K;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sys_timer aaec2000_timer = {
|
||||||
|
.init = aaec2000_timer_init,
|
||||||
|
.offset = aaec2000_gettimeoffset,
|
||||||
|
};
|
||||||
|
|
16
arch/arm/mach-aaec2000/core.h
Normal file
16
arch/arm/mach-aaec2000/core.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/mach-aaec2000/core.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005 Nicolas Bellido Y Ortega
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct sys_timer;
|
||||||
|
|
||||||
|
extern struct sys_timer aaec2000_timer;
|
||||||
|
extern void __init aaec2000_map_io(void);
|
||||||
|
extern void __init aaec2000_init_irq(void);
|
|
@ -26,6 +26,8 @@
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
|
|
||||||
|
unsigned int vram_size;
|
||||||
|
|
||||||
static void cl7500_ack_irq_a(unsigned int irq)
|
static void cl7500_ack_irq_a(unsigned int irq)
|
||||||
{
|
{
|
||||||
unsigned int val, mask;
|
unsigned int val, mask;
|
||||||
|
|
|
@ -227,7 +227,6 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
* primary CPU
|
* primary CPU
|
||||||
*/
|
*/
|
||||||
if (hard_smp_processor_id() == 0) {
|
if (hard_smp_processor_id() == 0) {
|
||||||
nmi_tick();
|
|
||||||
timer_tick(regs);
|
timer_tick(regs);
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
smp_send_timer();
|
smp_send_timer();
|
||||||
|
|
|
@ -162,12 +162,13 @@ void __init ixp2000_map_io(void)
|
||||||
static unsigned ticks_per_jiffy;
|
static unsigned ticks_per_jiffy;
|
||||||
static unsigned ticks_per_usec;
|
static unsigned ticks_per_usec;
|
||||||
static unsigned next_jiffy_time;
|
static unsigned next_jiffy_time;
|
||||||
|
static volatile unsigned long *missing_jiffy_timer_csr;
|
||||||
|
|
||||||
unsigned long ixp2000_gettimeoffset (void)
|
unsigned long ixp2000_gettimeoffset (void)
|
||||||
{
|
{
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
|
|
||||||
offset = next_jiffy_time - *IXP2000_T4_CSR;
|
offset = next_jiffy_time - *missing_jiffy_timer_csr;
|
||||||
|
|
||||||
return offset / ticks_per_usec;
|
return offset / ticks_per_usec;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +180,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
/* clear timer 1 */
|
/* clear timer 1 */
|
||||||
ixp2000_reg_write(IXP2000_T1_CLR, 1);
|
ixp2000_reg_write(IXP2000_T1_CLR, 1);
|
||||||
|
|
||||||
while ((next_jiffy_time - *IXP2000_T4_CSR) > ticks_per_jiffy) {
|
while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
|
||||||
timer_tick(regs);
|
timer_tick(regs);
|
||||||
next_jiffy_time -= ticks_per_jiffy;
|
next_jiffy_time -= ticks_per_jiffy;
|
||||||
}
|
}
|
||||||
|
@ -197,20 +198,37 @@ static struct irqaction ixp2000_timer_irq = {
|
||||||
|
|
||||||
void __init ixp2000_init_time(unsigned long tick_rate)
|
void __init ixp2000_init_time(unsigned long tick_rate)
|
||||||
{
|
{
|
||||||
ixp2000_reg_write(IXP2000_T1_CLR, 0);
|
|
||||||
ixp2000_reg_write(IXP2000_T4_CLR, 0);
|
|
||||||
|
|
||||||
ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
|
ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
|
||||||
ticks_per_usec = tick_rate / 1000000;
|
ticks_per_usec = tick_rate / 1000000;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use timer 1 as our timer interrupt.
|
||||||
|
*/
|
||||||
|
ixp2000_reg_write(IXP2000_T1_CLR, 0);
|
||||||
ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
|
ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
|
||||||
ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
|
ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use T4 as a monotonic counter to track missed jiffies
|
* We use a second timer as a monotonic counter for tracking
|
||||||
|
* missed jiffies. The IXP2000 has four timers, but if we're
|
||||||
|
* on an A-step IXP2800, timer 2 and 3 don't work, so on those
|
||||||
|
* chips we use timer 4. Timer 4 is the only timer that can
|
||||||
|
* be used for the watchdog, so we use timer 2 if we're on a
|
||||||
|
* non-buggy chip.
|
||||||
*/
|
*/
|
||||||
ixp2000_reg_write(IXP2000_T4_CLD, -1);
|
if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
|
||||||
ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
|
printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n");
|
||||||
|
|
||||||
|
ixp2000_reg_write(IXP2000_T4_CLR, 0);
|
||||||
|
ixp2000_reg_write(IXP2000_T4_CLD, -1);
|
||||||
|
ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
|
||||||
|
missing_jiffy_timer_csr = IXP2000_T4_CSR;
|
||||||
|
} else {
|
||||||
|
ixp2000_reg_write(IXP2000_T2_CLR, 0);
|
||||||
|
ixp2000_reg_write(IXP2000_T2_CLD, -1);
|
||||||
|
ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7));
|
||||||
|
missing_jiffy_timer_csr = IXP2000_T2_CSR;
|
||||||
|
}
|
||||||
next_jiffy_time = 0xffffffff;
|
next_jiffy_time = 0xffffffff;
|
||||||
|
|
||||||
/* register for interrupt */
|
/* register for interrupt */
|
||||||
|
|
|
@ -32,10 +32,7 @@
|
||||||
|
|
||||||
extern void rpc_init_irq(void);
|
extern void rpc_init_irq(void);
|
||||||
|
|
||||||
extern unsigned int vram_size;
|
unsigned int vram_size;
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
unsigned int memc_ctrl_reg;
|
unsigned int memc_ctrl_reg;
|
||||||
unsigned int number_mfm_drives;
|
unsigned int number_mfm_drives;
|
||||||
|
|
||||||
|
@ -63,8 +60,6 @@ static int __init parse_tag_acorn(const struct tag *tag)
|
||||||
|
|
||||||
__tagtable(ATAG_ACORN, parse_tag_acorn);
|
__tagtable(ATAG_ACORN, parse_tag_acorn);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct map_desc rpc_io_desc[] __initdata = {
|
static struct map_desc rpc_io_desc[] __initdata = {
|
||||||
{ SCREEN_BASE, SCREEN_START, 2*1048576, MT_DEVICE }, /* VRAM */
|
{ SCREEN_BASE, SCREEN_START, 2*1048576, MT_DEVICE }, /* VRAM */
|
||||||
{ (u32)IO_BASE, IO_START, IO_SIZE , MT_DEVICE }, /* IO space */
|
{ (u32)IO_BASE, IO_START, IO_SIZE , MT_DEVICE }, /* IO space */
|
||||||
|
|
|
@ -5,3 +5,4 @@
|
||||||
obj-y := core.o clock.o
|
obj-y := core.o clock.o
|
||||||
obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o
|
obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o
|
||||||
obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o
|
obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o
|
||||||
|
obj-$(CONFIG_PCI) += pci.o
|
||||||
|
|
|
@ -196,11 +196,15 @@ static struct map_desc versatile_io_desc[] __initdata = {
|
||||||
#ifdef CONFIG_DEBUG_LL
|
#ifdef CONFIG_DEBUG_LL
|
||||||
{ IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE },
|
{ IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE },
|
||||||
#endif
|
#endif
|
||||||
#ifdef FIXME
|
#ifdef CONFIG_PCI
|
||||||
{ PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE },
|
{ IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
|
||||||
{ PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE },
|
{ VERSATILE_PCI_VIRT_BASE, VERSATILE_PCI_BASE, VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
|
||||||
{ PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_512K, MT_DEVICE },
|
{ VERSATILE_PCI_CFG_VIRT_BASE, VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
|
||||||
{ PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE },
|
#if 0
|
||||||
|
{ VERSATILE_PCI_VIRT_MEM_BASE0, VERSATILE_PCI_MEM_BASE0, SZ_16M, MT_DEVICE },
|
||||||
|
{ VERSATILE_PCI_VIRT_MEM_BASE1, VERSATILE_PCI_MEM_BASE1, SZ_16M, MT_DEVICE },
|
||||||
|
{ VERSATILE_PCI_VIRT_MEM_BASE2, VERSATILE_PCI_MEM_BASE2, SZ_16M, MT_DEVICE },
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
360
arch/arm/mach-versatile/pci.c
Normal file
360
arch/arm/mach-versatile/pci.c
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/mach-versatile/pci.c
|
||||||
|
*
|
||||||
|
* (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
|
||||||
|
* You can redistribute and/or modify this software under the terms of version 2
|
||||||
|
* of the GNU General Public License as published by the Free Software Foundation.
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" 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.
|
||||||
|
* Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
|
||||||
|
*
|
||||||
|
* ARM Versatile PCI driver.
|
||||||
|
*
|
||||||
|
* 14/04/2005 Initial version, colin.king@philips.com
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <linux/config.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
|
#include <asm/hardware.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <asm/mach/pci.h>
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* these spaces are mapped using the following base registers:
|
||||||
|
*
|
||||||
|
* Usage Local Bus Memory Base/Map registers used
|
||||||
|
*
|
||||||
|
* Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0, non prefetch
|
||||||
|
* Mem 60000000 - 6FFFFFFF LB_BASE1/LB_MAP1, prefetch
|
||||||
|
* IO 44000000 - 4FFFFFFF LB_BASE2/LB_MAP2, IO
|
||||||
|
* Cfg 42000000 - 42FFFFFF PCI config
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define SYS_PCICTL IO_ADDRESS(VERSATILE_SYS_PCICTL)
|
||||||
|
#define PCI_IMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
|
||||||
|
#define PCI_IMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
|
||||||
|
#define PCI_IMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
|
||||||
|
#define PCI_SMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
|
||||||
|
#define PCI_SMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
|
||||||
|
#define PCI_SMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
|
||||||
|
#define PCI_SELFID IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
|
||||||
|
|
||||||
|
#define DEVICE_ID_OFFSET 0x00
|
||||||
|
#define CSR_OFFSET 0x04
|
||||||
|
#define CLASS_ID_OFFSET 0x08
|
||||||
|
|
||||||
|
#define VP_PCI_DEVICE_ID 0x030010ee
|
||||||
|
#define VP_PCI_CLASS_ID 0x0b400000
|
||||||
|
|
||||||
|
static unsigned long pci_slot_ignore = 0;
|
||||||
|
|
||||||
|
static int __init versatile_pci_slot_ignore(char *str)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
int slot;
|
||||||
|
|
||||||
|
while ((retval = get_option(&str,&slot))) {
|
||||||
|
if ((slot < 0) || (slot > 31)) {
|
||||||
|
printk("Illegal slot value: %d\n",slot);
|
||||||
|
} else {
|
||||||
|
pci_slot_ignore |= (1 << slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned long __pci_addr(struct pci_bus *bus,
|
||||||
|
unsigned int devfn, int offset)
|
||||||
|
{
|
||||||
|
unsigned int busnr = bus->number;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trap out illegal values
|
||||||
|
*/
|
||||||
|
if (offset > 255)
|
||||||
|
BUG();
|
||||||
|
if (busnr > 255)
|
||||||
|
BUG();
|
||||||
|
if (devfn > 255)
|
||||||
|
BUG();
|
||||||
|
|
||||||
|
return (VERSATILE_PCI_CFG_VIRT_BASE | (busnr << 16) |
|
||||||
|
(PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||||
|
int size, u32 *val)
|
||||||
|
{
|
||||||
|
unsigned long addr = __pci_addr(bus, devfn, where);
|
||||||
|
u32 v;
|
||||||
|
int slot = PCI_SLOT(devfn);
|
||||||
|
|
||||||
|
if (pci_slot_ignore & (1 << slot)) {
|
||||||
|
/* Ignore this slot */
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
v = 0xff;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
v = 0xffff;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
v = 0xffffffff;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
addr &= ~3;
|
||||||
|
v = __raw_readb(addr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
v = __raw_readl(addr & ~3);
|
||||||
|
if (addr & 2) v >>= 16;
|
||||||
|
v &= 0xffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
addr &= ~3;
|
||||||
|
v = __raw_readl(addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*val = v;
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
|
||||||
|
int size, u32 val)
|
||||||
|
{
|
||||||
|
unsigned long addr = __pci_addr(bus, devfn, where);
|
||||||
|
int slot = PCI_SLOT(devfn);
|
||||||
|
|
||||||
|
if (pci_slot_ignore & (1 << slot)) {
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
__raw_writeb((u8)val, addr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
__raw_writew((u16)val, addr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
__raw_writel(val, addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pci_ops pci_versatile_ops = {
|
||||||
|
.read = versatile_read_config,
|
||||||
|
.write = versatile_write_config,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource io_mem = {
|
||||||
|
.name = "PCI I/O space",
|
||||||
|
.start = VERSATILE_PCI_MEM_BASE0,
|
||||||
|
.end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
|
||||||
|
.flags = IORESOURCE_IO,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource non_mem = {
|
||||||
|
.name = "PCI non-prefetchable",
|
||||||
|
.start = VERSATILE_PCI_MEM_BASE1,
|
||||||
|
.end = VERSATILE_PCI_MEM_BASE1+VERSATILE_PCI_MEM_BASE1_SIZE-1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource pre_mem = {
|
||||||
|
.name = "PCI prefetchable",
|
||||||
|
.start = VERSATILE_PCI_MEM_BASE2,
|
||||||
|
.end = VERSATILE_PCI_MEM_BASE2+VERSATILE_PCI_MEM_BASE2_SIZE-1,
|
||||||
|
.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init pci_versatile_setup_resources(struct resource **resource)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = request_resource(&iomem_resource, &io_mem);
|
||||||
|
if (ret) {
|
||||||
|
printk(KERN_ERR "PCI: unable to allocate I/O "
|
||||||
|
"memory region (%d)\n", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = request_resource(&iomem_resource, &non_mem);
|
||||||
|
if (ret) {
|
||||||
|
printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
|
||||||
|
"memory region (%d)\n", ret);
|
||||||
|
goto release_io_mem;
|
||||||
|
}
|
||||||
|
ret = request_resource(&iomem_resource, &pre_mem);
|
||||||
|
if (ret) {
|
||||||
|
printk(KERN_ERR "PCI: unable to allocate prefetchable "
|
||||||
|
"memory region (%d)\n", ret);
|
||||||
|
goto release_non_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bus->resource[0] is the IO resource for this bus
|
||||||
|
* bus->resource[1] is the mem resource for this bus
|
||||||
|
* bus->resource[2] is the prefetch mem resource for this bus
|
||||||
|
*/
|
||||||
|
resource[0] = &io_mem;
|
||||||
|
resource[1] = &non_mem;
|
||||||
|
resource[2] = &pre_mem;
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
release_non_mem:
|
||||||
|
release_resource(&non_mem);
|
||||||
|
release_io_mem:
|
||||||
|
release_resource(&io_mem);
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
int myslot = -1;
|
||||||
|
unsigned long val;
|
||||||
|
|
||||||
|
if (nr == 0) {
|
||||||
|
sys->mem_offset = 0;
|
||||||
|
ret = pci_versatile_setup_resources(sys->resource);
|
||||||
|
if (ret < 0) {
|
||||||
|
printk("pci_versatile_setup: resources... oops?\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printk("pci_versatile_setup: resources... nr == 0??\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
__raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28,PCI_IMAP0);
|
||||||
|
__raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28,PCI_IMAP1);
|
||||||
|
__raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28,PCI_IMAP2);
|
||||||
|
|
||||||
|
__raw_writel(1, SYS_PCICTL);
|
||||||
|
|
||||||
|
val = __raw_readl(SYS_PCICTL);
|
||||||
|
if (!(val & 1)) {
|
||||||
|
printk("Not plugged into PCI backplane!\n");
|
||||||
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to discover the PCI core first to configure itself
|
||||||
|
* before the main PCI probing is performed
|
||||||
|
*/
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
|
if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) &&
|
||||||
|
(__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) {
|
||||||
|
myslot = i;
|
||||||
|
|
||||||
|
__raw_writel(myslot, PCI_SELFID);
|
||||||
|
val = __raw_readl(VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
|
||||||
|
val |= (1<<2);
|
||||||
|
__raw_writel(val, VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myslot == -1) {
|
||||||
|
printk("Cannot find PCI core!\n");
|
||||||
|
ret = -EIO;
|
||||||
|
} else {
|
||||||
|
printk("PCI core found (slot %d)\n",myslot);
|
||||||
|
/* Do not to map Versatile FPGA PCI device
|
||||||
|
into memory space as we are short of
|
||||||
|
mappable memory */
|
||||||
|
pci_slot_ignore |= (1 << myslot);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct pci_bus *pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
|
||||||
|
{
|
||||||
|
return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* V3_LB_BASE? - local bus address
|
||||||
|
* V3_LB_MAP? - pci bus address
|
||||||
|
*/
|
||||||
|
void __init pci_versatile_preinit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init pci_versatile_postinit(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this.
|
||||||
|
*/
|
||||||
|
static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||||
|
{
|
||||||
|
int irq;
|
||||||
|
int devslot = PCI_SLOT(dev->devfn);
|
||||||
|
|
||||||
|
/* slot, pin, irq
|
||||||
|
24 1 27
|
||||||
|
25 1 28 untested
|
||||||
|
26 1 29
|
||||||
|
27 1 30 untested
|
||||||
|
*/
|
||||||
|
|
||||||
|
irq = 27 + ((slot + pin + 2) % 3); /* Fudged */
|
||||||
|
|
||||||
|
printk("map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq);
|
||||||
|
|
||||||
|
return irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct hw_pci versatile_pci __initdata = {
|
||||||
|
.swizzle = NULL,
|
||||||
|
.map_irq = versatile_map_irq,
|
||||||
|
.nr_controllers = 1,
|
||||||
|
.setup = pci_versatile_setup,
|
||||||
|
.scan = pci_versatile_scan_bus,
|
||||||
|
.preinit = pci_versatile_preinit,
|
||||||
|
.postinit = pci_versatile_postinit,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init versatile_pci_init(void)
|
||||||
|
{
|
||||||
|
pci_common_init(&versatile_pci);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
subsys_initcall(versatile_pci_init);
|
|
@ -62,7 +62,7 @@ config CPU_ARM720T
|
||||||
# ARM920T
|
# ARM920T
|
||||||
config CPU_ARM920T
|
config CPU_ARM920T
|
||||||
bool "Support ARM920T processor" if !ARCH_S3C2410
|
bool "Support ARM920T processor" if !ARCH_S3C2410
|
||||||
depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX
|
depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
|
||||||
default y if ARCH_S3C2410
|
default y if ARCH_S3C2410
|
||||||
select CPU_32v4
|
select CPU_32v4
|
||||||
select CPU_ABRT_EV4T
|
select CPU_ABRT_EV4T
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(v6_lock);
|
static DEFINE_SPINLOCK(v6_lock);
|
||||||
|
|
||||||
#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the user page. No aliasing to deal with so we can just
|
* Copy the user page. No aliasing to deal with so we can just
|
||||||
* attack the kernel's existing mapping of these pages.
|
* attack the kernel's existing mapping of these pages.
|
||||||
|
@ -55,7 +53,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
|
||||||
*/
|
*/
|
||||||
void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
|
void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
unsigned int offset = DCACHE_COLOUR(vaddr);
|
unsigned int offset = CACHE_COLOUR(vaddr);
|
||||||
unsigned long from, to;
|
unsigned long from, to;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -95,7 +93,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
|
||||||
*/
|
*/
|
||||||
void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
|
void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
unsigned int offset = DCACHE_COLOUR(vaddr);
|
unsigned int offset = CACHE_COLOUR(vaddr);
|
||||||
unsigned long to = to_address + (offset << PAGE_SHIFT);
|
unsigned long to = to_address + (offset << PAGE_SHIFT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -77,9 +77,8 @@ no_pmd:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
|
make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = page_mapping(page);
|
|
||||||
struct mm_struct *mm = vma->vm_mm;
|
struct mm_struct *mm = vma->vm_mm;
|
||||||
struct vm_area_struct *mpnt;
|
struct vm_area_struct *mpnt;
|
||||||
struct prio_tree_iter iter;
|
struct prio_tree_iter iter;
|
||||||
|
@ -87,9 +86,6 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
|
||||||
pgoff_t pgoff;
|
pgoff_t pgoff;
|
||||||
int aliases = 0;
|
int aliases = 0;
|
||||||
|
|
||||||
if (!mapping)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
|
pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -115,9 +111,11 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
|
||||||
if (aliases)
|
if (aliases)
|
||||||
adjust_pte(vma, addr);
|
adjust_pte(vma, addr);
|
||||||
else
|
else
|
||||||
flush_cache_page(vma, addr, page_to_pfn(page));
|
flush_cache_page(vma, addr, pfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __flush_dcache_page(struct address_space *mapping, struct page *page);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Take care of architecture specific things when placing a new PTE into
|
* Take care of architecture specific things when placing a new PTE into
|
||||||
* a page table, or changing an existing PTE. Basically, there are two
|
* a page table, or changing an existing PTE. Basically, there are two
|
||||||
|
@ -134,29 +132,22 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
|
||||||
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
|
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
|
||||||
{
|
{
|
||||||
unsigned long pfn = pte_pfn(pte);
|
unsigned long pfn = pte_pfn(pte);
|
||||||
|
struct address_space *mapping;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
|
||||||
if (!pfn_valid(pfn))
|
if (!pfn_valid(pfn))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
page = pfn_to_page(pfn);
|
page = pfn_to_page(pfn);
|
||||||
if (page_mapping(page)) {
|
mapping = page_mapping(page);
|
||||||
|
if (mapping) {
|
||||||
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
|
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
|
||||||
|
|
||||||
if (dirty) {
|
if (dirty)
|
||||||
/*
|
__flush_dcache_page(mapping, page);
|
||||||
* This is our first userspace mapping of this page.
|
|
||||||
* Ensure that the physical page is coherent with
|
|
||||||
* the kernel mapping.
|
|
||||||
*
|
|
||||||
* FIXME: only need to do this on VIVT and aliasing
|
|
||||||
* VIPT cache architectures. We can do that
|
|
||||||
* by choosing whether to set this bit...
|
|
||||||
*/
|
|
||||||
__cpuc_flush_dcache_page(page_address(page));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache_is_vivt())
|
if (cache_is_vivt())
|
||||||
make_coherent(vma, addr, page, dirty);
|
make_coherent(mapping, vma, addr, pfn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,13 +37,8 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
|
||||||
#define flush_pfn_alias(pfn,vaddr) do { } while (0)
|
#define flush_pfn_alias(pfn,vaddr) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __flush_dcache_page(struct address_space *mapping, struct page *page)
|
void __flush_dcache_page(struct address_space *mapping, struct page *page)
|
||||||
{
|
{
|
||||||
struct mm_struct *mm = current->active_mm;
|
|
||||||
struct vm_area_struct *mpnt;
|
|
||||||
struct prio_tree_iter iter;
|
|
||||||
pgoff_t pgoff;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Writeback any data associated with the kernel mapping of this
|
* Writeback any data associated with the kernel mapping of this
|
||||||
* page. This ensures that data in the physical page is mutually
|
* page. This ensures that data in the physical page is mutually
|
||||||
|
@ -52,24 +47,21 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
|
||||||
__cpuc_flush_dcache_page(page_address(page));
|
__cpuc_flush_dcache_page(page_address(page));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's no mapping pointer here, then this page isn't
|
* If this is a page cache page, and we have an aliasing VIPT cache,
|
||||||
* visible to userspace yet, so there are no cache lines
|
* we only need to do one flush - which would be at the relevant
|
||||||
* associated with any other aliases.
|
|
||||||
*/
|
|
||||||
if (!mapping)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a page cache page. If we have a VIPT cache, we
|
|
||||||
* only need to do one flush - which would be at the relevant
|
|
||||||
* userspace colour, which is congruent with page->index.
|
* userspace colour, which is congruent with page->index.
|
||||||
*/
|
*/
|
||||||
if (cache_is_vipt()) {
|
if (mapping && cache_is_vipt_aliasing())
|
||||||
if (cache_is_vipt_aliasing())
|
flush_pfn_alias(page_to_pfn(page),
|
||||||
flush_pfn_alias(page_to_pfn(page),
|
page->index << PAGE_CACHE_SHIFT);
|
||||||
page->index << PAGE_CACHE_SHIFT);
|
}
|
||||||
return;
|
|
||||||
}
|
static void __flush_dcache_aliases(struct address_space *mapping, struct page *page)
|
||||||
|
{
|
||||||
|
struct mm_struct *mm = current->active_mm;
|
||||||
|
struct vm_area_struct *mpnt;
|
||||||
|
struct prio_tree_iter iter;
|
||||||
|
pgoff_t pgoff;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are possible user space mappings of this page:
|
* There are possible user space mappings of this page:
|
||||||
|
@ -116,12 +108,12 @@ void flush_dcache_page(struct page *page)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = page_mapping(page);
|
struct address_space *mapping = page_mapping(page);
|
||||||
|
|
||||||
if (cache_is_vipt_nonaliasing())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mapping && !mapping_mapped(mapping))
|
if (mapping && !mapping_mapped(mapping))
|
||||||
set_bit(PG_dcache_dirty, &page->flags);
|
set_bit(PG_dcache_dirty, &page->flags);
|
||||||
else
|
else {
|
||||||
__flush_dcache_page(mapping, page);
|
__flush_dcache_page(mapping, page);
|
||||||
|
if (mapping && cache_is_vivt())
|
||||||
|
__flush_dcache_aliases(mapping, page);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(flush_dcache_page);
|
EXPORT_SYMBOL(flush_dcache_page);
|
||||||
|
|
|
@ -93,14 +93,7 @@ struct node_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
|
#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
|
||||||
#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
|
|
||||||
|
|
||||||
#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
|
#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
|
||||||
#define V_PFN_UP(x) O_PFN_UP(__pa(x))
|
|
||||||
|
|
||||||
#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
|
|
||||||
#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
|
|
||||||
(((unsigned long)(s)) & PAGE_MASK))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: We really want to avoid allocating the bootmap bitmap
|
* FIXME: We really want to avoid allocating the bootmap bitmap
|
||||||
|
@ -113,7 +106,7 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
|
||||||
{
|
{
|
||||||
unsigned int start_pfn, bank, bootmap_pfn;
|
unsigned int start_pfn, bank, bootmap_pfn;
|
||||||
|
|
||||||
start_pfn = V_PFN_UP(&_end);
|
start_pfn = O_PFN_UP(__pa(&_end));
|
||||||
bootmap_pfn = 0;
|
bootmap_pfn = 0;
|
||||||
|
|
||||||
for (bank = 0; bank < mi->nr_banks; bank ++) {
|
for (bank = 0; bank < mi->nr_banks; bank ++) {
|
||||||
|
@ -122,9 +115,9 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
|
||||||
if (mi->bank[bank].node != node)
|
if (mi->bank[bank].node != node)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
start = O_PFN_UP(mi->bank[bank].start);
|
start = mi->bank[bank].start >> PAGE_SHIFT;
|
||||||
end = O_PFN_DOWN(mi->bank[bank].size +
|
end = (mi->bank[bank].size +
|
||||||
mi->bank[bank].start);
|
mi->bank[bank].start) >> PAGE_SHIFT;
|
||||||
|
|
||||||
if (end < start_pfn)
|
if (end < start_pfn)
|
||||||
continue;
|
continue;
|
||||||
|
@ -191,8 +184,8 @@ find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
|
||||||
/*
|
/*
|
||||||
* Get the start and end pfns for this bank
|
* Get the start and end pfns for this bank
|
||||||
*/
|
*/
|
||||||
start = O_PFN_UP(mi->bank[i].start);
|
start = mi->bank[i].start >> PAGE_SHIFT;
|
||||||
end = O_PFN_DOWN(mi->bank[i].start + mi->bank[i].size);
|
end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
|
||||||
|
|
||||||
if (np[node].start > start)
|
if (np[node].start > start)
|
||||||
np[node].start = start;
|
np[node].start = start;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue