/*
w83627ehf - Driver for the hardware monitoring functionality of
the Winbond W83627EHF Super-I/O chip
Copyright (C) 2005 Jean Delvare <khali@linux-fr.org>
Copyright (C) 2006 Yuan Mu <Ymu@Winbond.com.tw>,
Rudolf Marek <r.marek@sh.cvut.cz>
Shamelessly ripped from the w83627hf driver
Copyright (C) 2003 Mark Studebaker
Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help
in testing and debugging this driver.
This driver also supports the W83627EHG, which is the lead-free
version of the W83627EHF.
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.
Supports the following chips:
Chip #vin #fan #pwm #temp chip_id man_id
w83627ehf 10 5 4 3 0x88,0xa1 0x5ca3
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c-isa.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include "lm75.h"
/* The actual ISA address is read from Super-I/O configuration space */
static unsigned short address;
/*
* Super-I/O constants and functions
*/
static int REG; /* The register to read/write */
static int VAL; /* The value to read/write */
#define W83627EHF_LD_HWM 0x0b
#define SIO_REG_LDSEL 0x07 /* Logical device select */
#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
#define SIO_REG_ENABLE 0x30 /* Logical device enable */
#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
#define SIO_W83627EHF_ID 0x8840
#define SIO_ID_MASK 0xFFC0
static inline void
superio_outb(int reg, int val)
{
outb(reg, REG);
outb(val, VAL);
}
static inline int
superio_inb(int reg)
{
outb(reg, REG);
return inb(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(0x02, REG);
outb(0x02, VAL);
}
/*
* ISA constants
*/
#define REGION_ALIGNMENT ~7
#define REGION_OFFSET 5
#define REGION_LENGTH 2
#define ADDR_REG_OFFSET 5
#define DATA_REG_OFFSET 6
#define W83627EHF_REG_BANK 0x4E
#define W83627EHF_REG_CONFIG 0x40
#define W83627EHF_REG_CHIP_ID 0x49
#define W83627EHF_REG_MAN_ID 0x4F
static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 };
static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c };
/* The W83627EHF registers for nr=7,8,9 are in bank 5 */
#define W83627EHF_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \