diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 16:59:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 16:59:38 -0700 |
commit | 19520fc1ee36164808e6f084bd95e8178e2db231 (patch) | |
tree | abf66f8c2a2b35e574e9452673263614fc50c63f /drivers/hwmon | |
parent | c8def554d031664e984323f6a5d667f070717776 (diff) | |
parent | d668a8b022a201e65ec5e301a9e6dff78987550c (diff) |
Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging: (44 commits)
hwmon: (lineage-pem): Fix in1 voltage alarm sysfs attributes
hwmon/f71882fg: Add support for f71808e
hwmon/f71882fg: Add support for f71869f and f71869e
hwmon/f71882fg: Add support for f71889ed
hwmon/f71882fg: Break out test for auto pwm's controlled by digital readings
hwmon/f71882fg: Separate temp beep sysfs attr from the other temp sysfs attr
hwmon/f71882fg: Remove bogus temp2_type for certain models
hwmon/f71882fg: Make number of temps configurable
hwmon/f71882fg: Make creation of in sysfs attributes more generic
hwmon/f71882fg: Only allow negative auto point temps if fan_neg_temp is enabled
hwmon/f71882fg: Fix temp1 sensor type reporting
hwmon: (w83627ehf) Display correct temperature sensor labels for systems with NCT6775F
hwmon: (w83627ehf) Add fan debounce support for NCT6775F and NCT6776F
hwmon: (w83627ehf) Update Kconfig for W83677HG-B, NCT6775F and NCT6776F
hwmon: (w83627ehf) Store rpm instead of raw fan speed data
hwmon: (w83627ehf) Use 16 bit fan count registers if supported
hwmon: (w83627ehf) Add support for Nuvoton NCT6775F and NCT6776F
hwmon: (w83627ehf) Permit enabling SmartFan IV mode if configured at startup
hwmon: (w83627ehf) Convert register arrays to 16 bit, and convert access to pointers
hwmon: (w83627ehf) Remove references to datasheets which no longer exist
...
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 92 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 10 | ||||
-rw-r--r-- | drivers/hwmon/f71882fg.c | 522 | ||||
-rw-r--r-- | drivers/hwmon/lineage-pem.c | 586 | ||||
-rw-r--r-- | drivers/hwmon/lis3lv02d_spi.c | 19 | ||||
-rw-r--r-- | drivers/hwmon/lm85.c | 136 | ||||
-rw-r--r-- | drivers/hwmon/ltc4151.c | 256 | ||||
-rw-r--r-- | drivers/hwmon/max16064.c | 91 | ||||
-rw-r--r-- | drivers/hwmon/max34440.c | 199 | ||||
-rw-r--r-- | drivers/hwmon/max6639.c | 653 | ||||
-rw-r--r-- | drivers/hwmon/max8688.c | 158 | ||||
-rw-r--r-- | drivers/hwmon/pmbus.c | 203 | ||||
-rw-r--r-- | drivers/hwmon/pmbus.h | 313 | ||||
-rw-r--r-- | drivers/hwmon/pmbus_core.c | 1658 | ||||
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 1351 |
15 files changed, 5683 insertions, 564 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 297bc9a7d6e..1bfb4439e4e 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -467,6 +467,17 @@ config SENSORS_JC42 This driver can also be built as a module. If so, the module will be called jc42. +config SENSORS_LINEAGE + tristate "Lineage Compact Power Line Power Entry Module" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Lineage Compact Power Line + series of DC/DC and AC/DC converters such as CP1800, CP2000AC, + CP2000DC, CP2725, and others. + + This driver can also be built as a module. If so, the module + will be called lineage-pem. + config SENSORS_LM63 tristate "National Semiconductor LM63 and LM64" depends on I2C @@ -625,6 +636,17 @@ config SENSORS_LM93 This driver can also be built as a module. If so, the module will be called lm93. +config SENSORS_LTC4151 + tristate "Linear Technology LTC4151" + depends on I2C + default n + help + If you say yes here you get support for Linear Technology LTC4151 + High Voltage I2C Current and Voltage Monitor interface. + + This driver can also be built as a module. If so, the module will + be called ltc4151. + config SENSORS_LTC4215 tristate "Linear Technology LTC4215" depends on I2C && EXPERIMENTAL @@ -685,6 +707,16 @@ config SENSORS_MAX1619 This driver can also be built as a module. If so, the module will be called max1619. +config SENSORS_MAX6639 + tristate "Maxim MAX6639 sensor chip" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the MAX6639 + sensor chips. + + This driver can also be built as a module. If so, the module + will be called max6639. + config SENSORS_MAX6650 tristate "Maxim MAX6650 sensor chip" depends on I2C && EXPERIMENTAL @@ -735,6 +767,61 @@ config SENSORS_PCF8591 These devices are hard to detect and rarely found on mainstream hardware. If unsure, say N. +config PMBUS + tristate "PMBus support" + depends on I2C && EXPERIMENTAL + default n + help + Say yes here if you want to enable PMBus support. + + This driver can also be built as a module. If so, the module will + be called pmbus_core. + +if PMBUS + +config SENSORS_PMBUS + tristate "Generic PMBus devices" + default n + help + If you say yes here you get hardware monitoring support for generic + PMBus devices, including but not limited to BMR450, BMR451, BMR453, + BMR454, and LTC2978. + + This driver can also be built as a module. If so, the module will + be called pmbus. + +config SENSORS_MAX16064 + tristate "Maxim MAX16064" + default n + help + If you say yes here you get hardware monitoring support for Maxim + MAX16064. + + This driver can also be built as a module. If so, the module will + be called max16064. + +config SENSORS_MAX34440 + tristate "Maxim MAX34440/MAX34441" + default n + help + If you say yes here you get hardware monitoring support for Maxim + MAX34440 and MAX34441. + + This driver can also be built as a module. If so, the module will + be called max34440. + +config SENSORS_MAX8688 + tristate "Maxim MAX8688" + default n + help + If you say yes here you get hardware monitoring support for Maxim + MAX8688. + + This driver can also be built as a module. If so, the module will + be called max8688. + +endif # PMBUS + config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." depends on GENERIC_GPIO @@ -1083,7 +1170,7 @@ config SENSORS_W83627HF will be called w83627hf. config SENSORS_W83627EHF - tristate "Winbond W83627EHF/EHG/DHG, W83667HG" + tristate "Winbond W83627EHF/EHG/DHG, W83667HG, NCT6775F, NCT6776F" select HWMON_VID help If you say yes here you get support for the hardware @@ -1094,7 +1181,8 @@ config SENSORS_W83627EHF chip suited for specific Intel processors that use PECI such as the Core 2 Duo. - This driver also supports the W83667HG chip. + This driver also supports Nuvoton W83667HG, W83667HG-B, NCT6775F + (also known as W83667HG-I), and NCT6776F. This driver can also be built as a module. If so, the module will be called w83627ehf. diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index dde02d99c23..bd0410e4b44 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_JC42) += jc42.o obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o +obj-$(CONFIG_SENSORS_LINEAGE) += lineage-pem.o obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d.o lis3lv02d_i2c.o @@ -79,11 +80,13 @@ obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM92) += lm92.o obj-$(CONFIG_SENSORS_LM93) += lm93.o obj-$(CONFIG_SENSORS_LM95241) += lm95241.o +obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o obj-$(CONFIG_SENSORS_MAX1111) += max1111.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o +obj-$(CONFIG_SENSORS_MAX6639) += max6639.o obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o @@ -112,6 +115,13 @@ obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o +# PMBus drivers +obj-$(CONFIG_PMBUS) += pmbus_core.o +obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o +obj-$(CONFIG_SENSORS_MAX16064) += max16064.o +obj-$(CONFIG_SENSORS_MAX34440) += max34440.o +obj-$(CONFIG_SENSORS_MAX8688) += max8688.o + ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG endif diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 6e06019015a..a4d430ee7e2 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -1,6 +1,6 @@ /*************************************************************************** * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * - * Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com> * + * Copyright (C) 2007-2011 Hans de Goede <hdegoede@redhat.com> * * * * 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 * @@ -47,22 +47,23 @@ #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ +#define SIO_F71808E_ID 0x0901 /* Chipset ID */ #define SIO_F71858_ID 0x0507 /* Chipset ID */ #define SIO_F71862_ID 0x0601 /* Chipset ID */ +#define SIO_F71869_ID 0x0814 /* Chipset ID */ #define SIO_F71882_ID 0x0541 /* Chipset ID */ #define SIO_F71889_ID 0x0723 /* Chipset ID */ +#define SIO_F71889E_ID 0x0909 /* Chipset ID */ #define SIO_F8000_ID 0x0581 /* Chipset ID */ #define REGION_LENGTH 8 #define ADDR_REG_OFFSET 5 #define DATA_REG_OFFSET 6 -#define F71882FG_REG_PECI 0x0A - -#define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */ -#define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */ +#define F71882FG_REG_IN_STATUS 0x12 /* f7188x only */ +#define F71882FG_REG_IN_BEEP 0x13 /* f7188x only */ #define F71882FG_REG_IN(nr) (0x20 + (nr)) -#define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */ +#define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */ #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr))) @@ -86,28 +87,71 @@ #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr)) +#define F71882FG_REG_FAN_FAULT_T 0x9F +#define F71882FG_FAN_NEG_TEMP_EN 0x20 +#define F71882FG_FAN_PROG_SEL 0x80 + #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm))) #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm))) #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr)) #define F71882FG_REG_START 0x01 +#define F71882FG_MAX_INS 9 + #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ static unsigned short force_id; module_param(force_id, ushort, 0); MODULE_PARM_DESC(force_id, "Override the detected device ID"); -enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; +enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg, + f71889ed, f8000 }; static const char *f71882fg_names[] = { + "f71808e", "f71858fg", "f71862fg", + "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ "f71882fg", "f71889fg", + "f71889ed", "f8000", }; +static const char f71882fg_has_in[8][F71882FG_MAX_INS] = { + { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, /* f71808e */ + { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f71858fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71862fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71869 */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71882fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889fg */ + { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* f71889ed */ + { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* f8000 */ +}; + +static const char f71882fg_has_in1_alarm[8] = { + 0, /* f71808e */ + 0, /* f71858fg */ + 0, /* f71862fg */ + 0, /* f71869 */ + 1, /* f71882fg */ + 1, /* f71889fg */ + 1, /* f71889ed */ + 0, /* f8000 */ +}; + +static const char f71882fg_has_beep[8] = { + 0, /* f71808e */ + 0, /* f71858fg */ + 1, /* f71862fg */ + 1, /* f71869 */ + 1, /* f71882fg */ + 1, /* f71889fg */ + 1, /* f71889ed */ + 0, /* f8000 */ +}; + static struct platform_device *f71882fg_pdev; /* Super-I/O Function prototypes */ @@ -129,11 +173,12 @@ struct f71882fg_data { struct mutex update_lock; int temp_start; /* temp numbering start (0 or 1) */ char valid; /* !=0 if following fields are valid */ + char auto_point_temp_signed; unsigned long last_updated; /* In jiffies */ unsigned long last_limits; /* In jiffies */ /* Register Values */ - u8 in[9]; + u8 in[F71882FG_MAX_INS]; u8 in1_max; u8 in_status; u8 in_beep; @@ -142,7 +187,7 @@ struct f71882fg_data { u16 fan_full_speed[4]; u8 fan_status; u8 fan_beep; - /* Note: all models have only 3 temperature channels, but on some + /* Note: all models have max 3 temperature channels, but on some they are addressed as 0-2 and on others as 1-3, so for coding convenience we reserve space for 4 channels */ u16 temp[4]; @@ -262,13 +307,9 @@ static struct platform_driver f71882fg_driver = { static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); -/* Temp and in attr for the f71858fg, the f71858fg is special as it - has its temperature indexes start at 0 (the others start at 1) and - it only has 3 voltage inputs */ -static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { - SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), - SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), - SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), +/* Temp attr for the f71858fg, the f71858fg is special as it has its + temperature indexes start at 0 (the others start at 1) */ +static struct sensor_device_attribute_2 f71858fg_temp_attr[] = { SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, store_temp_max, 0, 0), @@ -292,7 +333,6 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0, 1), SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), - SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1), SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, @@ -308,17 +348,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), }; -/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */ -static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { - SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), - SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), - SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), - SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), - SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), - SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), - SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), - SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), - SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), +/* Temp attr for the standard models */ +static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { { SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, store_temp_max, 0, 1), @@ -328,17 +359,14 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { the max and crit alarms separately and lm_sensors v2 depends on the presence of temp#_alarm files. The same goes for temp2/3 _alarm. */ SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1), - SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, - store_temp_beep, 0, 1), SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, store_temp_crit, 0, 1), SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0, 1), SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), - SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, - store_temp_beep, 0, 5), SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1), SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), +}, { SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2), SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, store_temp_max, 0, 2), @@ -346,17 +374,14 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { store_temp_max_hyst, 0, 2), /* Should be temp2_max_alarm, see temp1_alarm note */ SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2), - SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, - store_temp_beep, 0, 2), SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, store_temp_crit, 0, 2), SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0, 2), SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), - SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, - store_temp_beep, 0, 6), SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), +}, { SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, store_temp_max, 0, 3), @@ -364,37 +389,39 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { store_temp_max_hyst, 0, 3), /* Should be temp3_max_alarm, see temp1_alarm note */ SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3), - SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, - store_temp_beep, 0, 3), SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, store_temp_crit, 0, 3), SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0, 3), SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7), - SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, - store_temp_beep, 0, 7), SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3), SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), -}; +} }; -/* For models with in1 alarm capability */ -static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = { - SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, - 0, 1), - SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, - 0, 1), - SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), -}; +/* Temp attr for models which can beep on temp alarm */ +static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { { + SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, + store_temp_beep, 0, 1), + SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, + store_temp_beep, 0, 5), +}, { + SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, + store_temp_beep, 0, 2), + SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, + store_temp_beep, 0, 6), +}, { + SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, + store_temp_beep, 0, 3), + SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, + store_temp_beep, 0, 7), +} }; -/* Temp and in attr for the f8000 +/* Temp attr for the f8000 Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) is used as hysteresis value to clear alarms Also like the f71858fg its temperature indexes start at 0 */ -static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { - SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), - SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), - SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), +static struct sensor_device_attribute_2 f8000_temp_attr[] = { SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit, store_temp_crit, 0, 0), @@ -408,7 +435,6 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, store_temp_max, 0, 1), SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), - SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1), SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit, @@ -419,6 +445,28 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = { SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), }; +/* in attr for all models */ +static struct sensor_device_attribute_2 fxxxx_in_attr[] = { + SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), + SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), + SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), + SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), + SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), + SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), + SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), + SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), + SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), +}; + +/* For models with in1 alarm capability */ +static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = { + SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, + 0, 1), + SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, + 0, 1), + SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), +}; + /* Fan / PWM attr common to all models */ static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { { SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), @@ -479,7 +527,7 @@ static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { }; /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the - f71858fg / f71882fg / f71889fg */ + standard models */ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, show_pwm_auto_point_channel, @@ -548,7 +596,87 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = { show_pwm_auto_point_temp_hyst, NULL, 3, 2), }; -/* PWM attr common to the f71858fg, f71882fg and f71889fg */ +/* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the + pwm setting when the temperature is above the pwmX_auto_point1_temp can be + programmed instead of being hardcoded to 0xff */ +static struct sensor_device_attribute_2 f71869_auto_pwm_attr[] = { + SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_channel, + store_pwm_auto_point_channel, 0, 0), + SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 0, 0), + SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 1, 0), + SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 4, 0), + SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp, store_pwm_auto_point_temp, + 0, 0), + SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp, store_pwm_auto_point_temp, + 3, 0), + SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp_hyst, + store_pwm_auto_point_temp_hyst, + 0, 0), + SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, + show_pwm_auto_point_temp_hyst, NULL, 3, 0), + + SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_channel, + store_pwm_auto_point_channel, 0, 1), + SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 0, 1), + SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 1, 1), + SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 4, 1), + SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp, store_pwm_auto_point_temp, + 0, 1), + SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp, store_pwm_auto_point_temp, + 3, 1), + SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp_hyst, + store_pwm_auto_point_temp_hyst, + 0, 1), + SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, + show_pwm_auto_point_temp_hyst, NULL, 3, 1), + + SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_channel, + store_pwm_auto_point_channel, 0, 2), + SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 0, 2), + SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 1, 2), + SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR, + show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, + 4, 2), + SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp, store_pwm_auto_point_temp, + 0, 2), + SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp, store_pwm_auto_point_temp, + 3, 2), + SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, + show_pwm_auto_point_temp_hyst, + store_pwm_auto_point_temp_hyst, + 0, 2), + SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, + show_pwm_auto_point_temp_hyst, NULL, 3, 2), +}; + +/* PWM attr for the standard models */ static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, show_pwm_auto_point_channel, @@ -943,16 +1071,16 @@ static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) static struct f71882fg_data *f71882fg_update_device(struct device *dev) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr, reg = 0, reg2; + int nr, reg, point; int nr_fans = (data->type == f71882fg) ? 4 : 3; - int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9; + int nr_temps = (data->type == f71808e) ? 2 : 3; mutex_lock(&data->update_lock); /* Update once every 60 seconds */ if (time_after(jiffies, data->last_limits + 60 * HZ) || !data->valid) { - if (data->type == f71882fg || data->type == f71889fg) { + if (f71882fg_has_in1_alarm[data->type]) { data->in1_max = f71882fg_read8(data, F71882FG_REG_IN1_HIGH); data->in_beep = @@ -960,7 +1088,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) } /* Get High & boundary temps*/ - for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) { + for (nr = data->temp_start; nr < nr_temps + data->temp_start; + nr++) { data->temp_ovt[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_OVT(nr)); data->temp_high[nr] = f71882fg_read8(data, @@ -973,44 +1102,19 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) data->temp_hyst[1] = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(1)); } + /* All but the f71858fg / f8000 have this register */ + if ((data->type != f71858fg) && (data->type != f8000)) { + reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); + data->temp_type[1] = (reg & 0x02) ? 2 : 4; + data->temp_type[2] = (reg & 0x04) ? 2 : 4; + data->temp_type[3] = (reg & 0x08) ? 2 : 4; + } - if (data->type == f71862fg || data->type == f71882fg || - data->type == f71889fg) { + if (f71882fg_has_beep[data->type]) { data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); - /* Have to hardcode type, because temp1 is special */ - reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); - data->temp_type[2] = (reg & 0x04) ? 2 : 4; - data->temp_type[3] = (reg & 0x08) ? 2 : 4; - } - /* Determine temp index 1 sensor type */ - if (data->type == f71889fg) { - reg2 = f71882fg_read8(data, F71882FG_REG_START); - switch ((reg2 & 0x60) >> 5) { - case 0x00: /* BJT / Thermistor */ - data->temp_type[1] = (reg & 0x02) ? 2 : 4; - break; - case 0x01: /* AMDSI */ - data->temp_type[1] = 5; - break; - case 0x02: /* PECI */ - case 0x03: /* Ibex Peak ?? Report as PECI for now */ - data->temp_type[1] = 6; - break; - } - } else { - reg2 = f71882fg_read8(data, F71882FG_REG_PECI); - if ((reg2 & 0x03) == 0x01) - data->temp_type[1] = 6; /* PECI */ - else if ((reg2 & 0x03) == 0x02) - data->temp_type[1] = 5; /* AMDSI */ - else if (data->type == f71862fg || - data->type == f71882fg) - data->temp_type[1] = (reg & 0x02) ? 2 : 4; - else /* f71858fg and f8000 only support BJT */ - data->temp_type[1] = 2; } data->pwm_enable = f71882fg_read8(data, @@ -1025,8 +1129,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); - if (data->type != f71862fg) { - int point; + switch (data->type) { + default: for (point = 0; point < 5; point++) { data->pwm_auto_point_pwm[nr][point] = f71882fg_read8(data, @@ -1039,7 +1143,14 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) F71882FG_REG_POINT_TEMP (nr, point)); } - } else { + break; + case f71808e: + case f71869: + data->pwm_auto_point_pwm[nr][0] = + f71882fg_read8(data, + F71882FG_REG_POINT_PWM(nr, 0)); + /* Fall through */ + case f71862fg: data->pwm_auto_point_pwm[nr][1] = f71882fg_read8(data, F71882FG_REG_POINT_PWM @@ -1056,6 +1167,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) f71882fg_read8(data, F71882FG_REG_POINT_TEMP (nr, 3)); + break; } } data->last_limits = jiffies; @@ -1067,7 +1179,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) F71882FG_REG_TEMP_STATUS); data->temp_diode_open = f71882fg_read8(data, F71882FG_REG_TEMP_DIODE_OPEN); - for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) + for (nr = data->temp_start; nr < nr_temps + data->temp_start; + nr++) data->temp[nr] = f71882fg_read_temp(data, nr); data->fan_status = f71882fg_read8(data, @@ -1083,17 +1196,18 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) data->pwm[nr] = f71882fg_read8(data, F71882FG_REG_PWM(nr)); } - /* The f8000 can monitor 1 more fan, but has no pwm for it */ if (data->type == f8000) data->fan[3] = f71882fg_read16(data, F71882FG_REG_FAN(3)); - if (data->type == f71882fg || data->type == f71889fg) + + if (f71882fg_has_in1_alarm[data->type]) data->in_status = f71882fg_read8(data, F71882FG_REG_IN_STATUS); - for (nr = 0; nr < nr_ins; nr++) - data->in[nr] = f71882fg_read8(data, - F71882FG_REG_IN(nr)); + for (nr = 0; nr < F71882FG_MAX_INS; nr++) + if (f71882fg_has_in[data->type][nr]) + data->in[nr] = f71882fg_read8(data, + F71882FG_REG_IN(nr)); data->last_updated = jiffies; data->valid = 1; @@ -1882,7 +1996,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, val /= 1000; - if (data->type == f71889fg) + if (data->auto_point_temp_signed) val = SENSORS_LIMIT(val, -128, 127); else val = SENSORS_LIMIT(val, 0, 127); @@ -1929,7 +2043,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) struct f71882fg_data *data; struct f71882fg_sio_data *sio_data = pdev->dev.platform_data; int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3; - u8 start_reg; + int nr_temps = (sio_data->type == f71808e) ? 2 : 3; + u8 start_reg, reg; data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL); if (!data) @@ -1968,37 +2083,72 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) /* The f71858fg temperature alarms behave as the f8000 alarms in this mode */ err = f71882fg_create_sysfs_files(pdev, - f8000_in_temp_attr, - ARRAY_SIZE(f8000_in_temp_attr)); + f8000_temp_attr, + ARRAY_SIZE(f8000_temp_attr)); else err = f71882fg_create_sysfs_files(pdev, - f71858fg_in_temp_attr, - ARRAY_SIZE(f71858fg_in_temp_attr)); - break; - case f71882fg: - case f71889fg: - err = f71882fg_create_sysfs_files(pdev, - fxxxx_in1_alarm_attr, - ARRAY_SIZE(fxxxx_in1_alarm_attr)); - if (err) - goto exit_unregister_sysfs; - /* fall through! */ - case f71862fg: - err = f71882fg_create_sysfs_files(pdev, - fxxxx_in_temp_attr, - ARRAY_SIZE(fxxxx_in_temp_attr)); + f71858fg_temp_attr, + ARRAY_SIZE(f71858fg_temp_attr)); break; case f8000: err = f71882fg_create_sysfs_files(pdev, - f8000_in_temp_attr, - ARRAY_SIZE(f8000_in_temp_attr)); + f8000_temp_attr, + ARRAY_SIZE(f8000_temp_attr)); break; + default: + err = f71882fg_create_sysfs_files(pdev, + &fxxxx_temp_attr[0][0], + ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps); } if (err) goto exit_unregister_sysfs; + + if (f71882fg_has_beep[data->type]) { + err = f71882fg_create_sysfs_files(pdev, + &fxxxx_temp_beep_attr[0][0], + ARRAY_SIZE(fxxxx_temp_beep_attr[0]) + * nr_temps); + if (err) + goto exit_unregister_sysfs; + } + + for (i = 0; i < F71882FG_MAX_INS; i++) { + if (f71882fg_has_in[data->type][i]) { + err = device_create_file(&pdev->dev, + &fxxxx_in_attr[i].dev_attr); + if (err) + goto exit_unregister_sysfs; + } + } + if (f71882fg_has_in1_alarm[data->type]) { + err = f71882fg_create_sysfs_files(pdev, + fxxxx_in1_alarm_attr, + ARRAY_SIZE(fxxxx_in1_alarm_attr)); + if (err) + goto exit_unregister_sysfs; + } } if (start_reg & 0x02) { + switch (data->type) { + case f71808e: + case f71869: + /* These always have signed auto point temps */ + data->auto_point_temp_signed = 1; + /* Fall through to select correct fan/pwm reg bank! */ + case f71889fg: + case f71889ed: |