2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-09-04 00:05:10 +00:00

Initial support for the Fintek F71805F/FG chip.

git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@3169 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare
2005-11-04 20:59:18 +00:00
parent 67adf125a0
commit ffdd27a3c2
17 changed files with 1186 additions and 1 deletions

View File

@@ -26,6 +26,7 @@ ask CVS about it:
Drop I2C_FUNC_SMBUS_EMUL Drop I2C_FUNC_SMBUS_EMUL
Library: Big update to use libsysfs. More TODO though. Library: Big update to use libsysfs. More TODO though.
Fix bus matching code for Linux 2.6 (Karsten Petersen) Fix bus matching code for Linux 2.6 (Karsten Petersen)
Add f71805f support
Makefile: Compile user-space programs with -Wundef Makefile: Compile user-space programs with -Wundef
Module i2c-i810: Documentation update, PCI IDs cleanup Module i2c-i810: Documentation update, PCI IDs cleanup
Module i2c-keywest: Remove bus probing code (2.6 backport) Module i2c-keywest: Remove bus probing code (2.6 backport)
@@ -41,6 +42,7 @@ ask CVS about it:
not initialize i2c_adapter name to "unset" (2.6 not initialize i2c_adapter name to "unset" (2.6
backport) backport)
Module adm9240: Cleanups (2.6 backport) Module adm9240: Cleanups (2.6 backport)
Module f71805f: New, supports the Fintek F71805F/FG Super-I/O
Module it87: Minor cleanups Module it87: Minor cleanups
Module lm90: Support the ADM1032-2 and ADT7461-2 (2.6 backport) Module lm90: Support the ADM1032-2 and ADT7461-2 (2.6 backport)
Module via686a: Cleanups Module via686a: Cleanups
@@ -62,6 +64,7 @@ ask CVS about it:
Drop EEPROM support (Aurelien Jarno) Drop EEPROM support (Aurelien Jarno)
Program sensors: Drop free_the_label Program sensors: Drop free_the_label
Fix compilation with uclibc (no iconv) Fix compilation with uclibc (no iconv)
Add f71805f support
Program sensors-detect: Drop algorithm names Program sensors-detect: Drop algorithm names
Do not rely on i2cdetect -l printing algo names Do not rely on i2cdetect -l printing algo names
Simplify adapter name matching mechanism Simplify adapter name matching mechanism

View File

@@ -78,7 +78,8 @@ if you have questions, suggestions or problems.
Author of the i2c-sis630 bus driver. Author of the i2c-sis630 bus driver.
Added Onsemi MC1066 support to the adm1021 driver. Added Onsemi MC1066 support to the adm1021 driver.
* Jean Delvare <khali@linux-fr.org> * Jean Delvare <khali@linux-fr.org>
Author of the lm63, lm83, lm90, pc87360 and w83l785ts chip drivers. Author of the lm63, lm83, lm90 and w83l785ts SMBus chip drivers.
Author of the f71805f and pc87360 Super-I/O chip drivers.
Author of the i2c-amd756-s4882 and pca9540 SMBus multiplexing drivers. Author of the i2c-amd756-s4882 and pca9540 SMBus multiplexing drivers.
Author of the decode-vaio.pl Vaio EEPROM decoder. Author of the decode-vaio.pl Vaio EEPROM decoder.
Author of the decode-edid.pl EDID data decoder. Author of the decode-edid.pl EDID data decoder.

1
README
View File

@@ -78,6 +78,7 @@ At least the following hardware sensor chips are supported:
Asus AS99127F, ASB100 Bach Asus AS99127F, ASB100 Bach
Dallas Semiconductor DS75, DS1621, DS1625, DS1775, and DS1780 Dallas Semiconductor DS75, DS1621, DS1625, DS1775, and DS1780
Hewlett Packard Maxilife (several revisions including '99 NBA) Hewlett Packard Maxilife (several revisions including '99 NBA)
Fintek F71805F/FG
Fujitsu Siemens Poseidon, Scylla, Hermes Fujitsu Siemens Poseidon, Scylla, Hermes
Genesys Logic GL518SM, GL520SM, GL523SM Genesys Logic GL518SM, GL520SM, GL523SM
Intel Xeon processor embedded sensors Intel Xeon processor embedded sensors

View File

@@ -97,6 +97,9 @@ ds1621
(the following chip is detected as a ds1621) (the following chip is detected as a ds1621)
ds1625 1 - - - yes no ds1625 1 - - - yes no
f71805f
f71805f 9 3 3 - no yes
fscher fscher
fscher 3 3 3 - yes no fscher 3 3 3 - yes no

107
doc/chips/f71805f Normal file
View File

@@ -0,0 +1,107 @@
Kernel driver `f71805f.o'
=========================
Status: Beta.
Supported chips:
* Fintek F71805F/FG
Addresses scanned: none, address read from Super I/O config space
Prefix: 'f71805f'
Datasheet: Provided by Fintek on request
Author: Jean Delvare <khali@linux-fr.org>
Thanks to Denis Kieft from Barracuda Networks for the donation of a
test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and
for providing initial documentation.
Thanks to Kris Chen from Fintek for answering technical questions and
providing additional documentation.
Thanks to Chris Lin from Jetway for providing wiring schematics and
anwsering technical questions.
Description
-----------
The Fintek F71805F/FG Super I/O chip includes complete hardware monitoring
capabilities. It can monitor up to 9 voltages (counting its own power
source), 3 fans and 3 temperature sensors.
This chip also has fan controlling features, using either DC or PWM, in
three different modes (one manual, two automatic). The driver doesn't
support these features yet.
The driver assumes that no more than one chip is present, which seems
reasonable.
Voltage Monitoring
------------------
Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported
range is thus from 0 to 2.040 V. Voltage values outside of this range
need external resistors. An exception is in0, which is used to monitor
the chip's own power source (+3.3V), and is divided internally by a
factor 2.
The two LSB of the voltage limit registers are not used (always 0), so
you can only set the limits in steps of 32 mV (before scaling).
The wirings and resistor values suggested by Fintek are as follow:
pin expected
name use R1 R2 divider raw val.
in0 VCC VCC3.3V int. int. 2.00 1.65 V
in1 VIN1 VTT1.2V 10K - 1.00 1.20 V
in2 VIN2 VRAM 100K 100K 2.00 ~1.25 V (1)
in3 VIN3 VCHIPSET 47K 100K 1.47 2.24 V (2)
in4 VIN4 VCC5V 200K 47K 5.25 0.95 V
in5 VIN5 +12V 200K 20K 11.00 1.05 V
in6 VIN6 VCC1.5V 10K - 1.00 1.50 V
in7 VIN7 VCORE 10K - 1.00 ~1.40 V (1)
in8 VIN8 VSB5V 200K 47K 1.00 0.95 V
(1) Depends on your hardware setup.
(2) Obviously not correct, swapping R1 and R2 would make more sense.
These values can be used as hints at best, as motherboard manufacturers
are free to use a completely different setup. As a matter of fact, the
Jetway K8M8MS uses a significantly different setup. You will have to
find out documentation about your own motherboard, and edit sensors.conf
accordingly.
Each voltage measured has associated low and high limits, each of which
triggers an alarm when crossed.
Fan Monitoring
--------------
Fan rotation speeds are reported as 12-bit values from a gated clock
signal. Speeds down to 366 RPM can be measured. There is no theoretical
high limit, but values over 6000 RPM seem to cause problem. The effective
resolution is much lower than you would expect, the step between different
register values being 10 rather than 1.
The chip assumes 2 pulse-per-revolution fans.
An alarm is triggered if the rotation speed drops below a programmable
limit or is too low to be measured.
Temperature Monitoring
----------------------
Temperatures are reported in degrees Celsius. Each temperature measured
has a high limit, those crossing triggers an alarm. There is an associated
hysteresis value, below which the temperature has to drop before the
alarm is cleared.
All temperature channels are external, there is no embedded temperature
sensor. Each channel can be used for connecting either a thermal diode
or a thermistor. The driver reports the currently selected mode, but
doesn't allow changing it. In theory, the BIOS should have configured
everything properly.

View File

@@ -85,3 +85,6 @@ Wincor Nixdorf Seagate Barracuda 7200.7 160GB harddisk drive 2004-10
Aweta Intel Server system 2005-09 Aweta Intel Server system 2005-09
Drivers developed: PC87431 (IPMI SMB) MDS Drivers developed: PC87431 (IPMI SMB) MDS
Barracuda Jetway K8M8MS, Sempron 2600+, 256 MB RAM 2005-10
Networks Drivers developed: f71805f Jean Delvare

View File

@@ -2366,3 +2366,67 @@ chip "w83627ehf-*"
set temp2_over 45 set temp2_over 45
set temp2_hyst 40 set temp2_hyst 40
# Fintek F71805F/FG configuration
# This is the recommended wiring and resistor values from the F71805F/FG
# datasheet. Your motherboard manufacturer may or may not have followed
# these.
chip "f71805f-*"
# Voltages
label in0 "+3.3V"
label in1 "Vtt1.2V"
label in2 "Vram"
label in3 "Vchip"
label in4 "+5V"
label in5 "+12V"
label in6 "Vcc1.5V"
label in7 "Vcore"
label in8 "5VSB"
# in0 is scaled internally
compute in2 @*(1+100/100), @/(1+100/100)
compute in3 @*(1+100/47), @/(1+100/47)
compute in4 @*(1+200/47), @/(1+200/47)
compute in5 @*(1+200/20), @/(1+200/20)
compute in8 @*(1+200/47), @/(1+200/47)
set in0_min 3.3 * 0.95
set in0_max 3.3 * 1.05
#set in1_min 1.2 * 0.95
#set in1_max 1.2 * 1.05
#set in2_min 2.5 * 0.95
#set in2_max 2.6 * 1.05
#set in3_min 3.3 * 0.95
#set in3_max 3.3 * 1.05
#set in4_min 5.0 * 0.95
#set in4_max 5.0 * 1.05
#set in5_min 12.0 * 0.95
#set in5_max 12.0 * 1.05
#set in6_min 1.5 * 0.95
#set in6_max 1.5 * 1.05
# in7 nominal value depends on the CPU model
#set in7_min 1.4 * 0.95
#set in7_max 1.4 * 1.05
#set in8_min 5.0 * 0.95
#set in8_max 5.0 * 1.05
# Fans
label fan1 "CPU Fan"
label fan2 "Sys Fan"
label fan3 "Aux Fan"
#set fan1_min 2100
#set fan2_min 1400
#set fan3_min 1400
# Temperatures
label temp1 "CPU Temp"
label temp2 "Sys Temp"
label temp3 "Aux Temp"
#set temp1_max 60
#set temp1_hyst 58
#set temp2_max 50
#set temp2_hyst 48
#set temp3_max 50
#set temp3_hyst 48

View File

@@ -71,6 +71,9 @@ endif
ifneq ($(shell if grep -q '^CONFIG_SENSORS_EEPROM=y' $(LINUX)/.config; then echo 1; fi),1) ifneq ($(shell if grep -q '^CONFIG_SENSORS_EEPROM=y' $(LINUX)/.config; then echo 1; fi),1)
KERNELCHIPSTARGETS += $(MODULE_DIR)/eeprom.o KERNELCHIPSTARGETS += $(MODULE_DIR)/eeprom.o
endif endif
ifneq ($(shell if grep -q '^CONFIG_SENSORS_F71805F=y' $(LINUX)/.config; then echo 1; fi),1)
KERNELCHIPSTARGETS += $(MODULE_DIR)/f71805f.o
endif
ifneq ($(shell if grep -q '^CONFIG_SENSORS_FSCHER=y' $(LINUX)/.config; then echo 1; fi),1) ifneq ($(shell if grep -q '^CONFIG_SENSORS_FSCHER=y' $(LINUX)/.config; then echo 1; fi),1)
KERNELCHIPSTARGETS += $(MODULE_DIR)/fscher.o KERNELCHIPSTARGETS += $(MODULE_DIR)/fscher.o
endif endif

751
kernel/chips/f71805f.c Normal file
View File

@@ -0,0 +1,751 @@
/*
* f71805f.c - driver for the Fintek F71805F Super-I/O chip integrated
* hardware monitoring features
* Copyright (C) 2005 Jean Delvare <khali@linux-fr.org>
*
* The F71805F is a LPC Super-I/O chip made by Fintek. It integrates
* complete hardware monitoring features: voltage, fan and temperature
* sensors, and manual and automatic fan speed control.
*
* 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/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/i2c-proc.h>
#include <asm/io.h>
#include "version.h"
/* ISA address is read from Super-I/O configuration space */
static unsigned short normal_i2c[] = { SENSORS_I2C_END };
static unsigned short normal_i2c_range[] = { SENSORS_I2C_END };
static unsigned int normal_isa[] = { 0, SENSORS_ISA_END };
static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
SENSORS_INSMOD_1(f71805f);
#define DRVNAME "f71805f"
/*
* Super-I/O constants and functions
*/
static int REG; /* The register to read from/write to */
static int VAL; /* The value to read/write */
#define F71805F_LD_HWM 0x04
#define SIO_REG_LDSEL 0x07 /* Logical device select */
#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
#define SIO_REG_DEVREV 0x22 /* Device revision */
#define SIO_REG_ENABLE 0x30 /* Logical device enable */
#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
#define SIO_F71805F_ID 0x0406
static inline int
superio_inb(int reg)
{
outb(reg, REG);
return inb(VAL);
}
static int
superio_inw(int reg)
{
int val;
outb(reg++, REG);
val = inb(VAL) << 8;
outb(reg, REG);
val |= inb(VAL);
return val;
}
static inline void
superio_select(int ld)
{
outb(SIO_REG_LDSEL, REG);
outb(ld, VAL);
}
static inline void
superio_enter(void)
{
outb(0x87, REG);
outb(0x87, REG);
}
static inline void
superio_exit(void)
{
outb(0xaa, REG);
}
/*
* ISA constants
*/
#define REGION_LENGTH 2
#define ADDR_REG_OFFSET 0
#define DATA_REG_OFFSET 1
/*
* Registers
*/
/* in nr from 0 to 8 (8-bit values) */
#define F71805F_REG_IN(nr) (0x10 + (nr))
#define F71805F_REG_IN_HIGH(nr) (0x40 + 2 * (nr))
#define F71805F_REG_IN_LOW(nr) (0x41 + 2 * (nr))
/* fan nr from 0 to 2 (12-bit values, two registers) */
#define F71805F_REG_FAN(nr) (0x20 + 2 * (nr))
#define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr))
#define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr))
/* temp nr from 0 to 2 (8-bit values) */
#define F71805F_REG_TEMP(nr) (0x1B + (nr))
#define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr))
#define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr))
#define F71805F_REG_TEMP_MODE 0x01
#define F71805F_REG_START 0x00
/* status nr from 0 to 2 */
#define F71805F_REG_STATUS(nr) (0x36 + (nr))
/*
* Data structures and manipulation thereof
*/
struct f71805f_data {
struct i2c_client client;
struct semaphore lock;
int sysctl_id;
struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
unsigned long last_limits; /* In jiffies */
/* Register values */
u8 in[9];
u8 in_high[9];
u8 in_low[9];
u16 fan[3];
u16 fan_low[3];
u8 fan_enabled; /* Read once at init time */
u8 temp[3];
u8 temp_high[3];
u8 temp_hyst[3];
u8 temp_mode;
u8 alarms[3];
};
static inline long in_from_reg(u8 reg)
{
return (reg * 8);
}
/* The 2 least significant bits are not used */
static inline u8 in_to_reg(long val)
{
if (val <= 0)
return 0;
if (val >= 2016)
return 0xfc;
return (((val + 16) / 32) << 2);
}
/* in0 is downscaled by a factor 2 internally */
static inline long in0_from_reg(u8 reg)
{
return (reg * 16);
}
static inline u8 in0_to_reg(long val)
{
if (val <= 0)
return 0;
if (val >= 4032)
return 0xfc;
return (((val + 32) / 64) << 2);
}
/* The 4 most significant bits are not used */
static inline long fan_from_reg(u16 reg)
{
reg &= 0xfff;
if (!reg || reg == 0xfff)
return 0;
return (1500000 / reg);
}
static inline u16 fan_to_reg(long rpm)
{
/* If the low limit is set below what the chip can measure,
store the largest possible 12-bit value in the registers,
so that no alarm will ever trigger. */
if (rpm < 367)
return 0xfff;
return (1500000 / rpm);
}
static inline u8 temp_to_reg(long val)
{
if (val < 0)
val = 0;
else if (val > 0xff)
val = 0xff;
return val;
}
/*
* Driver and client management
*/
static u8 f71805f_read8(struct i2c_client *client, u8 reg)
{
struct f71805f_data *data = client->data;
u8 val;
down(&data->lock);
outb_p(reg, client->addr + ADDR_REG_OFFSET);
val = inb_p(client->addr + DATA_REG_OFFSET);
up(&data->lock);
return val;
}
static void f71805f_write8(struct i2c_client *client, u8 reg, u8 val)
{
struct f71805f_data *data = client->data;
down(&data->lock);
outb_p(reg, client->addr + ADDR_REG_OFFSET);
outb_p(val, client->addr + DATA_REG_OFFSET);
up(&data->lock);
}
/* It is important to read the MSB first, because doing so latches the
value of the LSB, so we are sure both bytes belong to the same value. */
static u16 f71805f_read16(struct i2c_client *client, u8 reg)
{
struct f71805f_data *data = client->data;
u16 val;
down(&data->lock);
outb_p(reg, client->addr + ADDR_REG_OFFSET);
val = inb_p(client->addr + DATA_REG_OFFSET) << 8;
outb_p(++reg, client->addr + ADDR_REG_OFFSET);
val |= inb_p(client->addr + DATA_REG_OFFSET);
up(&data->lock);
return val;
}
static void f71805f_write16(struct i2c_client *client, u8 reg, u16 val)
{
struct f71805f_data *data = client->data;
down(&data->lock);
outb_p(reg, client->addr + ADDR_REG_OFFSET);
outb_p(val >> 8, client->addr + DATA_REG_OFFSET);
outb_p(++reg, client->addr + ADDR_REG_OFFSET);
outb_p(val & 0xff, client->addr + DATA_REG_OFFSET);
up(&data->lock);
}
static struct i2c_driver f71805f_driver;
static ctl_table f71805f_dir_table_template[];
static void f71805f_init_client(struct i2c_client *client)
{
struct f71805f_data *data = client->data;
u8 reg;
int i;
reg = f71805f_read8(client, F71805F_REG_START);
if ((reg & 0x41) != 0x01) {
printk(KERN_DEBUG "%s: Starting monitoring operations\n",
DRVNAME);
f71805f_write8(client,
F71805F_REG_START, (reg | 0x01) & ~0x40);
}
/* Fan monitoring can be disabled. If it is, we won't be polling
the register values, and instead set the cache to return 0 RPM. */
for (i = 0; i < 3; i++) {
reg = f71805f_read8(client, F71805F_REG_FAN_CTRL(i));
if (!(reg & 0x80))
data->fan_enabled |= (1 << i);
else
data->fan[i] = data->fan_low[i] = 0xfff;
}
}
static int f71805f_detect(struct i2c_adapter *adapter, int address,
unsigned short flags, int kind)
{
struct i2c_client *client;
struct f71805f_data *data;
int err = 0;
if (!request_region(address, REGION_LENGTH, f71805f_driver.name)) {
err = -EBUSY;
goto exit;
}
if (!(data = kmalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit_release;
}
memset(data, 0, sizeof(struct f71805f_data));
/* Fill in the client fields */
client = &data->client;
client->addr = address;
client->data = data;
client->adapter = adapter;
client->driver = &f71805f_driver;
strcpy(client->name, "F71805F chip");
init_MUTEX(&data->lock);
init_MUTEX(&data->update_lock);
/* Tell the i2c core a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
/* Register a new directory entry in /proc */
err = i2c_register_entry(client, "f71805f",
f71805f_dir_table_template, THIS_MODULE);
if (err < 0)
goto exit_detach;
data->sysctl_id = err;
/* Initialize the F71805F chip */
f71805f_init_client(client);
return 0;
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit_release:
release_region(address, REGION_LENGTH);
exit:
return err;
}
static int f71805f_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_detect(adapter, &addr_data, f71805f_detect);
}
static int f71805f_detach_client(struct i2c_client *client)
{
int err;
struct f71805f_data *data = client->data;
i2c_deregister_entry(data->sysctl_id);
if ((err = i2c_detach_client(client))) {
printk(KERN_ERR "%s: Client deregistration failed, "
"client not detached\n", DRVNAME);
return err;
}
release_region(client->addr, REGION_LENGTH);
kfree(client->data);
return 0;
}
static void f71805f_update_client(struct i2c_client *client)
{
struct f71805f_data *data = client->data;
int nr;
down(&data->update_lock);
/* Limit registers cache is refreshed after 60 seconds */
if ((jiffies - data->last_limits > 60 * HZ)
|| (jiffies < data->last_limits)
|| !data->valid) {
for (nr = 0; nr < 9; nr++) {
data->in_high[nr] = f71805f_read8(client,
F71805F_REG_IN_HIGH(nr));
data->in_low[nr] = f71805f_read8(client,
F71805F_REG_IN_LOW(nr));
}
for (nr = 0; nr < 3; nr++) {
if (data->fan_enabled & (1 << nr))
data->fan_low[nr] = f71805f_read16(client,
F71805F_REG_FAN_LOW(nr));
}
for (nr = 0; nr < 3; nr++) {
data->temp_high[nr] = f71805f_read8(client,
F71805F_REG_TEMP_HIGH(nr));
data->temp_hyst[nr] = f71805f_read8(client,
F71805F_REG_TEMP_HYST(nr));
}
data->temp_mode = f71805f_read8(client, F71805F_REG_TEMP_MODE);
data->last_limits = jiffies;
}
/* Measurement registers cache is refreshed after 1 second */
if ((jiffies - data->last_updated > HZ)
|| (jiffies < data->last_updated)
|| !data->valid) {
for (nr = 0; nr < 9; nr++) {
data->in[nr] = f71805f_read8(client,
F71805F_REG_IN(nr));
}
for (nr = 0; nr < 3; nr++) {
if (data->fan_enabled & (1 << nr))
data->fan[nr] = f71805f_read16(client,
F71805F_REG_FAN(nr));
}
for (nr = 0; nr < 3; nr++) {
data->temp[nr] = f71805f_read8(client,
F71805F_REG_TEMP(nr));
}
for (nr = 0; nr < 3; nr++) {
data->alarms[nr] = f71805f_read8(client,
F71805F_REG_STATUS(nr));
}
data->last_updated = jiffies;
data->valid = 1;
}
up(&data->update_lock);
}
/* -- SENSORS SYSCTL START -- */
#define F71805F_SYSCTL_IN0 1000
#define F71805F_SYSCTL_IN1 1001
#define F71805F_SYSCTL_IN2 1002
#define F71805F_SYSCTL_IN3 1003
#define F71805F_SYSCTL_IN4 1004
#define F71805F_SYSCTL_IN5 1005
#define F71805F_SYSCTL_IN6 1006
#define F71805F_SYSCTL_IN7 1007
#define F71805F_SYSCTL_IN8 1008
#define F71805F_SYSCTL_FAN1 1101
#define F71805F_SYSCTL_FAN2 1102
#define F71805F_SYSCTL_FAN3 1103
#define F71805F_SYSCTL_TEMP1 1201
#define F71805F_SYSCTL_TEMP2 1202
#define F71805F_SYSCTL_TEMP3 1203
#define F71805F_SYSCTL_SENSOR1 1211
#define F71805F_SYSCTL_SENSOR2 1212
#define F71805F_SYSCTL_SENSOR3 1213
#define F71805F_SYSCTL_ALARMS_IN 1090
#define F71805F_SYSCTL_ALARMS_FAN 1190
#define F71805F_SYSCTL_ALARMS_TEMP 1290
/* -- SENSORS SYSCTL END -- */
static void f71805f_in(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
int nr = ctl_name - F71805F_SYSCTL_IN0;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 3;
else if (operation == SENSORS_PROC_REAL_READ) {
f71805f_update_client(client);
results[0] = in_from_reg(data->in_low[nr]);
results[1] = in_from_reg(data->in_high[nr]);
results[2] = in_from_reg(data->in[nr]);
*nrels_mag = 3;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag < 1)
return;
down(&data->update_lock);
data->in_low[nr] = in_to_reg(results[0]);
f71805f_write8(client, F71805F_REG_IN_LOW(nr),
data->in_low[nr]);
if (*nrels_mag >= 2) {
data->in_high[nr] = in_to_reg(results[1]);
f71805f_write8(client, F71805F_REG_IN_HIGH(nr),
data->in_high[nr]);
}
up(&data->update_lock);
}
}
static void f71805f_in0(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 3;
else if (operation == SENSORS_PROC_REAL_READ) {
f71805f_update_client(client);
results[0] = in0_from_reg(data->in_low[0]);
results[1] = in0_from_reg(data->in_high[0]);
results[2] = in0_from_reg(data->in[0]);
*nrels_mag = 3;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag < 1)
return;
down(&data->update_lock);
data->in_low[0] = in0_to_reg(results[0]);
f71805f_write8(client, F71805F_REG_IN_LOW(0),
data->in_low[0]);
if (*nrels_mag >= 2) {
data->in_high[0] = in0_to_reg(results[1]);
f71805f_write8(client, F71805F_REG_IN_HIGH(0),
data->in_high[0]);
}
up(&data->update_lock);
}
}
static void f71805f_fan(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
int nr = ctl_name - F71805F_SYSCTL_FAN1;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
f71805f_update_client(client);
results[0] = fan_from_reg(data->fan_low[nr]);
results[1] = fan_from_reg(data->fan[nr]);
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag < 1)
return;
down(&data->update_lock);
data->fan_low[nr] = fan_to_reg(results[0]);
f71805f_write16(client, F71805F_REG_FAN_LOW(nr),
data->fan_low[nr]);
up(&data->update_lock);
}
}
static void f71805f_temp(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
int nr = ctl_name - F71805F_SYSCTL_TEMP1;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
f71805f_update_client(client);
results[0] = data->temp_high[nr];
results[1] = data->temp_hyst[nr];
results[2] = data->temp[nr];
*nrels_mag = 3;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag < 1)
return;
down(&data->update_lock);
data->temp_high[nr] = temp_to_reg(results[0]);
f71805f_write8(client, F71805F_REG_TEMP_HIGH(nr),
data->temp_high[nr]);
if (*nrels_mag >= 2) {
data->temp_hyst[nr] = temp_to_reg(results[1]);
f71805f_write8(client, F71805F_REG_TEMP_HYST(nr),
data->temp_hyst[nr]);
}
up(&data->update_lock);
}
}
static void f71805f_sensor(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
int nr = ctl_name - F71805F_SYSCTL_SENSOR1;
f71805f_update_client(client);
results[0] = (data->temp_mode & (1 << nr)) ? 3 : 4;
*nrels_mag = 1;
}
}
static void f71805f_alarms_in(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
f71805f_update_client(client);
results[0] = data->alarms[0]
| ((data->alarms[1] & 0x01) << 8);
*nrels_mag = 1;
}
}
static void f71805f_alarms_fan(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
f71805f_update_client(client);
results[0] = data->alarms[2] & 0x07;
*nrels_mag = 1;
}
}
static void f71805f_alarms_temp(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct f71805f_data *data = client->data;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
f71805f_update_client(client);
results[0] = (data->alarms[1] >> 3) & 0x07;
*nrels_mag = 1;
}
}
static ctl_table f71805f_dir_table_template[] = {
{ F71805F_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in0 },
{ F71805F_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_IN7, "in7", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_IN8, "in8", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_in },
{ F71805F_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_fan },
{ F71805F_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_fan },
{ F71805F_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_fan },
{ F71805F_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_temp },
{ F71805F_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_temp },
{ F71805F_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_temp },
{ F71805F_SYSCTL_SENSOR1, "sensor1", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_sensor },
{ F71805F_SYSCTL_SENSOR2, "sensor2", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_sensor },
{ F71805F_SYSCTL_SENSOR3, "sensor3", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_sensor },
{ F71805F_SYSCTL_ALARMS_IN, "alarms_in", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_alarms_in },
{ F71805F_SYSCTL_ALARMS_FAN, "alarms_fan", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_alarms_fan },
{ F71805F_SYSCTL_ALARMS_TEMP, "alarms_temp", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &f71805f_alarms_temp },
{ 0 }
};
static struct i2c_driver f71805f_driver = {
.name = "F71805F sensor driver",
.flags = I2C_DF_NOTIFY,
.attach_adapter = f71805f_attach_adapter,
.detach_client = f71805f_detach_client,
};
static int __init f71805f_find(int sioaddr, unsigned int *address)
{
int err = -ENODEV;
u16 devid;
REG = sioaddr;
VAL = sioaddr + 1;
superio_enter();
devid = superio_inw(SIO_REG_DEVID);
if (devid != SIO_F71805F_ID)
goto exit;
superio_select(F71805F_LD_HWM);
if (!(superio_inb(SIO_REG_ENABLE) & 0x01)) {
printk(KERN_WARNING "%s: Device not activated, skipping\n",
DRVNAME);
goto exit;
}
*address = superio_inw(SIO_REG_ADDR);
if (*address == 0) {
printk(KERN_WARNING "%s: Base address not set, skipping\n",
DRVNAME);
goto exit;
}
err = 0;
printk(KERN_INFO "%s: Found F71805F chip at %#x, revision %u\n",
DRVNAME, *address, superio_inb(SIO_REG_DEVREV));
exit:
superio_exit();
return err;
}
static int __init f71805f_init(void)
{
printk("%s: Driver version %s (%s)\n", DRVNAME, LM_VERSION, LM_DATE);
if (f71805f_find(0x2e, &normal_isa[0])
&& f71805f_find(0x4e, &normal_isa[0]))
return -ENODEV;
return i2c_add_driver(&f71805f_driver);
}
static void __exit f71805f_exit(void)
{
i2c_del_driver(&f71805f_driver);
}
MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("F71805F hardware monitoring driver");
module_init(f71805f_init);
module_exit(f71805f_exit);

View File

@@ -5418,6 +5418,138 @@ static sensors_chip_feature smsc47b397_features[] =
{ 0 } { 0 }
}; };
static sensors_chip_feature f71805f_features[] =
{
/* 9 voltage inputs */
{ SENSORS_F71805F_IN(0), "in0", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN0, VALUE(3), 3 },
{ SENSORS_F71805F_IN(1), "in1", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN1, VALUE(3), 3 },
{ SENSORS_F71805F_IN(2), "in2", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN2, VALUE(3), 3 },
{ SENSORS_F71805F_IN(3), "in3", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN3, VALUE(3), 3 },
{ SENSORS_F71805F_IN(4), "in4", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN4, VALUE(3), 3 },
{ SENSORS_F71805F_IN(5), "in5", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN5, VALUE(3), 3 },
{ SENSORS_F71805F_IN(6), "in6", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN6, VALUE(3), 3 },
{ SENSORS_F71805F_IN(7), "in7", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN7, VALUE(3), 3 },
{ SENSORS_F71805F_IN(8), "in8", NOMAP, NOMAP, R,
F71805F_SYSCTL_IN8, VALUE(3), 3 },
{ SENSORS_F71805F_IN_MIN(0), "in0_min",
SENSORS_F71805F_IN(0), SENSORS_F71805F_IN(0), RW,
F71805F_SYSCTL_IN0, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(1), "in1_min",
SENSORS_F71805F_IN(1), SENSORS_F71805F_IN(1), RW,
F71805F_SYSCTL_IN1, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(2), "in2_min",
SENSORS_F71805F_IN(2), SENSORS_F71805F_IN(2), RW,
F71805F_SYSCTL_IN2, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(3), "in3_min",
SENSORS_F71805F_IN(3), SENSORS_F71805F_IN(3), RW,
F71805F_SYSCTL_IN3, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(4), "in4_min",
SENSORS_F71805F_IN(4), SENSORS_F71805F_IN(4), RW,
F71805F_SYSCTL_IN4, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(5), "in5_min",
SENSORS_F71805F_IN(5), SENSORS_F71805F_IN(5), RW,
F71805F_SYSCTL_IN5, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(6), "in6_min",
SENSORS_F71805F_IN(6), SENSORS_F71805F_IN(6), RW,
F71805F_SYSCTL_IN6, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(7), "in7_min",
SENSORS_F71805F_IN(7), SENSORS_F71805F_IN(7), RW,
F71805F_SYSCTL_IN7, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MIN(8), "in8_min",
SENSORS_F71805F_IN(8), SENSORS_F71805F_IN(8), RW,
F71805F_SYSCTL_IN8, VALUE(1), 3 },
{ SENSORS_F71805F_IN_MAX(0), "in0_max",
SENSORS_F71805F_IN(0), SENSORS_F71805F_IN(0), RW,
F71805F_SYSCTL_IN0, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(1), "in1_max",
SENSORS_F71805F_IN(1), SENSORS_F71805F_IN(1), RW,
F71805F_SYSCTL_IN1, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(2), "in2_max",
SENSORS_F71805F_IN(2), SENSORS_F71805F_IN(2), RW,
F71805F_SYSCTL_IN2, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(3), "in3_max",
SENSORS_F71805F_IN(3), SENSORS_F71805F_IN(3), RW,
F71805F_SYSCTL_IN3, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(4), "in4_max",
SENSORS_F71805F_IN(4), SENSORS_F71805F_IN(4), RW,
F71805F_SYSCTL_IN4, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(5), "in5_max",
SENSORS_F71805F_IN(5), SENSORS_F71805F_IN(5), RW,
F71805F_SYSCTL_IN5, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(6), "in6_max",
SENSORS_F71805F_IN(6), SENSORS_F71805F_IN(6), RW,
F71805F_SYSCTL_IN6, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(7), "in7_max",
SENSORS_F71805F_IN(7), SENSORS_F71805F_IN(7), RW,
F71805F_SYSCTL_IN7, VALUE(2), 3 },
{ SENSORS_F71805F_IN_MAX(8), "in8_max",
SENSORS_F71805F_IN(8), SENSORS_F71805F_IN(8), RW,
F71805F_SYSCTL_IN8, VALUE(2), 3 },
/* 3 fan tachometers */
{ SENSORS_F71805F_FAN(1), "fan1", NOMAP, NOMAP, R,
F71805F_SYSCTL_FAN1, VALUE(2), 0 },
{ SENSORS_F71805F_FAN(2), "fan2", NOMAP, NOMAP, R,
F71805F_SYSCTL_FAN2, VALUE(2), 0 },
{ SENSORS_F71805F_FAN(3), "fan3", NOMAP, NOMAP, R,
F71805F_SYSCTL_FAN3, VALUE(2), 0 },
{ SENSORS_F71805F_FAN_MIN(1), "fan1_min",
SENSORS_F71805F_FAN(1), SENSORS_F71805F_FAN(1), RW,
F71805F_SYSCTL_FAN1, VALUE(1), 0 },
{ SENSORS_F71805F_FAN_MIN(2), "fan2_min",
SENSORS_F71805F_FAN(2), SENSORS_F71805F_FAN(2), RW,
F71805F_SYSCTL_FAN2, VALUE(1), 0 },
{ SENSORS_F71805F_FAN_MIN(3), "fan3_min",
SENSORS_F71805F_FAN(3), SENSORS_F71805F_FAN(3), RW,
F71805F_SYSCTL_FAN3, VALUE(1), 0 },
/* 3 temperature inputs */
{ SENSORS_F71805F_TEMP(1), "temp1", NOMAP, NOMAP, R,
F71805F_SYSCTL_TEMP1, VALUE(3), 0 },
{ SENSORS_F71805F_TEMP(2), "temp2", NOMAP, NOMAP, R,
F71805F_SYSCTL_TEMP2, VALUE(3), 0 },
{ SENSORS_F71805F_TEMP(3), "temp3", NOMAP, NOMAP, R,
F71805F_SYSCTL_TEMP3, VALUE(3), 0 },
{ SENSORS_F71805F_TEMP_MAX(1), "temp1_max",
SENSORS_F71805F_TEMP(1), SENSORS_F71805F_TEMP(1), RW,
F71805F_SYSCTL_TEMP1, VALUE(1), 0 },
{ SENSORS_F71805F_TEMP_MAX(2), "temp2_max",
SENSORS_F71805F_TEMP(2), SENSORS_F71805F_TEMP(2), RW,
F71805F_SYSCTL_TEMP2, VALUE(1), 0 },
{ SENSORS_F71805F_TEMP_MAX(3), "temp3_max",
SENSORS_F71805F_TEMP(3), SENSORS_F71805F_TEMP(3), RW,
F71805F_SYSCTL_TEMP3, VALUE(1), 0 },
{ SENSORS_F71805F_TEMP_HYST(1), "temp1_hyst",
SENSORS_F71805F_TEMP(1), SENSORS_F71805F_TEMP(1), RW,
F71805F_SYSCTL_TEMP1, VALUE(2), 0 },
{ SENSORS_F71805F_TEMP_HYST(2), "temp2_hyst",
SENSORS_F71805F_TEMP(2), SENSORS_F71805F_TEMP(2), RW,
F71805F_SYSCTL_TEMP2, VALUE(2), 0 },
{ SENSORS_F71805F_TEMP_HYST(3), "temp3_hyst",
SENSORS_F71805F_TEMP(3), SENSORS_F71805F_TEMP(3), RW,
F71805F_SYSCTL_TEMP3, VALUE(2), 0 },
{ SENSORS_F71805F_TEMP_TYPE(1), "sensor1", NOMAP, NOMAP, R,
F71805F_SYSCTL_SENSOR1, VALUE(1), 0 },
{ SENSORS_F71805F_TEMP_TYPE(2), "sensor2", NOMAP, NOMAP, R,
F71805F_SYSCTL_SENSOR2, VALUE(1), 0 },
{ SENSORS_F71805F_TEMP_TYPE(3), "sensor3", NOMAP, NOMAP, R,
F71805F_SYSCTL_SENSOR3, VALUE(1), 0 },
/* 3 alarm bitvectors */
{ SENSORS_F71805F_ALARMS_IN, "alarms_in", NOMAP, NOMAP, R,
F71805F_SYSCTL_ALARMS_IN, VALUE(1), 0 },
{ SENSORS_F71805F_ALARMS_FAN, "alarms_fan", NOMAP, NOMAP, R,
F71805F_SYSCTL_ALARMS_FAN, VALUE(1), 0 },
{ SENSORS_F71805F_ALARMS_TEMP, "alarms_temp", NOMAP, NOMAP, R,
F71805F_SYSCTL_ALARMS_TEMP, VALUE(1), 0 },
{ 0 }
};
sensors_chip_features sensors_chip_features_list[] = sensors_chip_features sensors_chip_features_list[] =
{ {
{ SENSORS_LM78_PREFIX, lm78_features }, { SENSORS_LM78_PREFIX, lm78_features },
@@ -5516,5 +5648,6 @@ sensors_chip_features sensors_chip_features_list[] =
{ SENSORS_ADM1031_PREFIX, adm1031_features }, { SENSORS_ADM1031_PREFIX, adm1031_features },
{ SENSORS_LM93_PREFIX, lm93_features }, { SENSORS_LM93_PREFIX, lm93_features },
{ SENSORS_SMSC47B397_PREFIX, smsc47b397_features }, { SENSORS_SMSC47B397_PREFIX, smsc47b397_features },
{ SENSORS_F71805F_PREFIX, f71805f_features },
{ 0 } { 0 }
}; };

View File

@@ -2090,4 +2090,24 @@
#define SENSORS_SMSC47B397_FAN3 0x13 /* R */ #define SENSORS_SMSC47B397_FAN3 0x13 /* R */
#define SENSORS_SMSC47B397_FAN4 0x14 /* R */ #define SENSORS_SMSC47B397_FAN4 0x14 /* R */
/* Fintek F71805F chip */
#define SENSORS_F71805F_PREFIX "f71805f"
/* in n from 0 to 8 */
#define SENSORS_F71805F_IN(n) (1 + (n))
#define SENSORS_F71805F_IN_MIN(n) (16 + (n))
#define SENSORS_F71805F_IN_MAX(n) (31 + (n))
/* fan n from 1 to 3 */
#define SENSORS_F71805F_FAN(n) (50 + (n))
#define SENSORS_F71805F_FAN_MIN(n) (60 + (n))
/* temp n from 1 to 3 */
#define SENSORS_F71805F_TEMP(n) (80 + (n))
#define SENSORS_F71805F_TEMP_MAX(n) (90 + (n))
#define SENSORS_F71805F_TEMP_HYST(n) (100 + (n))
#define SENSORS_F71805F_TEMP_TYPE(n) (110 + (n))
/* alarms */
#define SENSORS_F71805F_ALARMS_IN 200
#define SENSORS_F71805F_ALARMS_FAN 201
#define SENSORS_F71805F_ALARMS_TEMP 202
#endif /* def LIB_SENSORS_CHIPS_H */ #endif /* def LIB_SENSORS_CHIPS_H */

View File

@@ -20,6 +20,7 @@ if [ "$CONFIG_I2C_PROC" = "m" -o "$CONFIG_I2C_PROC" = "y" ] ; then
dep_tristate ' Analog Devices ADM9240 and compatibles' CONFIG_SENSORS_ADM9240 $CONFIG_I2C $CONFIG_I2C_PROC dep_tristate ' Analog Devices ADM9240 and compatibles' CONFIG_SENSORS_ADM9240 $CONFIG_I2C $CONFIG_I2C_PROC
dep_tristate ' Asus ASB100' CONFIG_SENSORS_ASB100 $CONFIG_I2C $CONFIG_I2C_PROC dep_tristate ' Asus ASB100' CONFIG_SENSORS_ASB100 $CONFIG_I2C $CONFIG_I2C_PROC
dep_tristate ' Dallas DS1621 and DS1625' CONFIG_SENSORS_DS1621 $CONFIG_I2C $CONFIG_I2C_PROC dep_tristate ' Dallas DS1621 and DS1625' CONFIG_SENSORS_DS1621 $CONFIG_I2C $CONFIG_I2C_PROC
dep_tristate ' Fintek F71805F' CONFIG_SENSORS_F71805F $CONFIG_I2C $CONFIG_I2C_PROC
dep_tristate ' Fujitsu-Siemens Hermes' CONFIG_SENSORS_FSCHER $CONFIG_I2C $CONFIG_I2C_PROC dep_tristate ' Fujitsu-Siemens Hermes' CONFIG_SENSORS_FSCHER $CONFIG_I2C $CONFIG_I2C_PROC
dep_tristate ' Fujitsu-Siemens Poseidon' CONFIG_SENSORS_FSCPOS $CONFIG_I2C $CONFIG_I2C_PROC dep_tristate ' Fujitsu-Siemens Poseidon' CONFIG_SENSORS_FSCPOS $CONFIG_I2C $CONFIG_I2C_PROC
dep_tristate ' Fujitsu-Siemens Scylla' CONFIG_SENSORS_FSCSCY $CONFIG_I2C $CONFIG_I2C_PROC dep_tristate ' Fujitsu-Siemens Scylla' CONFIG_SENSORS_FSCSCY $CONFIG_I2C $CONFIG_I2C_PROC

View File

@@ -29,6 +29,7 @@ kernel/chips/bt869.c drivers/sensors/bt869.c
kernel/chips/ddcmon.c drivers/sensors/ddcmon.c kernel/chips/ddcmon.c drivers/sensors/ddcmon.c
kernel/chips/ds1621.c drivers/sensors/ds1621.c kernel/chips/ds1621.c drivers/sensors/ds1621.c
kernel/chips/eeprom.c drivers/sensors/eeprom.c kernel/chips/eeprom.c drivers/sensors/eeprom.c
kernel/chips/f71805f.c drivers/sensors/f71805f.c
kernel/chips/fscher.c drivers/sensors/fscher.c kernel/chips/fscher.c drivers/sensors/fscher.c
kernel/chips/fscpos.c drivers/sensors/fscpos.c kernel/chips/fscpos.c drivers/sensors/fscpos.c
kernel/chips/fscscy.c drivers/sensors/fscscy.c kernel/chips/fscscy.c drivers/sensors/fscscy.c

View File

@@ -106,6 +106,7 @@ sub gen_Documentation_Configure_help
m@Analog Devices ADM9240 and compatibles@ or m@Analog Devices ADM9240 and compatibles@ or
m@Asus ASB100@ or m@Asus ASB100@ or
m@Dallas DS1621 and DS1625@ or m@Dallas DS1621 and DS1625@ or
m@Fintek F71805F@ or
m@Fujitsu-Siemens Hermes@ or m@Fujitsu-Siemens Hermes@ or
m@Fujitsu-Siemens Poseidon@ or m@Fujitsu-Siemens Poseidon@ or
m@Fujitsu-Siemens Scylla@ or m@Fujitsu-Siemens Scylla@ or
@@ -378,6 +379,16 @@ CONFIG_SENSORS_DS1621
in the lm_sensors package, which you can download at in the lm_sensors package, which you can download at
http://www.lm-sensors.nu/ http://www.lm-sensors.nu/
Fintek F71805F
CONFIG_SENSORS_F71805F
If you say yes here you get support for the hardware monitoring
features of the Fintek F71805F/FG Super-I/O chip. This can also be
built as a module.
You will also need the latest user-space utilities: you can find them
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu/
Fujitsu-Siemens Hermes Fujitsu-Siemens Hermes
CONFIG_SENSORS_FSCHER CONFIG_SENSORS_FSCHER
If you say yes here you get support for the Fujitsu-Siemens Hermes If you say yes here you get support for the Fujitsu-Siemens Hermes
@@ -1016,6 +1027,7 @@ obj-$(CONFIG_SENSORS_BT869) += bt869.o
obj-$(CONFIG_SENSORS_DDCMON) += ddcmon.o obj-$(CONFIG_SENSORS_DDCMON) += ddcmon.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
obj-$(CONFIG_SENSORS_FSCHER) += f71085f.o
obj-$(CONFIG_SENSORS_FSCHER) += fscher.o obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o
obj-$(CONFIG_SENSORS_FSCSCY) += fscscy.o obj-$(CONFIG_SENSORS_FSCSCY) += fscscy.o

View File

@@ -5768,6 +5768,86 @@ void print_smsc47b397(const sensors_chip_name *name)
PRINT_SMSC47B397_FAN(ii, name); PRINT_SMSC47B397_FAN(ii, name);
} }
void print_f71805f(const sensors_chip_name *name)
{
char *label;
double cur, min, max;
int alarms, valid, i;
if (!sensors_get_feature(*name, SENSORS_F71805F_ALARMS_IN, &cur))
alarms = cur + 0.5;
else {
printf("ERROR: Can't get alarms_in data!\n");
alarms = 0;
}
for (i = 0; i < 9; i++) {
if (!sensors_get_label_and_valid(*name, SENSORS_F71805F_IN(i),
&label, &valid)
&& !sensors_get_feature(*name, SENSORS_F71805F_IN(i), &cur)
&& !sensors_get_feature(*name, SENSORS_F71805F_IN_MIN(i), &min)
&& !sensors_get_feature(*name, SENSORS_F71805F_IN_MAX(i), &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 & (1 << i)) ? "ALARM" : "");
}
} else
printf("ERROR: Can't get in%d data!\n", i);
free(label);
}
if (!sensors_get_feature(*name, SENSORS_F71805F_ALARMS_FAN, &cur))
alarms = cur + 0.5;
else {
printf("ERROR: Can't get alarms_fan data!\n");
alarms = 0;
}
for (i = 1; i <= 3; i++) {
if (!sensors_get_label_and_valid(*name, SENSORS_F71805F_FAN(i),
&label, &valid)
&& !sensors_get_feature(*name, SENSORS_F71805F_FAN(i), &cur)
&& !sensors_get_feature(*name, SENSORS_F71805F_FAN_MIN(i), &min)) {
if (valid) {
print_label(label, 10);
printf("%4.0f RPM (min = %4.0f RPM) %s\n",
cur, min, (alarms & (1 << (i - 1))) ? "ALARM" : "");
}
} else
printf("ERROR: Can't get fan%d data!\n", i);
free(label);
}
if (!sensors_get_feature(*name, SENSORS_F71805F_ALARMS_TEMP, &cur))
alarms = cur + 0.5;
else {
printf("ERROR: Can't get alarms_temp data!\n");
alarms = 0;
}
for (i = 1; i <= 3; i++) {
if (!sensors_get_label_and_valid(*name, SENSORS_F71805F_TEMP(i),
&label, &valid)
&& !sensors_get_feature(*name, SENSORS_F71805F_TEMP(i), &cur)
&& !sensors_get_feature(*name, SENSORS_F71805F_TEMP_MAX(i), &max)
&& !sensors_get_feature(*name, SENSORS_F71805F_TEMP_HYST(i), &min)) {
if (valid) {
print_label(label, 10);
print_temp_info(cur, max, min, HYST, 0, 0);
printf("%5s", (alarms & (1 << (i - 1))) ? "ALARM" : "");
if (!sensors_get_feature(*name, SENSORS_F71805F_TEMP_TYPE(i), &cur)) {
int sensor = cur + 0.5;
printf(" [%s]", sensor == 3 ? "diode" : "thermistor");
}
printf("\n");
}
} else
printf("ERROR: Can't get temp%d data!\n", i);
free(label);
}
}
void print_unknown_chip(const sensors_chip_name *name) void print_unknown_chip(const sensors_chip_name *name)
{ {
int a,b,valid; int a,b,valid;

View File

@@ -70,5 +70,6 @@ extern void print_xeontemp(const sensors_chip_name *name);
extern void print_max6650(const sensors_chip_name *name); extern void print_max6650(const sensors_chip_name *name);
extern void print_adm1031(const sensors_chip_name *name); extern void print_adm1031(const sensors_chip_name *name);
extern void print_smsc47b397(const sensors_chip_name *name); extern void print_smsc47b397(const sensors_chip_name *name);
extern void print_f71805f(const sensors_chip_name *name);
#endif /* def PROG_SENSORS_CHIPS_H */ #endif /* def PROG_SENSORS_CHIPS_H */

View File

@@ -412,6 +412,7 @@ struct match matches[] = {
{ "adm1031", print_adm1031 }, { "adm1031", print_adm1031 },
{ "lm93", print_lm93 }, { "lm93", print_lm93 },
{ "smsc47b397", print_smsc47b397 }, { "smsc47b397", print_smsc47b397 },
{ "f71805f", print_f71805f },
{ NULL, NULL } { NULL, NULL }
}; };