2
0
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:
Mark D. Studebaker
2003-12-14 00:54:10 +00:00
parent 0b20ca2730
commit ded7e313b1
2 changed files with 120 additions and 17 deletions

View File

@@ -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);
} }

View File

@@ -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}}));
}
} }
} }