mirror of
https://github.com/lm-sensors/lm-sensors
synced 2025-08-31 14:25:39 +00:00
(mds) Add via686a integrated sensors support. Untested.
git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@742 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
@@ -26,6 +26,7 @@ KERNELCHIPSDIR := $(MODULE_DIR)
|
||||
KERNELCHIPSTARGETS := $(MODULE_DIR)/bt869.o $(MODULE_DIR)/gl520sm.o \
|
||||
$(MODULE_DIR)/matorb.o $(MODULE_DIR)/maxilife.o \
|
||||
$(MODULE_DIR)/thmc50.o \
|
||||
$(MODULE_DIR)/via686a.o \
|
||||
$(MODULE_DIR)/ddcmon.o
|
||||
ifneq ($(shell if grep -q '^CONFIG_SENSORS_ADM1021=y' $(LINUX)/.config; then echo 1; fi),1)
|
||||
KERNELCHIPSTARGETS += $(MODULE_DIR)/adm1021.o
|
||||
|
728
kernel/chips/via686a.c
Normal file
728
kernel/chips/via686a.c
Normal file
@@ -0,0 +1,728 @@
|
||||
/*
|
||||
via686a.c - Part of lm_sensors, Linux kernel modules
|
||||
for hardware monitoring
|
||||
|
||||
Copyright (c) 1998, 1999,2000 Frodo Looijaard <frodol@dds.nl>,
|
||||
Ky<4B>sti M<>lkki <kmalkki@cc.hut.fi>,
|
||||
and Mark Studebaker <mdsxyz123@yahoo.com>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 <linux/pci.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "version.h"
|
||||
#include "i2c-isa.h"
|
||||
#include "sensors.h"
|
||||
#include <linux/init.h>
|
||||
|
||||
#ifndef PCI_DEVICE_ID_VIA_82C686_4
|
||||
#define PCI_DEVICE_ID_VIA_82C686_4 0x3057
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1))
|
||||
#define init_MUTEX(s) do { *(s) = MUTEX; } while(0)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)
|
||||
#define THIS_MODULE NULL
|
||||
#endif
|
||||
|
||||
/* Addresses to scan.
|
||||
Note that we can't determine the ISA address until we have initialized
|
||||
our module */
|
||||
static unsigned short normal_i2c[] = { SENSORS_I2C_END };
|
||||
static unsigned short normal_i2c_range[] = { SENSORS_I2C_END };
|
||||
static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END };
|
||||
static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
|
||||
|
||||
/* Insmod parameters */
|
||||
SENSORS_INSMOD_1(via686a);
|
||||
|
||||
/*
|
||||
The Via 686a southbridge has a LM78-like chip integrated on the same IC.
|
||||
This driver is a customized copy of lm78.c
|
||||
*/
|
||||
|
||||
/* Many VIA686A constants specified below */
|
||||
|
||||
/* Length of ISA address segment */
|
||||
#define VIA686A_EXTENT 0x80
|
||||
#define VIA686A_BASE_REG 0x70
|
||||
#define VIA686A_ENABLE_REG 0x74
|
||||
|
||||
/* The VIA686A registers */
|
||||
/* ins numbered 0-4 */
|
||||
#define VIA686A_REG_IN_MAX(nr) (0x2b + ((nr) * 2))
|
||||
#define VIA686A_REG_IN_MIN(nr) (0x2c + ((nr) * 2))
|
||||
#define VIA686A_REG_IN(nr) (0x22 + (nr))
|
||||
|
||||
/* fans numbered 1-2 */
|
||||
#define VIA686A_REG_FAN_MIN(nr) (0x3a + (nr))
|
||||
#define VIA686A_REG_FAN(nr) (0x28 + (nr))
|
||||
|
||||
static const u8 regtemp[] = {0x20, 0x21, 0x19};
|
||||
static const u8 regover[] = {0x39, 0x3d, 0x1d};
|
||||
static const u8 reghyst[] = {0x3a, 0x3e, 0x1e};
|
||||
/* temps numbered 1-3 */
|
||||
#define VIA686A_REG_TEMP(nr) (regtemp[(nr) - 1])
|
||||
#define VIA686A_REG_TEMP_OVER(nr) (regover[(nr) - 1])
|
||||
#define VIA686A_REG_TEMP_HYST(nr) (reghyst[(nr) - 1])
|
||||
#define VIA686A_REG_TEMP_LOW1 0x4b
|
||||
#define VIA686A_REG_TEMP_LOW23 0x49
|
||||
|
||||
#define VIA686A_REG_ALARM1 0x41
|
||||
#define VIA686A_REG_ALARM2 0x42
|
||||
#define VIA686A_REG_FANDIV 0x47
|
||||
#define VIA686A_REG_CONFIG 0x40
|
||||
|
||||
/* Conversions. Rounding and limit checking is only done on the TO_REG
|
||||
variants. */
|
||||
|
||||
/************** VOLTAGE CONVERSIONS FIXME *************/
|
||||
#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
|
||||
#define IN_FROM_REG(val) (((val) * 16) / 10)
|
||||
|
||||
extern inline u8 FAN_TO_REG(long rpm, int div)
|
||||
{
|
||||
if (rpm == 0)
|
||||
return 255;
|
||||
rpm = SENSORS_LIMIT(rpm, 1, 1000000);
|
||||
return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
|
||||
254);
|
||||
}
|
||||
|
||||
#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
|
||||
|
||||
/********** TEMP CONVERSIONS FIXME ************/
|
||||
#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\
|
||||
((val)+5)/10),0,255))
|
||||
/* for 8-bit temperature hyst and over registers */
|
||||
#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10)
|
||||
/* for 10-bit temperature readings */
|
||||
#define TEMP_FROM_REG10(val) (((val)>0x80?(val)-0x100:(val))*10)
|
||||
|
||||
#define ALARMS_FROM_REG(val) (val)
|
||||
|
||||
#define DIV_FROM_REG(val) (1 << (val))
|
||||
#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
|
||||
|
||||
/* Initial limits */
|
||||
#define VIA686A_INIT_IN_0 200
|
||||
#define VIA686A_INIT_IN_1 250
|
||||
#define VIA686A_INIT_IN_2 330
|
||||
#define VIA686A_INIT_IN_3 (((500) * 100)/168)
|
||||
#define VIA686A_INIT_IN_4 (((1200) * 10)/38)
|
||||
|
||||
#define VIA686A_INIT_IN_PERCENTAGE 10
|
||||
|
||||
#define VIA686A_INIT_IN_MIN_0 \
|
||||
(VIA686A_INIT_IN_0 - VIA686A_INIT_IN_0 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MAX_0 \
|
||||
(VIA686A_INIT_IN_0 + VIA686A_INIT_IN_0 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MIN_1 \
|
||||
(VIA686A_INIT_IN_1 - VIA686A_INIT_IN_1 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MAX_1 \
|
||||
(VIA686A_INIT_IN_1 + VIA686A_INIT_IN_1 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MIN_2 \
|
||||
(VIA686A_INIT_IN_2 - VIA686A_INIT_IN_2 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MAX_2 \
|
||||
(VIA686A_INIT_IN_2 + VIA686A_INIT_IN_2 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MIN_3 \
|
||||
(VIA686A_INIT_IN_3 - VIA686A_INIT_IN_3 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MAX_3 \
|
||||
(VIA686A_INIT_IN_3 + VIA686A_INIT_IN_3 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MIN_4 \
|
||||
(VIA686A_INIT_IN_4 - VIA686A_INIT_IN_4 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
#define VIA686A_INIT_IN_MAX_4 \
|
||||
(VIA686A_INIT_IN_4 + VIA686A_INIT_IN_4 * VIA686A_INIT_IN_PERCENTAGE / 100)
|
||||
|
||||
#define VIA686A_INIT_FAN_MIN 3000
|
||||
|
||||
#define VIA686A_INIT_TEMP_OVER 600
|
||||
#define VIA686A_INIT_TEMP_HYST 500
|
||||
|
||||
#ifdef MODULE
|
||||
extern int init_module(void);
|
||||
extern int cleanup_module(void);
|
||||
#endif /* MODULE */
|
||||
|
||||
/* This module may seem overly long and complicated. In fact, it is not so
|
||||
bad. Quite a lot of bookkeeping is done. A real driver can often cut
|
||||
some corners. */
|
||||
|
||||
/* For each registered VIA686A, we need to keep some data in memory. That
|
||||
data is pointed to by via686a_list[NR]->data. The structure itself is
|
||||
dynamically allocated, at the same time when a new via686a client is
|
||||
allocated. */
|
||||
struct via686a_data {
|
||||
struct semaphore lock;
|
||||
int sysctl_id;
|
||||
|
||||
struct semaphore update_lock;
|
||||
char valid; /* !=0 if following fields are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
|
||||
u8 in[5]; /* Register value */
|
||||
u8 in_max[5]; /* Register value */
|
||||
u8 in_min[5]; /* Register value */
|
||||
u8 fan[2]; /* Register value */
|
||||
u8 fan_min[2]; /* Register value */
|
||||
u16 temp[3]; /* Register value 10 bit */
|
||||
u8 temp_over[3]; /* Register value */
|
||||
u8 temp_hyst[3]; /* Register value */
|
||||
u8 fan_div[2]; /* Register encoding, shifted right */
|
||||
u16 alarms; /* Register encoding, combined */
|
||||
};
|
||||
|
||||
|
||||
#ifdef MODULE
|
||||
static
|
||||
#else
|
||||
extern
|
||||
#endif
|
||||
int __init sensors_via686a_init(void);
|
||||
static int __init via686a_cleanup(void);
|
||||
|
||||
static int via686a_attach_adapter(struct i2c_adapter *adapter);
|
||||
static int via686a_detect(struct i2c_adapter *adapter, int address,
|
||||
unsigned short flags, int kind);
|
||||
static int via686a_detach_client(struct i2c_client *client);
|
||||
static int via686a_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg);
|
||||
static void via686a_inc_use(struct i2c_client *client);
|
||||
static void via686a_dec_use(struct i2c_client *client);
|
||||
|
||||
static int via686a_read_value(struct i2c_client *client, u8 register);
|
||||
static void via686a_write_value(struct i2c_client *client, u8 register,
|
||||
u8 value);
|
||||
static void via686a_update_client(struct i2c_client *client);
|
||||
static void via686a_init_client(struct i2c_client *client);
|
||||
static int via686a_find(int *address);
|
||||
|
||||
|
||||
static void via686a_in(struct i2c_client *client, int operation,
|
||||
int ctl_name, int *nrels_mag, long *results);
|
||||
static void via686a_fan(struct i2c_client *client, int operation,
|
||||
int ctl_name, int *nrels_mag, long *results);
|
||||
static void via686a_temp(struct i2c_client *client, int operation,
|
||||
int ctl_name, int *nrels_mag, long *results);
|
||||
static void via686a_alarms(struct i2c_client *client, int operation,
|
||||
int ctl_name, int *nrels_mag, long *results);
|
||||
static void via686a_fan_div(struct i2c_client *client, int operation,
|
||||
int ctl_name, int *nrels_mag, long *results);
|
||||
|
||||
static int via686a_id = 0;
|
||||
|
||||
/* The driver. I choose to use type i2c_driver, as at is identical to both
|
||||
smbus_driver and isa_driver, and clients could be of either kind */
|
||||
static struct i2c_driver via686a_driver = {
|
||||
/* name */ "VIA 686A",
|
||||
/* id */ I2C_DRIVERID_VIA686A,
|
||||
/* flags */ I2C_DF_NOTIFY,
|
||||
/* attach_adapter */ &via686a_attach_adapter,
|
||||
/* detach_client */ &via686a_detach_client,
|
||||
/* command */ &via686a_command,
|
||||
/* inc_use */ &via686a_inc_use,
|
||||
/* dec_use */ &via686a_dec_use
|
||||
};
|
||||
|
||||
/* Used by via686a_init/cleanup */
|
||||
static int __initdata via686a_initialized = 0;
|
||||
|
||||
/* The /proc/sys entries */
|
||||
/* These files are created for each detected VIA686A. 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 via686a_dir_table_template[] = {
|
||||
{VIA686A_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_in},
|
||||
{VIA686A_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_in},
|
||||
{VIA686A_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_in},
|
||||
{VIA686A_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_in},
|
||||
{VIA686A_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_in},
|
||||
{VIA686A_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_fan},
|
||||
{VIA686A_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_fan},
|
||||
{VIA686A_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_temp},
|
||||
{VIA686A_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_temp},
|
||||
{VIA686A_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_temp},
|
||||
{VIA686A_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_fan_div},
|
||||
{VIA686A_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &sensors_proc_real,
|
||||
&sensors_sysctl_real, NULL, &via686a_alarms},
|
||||
{0}
|
||||
};
|
||||
|
||||
static inline int via686a_read_value(struct i2c_client *client, u8 reg)
|
||||
{
|
||||
return(inb_p(client->addr + reg));
|
||||
}
|
||||
|
||||
static inline void via686a_write_value(struct i2c_client *client, u8 reg, u8 value)
|
||||
{
|
||||
outb_p(value, client->addr + reg);
|
||||
}
|
||||
|
||||
/* This is called when the module is loaded */
|
||||
int via686a_attach_adapter(struct i2c_adapter *adapter)
|
||||
{
|
||||
return sensors_detect(adapter, &addr_data, via686a_detect);
|
||||
}
|
||||
|
||||
/* Locate chip and get correct base address */
|
||||
int via686a_find(int *address)
|
||||
{
|
||||
struct pci_dev *s_bridge;
|
||||
u16 val;
|
||||
|
||||
if (!pci_present())
|
||||
return -ENODEV;
|
||||
|
||||
if (! (s_bridge = pci_find_device(PCI_VENDOR_ID_VIA,
|
||||
PCI_DEVICE_ID_VIA_82C686_4, NULL)))
|
||||
return -ENODEV;
|
||||
|
||||
if (PCIBIOS_SUCCESSFUL !=
|
||||
pci_read_config_word(s_bridge, VIA686A_BASE_REG, &val))
|
||||
return -ENODEV;
|
||||
*address = (val & 0xff80);
|
||||
|
||||
if (PCIBIOS_SUCCESSFUL !=
|
||||
pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val))
|
||||
return -ENODEV;
|
||||
if((*address == 0) || !(val & 0x01)) {
|
||||
printk("via686a.o: sensors not enabled - upgrade BIOS?\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int via686a_detect(struct i2c_adapter *adapter, int address,
|
||||
unsigned short flags, int kind)
|
||||
{
|
||||
int i;
|
||||
struct i2c_client *new_client;
|
||||
struct via686a_data *data;
|
||||
int err = 0;
|
||||
const char *type_name = "via686a sensors";
|
||||
|
||||
/* Make sure we are probing the ISA bus!! */
|
||||
if (!i2c_is_isa_adapter(adapter)) {
|
||||
printk
|
||||
("via686a.o: via686a_detect called for an I2C bus adapter?!?\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (check_region(address, VIA686A_EXTENT)) {
|
||||
printk("via686a.o: region 0x%x already in use!\n", address);
|
||||
err = -ENODEV;
|
||||
goto ERROR0;
|
||||
}
|
||||
|
||||
if (!(new_client = kmalloc(sizeof(struct i2c_client) +
|
||||
sizeof(struct via686a_data),
|
||||
GFP_KERNEL))) {
|
||||
err = -ENOMEM;
|
||||
goto ERROR0;
|
||||
}
|
||||
|
||||
data = (struct via686a_data *) (new_client + 1);
|
||||
new_client->addr = address;
|
||||
init_MUTEX(&data->lock);
|
||||
new_client->data = data;
|
||||
new_client->adapter = adapter;
|
||||
new_client->driver = &via686a_driver;
|
||||
new_client->flags = 0;
|
||||
|
||||
/* Reserve the ISA region */
|
||||
request_region(address, VIA686A_EXTENT, type_name);
|
||||
|
||||
/* Fill in the remaining client fields and put into the global list */
|
||||
strcpy(new_client->name, "Via 686A Integrated Sensors");
|
||||
|
||||
new_client->id = via686a_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 = sensors_register_entry((struct i2c_client *) new_client,
|
||||
type_name,
|
||||
via686a_dir_table_template,
|
||||
THIS_MODULE)) < 0) {
|
||||
err = i;
|
||||
goto ERROR4;
|
||||
}
|
||||
data->sysctl_id = i;
|
||||
|
||||
/* Initialize the VIA686A chip */
|
||||
via686a_init_client(new_client);
|
||||
return 0;
|
||||
|
||||
ERROR4:
|
||||
i2c_detach_client(new_client);
|
||||
ERROR3:
|
||||
release_region(address, VIA686A_EXTENT);
|
||||
kfree(new_client);
|
||||
ERROR0:
|
||||
return err;
|
||||
}
|
||||
|
||||
int via686a_detach_client(struct i2c_client *client)
|
||||
{
|
||||
int err;
|
||||
|
||||
sensors_deregister_entry(((struct via686a_data *) (client->data))->
|
||||
sysctl_id);
|
||||
|
||||
if ((err = i2c_detach_client(client))) {
|
||||
printk
|
||||
("via686a.o: Client deregistration failed, client not detached.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
release_region(client->addr, VIA686A_EXTENT);
|
||||
kfree(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No commands defined yet */
|
||||
int via686a_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void via686a_inc_use(struct i2c_client *client)
|
||||
{
|
||||
MOD_INC_USE_COUNT;
|
||||
}
|
||||
|
||||
void via686a_dec_use(struct i2c_client *client)
|
||||
{
|
||||
MOD_DEC_USE_COUNT;
|
||||
}
|
||||
|
||||
/* Called when we have found a new VIA686A. Set limits, etc. */
|
||||
void via686a_init_client(struct i2c_client *client)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Reset the device */
|
||||
via686a_write_value(client, VIA686A_REG_CONFIG, 0x80);
|
||||
|
||||
via686a_write_value(client, VIA686A_REG_IN_MIN(0),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MIN_0));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MAX(0),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MAX_0));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MIN(1),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MIN_1));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MAX(1),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MAX_1));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MIN(2),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MIN_2));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MAX(2),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MAX_2));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MIN(3),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MIN_3));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MAX(3),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MAX_3));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MIN(4),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MIN_4));
|
||||
via686a_write_value(client, VIA686A_REG_IN_MAX(4),
|
||||
IN_TO_REG(VIA686A_INIT_IN_MAX_4));
|
||||
via686a_write_value(client, VIA686A_REG_FAN_MIN(1),
|
||||
FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
|
||||
via686a_write_value(client, VIA686A_REG_FAN_MIN(2),
|
||||
FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
|
||||
for(i = 1; i < 3; i++) {
|
||||
via686a_write_value(client, VIA686A_REG_TEMP_OVER(i),
|
||||
TEMP_TO_REG(VIA686A_INIT_TEMP_OVER));
|
||||
via686a_write_value(client, VIA686A_REG_TEMP_HYST(i),
|
||||
TEMP_TO_REG(VIA686A_INIT_TEMP_HYST));
|
||||
}
|
||||
|
||||
/* Start monitoring */
|
||||
via686a_write_value(client, VIA686A_REG_CONFIG, 0x01);
|
||||
}
|
||||
|
||||
void via686a_update_client(struct i2c_client *client)
|
||||
{
|
||||
struct via686a_data *data = client->data;
|
||||
int i;
|
||||
|
||||
down(&data->update_lock);
|
||||
|
||||
if ((jiffies - data->last_updated > HZ + HZ / 2) ||
|
||||
(jiffies < data->last_updated) || !data->valid) {
|
||||
|
||||
for (i = 0; i <= 4; i++) {
|
||||
data->in[i] =
|
||||
via686a_read_value(client, VIA686A_REG_IN(i));
|
||||
data->in_min[i] = via686a_read_value(client,
|
||||
VIA686A_REG_IN_MIN(i));
|
||||
data->in_max[i] = via686a_read_value(client,
|
||||
VIA686A_REG_IN_MAX(i));
|
||||
}
|
||||
for (i = 1; i <= 2; i++) {
|
||||
data->fan[i - 1] =
|
||||
via686a_read_value(client, VIA686A_REG_FAN(i));
|
||||
data->fan_min[i - 1] = via686a_read_value(client,
|
||||
VIA686A_REG_FAN_MIN(i));
|
||||
}
|
||||
for (i = 1; i <= 3; i++) {
|
||||
data->temp[i - 1] = via686a_read_value(client,
|
||||
VIA686A_REG_TEMP(i)) << 2;
|
||||
data->temp_over[i - 1] = via686a_read_value(client,
|
||||
VIA686A_REG_TEMP_OVER(i));
|
||||
data->temp_hyst[i - 1] = via686a_read_value(client,
|
||||
VIA686A_REG_TEMP_HYST(i));
|
||||
}
|
||||
/* add in lower 2 bits */
|
||||
data->temp[0] |= (via686a_read_value(client,
|
||||
VIA686A_REG_TEMP_LOW1) & 0xc0) >> 6;
|
||||
data->temp[1] |= (via686a_read_value(client,
|
||||
VIA686A_REG_TEMP_LOW23) & 0x30) >> 4;
|
||||
data->temp[2] |= (via686a_read_value(client,
|
||||
VIA686A_REG_TEMP_LOW23) & 0xc0) >> 6;
|
||||
i = via686a_read_value(client, VIA686A_REG_FANDIV);
|
||||
data->fan_div[0] = (i >> 4) & 0x03;
|
||||
data->fan_div[1] = i >> 6;
|
||||
data->alarms = via686a_read_value(client, VIA686A_REG_ALARM1) ||
|
||||
(via686a_read_value(client, VIA686A_REG_ALARM2) << 8);
|
||||
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 via686a_in(struct i2c_client *client, int operation, int ctl_name,
|
||||
int *nrels_mag, long *results)
|
||||
{
|
||||
struct via686a_data *data = client->data;
|
||||
int nr = ctl_name - VIA686A_SYSCTL_IN0;
|
||||
|
||||
if (operation == SENSORS_PROC_REAL_INFO)
|
||||
*nrels_mag = 2;
|
||||
else if (operation == SENSORS_PROC_REAL_READ) {
|
||||
via686a_update_client(client);
|
||||
results[0] = IN_FROM_REG(data->in_min[nr]);
|
||||
results[1] = IN_FROM_REG(data->in_max[nr]);
|
||||
results[2] = IN_FROM_REG(data->in[nr]);
|
||||
*nrels_mag = 3;
|
||||
} else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
if (*nrels_mag >= 1) {
|
||||
data->in_min[nr] = IN_TO_REG(results[0]);
|
||||
via686a_write_value(client, VIA686A_REG_IN_MIN(nr),
|
||||
data->in_min[nr]);
|
||||
}
|
||||
if (*nrels_mag >= 2) {
|
||||
data->in_max[nr] = IN_TO_REG(results[1]);
|
||||
via686a_write_value(client, VIA686A_REG_IN_MAX(nr),
|
||||
data->in_max[nr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void via686a_fan(struct i2c_client *client, int operation, int ctl_name,
|
||||
int *nrels_mag, long *results)
|
||||
{
|
||||
struct via686a_data *data = client->data;
|
||||
int nr = ctl_name - VIA686A_SYSCTL_FAN1 + 1;
|
||||
|
||||
if (operation == SENSORS_PROC_REAL_INFO)
|
||||
*nrels_mag = 0;
|
||||
else if (operation == SENSORS_PROC_REAL_READ) {
|
||||
via686a_update_client(client);
|
||||
results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
|
||||
DIV_FROM_REG(data->
|
||||
fan_div[nr - 1]));
|
||||
results[1] =
|
||||
FAN_FROM_REG(data->fan[nr - 1],
|
||||
DIV_FROM_REG(data->fan_div[nr - 1]));
|
||||
*nrels_mag = 2;
|
||||
} else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
if (*nrels_mag >= 1) {
|
||||
data->fan_min[nr - 1] = FAN_TO_REG(results[0],
|
||||
DIV_FROM_REG(data->fan_div[nr - 1]));
|
||||
via686a_write_value(client,
|
||||
VIA686A_REG_FAN_MIN(nr),
|
||||
data->fan_min[nr - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void via686a_temp(struct i2c_client *client, int operation, int ctl_name,
|
||||
int *nrels_mag, long *results)
|
||||
{
|
||||
struct via686a_data *data = client->data;
|
||||
int nr = ctl_name - VIA686A_SYSCTL_TEMP;
|
||||
|
||||
if (operation == SENSORS_PROC_REAL_INFO)
|
||||
*nrels_mag = 1;
|
||||
else if (operation == SENSORS_PROC_REAL_READ) {
|
||||
via686a_update_client(client);
|
||||
results[0] = TEMP_FROM_REG(data->temp_over[nr]);
|
||||
results[1] = TEMP_FROM_REG(data->temp_hyst[nr]);
|
||||
results[2] = TEMP_FROM_REG10(data->temp[nr]);
|
||||
*nrels_mag = 3;
|
||||
} else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
if (*nrels_mag >= 1) {
|
||||
data->temp_over[nr] = TEMP_TO_REG(results[0]);
|
||||
via686a_write_value(client, VIA686A_REG_TEMP_OVER(nr),
|
||||
data->temp_over[nr]);
|
||||
}
|
||||
if (*nrels_mag >= 2) {
|
||||
data->temp_hyst[nr] = TEMP_TO_REG(results[1]);
|
||||
via686a_write_value(client, VIA686A_REG_TEMP_HYST(nr),
|
||||
data->temp_hyst[nr]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void via686a_alarms(struct i2c_client *client, int operation, int ctl_name,
|
||||
int *nrels_mag, long *results)
|
||||
{
|
||||
struct via686a_data *data = client->data;
|
||||
if (operation == SENSORS_PROC_REAL_INFO)
|
||||
*nrels_mag = 0;
|
||||
else if (operation == SENSORS_PROC_REAL_READ) {
|
||||
via686a_update_client(client);
|
||||
results[0] = ALARMS_FROM_REG(data->alarms);
|
||||
*nrels_mag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void via686a_fan_div(struct i2c_client *client, int operation,
|
||||
int ctl_name, int *nrels_mag, long *results)
|
||||
{
|
||||
struct via686a_data *data = client->data;
|
||||
int old;
|
||||
|
||||
if (operation == SENSORS_PROC_REAL_INFO)
|
||||
*nrels_mag = 0;
|
||||
else if (operation == SENSORS_PROC_REAL_READ) {
|
||||
via686a_update_client(client);
|
||||
results[0] = DIV_FROM_REG(data->fan_div[0]);
|
||||
results[1] = DIV_FROM_REG(data->fan_div[1]);
|
||||
*nrels_mag = 2;
|
||||
} else if (operation == SENSORS_PROC_REAL_WRITE) {
|
||||
old = via686a_read_value(client, VIA686A_REG_FANDIV);
|
||||
if (*nrels_mag >= 2) {
|
||||
data->fan_div[1] = DIV_TO_REG(results[1]);
|
||||
old = (old & 0x3f) | (data->fan_div[1] << 6);
|
||||
}
|
||||
if (*nrels_mag >= 1) {
|
||||
data->fan_div[0] = DIV_TO_REG(results[0]);
|
||||
old = (old & 0xcf) | (data->fan_div[0] << 4);
|
||||
via686a_write_value(client, VIA686A_REG_FANDIV,
|
||||
old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int __init sensors_via686a_init(void)
|
||||
{
|
||||
int res, addr;
|
||||
|
||||
printk("via686a.o version %s (%s)\n", LM_VERSION, LM_DATE);
|
||||
via686a_initialized = 0;
|
||||
|
||||
if (via686a_find(&addr)) {
|
||||
printk("via686a.o: No Via 686A sensors found.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
normal_isa[0] = addr;
|
||||
|
||||
if ((res = i2c_add_driver(&via686a_driver))) {
|
||||
printk
|
||||
("via686a.o: Driver registration failed.\n");
|
||||
via686a_cleanup();
|
||||
return res;
|
||||
}
|
||||
via686a_initialized++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init via686a_cleanup(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (via686a_initialized >= 1) {
|
||||
if ((res = i2c_del_driver(&via686a_driver))) {
|
||||
printk("via686a.o: Driver deregistration failed.\n");
|
||||
return res;
|
||||
}
|
||||
via686a_initialized--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_NO_SYMBOLS;
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
MODULE_AUTHOR("Ky<EFBFBD>sti M<>lkki <kmalkki@cc.hut.fi>, Mark Studebaker <mdsxyz123@yahoo.com>");
|
||||
MODULE_DESCRIPTION("VIA 686A Sensor device");
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
return sensors_via686a_init();
|
||||
}
|
||||
|
||||
int cleanup_module(void)
|
||||
{
|
||||
return via686a_cleanup();
|
||||
}
|
||||
|
||||
#endif /* MODULE */
|
@@ -374,6 +374,7 @@ extern inline int SENSORS_LIMIT(long value, long low, long high)
|
||||
#define I2C_DRIVERID_GL520 1016
|
||||
#define I2C_DRIVERID_THMC50 1017
|
||||
#define I2C_DRIVERID_DDCMON 1018
|
||||
#define I2C_DRIVERID_VIA686A 1019
|
||||
|
||||
/* Sysctl IDs */
|
||||
#ifdef DEV_HWMON
|
||||
@@ -639,6 +640,31 @@ struct sensors_chips_data {
|
||||
#define SIS5595_ALARM_FAN1 0x40
|
||||
#define SIS5595_ALARM_FAN2 0x80
|
||||
|
||||
#define VIA686A_SYSCTL_IN0 1000
|
||||
#define VIA686A_SYSCTL_IN1 1001
|
||||
#define VIA686A_SYSCTL_IN2 1002
|
||||
#define VIA686A_SYSCTL_IN3 1003
|
||||
#define VIA686A_SYSCTL_IN4 1004
|
||||
#define VIA686A_SYSCTL_FAN1 1101
|
||||
#define VIA686A_SYSCTL_FAN2 1102
|
||||
#define VIA686A_SYSCTL_TEMP 1200
|
||||
#define VIA686A_SYSCTL_TEMP2 1201
|
||||
#define VIA686A_SYSCTL_TEMP3 1202
|
||||
#define VIA686A_SYSCTL_FAN_DIV 2000
|
||||
#define VIA686A_SYSCTL_ALARMS 2001
|
||||
|
||||
#define VIA686A_ALARM_IN0 0x01
|
||||
#define VIA686A_ALARM_IN1 0x02
|
||||
#define VIA686A_ALARM_IN2 0x04
|
||||
#define VIA686A_ALARM_IN3 0x08
|
||||
#define VIA686A_ALARM_TEMP 0x10
|
||||
#define VIA686A_ALARM_FAN1 0x40
|
||||
#define VIA686A_ALARM_FAN2 0x80
|
||||
#define VIA686A_ALARM_IN4 0x100
|
||||
#define VIA686A_ALARM_TEMP2 0x400
|
||||
#define VIA686A_ALARM_CHAS 0x1000
|
||||
#define VIA686A_ALARM_TEMP3 0x8000
|
||||
|
||||
#define ICSPLL_SYSCTL1 1000
|
||||
|
||||
#define BT869_SYSCTL_STATUS 1000
|
||||
|
76
lib/chips.c
76
lib/chips.c
@@ -1559,6 +1559,81 @@ static sensors_chip_feature thmc50_features[] =
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static sensors_chip_feature via686a_features[] =
|
||||
{
|
||||
{ SENSORS_VIA686A_IN0, "2.0V", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_IN0, VALUE(3), 2 },
|
||||
{ SENSORS_VIA686A_IN1, "2.5V", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_IN1, VALUE(3), 2 },
|
||||
{ SENSORS_VIA686A_IN2, "3.3V", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_IN2, VALUE(3), 2 },
|
||||
{ SENSORS_VIA686A_IN3, "5.0V", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_IN3, VALUE(3), 2 },
|
||||
{ SENSORS_VIA686A_IN4, "12V", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_IN4, VALUE(3), 2 },
|
||||
{ SENSORS_VIA686A_IN0_MIN, "in0_min", SENSORS_VIA686A_IN0, SENSORS_VIA686A_IN0,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN0, VALUE(1), 2 },
|
||||
{ SENSORS_VIA686A_IN1_MIN, "in1_min", SENSORS_VIA686A_IN1, SENSORS_VIA686A_IN1,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN1, VALUE(1), 2 },
|
||||
{ SENSORS_VIA686A_IN2_MIN, "in2_min", SENSORS_VIA686A_IN2, SENSORS_VIA686A_IN2,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN2, VALUE(1), 2 },
|
||||
{ SENSORS_VIA686A_IN3_MIN, "in3_min", SENSORS_VIA686A_IN3, SENSORS_VIA686A_IN3,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN3, VALUE(1), 2 },
|
||||
{ SENSORS_VIA686A_IN3_MIN, "in4_min", SENSORS_VIA686A_IN4, SENSORS_VIA686A_IN4,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN4, VALUE(1), 2 },
|
||||
{ SENSORS_VIA686A_IN0_MAX, "in0_max", SENSORS_VIA686A_IN0, SENSORS_VIA686A_IN0,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN0, VALUE(2), 2 },
|
||||
{ SENSORS_VIA686A_IN1_MAX, "in1_max", SENSORS_VIA686A_IN1, SENSORS_VIA686A_IN1,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN1, VALUE(2), 2 },
|
||||
{ SENSORS_VIA686A_IN2_MAX, "in2_max", SENSORS_VIA686A_IN2, SENSORS_VIA686A_IN2,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN2, VALUE(2), 2 },
|
||||
{ SENSORS_VIA686A_IN3_MAX, "in3_max", SENSORS_VIA686A_IN3, SENSORS_VIA686A_IN3,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN3, VALUE(2), 2 },
|
||||
{ SENSORS_VIA686A_IN3_MAX, "in4_max", SENSORS_VIA686A_IN4, SENSORS_VIA686A_IN4,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_IN4, VALUE(2), 2 },
|
||||
{ SENSORS_VIA686A_FAN1, "fan1", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_FAN1, VALUE(2), 0 },
|
||||
{ SENSORS_VIA686A_FAN2, "fan2", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_FAN2, VALUE(2), 0 },
|
||||
{ SENSORS_VIA686A_FAN1_MIN, "fan1_min", SENSORS_VIA686A_FAN1, SENSORS_VIA686A_FAN1,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_FAN1, VALUE(1), 0 },
|
||||
{ SENSORS_VIA686A_FAN2_MIN, "fan2_min", SENSORS_VIA686A_FAN2, SENSORS_VIA686A_FAN2,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_FAN2, VALUE(1), 0 },
|
||||
{ SENSORS_VIA686A_TEMP, "temp1", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_TEMP, VALUE(3), 1 },
|
||||
{ SENSORS_VIA686A_TEMP_HYST, "temp1_hyst", SENSORS_VIA686A_TEMP,
|
||||
SENSORS_VIA686A_TEMP, SENSORS_MODE_RW,
|
||||
VIA686A_SYSCTL_TEMP, VALUE(2), 1 },
|
||||
{ SENSORS_VIA686A_TEMP_OVER, "temp1_over", SENSORS_VIA686A_TEMP,
|
||||
SENSORS_VIA686A_TEMP, SENSORS_MODE_RW,
|
||||
VIA686A_SYSCTL_TEMP, VALUE(1), 1 },
|
||||
{ SENSORS_VIA686A_TEMP, "temp2", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_TEMP, VALUE(3), 1 },
|
||||
{ SENSORS_VIA686A_TEMP_HYST, "temp2_hyst", SENSORS_VIA686A_TEMP2,
|
||||
SENSORS_VIA686A_TEMP2, SENSORS_MODE_RW,
|
||||
VIA686A_SYSCTL_TEMP, VALUE(2), 1 },
|
||||
{ SENSORS_VIA686A_TEMP_OVER, "temp2_over", SENSORS_VIA686A_TEMP2,
|
||||
SENSORS_VIA686A_TEMP2, SENSORS_MODE_RW,
|
||||
VIA686A_SYSCTL_TEMP, VALUE(1), 1 },
|
||||
{ SENSORS_VIA686A_TEMP, "temp3", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_TEMP, VALUE(3), 1 },
|
||||
{ SENSORS_VIA686A_TEMP_HYST, "temp3_hyst", SENSORS_VIA686A_TEMP3,
|
||||
SENSORS_VIA686A_TEMP3, SENSORS_MODE_RW,
|
||||
VIA686A_SYSCTL_TEMP, VALUE(2), 1 },
|
||||
{ SENSORS_VIA686A_TEMP_OVER, "temp3_over", SENSORS_VIA686A_TEMP3,
|
||||
SENSORS_VIA686A_TEMP3, SENSORS_MODE_RW,
|
||||
VIA686A_SYSCTL_TEMP, VALUE(1), 1 },
|
||||
{ SENSORS_VIA686A_FAN1_DIV, "fan1_div", SENSORS_VIA686A_FAN1, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_FAN_DIV, VALUE(1),
|
||||
0 },
|
||||
{ SENSORS_VIA686A_FAN2_DIV, "fan2_div", SENSORS_VIA686A_FAN2, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_RW, VIA686A_SYSCTL_FAN_DIV, VALUE(2),
|
||||
0 },
|
||||
{ SENSORS_VIA686A_ALARMS, "alarms", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING,
|
||||
SENSORS_MODE_R, VIA686A_SYSCTL_ALARMS, VALUE(1), 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static sensors_chip_feature ddcmon_features[] =
|
||||
{
|
||||
{ SENSORS_DDCMON_ID, "Monitor ID",
|
||||
@@ -1644,6 +1719,7 @@ sensors_chip_features sensors_chip_features_list[] =
|
||||
{ SENSORS_THMC50_PREFIX, thmc50_features },
|
||||
/* Cheat on ADM1022 for now - no separate #defines */
|
||||
{ SENSORS_ADM1022_PREFIX, thmc50_features },
|
||||
{ SENSORS_VIA686A_PREFIX, via686a_features },
|
||||
{ SENSORS_DDCMON_PREFIX, ddcmon_features },
|
||||
{ SENSORS_EEPROM_PREFIX, eeprom_features },
|
||||
{ 0 }
|
||||
|
37
lib/chips.h
37
lib/chips.h
@@ -724,6 +724,43 @@
|
||||
#define SENSORS_THMC50_INTER_MASK 82 /* RW */
|
||||
#define SENSORS_THMC50_DIE_CODE 90 /* R */
|
||||
|
||||
/* SiS southbridge with integrated lm78 */
|
||||
|
||||
#define SENSORS_VIA686A_PREFIX "via686a"
|
||||
|
||||
#define SENSORS_VIA686A_IN0 1 /* R */
|
||||
#define SENSORS_VIA686A_IN1 2 /* R */
|
||||
#define SENSORS_VIA686A_IN2 3 /* R */
|
||||
#define SENSORS_VIA686A_IN3 4 /* R */
|
||||
#define SENSORS_VIA686A_IN4 5 /* R */
|
||||
#define SENSORS_VIA686A_IN0_MIN 11 /* RW */
|
||||
#define SENSORS_VIA686A_IN1_MIN 12 /* RW */
|
||||
#define SENSORS_VIA686A_IN2_MIN 13 /* RW */
|
||||
#define SENSORS_VIA686A_IN3_MIN 14 /* RW */
|
||||
#define SENSORS_VIA686A_IN4_MIN 15 /* RW */
|
||||
#define SENSORS_VIA686A_IN0_MAX 21 /* RW */
|
||||
#define SENSORS_VIA686A_IN1_MAX 22 /* RW */
|
||||
#define SENSORS_VIA686A_IN2_MAX 23 /* RW */
|
||||
#define SENSORS_VIA686A_IN3_MAX 24 /* RW */
|
||||
#define SENSORS_VIA686A_IN4_MAX 25 /* RW */
|
||||
#define SENSORS_VIA686A_FAN1 31 /* R */
|
||||
#define SENSORS_VIA686A_FAN2 32 /* R */
|
||||
#define SENSORS_VIA686A_FAN1_MIN 41 /* RW */
|
||||
#define SENSORS_VIA686A_FAN2_MIN 42 /* RW */
|
||||
#define SENSORS_VIA686A_TEMP 51 /* R */
|
||||
#define SENSORS_VIA686A_TEMP_HYST 52 /* RW */
|
||||
#define SENSORS_VIA686A_TEMP_OVER 53 /* RW */
|
||||
#define SENSORS_VIA686A_TEMP2 54 /* R */
|
||||
#define SENSORS_VIA686A_TEMP2_HYST 55 /* RW */
|
||||
#define SENSORS_VIA686A_TEMP2_OVER 56 /* RW */
|
||||
#define SENSORS_VIA686A_TEMP3 57 /* R */
|
||||
#define SENSORS_VIA686A_TEMP3_HYST 58 /* RW */
|
||||
#define SENSORS_VIA686A_TEMP3_OVER 59 /* RW */
|
||||
#define SENSORS_VIA686A_FAN1_DIV 71 /* RW */
|
||||
#define SENSORS_VIA686A_FAN2_DIV 72 /* RW */
|
||||
#define SENSORS_VIA686A_ALARMS 81 /* R */
|
||||
|
||||
|
||||
/* DDC Monitor */
|
||||
|
||||
#define SENSORS_DDCMON_PREFIX "ddcmon"
|
||||
|
@@ -421,6 +421,145 @@ void print_sis5595(const sensors_chip_name *name)
|
||||
alarms & SIS5595_ALARM_BTI ?"ALARM":" ");
|
||||
}
|
||||
free_the_label(&label);
|
||||
|
||||
}
|
||||
|
||||
void print_via686a(const sensors_chip_name *name)
|
||||
{
|
||||
char *label = NULL;
|
||||
double cur,min,max,fdiv;
|
||||
int alarms,valid;
|
||||
|
||||
if (!sensors_get_feature(*name,SENSORS_VIA686A_ALARMS,&cur))
|
||||
alarms = cur + 0.5;
|
||||
else {
|
||||
printf("ERROR: Can't get alarm data!\n");
|
||||
alarms = 0;
|
||||
}
|
||||
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_IN0,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN0,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN0_MIN,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN0_MAX,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+6.2f V (min = %+6.2f V, max = %+6.2f V) %s\n",
|
||||
cur,min,max,alarms&VIA686A_ALARM_IN0?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get IN0 data!\n");
|
||||
free_the_label(&label);
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_IN1,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN1,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN1_MIN,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN1_MAX,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+6.2f V (min = %+6.2f V, max = %+6.2f V) %s\n",
|
||||
cur,min,max,alarms&VIA686A_ALARM_IN1?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get IN1 data!\n");
|
||||
free_the_label(&label);
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_IN2,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN2,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN2_MIN,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN2_MAX,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+6.2f V (min = %+6.2f V, max = %+6.2f V) %s\n",
|
||||
cur,min,max,alarms&VIA686A_ALARM_IN2?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get IN2 data!\n");
|
||||
free_the_label(&label);
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_IN3,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN3,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN3_MIN,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN3_MAX,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+6.2f V (min = %+6.2f V, max = %+6.2f V) %s\n",
|
||||
cur,min,max,alarms&VIA686A_ALARM_IN3?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get IN3 data!\n");
|
||||
free_the_label(&label);
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_IN4,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN4,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN4_MIN,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_IN4_MAX,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+6.2f V (min = %+6.2f V, max = %+6.2f V) %s\n",
|
||||
cur,min,max,alarms&VIA686A_ALARM_IN4?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get IN4 data!\n");
|
||||
free_the_label(&label);
|
||||
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_FAN1,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_FAN1,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_FAN1_DIV,&fdiv) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_FAN1_MIN,&min)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%4.0f RPM (min = %4.0f RPM, div = %1.0f) %s\n",
|
||||
cur,min,fdiv, alarms&VIA686A_ALARM_FAN1?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get FAN1 data!\n");
|
||||
free_the_label(&label);
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_FAN2,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_FAN2,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_FAN2_DIV,&fdiv) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_FAN2_MIN,&min)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%4.0f RPM (min = %4.0f RPM, div = %1.0f) %s\n",
|
||||
cur,min,fdiv, alarms&VIA686A_ALARM_FAN2?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get FAN2 data!\n");
|
||||
free_the_label(&label);
|
||||
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_TEMP,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP_HYST,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP_OVER,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+3.0f C (limit = %+3.0f C, hysteresis = %+3.0f C) %s\n",
|
||||
cur,max,min, alarms&VIA686A_ALARM_TEMP?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get TEMP data!\n");
|
||||
free_the_label(&label);
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_TEMP2,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP2,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP2_HYST,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP2_OVER,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+3.0f C (limit = %+3.0f C, hysteresis = %+3.0f C) %s\n",
|
||||
cur,max,min, alarms&VIA686A_ALARM_TEMP2?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get TEMP2 data!\n");
|
||||
free_the_label(&label);
|
||||
if (!sensors_get_label_and_valid(*name,SENSORS_VIA686A_TEMP3,&label,&valid) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP3,&cur) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP3_HYST,&min) &&
|
||||
!sensors_get_feature(*name,SENSORS_VIA686A_TEMP3_OVER,&max)) {
|
||||
if (valid) {
|
||||
print_label(label,10);
|
||||
printf("%+3.0f C (limit = %+3.0f C, hysteresis = %+3.0f C) %s\n",
|
||||
cur,max,min, alarms&VIA686A_ALARM_TEMP3?"ALARM":"");
|
||||
}
|
||||
} else
|
||||
printf("ERROR: Can't get TEMP3 data!\n");
|
||||
free_the_label(&label);
|
||||
|
||||
}
|
||||
|
||||
void print_lm78(const sensors_chip_name *name)
|
||||
|
@@ -29,6 +29,7 @@ extern void print_adm1021(const sensors_chip_name *name);
|
||||
extern void print_adm9240(const sensors_chip_name *name);
|
||||
extern void print_lm78(const sensors_chip_name *name);
|
||||
extern void print_sis5595(const sensors_chip_name *name);
|
||||
extern void print_via686a(const sensors_chip_name *name);
|
||||
extern void print_gl518(const sensors_chip_name *name);
|
||||
extern void print_lm80(const sensors_chip_name *name);
|
||||
extern void print_w83781d(const sensors_chip_name *name);
|
||||
|
@@ -262,6 +262,8 @@ void do_a_print(sensors_chip_name name)
|
||||
print_lm78(&name);
|
||||
else if (!strcmp(name.prefix,"sis5595"))
|
||||
print_sis5595(&name);
|
||||
else if (!strcmp(name.prefix,"via686a"))
|
||||
print_via686a(&name);
|
||||
else if (!strcmp(name.prefix,"lm80"))
|
||||
print_lm80(&name);
|
||||
else if (!strcmp(name.prefix,"gl518sm"))
|
||||
|
Reference in New Issue
Block a user