diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-17 09:47:35 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-17 09:47:35 -0700 |
commit | 96c015b75feaaa67c8744229937bd9c35919d16b (patch) | |
tree | c7021e4245d9a02fa78d9775027b9ac1dc9ec8a6 | |
parent | 3aee0605a41399063c0ad396f1f4267108f210d3 (diff) | |
parent | 5cfaf338134605ce8d9272b9c16605bc920d25be (diff) |
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
-rw-r--r-- | Documentation/hwmon/pcf8591 | 28 | ||||
-rw-r--r-- | Documentation/hwmon/tmp421 | 36 | ||||
-rw-r--r-- | MAINTAINERS | 6 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 110 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 7 | ||||
-rw-r--r-- | drivers/hwmon/abituguru.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/abituguru3.c | 79 | ||||
-rw-r--r-- | drivers/hwmon/applesmc.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/dme1737.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/f71805f.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/hdaps.c | 3 | ||||
-rw-r--r-- | drivers/hwmon/hwmon-vid.c | 10 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/lm78.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/lm85.c | 32 | ||||
-rw-r--r-- | drivers/hwmon/pc87360.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/pc87427.c | 8 | ||||
-rw-r--r-- | drivers/hwmon/sis5595.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/smsc47b397.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/smsc47m1.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/tmp421.c | 347 | ||||
-rw-r--r-- | drivers/hwmon/via686a.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/vt1211.c | 8 | ||||
-rw-r--r-- | drivers/hwmon/vt8231.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83627hf.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/w83781d.c | 2 |
27 files changed, 579 insertions, 125 deletions
diff --git a/Documentation/hwmon/pcf8591 b/Documentation/hwmon/pcf8591 index 5628fcf4207..e76a7892f68 100644 --- a/Documentation/hwmon/pcf8591 +++ b/Documentation/hwmon/pcf8591 @@ -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. diff --git a/Documentation/hwmon/tmp421 b/Documentation/hwmon/tmp421 new file mode 100644 index 00000000000..0cf07f82474 --- /dev/null +++ b/Documentation/hwmon/tmp421 @@ -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 diff --git a/MAINTAINERS b/MAINTAINERS index 9117b65f4ae..c5f312bac7b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 2e25b7a827d..461abb1e273 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -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 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 7f239a247c3..2e547881bc0 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -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 diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 4dbdb81ea3b..03694cc17a3 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -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 */ diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 7d3f15d32fd..3cf28af614b 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c @@ -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); diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 678e34b01e5..753b34885f9 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -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> diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 3df202a9ad7..9814d51b3af 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -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; diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index 89987657925..525a00bd70b 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -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); diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index d3612a1f198..be2d131e405 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c @@ -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 */ diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index bfc296145bb..bf0862a803c 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c @@ -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 */ }; diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 9157247fed8..ffeb2a10e1a 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -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" diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index a1787fdf5b9..f7e70163e01 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -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; diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index b251d8674b4..6c53d987de1 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -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) { diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index fb052fea374..4a64b85d4ec 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -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; diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c index 3a8a0f7a773..3170b26d244 100644 --- a/drivers/hwmon/pc87427.c +++ b/drivers/hwmon/pc87427.c @@ -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; } diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index aa2e8318f16..12f2e708656 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -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 diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 6f6d52b4fb6..f46d936c12d 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -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); diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index ba75bfcf14c..8ad50fdba00 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -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); diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c new file mode 100644 index 00000000000..20924343431 --- /dev/null +++ b/drivers/hwmon/tmp421.c @@ -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); diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index a022aedcaac..39e82a492f2 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -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 diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index 73f77a9b8b1..ae33bbb577c 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c @@ -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; } diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 9982b45fbb1..470a1226ba2 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -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); diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 0e9746913d2..bb5e7874878 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -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 }; diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 389150ba30d..2be28ac4ede 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -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; diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 0bdab959b73..d27ed1bac00 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -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" |