From 739a87e78514f18d43f13308d9869753df2dd529 Mon Sep 17 00:00:00 2001 From: "Mark D. Studebaker" Date: Sun, 29 Jul 2001 00:30:54 +0000 Subject: [PATCH] Apply patch from David Gesswein: The following patch does the following: Fixed bug with not all alarms enabled. Added ability to read battery voltage Select temperature sensor type at module load time. Added setting for Inside Technologies 786LCD board to example config file I also fixed what looked like a typo in the existing it87 section where in6_min/max was set twice and in7 was not set. As commented I think the equation for the negative voltages are wrong but without that motherboard I can't verify. With the 786LCD board sensors-detect reports a lm78 which doesn't exist and a sis5595 which may be part of the SIS630 chip but doesn't perform the monitoring. The it8705F/SIS950 which is on the board is reported as a misdetect. I didn't know enough about the various chips to figure out how to get correct detections. David Gesswein git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@1146 7894878c-1315-0410-8ee3-d5d059ff63e0 --- doc/chips/it87 | 23 ++++++++++++-- etc/sensors.conf.eg | 67 ++++++++++++++++++++++++++++++++++++++-- kernel/chips/it87.c | 55 +++++++++++++++++++++++++++------ kernel/include/sensors.h | 1 + lib/chips.c | 2 ++ lib/chips.h | 1 + prog/sensors/chips.c | 9 ++++++ 7 files changed, 144 insertions(+), 14 deletions(-) diff --git a/doc/chips/it87 b/doc/chips/it87 index d3fd4ea3..3d39a2f3 100644 --- a/doc/chips/it87 +++ b/doc/chips/it87 @@ -13,6 +13,8 @@ Supported chips: * Sis950 [clone of IT8705F] ISA 0x290 Datasheet: Publicly available at the SIS website + Appears to no longer be available on SIS website, found at + http://ic.doma.kiev.ua/pdf/chip/sio.htm Author: Christophe Gauthron @@ -30,7 +32,23 @@ Module Parameters List of adapter,address pairs to scan additionally * probe_range: short array (min = 1, max = 48) List of adapter,start-addr,end-addr triples to scan additionally - +* update_vbat: integer 0 if vbat should report power on value, 1 if + vbat should be updated after each read. Default is 0. + On some boards the battery voltage is provided by either the battery or + the onboard power supply. Only the first reading at power on will be + the actual battery voltage (which the chip does automatically). On other + boards the battery voltage is always fed to the chip so can be read at + any time. Excessive reading may decrease battery life but no information + is given in the datasheet. +* temp_type: integer bit mask + bit 0: Temp sensor 1 is thermal diode + bit 1: Temp sensor 2 is thermal diode + bit 2: Temp sensor 3 is thermal diode + bit 3: Temp sensor 1 is thermal resistor + bit 4: Temp sensor 2 is thermal resistor + bit 5: Temp sensor 3 is thermal resistor + For each sensor either the diode or resistor bit should be set, not both. + Default is temp sensor 1 and 3 resistor, 2 diode (value 0x2a) Description ----------- @@ -64,7 +82,7 @@ An alarm is triggered if the voltage has crossed a programmable minimum or maximum limit. Note that minimum in this case always means 'closest to zero'; this is important for negative voltage measurements. All voltage inputs can measure voltages between 0 and 4.08 volts, with a resolution -of 0.016 volt. +of 0.016 volt. The battery voltage in8 does not have limit registers. The VID lines (IT8712F only) encode the core voltage value: the voltage level your processor should work with. This is hardcoded by the mainboard and/or @@ -94,6 +112,7 @@ Chip `it87` in5 NONE NONE R 2 in6 NONE NONE R 2 in7 NONE NONE R 2 + in8 NONE NONE R 2 in0_min in0 in0 RW 2 in1_min in1 in1 RW 2 in2_min in2 in2 RW 2 diff --git a/etc/sensors.conf.eg b/etc/sensors.conf.eg index ce543243..5718275b 100644 --- a/etc/sensors.conf.eg +++ b/etc/sensors.conf.eg @@ -122,6 +122,8 @@ # formula (Rin,Rf: resistor values, Vs: read voltage, Vin: pin voltage) # Rin = (Vs * Rf) / Vin # +# Note: Some chips use a different formula, see it87 section for example. +# # Here are the official LM78 and LM79 data sheet values. # Vs R1,Rin R2,Rf Vin # in3 +5.0 6.8 10 +2.98 @@ -1023,15 +1025,23 @@ chip "it87-*" set in5_max -12 * 1.05 set in6_min -5 * 0.95 set in6_max -5 * 1.05 - set in6_min -5 * 0.95 - set in6_max -5 * 1.05 + set in7_min 5 * 0.95 + set in7_max 5 * 1.05 # vid not monitored by IT8705F ignore vid +# For this family of chips the negative voltage equation is different from +# the lm78. The chip uses two external resistor for scaling but one is +# tied to a positive reference voltage. See ITE8705F datasheet (SIS950 +# data sheet is wrong) +# Vs = (1 + Rin/Rf) * Vin - (Rin/Rf) * Vref. +# Vref = 4.096 volts, Vin is voltage measured, Vs is actual voltage. + compute in2 (1 + 1)*@ , @/(1 + 1) compute in3 ((6.8/10)+1)*@ , @/((6.8/10)+1) compute in4 ((30/10) +1)*@ , @/((30/10) +1) +# Since these have the wrong equation form they are probably not correct compute in5 -(72/10)*@ , -@/(72/10) compute in6 -(56/10)*@ , -@/(56/10) compute in7 ((6.8/10)+1)*@ , @/((6.8/10)+1) @@ -1054,3 +1064,56 @@ chip "it87-*" set fan2_min 3000 ignore fan3 +# The following is for the Inside Technologies 786LCD which uses either a +# IT8705F or a SIS950 for monitoring with the SIS630. +# You will need to load the it87 module as follows to select the correct +# temperature sensor type. +# modprobe it87 temp_type=0x31 +# The sensors-detect program reports lm78 and a sis5595 and lists the it87 as +# a misdetect. Don't do the modprobe for the lm78 or sis5595 as suggested. +# +# delete or comment out above it87 section and uncomment the following. +#chip "it87-*" +# label in0 "VCore 1" +# label in1 "VCore 2" +# label in2 "+3.3V" +# label in3 "+5V" +# label in4 "+12V" +# label in5 "3.3 Stdby" +# label in6 "-12V" +# label in7 "Stdby" +# label in8 "VBat" + # in0 will depend on your processor VID value, set to voltage specified in + # bios setup screen +# set in0_min 1.7 * 0.95 +# set in0_max 1.7 * 1.05 +# set in1_min 2.4 +# set in1_max 2.6 +# set in2_min 3.3 * 0.95 +# set in2_max 3.3 * 1.05 +# set in3_min 5.0 * 0.95 +# set in3_max 5.0 * 1.05 + # +- 12V are very poor tolerance on this board. Verified with voltmeter +# set in4_min 12 * 0.90 +# set in4_max 12 * 1.10 +# set in5_min 3.3 * 0.95 +# set in5_max 3.3 * 1.05 +# set in6_max -12 * 0.90 +# set in6_min -12 * 1.10 +# set in7_min 5 * 0.95 +# set in7_max 5 * 1.05 + # vid not monitored by IT8705F +# ignore vid + +# compute in3 ((6.8/10)+1)*@ , @/((6.8/10)+1) +# compute in4 ((30/10) +1)*@ , @/((30/10) +1) +# compute in6 (1+232/56)*@ - 4.096*232/56, (@ + 4.096*232/56)/(1+232/56) +# compute in7 ((6.8/10)+1)*@ , @/((6.8/10)+1) + # Temperature +# label temp1 "CPU Temp" +# ignore temp2 +# ignore temp3 + # Fans +# set fan1_min 3000 +# ignore fan2 +# ignore fan3 diff --git a/kernel/chips/it87.c b/kernel/chips/it87.c index 710ca50c..b5891e2a 100644 --- a/kernel/chips/it87.c +++ b/kernel/chips/it87.c @@ -24,6 +24,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + djg@pdp8.net David Gesswein 7/18/01 + Modified to fix bug with not all alarms enabled. + Added ability to read battery voltage and select temperature sensor + type at module load time. +*/ + #include #include #include @@ -56,6 +63,16 @@ static unsigned int normal_isa_range[] = { SENSORS_ISA_END }; /* Insmod parameters */ SENSORS_INSMOD_1(it87); + +/* Update battery voltage after every reading if true */ +static int update_vbat = 0; + + +/* Enable Temp1 as thermal resistor */ +/* Enable Temp2 as thermal diode */ +/* Enable Temp3 as thermal resistor */ +static int temp_type = 0x2a; + /* Many IT87 constants specified below */ /* Length of ISA address segment */ @@ -76,7 +93,7 @@ SENSORS_INSMOD_1(it87); #define IT87_REG_VID 0x0a #define IT87_REG_FAN_DIV 0x0b -/* Monitors: 8 voltage (0 to 7), 3 temp (1 to 3), 3 fan (1 to 3) */ +/* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ #define IT87_REG_FAN(nr) (0x0c + (nr)) #define IT87_REG_FAN_MIN(nr) (0x0f + (nr)) @@ -201,9 +218,9 @@ struct it87_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ - u8 in[8]; /* Register value */ - u8 in_max[8]; /* Register value */ - u8 in_min[8]; /* Register value */ + u8 in[9]; /* Register value */ + u8 in_max[9]; /* Register value */ + u8 in_min[9]; /* Register value */ u8 fan[3]; /* Register value */ u8 fan_min[3]; /* Register value */ u8 temp[3]; /* Register value */ @@ -297,6 +314,8 @@ static ctl_table it87_dir_table_template[] = { &i2c_sysctl_real, NULL, &it87_in}, {IT87_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &it87_in}, + {IT87_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL, &i2c_proc_real, + &i2c_sysctl_real, NULL, &it87_in}, {IT87_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &it87_fan}, {IT87_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real, @@ -606,6 +625,7 @@ void it87_init_client(struct i2c_client *client) IN_TO_REG(IT87_INIT_IN_MIN_7)); it87_write_value(client, IT87_REG_VIN_MAX(7), IN_TO_REG(IT87_INIT_IN_MAX_7)); + /* Note: Battery voltage does not have limit registers */ it87_write_value(client, IT87_REG_FAN_MIN(1), FAN_TO_REG(IT87_INIT_FAN_MIN_1, 2)); it87_write_value(client, IT87_REG_FAN_MIN(2), @@ -628,11 +648,10 @@ void it87_init_client(struct i2c_client *client) /* Enable voltage monitors */ it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff); - /* Enable Temo1 as thermal resistor */ - /* Enable Temp2 as thermal diode */ + /* Enable Temp1-Temp3 */ it87_write_value(client, IT87_REG_TEMP_ENABLE, (it87_read_value(client, IT87_REG_TEMP_ENABLE) & 0xc0) - | 0x0a); + | (temp_type & 0x3f)); /* Enable fans */ it87_write_value(client, IT87_REG_FAN_CTRL, @@ -642,8 +661,7 @@ void it87_init_client(struct i2c_client *client) /* Start monitoring */ it87_write_value(client, IT87_REG_CONFIG, (it87_read_value(client, IT87_REG_CONFIG) & 0xb7) - | 0x01); - + | (update_vbat ? 0x41 : 0x01)); } void it87_update_client(struct i2c_client *client) @@ -656,6 +674,12 @@ void it87_update_client(struct i2c_client *client) if ((jiffies - data->last_updated > HZ + HZ / 2) || (jiffies < data->last_updated) || !data->valid) { + if (update_vbat) { + /* Cleared after each update, so reenable. Value + returned by this read will be previous value */ + it87_write_value(client, IT87_REG_CONFIG, + it87_read_value(client, IT87_REG_CONFIG) | 0x40); + } for (i = 0; i <= 7; i++) { data->in[i] = it87_read_value(client, IT87_REG_VIN(i)); @@ -664,6 +688,13 @@ void it87_update_client(struct i2c_client *client) data->in_max[i] = it87_read_value(client, IT87_REG_VIN_MAX(i)); } + data->in[8] = + it87_read_value(client, IT87_REG_VIN(8)); + /* Temperature sensor doesn't have limit registers, set + to min and max value */ + data->in_min[8] = 0; + data->in_max[8] = 255; + for (i = 1; i <= 3; i++) { data->fan[i - 1] = it87_read_value(client, IT87_REG_FAN(i)); @@ -696,7 +727,7 @@ void it87_update_client(struct i2c_client *client) data->alarms_fan = it87_read_value(client, IT87_REG_ALARM1) & 0x7; data->alarms_vin = - it87_read_value(client, IT87_REG_ALARM2) & 0xf; + it87_read_value(client, IT87_REG_ALARM2) & 0xff; data->alarms_temp = it87_read_value(client, IT87_REG_ALARM3) & 0x7; @@ -926,6 +957,10 @@ EXPORT_NO_SYMBOLS; MODULE_AUTHOR("Chris Gauthron "); MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver"); +MODULE_PARM(update_vbat, "i"); +MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); +MODULE_PARM(temp_type, "i"); +MODULE_PARM_DESC(temp_type, "Temperature sensor type, normally leave unset"); int init_module(void) { diff --git a/kernel/include/sensors.h b/kernel/include/sensors.h index 29fa2c4e..ac67e3ad 100644 --- a/kernel/include/sensors.h +++ b/kernel/include/sensors.h @@ -478,6 +478,7 @@ #define IT87_SYSCTL_IN5 1005 #define IT87_SYSCTL_IN6 1006 #define IT87_SYSCTL_IN7 1007 +#define IT87_SYSCTL_IN8 1008 #define IT87_SYSCTL_FAN1 1101 /* Rotations/min */ #define IT87_SYSCTL_FAN2 1102 #define IT87_SYSCTL_FAN3 1103 diff --git a/lib/chips.c b/lib/chips.c index 9a11f127..a33e057b 100644 --- a/lib/chips.c +++ b/lib/chips.c @@ -2146,6 +2146,8 @@ static sensors_chip_feature it87_features[] = SENSORS_MODE_R, IT87_SYSCTL_IN6, VALUE(3), 2 }, { SENSORS_IT87_IN7, "in7", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, SENSORS_MODE_R, IT87_SYSCTL_IN7, VALUE(3), 2 }, + { SENSORS_IT87_IN8, "in8", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, + SENSORS_MODE_R, IT87_SYSCTL_IN8, VALUE(3), 2 }, { SENSORS_IT87_IN0_MIN, "in0_min", SENSORS_IT87_IN0, SENSORS_IT87_IN0, SENSORS_MODE_RW, IT87_SYSCTL_IN0, VALUE(1), 2 }, { SENSORS_IT87_IN1_MIN, "in1_min", SENSORS_IT87_IN1, SENSORS_IT87_IN1, diff --git a/lib/chips.h b/lib/chips.h index 9febea0b..3c6b31ab 100644 --- a/lib/chips.h +++ b/lib/chips.h @@ -981,6 +981,7 @@ #define SENSORS_IT87_IN5 6 /* R */ #define SENSORS_IT87_IN6 7 /* R */ #define SENSORS_IT87_IN7 8 /* R */ +#define SENSORS_IT87_IN8 9 /* R */ #define SENSORS_IT87_IN0_MIN 11 /* RW */ #define SENSORS_IT87_IN1_MIN 12 /* RW */ #define SENSORS_IT87_IN2_MIN 13 /* RW */ diff --git a/prog/sensors/chips.c b/prog/sensors/chips.c index e13d6704..7c13665f 100644 --- a/prog/sensors/chips.c +++ b/prog/sensors/chips.c @@ -2554,6 +2554,15 @@ void print_it87(const sensors_chip_name *name) } else printf("ERROR: Can't get IN7 data!\n"); free_the_label(&label); + if (!sensors_get_label_and_valid(*name,SENSORS_IT87_IN8,&label,&valid) && + !sensors_get_feature(*name,SENSORS_IT87_IN8,&cur)) { + if (valid) { + print_label(label,10); + printf("%+6.2f V\n", cur); + } + } else + printf("ERROR: Can't get IN8 data!\n"); + free_the_label(&label); if (!sensors_get_label_and_valid(*name,SENSORS_IT87_FAN1,&label,&valid) && !sensors_get_feature(*name,SENSORS_IT87_FAN1,&cur) &&