mirror of
https://github.com/lm-sensors/lm-sensors
synced 2025-08-31 06:15:15 +00:00
Thermistor support.
git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2542 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
@@ -27,7 +27,10 @@
|
||||
* PC87363 - 2 2 - 0xE8
|
||||
* PC87364 - 3 3 - 0xE4
|
||||
* PC87365 11 3 3 2 0xE5
|
||||
* PC87366 11 3 3 3 0xE9
|
||||
* PC87366 11 3 3 6 0xE9
|
||||
*
|
||||
* This driver assumes that no more than one chip is present, and the
|
||||
* standard Super-I/O address is used (0x2E/0x2F).
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -170,7 +173,6 @@ static inline u8 PWM_TO_REG(int val, int inv)
|
||||
#define IN_TO_REG(val,ref) ((val)<0 ? 0 : \
|
||||
(val)*256>=(ref)*255 ? 255: \
|
||||
((val) * 256 + (ref) / 2) / (ref))
|
||||
#define IN_STATUS_FROM_REG(val) ((val) & 0x97)
|
||||
|
||||
/*
|
||||
* Temperature registers and conversions
|
||||
@@ -187,7 +189,6 @@ static inline u8 PWM_TO_REG(int val, int inv)
|
||||
#define TEMP_FROM_REG(val) ((val)&0x80 ? (val) - 0x100 : (val))
|
||||
#define TEMP_TO_REG(val) ((val)<-55 ? 201 : (val)>127 ? 0x7F : \
|
||||
(val)<0 ? (val) + 0x100 : (val))
|
||||
#define TEMP_STATUS_FROM_REG(val) ((val) & 0xFF)
|
||||
|
||||
struct pc87360_data {
|
||||
struct i2c_client client;
|
||||
@@ -208,10 +209,11 @@ struct pc87360_data {
|
||||
u16 fan_conf[2]; /* Configuration register values, combined */
|
||||
|
||||
u16 in_vref; /* 10mV/bit */
|
||||
u8 in[11]; /* Register value */
|
||||
u8 in_min[11]; /* Register value */
|
||||
u8 in_max[11]; /* Register value */
|
||||
u8 in_status[11]; /* Register value */
|
||||
u8 in[14]; /* Register value */
|
||||
u8 in_min[14]; /* Register value */
|
||||
u8 in_max[14]; /* Register value */
|
||||
u8 in_crit[3]; /* Register value */
|
||||
u8 in_status[14]; /* Register value */
|
||||
u16 in_alarms; /* Register values, combined, masked */
|
||||
|
||||
u8 temp[3]; /* Register value */
|
||||
@@ -299,6 +301,9 @@ static struct i2c_driver pc87360_driver = {
|
||||
#define PC87365_SYSCTL_IN8 2108
|
||||
#define PC87365_SYSCTL_IN9 2109
|
||||
#define PC87365_SYSCTL_IN10 2110
|
||||
#define PC87365_SYSCTL_TEMP4 2111 /* not for PC87365 */
|
||||
#define PC87365_SYSCTL_TEMP5 2112 /* not for PC87365 */
|
||||
#define PC87365_SYSCTL_TEMP6 2113 /* not for PC87365 */
|
||||
#define PC87365_SYSCTL_IN0_STATUS 2300 /* bit field */
|
||||
#define PC87365_SYSCTL_IN1_STATUS 2301
|
||||
#define PC87365_SYSCTL_IN2_STATUS 2302
|
||||
@@ -310,6 +315,9 @@ static struct i2c_driver pc87360_driver = {
|
||||
#define PC87365_SYSCTL_IN8_STATUS 2308
|
||||
#define PC87365_SYSCTL_IN9_STATUS 2309
|
||||
#define PC87365_SYSCTL_IN10_STATUS 2310
|
||||
#define PC87365_SYSCTL_TEMP4_STATUS 2311 /* not for PC87365 */
|
||||
#define PC87365_SYSCTL_TEMP5_STATUS 2312 /* not for PC87365 */
|
||||
#define PC87365_SYSCTL_TEMP6_STATUS 2313 /* not for PC87365 */
|
||||
|
||||
#define PC87365_STATUS_IN_MIN 0x02
|
||||
#define PC87365_STATUS_IN_MAX 0x04
|
||||
@@ -425,12 +433,24 @@ static ctl_table pc87365_dir_table_template[] = { /* PC87366 too */
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp},
|
||||
{PC87365_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp},
|
||||
{PC87365_SYSCTL_TEMP1_STATUS, "temp1_status", NULL, 0, 0644, NULL,
|
||||
{PC87365_SYSCTL_TEMP4, "temp4", NULL, 0, 0644, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in},
|
||||
{PC87365_SYSCTL_TEMP5, "temp5", NULL, 0, 0644, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in},
|
||||
{PC87365_SYSCTL_TEMP6, "temp6", NULL, 0, 0644, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in},
|
||||
{PC87365_SYSCTL_TEMP1_STATUS, "temp1_status", NULL, 0, 0444, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp_status},
|
||||
{PC87365_SYSCTL_TEMP2_STATUS, "temp2_status", NULL, 0, 0644, NULL,
|
||||
{PC87365_SYSCTL_TEMP2_STATUS, "temp2_status", NULL, 0, 0444, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp_status},
|
||||
{PC87365_SYSCTL_TEMP3_STATUS, "temp3_status", NULL, 0, 0644, NULL,
|
||||
{PC87365_SYSCTL_TEMP3_STATUS, "temp3_status", NULL, 0, 0444, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_temp_status},
|
||||
{PC87365_SYSCTL_TEMP4_STATUS, "temp4_status", NULL, 0, 0444, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status},
|
||||
{PC87365_SYSCTL_TEMP5_STATUS, "temp5_status", NULL, 0, 0444, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status},
|
||||
{PC87365_SYSCTL_TEMP6_STATUS, "temp6_status", NULL, 0, 0444, NULL,
|
||||
&i2c_proc_real, &i2c_sysctl_real, NULL, &pc87365_in_status},
|
||||
{0}
|
||||
};
|
||||
|
||||
@@ -450,7 +470,7 @@ static int pc87360_find(u8 *devid, int *address)
|
||||
/* identify device */
|
||||
val = superio_inb(DEVID);
|
||||
switch (val) {
|
||||
case 0xE1: /* PC87360 */
|
||||
case 0xE1: /* PC87360 */
|
||||
case 0xE8: /* PC87363 */
|
||||
case 0xE4: /* PC87364 */
|
||||
nrdev = 1;
|
||||
@@ -571,7 +591,7 @@ int pc87360_detect(struct i2c_adapter *adapter, int address,
|
||||
type_name = "pc87366";
|
||||
template = pc87365_dir_table_template;
|
||||
data->fannr = extra_isa[0] ? 3 : 0;
|
||||
data->innr = extra_isa[1] ? 11 : 0;
|
||||
data->innr = extra_isa[1] ? 14 : 0;
|
||||
data->tempnr = extra_isa[2] ? 3 : 0;
|
||||
break;
|
||||
}
|
||||
@@ -694,11 +714,11 @@ static void pc87360_init_client(struct i2c_client *client)
|
||||
{
|
||||
struct pc87360_data *data = client->data;
|
||||
int i;
|
||||
const u8 init_in[11] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1 };
|
||||
const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
|
||||
const u8 init_temp[3] = { 2, 2, 1 };
|
||||
u8 reg;
|
||||
|
||||
if (init >= 3) {
|
||||
if (init >= 3 && data->innr) {
|
||||
reg = pc87360_read_value(data, LD_IN, NO_BANK,
|
||||
PC87365_REG_IN_CONVRATE);
|
||||
if (reg & 0x06) {
|
||||
@@ -719,12 +739,20 @@ static void pc87360_init_client(struct i2c_client *client)
|
||||
PC87365_REG_IN_STATUS);
|
||||
if (!(reg & 0x01)) {
|
||||
#ifdef DEBUG
|
||||
printk(KERN_DEBUG "pc87360.o: Forcibly "
|
||||
"enabling in%d\n", i);
|
||||
if (i < 11)
|
||||
printk(KERN_DEBUG "pc87360.o: "
|
||||
"Forcibly enabling in%d\n",
|
||||
i);
|
||||
else
|
||||
printk(KERN_DEBUG "pc87360.o: "
|
||||
"Forcibly enabling temp%d\n",
|
||||
i-8);
|
||||
#endif
|
||||
pc87360_write_value(data, LD_IN, i,
|
||||
PC87365_REG_IN_STATUS,
|
||||
(reg & 0x68) | 0x87);
|
||||
i < 11 ?
|
||||
(reg & 0x68) | 0x87 :
|
||||
(reg & 0x60) | 0x8F);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -854,7 +882,7 @@ static void pc87360_update_client(struct i2c_client *client)
|
||||
/* Voltages */
|
||||
for (i = 0; i < data->innr; i++) {
|
||||
data->in_status[i] = pc87360_read_value(data, LD_IN, i,
|
||||
PC87365_REG_IN_STATUS);
|
||||
PC87365_REG_IN_STATUS);
|
||||
/* Clear bits */
|
||||
pc87360_write_value(data, LD_IN, i,
|
||||
PC87365_REG_IN_STATUS,
|
||||
@@ -868,6 +896,10 @@ static void pc87360_update_client(struct i2c_client *client)
|
||||
data->in_max[i] = pc87360_read_value(data,
|
||||
LD_IN, i,
|
||||
PC87365_REG_IN_MAX);
|
||||
if (i >= 11)
|
||||
data->in_crit[i-11] =
|
||||
pc87360_read_value(data, LD_IN,
|
||||
i, PC87365_REG_TEMP_CRIT);
|
||||
}
|
||||
}
|
||||
if (data->innr) {
|
||||
@@ -1075,7 +1107,13 @@ void pc87365_in(struct i2c_client *client, int operation, int ctl_name,
|
||||
results[0] = IN_FROM_REG(data->in_min[nr], data->in_vref);
|
||||
results[1] = IN_FROM_REG(data->in_max[nr], data->in_vref);
|
||||
results[2] = IN_FROM_REG(data->in[nr], data->in_vref);
|
||||
*nrels_mag = 3;
|
||||
if (nr < 11) {
|
||||
*nrels_mag = 3;
|
||||
} else {
|
||||
results[3] = IN_FROM_REG(data->in_crit[nr-11],
|
||||
data->in_vref);
|
||||
*nrels_mag = 4;
|
||||
}
|
||||
}
|
||||
else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
if (*nrels_mag >= 1) {
|
||||
@@ -1092,6 +1130,13 @@ void pc87365_in(struct i2c_client *client, int operation, int ctl_name,
|
||||
PC87365_REG_IN_MAX,
|
||||
data->in_max[nr]);
|
||||
}
|
||||
if (*nrels_mag >= 3 && nr > 11) {
|
||||
data->in_crit[nr-11] = IN_TO_REG(results[3],
|
||||
data->in_vref);
|
||||
pc87360_write_value(data, LD_IN, nr,
|
||||
PC87365_REG_TEMP_CRIT,
|
||||
data->in_crit[nr-11]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1105,7 +1150,7 @@ void pc87365_in_status(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] = IN_STATUS_FROM_REG(data->in_status[nr]);
|
||||
results[0] = data->in_status[nr];
|
||||
*nrels_mag = 1;
|
||||
}
|
||||
}
|
||||
@@ -1160,7 +1205,7 @@ void pc87365_temp_status(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] = TEMP_STATUS_FROM_REG(data->temp_status[nr]);
|
||||
results[0] = data->temp_status[nr];
|
||||
*nrels_mag = 1;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user