Commit d588fcbe authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6: (44 commits)
  [PATCH] I2C: I2C controllers go into right place on sysfs
  [PATCH] hwmon-vid: Add support for Intel Core and Conroe
  [PATCH] lm70: New hardware monitoring driver
  [PATCH] hwmon: Fix the Kconfig header
  [PATCH] i2c-i801: Merge setup function
  [PATCH] i2c-i801: Better pci subsystem integration
  [PATCH] i2c-i801: Cleanups
  [PATCH] i2c-i801: Remove PCI function check
  [PATCH] i2c-i801: Remove force_addr parameter
  [PATCH] i2c-i801: Fix block transaction poll loops
  [PATCH] scx200_acb: Documentation update
  [PATCH] scx200_acb: Mark scx200_acb_probe __init
  [PATCH] scx200_acb: Use PCI I/O resource when appropriate
  [PATCH] i2c: Mark block write buffers as const
  [PATCH] i2c-ocores: Minor cleanups
  [PATCH] abituguru: Fix fan detection
  [PATCH] abituguru: Review fixes
  [PATCH] abituguru: New hardware monitoring driver
  [PATCH] w83792d: Add missing data access locks
  [PATCH] w83792d: Fix setting the PWM value
  ...
parents eaa85689 4941b395
Kernel driver abituguru
=======================
Supported chips:
* Abit uGuru (Hardware Monitor part only)
Prefix: 'abituguru'
Addresses scanned: ISA 0x0E0
Datasheet: Not available, this driver is based on reverse engineering.
A "Datasheet" has been written based on the reverse engineering it
should be available in the same dir as this file under the name
abituguru-datasheet.
Authors:
Hans de Goede <j.w.r.degoede@hhs.nl>,
(Initial reverse engineering done by Olle Sandberg
<ollebull@gmail.com>)
Module Parameters
-----------------
* force: bool Force detection. Note this parameter only causes the
detection to be skipped, if the uGuru can't be read
the module initialization (insmod) will still fail.
* fan_sensors: int Tell the driver how many fan speed sensors there are
on your motherboard. Default: 0 (autodetect).
* pwms: int Tell the driver how many fan speed controls (fan
pwms) your motherboard has. Default: 0 (autodetect).
* verbose: int How verbose should the driver be? (0-3):
0 normal output
1 + verbose error reporting
2 + sensors type probing info\n"
3 + retryable error reporting
Default: 2 (the driver is still in the testing phase)
Notice if you need any of the first three options above please insmod the
driver with verbose set to 3 and mail me <j.w.r.degoede@hhs.nl> the output of:
dmesg | grep abituguru
Description
-----------
This driver supports the hardware monitoring features of the Abit uGuru chip
found on Abit uGuru featuring motherboards (most modern Abit motherboards).
The uGuru chip in reality is a Winbond W83L950D in disguise (despite Abit
claiming it is "a new microprocessor designed by the ABIT Engineers").
Unfortunatly this doesn't help since the W83L950D is a generic
microcontroller with a custom Abit application running on it.
Despite Abit not releasing any information regarding the uGuru, Olle
Sandberg <ollebull@gmail.com> has managed to reverse engineer the sensor part
of the uGuru. Without his work this driver would not have been possible.
Known Issues
------------
The voltage and frequency control parts of the Abit uGuru are not supported.
This diff is collapsed.
Kernel driver lm70
==================
Supported chip:
* National Semiconductor LM70
Datasheet: http://www.national.com/pf/LM/LM70.html
Author:
Kaiwan N Billimoria <kaiwan@designergraphix.com>
Description
-----------
This driver implements support for the National Semiconductor LM70
temperature sensor.
The LM70 temperature sensor chip supports a single temperature sensor.
It communicates with a host processor (or microcontroller) via an
SPI/Microwire Bus interface.
Communication with the LM70 is simple: when the temperature is to be sensed,
the driver accesses the LM70 using SPI communication: 16 SCLK cycles
comprise the MOSI/MISO loop. At the end of the transfer, the 11-bit 2's
complement digital temperature (sent via the SIO line), is available in the
driver for interpretation. This driver makes use of the kernel's in-core
SPI support.
Thanks to
---------
Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver
development.
...@@ -7,6 +7,10 @@ Supported chips: ...@@ -7,6 +7,10 @@ Supported chips:
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
Datasheet: Publicly available at the National Semiconductor website Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/pf/LM/LM83.html http://www.national.com/pf/LM/LM83.html
* National Semiconductor LM82
Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/pf/LM/LM82.html
Author: Jean Delvare <khali@linux-fr.org> Author: Jean Delvare <khali@linux-fr.org>
...@@ -15,10 +19,11 @@ Description ...@@ -15,10 +19,11 @@ Description
----------- -----------
The LM83 is a digital temperature sensor. It senses its own temperature as 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 well as the temperature of up to three external diodes. The LM82 is
with many other devices such as the LM84 and all other ADM1021 clones. a stripped down version of the LM83 that only supports one external diode.
The main difference between the LM83 and the LM84 in that the later can Both are compatible with many other devices such as the LM84 and all
only sense the temperature of one external diode. 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 Using the adm1021 driver for a LM83 should work, but only two temperatures
will be reported instead of four. will be reported instead of four.
...@@ -30,12 +35,16 @@ contact us. Note that the LM90 can easily be misdetected as a LM83. ...@@ -30,12 +35,16 @@ contact us. Note that the LM90 can easily be misdetected as a LM83.
Confirmed motherboards: Confirmed motherboards:
SBS P014 SBS P014
SBS PSL09
Unconfirmed motherboards: Unconfirmed motherboards:
Gigabyte GA-8IK1100 Gigabyte GA-8IK1100
Iwill MPX2 Iwill MPX2
Soltek SL-75DRV5 Soltek SL-75DRV5
The LM82 is confirmed to have been found on most AMD Geode reference
designs and test platforms.
The driver has been successfully tested by Magnus Forsström, who I'd The driver has been successfully tested by Magnus Forsström, who I'd
like to thank here. More testers will be of course welcome. like to thank here. More testers will be of course welcome.
......
Kernel driver smsc47m192
========================
Supported chips:
* SMSC LPC47M192 and LPC47M997
Prefix: 'smsc47m192'
Addresses scanned: I2C 0x2c - 0x2d
Datasheet: The datasheet for LPC47M192 is publicly available from
http://www.smsc.com/
The LPC47M997 is compatible for hardware monitoring.
Author: Hartmut Rick <linux@rick.claranet.de>
Special thanks to Jean Delvare for careful checking
of the code and many helpful comments and suggestions.
Description
-----------
This driver implements support for the hardware sensor capabilities
of the SMSC LPC47M192 and LPC47M997 Super-I/O chips.
These chips support 3 temperature channels and 8 voltage inputs
as well as CPU voltage VID input.
They do also have fan monitoring and control capabilities, but the
these features are accessed via ISA bus and are not supported by this
driver. Use the 'smsc47m1' driver for fan monitoring and control.
Voltages and temperatures are measured by an 8-bit ADC, the resolution
of the temperatures is 1 bit per degree C.
Voltages are scaled such that the nominal voltage corresponds to
192 counts, i.e. 3/4 of the full range. Thus the available range for
each voltage channel is 0V ... 255/192*(nominal voltage), the resolution
is 1 bit per (nominal voltage)/192.
Both voltage and temperature values are scaled by 1000, the sys files
show voltages in mV and temperatures in units of 0.001 degC.
The +12V analog voltage input channel (in4_input) is multiplexed with
bit 4 of the encoded CPU voltage. This means that you either get
a +12V voltage measurement or a 5 bit CPU VID, but not both.
The default setting is to use the pin as 12V input, and use only 4 bit VID.
This driver assumes that the information in the configuration register
is correct, i.e. that the BIOS has updated the configuration if
the motherboard has this input wired to VID4.
The temperature and voltage readings are updated once every 1.5 seconds.
Reading them more often repeats the same values.
sysfs interface
---------------
in0_input - +2.5V voltage input
in1_input - CPU voltage input (nominal 2.25V)
in2_input - +3.3V voltage input
in3_input - +5V voltage input
in4_input - +12V voltage input (may be missing if used as VID4)
in5_input - Vcc voltage input (nominal 3.3V)
This is the supply voltage of the sensor chip itself.
in6_input - +1.5V voltage input
in7_input - +1.8V voltage input
in[0-7]_min,
in[0-7]_max - lower and upper alarm thresholds for in[0-7]_input reading
All voltages are read and written in mV.
in[0-7]_alarm - alarm flags for voltage inputs
These files read '1' in case of alarm, '0' otherwise.
temp1_input - chip temperature measured by on-chip diode
temp[2-3]_input - temperature measured by external diodes (one of these would
typically be wired to the diode inside the CPU)
temp[1-3]_min,
temp[1-3]_max - lower and upper alarm thresholds for temperatures
temp[1-3]_offset - temperature offset registers
The chip adds the offsets stored in these registers to
the corresponding temperature readings.
Note that temp1 and temp2 offsets share the same register,
they cannot both be different from zero at the same time.
Writing a non-zero number to one of them will reset the other
offset to zero.
All temperatures and offsets are read and written in
units of 0.001 degC.
temp[1-3]_alarm - alarm flags for temperature inputs, '1' in case of alarm,
'0' otherwise.
temp[2-3]_input_fault - diode fault flags for temperature inputs 2 and 3.
A fault is detected if the two pins for the corresponding
sensor are open or shorted, or any of the two is shorted
to ground or Vcc. '1' indicates a diode fault.
cpu0_vid - CPU voltage as received from the CPU
vrm - CPU VID standard used for decoding CPU voltage
The *_min, *_max, *_offset and vrm files can be read and
written, all others are read-only.
This diff is collapsed.
...@@ -6,31 +6,32 @@ voltages, fans speed). They are often connected through an I2C bus, but some ...@@ -6,31 +6,32 @@ voltages, fans speed). They are often connected through an I2C bus, but some
are also connected directly through the ISA bus. are also connected directly through the ISA bus.
The kernel drivers make the data from the sensor chips available in the /sys 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 virtual filesystem. Userspace tools are then used to display the measured
data in a more friendly manner. values or configure the chips in a more friendly manner.
Lm-sensors Lm-sensors
---------- ----------
Core set of utilites that will allow you to obtain health information, Core set of utilities that will allow you to obtain health information,
setup monitoring limits etc. You can get them on their homepage setup monitoring limits etc. You can get them on their homepage
http://www.lm-sensors.nu/ or as a package from your Linux distribution. http://www.lm-sensors.nu/ or as a package from your Linux distribution.
If from website: If from website:
Get lmsensors from project web site. Please note, you need only userspace Get lm-sensors from project web site. Please note, you need only userspace
part, so compile with "make user_install" target. part, so compile with "make user" and install with "make user_install".
General hints to get things working: General hints to get things working:
0) get lm-sensors userspace utils 0) get lm-sensors userspace utils
1) compile all drivers in I2C section as modules in your kernel 1) compile all drivers in I2C and Hardware Monitoring sections as modules
in your kernel
2) run sensors-detect script, it will tell you what modules you need to load. 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. 3) load them and run "sensors" command, you should see some results.
4) fix sensors.conf, labels, limits, fan divisors 4) fix sensors.conf, labels, limits, fan divisors
5) if any more problems consult FAQ, or documentation 5) if any more problems consult FAQ, or documentation
Other utilites Other utilities
-------------- ---------------
If you want some graphical indicators of system health look for applications If you want some graphical indicators of system health look for applications
like: gkrellm, ksensors, xsensors, wmtemp, wmsensors, wmgtemp, ksysguardd, like: gkrellm, ksensors, xsensors, wmtemp, wmsensors, wmgtemp, ksysguardd,
......
Kernel driver w83791d
=====================
Supported chips:
* Winbond W83791D
Prefix: 'w83791d'
Addresses scanned: I2C 0x2c - 0x2f
Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791Da.pdf
Author: Charles Spirakis <bezaur@gmail.com>
This driver was derived from the w83781d.c and w83792d.c source files.
Credits:
w83781d.c:
Frodo Looijaard <frodol@dds.nl>,
Philip Edelbrock <phil@netroedge.com>,
and Mark Studebaker <mdsxyz123@yahoo.com>
w83792d.c:
Chunhao Huang <DZShen@Winbond.com.tw>,
Rudolf Marek <r.marek@sh.cvut.cz>
Module Parameters
-----------------
* init boolean
(default 0)
Use 'init=1' to have the driver do extra software initializations.
The default behavior is to do the minimum initialization possible
and depend on the BIOS to properly setup the chip. If you know you
have a w83791d and you're having problems, try init=1 before trying
reset=1.
* reset boolean
(default 0)
Use 'reset=1' to reset the chip (via index 0x40, bit 7). The default
behavior is no chip reset to preserve BIOS settings.
* force_subclients=bus,caddr,saddr,saddr
This is used to force the i2c addresses for subclients of
a certain chip. Example usage is `force_subclients=0,0x2f,0x4a,0x4b'
to force the subclients of chip 0x2f on bus 0 to i2c addresses
0x4a and 0x4b.
Description
-----------
This driver implements support for the Winbond W83791D chip.
Detection of the chip can sometimes be foiled because it can be in an
internal state that allows no clean access (Bank with ID register is not
currently selected). If you know the address of the chip, use a 'force'
parameter; this will put it into a more well-behaved state first.
The driver implements three temperature sensors, five fan rotation speed
sensors, and ten voltage sensors.
Temperatures are measured in degrees Celsius and measurement resolution is 1
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
the temperature gets higher than the Overtemperature Shutdown value; it stays
on until the temperature falls 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, 8 for fan 1/2/3
and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more
range or accuracy.
Voltage sensors (also known as IN sensors) report their values in millivolts.
An alarm is triggered if the voltage has crossed a programmable minimum
or maximum limit.
Alarms are provided as output from a "realtime status register". The
following bits are defined:
bit - alarm on:
0 - Vcore
1 - VINR0
2 - +3.3VIN
3 - 5VDD
4 - temp1
5 - temp2
6 - fan1
7 - fan2
8 - +12VIN
9 - -12VIN
10 - -5VIN
11 - fan3
12 - chassis
13 - temp3
14 - VINR1
15 - reserved
16 - tart1
17 - tart2
18 - tart3
19 - VSB
20 - VBAT
21 - fan4
22 - fan5
23 - reserved
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.
The driver only reads the chip values each 3 seconds; reading them more
often will do no harm, but will return 'old' values.
W83791D TODO:
---------------
Provide a patch for per-file alarms as discussed on the mailing list
Provide a patch for smart-fan control (still need appropriate motherboard/fans)
...@@ -21,8 +21,7 @@ Authors: ...@@ -21,8 +21,7 @@ Authors:
Module Parameters Module Parameters
----------------- -----------------
* force_addr: int None.
Forcibly enable the ICH at the given address. EXTREMELY DANGEROUS!
Description Description
......
...@@ -7,6 +7,8 @@ Supported adapters: ...@@ -7,6 +7,8 @@ Supported adapters:
* nForce3 250Gb MCP 10de:00E4 * nForce3 250Gb MCP 10de:00E4
* nForce4 MCP 10de:0052 * nForce4 MCP 10de:0052
* nForce4 MCP-04 10de:0034 * nForce4 MCP-04 10de:0034
* nForce4 MCP51 10de:0264
* nForce4 MCP55 10de:0368
Datasheet: not publically available, but seems to be similar to the Datasheet: not publically available, but seems to be similar to the
AMD-8111 SMBus 2.0 adapter. AMD-8111 SMBus 2.0 adapter.
......
Kernel driver i2c-ocores
Supported adapters:
* OpenCores.org I2C controller by Richard Herveille (see datasheet link)
Datasheet: http://www.opencores.org/projects.cgi/web/i2c/overview
Author: Peter Korsgaard <jacmet@sunsite.dk>
Description
-----------
i2c-ocores is an i2c bus driver for the OpenCores.org I2C controller
IP core by Richard Herveille.
Usage
-----
i2c-ocores uses the platform bus, so you need to provide a struct
platform_device with the base address and interrupt number. The
dev.platform_data of the device should also point to a struct
ocores_i2c_platform_data (see linux/i2c-ocores.h) describing the
distance between registers and the input clock speed.
E.G. something like:
static struct resource ocores_resources[] = {
[0] = {
.start = MYI2C_BASEADDR,
.end = MYI2C_BASEADDR + 8,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = MYI2C_IRQ,
.end = MYI2C_IRQ,
.flags = IORESOURCE_IRQ,
},
};
static struct ocores_i2c_platform_data myi2c_data = {
.regstep = 2, /* two bytes between registers */
.clock_khz = 50000, /* input clock of 50MHz */
};
static struct platform_device myi2c = {
.name = "ocores-i2c",
.dev = {
.platform_data = &myi2c_data,
},
.num_resources = ARRAY_SIZE(ocores_resources),
.resource = ocores_resources,
};
...@@ -6,6 +6,8 @@ Supported adapters: ...@@ -6,6 +6,8 @@ Supported adapters:
Datasheet: Publicly available at the Intel website Datasheet: Publicly available at the Intel website
* ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
Datasheet: Only available via NDA from ServerWorks Datasheet: Only available via NDA from ServerWorks
* ATI IXP southbridges IXP200, IXP300, IXP400
Datasheet: Not publicly available
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
Datasheet: Publicly available at the SMSC website http://www.smsc.com Datasheet: Publicly available at the SMSC website http://www.smsc.com
...@@ -21,8 +23,6 @@ Module Parameters ...@@ -21,8 +23,6 @@ Module Parameters
Forcibly enable the PIIX4. DANGEROUS! Forcibly enable the PIIX4. DANGEROUS!
* force_addr: int * force_addr: int
Forcibly enable the PIIX4 at the given address. EXTREMELY DANGEROUS! Forcibly enable the PIIX4 at the given address. EXTREMELY DANGEROUS!
* fix_hstcfg: int
Fix config register. Needed on some boards (Force CPCI735).
Description Description
...@@ -63,10 +63,36 @@ The PIIX4E is just an new version of the PIIX4; it is supported as well. ...@@ -63,10 +63,36 @@ The PIIX4E is just an new version of the PIIX4; it is supported as well.
The PIIX/PIIX3 does not implement an SMBus or I2C bus, so you can't use The PIIX/PIIX3 does not implement an SMBus or I2C bus, so you can't use
this driver on those mainboards. this driver on those mainboards.
The ServerWorks Southbridges, the Intel 440MX, and the Victory766 are The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are
identical to the PIIX4 in I2C/SMBus support. identical to the PIIX4 in I2C/SMBus support.
A few OSB4 southbridges are known to be misconfigured by the BIOS. In this If you own Force CPCI735 motherboard or other OSB4 based systems you may need
case, you have you use the fix_hstcfg module parameter. Do not use it to change the SMBus Interrupt Select register so the SMBus controller uses
unless you know you have to, because in some cases it also breaks the SMI mode.
configuration on southbridges that don't need it.
1) Use lspci command and locate the PCI device with the SMBus controller:
00:0f.0 ISA bridge: ServerWorks OSB4 South Bridge (rev 4f)
The line may vary for different chipsets. Please consult the driver source
for all possible PCI ids (and lspci -n to match them). Lets assume the
device is located at 00:0f.0.
2) Now you just need to change the value in 0xD2 register. Get it first with
command: lspci -xxx -s 00:0f.0
If the value is 0x3 then you need to change it to 0x1
setpci -s 00:0f.0 d2.b=1
Please note that you don't need to do that in all cases, just when the SMBus is
not working properly.
Hardware-specific issues
------------------------
This driver will refuse to load on IBM systems with an Intel PIIX4 SMBus.
Some of these machines have an RFID EEPROM (24RF08) connected to the SMBus,
which can easily get corrupted due to a state machine bug. These are mostly
Thinkpad laptops, but desktop systems may also be affected. We have no list
of all affected systems, so the only safe solution was to prevent access to
the SMBus on all IBM systems (detected using DMI data.)
For additional information, read:
http://www2.lm-sensors.nu/~lm78/cvs/lm_sensors2/README.thinkpad
...@@ -2,14 +2,31 @@ Kernel driver scx200_acb ...@@ -2,14 +2,31 @@ Kernel driver scx200_acb
Author: Christer Weinigel <wingel@nano-system.com> Author: Christer Weinigel <wingel@nano-system.com>
The driver supersedes the older, never merged driver named i2c-nscacb.
Module Parameters Module Parameters
----------------- -----------------
* base: int * base: up to 4 ints
Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices
By default the driver uses two base addresses 0x820 and 0x840.
If you want only one base address, specify the second as 0 so as to
override this default.
Description Description
----------- -----------
Enable the use of the ACCESS.bus controller on the Geode SCx200 and Enable the use of the ACCESS.bus controller on the Geode SCx200 and
SC1100 processors and the CS5535 and CS5536 Geode companion devices. SC1100 processors and the CS5535 and CS5536 Geode companion devices.
Device-specific notes
---------------------
The SC1100 WRAP boards are known to use base addresses 0x810 and 0x820.
If the scx200_acb driver is built into the kernel, add the following
parameter to your boot command line:
scx200_acb.base=0x810,0x820
If the scx200_acb driver is built as a module, add the following line to
the file /etc/modprobe.conf instead:
options scx200_acb base=0x810,0x820
...@@ -181,6 +181,12 @@ M: bcrl@kvack.org ...@@ -181,6 +181,12 @@ M: bcrl@kvack.org
L: linux-aio@kvack.org L: linux-aio@kvack.org
S: Supported S: Supported
ABIT UGURU HARDWARE MONITOR DRIVER
P: Hans de Goede
M: j.w.r.degoede@hhs.nl
L: lm-sensors@lm-sensors.org
S: Maintained
ACENIC DRIVER ACENIC DRIVER
P: Jes Sorensen P: Jes Sorensen
M: jes@trained-monkey.org M: jes@trained-monkey.org
...@@ -2057,6 +2063,12 @@ M: adaplas@pol.net ...@@ -2057,6 +2063,12 @@ M: adaplas@pol.net
L: linux-fbdev-devel@lists.sourceforge.net L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained S: Maintained
OPENCORES I2C BUS DRIVER
P: Peter Korsgaard
M: jacmet@sunsite.dk
L: lm-sensors@lm-sensors.org
S: Maintained
ORACLE CLUSTER FILESYSTEM 2 (OCFS2) ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
P: Mark Fasheh P: Mark Fasheh
M: mark.fasheh@oracle.com M: mark.fasheh@oracle.com
...@@ -2528,12 +2540,6 @@ M: thomas@winischhofer.net ...@@ -2528,12 +2540,6 @@ M: thomas@winischhofer.net
W: http://www.winischhofer.at/linuxsisusbvga.shtml W: http://www.winischhofer.at/linuxsisusbvga.shtml
S: Maintained S: Maintained
SMSC47M1 HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Odd Fixes
SMB FILESYSTEM SMB FILESYSTEM
P: Urban Widmark P: Urban Widmark
M: urban@teststation.com M: urban@teststation.com
...@@ -3146,12 +3152,6 @@ L: wbsd-devel@list.drzeus.cx ...@@ -3146,12 +3152,6 @@ L: wbsd-devel@list.drzeus.cx
W: http://projects.drzeus.cx/wbsd W: http://projects.drzeus.cx/wbsd
S: Maintained S: Maintained
W83L785TS HARDWARE MONITOR DRIVER
P: Jean Delvare
M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Odd Fixes
WATCHDOG DEVICE DRIVERS WATCHDOG DEVICE DRIVERS
P: Wim Van Sebroeck P: Wim Van Sebroeck
M: wim@iguana.be M: wim@iguana.be
......
# #
# I2C Sensor chip drivers configuration # Hardware monitoring chip drivers configuration
# #
menu "Hardware Monitoring support" menu "Hardware Monitoring support"
...@@ -16,6 +16,10 @@ config HWMON ...@@ -16,6 +16,10 @@ config HWMON
should say Y here and also to the specific driver(s) for your should say Y here and also to the specific driver(s) for your
sensors chip(s) below. sensors chip(s) below.
To find out which specific driver(s) you need, use the
sensors-detect script from the lm_sensors package. Read
<file:Documentation/hwmon/userspace-tools> for details.
This support can also be built as a module. If so, the module This support can also be built as a module. If so, the module
will be called hwmon. will be called hwmon.
...@@ -23,6 +27,18 @@ config HWMON_VID ...@@ -23,6 +27,18 @@ config HWMON_VID
tristate tristate
default n default n
config SENSORS_ABITUGURU
tristate "Abit uGuru"
depends on HWMON && EXPERIMENTAL
help
If you say yes here you get support for the Abit uGuru chips
sensor part. The voltage and frequency control parts of the Abit
uGuru are not supported. The Abit uGuru chip can be found on Abit
uGuru featuring motherboards (most modern Abit motherboards).
This driver can also be built as a module. If so, the module
will be called abituguru.
config SENSORS_ADM1021 config SENSORS_ADM1021
tristate "Analog Devices ADM1021 and compatibles" tristate "Analog Devices ADM1021 and compatibles"
depends on HWMON && I2C depends on HWMON && I2C
...@@ -188,6 +204,16 @@ config SENSORS_LM63 ...@@ -188,6 +204,16 @@ config SENSORS_LM63
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called lm63. will be called lm63.
config SENSORS_LM70
tristate "National Semiconductor LM70"
depends on HWMON && SPI_MASTER && EXPERIMENTAL
help
If you say yes here you get support for the National Semiconductor
LM70 digital temperature sensor chip.
This driver can also be built as a module. If so, the module
will be called lm70.
config SENSORS_LM75 config SENSORS_LM75
tristate "National Semiconductor LM75 and compatibles" tristate "National Semiconductor LM75 and compatibles"
depends on HWMON && I2C depends on HWMON && I2C
...@@ -236,11 +262,11 @@ config SENSORS_LM80 ...@@ -236,11 +262,11 @@ config SENSORS_LM80
will be called lm80. will be called lm80.
config SENSORS_LM83 config SENSORS_LM83
tristate "National Semiconductor LM83" tristate "National Semiconductor LM83 and compatibles"
depends on HWMON && I2C depends on HWMON && I2C
help help
If you say yes here you get support for National Semiconductor If you say yes here you get support for National Semiconductor
LM83 sensor chips. LM82 and LM83 sensor chips.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called lm83. will be called lm83.
...@@ -333,11 +359,32 @@ config SENSORS_SMSC47M1 ...@@ -333,11 +359,32 @@ config SENSORS_SMSC47M1
help help
If you say yes here you get support for the integrated fan If you say yes here you get support for the integrated fan
monitoring and control capabilities of the SMSC LPC47B27x, monitoring and control capabilities of the SMSC LPC47B27x,
LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips. LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and
LPC47M997 chips.
The temperature and voltage sensor features of the LPC47M192
and LPC47M997 are supported by another driver, select also
"SMSC LPC47M192 and compatibles" below for those.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called smsc47m1. will be called smsc47m1.
config SENSORS_SMSC47M192
tristate "SMSC LPC47M192 and compatibles"
depends on HWMON && I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the temperature and
voltage sensors of the SMSC LPC47M192 and LPC47M997 chips.
The fan monitoring and control capabilities of these chips
are supported by another driver, select
"SMSC LPC47M10x and compatibles" above. You need both drivers
if you want fan control and voltage/temperature sensor support.
This driver can also be built as a module. If so, the module
will be called smsc47m192.
config SENSORS_SMSC47B397 config SENSORS_SMSC47B397
tristate "SMSC LPC47B397-NC" tristate "SMSC LPC47B397-NC"
depends on HWMON && I2C && EXPERIMENTAL depends on HWMON && I2C && EXPERIMENTAL
...@@ -385,6 +432,16 @@ config SENSORS_W83781D ...@@ -385,6 +432,16 @@ config SENSORS_W83781D
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called w83781d. will be called w83781d.
config SENSORS_W83791D
tristate "Winbond W83791D"
depends on HWMON && I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the Winbond W83791D chip.
This driver can also be built as a module. If so, the module
will be called w83791d.
config SENSORS_W83792D config SENSORS_W83792D
tristate "Winbond W83792D" tristate "Winbond W83792D"
depends on HWMON && I2C && EXPERIMENTAL depends on HWMON && I2C && EXPERIMENTAL
......
...@@ -10,7 +10,9 @@ obj-$(CONFIG_SENSORS_ASB100) += asb100.o ...@@ -10,7 +10,9 @@ obj-$(CONFIG_SENSORS_ASB100) += asb100.o
obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
obj-$(CONFIG_SENSORS_W83792D) += w83792d.o obj-$(CONFIG_SENSORS_W83792D) += w83792d.o
obj-$(CONFIG_SENSORS_W83781D) += w83781d.o obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
obj-$(CONFIG_SENSORS_W83791D) += w83791d.o
obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o
obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
...@@ -26,6 +28,7 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o ...@@ -26,6 +28,7 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM63) += lm63.o
obj-$(CONFIG_SENSORS_LM70) += lm70.o
obj-$(CONFIG_SENSORS_LM75) += lm75.o obj-$(CONFIG_SENSORS_LM75) += lm75.o
obj-$(CONFIG_SENSORS_LM77) += lm77.o obj-$(CONFIG_SENSORS_LM77) += lm77.o
obj-$(CONFIG_SENSORS_LM78) += lm78.o obj-$(CONFIG_SENSORS_LM78) += lm78.o
...@@ -40,6 +43,7 @@ obj-$(CONFIG_SENSORS_PC87360) += pc87360.o ...@@ -40,6 +43,7 @@ obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
......
This diff is collapsed.
...@@ -99,10 +99,6 @@ superio_exit(int base) ...@@ -99,10 +99,6 @@ superio_exit(int base)
#define ADDR_REG_OFFSET 0 #define ADDR_REG_OFFSET 0
#define DATA_REG_OFFSET 1 #define DATA_REG_OFFSET 1
static struct resource f71805f_resource __initdata = {
.flags = IORESOURCE_IO,
};
/* /*
* Registers * Registers
*/ */
...@@ -782,6 +778,11 @@ static struct platform_driver f71805f_driver = { ...@@ -782,6 +778,11 @@ static struct platform_driver f71805f_driver = {
static int __init f71805f_device_add(unsigned short address) static int __init f71805f_device_add(unsigned short address)
{ {
struct resource res = {
.start = address,
.end = address + REGION_LENGTH - 1,
.flags = IORESOURCE_IO,
};
int err; int err;
pdev = platform_device_alloc(DRVNAME, address); pdev = platform_device_alloc(DRVNAME, address);
...@@ -791,10 +792,8 @@ static int __init f71805f_device_add(unsigned short address) ...@@ -791,10 +792,8 @@ static int __init f71805f_device_add(unsigned short address)
goto exit; goto exit;
} }
f71805f_resource.start = address; res.name = pdev->name;
f71805f_resource.end = address + REGION_LENGTH - 1; err = platform_device_add_resources(pdev, &res, 1);
f71805f_resource.name = pdev->name;
err = platform_device_add_resources(pdev, &f71805f_resource, 1);
if (err) { if (err) {
printk(KERN_ERR DRVNAME ": Device resource addition failed " printk(KERN_ERR DRVNAME ": Device resource addition failed "
"(%d)\n", err); "(%d)\n", err);
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#define HDAPS_PORT_STATE 0x1611 /* device state */ #define HDAPS_PORT_STATE 0x1611 /* device state */
#define HDAPS_PORT_YPOS 0x1612 /* y-axis position */ #define HDAPS_PORT_YPOS 0x1612 /* y-axis position */
#define HDAPS_PORT_XPOS 0x1614 /* x-axis position */ #define HDAPS_PORT_XPOS 0x1614 /* x-axis position */
#define HDAPS_PORT_TEMP1 0x1616 /* device temperature, in celcius */ #define HDAPS_PORT_TEMP1 0x1616 /* device temperature, in Celsius */
#define HDAPS_PORT_YVAR 0x1617 /* y-axis variance (what is this?) */ #define HDAPS_PORT_YVAR 0x1617 /* y-axis variance (what is this?) */
#define HDAPS_PORT_XVAR 0x1619 /* x-axis variance (what is this?) */ #define HDAPS_PORT_XVAR 0x1619 /* x-axis variance (what is this?) */
#define HDAPS_PORT_TEMP2 0x161b /* device temperature (again?) */ #define HDAPS_PORT_TEMP2 0x161b /* device temperature (again?) */
...@@ -522,13 +522,15 @@ static int __init hdaps_init(void) ...@@ -522,13 +522,15 @@ static int __init hdaps_init(void)
{ {
int ret; int ret;
/* Note that DMI_MATCH(...,"ThinkPad T42") will match "ThinkPad T42p" */ /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
"ThinkPad T42p", so the order of the entries matters */
struct dmi_system_id hdaps_whitelist[] = { struct dmi_system_id hdaps_whitelist[] = {
HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), HDAPS_DMI_MATCH_NORMAL("ThinkPad H"),
HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"), HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"), HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"), HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"), HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad H"), /* R52 (1846AQG) */
HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"), HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"), HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"),
HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"), HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"),
...@@ -536,9 +538,9 @@ static int __init hdaps_init(void) ...@@ -536,9 +538,9 @@ static int __init hdaps_init(void)
HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"), HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),
HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"), HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"), HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"), HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"), HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"),
HDAPS_DMI_MATCH_NORMAL("ThinkPad Z60m"),
{ .ident = NULL } { .ident = NULL }
}; };
......
...@@ -58,11 +58,20 @@ ...@@ -58,11 +58,20 @@
doesn't seem to be any named specification for these. The conversion doesn't seem to be any named specification for these. The conversion
tables are detailed directly in the various Pentium M datasheets: tables are detailed directly in the various Pentium M datasheets:
http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm
The 14 specification corresponds to Intel Core series. There
doesn't seem to be any named specification for these. The conversion
tables are detailed directly in the various Pentium Core datasheets:
http://www.intel.com/design/mobile/datashts/309221.htm
The 110 (VRM 11) specification corresponds to Intel Conroe based series.
http://www.intel.com/design/processor/applnots/313214.htm
*/ */
/* vrm is the VRM/VRD document version multiplied by 10. /* vrm is the VRM/VRD document version multiplied by 10.
val is the 4-, 5- or 6-bit VID code. val is the 4-bit or more VID code.
Returned value is in mV to avoid floating point in the kernel. */ Returned value is in mV to avoid floating point in the kernel.
Some VID have some bits in uV scale, this is rounded to mV */
int vid_from_reg(int val, u8 vrm) int vid_from_reg(int val, u8 vrm)
{ {
int vid; int vid;
...@@ -70,26 +79,36 @@ int vid_from_reg(int val, u8 vrm) ...@@ -70,26 +79,36 @@ int vid_from_reg(int val, u8 vrm)
switch(vrm) { switch(vrm) {
case 100: /* VRD 10.0 */ case 100: /* VRD 10.0 */
/* compute in uV, round to mV */
val &= 0x3f;
if((val & 0x1f) == 0x1f) if((val & 0x1f) == 0x1f)
return 0; return 0;
if((val & 0x1f) <= 0x09 || val == 0x0a) if((val & 0x1f) <= 0x09 || val == 0x0a)
vid = 10875 - (val & 0x1f) * 250; vid = 1087500 - (val & 0x1f) * 25000;
else else
vid = 18625 - (val & 0x1f) * 250; vid = 1862500 - (val & 0x1f) * 25000;
if(val & 0x20) if(val & 0x20)
vid -= 125; vid -= 12500;
vid /= 10; /* only return 3 dec. places for now */ return((vid + 500) / 1000);
return vid;
case 110: /* Intel Conroe */
/* compute in uV, round to mV */
val &= 0xff;
if(((val & 0x7e) == 0xfe) || (!(val & 0x7e)))
return 0;
return((1600000 - (val - 2) * 6250 + 500) / 1000);
case 24: /* Opteron processor */ case 24: /* Opteron processor */
val &= 0x1f;
return(val == 0x1f ? 0 : 1550 - val * 25); return(val == 0x1f ? 0 : 1550 - val * 25);
case 91: /* VRM 9.1 */ case 91: /* VRM 9.1 */
case 90: /* VRM 9.0 */ case 90: /* VRM 9.0 */
val &= 0x1f;
return(val == 0x1f ? 0 : return(val == 0x1f ? 0 :
1850 - val * 25); 1850 - val * 25);
case 85: /* VRM 8.5 */ case 85: /* VRM 8.5 */
val &= 0x1f;
return((val & 0x10 ? 25 : 0) + return((val & 0x10 ? 25 : 0) +
((val & 0x0f) > 0x04 ? 2050 : 1250) - ((val & 0x0f) > 0x04 ? 2050 : 1250) -
((val & 0x0f) * 50)); ((val & 0x0f) * 50));
...@@ -98,14 +117,21 @@ int vid_from_reg(int val, u8 vrm) ...@@ -98,14 +117,21 @@ int vid_from_reg(int val, u8 vrm)
val &= 0x0f; val &= 0x0f;
/* fall through */ /* fall through */
case 82: /* VRM 8.2 */ case 82: /* VRM 8.2 */
val &= 0x1f;
return(val == 0x1f ? 0 : return(val == 0x1f ? 0 :
val & 0x10 ? 5100 - (val) * 100 : val & 0x10 ? 5100 - (val) * 100 :
2050 - (val) * 50); 2050 - (val) * 50);
case 17: /* Intel IMVP-II */ case 17: /* Intel IMVP-II */
val &= 0x1f;
return(val & 0x10 ? 975 - (val & 0xF) * 25 : return(val & 0x10 ? 975 - (val & 0xF) * 25 :
1750 - val * 50); 1750 - val * 50);
case 13: case 13:
return(1708 - (val & 0x3f) * 16); val &= 0x3f;
return(1708 - val * 16);
case 14: /* Intel Core */
/* compute in uV, round to mV */
val &= 0x7f;
return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000);
default: /* report 0 for unknown */ default: /* report 0 for unknown */
printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n"); printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
return 0; return 0;
...@@ -138,6 +164,8 @@ static struct vrm_model vrm_models[] = { ...@@ -138,6 +164,8 @@ static struct vrm_model vrm_models[] = {
{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */
{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */
{X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */
{X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14}, /* Intel Core (65 nm) */
{X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110}, /* Intel Conroe */
{X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */
{X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */ {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */
{X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */
......
/*
* lm70.c
*
* The LM70 is a temperature sensor chip from National Semiconductor (NS).
* Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com>
*
* The LM70 communicates with a host processor via an SPI/Microwire Bus
* interface. The complete datasheet is available at National's website
* here:
* http://www.national.com/pf/LM/LM70.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/sysfs.h>
#include <linux/hwmon.h>
#include <linux/spi/spi.h>
#include <asm/semaphore.h>
#define DRVNAME "lm70"
struct lm70 {
struct class_device *cdev;
struct semaphore sem;
};
/* sysfs hook function */
static ssize_t lm70_sense_temp(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct spi_device *spi = to_spi_device(dev);
int status, val;
u8 rxbuf[2];
s16 raw=0;
struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
if (down_interruptible(&p_lm70->sem))
return -ERESTARTSYS;
/*
* spi_read() requires a DMA-safe buffer; so we use
* spi_write_then_read(), transmitting 0 bytes.
*/
status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2);
if (status < 0) {
printk(KERN_WARNING
"spi_write_then_read failed with status %d\n", status);
goto out;
}
dev_dbg(dev, "rxbuf[1] : 0x%x rxbuf[0] : 0x%x\n", rxbuf[1], rxbuf[0]);
raw = (rxbuf[1] << 8) + rxbuf[0];
dev_dbg(dev, "raw=0x%x\n", raw);
/*
* The "raw" temperature read into rxbuf[] is a 16-bit signed 2's
* complement value. Only the MSB 11 bits (1 sign + 10 temperature
* bits) are meaningful; the LSB 5 bits are to be discarded.
* See the datasheet.
*
* Further, each bit represents 0.25 degrees Celsius; so, multiply
* by 0.25. Also multiply by 1000 to represent in millidegrees
* Celsius.
* So it's equivalent to multiplying by 0.25 * 1000 = 250.
*/
val = ((int)raw/32) * 250;
status = sprintf(buf, "%+d\n", val); /* millidegrees Celsius */
out:
up(&p_lm70->sem);
return status;
}
static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL);
/*----------------------------------------------------------------------*/
static int __devinit lm70_probe(struct spi_device *spi)
{
struct lm70 *p_lm70;
int status;
p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
if (!p_lm70)
return -ENOMEM;
init_MUTEX(&p_lm70->sem);
/* sysfs hook */
p_lm70->cdev = hwmon_device_register(&spi->dev);
if (IS_ERR(p_lm70->cdev)) {
dev_dbg(&spi->dev, "hwmon_device_register failed.\n");
status = PTR_ERR(p_lm70->cdev);
goto out_dev_reg_failed;
}
dev_set_drvdata(&spi->dev, p_lm70);
if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))) {
dev_dbg(&spi->dev, "device_create_file failure.\n");
goto out_dev_create_file_failed;
}
return 0;
out_dev_create_file_failed:
hwmon_device_unregister(p_lm70->cdev);
out_dev_reg_failed:
dev_set_drvdata(&spi->dev, NULL);
kfree(p_lm70);
return status;
}
static int __exit lm70_remove(struct spi_device *spi)
{
struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
device_remove_file(&spi->dev, &dev_attr_temp1_input);
hwmon_device_unregister(p_lm70->cdev);
dev_set_drvdata(&spi->dev, NULL);
kfree(p_lm70);
return 0;
}
static struct spi_driver lm70_driver = {
.driver = {
.name = "lm70",
.owner = THIS_MODULE,
},
.probe = lm70_probe,
.remove = __devexit_p(lm70_remove),
};
static int __init init_lm70(void)
{
return spi_register_driver(&lm70_driver);
}
static void __exit cleanup_lm70(void)
{
spi_unregister_driver(&lm70_driver);
}
module_init(init_lm70);
module_exit(cleanup_lm70);
MODULE_AUTHOR("Kaiwan N Billimoria");
MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver");
MODULE_LICENSE("GPL");
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
* Since the datasheet omits to give the chip stepping code, I give it * Since the datasheet omits to give the chip stepping code, I give it
* here: 0x03 (at register 0xff). * here: 0x03 (at register 0xff).
* *
* Also supports the LM82 temp sensor, which is basically a stripped down
* model of the LM83. Datasheet is here:
* http://www.national.com/pf/LM/LM82.html
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
...@@ -52,7 +56,7 @@ static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, ...@@ -52,7 +56,7 @@ static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
* Insmod parameters * Insmod parameters
*/ */
I2C_CLIENT_INSMOD_1(lm83); I2C_CLIENT_INSMOD_2(lm83, lm82);
/* /*
* The LM83 registers * The LM83 registers
...@@ -283,6 +287,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -283,6 +287,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
if (man_id == 0x01) { /* National Semiconductor */ if (man_id == 0x01) { /* National Semiconductor */
if (chip_id == 0x03) { if (chip_id == 0x03) {
kind = lm83; kind = lm83;
} else
if (chip_id == 0x01) {
kind = lm82;
} }
} }
...@@ -296,6 +303,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -296,6 +303,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind == lm83) { if (kind == lm83) {
name = "lm83"; name = "lm83";
} else
if (kind == lm82) {
name = "lm82";
} }
/* We can fill in the remaining client fields */ /* We can fill in the remaining client fields */
...@@ -319,32 +329,46 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -319,32 +329,46 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_detach; goto exit_detach;
} }
/*
* The LM82 can only monitor one external diode which is
* at the same register as the LM83 temp3 entry - so we
* declare 1 and 3 common, and then 2 and 4 only for the LM83.
*/
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp1_input.dev_attr); &sensor_dev_attr_temp1_input.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp2_input.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp3_input.dev_attr); &sensor_dev_attr_temp3_input.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp4_input.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp1_max.dev_attr); &sensor_dev_attr_temp1_max.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp2_max.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp3_max.dev_attr); &sensor_dev_attr_temp3_max.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp4_max.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp1_crit.dev_attr); &sensor_dev_attr_temp1_crit.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp2_crit.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp3_crit.dev_attr); &sensor_dev_attr_temp3_crit.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp4_crit.dev_attr);
device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_alarms);
if (kind == lm83) {
device_create_file(&new_client->dev,
&sensor_dev_attr_temp2_input.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp4_input.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp2_max.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp4_max.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp2_crit.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_temp4_crit.dev_attr);
}
return 0; return 0;
exit_detach: exit_detach:
......
This diff is collapsed.
...@@ -30,10 +30,7 @@ ...@@ -30,10 +30,7 @@
Supports the following chips: Supports the following chips:
Chip #vin #fan #pwm #temp chip_id man_id Chip #vin #fan #pwm #temp chip_id man_id
w83627ehf - 5 - 3 0x88 0x5ca3 w83627ehf 10 5 - 3 0x88 0x5ca3
This is a preliminary version of the driver, only supporting the
fan and temperature inputs. The chip does much more than that.
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -121,6 +118,14 @@ superio_exit(void) ...@@ -121,6 +118,14 @@ superio_exit(void)
static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 };
static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c };
/* The W83627EHF registers for nr=7,8,9 are in bank 5 */
#define W83627EHF_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
(0x554 + (((nr) - 7) * 2)))
#define W83627EHF_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
(0x555 + (((nr) - 7) * 2)))
#define W83627EHF_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \
(0x550 + (nr) - 7))
#define W83627EHF_REG_TEMP1 0x27 #define W83627EHF_REG_TEMP1 0x27
#define W83627EHF_REG_TEMP1_HYST 0x3a #define W83627EHF_REG_TEMP1_HYST 0x3a
#define W83627EHF_REG_TEMP1_OVER 0x39 #define W83627EHF_REG_TEMP1_OVER 0x39
...@@ -136,6 +141,10 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 }; ...@@ -136,6 +141,10 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 };
#define W83627EHF_REG_DIODE 0x59 #define W83627EHF_REG_DIODE 0x59
#define W83627EHF_REG_SMI_OVT 0x4C #define W83627EHF_REG_SMI_OVT 0x4C
#define W83627EHF_REG_ALARM1 0x459
#define W83627EHF_REG_ALARM2 0x45A
#define W83627EHF_REG_ALARM3 0x45B
/* /*
* Conversions * Conversions
*/ */
...@@ -172,6 +181,20 @@ temp1_to_reg(int temp) ...@@ -172,6 +181,20 @@ temp1_to_reg(int temp)
return (temp + 500) / 1000; return (temp + 500) / 1000;
} }
/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */
static u8 scale_in[10] = { 8, 8, 16, 16, 8, 8, 8, 16, 16, 8 };
static inline long in_from_reg(u8 reg, u8 nr)
{
return reg * scale_in[nr];
}
static inline u8 in_to_reg(u32 val, u8 nr)
{
return SENSORS_LIMIT(((val + (scale_in[nr] / 2)) / scale_in[nr]), 0, 255);
}
/* /*
* Data structures and manipulation thereof * Data structures and manipulation thereof
*/ */
...@@ -186,6 +209,9 @@ struct w83627ehf_data { ...@@ -186,6 +209,9 @@ struct w83627ehf_data {
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
/* Register values */ /* Register values */
u8 in[10]; /* Register value */
u8 in_max[10]; /* Register value */
u8 in_min[10]; /* Register value */
u8 fan[5]; u8 fan[5];
u8 fan_min[5]; u8 fan_min[5];
u8 fan_div[5]; u8 fan_div[5];
...@@ -196,6 +222,7 @@ struct w83627ehf_data { ...@@ -196,6 +222,7 @@ struct w83627ehf_data {
s16 temp[2]; s16 temp[2];
s16 temp_max[2]; s16 temp_max[2];
s16 temp_max_hyst[2]; s16 temp_max_hyst[2];
u32 alarms;
}; };
static inline int is_word_sized(u16 reg) static inline int is_word_sized(u16 reg)
...@@ -349,6 +376,16 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) ...@@ -349,6 +376,16 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
data->fan_div[3] |= (i >> 5) & 0x04; data->fan_div[3] |= (i >> 5) & 0x04;
} }
/* Measured voltages and limits */
for (i = 0; i < 10; i++) {
data->in[i] = w83627ehf_read_value(client,
W83627EHF_REG_IN(i));
data->in_min[i] = w83627ehf_read_value(client,
W83627EHF_REG_IN_MIN(i));
data->in_max[i] = w83627ehf_read_value(client,
W83627EHF_REG_IN_MAX(i));
}
/* Measured fan speeds and limits */ /* Measured fan speeds and limits */
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
if (!(data->has_fan & (1 << i))) if (!(data->has_fan & (1 << i)))
...@@ -395,6 +432,13 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) ...@@ -395,6 +432,13 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
W83627EHF_REG_TEMP_HYST[i]); W83627EHF_REG_TEMP_HYST[i]);
} }
data->alarms = w83627ehf_read_value(client,
W83627EHF_REG_ALARM1) |
(w83627ehf_read_value(client,
W83627EHF_REG_ALARM2) << 8) |
(w83627ehf_read_value(client,
W83627EHF_REG_ALARM3) << 16);
data->last_updated = jiffies; data->last_updated = jiffies;
data->valid = 1; data->valid = 1;
} }
...@@ -406,6 +450,109 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) ...@@ -406,6 +450,109 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
/* /*
* Sysfs callback functions * Sysfs callback functions
*/ */
#define show_in_reg(reg) \
static ssize_t \
show_##reg(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct w83627ehf_data *data = w83627ehf_update_device(dev); \
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \
return sprintf(buf, "%ld\n", in_from_reg(data->reg[nr], nr)); \
}
show_in_reg(in)
show_in_reg(in_min)
show_in_reg(in_max)
#define store_in_reg(REG, reg) \
static ssize_t \
store_in_##reg (struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct w83627ehf_data *data = i2c_get_clientdata(client); \
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \
u32 val = simple_strtoul(buf, NULL, 10); \
\
mutex_lock(&data->update_lock); \
data->in_##reg[nr] = in_to_reg(val, nr); \
w83627ehf_write_value(client, W83627EHF_REG_IN_##REG(nr), \
data->in_##reg[nr]); \
mutex_unlock(&data->update_lock); \
return count; \
}
store_in_reg(MIN, min)
store_in_reg(MAX, max)
static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83627ehf_data *data = w83627ehf_update_device(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
return sprintf(buf, "%u\n", (data->alarms >> nr) & 0x01);
}
static struct sensor_device_attribute sda_in_input[] = {
SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9),
};
static struct sensor_device_attribute sda_in_alarm[] = {
SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0),
SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1),
SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2),
SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3),
SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8),
SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 21),
SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 20),
SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16),
SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17),
SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 19),
};
static struct sensor_device_attribute sda_in_min[] = {
SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3),
SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4),
SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5),
SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6),
SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7),
SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8),
SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9),
};
static struct sensor_device_attribute sda_in_max[] = {
SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3),
SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4),
SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5),
SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6),
SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7),
SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8),
SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9),
};
static void device_create_file_in(struct device *dev, int i)
{
device_create_file(dev, &sda_in_input[i].dev_attr);
device_create_file(dev, &sda_in_alarm[i].dev_attr);
device_create_file(dev, &sda_in_min[i].dev_attr);
device_create_file(dev, &sda_in_max[i].dev_attr);
}
#define show_fan_reg(reg) \ #define show_fan_reg(reg) \
static ssize_t \ static ssize_t \
...@@ -505,6 +652,14 @@ static struct sensor_device_attribute sda_fan_input[] = { ...@@ -505,6 +652,14 @@ static struct sensor_device_attribute sda_fan_input[] = {
SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
}; };
static struct sensor_device_attribute sda_fan_alarm[] = {
SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6),
SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7),
SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11),
SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 10),
SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 23),
};
static struct sensor_device_attribute sda_fan_min[] = { static struct sensor_device_attribute sda_fan_min[] = {
SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 0), store_fan_min, 0),
...@@ -529,6 +684,7 @@ static struct sensor_device_attribute sda_fan_div[] = { ...@@ -529,6 +684,7 @@ static struct sensor_device_attribute sda_fan_div[] = {
static void device_create_file_fan(struct device *dev, int i) static void device_create_file_fan(struct device *dev, int i)
{ {
device_create_file(dev, &sda_fan_input[i].dev_attr); device_create_file(dev, &sda_fan_input[i].dev_attr);
device_create_file(dev, &sda_fan_alarm[i].dev_attr);
device_create_file(dev, &sda_fan_div[i].dev_attr); device_create_file(dev, &sda_fan_div[i].dev_attr);
device_create_file(dev, &sda_fan_min[i].dev_attr); device_create_file(dev, &sda_fan_min[i].dev_attr);
} }
...@@ -616,6 +772,9 @@ static struct sensor_device_attribute sda_temp[] = { ...@@ -616,6 +772,9 @@ static struct sensor_device_attribute sda_temp[] = {
store_temp_max_hyst, 0), store_temp_max_hyst, 0),
SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 1), store_temp_max_hyst, 1),
SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
}; };
/* /*
...@@ -705,6 +864,9 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) ...@@ -705,6 +864,9 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
goto exit_detach; goto exit_detach;
} }
for (i = 0; i < 10; i++)
device_create_file_in(dev, i);
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
if (data->has_fan & (1 << i)) if (data->has_fan & (1 << i))
device_create_file_fan(dev, i); device_create_file_fan(dev, i);
......
This diff is collapsed.
This diff is collapsed.
...@@ -163,7 +163,7 @@ config I2C_PXA_SLAVE ...@@ -163,7 +163,7 @@ config I2C_PXA_SLAVE
I2C bus. I2C bus.
config I2C_PIIX4 config I2C_PIIX4
tristate "Intel PIIX4" tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)"
depends on I2C && PCI depends on I2C && PCI
help help
If you say yes to this option, support will be included for the Intel If you say yes to this option, support will be included for the Intel
...@@ -172,6 +172,9 @@ config I2C_PIIX4 ...@@ -172,6 +172,9 @@ config I2C_PIIX4
of Broadcom): of Broadcom):
Intel PIIX4 Intel PIIX4
Intel 440MX Intel 440MX
ATI IXP200
ATI IXP300
ATI IXP400
Serverworks OSB4 Serverworks OSB4
Serverworks CSB5 Serverworks CSB5
Serverworks CSB6 Serverworks CSB6
...@@ -273,6 +276,17 @@ config I2C_NFORCE2 ...@@ -273,6 +276,17 @@ config I2C_NFORCE2
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-nforce2. will be called i2c-nforce2.
config I2C_OCORES
tristate "OpenCores I2C Controller"
depends on I2C && EXPERIMENTAL
help
If you say yes to this option, support will be included for the
OpenCores I2C controller. For details see
http://www.opencores.org/projects.cgi/web/i2c/overview
This driver can also be built as a module. If so, the module
will be called i2c-ocores.
config I2C_PARPORT config I2C_PARPORT
tristate "Parallel port adapter" tristate "Parallel port adapter"
depends on I2C && PARPORT depends on I2C && PARPORT
...@@ -500,6 +514,7 @@ config I2C_PCA_ISA ...@@ -500,6 +514,7 @@ config I2C_PCA_ISA
tristate "PCA9564 on an ISA bus" tristate "PCA9564 on an ISA bus"
depends on I2C depends on I2C
select I2C_ALGOPCA select I2C_ALGOPCA
default n
help help
This driver supports ISA boards using the Philips PCA 9564 This driver supports ISA boards using the Philips PCA 9564
Parallel bus to I2C bus controller Parallel bus to I2C bus controller
...@@ -507,6 +522,11 @@ config I2C_PCA_ISA ...@@ -507,6 +522,11 @@ config I2C_PCA_ISA
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-pca-isa. will be called i2c-pca-isa.
This device is almost undetectable and using this driver on a
system which doesn't have this device will result in long
delays when I2C/SMBus chip drivers are loaded (e.g. at boot
time). If unsure, say N.
config I2C_MV64XXX config I2C_MV64XXX
tristate "Marvell mv64xxx I2C Controller" tristate "Marvell mv64xxx I2C Controller"
depends on I2C && MV64X60 && EXPERIMENTAL depends on I2C && MV64X60 && EXPERIMENTAL
......
...@@ -23,6 +23,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o ...@@ -23,6 +23,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o
obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o
......
/* /*
i801.c - Part of lm_sensors, Linux kernel modules for hardware i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring monitoring
Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
This driver supports several versions of Intel's I/O Controller Hubs (ICH). This driver supports several versions of Intel's I/O Controller Hubs (ICH).
For SMBus support, they are similar to the PIIX4 and are part For SMBus support, they are similar to the PIIX4 and are part
of Intel's '810' and other chipsets. of Intel's '810' and other chipsets.
See the doc/busses/i2c-i801 file for details. See the file Documentation/i2c/busses/i2c-i801 for details.
I2C Block Read and Process Call are not supported. I2C Block Read and Process Call are not supported.
*/ */
...@@ -66,9 +66,8 @@ ...@@ -66,9 +66,8 @@
#define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */
/* PCI Address Constants */ /* PCI Address Constants */
#define SMBBA 0x020 #define SMBBAR 4
#define SMBHSTCFG 0x040 #define SMBHSTCFG 0x040
#define SMBREV 0x008
/* Host configuration bits for SMBHSTCFG */ /* Host configuration bits for SMBHSTCFG */
#define SMBHSTCFG_HST_EN 1 #define SMBHSTCFG_HST_EN 1
...@@ -92,92 +91,16 @@ ...@@ -92,92 +91,16 @@
#define I801_START 0x40 #define I801_START 0x40
#define I801_PEC_EN 0x80 /* ICH4 only */ #define I801_PEC_EN 0x80 /* ICH4 only */
/* insmod parameters */
/* If force_addr is set to anything different from 0, we forcibly enable
the I801 at the given address. VERY DANGEROUS! */
static u16 force_addr;
module_param(force_addr, ushort, 0);
MODULE_PARM_DESC(force_addr,
"Forcibly enable the I801 at the given address. "
"EXTREMELY DANGEROUS!");
static int i801_transaction(void); static int i801_transaction(void);
static int i801_block_transaction(union i2c_smbus_data *data, char read_write, static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
int command, int hwpec); int command, int hwpec);
static unsigned short i801_smba; static unsigned long i801_smba;
static struct pci_driver i801_driver; static struct pci_driver i801_driver;
static struct pci_dev *I801_dev; static struct pci_dev *I801_dev;
static int isich4; static int isich4;
static int i801_setup(struct pci_dev *dev)
{
int error_return = 0;
unsigned char temp;
/* Note: we keep on searching until we have found 'function 3' */
if(PCI_FUNC(dev->devfn) != 3)
return -ENODEV;
I801_dev = dev;
if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
(dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
(dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
isich4 = 1;
else
isich4 = 0;
/* Determine the address of the SMBus areas */
if (force_addr) {
i801_smba = force_addr & 0xfff0;
} else {
pci_read_config_word(I801_dev, SMBBA, &i801_smba);
i801_smba &= 0xfff0;
if(i801_smba == 0) {
dev_err(&dev->dev, "SMB base address uninitialized "
"- upgrade BIOS or use force_addr=0xaddr\n");
return -ENODEV;
}
}
if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
i801_smba);
error_return = -EBUSY;
goto END;
}
pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
/* If force_addr is set, we program the new address here. Just to make
sure, we disable the device first. */
if (force_addr) {
pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe);
pci_write_config_word(I801_dev, SMBBA, i801_smba);
pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01);
dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to "
"new address %04x!\n", i801_smba);
} else if ((temp & 1) == 0) {
pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1);
dev_warn(&dev->dev, "enabling SMBus device\n");
}
if (temp & 0x02)
dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
else
dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
pci_read_config_byte(I801_dev, SMBREV, &temp);
dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
END:
return error_return;
}
static int i801_transaction(void) static int i801_transaction(void)
{ {
int temp; int temp;
...@@ -334,8 +257,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, ...@@ -334,8 +257,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
/* We will always wait for a fraction of a second! */ /* We will always wait for a fraction of a second! */
timeout = 0; timeout = 0;
do { do {
temp = inb_p(SMBHSTSTS);
msleep(1); msleep(1);
temp = inb_p(SMBHSTSTS);
} }
while ((!(temp & 0x80)) while ((!(temp & 0x80))
&& (timeout++ < MAX_TIMEOUT)); && (timeout++ < MAX_TIMEOUT));
...@@ -393,8 +316,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, ...@@ -393,8 +316,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
/* wait for INTR bit as advised by Intel */ /* wait for INTR bit as advised by Intel */
timeout = 0; timeout = 0;
do { do {
temp = inb_p(SMBHSTSTS);
msleep(1); msleep(1);
temp = inb_p(SMBHSTSTS);
} while ((!(temp & 0x02)) } while ((!(temp & 0x02))
&& (timeout++ < MAX_TIMEOUT)); && (timeout++ < MAX_TIMEOUT));
...@@ -541,25 +464,76 @@ MODULE_DEVICE_TABLE (pci, i801_ids); ...@@ -541,25 +464,76 @@ MODULE_DEVICE_TABLE (pci, i801_ids);
static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{ {
unsigned char temp;
int err;
I801_dev = dev;
if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
(dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
(dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
isich4 = 1;
else
isich4 = 0;
err = pci_enable_device(dev);
if (err) {
dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
err);
goto exit;
}
/* Determine the address of the SMBus area */
i801_smba = pci_resource_start(dev, SMBBAR);
if (!i801_smba) {
dev_err(&dev->dev, "SMBus base address uninitialized, "
"upgrade BIOS\n");
err = -ENODEV;
goto exit_disable;
}
err = pci_request_region(dev, SMBBAR, i801_driver.name);
if (err) {
dev_err(&dev->dev, "Failed to request SMBus region "
"0x%lx-0x%lx\n", i801_smba,
pci_resource_end(dev, SMBBAR));
goto exit_disable;
}
if (i801_setup(dev)) { pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
dev_warn(&dev->dev, temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
"I801 not detected, module not inserted.\n"); if (!(temp & SMBHSTCFG_HST_EN)) {
return -ENODEV; dev_info(&dev->dev, "Enabling SMBus device\n");
temp |= SMBHSTCFG_HST_EN;
} }
pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
if (temp & SMBHSTCFG_SMB_SMI_EN)
dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
else
dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n");
/* set up the driverfs linkage to our parent device */ /* set up the driverfs linkage to our parent device */
i801_adapter.dev.parent = &dev->dev; i801_adapter.dev.parent = &dev->dev;
snprintf(i801_adapter.name, I2C_NAME_SIZE, snprintf(i801_adapter.name, I2C_NAME_SIZE,
"SMBus I801 adapter at %04x", i801_smba); "SMBus I801 adapter at %04lx", i801_smba);
return i2c_add_adapter(&i801_adapter); err = i2c_add_adapter(&i801_adapter);
if (err) {
dev_err(&dev->dev, "Failed to add SMBus adapter\n");
goto exit_disable;
}
exit_disable:
pci_disable_device(dev);
exit:
return err;
} }
static void __devexit i801_remove(struct pci_dev *dev) static void __devexit i801_remove(struct pci_dev *dev)
{ {
i2c_del_adapter(&i801_adapter); i2c_del_adapter(&i801_adapter);
release_region(i801_smba, (isich4 ? 16 : 8)); pci_release_region(dev, SMBBAR);
pci_disable_device(dev);
} }
static struct pci_driver i801_driver = { static struct pci_driver i801_driver = {
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
nForce3 250Gb MCP 00E4 nForce3 250Gb MCP 00E4
nForce4 MCP 0052 nForce4 MCP 0052
nForce4 MCP-04 0034 nForce4 MCP-04 0034
nForce4 MCP51 0264
nForce4 MCP55 0368
This driver supports the 2 SMBuses that are included in the MCP of the This driver supports the 2 SMBuses that are included in the MCP of the
nForce2/3/4 chipsets. nForce2/3/4 chipsets.
...@@ -64,6 +66,7 @@ struct nforce2_smbus { ...@@ -64,6 +66,7 @@ struct nforce2_smbus {
/* /*
* nVidia nForce2 SMBus control register definitions * nVidia nForce2 SMBus control register definitions
* (Newer incarnations use standard BARs 4 and 5 instead)
*/ */
#define NFORCE_PCI_SMB1 0x50 #define NFORCE_PCI_SMB1 0x50
#define NFORCE_PCI_SMB2 0x54 #define NFORCE_PCI_SMB2 0x54
...@@ -259,6 +262,8 @@ static struct pci_device_id nforce2_ids[] = { ...@@ -259,6 +262,8 @@ static struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
{ 0 } { 0 }
}; };
...@@ -266,19 +271,29 @@ static struct pci_device_id nforce2_ids[] = { ...@@ -266,19 +271,29 @@ static struct pci_device_id nforce2_ids[] = {
MODULE_DEVICE_TABLE (pci, nforce2_ids); MODULE_DEVICE_TABLE (pci, nforce2_ids);
static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg, static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
struct nforce2_smbus *smbus, char *name) int alt_reg, struct nforce2_smbus *smbus, const char *name)
{ {
u16 iobase;
int error; int error;
if (pci_read_config_word(dev, reg, &iobase) != PCIBIOS_SUCCESSFUL) { smbus->base = pci_resource_start(dev, bar);
dev_err(&smbus->adapter.dev, "Error reading PCI config for %s\n", name); if (smbus->base) {
return -1; smbus->size = pci_resource_len(dev, bar);
} else {
/* Older incarnations of the device used non-standard BARs */
u16 iobase;
if (pci_read_config_word(dev, alt_reg, &iobase)
!= PCIBIOS_SUCCESSFUL) {
dev_err(&dev->dev, "Error reading PCI config for %s\n",
name);
return -1;
}
smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
smbus->size = 8;
} }
smbus->dev = dev; smbus->dev = dev;
smbus->base = iobase & 0xfffc;
smbus->size = 8;
if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
...@@ -313,12 +328,13 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ ...@@ -313,12 +328,13 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
pci_set_drvdata(dev, smbuses); pci_set_drvdata(dev, smbuses);
/* SMBus adapter 1 */ /* SMBus adapter 1 */
res1 = nforce2_probe_smb (dev, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
if (res1 < 0) { if (res1 < 0) {
dev_err(&dev->dev, "Error probing SMB1.\n"); dev_err(&dev->dev, "Error probing SMB1.\n");
smbuses[0].base = 0; /* to have a check value */ smbuses[0].base = 0; /* to have a check value */
} }
res2 = nforce2_probe_smb (dev, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); /* SMBus adapter 2 */
res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2");
if (res2 < 0) { if (res2 < 0) {
dev_err(&dev->dev, "Error probing SMB2.\n"); dev_err(&dev->dev, "Error probing SMB2.\n");
smbuses[1].base = 0; /* to have a check value */ smbuses[1].base = 0; /* to have a check value */
......
This diff is collapsed.
...@@ -102,13 +102,6 @@ MODULE_PARM_DESC(force_addr, ...@@ -102,13 +102,6 @@ MODULE_PARM_DESC(force_addr,
"Forcibly enable the PIIX4 at the given address. " "Forcibly enable the PIIX4 at the given address. "
"EXTREMELY DANGEROUS!"); "EXTREMELY DANGEROUS!");
/* If fix_hstcfg is set to anything different from 0, we reset one of the
registers to be a valid value. */
static int fix_hstcfg;
module_param (fix_hstcfg, int, 0);
MODULE_PARM_DESC(fix_hstcfg,
"Fix config register. Needed on some boards (Force CPCI735).");
static int piix4_transaction(void); static int piix4_transaction(void);
static unsigned short piix4_smba; static unsigned short piix4_smba;
...@@ -137,7 +130,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, ...@@ -137,7 +130,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
/* Don't access SMBus on IBM systems which get corrupted eeproms */ /* Don't access SMBus on IBM systems which get corrupted eeproms */
if (dmi_check_system(piix4_dmi_table) && if (dmi_check_system(piix4_dmi_table) &&
PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module " dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
"may corrupt your serial eeprom! Refusing to load " "may corrupt your serial eeprom! Refusing to load "
"module!\n"); "module!\n");
return -EPERM; return -EPERM;
...@@ -166,22 +159,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, ...@@ -166,22 +159,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
/* Some BIOS will set up the chipset incorrectly and leave a register
in an undefined state (causing I2C to act very strangely). */
if (temp & 0x02) {
if (fix_hstcfg) {
dev_info(&PIIX4_dev->dev, "Working around buggy BIOS "
"(I2C)\n");
temp &= 0xfd;
pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp);
} else {
dev_info(&PIIX4_dev->dev, "Unusual config register "
"value\n");
dev_info(&PIIX4_dev->dev, "Try using fix_hstcfg=1 if "
"you experience problems\n");
}
}
/* If force_addr is set, we program the new address here. Just to make /* If force_addr is set, we program the new address here. Just to make
sure, we disable the PIIX4 first. */ sure, we disable the PIIX4 first. */
if (force_addr) { if (force_addr) {
...@@ -214,7 +191,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, ...@@ -214,7 +191,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
} }
} }
if ((temp & 0x0E) == 8) if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n"); dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n");
else if ((temp & 0x0E) == 0) else if ((temp & 0x0E) == 0)
dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n"); dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n");
...@@ -413,6 +390,12 @@ static struct i2c_adapter piix4_adapter = { ...@@ -413,6 +390,12 @@ static struct i2c_adapter piix4_adapter = {
static struct pci_device_id piix4_ids[] = { static struct pci_device_id piix4_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3), { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3),
.driver_data = 3 }, .driver_data = 3 },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS),
.driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS),
.driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS),
.driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4), { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4),
.driver_data = 0 }, .driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5), { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5),
......
This diff is collapsed.
...@@ -39,6 +39,7 @@ config SENSORS_EEPROM ...@@ -39,6 +39,7 @@ config SENSORS_EEPROM
config SENSORS_PCF8574 config SENSORS_PCF8574
tristate "Philips PCF8574 and PCF8574A" tristate "Philips PCF8574 and PCF8574A"
depends on I2C && EXPERIMENTAL depends on I2C && EXPERIMENTAL
default n
help help
If you say yes here you get support for Philips PCF8574 and If you say yes here you get support for Philips PCF8574 and
PCF8574A chips. PCF8574A chips.
...@@ -46,6 +47,9 @@ config SENSORS_PCF8574 ...@@ -46,6 +47,9 @@ config SENSORS_PCF8574
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called pcf8574. will be called pcf8574.
These devices are hard to detect and rarely found on mainstream
hardware. If unsure, say N.
config SENSORS_PCA9539 config SENSORS_PCA9539
tristate "Philips PCA9539 16-bit I/O port" tristate "Philips PCA9539 16-bit I/O port"
depends on I2C && EXPERIMENTAL depends on I2C && EXPERIMENTAL
...@@ -59,12 +63,16 @@ config SENSORS_PCA9539 ...@@ -59,12 +63,16 @@ config SENSORS_PCA9539
config SENSORS_PCF8591 config SENSORS_PCF8591
tristate "Philips PCF8591" tristate "Philips PCF8591"
depends on I2C && EXPERIMENTAL depends on I2C && EXPERIMENTAL
default n
help help
If you say yes here you get support for Philips PCF8591 chips. If you say yes here you get support for Philips PCF8591 chips.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called pcf8591. will be called pcf8591.
These devices are hard to detect and rarely found on mainstream
hardware. If unsure, say N.
config ISP1301_OMAP config ISP1301_OMAP
tristate "Philips ISP1301 with OMAP OTG" tristate "Philips ISP1301 with OMAP OTG"
depends on I2C && ARCH_OMAP_OTG depends on I2C && ARCH_OMAP_OTG
......
This diff is collapsed.
...@@ -916,7 +916,7 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) ...@@ -916,7 +916,7 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
} }
s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
u8 length, u8 *values) u8 length, const u8 *values)
{ {
union i2c_smbus_data data; union i2c_smbus_data data;
...@@ -944,7 +944,7 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val ...@@ -944,7 +944,7 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val
} }
s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
u8 length, u8 *values) u8 length, const u8 *values)
{ {
union i2c_smbus_data data; union i2c_smbus_data data;
......
...@@ -426,10 +426,7 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) ...@@ -426,10 +426,7 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
/* register this i2c device with the driver core */ /* register this i2c device with the driver core */
i2c_dev->adap = adap; i2c_dev->adap = adap;
if (adap->dev.parent == &platform_bus) dev = &adap->dev;
dev = &adap->dev;
else
dev = adap->dev.parent;
i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL,
MKDEV(I2C_MAJOR, i2c_dev->minor), MKDEV(I2C_MAJOR, i2c_dev->minor),
dev, "i2c-%d", i2c_dev->minor); dev, "i2c-%d", i2c_dev->minor);
......
/*
* i2c-ocores.h - definitions for the i2c-ocores interface
*
* Peter Korsgaard <jacmet@sunsite.dk>
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#ifndef _LINUX_I2C_OCORES_H
#define _LINUX_I2C_OCORES_H
struct ocores_i2c_platform_data {
u32 regstep; /* distance between registers */
u32 clock_khz; /* input clock in kHz */
};
#endif /* _LINUX_I2C_OCORES_H */
...@@ -97,13 +97,13 @@ extern s32 i2c_smbus_write_word_data(struct i2c_client * client, ...@@ -97,13 +97,13 @@ extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
u8 command, u16 value); u8 command, u16 value);
extern s32 i2c_smbus_write_block_data(struct i2c_client * client, extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
u8 command, u8 length, u8 command, u8 length,
u8 *values); const u8 *values);
/* Returns the number of read bytes */ /* Returns the number of read bytes */
extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
u8 command, u8 *values); u8 command, u8 *values);
extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
u8 command, u8 length, u8 command, u8 length,
u8 *values); const u8 *values);
/* /*
* A driver is capable of handling one or more physical devices present on * A driver is capable of handling one or more physical devices present on
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment