mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-11-03 13:38:25 +00:00
(Kyösti)
* GL518 & GL520: setting fan{1,2}_min 0 masks alarm & beep
* GL518SM rev 0x00 : Run iteration code in kernel thread
Every run of "sensors" now reports results of the previous
iteration run, and triggers a new one.
* GL520: Reads all inputs now
* GL520: Select between Temp2 or -12V input.
git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@520 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
1 parent
a55703e80b
commit
a92e84fe2a
3 files changed
+236
-125
No files matched your search
@@ -276,6 +276,7 @@ chip "gl518sm-*"
|
||||
set vin3_min 2.10
|
||||
set vin3_max 2.30
|
||||
set fan1_off 0
|
||||
set fan2_min 0
|
||||
set iterate 0
|
||||
|
||||
chip "gl520sm-*"
|
||||
@@ -309,6 +310,7 @@ chip "gl520sm-*"
|
||||
set vin2_max 13.0
|
||||
set vin3_min 2.10
|
||||
set vin3_max 2.30
|
||||
set two_temps 1
|
||||
|
||||
chip "lm80-*"
|
||||
|
||||
|
||||
+155
-84
@@ -109,7 +109,7 @@ extern inline u8 FAN_TO_REG(long rpm, int div)
|
||||
#define BEEP_ENABLE_FROM_REG(val) ((val)?0:1)
|
||||
|
||||
#define BEEPS_TO_REG(val) ((val) & 0x7f)
|
||||
#define BEEPS_FROM_REG(val) (val)
|
||||
#define BEEPS_FROM_REG(val) ((val) & 0x7f)
|
||||
|
||||
/* Initial values */
|
||||
#define GL518_INIT_TEMP_OVER 600
|
||||
@@ -149,6 +149,11 @@ struct gl518_data {
|
||||
enum chips type;
|
||||
|
||||
struct semaphore update_lock;
|
||||
|
||||
int iterate_lock, quit_thread;
|
||||
struct task_struct *thread;
|
||||
struct wait_queue *wq;
|
||||
|
||||
char valid; /* !=0 if following fields are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
unsigned long last_updated_v00;
|
||||
@@ -164,10 +169,10 @@ struct gl518_data {
|
||||
u8 temp_over; /* Register values */
|
||||
u8 temp_hyst; /* Register values */
|
||||
u8 alarms,beeps; /* Register value */
|
||||
u8 alarm_mask; /* Register value */
|
||||
u8 fan_div[2]; /* Register encoding, shifted right */
|
||||
u8 beep_enable; /* Boolean */
|
||||
u8 iterate; /* Voltage iteration mode */
|
||||
u8 fan1conf; /* Fan1 on/off control */
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
@@ -194,8 +199,10 @@ static u16 swap_bytes(u16 val);
|
||||
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 int gl518_update_thread(void *data);
|
||||
static void gl518_update_iterate(struct i2c_client *client);
|
||||
|
||||
static void gl518_vin(struct i2c_client *client, int operation,
|
||||
int ctl_name, int *nrels_mag, long *results);
|
||||
@@ -381,6 +388,10 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
|
||||
|
||||
/* Initialize the GL518SM chip */
|
||||
data->iterate = 0;
|
||||
data->iterate_lock = 0;
|
||||
data->quit_thread = 0;
|
||||
data->thread = NULL;
|
||||
data->alarm_mask = 0xff;
|
||||
gl518_init_client((struct i2c_client *) new_client);
|
||||
return 0;
|
||||
|
||||
@@ -562,15 +573,9 @@ void gl518_update_client(struct i2c_client *client)
|
||||
val = gl518_read_value(client,GL518_REG_MISC);
|
||||
data->fan_div[0] = (val >> 6) & 0x03;
|
||||
data->fan_div[1] = (val >> 4) & 0x03;
|
||||
data->fan1conf = (val >> 3) & 1;
|
||||
|
||||
if (((data->fan1conf) && (data->temp < data->temp_over)) ||
|
||||
(data->fan_min[0]==0xff))
|
||||
data->alarms &= ~GL518_ALARM_FAN1;
|
||||
|
||||
if (data->fan_min[1]==0xff)
|
||||
data->alarms &= ~GL518_ALARM_FAN2;
|
||||
|
||||
data->alarms &= data->alarm_mask;
|
||||
|
||||
val = gl518_read_value(client, GL518_REG_CONF);
|
||||
data->beep_enable = (val >> 2) & 1;
|
||||
|
||||
@@ -603,26 +608,68 @@ void gl518_update_client_rev00(struct i2c_client *client)
|
||||
|
||||
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)
|
||||
|| (! data->valid)) {
|
||||
gl518_update_vins(client);
|
||||
for (i=0; i<4; i++)
|
||||
data->voltage[i]=data->iter_voltage[i];
|
||||
if (((jiffies - data->last_updated_v00 > 30*HZ) || (data->alarms & 7)
|
||||
|| (! data->valid)) && (! data->iterate_lock)) {
|
||||
data->iterate_lock=1;
|
||||
gl518_update_iterate(client);
|
||||
data->iterate_lock=0;
|
||||
}
|
||||
for (i=0; i<4; i++)
|
||||
data->voltage[i]=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) */
|
||||
wake_up_interruptible(&data->wq);
|
||||
} else { /* no iteration */
|
||||
data->voltage[3] = gl518_read_value(client,GL518_REG_VIN3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int gl518_update_thread(void *c)
|
||||
{
|
||||
struct i2c_client *client = c;
|
||||
struct gl518_data *data = client->data;
|
||||
|
||||
#ifdef __SMP__
|
||||
lock_kernel();
|
||||
#endif
|
||||
exit_mm(current);
|
||||
current->session = 1;
|
||||
current->pgrp = 1;
|
||||
sigfillset(¤t->blocked);
|
||||
current->fs->umask = 0;
|
||||
strcpy(current->comm,"gl518sm");
|
||||
|
||||
data->wq = NULL;
|
||||
data->thread = current;
|
||||
|
||||
#ifdef __SMP__
|
||||
unlock_kernel();
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if (! data->iterate_lock) {
|
||||
data->iterate_lock=1;
|
||||
gl518_update_iterate(client);
|
||||
data->iterate_lock=0;
|
||||
}
|
||||
|
||||
if ((data->quit_thread) || signal_pending(current))
|
||||
break;
|
||||
interruptible_sleep_on(&data->wq);
|
||||
}
|
||||
|
||||
data->thread = NULL;
|
||||
data->quit_thread = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
void gl518_update_iterate(struct i2c_client *client)
|
||||
{
|
||||
struct gl518_data *data = client->data;
|
||||
int i, j, loop_more=1, min[3], max[3], delta[3];
|
||||
@@ -640,71 +687,79 @@ void gl518_update_vins(struct i2c_client *client)
|
||||
|
||||
alarm = data->alarms;
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
if (alarm & (1<<i)) {
|
||||
min[i] = 0;
|
||||
max[i] = 127;
|
||||
} else {
|
||||
min[i] = data->voltage_min[i];
|
||||
max[i] = (data->voltage_max[i]+data->voltage_min[i]) / 2;
|
||||
}
|
||||
delta[i] = (max[i] - min[i]) / 2;
|
||||
for (i=0; i<3; i++) {
|
||||
if (alarm & (1<<i)) {
|
||||
min[i] = 0;
|
||||
max[i] = 127;
|
||||
} else {
|
||||
min[i] = data->voltage_min[i];
|
||||
max[i] = (data->voltage_max[i]+data->voltage_min[i]) / 2;
|
||||
}
|
||||
delta[i] = (max[i] - min[i]) / 2;
|
||||
}
|
||||
|
||||
for (j=0; (j<10 && loop_more); j++) {
|
||||
|
||||
for (j=0; (j<10 && loop_more); j++) {
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
gl518_write_value(client, VIN_REG(i), max[i] << 8 | min[i]);
|
||||
|
||||
/* we wait now 1.5 seconds before comparing */
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule_timeout(HZ + HZ/2);
|
||||
alarm = gl518_read_value(client,GL518_REG_INT);
|
||||
|
||||
#ifdef DEBUG_VIN
|
||||
printk("gl518sm: iteration %2d: %4d%c %4d%c %4d%c\n", j,
|
||||
max[0], (alarm&1)?'!':' ',
|
||||
max[1], (alarm&2)?'!':' ',
|
||||
max[2], (alarm&4)?'!':' ');
|
||||
#endif
|
||||
|
||||
for (loop_more=0, i=0; i<3; i++) {
|
||||
if (alarm & (1<<i))
|
||||
max[i] += delta[i];
|
||||
else
|
||||
max[i] -= delta[i];
|
||||
|
||||
if (delta[i])
|
||||
loop_more++;
|
||||
delta[i] >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
if (alarm & (1<<i))
|
||||
max[i]++;
|
||||
gl518_write_value(client, VIN_REG(i), max[i] << 8 | min[i]);
|
||||
|
||||
if ((data->thread) &&
|
||||
((data->quit_thread) || signal_pending(current)))
|
||||
goto finish;
|
||||
|
||||
/* we wait now 1.5 seconds before comparing */
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule_timeout(HZ + HZ/2);
|
||||
|
||||
alarm = gl518_read_value(client,GL518_REG_INT);
|
||||
|
||||
#ifdef DEBUG_VIN
|
||||
printk("gl518sm: final :%5d %5d %5d\n", max[0], max[1], max[2]);
|
||||
printk("gl518sm: meter :%5d %5d %5d\n", data->voltage[0],
|
||||
data->voltage[1], data->voltage[2]);
|
||||
printk("gl518sm: iteration %2d: %4d%c %4d%c %4d%c\n", j,
|
||||
max[0], (alarm&1)?'!':' ',
|
||||
max[1], (alarm&2)?'!':' ',
|
||||
max[2], (alarm&4)?'!':' ');
|
||||
#endif
|
||||
|
||||
data->last_updated_v00 = jiffies;
|
||||
|
||||
/* reset beeps & irqs for vin0-2*/
|
||||
gl518_write_value(client,GL518_REG_ALARM, beeps);
|
||||
gl518_write_value(client,GL518_REG_MASK, irqs);
|
||||
for (loop_more=0, i=0; i<3; i++) {
|
||||
if (alarm & (1<<i))
|
||||
max[i] += delta[i];
|
||||
else
|
||||
max[i] -= delta[i];
|
||||
|
||||
/* set values */
|
||||
for (i=0; i<3; i++) {
|
||||
data->iter_voltage[i] = max[i];
|
||||
gl518_write_value(client, VIN_REG(i),
|
||||
data->voltage_max[i] << 8 | data->voltage_min[i]);
|
||||
}
|
||||
if (delta[i])
|
||||
loop_more++;
|
||||
delta[i] >>= 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* finally read the vin3 meter */
|
||||
data->iter_voltage[3] = gl518_read_value(client,GL518_REG_VIN3);
|
||||
for (i=0; i<3; i++)
|
||||
if (alarm & (1<<i))
|
||||
max[i]++;
|
||||
|
||||
#ifdef DEBUG_VIN
|
||||
printk("gl518sm: final :%5d %5d %5d\n", max[0], max[1], max[2]);
|
||||
printk("gl518sm: meter :%5d %5d %5d\n", data->voltage[0],
|
||||
data->voltage[1], data->voltage[2]);
|
||||
#endif
|
||||
|
||||
/* update values, including vin3 */
|
||||
for (i=0; i<3; i++) {
|
||||
data->iter_voltage[i] = max[i];
|
||||
}
|
||||
data->iter_voltage[3] = gl518_read_value(client,GL518_REG_VIN3);
|
||||
data->last_updated_v00 = jiffies;
|
||||
|
||||
finish:
|
||||
|
||||
/* reset values */
|
||||
for (i=0; i<3; i++) {
|
||||
gl518_write_value(client, VIN_REG(i),
|
||||
data->voltage_max[i] << 8 | data->voltage_min[i]);
|
||||
}
|
||||
|
||||
gl518_write_value(client,GL518_REG_ALARM, beeps);
|
||||
gl518_write_value(client,GL518_REG_MASK, irqs);
|
||||
|
||||
#undef VIN_REG
|
||||
}
|
||||
@@ -790,11 +845,19 @@ void gl518_fan(struct i2c_client *client, int operation, int ctl_name,
|
||||
DIV_FROM_REG(data->fan_div[nr]));
|
||||
old = gl518_read_value(client,GL518_REG_FAN_LIMIT);
|
||||
|
||||
if (nr == 0)
|
||||
old = (old & 0x00ff) | (data->fan_min[nr] << 8);
|
||||
else
|
||||
old = (old & 0xff00) | data->fan_min[nr];
|
||||
|
||||
if (nr == 0) {
|
||||
old = (old & 0x00ff) | (data->fan_min[0] << 8);
|
||||
if (results[0]==0)
|
||||
data->alarm_mask &= ~0x20;
|
||||
else
|
||||
data->alarm_mask |= 0x20;
|
||||
} else {
|
||||
old = (old & 0xff00) | data->fan_min[1];
|
||||
if (results[0]==0)
|
||||
data->alarm_mask &= ~0x40;
|
||||
else
|
||||
data->alarm_mask |= 0x40;
|
||||
}
|
||||
gl518_write_value(client,GL518_REG_FAN_LIMIT,old);
|
||||
}
|
||||
}
|
||||
@@ -833,7 +896,7 @@ void gl518_beep(struct i2c_client *client, int operation, int ctl_name,
|
||||
(data->beep_enable << 2));
|
||||
}
|
||||
if (*nrels_mag >= 2) {
|
||||
data->beeps = BEEPS_TO_REG(results[1]);
|
||||
data->beeps = BEEPS_TO_REG(results[1]) & data->alarm_mask;
|
||||
gl518_write_value(client,GL518_REG_ALARM,data->beeps);
|
||||
}
|
||||
}
|
||||
@@ -904,12 +967,20 @@ void gl518_iterate(struct i2c_client *client, int operation, int ctl_name,
|
||||
*nrels_mag = 1;
|
||||
} 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;
|
||||
data->iter_voltage[i] = 105; /* bogus */
|
||||
}
|
||||
data->iterate=results[0];
|
||||
for (i=0; i<4; i++) {
|
||||
data->voltage[i]=0;
|
||||
data->iter_voltage[i]=0;
|
||||
}
|
||||
data->valid=0;
|
||||
|
||||
if ((data->iterate != 2) && (data->thread)) {
|
||||
data->quit_thread = 1;
|
||||
wake_up_interruptible(&data->wq);
|
||||
} else if ((data->iterate==2) && (! data->thread)) {
|
||||
data->wq = NULL;
|
||||
kernel_thread(gl518_update_thread, (void*) client, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+79
-41
@@ -75,7 +75,9 @@ That's why _TEMP2 and _VIN4 access the same register
|
||||
#define GL520_REG_VIN1 0x14
|
||||
#define GL520_REG_VDD 0x15
|
||||
#define GL520_REG_TEMP2_OVER 0x17
|
||||
#define GL520_REG_VIN4_MAX 0x17
|
||||
#define GL520_REG_TEMP2_HYST 0x18
|
||||
#define GL520_REG_VIN4_MIN 0x18
|
||||
|
||||
|
||||
/* Conversions. Rounding and limit checking is only done on the TO_REG
|
||||
@@ -128,6 +130,7 @@ extern inline u8 FAN_TO_REG(long rpm, int div)
|
||||
#define GL520_INIT_VIN_1 330 /* 3.3 V */
|
||||
#define GL520_INIT_VIN_2 286 /* 12 V */
|
||||
#define GL520_INIT_VIN_3 260 /* Vcore */
|
||||
#define GL520_INIT_VIN_4 160 /* -12 V */
|
||||
#define GL520_INIT_VDD 500 /* 5 V */
|
||||
|
||||
#define GL520_INIT_PERCENTAGE 10
|
||||
@@ -170,8 +173,10 @@ struct gl520_data {
|
||||
u8 temp_over[2]; /* Register values */
|
||||
u8 temp_hyst[2]; /* Register values */
|
||||
u8 alarms,beeps,vid; /* Register value */
|
||||
u8 alarm_mask; /* Register value */
|
||||
u8 fan_div[2]; /* Register encoding, shifted right */
|
||||
u8 beep_enable; /* Boolean */
|
||||
u8 two_temps; /* Boolean */
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
@@ -375,6 +380,8 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
|
||||
data->sysctl_id = i;
|
||||
|
||||
/* Initialize the GL520SM chip */
|
||||
data->two_temps=1;
|
||||
data->alarm_mask=0xff;
|
||||
gl520_init_client((struct i2c_client *) new_client);
|
||||
return 0;
|
||||
|
||||
@@ -413,6 +420,7 @@ void gl520_init_client(struct i2c_client *client)
|
||||
gl520_write_value(client,GL520_REG_TEMP1_OVER,
|
||||
TEMP_TO_REG(GL520_INIT_TEMP_OVER));
|
||||
|
||||
/* We set Temp2, but not Vin4. */
|
||||
gl520_write_value(client,GL520_REG_TEMP2_HYST,
|
||||
TEMP_TO_REG(GL520_INIT_TEMP_HYST));
|
||||
gl520_write_value(client,GL520_REG_TEMP2_OVER,
|
||||
@@ -534,6 +542,7 @@ void gl520_update_client(struct i2c_client *client)
|
||||
|
||||
data->alarms = gl520_read_value(client,GL520_REG_INT);
|
||||
data->beeps = gl520_read_value(client,GL520_REG_ALARM);
|
||||
data->vid = gl520_read_value(client,GL520_REG_VID) & 0x1f;
|
||||
|
||||
val = gl520_read_value(client,GL520_REG_VDD_LIMIT);
|
||||
data->voltage_min[0] = val & 0xff;
|
||||
@@ -548,11 +557,6 @@ void gl520_update_client(struct i2c_client *client)
|
||||
data->voltage_min[3] = val & 0xff;
|
||||
data->voltage_max[3] = (val >> 8) & 0xff;
|
||||
|
||||
data->voltage[0] = gl520_read_value(client,GL520_REG_VDD);
|
||||
data->voltage[1] = gl520_read_value(client,GL520_REG_VIN1);
|
||||
data->voltage[2] = gl520_read_value(client,GL520_REG_VIN2);
|
||||
data->voltage[3] = gl520_read_value(client,GL520_REG_VIN3);
|
||||
|
||||
val = gl520_read_value(client,GL520_REG_FAN_COUNT);
|
||||
data->fan[0] = (val >> 8) & 0xff;
|
||||
data->fan[1] = val & 0xff;
|
||||
@@ -560,28 +564,34 @@ void gl520_update_client(struct i2c_client *client)
|
||||
val = gl520_read_value(client,GL520_REG_FAN_LIMIT);
|
||||
data->fan_min[0] = (val >> 8) & 0xff;
|
||||
data->fan_min[1] = val & 0xff;
|
||||
|
||||
|
||||
data->temp[0] = gl520_read_value(client,GL520_REG_TEMP1);
|
||||
data->temp_over[0] = gl520_read_value(client,GL520_REG_TEMP1_OVER);
|
||||
data->temp_hyst[0] = gl520_read_value(client,GL520_REG_TEMP1_HYST);
|
||||
|
||||
data->temp[1] = gl520_read_value(client,GL520_REG_TEMP2);
|
||||
data->temp_over[1] = gl520_read_value(client,GL520_REG_TEMP2_OVER);
|
||||
data->temp_hyst[1] = gl520_read_value(client,GL520_REG_TEMP2_HYST);
|
||||
|
||||
val = gl520_read_value(client,GL520_REG_MISC);
|
||||
data->fan_div[0] = (val >> 6) & 0x03;
|
||||
data->fan_div[1] = (val >> 4) & 0x03;
|
||||
|
||||
data->alarms &= data->alarm_mask;
|
||||
|
||||
if (data->fan_min[0]==0xff)
|
||||
data->alarms &= ~GL520_ALARM_FAN1;
|
||||
|
||||
if (data->fan_min[1]==0xff)
|
||||
data->alarms &= ~GL520_ALARM_FAN2;
|
||||
|
||||
val = gl520_read_value(client, GL520_REG_CONF);
|
||||
data->beep_enable = (val >> 2) & 1;
|
||||
|
||||
data->voltage[0] = gl520_read_value(client,GL520_REG_VDD);
|
||||
data->voltage[1] = gl520_read_value(client,GL520_REG_VIN1);
|
||||
data->voltage[2] = gl520_read_value(client,GL520_REG_VIN2);
|
||||
data->voltage[3] = gl520_read_value(client,GL520_REG_VIN3);
|
||||
|
||||
/* Temp1 and Vin4 are the same input */
|
||||
data->temp[1] = gl520_read_value(client,GL520_REG_TEMP2);
|
||||
data->temp_over[1] = gl520_read_value(client,GL520_REG_TEMP2_OVER);
|
||||
data->temp_hyst[1] = gl520_read_value(client,GL520_REG_TEMP2_HYST);
|
||||
|
||||
data->voltage[4] = gl520_read_value(client,GL520_REG_VIN4);
|
||||
data->voltage_min[4] = gl520_read_value(client,GL520_REG_VIN4_MIN);
|
||||
data->voltage_max[4] = gl520_read_value(client,GL520_REG_VIN4_MAX);
|
||||
|
||||
data->last_updated = jiffies;
|
||||
data->valid = 1;
|
||||
}
|
||||
@@ -593,22 +603,29 @@ void gl520_temp(struct i2c_client *client, int operation, int ctl_name,
|
||||
int *nrels_mag, long *results)
|
||||
{
|
||||
struct gl520_data *data = client->data;
|
||||
int nr = ctl_name - GL520_SYSCTL_TEMP1;
|
||||
int regnr;
|
||||
|
||||
if (operation == SENSORS_PROC_REAL_INFO)
|
||||
*nrels_mag = 1;
|
||||
else if (operation == SENSORS_PROC_REAL_READ) {
|
||||
gl520_update_client(client);
|
||||
results[0] = TEMP_FROM_REG(data->temp_over[0]);
|
||||
results[1] = TEMP_FROM_REG(data->temp_hyst[0]);
|
||||
results[2] = TEMP_FROM_REG(data->temp[0]);
|
||||
results[0] = TEMP_FROM_REG(data->temp_over[nr]);
|
||||
results[1] = TEMP_FROM_REG(data->temp_hyst[nr]);
|
||||
results[2] = TEMP_FROM_REG(data->temp[nr]);
|
||||
*nrels_mag = 3;
|
||||
} else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
if ((nr==0) && (! data->two_temps))
|
||||
return;
|
||||
regnr=nr==0?GL520_REG_TEMP1_OVER:GL520_REG_TEMP2_OVER;
|
||||
if (*nrels_mag >= 1) {
|
||||
data->temp_over[0] = TEMP_TO_REG(results[0]);
|
||||
gl520_write_value(client,GL520_REG_TEMP1_OVER,data->temp_over[0]);
|
||||
data->temp_over[nr] = TEMP_TO_REG(results[nr]);
|
||||
gl520_write_value(client,regnr,data->temp_over[nr]);
|
||||
}
|
||||
regnr=nr==0?GL520_REG_TEMP1_HYST:GL520_REG_TEMP2_HYST;
|
||||
if (*nrels_mag >= 2) {
|
||||
data->temp_hyst[0] = TEMP_TO_REG(results[1]);
|
||||
gl520_write_value(client,GL520_REG_TEMP1_HYST,data->temp_hyst[0]);
|
||||
data->temp_hyst[nr] = TEMP_TO_REG(results[nr]);
|
||||
gl520_write_value(client,regnr,data->temp_hyst[nr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -632,18 +649,25 @@ void gl520_vin(struct i2c_client *client, int operation, int ctl_name,
|
||||
VDD_FROM_REG(data->voltage[nr]);
|
||||
*nrels_mag = 3;
|
||||
} else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
regnr=nr==0?GL520_REG_VDD_LIMIT:nr==1?GL520_REG_VIN1_LIMIT:nr==2?
|
||||
GL520_REG_VIN2_LIMIT:GL520_REG_VIN3_LIMIT;
|
||||
if (*nrels_mag == 1)
|
||||
old = gl520_read_value(client,regnr) & 0xff00;
|
||||
if (*nrels_mag >= 2) {
|
||||
data->voltage_max[nr] = nr?IN_TO_REG(results[1]):VDD_TO_REG(results[1]);
|
||||
old = data->voltage_max[nr] << 8;
|
||||
}
|
||||
if (*nrels_mag >= 1) {
|
||||
data->voltage_min[nr] = nr?IN_TO_REG(results[0]):VDD_TO_REG(results[0]);
|
||||
old |= data->voltage_min[nr];
|
||||
gl520_write_value(client,regnr,old);
|
||||
if (nr!=4) {
|
||||
regnr=nr==0?GL520_REG_VDD_LIMIT:nr==1?GL520_REG_VIN1_LIMIT:nr==2?
|
||||
GL520_REG_VIN2_LIMIT:GL520_REG_VIN3_LIMIT;
|
||||
if (*nrels_mag == 1)
|
||||
old = gl520_read_value(client,regnr) & 0xff00;
|
||||
if (*nrels_mag >= 2) {
|
||||
data->voltage_max[nr] = nr?IN_TO_REG(results[1]):VDD_TO_REG(results[1]);
|
||||
old = data->voltage_max[nr] << 8;
|
||||
}
|
||||
if (*nrels_mag >= 1) {
|
||||
data->voltage_min[nr] = nr?IN_TO_REG(results[0]):VDD_TO_REG(results[0]);
|
||||
old |= data->voltage_min[nr];
|
||||
gl520_write_value(client,regnr,old);
|
||||
}
|
||||
} else if (! data->two_temps) {
|
||||
if (*nrels_mag == 1)
|
||||
gl520_write_value(client,GL520_REG_VIN4_MIN,IN_TO_REG(results[0]));
|
||||
if (*nrels_mag >= 2)
|
||||
gl520_write_value(client,GL520_REG_VIN4_MAX,IN_TO_REG(results[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -670,11 +694,19 @@ void gl520_fan(struct i2c_client *client, int operation, int ctl_name,
|
||||
DIV_FROM_REG(data->fan_div[nr]));
|
||||
old = gl520_read_value(client,GL520_REG_FAN_LIMIT);
|
||||
|
||||
if (nr == 0)
|
||||
if (nr == 0) {
|
||||
old = (old & 0x00ff) | (data->fan_min[nr] << 8);
|
||||
else
|
||||
if (results[0]==0)
|
||||
data->alarm_mask &= ~0x20;
|
||||
else
|
||||
data->alarm_mask |= 0x20;
|
||||
} else {
|
||||
old = (old & 0xff00) | data->fan_min[nr];
|
||||
|
||||
if (results[0]==0)
|
||||
data->alarm_mask &= ~0x40;
|
||||
else
|
||||
data->alarm_mask |= 0x40;
|
||||
}
|
||||
gl520_write_value(client,GL520_REG_FAN_LIMIT,old);
|
||||
}
|
||||
}
|
||||
@@ -713,7 +745,7 @@ void gl520_beep(struct i2c_client *client, int operation, int ctl_name,
|
||||
(data->beep_enable << 2));
|
||||
}
|
||||
if (*nrels_mag >= 2) {
|
||||
data->beeps = BEEPS_TO_REG(results[1]);
|
||||
data->beeps = BEEPS_TO_REG(results[1]) & data->alarm_mask;
|
||||
gl520_write_value(client,GL520_REG_ALARM,data->beeps);
|
||||
}
|
||||
}
|
||||
@@ -781,17 +813,23 @@ void gl520_fan1off(struct i2c_client *client, int operation, int ctl_name,
|
||||
void gl520_config(struct i2c_client *client, int operation, int ctl_name,
|
||||
int *nrels_mag, long *results)
|
||||
{
|
||||
struct gl520_data *data = client->data;
|
||||
int old;
|
||||
if (operation == SENSORS_PROC_REAL_INFO)
|
||||
*nrels_mag = 0;
|
||||
else if (operation == SENSORS_PROC_REAL_READ) {
|
||||
results[0] = ((gl520_read_value(client, GL520_REG_CONF) & 0x10)==0);
|
||||
data->two_temps = results[0];
|
||||
*nrels_mag = 1;
|
||||
} else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
if (*nrels_mag >= 1) {
|
||||
old = gl520_read_value(client, GL520_REG_CONF) & 0xef;
|
||||
if (! results[1])
|
||||
if (! results[1]) {
|
||||
old |= 0x10;
|
||||
data->two_temps=0;
|
||||
} else {
|
||||
data->two_temps=1;
|
||||
}
|
||||
gl520_write_value(client,GL520_REG_CONF,old);
|
||||
}
|
||||
}
|
||||
@@ -831,7 +869,7 @@ EXPORT_NO_SYMBOLS;
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
|
||||
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Kyösti Mälkki <kmalkki@cc.hut.fi>");
|
||||
MODULE_DESCRIPTION("GL520SM driver");
|
||||
|
||||
int init_module(void)
|
||||
|
||||
Reference in new issue
Block a user