mirror of
https://github.com/lm-sensors/lm-sensors
synced 2025-09-02 07:15:39 +00:00
add superio detection and driver support for it8712.
Subject: [PATCH] Re: SOLVED: Ticket #1409 Date: Fri, 03 Oct 2003 16:48:32 +0200 From: Bjørn Mork <bjorn@mork.no> Organization: m To: Mark Studebaker <mds@paradyne.com> CC: lm78@stimpy.netroedge.com, LM_Sensors developers <sensors@stimpy.netroedge.com> References: 1 , 2 , 3 Bjørn Mork <bjorn@mork.no> writes: > Mark Studebaker <mds@paradyne.com> writes: > >> If you port over the super i/o code from one of the 3 drivers listed >> above >> and send us a patch we'll include it. > > OK. Will do. Here's the patch as promised. Took the code from smsc47m1.c. It currently only changes behaviour for the IT8712F since I cannot test on any other IT87-chips, and the comments in sensors-detect made me uncertain whether they really use the same key/exit sequence. Also changed sensors-detect somewhat to support longer devids and exit sequences. Don't know if you'll approve my perl though... Bjørn git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2170 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
@@ -63,6 +63,61 @@ static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
|
|||||||
SENSORS_INSMOD_4(it87, it8705, it8712, sis950);
|
SENSORS_INSMOD_4(it87, it8705, it8712, sis950);
|
||||||
|
|
||||||
|
|
||||||
|
#define REG 0x2e /* The register to read/write */
|
||||||
|
#define DEV 0x07 /* Register: Logical device select */
|
||||||
|
#define VAL 0x2f /* The value to read/write */
|
||||||
|
#define PME 0x04 /* The device with the fan registers in it */
|
||||||
|
#define DEVID 0x20 /* Register: Device ID */
|
||||||
|
|
||||||
|
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(void)
|
||||||
|
{
|
||||||
|
outb(DEV, REG);
|
||||||
|
outb(PME, VAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
superio_enter(void)
|
||||||
|
{
|
||||||
|
outb(0x87, REG);
|
||||||
|
outb(0x01, REG);
|
||||||
|
outb(0x55, REG);
|
||||||
|
outb(0x55, REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
superio_exit(void)
|
||||||
|
{
|
||||||
|
/* safety precaution in case we put some other super IO chip
|
||||||
|
in config mode by accident */
|
||||||
|
outb(0xAA, REG);
|
||||||
|
|
||||||
|
/* documented exit sequence */
|
||||||
|
outb(0x02, REG);
|
||||||
|
outb(0x02, VAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* just IT8712F for now - this should be extended to support the other
|
||||||
|
chips as well */
|
||||||
|
#define IT87_DEVID_MATCH(id) ((id) == 0x8712)
|
||||||
|
|
||||||
|
#define IT87_ACT_REG 0x30
|
||||||
|
#define IT87_BASE_REG 0x60
|
||||||
|
|
||||||
/* Update battery voltage after every reading if true */
|
/* Update battery voltage after every reading if true */
|
||||||
static int update_vbat = 0;
|
static int update_vbat = 0;
|
||||||
|
|
||||||
@@ -210,6 +265,7 @@ struct it87_data {
|
|||||||
|
|
||||||
|
|
||||||
static int it87_attach_adapter(struct i2c_adapter *adapter);
|
static int it87_attach_adapter(struct i2c_adapter *adapter);
|
||||||
|
static int it87_find(int *address);
|
||||||
static int it87_detect(struct i2c_adapter *adapter, int address,
|
static int it87_detect(struct i2c_adapter *adapter, int address,
|
||||||
unsigned short flags, int kind);
|
unsigned short flags, int kind);
|
||||||
static int it87_detach_client(struct i2c_client *client);
|
static int it87_detach_client(struct i2c_client *client);
|
||||||
@@ -386,6 +442,29 @@ static int it87_attach_adapter(struct i2c_adapter *adapter)
|
|||||||
return i2c_detect(adapter, &addr_data, it87_detect);
|
return i2c_detect(adapter, &addr_data, it87_detect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int it87_find(int *address)
|
||||||
|
{
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
superio_enter();
|
||||||
|
val = (superio_inb(DEVID) << 8) |
|
||||||
|
superio_inb(DEVID + 1);
|
||||||
|
if (!IT87_DEVID_MATCH(val)) {
|
||||||
|
superio_exit();
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
superio_select();
|
||||||
|
val = (superio_inb(IT87_BASE_REG) << 8) |
|
||||||
|
superio_inb(IT87_BASE_REG + 1);
|
||||||
|
superio_exit();
|
||||||
|
*address = val & ~(IT87_EXTENT - 1);
|
||||||
|
if (*address == 0) {
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function is called by i2c_detect */
|
/* This function is called by i2c_detect */
|
||||||
int it87_detect(struct i2c_adapter *adapter, int address,
|
int it87_detect(struct i2c_adapter *adapter, int address,
|
||||||
unsigned short flags, int kind)
|
unsigned short flags, int kind)
|
||||||
@@ -1036,7 +1115,12 @@ void it87_sens(struct i2c_client *client, int operation, int ctl_name,
|
|||||||
|
|
||||||
static int __init sm_it87_init(void)
|
static int __init sm_it87_init(void)
|
||||||
{
|
{
|
||||||
|
int addr;
|
||||||
|
|
||||||
printk("it87.o version %s (%s)\n", LM_VERSION, LM_DATE);
|
printk("it87.o version %s (%s)\n", LM_VERSION, LM_DATE);
|
||||||
|
if (!it87_find(&addr)) {
|
||||||
|
normal_isa[0] = addr;
|
||||||
|
}
|
||||||
return i2c_add_driver(&it87_driver);
|
return i2c_add_driver(&it87_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1293,8 +1293,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
# actreg (optional): The activation register within the logical device
|
# actreg (optional): The activation register within the logical device
|
||||||
# actmask (optional): The activation bit in the activation register
|
# actmask (optional): The activation bit in the activation register
|
||||||
# basereg: The I/O base register within the logical device
|
# basereg: The I/O base register within the logical device
|
||||||
# exitreg: The register to write the exit value to
|
# exitseq: Sequence of addr,val pairs which exits config modem
|
||||||
# exit: The value to write to the exit register to exit
|
|
||||||
# alias_detect (optional): For chips which can be both on the ISA and the
|
# alias_detect (optional): For chips which can be both on the ISA and the
|
||||||
# I2C bus, a function which detectes whether two entries are the same.
|
# I2C bus, a function which detectes whether two entries are the same.
|
||||||
# The function should take three parameters: The ISA address, the
|
# The function should take three parameters: The ISA address, the
|
||||||
@@ -1305,19 +1304,34 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
# driver => "it87",
|
# driver => "it87",
|
||||||
# addrreg => 0x2e,
|
# addrreg => 0x2e,
|
||||||
# datareg => 0x2f,
|
# datareg => 0x2f,
|
||||||
# enter => [0x55, 0x01, 0x55, 0x55].
|
# enter => [0x55, 0x01, 0x55, 0x55],
|
||||||
# code doesn't handle multiple devid regs yet
|
# code doesn't handle multiple devid regs yet
|
||||||
# devidreg => [0x20, 0x21],
|
# devidreg => 0x20,
|
||||||
# devid => [0x87, 0x05],
|
# devid => 0x8705,
|
||||||
# logdevreg => 0x07,
|
# logdevreg => 0x07,
|
||||||
# logdev => 0x04,
|
# logdev => 0x04,
|
||||||
# actreg => 0x30,
|
# actreg => 0x30,
|
||||||
# actmask => 0x01,
|
# actmask => 0x01,
|
||||||
# basereg => 0x60,
|
# basereg => 0x60,
|
||||||
# exit is writing 0x01 to reg 0x02. - not compatible with other superio chips
|
# exit is writing 0x01(?) to reg 0x02. - not compatible with other superio chips
|
||||||
# exitreg => 0x02,
|
# exitseq => [0x2e, 0xaa, 0x2e, 0x02, 0x2f, 0x01],
|
||||||
# exit => 0x01,
|
|
||||||
# },
|
# },
|
||||||
|
{
|
||||||
|
name => "ITE 8712F Super IO Sensors",
|
||||||
|
driver => "it87",
|
||||||
|
addrreg => 0x2e,
|
||||||
|
datareg => 0x2f,
|
||||||
|
enter => [0x87, 0x01, 0x55, 0x55],
|
||||||
|
devidreg => 0x20,
|
||||||
|
devid => 0x8712,
|
||||||
|
logdevreg => 0x07,
|
||||||
|
logdev => 0x04,
|
||||||
|
actreg => 0x30,
|
||||||
|
actmask => 0x01,
|
||||||
|
basereg => 0x60,
|
||||||
|
# exit is writing 0x02 to reg 0x02. - not compatible with other superio chips
|
||||||
|
exitseq => [0x2e, 0xaa, 0x2e, 0x02, 0x2f, 0x02],
|
||||||
|
},
|
||||||
# Nat'l untested
|
# Nat'l untested
|
||||||
# {
|
# {
|
||||||
# name => "Nat. Semi. PC87366 Super I/O Sensors",
|
# name => "Nat. Semi. PC87366 Super I/O Sensors",
|
||||||
@@ -1333,8 +1347,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
# actmask => 0x01,
|
# actmask => 0x01,
|
||||||
# basereg => 0x60,
|
# basereg => 0x60,
|
||||||
# exit is writing 0x01 to reg 0x02. - not compatible with other superio chips
|
# exit is writing 0x01 to reg 0x02. - not compatible with other superio chips
|
||||||
# exitreg => ?? none req'd??
|
# exitseq => ??,
|
||||||
# exit => ??
|
|
||||||
# },
|
# },
|
||||||
{
|
{
|
||||||
name => "SMSC 47M10x Super IO Fan Sensors",
|
name => "SMSC 47M10x Super IO Fan Sensors",
|
||||||
@@ -1350,7 +1363,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
actreg => 0x20,
|
actreg => 0x20,
|
||||||
actmask => 0x01,
|
actmask => 0x01,
|
||||||
basereg => 0x60,
|
basereg => 0x60,
|
||||||
exit => 0xaa,
|
exitseq => [0x2e, 0xaa],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => "SMSC 47M14x Super IO Fan Sensors",
|
name => "SMSC 47M14x Super IO Fan Sensors",
|
||||||
@@ -1366,7 +1379,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
actreg => 0x20,
|
actreg => 0x20,
|
||||||
actmask => 0x01,
|
actmask => 0x01,
|
||||||
basereg => 0x60,
|
basereg => 0x60,
|
||||||
exit => 0xaa,
|
exitseq => [0x2e, 0xaa],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => "VT1211 Super IO Sensors",
|
name => "VT1211 Super IO Sensors",
|
||||||
@@ -1382,7 +1395,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
actreg => 0x30,
|
actreg => 0x30,
|
||||||
actmask => 0x01,
|
actmask => 0x01,
|
||||||
basereg => 0x60,
|
basereg => 0x60,
|
||||||
exit => 0xaa,
|
exitseq => [0x2e, 0xaa],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => "Winbond W83627HF Super IO Sensors",
|
name => "Winbond W83627HF Super IO Sensors",
|
||||||
@@ -1398,7 +1411,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
actreg => 0x30,
|
actreg => 0x30,
|
||||||
actmask => 0x01,
|
actmask => 0x01,
|
||||||
basereg => 0x60,
|
basereg => 0x60,
|
||||||
exit => 0xaa,
|
exitseq => [0x2e, 0xaa],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => "Winbond W83627THF Super IO Sensors",
|
name => "Winbond W83627THF Super IO Sensors",
|
||||||
@@ -1430,7 +1443,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
actreg => 0x30,
|
actreg => 0x30,
|
||||||
actmask => 0x01,
|
actmask => 0x01,
|
||||||
basereg => 0x60,
|
basereg => 0x60,
|
||||||
exit => 0xaa,
|
exitseq => [0x2e, 0xaa],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name => "Winbond W83697HF Super IO Sensors",
|
name => "Winbond W83697HF Super IO Sensors",
|
||||||
@@ -1462,7 +1475,7 @@ use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
|||||||
actreg => 0x30,
|
actreg => 0x30,
|
||||||
actmask => 0x01,
|
actmask => 0x01,
|
||||||
basereg => 0x60,
|
basereg => 0x60,
|
||||||
exit => 0xaa,
|
exitseq => [0x2e, 0xaa],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2345,6 +2358,10 @@ sub scan_superio
|
|||||||
# check the device ID
|
# check the device ID
|
||||||
outb($$chip{addrreg}, $$chip{devidreg});
|
outb($$chip{addrreg}, $$chip{devidreg});
|
||||||
$val = inb($$chip{datareg});
|
$val = inb($$chip{datareg});
|
||||||
|
if($$chip{devid}>0xff) {
|
||||||
|
outb($$chip{addrreg}, $$chip{devidreg} + 1);
|
||||||
|
$val = ($val << 8) | inb($$chip{datareg});
|
||||||
|
}
|
||||||
if($val == $$chip{devid}) {
|
if($val == $$chip{devid}) {
|
||||||
print " Success...";
|
print " Success...";
|
||||||
# switch to the sensor logical device
|
# switch to the sensor logical device
|
||||||
@@ -2384,7 +2401,9 @@ sub scan_superio
|
|||||||
printf " Failed! (0x%02x)\n", $val;
|
printf " Failed! (0x%02x)\n", $val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outb($$chip{exitreg}, $$chip{exit});
|
while ($addr = shift(@{$$chip{exitseq}})) {
|
||||||
|
outb($addr, shift(@{$$chip{exitseq}}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user