mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 09:14:19 +08:00
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging: hwmon: (lm85) Don't bind to Winbond/Nuvoton WPCD377I hwmon: (pcf8591) Documentation clean-ups hwmon: Clearly mark ACPI drivers as such hwmon: Use resource_size hwmon: Include <linux/io.h> instead of <asm/io.h> hwmon: (tmp421) Add documentation hwmon: Add driver for Texas Instruments TMP421/422/423 sensor chips hwmon-vid: Ignore 6th VID pin of AMD family 0Fh processors hwmon: (asus_atk0110) Add maintainer information hwmon: (abituguru3) Support multiple DMI strings per chip ID
This commit is contained in:
commit
96c015b75f
@ -2,11 +2,11 @@ Kernel driver pcf8591
|
||||
=====================
|
||||
|
||||
Supported chips:
|
||||
* Philips PCF8591
|
||||
* Philips/NXP PCF8591
|
||||
Prefix: 'pcf8591'
|
||||
Addresses scanned: I2C 0x48 - 0x4f
|
||||
Datasheet: Publicly available at the Philips Semiconductor website
|
||||
http://www.semiconductors.philips.com/pip/PCF8591P.html
|
||||
Datasheet: Publicly available at the NXP website
|
||||
http://www.nxp.com/pip/PCF8591_6.html
|
||||
|
||||
Authors:
|
||||
Aurelien Jarno <aurelien@aurel32.net>
|
||||
@ -16,9 +16,10 @@ Authors:
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
|
||||
analog output) for the I2C bus produced by Philips Semiconductors. It
|
||||
is designed to provide a byte I2C interface to up to 4 separate devices.
|
||||
analog output) for the I2C bus produced by Philips Semiconductors (now NXP).
|
||||
It is designed to provide a byte I2C interface to up to 4 separate devices.
|
||||
|
||||
The PCF8591 has 4 analog inputs programmable as single-ended or
|
||||
differential inputs :
|
||||
@ -58,8 +59,8 @@ Accessing PCF8591 via /sys interface
|
||||
-------------------------------------
|
||||
|
||||
! Be careful !
|
||||
The PCF8591 is plainly impossible to detect ! Stupid chip.
|
||||
So every chip with address in the interval [48..4f] is
|
||||
The PCF8591 is plainly impossible to detect! Stupid chip.
|
||||
So every chip with address in the interval [0x48..0x4f] is
|
||||
detected as PCF8591. If you have other chips in this address
|
||||
range, the workaround is to load this module after the one
|
||||
for your others chips.
|
||||
@ -67,19 +68,20 @@ for your others chips.
|
||||
On detection (i.e. insmod, modprobe et al.), directories are being
|
||||
created for each detected PCF8591:
|
||||
|
||||
/sys/bus/devices/<0>-<1>/
|
||||
/sys/bus/i2c/devices/<0>-<1>/
|
||||
where <0> is the bus the chip was detected on (e. g. i2c-0)
|
||||
and <1> the chip address ([48..4f])
|
||||
|
||||
Inside these directories, there are such files:
|
||||
in0, in1, in2, in3, out0_enable, out0_output, name
|
||||
in0_input, in1_input, in2_input, in3_input, out0_enable, out0_output, name
|
||||
|
||||
Name contains chip name.
|
||||
|
||||
The in0, in1, in2 and in3 files are RO. Reading gives the value of the
|
||||
corresponding channel. Depending on the current analog inputs configuration,
|
||||
files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
|
||||
ended inputs and -128 to +127 for differential inputs (8-bit ADC).
|
||||
The in0_input, in1_input, in2_input and in3_input files are RO. Reading gives
|
||||
the value of the corresponding channel. Depending on the current analog inputs
|
||||
configuration, files in2_input and in3_input may not exist. Values range
|
||||
from 0 to 255 for single ended inputs and -128 to +127 for differential inputs
|
||||
(8-bit ADC).
|
||||
|
||||
The out0_enable file is RW. Reading gives "1" for analog output enabled and
|
||||
"0" for analog output disabled. Writing accepts "0" and "1" accordingly.
|
||||
|
36
Documentation/hwmon/tmp421
Normal file
36
Documentation/hwmon/tmp421
Normal file
@ -0,0 +1,36 @@
|
||||
Kernel driver tmp421
|
||||
====================
|
||||
|
||||
Supported chips:
|
||||
* Texas Instruments TMP421
|
||||
Prefix: 'tmp421'
|
||||
Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
|
||||
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
|
||||
* Texas Instruments TMP422
|
||||
Prefix: 'tmp422'
|
||||
Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
|
||||
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
|
||||
* Texas Instruments TMP423
|
||||
Prefix: 'tmp423'
|
||||
Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
|
||||
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
|
||||
|
||||
Authors:
|
||||
Andre Prendel <andre.prendel@gmx.de>
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This driver implements support for Texas Instruments TMP421, TMP422
|
||||
and TMP423 temperature sensor chips. These chips implement one local
|
||||
and up to one (TMP421), up to two (TMP422) or up to three (TMP423)
|
||||
remote sensors. Temperature is measured in degrees Celsius. The chips
|
||||
are wired over I2C/SMBus and specified over a temperature range of -40
|
||||
to +125 degrees Celsius. Resolution for both the local and remote
|
||||
channels is 0.0625 degree C.
|
||||
|
||||
The chips support only temperature measurement. The driver exports
|
||||
the temperature values via the following sysfs files:
|
||||
|
||||
temp[1-4]_input
|
||||
temp[2-4]_fault
|
@ -931,6 +931,12 @@ W: http://wireless.kernel.org/en/users/Drivers/ar9170
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/ath/ar9170/
|
||||
|
||||
ATK0110 HWMON DRIVER
|
||||
M: Luca Tettamanti <kronos.it@gmail.com>
|
||||
L: lm-sensors@lm-sensors.org
|
||||
S: Maintained
|
||||
F: drivers/hwmon/asus_atk0110.c
|
||||
|
||||
ATI_REMOTE2 DRIVER
|
||||
M: Ville Syrjala <syrjala@sci.fi>
|
||||
S: Maintained
|
||||
|
@ -28,6 +28,17 @@ config HWMON_VID
|
||||
tristate
|
||||
default n
|
||||
|
||||
config HWMON_DEBUG_CHIP
|
||||
bool "Hardware Monitoring Chip debugging messages"
|
||||
default n
|
||||
help
|
||||
Say Y here if you want the I2C chip drivers to produce a bunch of
|
||||
debug messages to the system log. Select this if you are having
|
||||
a problem with I2C support and want to see more of what is going
|
||||
on.
|
||||
|
||||
comment "Native drivers"
|
||||
|
||||
config SENSORS_ABITUGURU
|
||||
tristate "Abit uGuru (rev 1 & 2)"
|
||||
depends on X86 && EXPERIMENTAL
|
||||
@ -248,18 +259,6 @@ config SENSORS_ASB100
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called asb100.
|
||||
|
||||
config SENSORS_ATK0110
|
||||
tristate "ASUS ATK0110 ACPI hwmon"
|
||||
depends on X86 && ACPI && EXPERIMENTAL
|
||||
help
|
||||
If you say yes here you get support for the ACPI hardware
|
||||
monitoring interface found in many ASUS motherboards. This
|
||||
driver will provide readings of fans, voltages and temperatures
|
||||
through the system firmware.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called asus_atk0110.
|
||||
|
||||
config SENSORS_ATXP1
|
||||
tristate "Attansic ATXP1 VID controller"
|
||||
depends on I2C && EXPERIMENTAL
|
||||
@ -814,6 +813,16 @@ config SENSORS_TMP401
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called tmp401.
|
||||
|
||||
config SENSORS_TMP421
|
||||
tristate "Texas Instruments TMP421 and compatible"
|
||||
depends on I2C && EXPERIMENTAL
|
||||
help
|
||||
If you say yes here you get support for Texas Instruments TMP421,
|
||||
TMP422 and TMP423 temperature sensor chips.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called tmp421.
|
||||
|
||||
config SENSORS_VIA686A
|
||||
tristate "VIA686A"
|
||||
depends on PCI
|
||||
@ -964,34 +973,6 @@ config SENSORS_HDAPS
|
||||
Say Y here if you have an applicable laptop and want to experience
|
||||
the awesome power of hdaps.
|
||||
|
||||
config SENSORS_LIS3LV02D
|
||||
tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
|
||||
depends on ACPI && INPUT
|
||||
select INPUT_POLLDEV
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
default n
|
||||
help
|
||||
This driver provides support for the LIS3LV02Dx accelerometer. In
|
||||
particular, it can be found in a number of HP laptops, which have the
|
||||
"Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
|
||||
systems the driver should load automatically (via ACPI). The
|
||||
accelerometer might also be found in other systems, connected via SPI
|
||||
or I2C. The accelerometer data is readable via
|
||||
/sys/devices/platform/lis3lv02d.
|
||||
|
||||
This driver also provides an absolute input class device, allowing
|
||||
the laptop to act as a pinball machine-esque joystick. On HP laptops,
|
||||
if the led infrastructure is activated, support for a led indicating
|
||||
disk protection will be provided as hp:red:hddprotection.
|
||||
|
||||
This driver can also be built as modules. If so, the core module
|
||||
will be called lis3lv02d and a specific module for HP laptops will be
|
||||
called hp_accel.
|
||||
|
||||
Say Y here if you have an applicable laptop and want to experience
|
||||
the awesome power of lis3lv02d.
|
||||
|
||||
config SENSORS_LIS3_SPI
|
||||
tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
|
||||
depends on !ACPI && SPI_MASTER && INPUT
|
||||
@ -1034,13 +1015,50 @@ config SENSORS_APPLESMC
|
||||
Say Y here if you have an applicable laptop and want to experience
|
||||
the awesome power of applesmc.
|
||||
|
||||
config HWMON_DEBUG_CHIP
|
||||
bool "Hardware Monitoring Chip debugging messages"
|
||||
if ACPI
|
||||
|
||||
comment "ACPI drivers"
|
||||
|
||||
config SENSORS_ATK0110
|
||||
tristate "ASUS ATK0110"
|
||||
depends on X86 && EXPERIMENTAL
|
||||
help
|
||||
If you say yes here you get support for the ACPI hardware
|
||||
monitoring interface found in many ASUS motherboards. This
|
||||
driver will provide readings of fans, voltages and temperatures
|
||||
through the system firmware.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called asus_atk0110.
|
||||
|
||||
config SENSORS_LIS3LV02D
|
||||
tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
|
||||
depends on INPUT
|
||||
select INPUT_POLLDEV
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
default n
|
||||
help
|
||||
Say Y here if you want the I2C chip drivers to produce a bunch of
|
||||
debug messages to the system log. Select this if you are having
|
||||
a problem with I2C support and want to see more of what is going
|
||||
on.
|
||||
This driver provides support for the LIS3LV02Dx accelerometer. In
|
||||
particular, it can be found in a number of HP laptops, which have the
|
||||
"Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
|
||||
systems the driver should load automatically (via ACPI). The
|
||||
accelerometer might also be found in other systems, connected via SPI
|
||||
or I2C. The accelerometer data is readable via
|
||||
/sys/devices/platform/lis3lv02d.
|
||||
|
||||
This driver also provides an absolute input class device, allowing
|
||||
the laptop to act as a pinball machine-esque joystick. On HP laptops,
|
||||
if the led infrastructure is activated, support for a led indicating
|
||||
disk protection will be provided as hp:red:hddprotection.
|
||||
|
||||
This driver can also be built as modules. If so, the core module
|
||||
will be called lis3lv02d and a specific module for HP laptops will be
|
||||
called hp_accel.
|
||||
|
||||
Say Y here if you have an applicable laptop and want to experience
|
||||
the awesome power of lis3lv02d.
|
||||
|
||||
endif # ACPI
|
||||
|
||||
endif # HWMON
|
||||
|
@ -5,6 +5,10 @@
|
||||
obj-$(CONFIG_HWMON) += hwmon.o
|
||||
obj-$(CONFIG_HWMON_VID) += hwmon-vid.o
|
||||
|
||||
# APCI drivers
|
||||
obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o
|
||||
|
||||
# Native drivers
|
||||
# asb100, then w83781d go first, as they can override other drivers' addresses.
|
||||
obj-$(CONFIG_SENSORS_ASB100) += asb100.o
|
||||
obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
|
||||
@ -29,10 +33,8 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o
|
||||
obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
|
||||
obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o
|
||||
obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
|
||||
|
||||
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
|
||||
obj-$(CONFIG_SENSORS_AMS) += ams/
|
||||
obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o
|
||||
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
|
||||
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
|
||||
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
|
||||
@ -84,6 +86,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
|
||||
obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
|
||||
obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
|
||||
obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
|
||||
obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
|
||||
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
|
||||
obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
|
||||
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/* Banks */
|
||||
#define ABIT_UGURU_ALARM_BANK 0x20 /* 1x 3 bytes */
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/* uGuru3 bank addresses */
|
||||
#define ABIT_UGURU3_SETTINGS_BANK 0x01
|
||||
@ -117,9 +117,12 @@ struct abituguru3_sensor_info {
|
||||
int offset;
|
||||
};
|
||||
|
||||
/* Avoid use of flexible array members */
|
||||
#define ABIT_UGURU3_MAX_DMI_NAMES 2
|
||||
|
||||
struct abituguru3_motherboard_info {
|
||||
u16 id;
|
||||
const char *dmi_name;
|
||||
const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1];
|
||||
/* + 1 -> end of sensors indicated by a sensor with name == NULL */
|
||||
struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
|
||||
};
|
||||
@ -164,7 +167,7 @@ struct abituguru3_data {
|
||||
|
||||
/* Constants */
|
||||
static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ 0x000C, NULL /* Unknown, need DMI string */, {
|
||||
{ 0x000C, { NULL } /* Unknown, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 10, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -186,7 +189,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX1 Fan", 35, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x000D, NULL /* Abit AW8, need DMI string */, {
|
||||
{ 0x000D, { NULL } /* Abit AW8, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 10, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -215,7 +218,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX5 Fan", 39, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x000E, NULL /* AL-8, need DMI string */, {
|
||||
{ 0x000E, { NULL } /* AL-8, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 10, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -236,7 +239,8 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "SYS Fan", 34, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x000F, NULL /* Unknown, need DMI string */, {
|
||||
{ 0x000F, { NULL } /* Unknown, need DMI string */, {
|
||||
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 10, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -257,7 +261,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "SYS Fan", 34, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, {
|
||||
{ 0x0010, { NULL } /* Abit NI8 SLI GR, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 10, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -279,7 +283,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "OTES1 Fan", 36, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0011, "AT8 32X", {
|
||||
{ 0x0011, { "AT8 32X", NULL }, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 20, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -306,7 +310,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX3 Fan", 37, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
|
||||
{ 0x0012, { NULL } /* Abit AN8 32X, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 20, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -328,7 +332,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX1 Fan", 36, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0013, NULL /* Abit AW8D, need DMI string */, {
|
||||
{ 0x0013, { NULL } /* Abit AW8D, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 10, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -357,7 +361,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX5 Fan", 39, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0014, "AB9", /* + AB9 Pro */ {
|
||||
{ 0x0014, { "AB9", "AB9 Pro", NULL }, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 10, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -378,7 +382,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "SYS Fan", 34, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0015, NULL /* Unknown, need DMI string */, {
|
||||
{ 0x0015, { NULL } /* Unknown, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR", 1, 0, 20, 1, 0 },
|
||||
{ "DDR VTT", 2, 0, 10, 1, 0 },
|
||||
@ -402,7 +406,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX3 Fan", 36, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0016, "AW9D-MAX", {
|
||||
{ 0x0016, { "AW9D-MAX", NULL }, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR2", 1, 0, 20, 1, 0 },
|
||||
{ "DDR2 VTT", 2, 0, 10, 1, 0 },
|
||||
@ -430,7 +434,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "OTES1 Fan", 38, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0017, NULL /* Unknown, need DMI string */, {
|
||||
{ 0x0017, { NULL } /* Unknown, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR2", 1, 0, 20, 1, 0 },
|
||||
{ "DDR2 VTT", 2, 0, 10, 1, 0 },
|
||||
@ -455,7 +459,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX3 FAN", 37, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0018, "AB9 QuadGT", {
|
||||
{ 0x0018, { "AB9 QuadGT", NULL }, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR2", 1, 0, 20, 1, 0 },
|
||||
{ "DDR2 VTT", 2, 0, 10, 1, 0 },
|
||||
@ -482,7 +486,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX3 Fan", 36, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0019, "IN9 32X MAX", {
|
||||
{ 0x0019, { "IN9 32X MAX", NULL }, {
|
||||
{ "CPU Core", 7, 0, 10, 1, 0 },
|
||||
{ "DDR2", 13, 0, 20, 1, 0 },
|
||||
{ "DDR2 VTT", 14, 0, 10, 1, 0 },
|
||||
@ -509,7 +513,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX3 FAN", 36, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x001A, "IP35 Pro", {
|
||||
{ 0x001A, { "IP35 Pro", "IP35 Pro XE", NULL }, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR2", 1, 0, 20, 1, 0 },
|
||||
{ "DDR2 VTT", 2, 0, 10, 1, 0 },
|
||||
@ -537,7 +541,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX4 Fan", 37, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x001B, NULL /* Unknown, need DMI string */, {
|
||||
{ 0x001B, { NULL } /* Unknown, need DMI string */, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR3", 1, 0, 20, 1, 0 },
|
||||
{ "DDR3 VTT", 2, 0, 10, 1, 0 },
|
||||
@ -564,7 +568,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX3 Fan", 36, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x001C, "IX38 QuadGT", {
|
||||
{ 0x001C, { "IX38 QuadGT", NULL }, {
|
||||
{ "CPU Core", 0, 0, 10, 1, 0 },
|
||||
{ "DDR2", 1, 0, 20, 1, 0 },
|
||||
{ "DDR2 VTT", 2, 0, 10, 1, 0 },
|
||||
@ -591,7 +595,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
|
||||
{ "AUX3 Fan", 36, 2, 60, 1, 0 },
|
||||
{ NULL, 0, 0, 0, 0, 0 } }
|
||||
},
|
||||
{ 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } }
|
||||
{ 0x0000, { NULL }, { { NULL, 0, 0, 0, 0, 0 } } }
|
||||
};
|
||||
|
||||
|
||||
@ -946,15 +950,6 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
|
||||
printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard "
|
||||
"ID: %04X\n", (unsigned int)id);
|
||||
|
||||
#ifdef CONFIG_DMI
|
||||
if (!abituguru3_motherboards[i].dmi_name) {
|
||||
printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
|
||||
"not detected using DMI. Please send the output of "
|
||||
"\"dmidecode\" to the abituguru3 maintainer "
|
||||
"(see MAINTAINERS)\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fill the sysfs attr array */
|
||||
sysfs_attr_i = 0;
|
||||
sysfs_filename = data->sysfs_names;
|
||||
@ -1131,6 +1126,7 @@ static int __init abituguru3_dmi_detect(void)
|
||||
{
|
||||
const char *board_vendor, *board_name;
|
||||
int i, err = (force) ? 1 : -ENODEV;
|
||||
const char *const *dmi_name;
|
||||
size_t sublen;
|
||||
|
||||
board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
|
||||
@ -1151,17 +1147,17 @@ static int __init abituguru3_dmi_detect(void)
|
||||
sublen--;
|
||||
|
||||
for (i = 0; abituguru3_motherboards[i].id; i++) {
|
||||
const char *dmi_name = abituguru3_motherboards[i].dmi_name;
|
||||
if (!dmi_name || strlen(dmi_name) != sublen)
|
||||
continue;
|
||||
if (!strncasecmp(board_name, dmi_name, sublen))
|
||||
break;
|
||||
dmi_name = abituguru3_motherboards[i].dmi_name;
|
||||
for ( ; *dmi_name; dmi_name++) {
|
||||
if (strlen(*dmi_name) != sublen)
|
||||
continue;
|
||||
if (!strncasecmp(board_name, *dmi_name, sublen))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!abituguru3_motherboards[i].id)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
/* No match found */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_DMI */
|
||||
@ -1221,6 +1217,13 @@ static int __init abituguru3_init(void)
|
||||
err = abituguru3_detect();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#ifdef CONFIG_DMI
|
||||
printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
|
||||
"not detected using DMI. Please send the output of "
|
||||
"\"dmidecode\" to the abituguru3 maintainer "
|
||||
"(see MAINTAINERS)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
err = platform_driver_register(&abituguru3_driver);
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/* ISA device, if found */
|
||||
static struct platform_device *pdev;
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static unsigned short force_id;
|
||||
module_param(force_id, ushort, 0);
|
||||
|
@ -35,8 +35,7 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
|
||||
#define HDAPS_NR_PORTS 0x30 /* number of ports: 0x1600 - 0x162f */
|
||||
|
@ -179,8 +179,14 @@ struct vrm_model {
|
||||
static struct vrm_model vrm_models[] = {
|
||||
{X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */
|
||||
{X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */
|
||||
{X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* NPT family 0Fh */
|
||||
/* In theory, all NPT family 0Fh processors have 6 VID pins and should
|
||||
thus use vrm 25, however in practice not all mainboards route the
|
||||
6th VID pin because it is never needed. So we use the 5 VID pin
|
||||
variant (vrm 24) for the models which exist today. */
|
||||
{X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24}, /* NPT family 0Fh */
|
||||
{X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* future fam. 0Fh */
|
||||
{X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */
|
||||
|
||||
{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */
|
||||
{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */
|
||||
{X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */
|
||||
@ -191,12 +197,14 @@ static struct vrm_model vrm_models[] = {
|
||||
{X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */
|
||||
{X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */
|
||||
{X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */
|
||||
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */
|
||||
{X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */
|
||||
|
||||
{X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */
|
||||
};
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define DRVNAME "it87"
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
/* ISA device, if found */
|
||||
static struct platform_device *pdev;
|
||||
|
@ -75,6 +75,8 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100,
|
||||
#define LM85_VERSTEP_GENERIC2 0x70
|
||||
#define LM85_VERSTEP_LM85C 0x60
|
||||
#define LM85_VERSTEP_LM85B 0x62
|
||||
#define LM85_VERSTEP_LM96000_1 0x68
|
||||
#define LM85_VERSTEP_LM96000_2 0x69
|
||||
#define LM85_VERSTEP_ADM1027 0x60
|
||||
#define LM85_VERSTEP_ADT7463 0x62
|
||||
#define LM85_VERSTEP_ADT7463C 0x6A
|
||||
@ -1133,6 +1135,26 @@ static void lm85_init_client(struct i2c_client *client)
|
||||
dev_warn(&client->dev, "Device is not ready\n");
|
||||
}
|
||||
|
||||
static int lm85_is_fake(struct i2c_client *client)
|
||||
{
|
||||
/*
|
||||
* Differenciate between real LM96000 and Winbond WPCD377I. The latter
|
||||
* emulate the former except that it has no hardware monitoring function
|
||||
* so the readings are always 0.
|
||||
*/
|
||||
int i;
|
||||
u8 in_temp, fan;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
in_temp = i2c_smbus_read_byte_data(client, 0x20 + i);
|
||||
fan = i2c_smbus_read_byte_data(client, 0x28 + i);
|
||||
if (in_temp != 0x00 || fan != 0xff)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 0 if detection is successful, -ENODEV otherwise */
|
||||
static int lm85_detect(struct i2c_client *client, int kind,
|
||||
struct i2c_board_info *info)
|
||||
@ -1173,6 +1195,16 @@ static int lm85_detect(struct i2c_client *client, int kind,
|
||||
case LM85_VERSTEP_LM85B:
|
||||
kind = lm85b;
|
||||
break;
|
||||
case LM85_VERSTEP_LM96000_1:
|
||||
case LM85_VERSTEP_LM96000_2:
|
||||
/* Check for Winbond WPCD377I */
|
||||
if (lm85_is_fake(client)) {
|
||||
dev_dbg(&adapter->dev,
|
||||
"Found Winbond WPCD377I, "
|
||||
"ignoring\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (company == LM85_COMPANY_ANALOG_DEV) {
|
||||
switch (verstep) {
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static u8 devid;
|
||||
static struct platform_device *pdev;
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static unsigned short force_id;
|
||||
module_param(force_id, ushort, 0);
|
||||
@ -435,7 +435,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
|
||||
/* This will need to be revisited when we add support for
|
||||
temperature and voltage monitoring. */
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
|
||||
if (!request_region(res->start, resource_size(res), DRVNAME)) {
|
||||
err = -EBUSY;
|
||||
dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
|
||||
(unsigned long)res->start, (unsigned long)res->end);
|
||||
@ -475,7 +475,7 @@ exit_remove_files:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
|
||||
}
|
||||
exit_release_region:
|
||||
release_region(res->start, res->end - res->start + 1);
|
||||
release_region(res->start, resource_size(res));
|
||||
exit_kfree:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
@ -500,7 +500,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
|
||||
kfree(data);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
release_region(res->start, res->end - res->start + 1);
|
||||
release_region(res->start, resource_size(res));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
|
||||
/* If force_addr is set to anything different from 0, we forcibly enable
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static unsigned short force_id;
|
||||
module_param(force_id, ushort, 0);
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static unsigned short force_id;
|
||||
module_param(force_id, ushort, 0);
|
||||
|
347
drivers/hwmon/tmp421.c
Normal file
347
drivers/hwmon/tmp421.c
Normal file
@ -0,0 +1,347 @@
|
||||
/* tmp421.c
|
||||
*
|
||||
* Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
|
||||
* Preliminary support by:
|
||||
* Melvin Rook, Raymond Ng
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for the Texas Instruments TMP421 SMBus temperature sensor IC.
|
||||
* Supported models: TMP421, TMP422, TMP423
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
/* Addresses to scan */
|
||||
static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
I2C_CLIENT_END };
|
||||
|
||||
/* Insmod parameters */
|
||||
I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423);
|
||||
|
||||
/* The TMP421 registers */
|
||||
#define TMP421_CONFIG_REG_1 0x09
|
||||
#define TMP421_CONVERSION_RATE_REG 0x0B
|
||||
#define TMP421_MANUFACTURER_ID_REG 0xFE
|
||||
#define TMP421_DEVICE_ID_REG 0xFF
|
||||
|
||||
static const u8 TMP421_TEMP_MSB[4] = { 0x00, 0x01, 0x02, 0x03 };
|
||||
static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 };
|
||||
|
||||
/* Flags */
|
||||
#define TMP421_CONFIG_SHUTDOWN 0x40
|
||||
#define TMP421_CONFIG_RANGE 0x04
|
||||
|
||||
/* Manufacturer / Device ID's */
|
||||
#define TMP421_MANUFACTURER_ID 0x55
|
||||
#define TMP421_DEVICE_ID 0x21
|
||||
#define TMP422_DEVICE_ID 0x22
|
||||
#define TMP423_DEVICE_ID 0x23
|
||||
|
||||
static const struct i2c_device_id tmp421_id[] = {
|
||||
{ "tmp421", tmp421 },
|
||||
{ "tmp422", tmp422 },
|
||||
{ "tmp423", tmp423 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tmp421_id);
|
||||
|
||||
struct tmp421_data {
|
||||
struct device *hwmon_dev;
|
||||
struct mutex update_lock;
|
||||
char valid;
|
||||
unsigned long last_updated;
|
||||
int kind;
|
||||
u8 config;
|
||||
s16 temp[4];
|
||||
};
|
||||
|
||||
static int temp_from_s16(s16 reg)
|
||||
{
|
||||
int temp = reg;
|
||||
|
||||
return (temp * 1000 + 128) / 256;
|
||||
}
|
||||
|
||||
static int temp_from_u16(u16 reg)
|
||||
{
|
||||
int temp = reg;
|
||||
|
||||
/* Add offset for extended temperature range. */
|
||||
temp -= 64 * 256;
|
||||
|
||||
return (temp * 1000 + 128) / 256;
|
||||
}
|
||||
|
||||
static struct tmp421_data *tmp421_update_device(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct tmp421_data *data = i2c_get_clientdata(client);
|
||||
int i;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
|
||||
data->config = i2c_smbus_read_byte_data(client,
|
||||
TMP421_CONFIG_REG_1);
|
||||
|
||||
for (i = 0; i <= data->kind; i++) {
|
||||
data->temp[i] = i2c_smbus_read_byte_data(client,
|
||||
TMP421_TEMP_MSB[i]) << 8;
|
||||
data->temp[i] |= i2c_smbus_read_byte_data(client,
|
||||
TMP421_TEMP_LSB[i]);
|
||||
}
|
||||
data->last_updated = jiffies;
|
||||
data->valid = 1;
|
||||
}
|
||||
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static ssize_t show_temp_value(struct device *dev,
|
||||
struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
int index = to_sensor_dev_attr(devattr)->index;
|
||||
struct tmp421_data *data = tmp421_update_device(dev);
|
||||
int temp;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
if (data->config & TMP421_CONFIG_RANGE)
|
||||
temp = temp_from_u16(data->temp[index]);
|
||||
else
|
||||
temp = temp_from_s16(data->temp[index]);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return sprintf(buf, "%d\n", temp);
|
||||
}
|
||||
|
||||
static ssize_t show_fault(struct device *dev,
|
||||
struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
int index = to_sensor_dev_attr(devattr)->index;
|
||||
struct tmp421_data *data = tmp421_update_device(dev);
|
||||
|
||||
/*
|
||||
* The OPEN bit signals a fault. This is bit 0 of the temperature
|
||||
* register (low byte).
|
||||
*/
|
||||
if (data->temp[index] & 0x01)
|
||||
return sprintf(buf, "1\n");
|
||||
else
|
||||
return sprintf(buf, "0\n");
|
||||
}
|
||||
|
||||
static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
|
||||
int n)
|
||||
{
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct tmp421_data *data = dev_get_drvdata(dev);
|
||||
struct device_attribute *devattr;
|
||||
unsigned int index;
|
||||
|
||||
devattr = container_of(a, struct device_attribute, attr);
|
||||
index = to_sensor_dev_attr(devattr)->index;
|
||||
|
||||
if (data->kind > index)
|
||||
return a->mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
|
||||
static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
|
||||
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
|
||||
static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
|
||||
|
||||
static struct attribute *tmp421_attr[] = {
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp2_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp2_fault.dev_attr.attr,
|
||||
&sensor_dev_attr_temp3_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp3_fault.dev_attr.attr,
|
||||
&sensor_dev_attr_temp4_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp4_fault.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group tmp421_group = {
|
||||
.attrs = tmp421_attr,
|
||||
.is_visible = tmp421_is_visible,
|
||||
};
|
||||
|
||||
static int tmp421_init_client(struct i2c_client *client)
|
||||
{
|
||||
int config, config_orig;
|
||||
|
||||
/* Set the conversion rate to 2 Hz */
|
||||
i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05);
|
||||
|
||||
/* Start conversions (disable shutdown if necessary) */
|
||||
config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1);
|
||||
if (config < 0) {
|
||||
dev_err(&client->dev, "Could not read configuration"
|
||||
" register (%d)\n", config);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
config_orig = config;
|
||||
config &= ~TMP421_CONFIG_SHUTDOWN;
|
||||
|
||||
if (config != config_orig) {
|
||||
dev_info(&client->dev, "Enable monitoring chip\n");
|
||||
i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmp421_detect(struct i2c_client *client, int kind,
|
||||
struct i2c_board_info *info)
|
||||
{
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
const char *names[] = { "TMP421", "TMP422", "TMP423" };
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -ENODEV;
|
||||
|
||||
if (kind <= 0) {
|
||||
u8 reg;
|
||||
|
||||
reg = i2c_smbus_read_byte_data(client,
|
||||
TMP421_MANUFACTURER_ID_REG);
|
||||
if (reg != TMP421_MANUFACTURER_ID)
|
||||
return -ENODEV;
|
||||
|
||||
reg = i2c_smbus_read_byte_data(client,
|
||||
TMP421_DEVICE_ID_REG);
|
||||
switch (reg) {
|
||||
case TMP421_DEVICE_ID:
|
||||
kind = tmp421;
|
||||
break;
|
||||
case TMP422_DEVICE_ID:
|
||||
kind = tmp422;
|
||||
break;
|
||||
case TMP423_DEVICE_ID:
|
||||
kind = tmp423;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
|
||||
dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
|
||||
names[kind - 1], client->addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmp421_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct tmp421_data *data;
|
||||
int err;
|
||||
|
||||
data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
mutex_init(&data->update_lock);
|
||||
data->kind = id->driver_data;
|
||||
|
||||
err = tmp421_init_client(client);
|
||||
if (err)
|
||||
goto exit_free;
|
||||
|
||||
err = sysfs_create_group(&client->dev.kobj, &tmp421_group);
|
||||
if (err)
|
||||
goto exit_free;
|
||||
|
||||
data->hwmon_dev = hwmon_device_register(&client->dev);
|
||||
if (IS_ERR(data->hwmon_dev)) {
|
||||
err = PTR_ERR(data->hwmon_dev);
|
||||
data->hwmon_dev = NULL;
|
||||
goto exit_remove;
|
||||
}
|
||||
return 0;
|
||||
|
||||
exit_remove:
|
||||
sysfs_remove_group(&client->dev.kobj, &tmp421_group);
|
||||
|
||||
exit_free:
|
||||
i2c_set_clientdata(client, NULL);
|
||||
kfree(data);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tmp421_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tmp421_data *data = i2c_get_clientdata(client);
|
||||
|
||||
hwmon_device_unregister(data->hwmon_dev);
|
||||
sysfs_remove_group(&client->dev.kobj, &tmp421_group);
|
||||
|
||||
i2c_set_clientdata(client, NULL);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver tmp421_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.driver = {
|
||||
.name = "tmp421",
|
||||
},
|
||||
.probe = tmp421_probe,
|
||||
.remove = tmp421_remove,
|
||||
.id_table = tmp421_id,
|
||||
.detect = tmp421_detect,
|
||||
.address_data = &addr_data,
|
||||
};
|
||||
|
||||
static int __init tmp421_init(void)
|
||||
{
|
||||
return i2c_add_driver(&tmp421_driver);
|
||||
}
|
||||
|
||||
static void __exit tmp421_exit(void)
|
||||
{
|
||||
i2c_del_driver(&tmp421_driver);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
|
||||
MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor"
|
||||
" driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(tmp421_init);
|
||||
module_exit(tmp421_exit);
|
@ -42,7 +42,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
|
||||
/* If force_addr is set to anything different from 0, we forcibly enable
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static int uch_config = -1;
|
||||
module_param(uch_config, int, 0);
|
||||
@ -1136,7 +1136,7 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
|
||||
if (!request_region(res->start, resource_size(res), DRVNAME)) {
|
||||
err = -EBUSY;
|
||||
dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
|
||||
(unsigned long)res->start, (unsigned long)res->end);
|
||||
@ -1209,7 +1209,7 @@ EXIT_DEV_REMOVE:
|
||||
dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
|
||||
EXIT_DEV_REMOVE_SILENT:
|
||||
vt1211_remove_sysfs(pdev);
|
||||
release_region(res->start, res->end - res->start + 1);
|
||||
release_region(res->start, resource_size(res));
|
||||
EXIT_KFREE:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(data);
|
||||
@ -1228,7 +1228,7 @@ static int __devexit vt1211_remove(struct platform_device *pdev)
|
||||
kfree(data);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
release_region(res->start, res->end - res->start + 1);
|
||||
release_region(res->start, resource_size(res));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static int force_addr;
|
||||
module_param(force_addr, int, 0);
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include "lm75.h"
|
||||
|
||||
enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg };
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#include "lm75.h"
|
||||
|
||||
static struct platform_device *pdev;
|
||||
|
@ -48,7 +48,7 @@
|
||||
#ifdef CONFIG_ISA
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
#endif
|
||||
|
||||
#include "lm75.h"
|
||||
|
Loading…
Reference in New Issue
Block a user