2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-08-31 14:25:39 +00:00

Fujitsu Poseidon support from Hermann Jung <hej@odn.de>

git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@1179 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Mark D. Studebaker
2001-09-18 15:20:15 +00:00
parent 27fb86918e
commit d78cb7b93b
13 changed files with 1188 additions and 1 deletions

View File

@@ -62,3 +62,5 @@ problems.
Author of the DEC Tsunami bus driver.
* Christophe Gauthron <chrisg@0-in.com>
Author of the IT87 driver.
* Hermann Jung <hej@odn.de>
Author of the fscpos driver.

1
README
View File

@@ -50,6 +50,7 @@ At least the following hardware sensor chips are supported:
Asus AS99127F
Dallas Semiconductor DS75, DS1621, DS1625, DS1775, and DS1780
Hewlett Packard Maxilife (several revisions including '99 NBA)
Fujitsu Siemens Poseidon Chip
Genesys Logic GL518SM (rev 00, 80), GL520SM, GL523SM
Intel Xeon processor embedded sensors
ITE IT8705F, IT8712F embedded sensors

122
doc/chips/fscpos Normal file
View File

@@ -0,0 +1,122 @@
Kernel driver `fscpos.o'
======================
Status: Beta
tested with motherboard d1107
think twice before you're using the write mode of some
variables, especially the watchdog
Supported chips:
* fujitsu siemens poseidon chip
Prefix `fscpos'
Addresses scanned: I2C 0x73
Author: Hermann Jung <hej@odn.de>
Module Parameters
-----------------
* force: short array (min = 1, max = 48)
List of adapter,address pairs to boldly assume to be present
* ignore: short array (min = 1, max = 48)
List of adapter,address pairs not to scan
* ignore_range: short array (min = 1, max = 48)
List of adapter,start-addr,end-addr triples not to scan
* probe: short array (min = 1, max = 48)
List of adapter,address pairs to scan additionally
* probe_range: short array (min = 1, max = 48)
List of adapter,start-addr,end-addr triples to scan additionally
Description
-----------
This driver implements support for the Fujitsu Siemens Poseidon chip.
It is descibed in the 'Register Set Specification BMC Poseidon based Systemboard'
from Fujitsu Siemens.
The poseidon chip implements a hardware based system management for e. g. controlling
fan speed and core voltage.
There is also a watchdog counter on the chip which can trigger an alarm and even
shutdown the system.
The chip provides three temperature values (cpu, motherboard and auxiliary),
three current values (12 volt, 5 volt and batterie) and
three fans (power supply, cpu and auxiliary).
Temperatures are measured in degrees Celcius. The resolution is 1 degree.
FAN rotation speeds are reported in RPM (rotations per minute).
The value can be divided by a programmable divider (1, 2, 4 or 8) which
is stord on the chip.
Voltage sensors (also known as IN sensors) report their values in volts.
All values are reported as final values from the driver.
There is not need for further calculations
Chip Features
-------------
Chip `fscpos'
LABEL LABEL CLASS COMPUTE CLASS ACCESS MAGNITUDE
rev NONE NONE R 0
event NONE NONE R 0
control NONE NONE RW 0
volt12 NONE NONE R 2
volt5 NONE NONE R 2
voltbatt NONE NONE R 2
temp1 NONE NONE R 0
temp2 NONE NONE R 0
temp3 NONE NONE R 0
temp1_state temp1 temp1 RW 0
temp2_state temp2 temp2 RW 0
temp3_state temp3 temp3 RW 0
fan1 NONE NONE R 0
fan2 NONE NONE R 0
fan3 NONE NONE R 0
fan1_min fan1 fan1 RW 0
fan2_min fan2 fan2 RW 0
fan1_state fan1 fan1 RW 0
fan2_state fan2 fan2 RW 0
fan3_state fan3 fan3 RW 0
fan1_ripple fan1 fan1 RW 0
fan2_ripple fan2 fan2 RW 0
fan3_ripple fan3 fan3 RW 0
wdog_preset NONE NONE RW 0
wdog_state wdog_preset wdog_preset RW 0
wdog_control wdog_preset wdog_preset RW 0
LABEL FEATURE SYMBOL SYSCTL FILE:OFFSET
rev FSCPOS_SYSCTL_REV rev:1
event FSCPOS_SYSCTL_EVENT event:1
control FSCPOS_SYSCTL_CONTROL control:1
volt12 FSCPOS_SYSCTL_VOLTAGE1 volt0:1
volt5 FSCPOS_SYSCTL_VOLTAGE2 volt1:1
voltbatt FSCPOS_SYSCTL_VOLTAGE3 volt2:1
temp1 FSCPOS_SYSCTL_TEMP1 temp0:2
temp2 FSCPOS_SYSCTL_TEMP2 temp1:2
temp3 FSCPOS_SYSCTL_TEMP3 temp2:2
temp1_state FSCPOS_SYSCTL_TEMP1_STATE temp0:1
temp2_state FSCPOS_SYSCTL_TEMP2_STATE temp1:1
temp3_state FSCPOS_SYSCTL_TEMP3_STATE temp2:1
fan1 FSCPOS_SYSCTL_FAN1 fan0:4
fan2 FSCPOS_SYSCTL_FAN2 fan1:4
fan3 FSCPOS_SYSCTL_FAN3 fan2:4
fan1_min FSCPOS_SYSCTL_FAN1_MIN fan0:2
fan2_min FSCPOS_SYSCTL_FAN2_MIN fan1:2
fan1_state FSCPOS_SYSCTL_FAN1_STATE fan0:1
fan2_state FSCPOS_SYSCTL_FAN2_STATE fan1:1
fan3_state FSCPOS_SYSCTL_FAN3_STATE fan2:1
fan1_ripple FSCPOS_SYSCTL_FAN1_RIPPLE fan0:3
fan2_ripple FSCPOS_SYSCTL_FAN2_RIPPLE fan1:3
fan3_ripple FSCPOS_SYSCTL_FAN3_RIPPLE fan2:3
wdog_preset FSCPOS_SYSCTL_WDOG_PRESET wdog:1
wdog_state FSCPOS_SYSCTL_WDOG_STATE wdog:2
wdog_control FSCPOS_SYSCTL_WDOG_CONTROL wdog:3

View File

@@ -1117,3 +1117,24 @@ chip "it87-*"
# set fan1_min 3000
# ignore fan2
# ignore fan3
#
# values for the fujitsu siemens poseidon chip
#
# Temperature
label temp1 "Temp1/CPU"
label temp2 "Temp2/MB"
label temp3 "Temp2/AUX"
# Fans
label fan1 "Fan1"
ignore fan2
ignore fan3
# Voltage
label volt12 "12 V"
label volt5 " 5 V"
label voltbatt " 3.3 V"

View File

@@ -26,6 +26,7 @@ KERNELCHIPSDIR := $(MODULE_DIR)
# These targets are NOT included in 'mkpatch' ...
KERNELCHIPSTARGETS := \
$(MODULE_DIR)/adm1024.o \
$(MODULE_DIR)/fscpos.o \
$(MODULE_DIR)/it87.o \
$(MODULE_DIR)/maxilife.o \
$(MODULE_DIR)/mtp008.o

777
kernel/chips/fscpos.c Normal file
View File

@@ -0,0 +1,777 @@
/*
fscpos.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (c) 2001 Hermann Jung <hej@odn.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
fujitsu siemens poseidon chip,
module based on lm80.c
Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
and Philip Edelbrock <phil@netroedge.com>
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/proc_fs.h>
#include <linux/ioport.h>
#include <linux/sysctl.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include "version.h"
#include "sensors.h"
#include <linux/init.h>
/* temporary defines */
#define I2C_DRIVERID_FSCPOS 0xabcd
/* -- end of temporary defines */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) || \
(LINUX_VERSION_CODE == KERNEL_VERSION(2,3,0))
#define init_MUTEX(s) do { *(s) = MUTEX; } while(0)
#endif
#ifndef THIS_MODULE
#define THIS_MODULE NULL
#endif
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x73, SENSORS_I2C_END };
static unsigned short normal_i2c_range[] = { SENSORS_I2C_END };
static unsigned int normal_isa[] = { SENSORS_ISA_END };
static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
/* Insmod parameters */
SENSORS_INSMOD_1(fscpos);
/* The FSCPOS registers */
/* chip identification */
#define FSCPOS_REG_IDENT_0 0x00
#define FSCPOS_REG_IDENT_1 0x01
#define FSCPOS_REG_IDENT_2 0x02
#define FSCPOS_REG_REVISION 0x03
/* global control and status */
#define FSCPOS_REG_EVENT_STATE 0x04
#define FSCPOS_REG_CONTROL 0x05
/* watchdog */
#define FSCPOS_REG_WDOG_PRESET 0x28
#define FSCPOS_REG_WDOG_STATE 0x23
#define FSCPOS_REG_WDOG_CONTROL 0x21
/* fan 0 */
#define FSCPOS_REG_FAN0_MIN 0x55
#define FSCPOS_REG_FAN0_ACT 0x0e
#define FSCPOS_REG_FAN0_STATE 0x0d
#define FSCPOS_REG_FAN0_RIPPLE 0x0f
/* fan 1 */
#define FSCPOS_REG_FAN1_MIN 0x65
#define FSCPOS_REG_FAN1_ACT 0x6b
#define FSCPOS_REG_FAN1_STATE 0x62
#define FSCPOS_REG_FAN1_RIPPLE 0x6f
/* fan 2 */
/* min speed fan2 not supported */
#define FSCPOS_REG_FAN2_ACT 0xab
#define FSCPOS_REG_FAN2_STATE 0xa2
#define FSCPOS_REG_FAN2_RIPPLE 0x0af
/* voltage supervision */
#define FSCPOS_REG_VOLT_12 0x45
#define FSCPOS_REG_VOLT_5 0x42
#define FSCPOS_REG_VOLT_BATT 0x48
/* temperatures */
/* sensor 0 */
#define FSCPOS_REG_TEMP0_ACT 0x64
#define FSCPOS_REG_TEMP0_STATE 0x71
/* sensor 1 */
#define FSCPOS_REG_TEMP1_ACT 0x32
#define FSCPOS_REG_TEMP1_STATE 0x81
/* sensor 2 */
#define FSCPOS_REG_TEMP2_ACT 0x35
#define FSCPOS_REG_TEMP2_STATE 0x91
/* Conversions. Rounding and limit checking is only done on the TO_REG
variants. Note that you should be a bit careful with which arguments
these macros are called: arguments may be evaluated more than once.
Fixing this is just not worth it. */
#define IN_TO_REG(val,nr) (SENSORS_LIMIT((val),0,255))
#define IN_FROM_REG(val,nr) (val)
/* Initial limits */
#ifdef MODULE
extern int init_module(void);
extern int cleanup_module(void);
#endif /* MODULE */
/* For each registered FSCPOS, we need to keep some data in memory. That
data is pointed to by fscpos_list[NR]->data. The structure itself is
dynamically allocated, at the same time when a new fscpos client is
allocated. */
struct fscpos_data {
int sysctl_id;
struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
u8 revision; /* revision of chip */
u8 global_event; /* global event status */
u8 global_control; /* global control register */
u8 watchdog[3]; /* watchdog */
u8 volt[3]; /* 12, 5, battery current */
u8 temp_act[3]; /* temperature */
u8 temp_status[3]; /* status of sensor */
u8 fan_act[3]; /* fans revolutions per second */
u8 fan_status[3]; /* fan status */
u8 fan_min[3]; /* fan min value for rps */
u8 fan_ripple[3]; /* divider for rps */
};
#ifdef MODULE
static
#else
extern
#endif
int __init sensors_fscpos_init(void);
static int __init fscpos_cleanup(void);
static int fscpos_attach_adapter(struct i2c_adapter *adapter);
static int fscpos_detect(struct i2c_adapter *adapter, int address,
unsigned short flags, int kind);
static int fscpos_detach_client(struct i2c_client *client);
static int fscpos_command(struct i2c_client *client, unsigned int cmd,
void *arg);
static void fscpos_inc_use(struct i2c_client *client);
static void fscpos_dec_use(struct i2c_client *client);
static int fscpos_read_value(struct i2c_client *client, u8 register);
static int fscpos_write_value(struct i2c_client *client, u8 register,
u8 value);
static void fscpos_update_client(struct i2c_client *client);
static void fscpos_init_client(struct i2c_client *client);
static void fscpos_in(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results);
static void fscpos_fan(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
static void fscpos_fan_internal(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results,
int nr, int reg_state, int reg_min, int res_ripple);
static void fscpos_temp(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
static void fscpos_volt(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
static void fscpos_wdog(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results);
static int fscpos_id = 0;
static struct i2c_driver fscpos_driver = {
/* name */ "FSCPOS sensor driver",
/* id */ I2C_DRIVERID_FSCPOS,
/* flags */ I2C_DF_NOTIFY,
/* attach_adapter */ &fscpos_attach_adapter,
/* detach_client */ &fscpos_detach_client,
/* command */ &fscpos_command,
/* inc_use */ &fscpos_inc_use,
/* dec_use */ &fscpos_dec_use
};
/* Used by fscpos_init/cleanup */
static int __initdata fscpos_initialized = 0;
/* The /proc/sys entries */
/* These files are created for each detected FSCPOS. This is just a template;
though at first sight, you might think we could use a statically
allocated list, we need some way to get back to the parent - which
is done through one of the 'extra' fields which are initialized
when a new copy is allocated. */
static ctl_table fscpos_dir_table_template[] = {
{FSCPOS_SYSCTL_REV, "rev", NULL, 0, 0444, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_in},
{FSCPOS_SYSCTL_EVENT, "event", NULL, 0, 0444, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_in},
{FSCPOS_SYSCTL_CONTROL, "control", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_in},
{FSCPOS_SYSCTL_TEMP0, "temp0", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_temp},
{FSCPOS_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_temp},
{FSCPOS_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_temp},
{FSCPOS_SYSCTL_VOLT0, "volt0", NULL, 0, 0444, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_volt},
{FSCPOS_SYSCTL_VOLT1, "volt1", NULL, 0, 0444, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_volt},
{FSCPOS_SYSCTL_VOLT2, "volt2", NULL, 0, 0444, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_volt},
{FSCPOS_SYSCTL_FAN0, "fan0", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_fan},
{FSCPOS_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_fan},
{FSCPOS_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_fan},
{FSCPOS_SYSCTL_WDOG, "wdog", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &fscpos_wdog},
{0}
};
int fscpos_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_detect(adapter, &addr_data, fscpos_detect);
}
int fscpos_detect(struct i2c_adapter *adapter, int address,
unsigned short flags, int kind)
{
int i;
struct i2c_client *new_client;
struct fscpos_data *data;
int err = 0;
const char *type_name, *client_name;
/* Make sure we aren't probing the ISA bus!! This is just a safety check
at this moment; i2c_detect really won't call us. */
#ifdef DEBUG
if (i2c_is_isa_adapter(adapter)) {
printk
("fscpos.o: fscpos_detect called for an ISA bus adapter?!?\n");
return 0;
}
#endif
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto ERROR0;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access fscpos_{read,write}_value. */
if (!(new_client = kmalloc(sizeof(struct i2c_client) +
sizeof(struct fscpos_data),
GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR0;
}
data = (struct fscpos_data *) (new_client + 1);
new_client->addr = address;
new_client->data = data;
new_client->adapter = adapter;
new_client->driver = &fscpos_driver;
new_client->flags = 0;
/* Now, we do the remaining detection. */
if (fscpos_read_value(new_client, FSCPOS_REG_IDENT_0) != 0x50)
goto ERROR1;
if (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1) != 0x45)
goto ERROR1;
if (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) != 0x47)
goto ERROR1;
/* Determine the chip type - only one kind supported! */
if (kind <= 0)
kind = fscpos;
if (kind == fscpos) {
type_name = "fscpos";
client_name = "fsc poseidon chip";
} else {
#ifdef DEBUG
printk("fscpos.o: Internal error: unknown kind (%d)?!?",
kind);
#endif
goto ERROR1;
}
/* Fill in the remaining client fields and put it into the global list */
strcpy(new_client->name, client_name);
new_client->id = fscpos_id++;
data->valid = 0;
init_MUTEX(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto ERROR3;
/* Register a new directory entry with module sensors */
if ((i = i2c_register_entry(new_client, type_name,
fscpos_dir_table_template,
THIS_MODULE)) < 0) {
err = i;
goto ERROR4;
}
data->sysctl_id = i;
fscpos_init_client(new_client);
return 0;
/* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */
ERROR4:
i2c_detach_client(new_client);
ERROR3:
ERROR1:
kfree(new_client);
ERROR0:
return err;
}
int fscpos_detach_client(struct i2c_client *client)
{
int err;
i2c_deregister_entry(((struct fscpos_data *) (client->data))->
sysctl_id);
if ((err = i2c_detach_client(client))) {
printk
("fscpos.o: Client deregistration failed, client not detached.\n");
return err;
}
kfree(client);
return 0;
}
/* No commands defined yet */
int fscpos_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
return 0;
}
void fscpos_inc_use(struct i2c_client *client)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
void fscpos_dec_use(struct i2c_client *client)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
int fscpos_read_value(struct i2c_client *client, u8 reg)
{
#ifdef DEBUG
printk("fscpos: read reg 0x%02x\n",reg);
#endif
return i2c_smbus_read_byte_data(client, reg);
}
int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value)
{
#ifdef DEBUG
printk("fscpos: write reg 0x%02x, val 0x%02x\n",reg, value);
#endif
return i2c_smbus_write_byte_data(client, reg, value);
}
/* Called when we have found a new FSCPOS. It should set limits, etc. */
void fscpos_init_client(struct i2c_client *client)
{
struct fscpos_data *data = client->data;
/* read revision from chip */
data->revision = fscpos_read_value(client,FSCPOS_REG_REVISION);
/* setup missing fan2_min value */
data->fan_min[2] = 0xff;
}
void fscpos_update_client(struct i2c_client *client)
{
struct fscpos_data *data = client->data;
down(&data->update_lock);
if ((jiffies - data->last_updated > 2 * HZ) ||
(jiffies < data->last_updated) || !data->valid) {
#ifdef DEBUG
printk("Starting fscpos update\n");
#endif
data->temp_act[0] = fscpos_read_value(client, FSCPOS_REG_TEMP0_ACT);
data->temp_act[1] = fscpos_read_value(client, FSCPOS_REG_TEMP1_ACT);
data->temp_act[2] = fscpos_read_value(client, FSCPOS_REG_TEMP2_ACT);
data->temp_status[0] = fscpos_read_value(client, FSCPOS_REG_TEMP0_STATE);
data->temp_status[1] = fscpos_read_value(client, FSCPOS_REG_TEMP1_STATE);
data->temp_status[2] = fscpos_read_value(client, FSCPOS_REG_TEMP2_STATE);
data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12);
data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5);
data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT);
data->fan_act[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_ACT);
data->fan_act[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_ACT);
data->fan_act[2] = fscpos_read_value(client, FSCPOS_REG_FAN2_ACT);
data->fan_status[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_STATE);
data->fan_status[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_STATE);
data->fan_status[2] = fscpos_read_value(client, FSCPOS_REG_FAN2_STATE);
data->fan_min[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_MIN);
data->fan_min[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_MIN);
/* fan2_min is not supported */
data->fan_ripple[0] = fscpos_read_value(client, FSCPOS_REG_FAN0_RIPPLE);
data->fan_ripple[1] = fscpos_read_value(client, FSCPOS_REG_FAN1_RIPPLE);
data->fan_ripple[2] = fscpos_read_value(client, FSCPOS_REG_FAN2_RIPPLE);
data->watchdog[0] = fscpos_read_value(client, FSCPOS_REG_WDOG_PRESET);
data->watchdog[1] = fscpos_read_value(client, FSCPOS_REG_WDOG_STATE);
data->watchdog[2] = fscpos_read_value(client, FSCPOS_REG_WDOG_CONTROL);
data->last_updated = jiffies;
data->valid = 1;
}
up(&data->update_lock);
}
/* The next few functions are the call-back functions of the /proc/sys and
sysctl files. Which function is used is defined in the ctl_table in
the extra1 field.
Each function must return the magnitude (power of 10 to divide the date
with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
put a maximum of *nrels elements in results reflecting the data of this
file, and set *nrels to the number it actually put in it, if operation==
SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
large enough (by checking the incoming value of *nrels). This is not very
good practice, but as long as you put less than about 5 values in results,
you can assume it is large enough. */
void fscpos_in(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct fscpos_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
fscpos_update_client(client);
switch(ctl_name) {
case FSCPOS_SYSCTL_REV:
results[0] = data->revision ;
break;
case FSCPOS_SYSCTL_EVENT:
results[0] = data->global_event & 0x1f;
break;
case FSCPOS_SYSCTL_CONTROL:
results[0] = data->global_control & 0x01;
break;
default:
printk("fscpos: ctl_name %d not supported\n",
ctl_name);
*nrels_mag = 0;
return;
}
*nrels_mag = 1;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if((ctl_name == FSCPOS_SYSCTL_CONTROL) && (*nrels_mag >= 1)) {
data->global_control = (results[0] & 0x01);
printk("fscpos: writing 0x%02x to global_control\n",
data->global_control);
fscpos_write_value(client,FSCPOS_REG_CONTROL,
data->global_control);
}
else
printk("fscpos: writing to chip not supported\n");
}
}
#define TEMP_FROM_REG(val) (val-128)
void fscpos_temp(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct fscpos_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
fscpos_update_client(client);
switch(ctl_name) {
case FSCPOS_SYSCTL_TEMP0:
results[0] = data->temp_status[0] & 0x03;
results[1] = TEMP_FROM_REG(data->temp_act[0]);
break;
case FSCPOS_SYSCTL_TEMP1:
results[0] = data->temp_status[1] & 0x03;
results[1] = TEMP_FROM_REG(data->temp_act[1]);
break;
case FSCPOS_SYSCTL_TEMP2:
results[0] = data->temp_status[2] & 0x03;
results[1] = TEMP_FROM_REG(data->temp_act[2]);
break;
default:
printk("fscpos: ctl_name %d not supported\n",
ctl_name);
*nrels_mag = 0;
return;
}
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if(*nrels_mag >= 1) {
switch(ctl_name) {
case FSCPOS_SYSCTL_TEMP0:
data->temp_status[0] =
(data->temp_status[0] & ~0x02)
| (results[0] & 0x02);
printk("fscpos: writing value 0x%02x "
"to temp0_status\n",
data->temp_status[0]);
fscpos_write_value(client,
FSCPOS_REG_TEMP0_STATE,
data->temp_status[0] & 0x02);
break;
case FSCPOS_SYSCTL_TEMP1:
data->temp_status[1] = (data->temp_status[1] & ~0x02) | (results[0] & 0x02);
printk("fscpos: writing value 0x%02x to temp1_status\n", data->temp_status[1]);
fscpos_write_value(client,FSCPOS_REG_TEMP1_STATE,
data->temp_status[1] & 0x02);
break;
case FSCPOS_SYSCTL_TEMP2:
data->temp_status[2] = (data->temp_status[2] & ~0x02) | (results[0] & 0x02);
printk("fscpos: writing value 0x%02x to temp2_status\n", data->temp_status[2]);
fscpos_write_value(client,FSCPOS_REG_TEMP2_STATE,
data->temp_status[2] & 0x02);
break;
default:
printk("fscpos: ctl_name %d not supported\n",ctl_name);
}
}
else
printk("fscpos: writing to chip not supported\n");
}
}
#define VOLT_FROM_REG(val,mult) (val*mult/255)
void fscpos_volt(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct fscpos_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 2;
else if (operation == SENSORS_PROC_REAL_READ) {
fscpos_update_client(client);
switch(ctl_name) {
case FSCPOS_SYSCTL_VOLT0:
results[0] = VOLT_FROM_REG(data->volt[0],1420);
break;
case FSCPOS_SYSCTL_VOLT1:
results[0] = VOLT_FROM_REG(data->volt[1],660);
break;
case FSCPOS_SYSCTL_VOLT2:
results[0] = VOLT_FROM_REG(data->volt[2],330);
break;
default:
printk("fscpos: ctl_name %d not supported\n",
ctl_name);
*nrels_mag = 0;
return;
}
*nrels_mag = 1;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
printk("fscpos: writing to chip not supported\n");
}
}
void fscpos_fan(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
switch(ctl_name) {
case FSCPOS_SYSCTL_FAN0:
fscpos_fan_internal(client,operation,ctl_name,nrels_mag,results,
0,FSCPOS_REG_FAN0_STATE,FSCPOS_REG_FAN0_MIN,
FSCPOS_REG_FAN0_RIPPLE);
break;
case FSCPOS_SYSCTL_FAN1:
fscpos_fan_internal(client,operation,ctl_name,nrels_mag,results,
1,FSCPOS_REG_FAN1_STATE,FSCPOS_REG_FAN1_MIN,
FSCPOS_REG_FAN1_RIPPLE);
break;
case FSCPOS_SYSCTL_FAN2:
fscpos_fan_internal(client,operation,ctl_name,nrels_mag,results,
2,FSCPOS_REG_FAN2_STATE,0xff,
FSCPOS_REG_FAN2_RIPPLE);
break;
default:
printk("fscpos: illegal fan nr %d\n",ctl_name);
}
}
#define RPM_FROM_REG(val) (val*60)
void fscpos_fan_internal(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results, int nr,
int reg_state, int reg_min, int reg_ripple )
{
struct fscpos_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
fscpos_update_client(client);
results[0] = data->fan_status[nr] & 0x04;
results[1] = data->fan_min[nr];
results[2] = data->fan_ripple[nr] & 0x03;
results[3] = RPM_FROM_REG(data->fan_act[nr]);
*nrels_mag = 4;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if(*nrels_mag >= 1) {
data->fan_status[nr] = results[0] & 0x04;
printk("fscpos: writing value 0x%02x to fan%d_status\n",
data->fan_status[nr],nr);
fscpos_write_value(client,reg_state,
data->fan_status[nr]);
}
if((*nrels_mag >= 2) && (nr < 2)) {
/* minimal speed for fan2 not supported */
data->fan_min[nr] = results[1];
printk("fscpos: writing value 0x%02x to fan%d_min\n",
data->fan_min[nr],nr);
fscpos_write_value(client,reg_min,
data->fan_min[nr]);
}
if(*nrels_mag >= 3) {
if((results[2] & 0x03) == 0) {
printk("fscpos: fan%d ripple 0 not allowed\n",nr);
return;
}
data->fan_ripple[nr] = results[2] & 0x03;
printk("fscpos: writing value 0x%02x to fan%d_ripple\n",
data->fan_ripple[nr],nr);
fscpos_write_value(client,reg_ripple,
data->fan_ripple[nr]);
}
}
}
void fscpos_wdog(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct fscpos_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
fscpos_update_client(client);
results[0] = data->watchdog[0] ;
results[1] = data->watchdog[1] & 0x02;
results[2] = data->watchdog[2] & 0xb0;
*nrels_mag = 3;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
data->watchdog[0] = results[0] & 0xff;
printk("fscpos: writing value 0x%02x to wdog_preset\n",
data->watchdog[0]);
fscpos_write_value(client,FSCPOS_REG_WDOG_PRESET,
data->watchdog[0]);
}
if (*nrels_mag >= 2) {
data->watchdog[1] = results[1] & 0x02;
printk("fscpos: writing value 0x%02x to wdog_state\n",
data->watchdog[1]);
fscpos_write_value(client,FSCPOS_REG_WDOG_STATE,
data->watchdog[1]);
}
if (*nrels_mag >= 3) {
data->watchdog[2] = results[2] & 0xb0;
printk("fscpos: writing value 0x%02x to wdog_control\n",
data->watchdog[2]);
fscpos_write_value(client,FSCPOS_REG_WDOG_CONTROL,
data->watchdog[2]);
}
}
}
int __init sensors_fscpos_init(void)
{
int res;
printk("fscpos.o version %s (%s)\n", LM_VERSION, LM_DATE);
fscpos_initialized = 0;
if ((res = i2c_add_driver(&fscpos_driver))) {
printk
("fscpos.o: Driver registration failed, module not inserted.\n");
fscpos_cleanup();
return res;
}
fscpos_initialized++;
return 0;
}
int __init fscpos_cleanup(void)
{
int res;
if (fscpos_initialized >= 1) {
if ((res = i2c_del_driver(&fscpos_driver))) {
printk
("fscpos.o: Driver deregistration failed, module not removed.\n");
return res;
}
fscpos_initialized--;
}
return 0;
}
EXPORT_NO_SYMBOLS;
#ifdef MODULE
MODULE_AUTHOR
("Hermann Jung <hej@odn.de> based on work from Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>");
MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
int init_module(void)
{
return sensors_fscpos_init();
}
int cleanup_module(void)
{
return fscpos_cleanup();
}
#endif /* MODULE */

View File

@@ -506,4 +506,18 @@
#define IT87_ALARM_TEMP2 0x0002
#define IT87_ALARM_TEMP3 0x0004
#define FSCPOS_SYSCTL_VOLT0 1000 /* 12 volt supply */
#define FSCPOS_SYSCTL_VOLT1 1001 /* 5 volt supply */
#define FSCPOS_SYSCTL_VOLT2 1002 /* batterie voltage*/
#define FSCPOS_SYSCTL_FAN0 1101 /* state, min, ripple, actual value fan 0 */
#define FSCPOS_SYSCTL_FAN1 1102 /* state, min, ripple, actual value fan 1 */
#define FSCPOS_SYSCTL_FAN2 1103 /* state, min, ripple, actual value fan 2 */
#define FSCPOS_SYSCTL_TEMP0 1201 /* state and value of sensor 0, cpu die */
#define FSCPOS_SYSCTL_TEMP1 1202 /* state and value of sensor 1, motherboard */
#define FSCPOS_SYSCTL_TEMP2 1203 /* state and value of sensor 2, chassis */
#define FSCPOS_SYSCTL_REV 2000 /* Revision */
#define FSCPOS_SYSCTL_EVENT 2001 /* global event status */
#define FSCPOS_SYSCTL_CONTROL 2002 /* global control byte */
#define FSCPOS_SYSCTL_WDOG 2003 /* state, min, ripple, actual value fan 2 */
#endif /* def SENSORS_SENSORS_H */

View File

@@ -2236,6 +2236,77 @@ static sensors_chip_feature it87_features[] =
{ 0 }
};
static sensors_chip_feature fscpos_features[] =
{
{ SENSORS_FSCPOS_REV, "rev", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_REV, VALUE(1), 0 },
{ SENSORS_FSCPOS_EVENT, "event", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_EVENT, VALUE(1), 0 },
{ SENSORS_FSCPOS_CONTROL, "control", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_RW, FSCPOS_SYSCTL_CONTROL, VALUE(1), 0 },
{ SENSORS_FSCPOS_VOLTAGE1, "volt12", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_VOLT0, VALUE(1), 2 },
{ SENSORS_FSCPOS_VOLTAGE2, "volt5", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_VOLT1, VALUE(1), 2 },
{ SENSORS_FSCPOS_VOLTAGE3, "voltbatt", SENSORS_NO_MAPPING,
SENSORS_NO_MAPPING, SENSORS_MODE_R,
FSCPOS_SYSCTL_VOLT2, VALUE(1), 2 },
{ SENSORS_FSCPOS_TEMP1, "temp1", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_TEMP0, VALUE(2), 0 },
{ SENSORS_FSCPOS_TEMP2, "temp2", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_TEMP1, VALUE(2), 0 },
{ SENSORS_FSCPOS_TEMP3, "temp3", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_TEMP2, VALUE(2), 0 },
{ SENSORS_FSCPOS_TEMP1_STATE, "temp1_state", SENSORS_FSCPOS_TEMP1,
SENSORS_FSCPOS_TEMP1, SENSORS_MODE_RW,
FSCPOS_SYSCTL_TEMP0, VALUE(1), 0 },
{ SENSORS_FSCPOS_TEMP2_STATE, "temp2_state", SENSORS_FSCPOS_TEMP2,
SENSORS_FSCPOS_TEMP2, SENSORS_MODE_RW,
FSCPOS_SYSCTL_TEMP1, VALUE(1), 0 },
{ SENSORS_FSCPOS_TEMP3_STATE, "temp3_state", SENSORS_FSCPOS_TEMP3,
SENSORS_FSCPOS_TEMP3, SENSORS_MODE_RW,
FSCPOS_SYSCTL_TEMP2, VALUE(1), 0 },
{ SENSORS_FSCPOS_FAN1, "fan1", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_FAN0, VALUE(4), 0 },
{ SENSORS_FSCPOS_FAN2, "fan2", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_FAN1, VALUE(4), 0 },
{ SENSORS_FSCPOS_FAN3, "fan3", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
SENSORS_MODE_R, FSCPOS_SYSCTL_FAN2, VALUE(4), 0 },
{ SENSORS_FSCPOS_FAN1_MIN, "fan1_min", SENSORS_FSCPOS_FAN1,
SENSORS_FSCPOS_FAN1, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN0, VALUE(2), 0 },
{ SENSORS_FSCPOS_FAN2_MIN, "fan2_min", SENSORS_FSCPOS_FAN2,
SENSORS_FSCPOS_FAN2, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN1, VALUE(2), 0 },
{ SENSORS_FSCPOS_FAN1_STATE, "fan1_state", SENSORS_FSCPOS_FAN1,
SENSORS_FSCPOS_FAN1, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN0, VALUE(1), 0 },
{ SENSORS_FSCPOS_FAN2_STATE, "fan2_state", SENSORS_FSCPOS_FAN2,
SENSORS_FSCPOS_FAN2, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN1, VALUE(1), 0 },
{ SENSORS_FSCPOS_FAN3_STATE, "fan3_state", SENSORS_FSCPOS_FAN3,
SENSORS_FSCPOS_FAN3, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN2, VALUE(1), 0 },
{ SENSORS_FSCPOS_FAN1_RIPPLE, "fan1_ripple", SENSORS_FSCPOS_FAN1,
SENSORS_FSCPOS_FAN1, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN0, VALUE(3), 0 },
{ SENSORS_FSCPOS_FAN2_RIPPLE, "fan2_ripple", SENSORS_FSCPOS_FAN2,
SENSORS_FSCPOS_FAN2, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN1, VALUE(3), 0 },
{ SENSORS_FSCPOS_FAN3_RIPPLE, "fan3_ripple", SENSORS_FSCPOS_FAN3,
SENSORS_FSCPOS_FAN3, SENSORS_MODE_RW,
FSCPOS_SYSCTL_FAN2, VALUE(3), 0 },
{ SENSORS_FSCPOS_WDOG_PRESET, "wdog_preset", SENSORS_NO_MAPPING,
SENSORS_NO_MAPPING, SENSORS_MODE_RW,
FSCPOS_SYSCTL_WDOG, VALUE(1), 0 },
{ SENSORS_FSCPOS_WDOG_STATE, "wdog_state", SENSORS_FSCPOS_WDOG_PRESET,
SENSORS_FSCPOS_WDOG_PRESET, SENSORS_MODE_RW,
FSCPOS_SYSCTL_WDOG, VALUE(2), 0 },
{ SENSORS_FSCPOS_WDOG_CONTROL, "wdog_control", SENSORS_FSCPOS_WDOG_PRESET,
SENSORS_FSCPOS_WDOG_PRESET, SENSORS_MODE_RW,
FSCPOS_SYSCTL_WDOG, VALUE(3), 0 },
{ 0 }
};
sensors_chip_features sensors_chip_features_list[] =
@@ -2285,5 +2356,6 @@ sensors_chip_features sensors_chip_features_list[] =
{ SENSORS_DS1621_PREFIX, ds1621_features },
{ SENSORS_ADM1024_PREFIX, adm1024_features },
{ SENSORS_IT87_PREFIX, it87_features },
{ SENSORS_FSCPOS_PREFIX, fscpos_features },
{ 0 }
};

View File

@@ -1021,4 +1021,39 @@
#define SENSORS_IT87_ALARMS_VIN 82 /* R */
#define SENSORS_IT87_ALARMS_TEMP 83 /* R */
/* fsc poseidon chip */
#define SENSORS_FSCPOS_PREFIX "fscpos"
#define SENSORS_FSCPOS_REV 1 /* R */
#define SENSORS_FSCPOS_EVENT 2 /* R */
#define SENSORS_FSCPOS_CONTROL 3 /* RW */
#define SENSORS_FSCPOS_FAN1 4 /* R */
#define SENSORS_FSCPOS_FAN2 5 /* R */
#define SENSORS_FSCPOS_FAN3 6 /* R */
#define SENSORS_FSCPOS_FAN1_MIN 7 /* RW */
#define SENSORS_FSCPOS_FAN2_MIN 8 /* RW */
#define SENSORS_FSCPOS_FAN3_MIN 9 /* RW */
#define SENSORS_FSCPOS_FAN1_STATE 10 /* RW */
#define SENSORS_FSCPOS_FAN2_STATE 11 /* RW */
#define SENSORS_FSCPOS_FAN3_STATE 12 /* RW */
#define SENSORS_FSCPOS_FAN1_RIPPLE 13 /* RW */
#define SENSORS_FSCPOS_FAN2_RIPPLE 14 /* RW */
#define SENSORS_FSCPOS_FAN3_RIPPLE 15 /* RW */
#define SENSORS_FSCPOS_TEMP1 16 /* R */
#define SENSORS_FSCPOS_TEMP2 17 /* R */
#define SENSORS_FSCPOS_TEMP3 18 /* R */
#define SENSORS_FSCPOS_TEMP1_STATE 19 /* RW */
#define SENSORS_FSCPOS_TEMP2_STATE 20 /* RW */
#define SENSORS_FSCPOS_TEMP3_STATE 21 /* RW */
#define SENSORS_FSCPOS_VOLTAGE1 22 /* R */
#define SENSORS_FSCPOS_VOLTAGE2 23 /* R */
#define SENSORS_FSCPOS_VOLTAGE3 24 /* R */
#define SENSORS_FSCPOS_WDOG_PRESET 25/* RW */
#define SENSORS_FSCPOS_WDOG_STATE 26/* RW */
#define SENSORS_FSCPOS_WDOG_CONTROL 27/* RW */
#endif /* def LIB_SENSORS_CHIPS_H */

View File

@@ -445,7 +445,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
adm9240_detect adm1021_detect sis5595_isa_detect eeprom_detect
via686a_isa_detect adm1022_detect ltc1710_detect gl525sm_detect
lm87_detect ite_detect ite_isa_detect ite_alias_detect
ddcmonitor_detect ds1621_detect adm1024_detect);
ddcmonitor_detect ds1621_detect adm1024_detect fscpos_detect);
# This is a list of all recognized chips.
# Each entry must have the following fields:
@@ -719,6 +719,12 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
i2c_addrs => [0x50],
i2c_detect => sub { ddcmonitor_detect @_ },
},
{
name => "FSC poseidon chip",
driver => "fscpos",
i2c_addrs => [0x73],
i2c_detect => sub { fscpos_detect @_ },
},
);
@@ -2197,6 +2203,29 @@ FAILURE:
return;
}
# $_[0]: A reference to the file descriptor to access this chip.
# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (2) if detected.
# Registers used:
# 0x00-0x02: Identification
sub fscpos_detect
{
my ($file,$addr) = @_;
# check the first 3 registers
if (i2c_smbus_read_byte_data($file,0x00) != 0x50) {
return (0);
}
if (i2c_smbus_read_byte_data($file,0x01) != 0x45) {
return (0);
}
if (i2c_smbus_read_byte_data($file,0x02) != 0x47) {
return (0);
}
# no poseidon chip
return (1);
}
################
# MAIN PROGRAM #
################

View File

@@ -2647,6 +2647,116 @@ void print_it87(const sensors_chip_name *name)
free_the_label(&label);
}
void print_fscpos(const sensors_chip_name *name)
{
char *label = NULL;
double voltage, temp,state,fan,min_rpm;
int valid;
printf("Chip: fujitsu siemens poseidon\n");
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_TEMP1,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_TEMP1,&temp) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_TEMP1_STATE,&state)) {
if (valid) {
print_label(label,10);
if((int) state & 0x01)
printf("\t%+6.2f C \n",temp);
else
printf("\tfailed\n");
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_TEMP2,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_TEMP2,&temp) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_TEMP2_STATE,&state)) {
if (valid) {
print_label(label,10);
if((int) state & 0x01)
printf("\t%+6.2f C \n",temp);
else
printf("\tfailed\n");
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_TEMP3,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_TEMP3,&temp) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_TEMP3_STATE,&state)) {
if (valid) {
print_label(label,10);
if((int) state & 0x01)
printf("\t%+6.2f C \n",temp);
else
printf("\tfailed\n");
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_FAN1,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN1,&fan) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN1_MIN,&min_rpm) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN1_STATE,&state)) {
if (valid) {
print_label(label,10);
if((int) state & 0x02)
printf("\tfaulty\n");
else if (fan < min_rpm)
printf("\t%6.0f RPM (not present or faulty)\n",fan);
else
printf("\t%+6.0f RPM \n",fan);
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_FAN2,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN2,&fan) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN2_MIN,&min_rpm) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN2_STATE,&state)) {
if (valid) {
print_label(label,10);
if((int) state & 0x02)
printf("\tfaulty\n");
else if (fan < min_rpm)
printf("\t%6.0f RPM (not present or faulty)\n",fan);
else
printf("\t%+6.0f RPM \n",fan);
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_FAN3,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN3,&fan) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_FAN3_STATE,&state)) {
if (valid) {
print_label(label,10);
if((int) state & 0x02)
printf("\tfaulty\n");
else
printf("\t%+6.0f RPM \n",fan);
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_VOLTAGE1,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_VOLTAGE1,&voltage)) {
if (valid) {
print_label(label,10);
printf("\t%+6.2f V\n",voltage);
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_VOLTAGE2,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_VOLTAGE2,&voltage)) {
if (valid) {
print_label(label,10);
printf("\t%+6.2f V\n",voltage);
}
}
free_the_label(&label);
if (!sensors_get_label_and_valid(*name,SENSORS_FSCPOS_VOLTAGE3,&label,&valid) &&
!sensors_get_feature(*name,SENSORS_FSCPOS_VOLTAGE3,&voltage)) {
if (valid) {
print_label(label,10);
printf("\t%+6.2f V\n",voltage);
}
}
free_the_label(&label);
}
void print_unknown_chip(const sensors_chip_name *name)
{

View File

@@ -42,5 +42,6 @@ extern void print_ddcmon(const sensors_chip_name *name);
extern void print_eeprom(const sensors_chip_name *name);
extern void print_lm87(const sensors_chip_name *name);
extern void print_it87(const sensors_chip_name *name);
extern void print_fscpos(const sensors_chip_name *name);
#endif /* def PROG_SENSORS_CHIPS_H */

View File

@@ -333,6 +333,8 @@ void do_a_print(sensors_chip_name name)
print_ddcmon(&name);
else if (!strcmp(name.prefix,"eeprom"))
print_eeprom(&name);
else if (!strcmp(name.prefix,"fscpos"))
print_fscpos(&name);
else
print_unknown_chip(&name);
printf("\n");