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:
3
CHANGES
3
CHANGES
@@ -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
|
||||||
|
@@ -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
1
README
@@ -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
|
||||||
|
@@ -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
107
doc/chips/f71805f
Normal 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.
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
751
kernel/chips/f71805f.c
Normal 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);
|
133
lib/chips.c
133
lib/chips.c
@@ -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 }
|
||||||
};
|
};
|
||||||
|
20
lib/chips.h
20
lib/chips.h
@@ -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 */
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user