From 41c6e871a49d40edb29eb78f80e8ae0be5874737 Mon Sep 17 00:00:00 2001 From: Kyosti Malkki Date: Thu, 22 Jul 1999 16:43:37 +0000 Subject: [PATCH] =?UTF-8?q?(Ky=C3=B6sti)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Restructured iteration code for rev 0x00 Two modes already: 0 no iteration, no delay, reads only vin3, vin0-2 = 0 1 does iteration, delays reads approx. 8 seconds To be added: 2 does iteration in background, no delay for user apps In this mode the results of the last iteration loop are shown, and then a new iteration loop is triggered. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@510 7894878c-1315-0410-8ee3-d5d059ff63e0 --- kernel/chips/gl518sm.c | 130 ++++++++++++++++++++++------------------- kernel/chips/gl520sm.c | 1 + 2 files changed, 70 insertions(+), 61 deletions(-) diff --git a/kernel/chips/gl518sm.c b/kernel/chips/gl518sm.c index 15f3d3c5..ac27f715 100644 --- a/kernel/chips/gl518sm.c +++ b/kernel/chips/gl518sm.c @@ -24,6 +24,7 @@ #include #include #include "sensors.h" +#include "i2c-isa.h" #include "version.h" #include "compat.h" @@ -149,6 +150,7 @@ struct gl518_data { u8 voltage[4]; /* Register values; [0] = VDD */ u8 voltage_min[4]; /* Register values; [0] = VDD */ u8 voltage_max[4]; /* Register values; [0] = VDD */ + u8 iter_voltage[4]; /* Register values; [0] = VDD */ u8 fan[2]; u8 fan_min[2]; u8 temp; /* Register values */ @@ -161,17 +163,9 @@ struct gl518_data { u8 fan1conf; /* Fan1 on/off control */ }; -/* load time parameter that says if we want to spend 10 seconds for - reading all voltages from a GL518 rev 0, or if we want to read zeros */ -static int readall = 0; - #ifdef MODULE extern int init_module(void); extern int cleanup_module(void); -MODULE_PARM(readall,"i"); -MODULE_PARM_DESC(readall,"Enable the experimental code, which tries to find " - "the voltages of revision zero chips by " - "slow (10 seconds) iteration"); #endif /* MODULE */ static int gl518_init(void); @@ -189,6 +183,7 @@ static int gl518_read_value(struct i2c_client *client, u8 reg); static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value); static void gl518_update_client(struct i2c_client *client); static void gl518_update_client_rev00(struct i2c_client *client); +static void gl518_update_vins(struct i2c_client *client); static void gl518_vin(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); @@ -373,6 +368,7 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) data->sysctl_id = i; /* Initialize the GL518SM chip */ + data->iterate = 0; gl518_init_client((struct i2c_client *) new_client); return 0; @@ -396,8 +392,6 @@ ERROR0: /* Called when we have found a new GL518SM. It should set limits, etc. */ void gl518_init_client(struct i2c_client *client) { - struct gl518_data *data = client->data; - /* Power-on defaults (bit 7=1) */ gl518_write_value(client,GL518_REG_CONF,0x80); @@ -433,8 +427,6 @@ void gl518_init_client(struct i2c_client *client) /* Clear status register (bit 5=1), start (bit6=1) */ gl518_write_value(client,GL518_REG_CONF,0x24); gl518_write_value(client,GL518_REG_CONF,0x44); - - data->iterate=readall; } int gl518_detach_client(struct i2c_client *client) @@ -543,21 +535,6 @@ void gl518_update_client(struct i2c_client *client) data->voltage_min[3] = val & 0xff; data->voltage_max[3] = (val >> 8) & 0xff; - data->voltage[3] = gl518_read_value(client,GL518_REG_VIN3); -#ifndef DEBUG_VIN - if (data->type != gl518sm_r00) { - data->voltage[0] = gl518_read_value(client,GL518_REG_VDD); - data->voltage[1] = gl518_read_value(client,GL518_REG_VIN1); - data->voltage[2] = gl518_read_value(client,GL518_REG_VIN2); - } else - gl518_update_client_rev00(client); -#else - data->voltage[0] = gl518_read_value(client,GL518_REG_VDD); - data->voltage[1] = gl518_read_value(client,GL518_REG_VIN1); - data->voltage[2] = gl518_read_value(client,GL518_REG_VIN2); - gl518_update_client_rev00(client); -#endif - val = gl518_read_value(client,GL518_REG_FAN_COUNT); data->fan[0] = (val >> 8) & 0xff; data->fan[1] = val & 0xff; @@ -585,6 +562,18 @@ void gl518_update_client(struct i2c_client *client) val = gl518_read_value(client, GL518_REG_CONF); data->beep_enable = (val >> 2) & 1; +#ifndef DEBUG_VIN + if (data->type != gl518sm_r00) { + data->voltage[0] = gl518_read_value(client,GL518_REG_VDD); + data->voltage[1] = gl518_read_value(client,GL518_REG_VIN1); + data->voltage[2] = gl518_read_value(client,GL518_REG_VIN2); + data->voltage[3] = gl518_read_value(client,GL518_REG_VIN3); + } else + gl518_update_client_rev00(client); +#else + gl518_update_client_rev00(client); +#endif + data->last_updated = jiffies; data->valid = 1; } @@ -592,35 +581,51 @@ void gl518_update_client(struct i2c_client *client) up(&data->update_lock); } -/* This updates vdd, vin1, vin2 values by doing slow and multiple - comparisons for the GL518SM rev 00 that lacks support for direct - reading of these values. */ - +/* Here we decide how to run the iteration code. + When called, we trigger the iteration and report the last + measured voltage. No delay for user apps */ void gl518_update_client_rev00(struct i2c_client *client) +{ + struct gl518_data *data = client->data; + int i; + + if (data->iterate == 1) { /* 10 sec delay */ + /* as that update is slow, we consider the data valid for 30 seconds */ + if ((jiffies - data->last_updated_v00 > 30*HZ) || (data->alarms & 7)) { + gl518_update_vins(client); + for (i=0; i<4; i++) + data->voltage[4]=data->iter_voltage[i]; + } + } else if (data->iterate == 2) { /* show results of last iteration */ + for (i=0; i<4; i++) + data->voltage[i]=data->iter_voltage[i]; + /* if (! already_running) trigger(gl518sm_update_vins) */ + } else { /* no iteration */ + data->voltage[3] = gl518_read_value(client,GL518_REG_VIN3); + } +} + +/* This updates vdd, vin1, vin2 values by doing slow and multiple + comparisons for the GL518SM rev 00 that lacks support for direct + reading of these values. Values are kept in iter_voltage */ + +void gl518_update_vins(struct i2c_client *client) { struct gl518_data *data = client->data; int i, j, loop_more=1, min[3], max[3], delta[3]; - int alarm, config; + int alarm, beeps, irqs; #define VIN_REG(c) c==0?GL518_REG_VDD_LIMIT:\ c==1?GL518_REG_VIN1_LIMIT:\ GL518_REG_VIN2_LIMIT - - config = gl518_read_value(client, GL518_REG_CONF) & 0xfb; - alarm = data->alarms; - - if (data->iterate==0) { - for (i=0; i<3; i++) - data->voltage[i]=0; - return; - } -#ifndef DEBUG_VIN - /* as that update is slow, we consider the data valid for 30 seconds */ - if ((jiffies - data->last_updated_v00 > 30*HZ) || (alarm & 7)) { -#else - if (jiffies - data->last_updated_v00 > HZ+HZ/2 ) { -#endif + /* disable beeps & irqs for vin0-2*/ + beeps = gl518_read_value(client, GL518_REG_ALARM); + irqs = gl518_read_value(client, GL518_REG_MASK); + gl518_write_value(client,GL518_REG_ALARM, beeps &~ 0x7); + gl518_write_value(client,GL518_REG_MASK, irqs &~ 0x7); + + alarm = data->alarms; for (i=0; i<3; i++) { if (alarm & (1<last_updated_v00 = jiffies; - /* reset beeps */ - gl518_write_value(client, GL518_REG_CONF, - (config | (data->beep_enable << 2))); + /* reset beeps & irqs for vin0-2*/ + gl518_write_value(client,GL518_REG_ALARM, beeps); + gl518_write_value(client,GL518_REG_MASK, irqs); - /* reset values */ + /* set values */ for (i=0; i<3; i++) { - data->voltage[i] = max[i]; + data->iter_voltage[i] = max[i]; gl518_write_value(client, VIN_REG(i), data->voltage_max[i] << 8 | data->voltage_min[i]); } - } + + /* finally read the vin3 meter */ + data->iter_voltage[3] = gl518_read_value(client,GL518_REG_VIN3); + #undef VIN_REG } @@ -878,6 +883,7 @@ void gl518_iterate(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results) { struct gl518_data *data = client->data; + int i; if (operation == SENSORS_PROC_REAL_INFO) *nrels_mag = 0; else if (operation == SENSORS_PROC_REAL_READ) { @@ -886,6 +892,8 @@ void gl518_iterate(struct i2c_client *client, int operation, int ctl_name, } else if (operation == SENSORS_PROC_REAL_WRITE) { if (*nrels_mag >= 1) data->iterate=results[0]; + for (i=0; i<4; i++) + data->voltage[i] = 0; } } @@ -922,7 +930,7 @@ int gl518_cleanup(void) #ifdef MODULE -MODULE_AUTHOR("Frodo Looijaard "); +MODULE_AUTHOR("Frodo Looijaard and Kyösti Mälkki "); MODULE_DESCRIPTION("GL518SM driver"); int init_module(void) diff --git a/kernel/chips/gl520sm.c b/kernel/chips/gl520sm.c index 36d74d02..916f38fe 100644 --- a/kernel/chips/gl520sm.c +++ b/kernel/chips/gl520sm.c @@ -24,6 +24,7 @@ #include #include #include "sensors.h" +#include "i2c-isa.h" #include "version.h" #include "compat.h"