/*
w83792d.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (C) 2004, 2005 Winbond Electronics Corp.
Chunhao Huang <DZShen@Winbond.com.tw>,
Rudolf Marek <r.marek@assembler.cz>
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.
Note:
1. This driver is only for 2.6 kernel, 2.4 kernel need a different driver.
2. This driver is only for Winbond W83792D C version device, there
are also some motherboards with B version W83792D device. The
calculation method to in6-in7(measured value, limits) is a little
different between C and B version. C or B version can be identified
by CR[0x49h].
*/
/*
Supports following chips:
Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
w83792d 9 7 7 3 0x7a 0x5ca3 yes no
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
I2C_CLIENT_END };
/* Insmod parameters */
static unsigned short force_subclients[4];
module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
static int init;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to one to force chip initialization");
/* The W83792D registers */
static const u8 W83792D_REG_IN[9] = {
0x20, /* Vcore A in DataSheet */
0x21, /* Vcore B in DataSheet */
0x22, /* VIN0 in DataSheet */
0x23, /* VIN1 in DataSheet */
0x24, /* VIN2 in DataSheet */
0x25, /* VIN3 in DataSheet */
0x26, /* 5VCC in DataSheet */
0xB0, /* 5VSB in DataSheet */
0xB1 /* VBAT in DataSheet */
};
#define W83792D_REG_LOW_BITS1 0x3E /* Low Bits I in DataSheet */
#define W83792D_REG_LOW_BITS2 0x3F /* Low Bits II in DataSheet */
static const u8 W83792D_REG_IN_MAX[9] = {
0x2B, /* Vcore A High Limit in DataSheet */
0x2D, /* Vcore B High Limit in DataSheet */
0x2F, /* VIN0 High Limit in DataSheet */
0x31, /* VIN1 High Limit in DataSheet */
0x33, /* VIN2 High Limit in DataSheet */
0x35, /* VIN3 High Limit in DataSheet */
0x37, /* 5VCC High Limit in DataSheet */
0xB4, /* 5VSB High Limit in DataSheet */
0xB6 /* VBAT High Limit in DataSheet */
};
static const u8 W83792D_REG_IN_MIN[9] = {
0x2C, /* Vcore A Low Limit in DataSheet */
0x2E, /* Vcore B Low Limit in DataSheet */
0x30, /* VIN0 Low Limit in DataSheet */
0x32, /* VIN1 Low Limit in DataSheet */
0x34, /* VIN2 Low Limit in DataSheet */
0x36, /* VIN3 Low Limit in DataSheet */
0x38, /* 5VCC Low Limit in DataSheet */
0xB5, /* 5VSB Low Limit in DataSheet */
0xB7 /* VBAT Low Limit in DataSheet */
};
static const u8 W83792D_REG_FAN[7] = {
0x28, /* FAN 1 Count in DataSheet */
0x29, /* FAN 2 Count in DataSheet */
0x2A, /* FAN 3 Count in DataSheet */
0xB8, /* FAN 4 Count in DataSheet */
0xB9, /* FAN 5 Count in DataSheet */
0xBA, /* FAN 6 Count in DataSheet */
0xBE /* FAN 7 Count in DataSheet */
};
static const u8 W83792D_REG_FAN_MIN[7] = {
0x3B, /* FAN 1 Count Low Limit in DataSheet */
0x3C, /* FAN 2 Count Low Limit in DataSheet */
0x3D, /* FAN 3 Count Low Limit in DataSheet */
0xBB, /* FAN 4 Count Low Limit
|