diff --git a/CHANGES b/CHANGES index d66193ae..32d2eea8 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ ask CVS about it: Module i2c-sis630: Sync with 2.6.0-X driver version Module it87: Add pwm and "smart guardian" support Module lm90: Add ADM1032 support + Module w83781d: Fix 791d and 627hf detection Program pwmconfig: Handle multiple fans controlled by a single pwm Program sensors: Add ADM1032 support Program sensors-detect: Prefer Super I/O drivers; diff --git a/doc/chips/it87 b/doc/chips/it87 index 893b0eba..f24153ff 100644 --- a/doc/chips/it87 +++ b/doc/chips/it87 @@ -62,6 +62,7 @@ Module Parameters thermistor diode thermistor 0x2a ** default thermistor thermistor diode 0x1c thermistor thermistor thermistor 0x38 + As of release 2.8.2 the sensor type can be set at runtime. See below. * reset_it87: integer 1 if the registers of the chip should be reset at module load time, 0 to not reset the registers. Default is 0. * init: integer 1 if the registers should be initialized with the module's @@ -123,6 +124,12 @@ miss once-only alarms. The IT87xx only updates its values each 1.5 seconds; reading it more often will do no harm, but will return 'old' values. +The sensor type can be set at runtime as of release 2.8.2. +To change sensor x to a thermistor, 'echo 2 > sensorx' +where x is 1, 2, or 3. +To change sensor x to a thermal diode, 'echo 3 > sensorx'. +Any other value is invalid. + The fan speed control features can be enabled by setting the bits 0-2 of the fan_ctl register to 1. (Note: bits 6-4 of this register must be set to 1 to enable the fan monitoring). diff --git a/kernel/chips/it87.c b/kernel/chips/it87.c index 5b618043..94386d9e 100644 --- a/kernel/chips/it87.c +++ b/kernel/chips/it87.c @@ -132,6 +132,10 @@ static int init = 1; #define IT87_REG_CHIPID 0x58 +/* sensor pin types */ +#define INVALID 0 +#define THERMISTOR 2 +#define PIIDIODE 3 /* Conversions. Rounding and limit checking is only done on the TO_REG variants. Note that you should be a bit careful with which arguments @@ -267,6 +271,8 @@ struct it87_data { u8 fan_ctl[2]; /* Register encoding */ u8 sg_tl[3][5]; /* Register value */ u8 sg_pwm[3][3]; /* Register value */ + u8 sens[3]; /* 2 = Thermistor, + 3 = PII/Celeron diode */ }; @@ -302,6 +308,8 @@ static void it87_sgpwm(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); static void it87_sgtl(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); +static void it87_sens(struct i2c_client *client, int operation, + int ctl_name, int *nrels_mag, long *results); static struct i2c_driver it87_driver = { .owner = THIS_MODULE, @@ -341,7 +349,9 @@ static int it87_id = 0; #define IT87_SYSCTL_PWM3 1403 #define IT87_SYSCTL_FAN_CTL 1501 #define IT87_SYSCTL_FAN_ON_OFF 1502 - +#define IT87_SYSCTL_SENS1 1601 /* 1, 2, or Beta (3000-5000) */ +#define IT87_SYSCTL_SENS2 1602 +#define IT87_SYSCTL_SENS3 1603 #define IT87_ALARM_IN0 0x000100 #define IT87_ALARM_IN1 0x000200 @@ -424,6 +434,12 @@ static ctl_table it87_dir_table_template[] = { &i2c_sysctl_real, NULL, &it87_sgtl}, {IT87_SYSCTL_PWM3, "sg_tl3", NULL, 0, 0444, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &it87_sgtl}, + {IT87_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &i2c_proc_real, + &i2c_sysctl_real, NULL, &it87_sens}, + {IT87_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &i2c_proc_real, + &i2c_sysctl_real, NULL, &it87_sens}, + {IT87_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &i2c_proc_real, + &i2c_sysctl_real, NULL, &it87_sens}, {0} }; @@ -735,7 +751,7 @@ static void it87_init_client(struct i2c_client *client) static void it87_update_client(struct i2c_client *client) { struct it87_data *data = client->data; - int i; + int i, tmp, tmp2; down(&data->update_lock); @@ -809,6 +825,18 @@ static void it87_update_client(struct i2c_client *client) (it87_read_value(client, IT87_REG_ALARM3) << 16); data->fan_ctl[0] = it87_read_value(client, IT87_REG_FAN_CTRL); data->fan_ctl[1] = it87_read_value(client, IT87_REG_FAN_ONOFF); + + tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); + for(i = 0; i < 3; i++) { + tmp2 = (tmp >> i) & 0x09; + if(tmp2 == 0x01) + data->sens[i] = PIIDIODE; + else if(tmp2 == 0x09) + data->sens[i] = THERMISTOR; + else + data->sens[i] = INVALID; + } + data->last_updated = jiffies; data->valid = 1; } @@ -1084,6 +1112,46 @@ void it87_fan_ctl(struct i2c_client *client, int operation, int ctl_name, } } +void it87_sens(struct i2c_client *client, int operation, int ctl_name, + int *nrels_mag, long *results) +{ + struct it87_data *data = client->data; + int nr = 1 + ctl_name - IT87_SYSCTL_SENS1; + u8 tmp, val1, val2; + + if (operation == SENSORS_PROC_REAL_INFO) + *nrels_mag = 0; + else if (operation == SENSORS_PROC_REAL_READ) { + results[0] = data->sens[nr - 1]; + *nrels_mag = 1; + } else if (operation == SENSORS_PROC_REAL_WRITE) { + if (*nrels_mag >= 1) { + val1 = 0x01 << (nr - 1); + val2 = 0x08 << (nr - 1); + tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); + switch (results[0]) { + case PIIDIODE: + tmp &= ~ val2; + tmp |= val1; + break; + case THERMISTOR: + tmp &= ~ val1; + tmp |= val2; + break; + default: + printk + (KERN_ERR + "it87.o: Invalid sensor type %ld; must be 2 (thermistor) or 3 (diode)\n", + results[0]); + return; + } + it87_write_value(client, + IT87_REG_TEMP_ENABLE, tmp); + data->sens[nr - 1] = results[0]; + } + } +} + static int __init sm_it87_init(void) { printk("it87.o version %s (%s)\n", LM_VERSION, LM_DATE); diff --git a/lib/chips.c b/lib/chips.c index 62c163d3..b515724e 100644 --- a/lib/chips.c +++ b/lib/chips.c @@ -3766,6 +3766,12 @@ static sensors_chip_feature it87_features[] = 0 }, { SENSORS_IT87_ALARMS, "alarms", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, SENSORS_MODE_R, IT87_SYSCTL_ALARMS, VALUE(1), 0 }, + { SENSORS_IT87_SENS1, "sensor1", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, + SENSORS_MODE_RW, IT87_SYSCTL_SENS1, VALUE(1), 0 }, + { SENSORS_IT87_SENS2, "sensor2", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, + SENSORS_MODE_RW, IT87_SYSCTL_SENS2, VALUE(1), 0 }, + { SENSORS_IT87_SENS3, "sensor3", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, + SENSORS_MODE_RW, IT87_SYSCTL_SENS3, VALUE(1), 0 }, { 0 } }; diff --git a/lib/chips.h b/lib/chips.h index 1388b61f..1987fd44 100644 --- a/lib/chips.h +++ b/lib/chips.h @@ -1399,6 +1399,9 @@ #define SENSORS_IT87_ALARMS_VIN 82 /* R */ #define SENSORS_IT87_ALARMS_TEMP 83 /* R */ #define SENSORS_IT87_ALARMS 84 /* R */ +#define SENSORS_IT87_SENS1 91 /* RW */ +#define SENSORS_IT87_SENS2 92 /* RW */ +#define SENSORS_IT87_SENS3 93 /* RW */ /* fsc poseidon chip */ diff --git a/prog/sensors/chips.c b/prog/sensors/chips.c index 4b173715..71bf41c1 100644 --- a/prog/sensors/chips.c +++ b/prog/sensors/chips.c @@ -3019,7 +3019,7 @@ void print_eeprom(const sensors_chip_name *name) void print_it87(const sensors_chip_name *name) { char *label = NULL; - double cur, min, max, fdiv; + double cur, min, max, fdiv, sens; int alarms, valid; if (!sensors_get_feature(*name,SENSORS_IT87_ALARMS, &cur)) { @@ -3176,10 +3176,13 @@ void print_it87(const sensors_chip_name *name) if (!sensors_get_label_and_valid(*name,SENSORS_IT87_TEMP1,&label,&valid) && !sensors_get_feature(*name,SENSORS_IT87_TEMP1,&cur) && !sensors_get_feature(*name,SENSORS_IT87_TEMP1_LOW,&min) && + !sensors_get_feature(*name,SENSORS_IT87_SENS1,&sens) && !sensors_get_feature(*name,SENSORS_IT87_TEMP1_HIGH,&max)) { if (valid) { print_label(label,10); print_temp_info( cur, max, min, MINMAX, 0, 0); + printf(" sensor = %s ", (((int)sens)==3) ? "diode" : + (((int)sens)==2) ? "thermistor" : "invalid"); printf( " %s\n", alarms & IT87_ALARM_TEMP1 ? "ALARM" : "" ); } } else @@ -3188,10 +3191,13 @@ void print_it87(const sensors_chip_name *name) if (!sensors_get_label_and_valid(*name,SENSORS_IT87_TEMP2,&label,&valid) && !sensors_get_feature(*name,SENSORS_IT87_TEMP2,&cur) && !sensors_get_feature(*name,SENSORS_IT87_TEMP2_LOW,&min) && + !sensors_get_feature(*name,SENSORS_IT87_SENS2,&sens) && !sensors_get_feature(*name,SENSORS_IT87_TEMP2_HIGH,&max)) { if (valid) { print_label(label,10); print_temp_info( cur, max, min, MINMAX, 0, 0); + printf(" sensor = %s ", (((int)sens)==3) ? "diode" : + (((int)sens)==2) ? "thermistor" : "invalid"); printf( " %s\n", alarms & IT87_ALARM_TEMP2 ? "ALARM" : "" ); } } else @@ -3200,10 +3206,13 @@ void print_it87(const sensors_chip_name *name) if (!sensors_get_label_and_valid(*name,SENSORS_IT87_TEMP3,&label,&valid) && !sensors_get_feature(*name,SENSORS_IT87_TEMP3,&cur) && !sensors_get_feature(*name,SENSORS_IT87_TEMP3_LOW,&min) && + !sensors_get_feature(*name,SENSORS_IT87_SENS3,&sens) && !sensors_get_feature(*name,SENSORS_IT87_TEMP3_HIGH,&max)) { if (valid) { print_label(label,10); print_temp_info( cur, max, min, MINMAX, 0, 0); + printf(" sensor = %s ", (((int)sens)==3) ? "diode" : + (((int)sens)==2) ? "thermistor" : "invalid"); printf( " %s\n", alarms & IT87_ALARM_TEMP3 ? "ALARM" : "" ); } } else