2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-08-30 22:05:11 +00:00

Added sensor[1-3] to 782d/783s to select sensor type.

Added RT table read to 781d but then #undef'ed it since it was just
all 1's. Changed max entries in sensor.c to 32 bytes to handle RT table.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@335 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Mark D. Studebaker
1999-03-23 21:48:19 +00:00
parent 27c6df42b3
commit 3ccf39c7d0
4 changed files with 184 additions and 4 deletions

View File

@@ -18,7 +18,24 @@ w83783s: untested
/PROC ENTRIES
-------------
Varies depending on chip type.
Varies depending on chip type. Most are identical to the lm78 entries.
See the lm78 documentation for details.
Additional entries:
pwm[1-4]: (782d/783s only)
Controls the speed of the fans with PWM (Pulse Width Modulation)
Valid values:
0 - 255. 255 = max speed.
sensor[1-3]: (782d/783s only)
Controls the sensor type. To change to a different
sensor type, for example, do 'echo 2 > sensor1'.
Valid values:
1: Pentium II / Celeron diode
2: 2N3904 Transistor in a diode configuration
3435: Thermistor with Beta = 3435. Beta is a measure
of sensitivity to temperature.
The driver only updates its values each 1.5 seconds; reading it more often
will do no harm, but will return 'old' values.
@@ -31,7 +48,6 @@ TO DO:
783s temp2 (labeled as temp1 in data sheet) at different location
than 781d/782d, not implemented yet.
781d R-T table
782d/783s undocumented thermistor/PII/3904 select bits for pins 38-40
782d/783s clock speed select

View File

@@ -45,6 +45,9 @@
#include "i2c.h"
#include "compat.h"
/* RT Table support experimental - define this to enable */
#undef W83781D_RT
/* Many W83781D constants specified below */
/* Length of ISA address segment */
@@ -105,6 +108,19 @@
const u8 regpwm[] = {W83781D_REG_PWM1, W83781D_REG_PWM2, W83781D_REG_PWM3, W83781D_REG_PWM4};
#define W83781D_REG_PWM(nr) (regpwm[(nr) - 1])
/* The following are undocumented in the data sheets however we
received the information in an email from Winbond tech support */
/* Sensor selection 782D/783S only */
#define W83781D_REG_SCFG1 0x5D
const u8 BIT_SCFG1[] = {0x02, 0x04, 0x08};
#define W83781D_REG_SCFG2 0x59
const u8 BIT_SCFG2[] = {0x10, 0x04, 0x08};
#define W83781D_DEFAULT_BETA 3435
/* RT Table registers */
#define W83781D_REG_RT_IDX 0x50
#define W83781D_REG_RT_VAL 0x51
#define W83781D_WCHIPID 0x10
#define W83782D_WCHIPID 0x30
#define W83783S_WCHIPID 0x40
@@ -297,6 +313,13 @@ struct w83781d_data {
u8 beep_enable; /* Boolean */
u8 wchipid; /* Register value */
u8 pwm[4]; /* Register value */
u16 sens[3]; /* 782D/783S only.
1 = pentium diode; 2 = 3904 diode;
3000-5000 = thermistor beta.
Default = 3435. Other Betas unimplemented */
#ifdef W83781D_RT
u8 rt[3][32]; /* Register value */
#endif
};
@@ -342,6 +365,12 @@ static void w83781d_fan_div(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
static void w83781d_pwm(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
static void w83781d_sens(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
#ifdef W83781D_RT
static void w83781d_rt(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
#endif
/* I choose here for semi-static W83781D allocation. Complete dynamic
allocation could also be used; the code needed for this would probably
@@ -406,6 +435,14 @@ static ctl_table w83781d_dir_table_template[] = {
&sensors_sysctl_real, NULL, &w83781d_alarms },
{ W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_beep },
#ifdef W83781D_RT
{ W83781D_SYSCTL_RT1, "rt1", NULL, 0, 0444, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_rt },
{ W83781D_SYSCTL_RT2, "rt2", NULL, 0, 0444, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_rt },
{ W83781D_SYSCTL_RT3, "rt3", NULL, 0, 0444, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_rt },
#endif
{ 0 }
};
@@ -453,6 +490,12 @@ static ctl_table w83782d_isa_dir_table_template[] = {
&sensors_sysctl_real, NULL, &w83781d_pwm },
{ W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_pwm },
{ W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ 0 }
};
@@ -504,6 +547,12 @@ static ctl_table w83782d_i2c_dir_table_template[] = {
&sensors_sysctl_real, NULL, &w83781d_pwm },
{ W83781D_SYSCTL_PWM4, "pwm4", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_pwm },
{ W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ W83781D_SYSCTL_SENS3, "sensor3", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ 0 }
};
@@ -543,6 +592,10 @@ static ctl_table w83783s_dir_table_template[] = {
&sensors_sysctl_real, NULL, &w83781d_pwm },
{ W83781D_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_pwm },
{ W83781D_SYSCTL_SENS1, "sensor1", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ W83781D_SYSCTL_SENS2, "sensor2", NULL, 0, 0644, NULL, &sensors_proc_real,
&sensors_sysctl_real, NULL, &w83781d_sens },
{ 0 }
};
@@ -988,9 +1041,12 @@ int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
/* Called when we have found a new W83781D. It should set limits, etc. */
void w83781d_init_client(struct i2c_client *client)
{
struct w83781d_data *data = client->data;
int vid,wchipid;
int i;
u8 tmp;
wchipid = ((struct w83781d_data *) (client->data))->wchipid;
wchipid = data->wchipid;
/* Reset all except Watchdog values and last conversion values
This sets fan-divs to 2, among others */
w83781d_write_value(client,W83781D_REG_CONFIG,0x80);
@@ -999,6 +1055,47 @@ void w83781d_init_client(struct i2c_client *client)
vid |= (w83781d_read_value(client,W83781D_REG_CHIPID) & 0x01) << 4;
vid = VID_FROM_REG(vid);
if(wchipid != W83781D_WCHIPID) {
tmp = w83781d_read_value(client,W83781D_REG_SCFG1);
for (i = 1; i <= 3; i++) {
if(!(tmp & BIT_SCFG1[i-1])) {
data->sens[i-1] = W83781D_DEFAULT_BETA;
} else {
if(w83781d_read_value(client,W83781D_REG_TEMP) & BIT_SCFG2[i-1])
data->sens[i-1] = 1;
else
data->sens[i-1] = 2;
}
if(data->wchipid == W83783S_WCHIPID && i == 2)
break;
}
}
#ifdef W83781D_RT
/*
Fill up the RT Tables.
We assume that they are 32 bytes long, in order for temp 1-3.
Data sheet documentation is sparse.
We also assume that it is only for the 781D although I suspect
that the 782D/783D support it as well....
*/
if(wchipid == W83781D_WCHIPID) {
/*
Auto-indexing doesn't seem to work...
w83781d_write_value(client,W83781D_REG_RT_IDX,0);
*/
for (i = 0; i < 3; i++) {
int j;
for (j = 0; j < 32; j++) {
u16 k = 0;
w83781d_write_value(client,W83781D_REG_RT_IDX,k++);
data->rt[i][j] = w83781d_read_value(client,W83781D_REG_RT_VAL);
}
}
}
#endif
w83781d_write_value(client,W83781D_REG_IN_MIN(0),
IN_TO_REG(W83781D_INIT_IN_MIN_0,0));
w83781d_write_value(client,W83781D_REG_IN_MAX(0),
@@ -1382,6 +1479,67 @@ void w83781d_pwm(struct i2c_client *client, int operation, int ctl_name,
}
}
void w83781d_sens(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct w83781d_data *data = client->data;
int nr = 1 + ctl_name - W83781D_SYSCTL_SENS1;
u8 tmp;
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) {
switch(results[0]) {
case 1: /* PII/Celeron diode */
tmp = w83781d_read_value(client,W83781D_REG_SCFG1);
w83781d_write_value(client,W83781D_REG_SCFG1, tmp | BIT_SCFG2[nr-1]);
tmp = w83781d_read_value(client,W83781D_REG_SCFG2);
w83781d_write_value(client,W83781D_REG_SCFG2, tmp | BIT_SCFG2[nr-1]);
data->sens[nr-1] = results[0];
break;
case 2: /* 3904 */
tmp = w83781d_read_value(client,W83781D_REG_SCFG1);
w83781d_write_value(client,W83781D_REG_SCFG1, tmp | BIT_SCFG2[nr-1]);
tmp = w83781d_read_value(client,W83781D_REG_SCFG2);
w83781d_write_value(client,W83781D_REG_SCFG2, tmp & ~ BIT_SCFG2[nr-1]);
data->sens[nr-1] = results[0];
break;
case W83781D_DEFAULT_BETA: /* thermistor */
tmp = w83781d_read_value(client,W83781D_REG_SCFG1);
w83781d_write_value(client,W83781D_REG_SCFG1, tmp & ~ BIT_SCFG2[nr-1]);
data->sens[nr-1] = results[0];
break;
default:
printk("w83781d.o: Invalid sensor type %ld; must be 1, 2, or %d\n", results[0], W83781D_DEFAULT_BETA);
break;
}
}
}
}
#ifdef W83781D_RT
void w83781d_rt(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct w83781d_data *data = client->data;
int nr = 1 + ctl_name - W83781D_SYSCTL_RT1;
int i;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
for(i = 0; i < 32; i++) {
results[i] = data->rt[nr-1][i];
}
*nrels_mag = 32;
}
}
#endif
int w83781d_init(void)
{
int res;

View File

@@ -352,6 +352,12 @@ struct sensors_chips_data {
#define W83781D_SYSCTL_PWM2 1402
#define W83781D_SYSCTL_PWM3 1403
#define W83781D_SYSCTL_PWM4 1404
#define W83781D_SYSCTL_SENS1 1501 /* 1, 2, or Beta (3000-5000) */
#define W83781D_SYSCTL_SENS2 1502
#define W83781D_SYSCTL_SENS3 1503
#define W83781D_SYSCTL_RT1 1601 /* 32-entry table */
#define W83781D_SYSCTL_RT2 1602 /* 32-entry table */
#define W83781D_SYSCTL_RT3 1603 /* 32-entry table */
#define W83781D_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */
#define W83781D_SYSCTL_ALARMS 2001 /* bitvector */
#define W83781D_SYSCTL_BEEP 2002 /* bitvector */

View File

@@ -334,7 +334,7 @@ int sensors_sysctl_chips (ctl_table *table, int *name, int nlen, void *oldval,
int sensors_proc_real(ctl_table *ctl, int write, struct file * filp,
void *buffer, size_t *lenp)
{
#define MAX_RESULTS 20
#define MAX_RESULTS 32
int mag,nrels=MAX_RESULTS;
long results[MAX_RESULTS];
sensors_real_callback callback = ctl -> extra1;