From bf8d5f1305ac17ef6c74fb20b17eafa4b0ec7c81 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 9 Jan 2004 21:26:54 +0000 Subject: [PATCH] Change the way the lm90 driver handles hysteresis. Now similar to the 2.6 version of the driver. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2210 7894878c-1315-0410-8ee3-d5d059ff63e0 --- kernel/chips/lm90.c | 53 +++++++++++++++++++++++++++++++++++++------- lib/chips.c | 9 +++++--- lib/chips.h | 3 ++- prog/sensors/chips.c | 37 +++++++------------------------ 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/kernel/chips/lm90.c b/kernel/chips/lm90.c index 7702a21e..718cdfe7 100644 --- a/kernel/chips/lm90.c +++ b/kernel/chips/lm90.c @@ -130,7 +130,9 @@ static void lm90_local_tcrit(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); static void lm90_remote_tcrit(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); -static void lm90_hyst(struct i2c_client *client, int operation, +static void lm90_local_hyst(struct i2c_client *client, int operation, + int ctl_name, int *nrels_mag, long *results); +static void lm90_remote_hyst(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); static void lm90_alarms(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); @@ -164,7 +166,7 @@ struct lm90_data u8 local_temp, local_high, local_low; u16 remote_temp, remote_high, remote_low; /* combined */ u8 local_crit, remote_crit; - u8 hyst; + u8 hyst; /* linked to two sysctl files (hyst1 RW, hyst2 RO) */ u16 alarms; /* bitvector, combined */ }; @@ -179,7 +181,8 @@ struct lm90_data #define LM90_SYSCTL_REMOTE_TEMP 1201 #define LM90_SYSCTL_LOCAL_TCRIT 1204 #define LM90_SYSCTL_REMOTE_TCRIT 1205 -#define LM90_SYSCTL_HYST 1207 +#define LM90_SYSCTL_LOCAL_HYST 1207 +#define LM90_SYSCTL_REMOTE_HYST 1208 #define LM90_SYSCTL_ALARMS 1210 #define LM90_ALARM_LOCAL_HIGH 0x40 @@ -203,8 +206,10 @@ static ctl_table lm90_dir_table_template[] = &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_local_tcrit}, {LM90_SYSCTL_REMOTE_TCRIT, "tcrit2", NULL, 0, 0644, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_remote_tcrit}, - {LM90_SYSCTL_HYST, "hyst", NULL, 0, 0644, NULL, - &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_hyst}, + {LM90_SYSCTL_LOCAL_HYST, "hyst1", NULL, 0, 0644, NULL, + &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_local_hyst}, + {LM90_SYSCTL_REMOTE_HYST, "hyst2", NULL, 0, 0444, NULL, + &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_remote_hyst}, {LM90_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real, &i2c_sysctl_real, NULL, &lm90_alarms}, {0} @@ -633,7 +638,22 @@ static void lm90_remote_tcrit(struct i2c_client *client, int operation, } } -static void lm90_hyst(struct i2c_client *client, int operation, +/* + * One quick note about hysteresis. Internally, the hysteresis value + * is held in a single register by the LM90, as a relative value. + * This relative value applies to both the local critical temperature + * and the remote critical temperature. Since all temperatures exported + * through procfs have to be absolute, we have to do some conversions. + * The solution retained here is to export two absolute values, one for + * each critical temperature. In order not to confuse the users too + * much, only one file is writable. Would we fail to do so, users + * would probably attempt to write to both files, as if they were + * independant, and since they aren't, they wouldn't understand why + * setting one affects the other one (and would probably claim there's + * a bug in the driver). + */ + +static void lm90_local_hyst(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results) { struct lm90_data *data = client->data; @@ -643,20 +663,37 @@ static void lm90_hyst(struct i2c_client *client, int operation, else if (operation == SENSORS_PROC_REAL_READ) { lm90_update_client(client); - results[0] = TEMP1_FROM_REG(data->hyst); + results[0] = TEMP1_FROM_REG(data->local_crit) - + TEMP1_FROM_REG(data->hyst); *nrels_mag = 1; } else if (operation == SENSORS_PROC_REAL_WRITE) { if (*nrels_mag >= 1) { - data->hyst = HYST_TO_REG(results[0]); + data->hyst = HYST_TO_REG(data->local_crit - results[0]); i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST, data->hyst); } } } +static void lm90_remote_hyst(struct i2c_client *client, int operation, + int ctl_name, int *nrels_mag, long *results) +{ + struct lm90_data *data = client->data; + + if (operation == SENSORS_PROC_REAL_INFO) + *nrels_mag = 0; /* magnitude */ + else if (operation == SENSORS_PROC_REAL_READ) + { + lm90_update_client(client); + results[0] = TEMP1_FROM_REG(data->remote_crit) - + TEMP1_FROM_REG(data->hyst); + *nrels_mag = 1; + } +} + static void lm90_alarms(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results) { diff --git a/lib/chips.c b/lib/chips.c index 62179a46..34fa292c 100644 --- a/lib/chips.c +++ b/lib/chips.c @@ -727,9 +727,12 @@ static sensors_chip_feature lm90_features[] = { SENSORS_LM90_REMOTE_TCRIT, "tcrit2", SENSORS_LM90_REMOTE_TEMP, SENSORS_LM90_REMOTE_TEMP, RW, LM90_SYSCTL_REMOTE_TCRIT, VALUE(1), 0 }, - { SENSORS_LM90_TCRIT_HYST, "hyst", - NOMAP, NOMAP, - RW, LM90_SYSCTL_HYST, VALUE(1), 0, "temp_hyst2", 3 }, + { SENSORS_LM90_LOCAL_TCRIT_HYST, "hyst1", + SENSORS_LM90_LOCAL_TCRIT, SENSORS_LM90_LOCAL_TCRIT, + RW, LM90_SYSCTL_LOCAL_HYST, VALUE(1), 0 }, + { SENSORS_LM90_REMOTE_TCRIT_HYST, "hyst2", + SENSORS_LM90_REMOTE_TCRIT, SENSORS_LM90_REMOTE_TCRIT, + R, LM90_SYSCTL_REMOTE_HYST, VALUE(1), 0 }, { SENSORS_LM90_ALARMS, "alarms", NOMAP, NOMAP, R, LM90_SYSCTL_ALARMS, VALUE(1), 0 }, diff --git a/lib/chips.h b/lib/chips.h index b6625e6e..6a63e0a1 100644 --- a/lib/chips.h +++ b/lib/chips.h @@ -456,7 +456,8 @@ #define SENSORS_LM90_REMOTE_HIGH 58 /* RW */ #define SENSORS_LM90_REMOTE_LOW 59 /* RW */ #define SENSORS_LM90_REMOTE_TCRIT 60 /* RW */ -#define SENSORS_LM90_TCRIT_HYST 79 /* RW */ +#define SENSORS_LM90_LOCAL_TCRIT_HYST 79 /* RW */ +#define SENSORS_LM90_REMOTE_TCRIT_HYST 80 /* R, see driver source */ #define SENSORS_LM90_ALARMS 81 /* R */ /* Winbond W83781D chips */ diff --git a/prog/sensors/chips.c b/prog/sensors/chips.c index 17115311..e9390f32 100644 --- a/prog/sensors/chips.c +++ b/prog/sensors/chips.c @@ -4579,36 +4579,13 @@ void print_lm90(const sensors_chip_name *name) printf("ERROR: Can't get remote temperature data!\n"); free_the_label(&label); - /* 2.6 tweak: - * In 2.4 there is only one, relative hyst value, (default 10). - * In 2.6 there are two, absolute values. - * The library will link hyst (2.4) to temp_hyst2 (2.6) and we have - * to compute the relative value from temp_hyst2 and temp_crit2. - * We detect that using the following rules: - * - if hyst is not in the range 0..31, it is absolute (2.6); - * - if hyst exceeds tcrit1 or tcrit2, it is absolute (2.6); - * - if hyst is greater than it would be if considered absolute, - * it is absolute (heuristic); - * - else it is relative (2.4). - * Also note that the use of low and high right below is - * arbitrary, only to reuse previously defined variables, at the - * admitted cost of a lower readability. - */ - if (!sensors_get_feature(*name, SENSORS_LM90_TCRIT_HYST, &hyst) - && !sensors_get_feature(*name, SENSORS_LM90_LOCAL_TCRIT, &low) - && !sensors_get_feature(*name, SENSORS_LM90_REMOTE_TCRIT, &high)) { - if (hyst<=-0.5 || hyst>=31.5 || hyst>low || hyst>high || hyst>high-hyst) - hyst = high-hyst; - } else { - printf("ERROR: Can't get hyst data!\n"); - hyst = 10; - } - if (!sensors_get_label_and_valid(*name, SENSORS_LM90_LOCAL_TCRIT, - &label, &valid)) { + &label, &valid) + && !sensors_get_feature(*name, SENSORS_LM90_LOCAL_TCRIT, &high) + && !sensors_get_feature(*name, SENSORS_LM90_LOCAL_TCRIT_HYST, &hyst)) { if (valid) { print_label(label, 10); - print_temp_info(low, low-hyst, 0, HYSTONLY, 0, 0); + print_temp_info(high, hyst, 0, HYSTONLY, 0, 0); printf("\n"); } } else @@ -4616,10 +4593,12 @@ void print_lm90(const sensors_chip_name *name) free_the_label(&label); if (!sensors_get_label_and_valid(*name, SENSORS_LM90_REMOTE_TCRIT, - &label, &valid)) { + &label, &valid) + && !sensors_get_feature(*name, SENSORS_LM90_REMOTE_TCRIT, &high) + && !sensors_get_feature(*name, SENSORS_LM90_REMOTE_TCRIT_HYST, &hyst)) { if (valid) { print_label(label, 10); - print_temp_info(high, high-hyst, 0, HYSTONLY, 0, 0); + print_temp_info(high, hyst, 0, HYSTONLY, 0, 0); printf("\n"); } } else