Commit 2f2408a8 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: (29 commits)
  hwmon: Fix various typos
  hwmon: Check for ACPI resource conflicts
  hwmon: (lm70) Add TI TMP121 support
  hwmon: (lm70) Code streamlining and cleanup
  hwmon: Deprecate the fscher and fscpos drivers
  hwmon: (fschmd) Add watchdog support
  hwmon: (fschmd) Cleanups for watchdog support
  hwmon: (i5k_amb) Load automatically on all 5000/5400 chipsets
  hwmon: (it87) Add support for the ITE IT8720F
  hwmon: Don't overuse I2C_CLIENT_MODULE_PARM
  hwmon: Add LTC4245 driver
  hwmon: (f71882fg) Fix fan_to/from_reg prototypes
  hwmon: (f71882fg) Printout fan modes
  hwmon: (f71882fg) Add documentation
  hwmon: (f71882fg) Fix auto_channels_temp temp numbering with f8000
  hwmon: (f71882fg) Add missing pwm3 attr for f71862fg
  hwmon: (f71882fg) Add F8000 support
  hwmon: (f71882fg) Remove the fan_mode module option
  hwmon: (f71882fg) Separate max and crit alarm and beep
  hwmon: (f71882fg) Check for hwmon powerdown state
  ...
parents fa7b906e 77fa49d9
......@@ -318,6 +318,14 @@ Who: Jean Delvare <khali@linux-fr.org>
---------------------------
What: fscher and fscpos drivers
When: June 2009
Why: Deprecated by the new fschmd driver.
Who: Hans de Goede <hdegoede@redhat.com>
Jean Delvare <khali@linux-fr.org>
---------------------------
What: SELinux "compat_net" functionality
When: 2.6.30 at the earliest
Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
......
Kernel driver f71882fg
======================
Supported chips:
* Fintek F71882FG and F71883FG
Prefix: 'f71882fg'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Available from the Fintek website
* Fintek F71862FG and F71863FG
Prefix: 'f71862fg'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Available from the Fintek website
* Fintek F8000
Prefix: 'f8000'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Not public
Author: Hans de Goede <hdegoede@redhat.com>
Description
-----------
Fintek F718xxFG/F8000 Super I/O chips include complete hardware monitoring
capabilities. They can monitor up to 9 voltages (3 for the F8000), 4 fans and
3 temperature sensors.
These chips also have fan controlling features, using either DC or PWM, in
three different modes (one manual, two automatic).
The driver assumes that no more than one chip is present, which seems
reasonable.
Monitoring
----------
The Voltage, Fan and Temperature Monitoring uses the standard sysfs
interface as documented in sysfs-interface, without any exceptions.
Fan Control
-----------
Both PWM (pulse-width modulation) and DC fan speed control methods are
supported. The right one to use depends on external circuitry on the
motherboard, so the driver assumes that the BIOS set the method
properly.
There are 2 modes to specify the speed of the fan, PWM duty cycle (or DC
voltage) mode, where 0-100% duty cycle (0-100% of 12V) is specified. And RPM
mode where the actual RPM of the fan (as measured) is controlled and the speed
gets specified as 0-100% of the fan#_full_speed file.
Since both modes work in a 0-100% (mapped to 0-255) scale, there isn't a
whole lot of a difference when modifying fan control settings. The only
important difference is that in RPM mode the 0-100% controls the fan speed
between 0-100% of fan#_full_speed. It is assumed that if the BIOS programs
RPM mode, it will also set fan#_full_speed properly, if it does not then
fan control will not work properly, unless you set a sane fan#_full_speed
value yourself.
Switching between these modes requires re-initializing a whole bunch of
registers, so the mode which the BIOS has set is kept. The mode is
printed when loading the driver.
Three different fan control modes are supported; the mode number is written
to the pwm#_enable file. Note that not all modes are supported on all
chips, and some modes may only be available in RPM / PWM mode on the F8000.
Writing an unsupported mode will result in an invalid parameter error.
* 1: Manual mode
You ask for a specific PWM duty cycle / DC voltage or a specific % of
fan#_full_speed by writing to the pwm# file. This mode is only
available on the F8000 if the fan channel is in RPM mode.
* 2: Normal auto mode
You can define a number of temperature/fan speed trip points, which % the
fan should run at at this temp and which temp a fan should follow using the
standard sysfs interface. The number and type of trip points is chip
depended, see which files are available in sysfs.
Fan/PWM channel 3 of the F8000 is always in this mode!
* 3: Thermostat mode (Only available on the F8000 when in duty cycle mode)
The fan speed is regulated to keep the temp the fan is mapped to between
temp#_auto_point2_temp and temp#_auto_point3_temp.
Both of the automatic modes require that pwm1 corresponds to fan1, pwm2 to
fan2 and pwm3 to fan3.
......@@ -26,6 +26,10 @@ Supported chips:
Datasheet: Publicly available at the ITE website
http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip
http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip
* IT8720F
Prefix: 'it8720'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not yet publicly available.
* SiS950 [clone of IT8705F]
Prefix: 'it87'
Addresses scanned: from Super I/O config space (8 I/O ports)
......@@ -71,7 +75,7 @@ Description
-----------
This driver implements support for the IT8705F, IT8712F, IT8716F,
IT8718F, IT8726F and SiS950 chips.
IT8718F, IT8720F, IT8726F and SiS950 chips.
These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
joysticks and other miscellaneous stuff. For hardware monitoring, they
......@@ -84,19 +88,19 @@ the IT8716F and late IT8712F have 6. They are shared with other functions
though, so the functionality may not be available on a given system.
The driver dumbly assume it is there.
The IT8718F also features VID inputs (up to 8 pins) but the value is
stored in the Super-I/O configuration space. Due to technical limitations,
The IT8718F and IT8720F also features VID inputs (up to 8 pins) but the value
is stored in the Super-I/O configuration space. Due to technical limitations,
this value can currently only be read once at initialization time, so
the driver won't notice and report changes in the VID value. The two
upper VID bits share their pins with voltage inputs (in5 and in6) so you
can't have both on a given board.
The IT8716F, IT8718F and later IT8712F revisions have support for
The IT8716F, IT8718F, IT8720F and later IT8712F revisions have support for
2 additional fans. The additional fans are supported by the driver.
The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional
16-bit tachometer counters for fans 1 to 3. This is better (no more fan
clock divider mess) but not compatible with the older chips and
The IT8716F, IT8718F and IT8720F, and late IT8712F and IT8705F also have
optional 16-bit tachometer counters for fans 1 to 3. This is better (no more
fan clock divider mess) but not compatible with the older chips and
revisions. The 16-bit tachometer mode is enabled by the driver when one
of the above chips is detected.
......@@ -122,7 +126,7 @@ 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/IT8716F/IT8718F) encode the core voltage value:
The VID lines (IT8712F/IT8716F/IT8718F/IT8720F) 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.
......
Kernel driver lm70
==================
Supported chip:
Supported chips:
* National Semiconductor LM70
Datasheet: http://www.national.com/pf/LM/LM70.html
* Texas Instruments TMP121/TMP123
Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html
Author:
Kaiwan N Billimoria <kaiwan@designergraphix.com>
......@@ -25,6 +27,14 @@ 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.
As a real (in-tree) example of this "SPI protocol driver" interfacing
with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
and its associated documentation.
The TMP121/TMP123 are very similar; main differences are 4 wire SPI inter-
face (read only) and 13-bit temperature data (0.0625 degrees celsius reso-
lution).
Thanks to
---------
Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver
......
......@@ -164,7 +164,7 @@ configured individually according to the following options.
temperature. (PWM value from 0 to 255)
* pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature
the bahaviour of fans. Write 1 to let fans spinning at
the behaviour 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
......
Kernel driver ltc4245
=====================
Supported chips:
* Linear Technology LTC4245
Prefix: 'ltc4245'
Addresses scanned: 0x20-0x3f
Datasheet:
http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1140,P19392,D13517
Author: Ira W. Snyder <iws@ovro.caltech.edu>
Description
-----------
The LTC4245 controller allows a board to be safely inserted and removed
from a live backplane in multiple supply systems such as CompactPCI and
PCI Express.
Usage Notes
-----------
This driver does not probe for LTC4245 devices, due to the fact that some
of the possible addresses are unfriendly to probing. You will need to use
the "force" parameter to tell the driver where to find the device.
Example: the following will load the driver for an LTC4245 at address 0x23
on I2C bus #1:
$ modprobe ltc4245 force=1,0x23
Sysfs entries
-------------
The LTC4245 has built-in limits for over and under current warnings. This
makes it very likely that the reference circuit will be used.
This driver uses the values in the datasheet to change the register values
into the values specified in the sysfs-interface document. The current readings
rely on the sense resistors listed in Table 2: "Sense Resistor Values".
in1_input 12v input voltage (mV)
in2_input 5v input voltage (mV)
in3_input 3v input voltage (mV)
in4_input Vee (-12v) input voltage (mV)
in1_min_alarm 12v input undervoltage alarm
in2_min_alarm 5v input undervoltage alarm
in3_min_alarm 3v input undervoltage alarm
in4_min_alarm Vee (-12v) input undervoltage alarm
curr1_input 12v current (mA)
curr2_input 5v current (mA)
curr3_input 3v current (mA)
curr4_input Vee (-12v) current (mA)
curr1_max_alarm 12v overcurrent alarm
curr2_max_alarm 5v overcurrent alarm
curr3_max_alarm 3v overcurrent alarm
curr4_max_alarm Vee (-12v) overcurrent alarm
in5_input 12v output voltage (mV)
in6_input 5v output voltage (mV)
in7_input 3v output voltage (mV)
in8_input Vee (-12v) output voltage (mV)
in5_min_alarm 12v output undervoltage alarm
in6_min_alarm 5v output undervoltage alarm
in7_min_alarm 3v output undervoltage alarm
in8_min_alarm Vee (-12v) output undervoltage alarm
in9_input GPIO #1 voltage data
in10_input GPIO #2 voltage data
in11_input GPIO #3 voltage data
power1_input 12v power usage (mW)
power2_input 5v power usage (mW)
power3_input 3v power usage (mW)
power4_input Vee (-12v) power usage (mW)
......@@ -13,10 +13,20 @@ Description
This driver provides glue code connecting a National Semiconductor LM70 LLP
temperature sensor evaluation board to the kernel's SPI core subsystem.
This is a SPI master controller driver. It can be used in conjunction with
(layered under) the LM70 logical driver (a "SPI protocol driver").
In effect, this driver turns the parallel port interface on the eval board
into a SPI bus with a single device, which will be driven by the generic
LM70 driver (drivers/hwmon/lm70.c).
Hardware Interfacing
--------------------
The schematic for this particular board (the LM70EVAL-LLP) is
available (on page 4) here:
http://www.national.com/appinfo/tempsensors/files/LM70LLPEVALmanual.pdf
The hardware interfacing on the LM70 LLP eval board is as follows:
Parallel LM70 LLP
......
......@@ -284,11 +284,12 @@ config SENSORS_F71805F
will be called f71805f.
config SENSORS_F71882FG
tristate "Fintek F71882FG and F71883FG"
tristate "Fintek F71862FG, F71882FG and F8000"
depends on EXPERIMENTAL
help
If you say yes here you get support for hardware monitoring
features of the Fintek F71882FG and F71883FG Super-I/O chips.
features of the Fintek F71882FG/F71883FG, F71862FG/71863FG
and F8000 Super-I/O chips.
This driver can also be built as a module. If so, the module
will be called f71882fg.
......@@ -304,9 +305,13 @@ config SENSORS_F75375S
will be called f75375s.
config SENSORS_FSCHER
tristate "FSC Hermes"
tristate "FSC Hermes (DEPRECATED)"
depends on X86 && I2C
help
This driver is DEPRECATED please use the new merged fschmd
("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver
instead.
If you say yes here you get support for Fujitsu Siemens
Computers Hermes sensor chips.
......@@ -314,9 +319,13 @@ config SENSORS_FSCHER
will be called fscher.
config SENSORS_FSCPOS
tristate "FSC Poseidon"
tristate "FSC Poseidon (DEPRECATED)"
depends on X86 && I2C
help
This driver is DEPRECATED please use the new merged fschmd
("FSC Poseidon, Scylla, Hermes, Heimdall and Heracles") driver
instead.
If you say yes here you get support for Fujitsu Siemens
Computers Poseidon sensor chips.
......@@ -325,14 +334,15 @@ config SENSORS_FSCPOS
config SENSORS_FSCHMD
tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles"
depends on X86 && I2C && EXPERIMENTAL
depends on X86 && I2C
help
If you say yes here you get support for various Fujitsu Siemens
Computers sensor chips.
Computers sensor chips, including support for the integrated
watchdog.
This is a new merged driver for FSC sensor chips which is intended
as a replacment for the fscpos, fscscy and fscher drivers and adds
support for several other FCS sensor chips.
This is a merged driver for FSC sensor chips replacing the fscpos,
fscscy and fscher drivers and adding support for several other FSC
sensor chips.
This driver can also be built as a module. If so, the module
will be called fschmd.
......@@ -399,7 +409,8 @@ config SENSORS_IT87
select HWMON_VID
help
If you say yes here you get support for ITE IT8705F, IT8712F,
IT8716F, IT8718F and IT8726F sensor chips, and the SiS960 clone.
IT8716F, IT8718F, IT8720F and IT8726F sensor chips, and the
SiS960 clone.
This driver can also be built as a module. If so, the module
will be called it87.
......@@ -417,11 +428,12 @@ config SENSORS_LM63
will be called lm63.
config SENSORS_LM70
tristate "National Semiconductor LM70"
tristate "National Semiconductor LM70 / Texas Instruments TMP121"
depends on SPI_MASTER && EXPERIMENTAL
help
If you say yes here you get support for the National Semiconductor
LM70 digital temperature sensor chip.
LM70 and Texas Instruments TMP121/TMP123 digital temperature
sensor chips.
This driver can also be built as a module. If so, the module
will be called lm70.
......@@ -548,6 +560,17 @@ config SENSORS_LM93
This driver can also be built as a module. If so, the module
will be called lm93.
config SENSORS_LTC4245
tristate "Linear Technology LTC4245"
depends on I2C && EXPERIMENTAL
default n
help
If you say yes here you get support for Linear Technology LTC4245
Multiple Supply Hot Swap Controller I2C interface.
This driver can also be built as a module. If so, the module will
be called ltc4245.
config SENSORS_MAX1111
tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
depends on SPI_MASTER
......
......@@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o
obj-$(CONFIG_SENSORS_LM90) += lm90.o
obj-$(CONFIG_SENSORS_LM92) += lm92.o
obj-$(CONFIG_SENSORS_LM93) += lm93.o
obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o
obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
......
......@@ -53,7 +53,10 @@ static const unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(asb100);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
static unsigned short force_subclients[4];
module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
/* Voltage IN registers 0-6 */
......
......@@ -34,6 +34,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <asm/io.h>
/* ISA device, if found */
......@@ -2361,6 +2362,10 @@ static int __init dme1737_isa_device_add(unsigned short addr)
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
if (!(pdev = platform_device_alloc("dme1737", addr))) {
printk(KERN_ERR "dme1737: Failed to allocate device.\n");
err = -ENOMEM;
......
......@@ -39,6 +39,7 @@
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/ioport.h>
#include <linux/acpi.h>
#include <asm/io.h>
static unsigned short force_id;
......@@ -1455,6 +1456,10 @@ static int __init f71805f_device_add(unsigned short address,
}
res.name = pdev->name;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit_device_put;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
printk(KERN_ERR DRVNAME ": Device resource addition failed "
......
This diff is collapsed.
This diff is collapsed.
......@@ -490,6 +490,13 @@ static unsigned long chipset_ids[] = {
0
};
static struct pci_device_id i5k_amb_ids[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, i5k_amb_ids);
static int __devinit i5k_amb_probe(struct platform_device *pdev)
{
struct i5k_amb_data *data;
......
......@@ -14,6 +14,7 @@
IT8712F Super I/O chip w/LPC interface
IT8716F Super I/O chip w/LPC interface
IT8718F Super I/O chip w/LPC interface
IT8720F Super I/O chip w/LPC interface
IT8726F Super I/O chip w/LPC interface
Sis950 A clone of the IT8705F
......@@ -48,11 +49,12 @@
#include <linux/sysfs.h>
#include <linux/string.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <asm/io.h>
#define DRVNAME "it87"
enum chips { it87, it8712, it8716, it8718 };
enum chips { it87, it8712, it8716, it8718, it8720 };
static unsigned short force_id;
module_param(force_id, ushort, 0);
......@@ -64,7 +66,10 @@ static struct platform_device *pdev;
#define DEV 0x07 /* Register: Logical device select */
#define VAL 0x2f /* The value to read/write */
#define PME 0x04 /* The device with the fan registers in it */
#define GPIO 0x07 /* The device with the IT8718F VID value in it */
/* The device with the IT8718F/IT8720F VID value in it */
#define GPIO 0x07
#define DEVID 0x20 /* Register: Device ID */
#define DEVREV 0x22 /* Register: Device Revision */
......@@ -113,6 +118,7 @@ superio_exit(void)
#define IT8705F_DEVID 0x8705
#define IT8716F_DEVID 0x8716
#define IT8718F_DEVID 0x8718
#define IT8720F_DEVID 0x8720
#define IT8726F_DEVID 0x8726
#define IT87_ACT_REG 0x30
#define IT87_BASE_REG 0x60
......@@ -150,8 +156,8 @@ static int fix_pwm_polarity;
#define IT87_REG_ALARM2 0x02
#define IT87_REG_ALARM3 0x03
/* The IT8718F has the VID value in a different register, in Super-I/O
configuration space. */
/* The IT8718F and IT8720F have the VID value in a different register, in
Super-I/O configuration space. */
#define IT87_REG_VID 0x0a
/* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
for fan divisors. Later IT8712F revisions must use 16-bit tachometer
......@@ -282,7 +288,8 @@ static inline int has_16bit_fans(const struct it87_data *data)
return (data->type == it87 && data->revision >= 0x03)
|| (data->type == it8712 && data->revision >= 0x08)
|| data->type == it8716
|| data->type == it8718;
|| data->type == it8718
|| data->type == it8720;
}
static int it87_probe(struct platform_device *pdev);
......@@ -992,6 +999,9 @@ static int __init it87_find(unsigned short *address,
case IT8718F_DEVID:
sio_data->type = it8718;
break;
case IT8720F_DEVID:
sio_data->type = it8720;
break;
case 0xffff: /* No device at all */
goto exit;
default:
......@@ -1022,7 +1032,8 @@ static int __init it87_find(unsigned short *address,
int reg;
superio_select(GPIO);
if (chip_type == it8718)
if ((chip_type == it8718) ||
(chip_type == it8720))
sio_data->vid_value = superio_inb(IT87_SIO_VID_REG);
reg = superio_inb(IT87_SIO_PINX2_REG);
......@@ -1068,6 +1079,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
"it8712",
"it8716",
"it8718",
"it8720",
};
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
......@@ -1226,7 +1238,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
}
if (data->type == it8712 || data->type == it8716
|| data->type == it8718) {
|| data->type == it8718 || data->type == it8720) {
data->vrm = vid_which_vrm();
/* VID reading from Super-I/O config space if available */
data->vid = sio_data->vid_value;
......@@ -1374,7 +1386,7 @@ static void __devinit it87_init_device(struct platform_device *pdev)
it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
}
/* Check if temperature channnels are reset manually or by some reason */
/* Check if temperature channels are reset manually or by some reason */
tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE);
if ((tmp & 0x3f) == 0) {
/* Temp1,Temp3=thermistor; Temp2=thermal diode */
......@@ -1513,7 +1525,8 @@ static struct it87_data *it87_update_device(struct device *dev)
data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
/* The 8705 does not have VID capability.
The 8718 does not use IT87_REG_VID for the same purpose. */
The 8718 and the 8720 don't use IT87_REG_VID for the
same purpose. */
if (data->type == it8712 || data->type == it8716) {
data->vid = it87_read_value(data, IT87_REG_VID);
/* The older IT8712F revisions had only 5 VID pins,
......@@ -1540,6 +1553,10 @@ static int __init it87_device_add(unsigned short address,
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
......@@ -1608,7 +1625,7 @@ static void __exit sm_it87_exit(void)
MODULE_AUTHOR("Chris Gauthron, "
"Jean Delvare <khali@linux-fr.org>");
MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8726F, SiS950 driver");
MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8720F/8726F, SiS950 driver");
module_param(update_vbat, bool, 0);
MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
module_param(fix_pwm_polarity, bool, 0);
......
......@@ -37,9 +37,13 @@
#define DRVNAME "lm70"
#define LM70_CHIP_LM70 0 /* original NS LM70 */
#define LM70_CHIP_TMP121 1 /* TI TMP121/TMP123 */
struct lm70 {
struct device *hwmon_dev;
struct mutex lock;
unsigned int chip;
};
/* sysfs hook function */
......@@ -47,7 +51,7 @@ 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;
int status, val = 0;
u8 rxbuf[2];
s16 raw=0;
struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
......@@ -65,12 +69,12 @@ static ssize_t lm70_sense_temp(struct device *dev,
"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);
raw = (rxbuf[0] << 8) + rxbuf[1];
dev_dbg(dev, "rxbuf[0] : 0x%02x rxbuf[1] : 0x%02x raw=0x%04x\n",
rxbuf[0], rxbuf[1], raw);
/*
* LM70:
* 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.
......@@ -80,8 +84,21 @@ static ssize_t lm70_sense_temp(struct device *dev,
* by 0.25. Also multiply by 1000 to represent in millidegrees
* Celsius.
* So it's equivalent to multiplying by 0.25 * 1000 = 250.
*
* TMP121/TMP123:
* 13 bits of 2's complement data, discard LSB 3 bits,
* resolution 0.0625 degrees celsius.
*/
val = ((int)raw/32) * 250;
switch (p_lm70->chip) {
case LM70_CHIP_LM70:
val = ((int)raw / 32) * 250;
break;
case LM70_CHIP_TMP121:
val = ((int)raw / 8) * 625 / 10;
break;
}
status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
out:
mutex_unlock(&p_lm70->lock);
......@@ -93,27 +110,39 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL);
static ssize_t lm70_show_name(struct device *dev, struct device_attribute
*devattr, char *buf)
{
return sprintf(buf, "lm70\n");
struct lm70 *p_lm70 = dev_get_drvdata(dev);
int ret;
switch (p_lm70->chip) {
case LM70_CHIP_LM70:
ret = sprintf(buf, "lm70\n");
break;
case LM70_CHIP_TMP121:
ret = sprintf(buf, "tmp121\n");
break;
default:
ret = -EINVAL;
}
return ret;
}
static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL);
/*----------------------------------------------------------------------*/
static int __devinit lm70_probe(struct spi_device *spi)
static int __devinit common_probe(struct spi_device *spi, int chip)
{
struct lm70 *p_lm70;
int status;
/* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */
if ((spi->mode & (SPI_CPOL|SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
return -EINVAL;
/* NOTE: we assume 8-bit words, and convert to 16 bits manually */
p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
if (!p_lm70)
return -ENOMEM;
mutex_init(&p_lm70->lock);
p_lm70->chip = chip;
/* sysfs hook */
p_lm70->hwmon_dev = hwmon_device_register(&spi->dev);
......@@ -141,6 +170,24 @@ static int __devinit lm70_probe(struct spi_device *spi)
return status;
}
static int __devinit lm70_probe(struct spi_device *spi)
{
/* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */
if ((spi->mode & (SPI_CPOL | SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
return -EINVAL;
return common_probe(spi, LM70_CHIP_LM70);
}
static int __devinit tmp121_probe(struct spi_device *spi)
{
/* signaling is SPI_MODE_0 with only MISO connected */
if (spi->mode & (SPI_CPOL | SPI_CPHA))
return -EINVAL;
return common_probe(spi, LM70_CHIP_TMP121);
}
static int __devexit lm70_remove(struct spi_device *spi)
{
struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
......@@ -154,6 +201,15 @@ static int __devexit lm70_remove(struct spi_device *spi)
return 0;
}
static struct spi_driver tmp121_driver = {
.driver = {
.name = "tmp121",
.owner = THIS_MODULE,
},
.probe = tmp121_probe,
.remove = __devexit_p(lm70_remove),
};
static struct spi_driver lm70_driver = {
.driver = {
.name = "lm70",
......@@ -165,17 +221,26 @@ static struct spi_driver lm70_driver = {
static int __init init_lm70(void)
{
return spi_register_driver(&lm70_driver);
int ret = spi_register_driver(&lm70_driver);
if (ret)
return ret;
ret = spi_register_driver(&tmp121_driver);
if (ret)
spi_unregister_driver(&lm70_driver);
return ret;
}
static void __exit cleanup_lm70(void)
{
spi_unregister_driver(&lm70_driver);
spi_unregister_driver(&tmp121_driver);
}
module_init(init_lm70);
module_exit(cleanup_lm70);
MODULE_AUTHOR("Kaiwan N Billimoria");
MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver");
MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -43,6 +43,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <asm/io.h>
static u8 devid;
......@@ -1627,6 +1628,11 @@ static int __init pc87360_device_add(unsigned short address)
continue;
res.start = extra_isa[i];
res.end = extra_isa[i] + PC87360_EXTENT - 1;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit_device_put;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
printk(KERN_ERR "pc87360: Device resource[%d] "
......
......@@ -32,6 +32,7 @@
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/ioport.h>
#include <linux/acpi.h>
#include <asm/io.h>
static unsigned short force_id;
......@@ -524,6 +525,10 @@ static int __init pc87427_device_add(unsigned short address)
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
......
......@@ -62,6 +62,7 @@
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/acpi.h>
#include <asm/io.h>
......@@ -727,6 +728,10 @@ static int __devinit sis5595_device_add(unsigned short address)
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc("sis5595", address);
if (!pdev) {
err = -ENOMEM;
......
......@@ -36,6 +36,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <asm/io.h>
static unsigned short force_id;
......@@ -303,6 +304,10 @@ static int __init smsc47b397_device_add(unsigned short address)
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
......
......@@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/acpi.h>
#include <asm/io.h>
static unsigned short force_id;
......@@ -705,6 +706,10 @@ static int __init smsc47m1_device_add(unsigned short address,
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
......
......@@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/acpi.h>
#include <asm/io.h>
......@@ -783,6 +784,10 @@ static int __devinit via686a_device_add(unsigned short address)
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc("via686a", address);
if (!pdev) {
err = -ENOMEM;
......
......@@ -32,6 +32,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/ioport.h>
#include <linux/acpi.h>
#include <asm/io.h>
static int uch_config = -1;
......@@ -1259,6 +1260,10 @@ static int __init vt1211_device_add(unsigned short address)
}
res.name = pdev->name;
err = acpi_check_resource_conflict(&res);
if (err)
goto EXIT;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
printk(KERN_ERR DRVNAME ": Device resource addition failed "
......
......@@ -35,6 +35,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <asm/io.h>
static int force_addr;
......@@ -894,6 +895,10 @@ static int __devinit vt8231_device_add(unsigned short address)
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc("vt8231", address);
if (!pdev) {
err = -ENOMEM;
......
......@@ -48,6 +48,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include "lm75.h"
......@@ -502,7 +503,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
}
for (i = 0; i < 4; i++) {
/* pwmcfg, tolarance mapped for i=0, i=1 to same reg */
/* pwmcfg, tolerance mapped for i=0, i=1 to same reg */
if (i != 1) {
pwmcfg = w83627ehf_read_value(data,
W83627EHF_REG_PWM_ENABLE[i]);
......@@ -1544,6 +1545,11 @@ static int __init sensors_w83627ehf_init(void)
res.start = address + IOREGION_OFFSET;
res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
res.flags = IORESOURCE_IO;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
printk(KERN_ERR DRVNAME ": Device resource addition failed "
......
......@@ -50,6 +50,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/ioport.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include "lm75.h"
......@@ -1793,6 +1794,10 @@ static int __init w83627hf_device_add(unsigned short address,
};
int err;
err = acpi_check_resource_conflict(&res);
if (err)
goto exit;
pdev = platform_device_alloc(DRVNAME, address);
if (!pdev) {
err = -ENOMEM;
......
......@@ -58,7 +58,10 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
0x2e, 0x2f, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
static unsigned short force_subclients[4];
module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
static int reset;
......
......@@ -53,7 +53,10 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(w83791d);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
static unsigned short force_subclients[4];
module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
static int reset;
......
......@@ -51,7 +51,10 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(w83792d);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
static unsigned short force_subclients[4];
module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
static int init;
......
......@@ -42,7 +42,10 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(w83793);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
static unsigned short force_subclients[4];
module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
static int reset;
......
/*
* spi_lm70llp.c - driver for lm70llp eval board for the LM70 sensor
* spi_lm70llp.c - driver for LM70EVAL-LLP board for the LM70 sensor
*
* Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com>
*
......@@ -40,8 +40,12 @@
* master controller driver. The hwmon/lm70 driver is a "SPI protocol
* driver", layered on top of this one and usable without the lm70llp.
*
* Datasheet and Schematic:
* The LM70 is a temperature sensor chip from National Semiconductor; its
* datasheet is available at http://www.national.com/pf/LM/LM70.html
* The schematic for this particular board (the LM70EVAL-LLP) is
* available (on page 4) here:
* http://www.national.com/appinfo/tempsensors/files/LM70LLPEVALmanual.pdf
*
* Also see Documentation/spi/spi-lm70llp. The SPI<->parport code here is
* (heavily) based on spi-butterfly by David Brownell.
......@@ -64,7 +68,7 @@
*
* Note that parport pin 13 actually gets inverted by the transistor
* arrangement which lets either the parport or the LM70 drive the
* SI/SO signal.
* SI/SO signal (see the schematic for details).
*/
#define DRVNAME "spi-lm70llp"
......@@ -106,12 +110,16 @@ static inline struct spi_lm70llp *spidev_to_pp(struct spi_device *spi)
static inline void deassertCS(struct spi_lm70llp *pp)
{
u8 data = parport_read_data(pp->port);
data &= ~0x80; /* pull D7/SI-out low while de-asserted */
parport_write_data(pp->port, data | nCS);
}
static inline void assertCS(struct spi_lm70llp *pp)
{
u8 data = parport_read_data(pp->port);
data |= 0x80; /* pull D7/SI-out high so lm70 drives SO-in */
parport_write_data(pp->port, data & ~nCS);
}
......@@ -184,22 +192,7 @@ static void lm70_chipselect(struct spi_device *spi, int value)
*/
static u32 lm70_txrx(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
{
static u32 sio=0;
static int first_time=1;
/* First time: perform SPI bitbang and return the LSB of
* the result of the SPI call.
*/
if (first_time) {
sio = bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
first_time=0;
return (sio & 0x00ff);
}
/* Return the MSB of the result of the SPI call */
else {
first_time=1;
return (sio >> 8);
}
return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
}
static void spi_lm70llp_attach(struct parport *p)
......@@ -293,10 +286,9 @@ static void spi_lm70llp_attach(struct parport *p)
status = -ENODEV;
goto out_bitbang_stop;
}
pp->spidev_lm70->bits_per_word = 16;
pp->spidev_lm70->bits_per_word = 8;
lm70llp = pp;
return;
out_bitbang_stop:
......@@ -326,7 +318,6 @@ static void spi_lm70llp_detach(struct parport *p)
/* power down */
parport_write_data(pp->port, 0);
msleep(10);
parport_release(pp->pd);
parport_unregister_device(pp->pd);
......
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