The pc87360 driver now support the PC87365 and PC87366 as well,

and can write to registers. Untested.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2427 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare committed 2004-04-09 18:41:30 +00:00
1 parent 4c32b1a881
commit 2cdac4e54a
5 files changed
+69 -36

No files matched your search

+2
View File
@@ -149,6 +149,8 @@ pc87360
pc87360 - - 2 2 pwm no yes (LPC)
pc87363 - - 2 2 pwm no yes (LPC)
pc87364 - - 3 3 pwm no yes (LPC)
pc87365 - - 3 3 pwm no yes (LPC)
pc87366 - - 3 3 pwm no yes (LPC)
sis5595
sis5595 0-1 4-5 2 - no yes
+6 -5
View File
@@ -40,7 +40,7 @@ is triggered if the rotation speed has dropped below a programmable limit.
Fan readings can be divided by a programmable divider (1, 2, 4 or 8) to give
the readings more range or accuracy. Not all RPM values can accurately be
represented, so some rounding is done. With a divider of 2, the lowest
representable value is around 2600 RPM.
representable value is around 1900 RPM. See doc/fan-divisors for details.
A different alarm is also triggered if the fan speed is too low to be
measured. It is suggested to increase the fan divisor in this case.
@@ -58,7 +58,8 @@ miss once-only alarms.
Limitations
-----------
This driver is read-only at the moment, and only supports fans. Since I
don't own a supported chip for testing, and the datasheet suggests that
you shouldn't change values once the monitoring has started (this is
normally done by the BIOS at boot time), I decided to play it safe.
This driver only supports fans at the moment.
The datasheets suggests that some values (fan mins, fan divisors)
shouldn't be changed once the monitoring has started, but we ignore that
recommendation. We'll reconsider if it actually causes trouble.
+49 -19
View File
@@ -102,8 +102,10 @@ static inline void superio_exit(void)
#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0: \
960000/((val)*(div)))
#define FAN_TO_REG(val,div) ((val)<=0?255: \
960000/((val)*(div)))
#define FAN_DIV_FROM_REG(val) (1 << ((val >> 5) & 0x03))
#define PWM_FROM_REG(val) (val)
#define FAN_DIV_TO_REG(val) ((val)==8?0x60:(val)==4?0x40:(val)==1?0x00:0x20)
#define ALARM_FROM_REG(val) ((val) & 0x07)
struct pc87360_data {
@@ -129,10 +131,8 @@ static int pc87360_detect(struct i2c_adapter *adapter, int address,
static int pc87360_detach_client(struct i2c_client *client);
static int pc87360_read_value(struct i2c_client *client, u8 register);
#if 0
static int pc87360_write_value(struct i2c_client *client, u8 register,
u8 value);
#endif
static void pc87360_update_client(struct i2c_client *client);
static void pc87360_init_client(struct i2c_client *client);
static int pc87360_find(int *address, u8 *devid);
@@ -177,31 +177,31 @@ static struct i2c_driver pc87360_driver = {
/* -- SENSORS SYSCTL END -- */
static ctl_table pc87360_dir_table_template[] = { /* PC87363 too */
{PC87360_SYSCTL_FAN1, "fan1", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan},
{PC87360_SYSCTL_FAN2, "fan2", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan},
{PC87360_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_div},
{PC87360_SYSCTL_FAN1_STATUS, "fan1_status", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status},
{PC87360_SYSCTL_FAN2_STATUS, "fan2_status", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status},
{PC87360_SYSCTL_PWM1, "pwm1", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm},
{PC87360_SYSCTL_PWM2, "pwm2", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm},
{0}
};
static ctl_table pc87364_dir_table_template[] = { /* PC87365 and PC87366 too */
{PC87360_SYSCTL_FAN1, "fan1", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan},
{PC87360_SYSCTL_FAN2, "fan2", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan},
{PC87360_SYSCTL_FAN3, "fan3", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan},
{PC87360_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_div},
{PC87360_SYSCTL_FAN1_STATUS, "fan1_status", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status},
@@ -209,11 +209,11 @@ static ctl_table pc87364_dir_table_template[] = { /* PC87365 and PC87366 too */
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status},
{PC87360_SYSCTL_FAN3_STATUS, "fan3_status", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_fan_status},
{PC87360_SYSCTL_PWM1, "pwm1", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm},
{PC87360_SYSCTL_PWM2, "pwm2", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm},
{PC87360_SYSCTL_PWM3, "pwm3", NULL, 0, 0444, NULL,
{PC87360_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87360_pwm},
{0}
};
@@ -356,13 +356,11 @@ static int pc87360_read_value(struct i2c_client *client, u8 reg)
return res;
}
#if 0
static int pc87360_write_value(struct i2c_client *client, u8 reg, u8 value)
{
outb_p(value, client->addr + reg);
return 0;
}
#endif
static void pc87360_init_client(struct i2c_client *client)
{
@@ -409,9 +407,17 @@ void pc87360_fan(struct i2c_client *client, int operation, int ctl_name,
FAN_DIV_FROM_REG(data->fan_status[nr]));
*nrels_mag = 2;
}
/* We ignore National's recommendation */
else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
data->fan_min[nr] = FAN_TO_REG(results[0],
FAN_DIV_FROM_REG(data->fan_status[nr]));
pc87360_write_value(client, PC87360_REG_FAN_MIN(nr),
data->fan_min[nr]);
}
}
}
void pc87360_fan_div(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
@@ -427,6 +433,22 @@ void pc87360_fan_div(struct i2c_client *client, int operation,
}
*nrels_mag = data->fannr;
}
/* We ignore National's recommendation */
else if (operation == SENSORS_PROC_REAL_WRITE) {
for (i = 0; i < data->fannr && i < *nrels_mag; i++) {
/* Preserve fan min */
int fan_min = FAN_FROM_REG(data->fan_min[i],
FAN_DIV_FROM_REG(data->fan_status[i]));
data->fan_status[i] = (data->fan_status[i] & 0x9F)
| FAN_DIV_TO_REG(results[i]);
pc87360_write_value(client, PC87360_REG_FAN_STATUS(i),
data->fan_status[i]);
data->fan_min[i] = FAN_TO_REG(fan_min,
FAN_DIV_FROM_REG(data->fan_status[i]));
pc87360_write_value(client, PC87360_REG_FAN_MIN(i),
data->fan_min[i]);
}
}
}
void pc87360_pwm(struct i2c_client *client, int operation, int ctl_name,
@@ -439,9 +461,17 @@ void pc87360_pwm(struct i2c_client *client, int operation, int ctl_name,
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
pc87360_update_client(client);
results[0] = PWM_FROM_REG(data->pwm[nr]);
results[0] = data->pwm[nr];
*nrels_mag = 1;
}
else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1)
{
data->pwm[nr] = SENSORS_LIMIT(results[0], 0, 255);
pc87360_write_value(client, PC87360_REG_PWM(nr),
data->pwm[nr]);
}
}
}
void pc87360_fan_status(struct i2c_client *client, int operation, int ctl_name,
+10 -10
View File
@@ -4258,15 +4258,15 @@ static sensors_chip_feature pc87360_features[] =
{ SENSORS_PC87360_FAN2, "fan2", NOMAP, NOMAP, R,
PC87360_SYSCTL_FAN2, VALUE(2), 0 },
{ SENSORS_PC87360_FAN1_MIN, "fan1_min", SENSORS_PC87360_FAN1,
SENSORS_PC87360_FAN1, R, PC87360_SYSCTL_FAN1,
SENSORS_PC87360_FAN1, RW, PC87360_SYSCTL_FAN1,
VALUE(1), 0 },
{ SENSORS_PC87360_FAN2_MIN, "fan2_min", SENSORS_PC87360_FAN2,
SENSORS_PC87360_FAN2, R, PC87360_SYSCTL_FAN2,
SENSORS_PC87360_FAN2, RW, PC87360_SYSCTL_FAN2,
VALUE(1), 0 },
{ SENSORS_PC87360_FAN1_DIV, "fan1_div", SENSORS_PC87360_FAN1,
NOMAP, R, PC87360_SYSCTL_FAN_DIV, VALUE(1), 0 },
NOMAP, RW, PC87360_SYSCTL_FAN_DIV, VALUE(1), 0 },
{ SENSORS_PC87360_FAN2_DIV, "fan2_div", SENSORS_PC87360_FAN2,
NOMAP, R, PC87360_SYSCTL_FAN_DIV, VALUE(2), 0 },
NOMAP, RW, PC87360_SYSCTL_FAN_DIV, VALUE(2), 0 },
{ SENSORS_PC87360_FAN1_STATUS, "fan1_status", SENSORS_PC87360_FAN1,
NOMAP, R, PC87360_SYSCTL_FAN1_STATUS, VALUE(1), 0 },
{ SENSORS_PC87360_FAN2_STATUS, "fan2_status", SENSORS_PC87360_FAN2,
@@ -4283,20 +4283,20 @@ static sensors_chip_feature pc87364_features[] =
{ SENSORS_PC87360_FAN3, "fan3", NOMAP, NOMAP, R,
PC87360_SYSCTL_FAN3, VALUE(2), 0 },
{ SENSORS_PC87360_FAN1_MIN, "fan1_min", SENSORS_PC87360_FAN1,
SENSORS_PC87360_FAN1, R, PC87360_SYSCTL_FAN1,
SENSORS_PC87360_FAN1, RW, PC87360_SYSCTL_FAN1,
VALUE(1), 0 },
{ SENSORS_PC87360_FAN2_MIN, "fan2_min", SENSORS_PC87360_FAN2,
SENSORS_PC87360_FAN2, R, PC87360_SYSCTL_FAN2,
SENSORS_PC87360_FAN2, RW, PC87360_SYSCTL_FAN2,
VALUE(1), 0 },
{ SENSORS_PC87360_FAN3_MIN, "fan3_min", SENSORS_PC87360_FAN3,
SENSORS_PC87360_FAN3, R, PC87360_SYSCTL_FAN3,
SENSORS_PC87360_FAN3, RW, PC87360_SYSCTL_FAN3,
VALUE(1), 0 },
{ SENSORS_PC87360_FAN1_DIV, "fan1_div", SENSORS_PC87360_FAN1,
NOMAP, R, PC87360_SYSCTL_FAN_DIV, VALUE(1), 0 },
NOMAP, RW, PC87360_SYSCTL_FAN_DIV, VALUE(1), 0 },
{ SENSORS_PC87360_FAN2_DIV, "fan2_div", SENSORS_PC87360_FAN2,
NOMAP, R, PC87360_SYSCTL_FAN_DIV, VALUE(2), 0 },
NOMAP, RW, PC87360_SYSCTL_FAN_DIV, VALUE(2), 0 },
{ SENSORS_PC87360_FAN3_DIV, "fan3_div", SENSORS_PC87360_FAN3,
NOMAP, R, PC87360_SYSCTL_FAN_DIV, VALUE(2), 0 },
NOMAP, RW, PC87360_SYSCTL_FAN_DIV, VALUE(3), 0 },
{ SENSORS_PC87360_FAN1_STATUS, "fan1_status", SENSORS_PC87360_FAN1,
NOMAP, R, PC87360_SYSCTL_FAN1_STATUS, VALUE(1), 0 },
{ SENSORS_PC87360_FAN2_STATUS, "fan2_status", SENSORS_PC87360_FAN2,
+2 -2
View File
@@ -1373,13 +1373,13 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
},
{
name => "Nat. Semi. PC87365 Super IO Sensors",
driver => "to-be-written",
driver => "pc87360",
devid => 0xe5,
logdev => 0x09, # fans; voltages at 0x0d; temps at 0x0e
},
{
name => "Nat. Semi. PC87366 Super IO Sensors",
driver => "to-be-written",
driver => "pc87360",
devid => 0xe9,
logdev => 0x09, # fans; voltages at 0x0d; temps at 0x0e
},