From a41a6d70ab13bf8cef02fe6dba2df148cc221e80 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 20 Apr 2004 17:55:10 +0000 Subject: [PATCH] Fix fan speed computations. Fix voltage magnitudes. Fix voltage limits order. Add voltage limits write support. Add temperature limits write support. Prevent user from setting limit of nonexistent fan 3. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2460 7894878c-1315-0410-8ee3-d5d059ff63e0 --- kernel/chips/pc87360.c | 51 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/kernel/chips/pc87360.c b/kernel/chips/pc87360.c index 7f9a6cc8..f0b00458 100644 --- a/kernel/chips/pc87360.c +++ b/kernel/chips/pc87360.c @@ -97,9 +97,9 @@ static inline void superio_exit(void) #define PC87360_REG_FAN_STATUS(nr) (0x08 + 3 * (nr)) #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0: \ - 960000/((val)*(div))) + 480000/((val)*(div))) #define FAN_TO_REG(val,div) ((val)<=0?255: \ - 960000/((val)*(div))) + 480000/((val)*(div))) #define FAN_DIV_FROM_REG(val) (1 << ((val >> 5) & 0x03)) #define FAN_DIV_TO_REG(val) ((val)==8?0x60:(val)==4?0x40:(val)==1?0x00:0x20) #define FAN_STATUS_FROM_REG(val) ((val) & 0x07) @@ -118,7 +118,9 @@ static inline void superio_exit(void) #define PC87365_REG_IN_ALARMS1 0x00 #define PC87365_REG_IN_ALARMS2 0x01 -#define IN_FROM_REG(val) (((val) * 2967 + 127) / 255) +#define IN_FROM_REG(val) (((val) * 297 + 127) / 255) +#define IN_TO_REG(val) ((val)<0?0:(val)>297?255: \ + ((val) * 255 + 148) / 297) #define IN_STATUS_FROM_REG(val) ((val) & 0x86) /* @@ -136,6 +138,8 @@ static inline void superio_exit(void) #define PC87365_REG_TEMP_ALARMS 0x00 #define TEMP_FROM_REG(val) ((val)&0x80 ? (val) : (val) - 128) +#define TEMP_TO_REG(val) ((val)<-128?0x80:(val)>127?0x7F: \ + (val)<0?(val)+0x80:(val)) #define TEMP_STATUS_FROM_REG(val) ((val) & 0xCE) struct pc87360_data { @@ -658,6 +662,8 @@ void pc87360_fan(struct i2c_client *client, int operation, int ctl_name, } /* We ignore National's recommendation */ else if (operation == SENSORS_PROC_REAL_WRITE) { + if (nr >= data->fannr) + return; if (*nrels_mag >= 1) { data->fan_min[nr] = FAN_TO_REG(results[0], FAN_DIV_FROM_REG(data->fan_status[nr])); @@ -745,14 +751,27 @@ void pc87365_in(struct i2c_client *client, int operation, int ctl_name, int nr = ctl_name - PC87365_SYSCTL_IN0; if (operation == SENSORS_PROC_REAL_INFO) - *nrels_mag = 3; + *nrels_mag = 2; else if (operation == SENSORS_PROC_REAL_READ) { pc87360_update_client(client); - results[0] = IN_FROM_REG(data->in_max[nr]); - results[1] = IN_FROM_REG(data->in_min[nr]); + results[0] = IN_FROM_REG(data->in_min[nr]); + results[1] = IN_FROM_REG(data->in_max[nr]); results[2] = IN_FROM_REG(data->in[nr]); *nrels_mag = 3; } + else if (operation == SENSORS_PROC_REAL_WRITE) { + if (*nrels_mag >= 1) { + data->in_min[nr] = IN_TO_REG(results[0]); + pc87360_write_value(data, 1, PC87365_REG_IN_BANK, nr); + pc87360_write_value(data, 1, PC87365_REG_IN_MIN, + data->in_min[nr]); + } + if (*nrels_mag >= 2) { + data->in_max[nr] = IN_TO_REG(results[1]); + pc87360_write_value(data, 1, PC87365_REG_IN_MAX, + data->in_max[nr]); + } + } } void pc87365_in_status(struct i2c_client *client, int operation, int ctl_name, @@ -786,6 +805,26 @@ void pc87365_temp(struct i2c_client *client, int operation, int ctl_name, results[2] = TEMP_FROM_REG(data->temp[nr]); *nrels_mag = 4; } + else if (operation == SENSORS_PROC_REAL_WRITE) { + if (nr >= data->tempnr) + return; + if (*nrels_mag >= 1) { + pc87360_write_value(data, 2, PC87365_REG_TEMP_BANK, nr); + data->temp_max[nr] = TEMP_TO_REG(results[0]); + pc87360_write_value(data, 2, PC87365_REG_TEMP_MAX, + data->temp_max[nr]); + } + if (*nrels_mag >= 2) { + data->temp_min[nr] = TEMP_TO_REG(results[1]); + pc87360_write_value(data, 2, PC87365_REG_TEMP_MAX, + data->temp_max[nr]); + } + if (*nrels_mag >= 3) { + data->temp_crit[nr] = TEMP_TO_REG(results[2]); + pc87360_write_value(data, 2, PC87365_REG_TEMP_CRIT, + data->temp_crit[nr]); + } + } } void pc87365_temp_status(struct i2c_client *client, int operation, int ctl_name,