Merge pull request #1063 from richardg867/master
Fix VT82C686 and GL518SM hardware monitors
This commit is contained in:
@@ -122,19 +122,45 @@ gl518sm_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv)
|
||||
static uint16_t
|
||||
gl518sm_read(gl518sm_t *dev, uint8_t reg)
|
||||
{
|
||||
uint16_t ret = dev->regs[reg & 0x1f];
|
||||
uint16_t ret;
|
||||
|
||||
reg &= 0x1f;
|
||||
|
||||
switch (reg) {
|
||||
case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c:
|
||||
/* two-byte registers: leave as-is */
|
||||
case 0x04: /* temperature */
|
||||
ret = (dev->values->temperatures[0] + 119) & 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* single-byte registers: duplicate low byte to high byte (real hardware behavior unknown) */
|
||||
ret |= (ret << 8);
|
||||
case 0x07: /* fan speeds */
|
||||
ret = GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8;
|
||||
ret |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3));
|
||||
break;
|
||||
|
||||
case 0x0d: /* VIN3 - AOpen System Monitor requires an approximate voltage offset of 13 at least here */
|
||||
ret = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[2]);
|
||||
break;
|
||||
|
||||
case 0x13: /* VIN2 */
|
||||
ret = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[1]);
|
||||
break;
|
||||
|
||||
case 0x14: /* VIN1 */
|
||||
ret = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[0]);
|
||||
break;
|
||||
|
||||
case 0x15: /* VDD */
|
||||
ret = 13 + GL518SM_VDD_TO_REG(dev->values->voltages[3]);
|
||||
break;
|
||||
|
||||
default: /* other registers */
|
||||
ret = dev->regs[reg];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Duplicate the low byte to the high byte on single-byte registers, although real hardware behavior is undefined. */
|
||||
if ((reg < 0x07) || (reg > 0x0c))
|
||||
ret |= ret << 8;
|
||||
|
||||
gl518sm_log("GL518SM: read(%02X) = %04X\n", reg, ret);
|
||||
|
||||
return ret;
|
||||
@@ -176,26 +202,22 @@ gl518sm_write(gl518sm_t *dev, uint8_t reg, uint16_t val)
|
||||
return 0;
|
||||
|
||||
case 0x0a:
|
||||
dev->regs[0x13] = (val & 0xff);
|
||||
dev->regs[0x13] = val & 0xff;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
dev->regs[reg] = (val & 0xfc);
|
||||
dev->regs[reg] = val & 0xfc;
|
||||
|
||||
if (val & 0x80) /* Init */
|
||||
gl518sm_reset(dev);
|
||||
break;
|
||||
|
||||
case 0x0f:
|
||||
dev->regs[reg] = (val & 0xf8);
|
||||
|
||||
/* update fan values to match the new divisor */
|
||||
dev->regs[0x07] = (GL518SM_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x0f] >> 6) & 0x3)) << 8);
|
||||
dev->regs[0x07] |= GL518SM_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x0f] >> 4) & 0x3));
|
||||
dev->regs[reg] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
dev->regs[reg] = (val & 0x7f);
|
||||
dev->regs[reg] = val & 0x7f;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -214,21 +236,14 @@ gl518sm_reset(gl518sm_t *dev)
|
||||
|
||||
dev->regs[0x00] = 0x80;
|
||||
dev->regs[0x01] = 0x80; /* revision 0x80 can read all voltages */
|
||||
dev->regs[0x04] = ((dev->values->temperatures[0] + 119) & 0xff);
|
||||
dev->regs[0x05] = 0xc7;
|
||||
dev->regs[0x06] = 0xc2;
|
||||
dev->regs[0x07] = ((GL518SM_RPM_TO_REG(dev->values->fans[0], 8) << 8) | GL518SM_RPM_TO_REG(dev->values->fans[1], 8));
|
||||
dev->regs[0x08] = 0x6464;
|
||||
dev->regs[0x09] = 0xdac5;
|
||||
dev->regs[0x0a] = 0xdac5;
|
||||
dev->regs[0x0b] = 0xdac5;
|
||||
dev->regs[0x0c] = 0xdac5;
|
||||
/* AOpen System Monitor requires an approximate voltage offset of 13 at least on 3.3V (voltages[2]) */
|
||||
dev->regs[0x0d] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[2]);
|
||||
dev->regs[0x0f] = 0xf8;
|
||||
dev->regs[0x13] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[1]);
|
||||
dev->regs[0x14] = 13 + GL518SM_VOLTAGE_TO_REG(dev->values->voltages[0]);
|
||||
dev->regs[0x15] = 13 + GL518SM_VDD_TO_REG(5000);
|
||||
}
|
||||
|
||||
|
||||
@@ -254,14 +269,15 @@ gl518sm_init(const device_t *info)
|
||||
/* Set default values. */
|
||||
hwm_values_t defaults = {
|
||||
{ /* fan speeds */
|
||||
3000, /* System */
|
||||
3000 /* CPU */
|
||||
3000, /* usually Chassis */
|
||||
3000 /* usually CPU */
|
||||
}, { /* temperatures */
|
||||
30 /* CPU */
|
||||
30 /* usually CPU */
|
||||
}, { /* voltages */
|
||||
hwm_get_vcore(), /* Vcore */
|
||||
RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the GL518SM datasheet) */
|
||||
3300 /* +3.3V */
|
||||
RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the datasheet) */
|
||||
3300, /* +3.3V */
|
||||
5000 /* +5V */
|
||||
}
|
||||
};
|
||||
hwm_values = defaults;
|
||||
|
@@ -37,10 +37,13 @@
|
||||
#define LM78_AS99127F (LM78_AS99127F_REV1 | LM78_AS99127F_REV2) /* special mask covering both _REV1 and _REV2 */
|
||||
#define LM78_WINBOND (LM78_W83781D | LM78_AS99127F | LM78_W83782D) /* special mask covering all Winbond variants */
|
||||
#define LM78_WINBOND_VENDOR_ID ((dev->local & LM78_AS99127F_REV1) ? 0x12c3 : 0x5ca3)
|
||||
#define LM78_WINBOND_BANK (dev->regs[0x4e] & 0x07)
|
||||
|
||||
#define CLAMP(a, min, max) (((a) < (min)) ? (min) : (((a) > (max)) ? (max) : (a)))
|
||||
#define LM78_RPM_TO_REG(r, d) ((r) ? CLAMP(1350000 / (r * d), 1, 255) : 0)
|
||||
#define LM78_VOLTAGE_TO_REG(v) ((v) >> 4)
|
||||
#define LM78_NEG_VOLTAGE(v, r) (v * (604.0 / ((double) r))) /* negative voltage formula from the W83781D datasheet */
|
||||
#define LM78_NEG_VOLTAGE2(v, r) (((3600 + v) * (((double) r) / (((double) r) + 56.0))) - v) /* negative voltage formula from the W83782D datasheet */
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -54,8 +57,6 @@ typedef struct {
|
||||
uint8_t data_register;
|
||||
|
||||
uint8_t smbus_addr;
|
||||
uint8_t hbacs;
|
||||
uint8_t active_bank;
|
||||
} lm78_t;
|
||||
|
||||
|
||||
@@ -135,17 +136,19 @@ lm78_isa_read(uint16_t port, void *priv)
|
||||
case 0x5:
|
||||
ret = (dev->addr_register & 0x7f);
|
||||
break;
|
||||
case 0x6:
|
||||
ret = lm78_read(dev, dev->addr_register, dev->active_bank);
|
||||
|
||||
if (((dev->active_bank == 0) &&
|
||||
case 0x6:
|
||||
ret = lm78_read(dev, dev->addr_register, LM78_WINBOND_BANK);
|
||||
|
||||
if (((LM78_WINBOND_BANK == 0) &&
|
||||
((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) ||
|
||||
((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) ||
|
||||
((dev->local & LM78_W83782D) && (dev->active_bank == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
((dev->local & LM78_W83782D) && (LM78_WINBOND_BANK == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
lm78_log("LM78: Read from unknown ISA port %d\n", port & 0x7);
|
||||
break;
|
||||
@@ -159,7 +162,7 @@ static uint8_t
|
||||
lm78_smbus_read_byte(uint8_t addr, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
return lm78_read(dev, dev->addr_register, dev->active_bank);
|
||||
return lm78_read(dev, dev->addr_register, LM78_WINBOND_BANK);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +170,7 @@ static uint8_t
|
||||
lm78_smbus_read_byte_cmd(uint8_t addr, uint8_t cmd, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
return lm78_read(dev, cmd, dev->active_bank);
|
||||
return lm78_read(dev, cmd, LM78_WINBOND_BANK);
|
||||
}
|
||||
|
||||
|
||||
@@ -175,22 +178,22 @@ static uint16_t
|
||||
lm78_smbus_read_word_cmd(uint8_t addr, uint8_t cmd, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
return (lm78_read(dev, cmd, dev->active_bank) << 8) | lm78_read(dev, cmd, dev->active_bank);
|
||||
return (lm78_read(dev, cmd, LM78_WINBOND_BANK) << 8) | lm78_read(dev, cmd, LM78_WINBOND_BANK);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank)
|
||||
{
|
||||
uint8_t ret = 0, masked_reg = reg;
|
||||
uint8_t ret = 0, masked_reg = reg, bankswitched = ((reg & 0xf8) == 0x50);
|
||||
lm75_t *lm75;
|
||||
|
||||
if (((reg & 0xf8) == 0x50) && ((bank == 1) || (bank == 2))) {
|
||||
if (bankswitched && ((bank == 1) || (bank == 2))) {
|
||||
/* LM75 registers */
|
||||
lm75 = device_get_priv(dev->lm75[bank - 1]);
|
||||
if (lm75)
|
||||
ret = lm75_read(lm75, reg);
|
||||
} else if (((reg & 0xf8) == 0x50) && ((bank == 4) || (bank == 5) || (bank == 6))) {
|
||||
} else if (bankswitched && ((bank == 4) || (bank == 5) || (bank == 6))) {
|
||||
/* W83782D additional registers */
|
||||
if (dev->local & LM78_W83782D) {
|
||||
if ((bank == 5) && ((reg == 0x50) || (reg == 0x51))) /* voltages */
|
||||
@@ -210,7 +213,7 @@ lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank)
|
||||
else if ((masked_reg >= 0x28) && (masked_reg <= 0x2a)) /* fan speeds */
|
||||
ret = LM78_RPM_TO_REG(dev->values->fans[reg & 3], 1 << ((dev->regs[((reg & 3) == 2) ? 0x4b : 0x47] >> ((reg & 3) ? 6 : 4)) & 0x3));
|
||||
else if ((reg == 0x4f) && (dev->local & LM78_WINBOND)) /* two-byte vendor ID register */
|
||||
ret = (dev->hbacs ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID);
|
||||
ret = ((dev->regs[0x4e] & 0x80) ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID);
|
||||
else if ((reg >= 0x60) && (reg <= 0x7f)) /* read auto-increment value RAM registers from their non-auto-increment locations */
|
||||
ret = dev->regs[reg & 0x3f];
|
||||
else if (dev->local & LM78_AS99127F) { /* AS99127F mirrored registers */
|
||||
@@ -244,12 +247,12 @@ lm78_isa_write(uint16_t port, uint8_t val, void *priv)
|
||||
dev->addr_register = (val & 0x7f);
|
||||
break;
|
||||
case 0x6:
|
||||
lm78_write(dev, dev->addr_register, val, dev->active_bank);
|
||||
lm78_write(dev, dev->addr_register, val, LM78_WINBOND_BANK);
|
||||
|
||||
if (((dev->active_bank == 0) &&
|
||||
if (((LM78_WINBOND_BANK == 0) &&
|
||||
((dev->addr_register == 0x41) || (dev->addr_register == 0x43) || (dev->addr_register == 0x45) || (dev->addr_register == 0x56) ||
|
||||
((dev->addr_register >= 0x60) && (dev->addr_register < 0x7f)))) ||
|
||||
((dev->local & LM78_W83782D) && (dev->active_bank == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
((dev->local & LM78_W83782D) && (LM78_WINBOND_BANK == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
@@ -273,7 +276,7 @@ static void
|
||||
lm78_smbus_write_byte_cmd(uint8_t addr, uint8_t cmd, uint8_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
lm78_write(dev, cmd, val, dev->active_bank);
|
||||
lm78_write(dev, cmd, val, LM78_WINBOND_BANK);
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +284,7 @@ static void
|
||||
lm78_smbus_write_word_cmd(uint8_t addr, uint8_t cmd, uint16_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
lm78_write(dev, cmd, val, dev->active_bank);
|
||||
lm78_write(dev, cmd, val, LM78_WINBOND_BANK);
|
||||
}
|
||||
|
||||
|
||||
@@ -387,12 +390,6 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4e:
|
||||
dev->hbacs = (dev->regs[0x4e] & 0x80);
|
||||
/* BANKSEL[0:2] is a bitfield according to the datasheet, but not in reality */
|
||||
dev->active_bank = (dev->regs[0x4e] & 0x07);
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
/* AS99127F boards perform a soft reset through this register */
|
||||
if ((dev->local & LM78_AS99127F) && (val == 0x01)) {
|
||||
@@ -432,7 +429,6 @@ lm78_reset(lm78_t *dev, uint8_t initialization)
|
||||
dev->regs[0x4c] = 0x01;
|
||||
dev->regs[0x4d] = 0x15;
|
||||
dev->regs[0x4e] = 0x80;
|
||||
dev->hbacs = (dev->regs[0x4e] & 0x80);
|
||||
dev->regs[0x4f] = (LM78_WINBOND_VENDOR_ID >> 8);
|
||||
dev->regs[0x57] = 0x80;
|
||||
|
||||
@@ -482,7 +478,7 @@ lm78_close(void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
uint16_t isa_io = (dev->local & 0xffff);
|
||||
uint16_t isa_io = dev->local & 0xffff;
|
||||
if (isa_io)
|
||||
io_removehandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev);
|
||||
|
||||
@@ -498,7 +494,7 @@ lm78_init(const device_t *info)
|
||||
|
||||
dev->local = info->local;
|
||||
|
||||
/* Set default values. */
|
||||
/* Set global default values. */
|
||||
hwm_values_t defaults = {
|
||||
{ /* fan speeds */
|
||||
3000, /* usually Chassis, sometimes CPU */
|
||||
@@ -509,25 +505,26 @@ lm78_init(const device_t *info)
|
||||
30, /* Winbond only: usually CPU, sometimes Probe */
|
||||
30 /* Winbond only: usually CPU when not the one above */
|
||||
}, { /* voltages */
|
||||
hwm_get_vcore(), /* Vcore */
|
||||
0, /* sometimes Vtt, Vio or second CPU */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
12000 * (604.0 / 2100.0), /* -12V (Rf/Rin negative voltage formula from the W83781D datasheet) */
|
||||
5000 * (604.0 / 909.0), /* -5V (Rf/Rin negative voltage formula from the W83781D datasheet) */
|
||||
RESISTOR_DIVIDER(5000, 51, 75), /* W83782D only: +5VSB (5.1K/7.5K divider suggested in the datasheet) */
|
||||
3000 /* W83782D only: VBAT */
|
||||
hwm_get_vcore(), /* Vcore */
|
||||
0, /* sometimes Vtt, Vio or second CPU */
|
||||
3300, /* +3.3V */
|
||||
RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */
|
||||
RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */
|
||||
LM78_NEG_VOLTAGE(12000, 2100), /* -12V */
|
||||
LM78_NEG_VOLTAGE(5000, 909), /* -5V */
|
||||
RESISTOR_DIVIDER(5000, 51, 75), /* W83782D only: +5VSB (5.1K/7.5K divider suggested in the datasheet) */
|
||||
3000 /* W83782D only: Vbat */
|
||||
}
|
||||
};
|
||||
|
||||
/* Set per-chip defaults. */
|
||||
/* Set chip-specific default values. */
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
defaults.voltages[5] = 12000 * (604.0 / 2400.0); /* different -12V Rin value for AS99127F (bruteforced) */
|
||||
/* AS99127: different -12V Rin value (bruteforced) */
|
||||
defaults.voltages[5] = LM78_NEG_VOLTAGE(12000, 2400);
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
/* different negative voltage formula for W83782D (from the datasheet) */
|
||||
defaults.voltages[5] = ((3600 + 12000) * (232.0 / (232.0 + 56.0))) - 12000;
|
||||
defaults.voltages[6] = ((3600 + 5000) * (120.0 / (120.0 + 56.0))) - 5000;
|
||||
/* W83782D: different negative voltage formula */
|
||||
defaults.voltages[5] = LM78_NEG_VOLTAGE2(12000, 232);
|
||||
defaults.voltages[6] = LM78_NEG_VOLTAGE2(5000, 120);
|
||||
}
|
||||
|
||||
hwm_values = defaults;
|
||||
@@ -538,9 +535,9 @@ lm78_init(const device_t *info)
|
||||
if (dev->local & LM78_WINBOND) {
|
||||
dev->lm75[i] = (device_t *) malloc(sizeof(device_t));
|
||||
memcpy(dev->lm75[i], &lm75_w83781d_device, sizeof(device_t));
|
||||
dev->lm75[i]->local = ((i + 1) << 8);
|
||||
dev->lm75[i]->local = (i + 1) << 8;
|
||||
if (dev->local & LM78_SMBUS)
|
||||
dev->lm75[i]->local |= (0x48 + i);
|
||||
dev->lm75[i]->local |= 0x48 + i;
|
||||
device_add(dev->lm75[i]);
|
||||
} else {
|
||||
dev->lm75[i] = NULL;
|
||||
@@ -549,7 +546,7 @@ lm78_init(const device_t *info)
|
||||
|
||||
lm78_reset(dev, 0);
|
||||
|
||||
uint16_t isa_io = (dev->local & 0xffff);
|
||||
uint16_t isa_io = dev->local & 0xffff;
|
||||
if (isa_io)
|
||||
io_sethandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev);
|
||||
|
||||
|
@@ -45,6 +45,9 @@ typedef struct {
|
||||
} vt82c686_t;
|
||||
|
||||
|
||||
static double voltage_factors[5] = {1.25, 1.25, 1.67, 2.6, 6.3};
|
||||
|
||||
|
||||
static void vt82c686_reset(vt82c686_t *dev, uint8_t initialization);
|
||||
|
||||
|
||||
@@ -52,7 +55,29 @@ static uint8_t
|
||||
vt82c686_read(uint16_t addr, void *priv)
|
||||
{
|
||||
vt82c686_t *dev = (vt82c686_t *) priv;
|
||||
return dev->regs[addr - dev->io_base];
|
||||
uint8_t ret;
|
||||
|
||||
addr -= dev->io_base;
|
||||
|
||||
switch (addr) {
|
||||
case 0x1f: case 0x20: case 0x21: /* temperatures */
|
||||
ret = VT82C686_TEMP_TO_REG(dev->values->temperatures[(addr == 0x1f) ? 2 : (addr & 1)]);
|
||||
break;
|
||||
|
||||
case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: /* voltages */
|
||||
ret = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[addr - 0x22], voltage_factors[addr - 0x22]);
|
||||
break;
|
||||
|
||||
case 0x29: case 0x2a: /* fan speeds */
|
||||
ret = VT82C686_RPM_TO_REG(dev->values->fans[addr - 0x29], 1 << ((dev->regs[0x47] >> ((addr == 0x29) ? 4 : 6)) & 0x3));
|
||||
break;
|
||||
|
||||
default: /* other registers */
|
||||
ret = dev->regs[addr];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,18 +90,9 @@ vt82c686_write(uint16_t port, uint8_t val, void *priv)
|
||||
if ((reg == 0x41) || (reg == 0x42) || (reg == 0x45) || (reg == 0x46) || (reg == 0x48) || (reg == 0x4a) || (reg >= 0x4c))
|
||||
return;
|
||||
|
||||
switch (reg) {
|
||||
case 0x40:
|
||||
if (val & 0x80)
|
||||
vt82c686_reset(dev, 1);
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
val &= 0xf0;
|
||||
/* update FAN1/FAN2 values to match the new divisor */
|
||||
dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 1 << ((dev->regs[0x47] >> 4) & 0x3));
|
||||
dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 1 << ((dev->regs[0x47] >> 6) & 0x3));
|
||||
break;
|
||||
if ((reg == 0x40) && (val & 0x80)) {
|
||||
val &= 0x7f;
|
||||
vt82c686_reset(dev, 1);
|
||||
}
|
||||
|
||||
dev->regs[reg] = val;
|
||||
@@ -121,28 +137,12 @@ vt82c686_reset(vt82c686_t *dev, uint8_t initialization)
|
||||
{
|
||||
memset(dev->regs, 0, 80);
|
||||
|
||||
dev->regs[0x1f] = VT82C686_TEMP_TO_REG(dev->values->temperatures[2]);
|
||||
dev->regs[0x20] = VT82C686_TEMP_TO_REG(dev->values->temperatures[0]);
|
||||
dev->regs[0x21] = VT82C686_TEMP_TO_REG(dev->values->temperatures[1]);
|
||||
|
||||
dev->regs[0x22] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[0], 1.25);
|
||||
dev->regs[0x23] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[1], 1.25);
|
||||
dev->regs[0x24] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[2], 1.67);
|
||||
dev->regs[0x25] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[3], 2.6);
|
||||
dev->regs[0x26] = VT82C686_VOLTAGE_TO_REG(dev->values->voltages[4], 6.3);
|
||||
|
||||
dev->regs[0x29] = VT82C686_RPM_TO_REG(dev->values->fans[0], 2);
|
||||
dev->regs[0x2a] = VT82C686_RPM_TO_REG(dev->values->fans[1], 2);
|
||||
|
||||
dev->regs[0x40] = 0x08;
|
||||
dev->regs[0x47] = 0x50;
|
||||
dev->regs[0x49] = (dev->values->temperatures[2] & 0x3) << 6;
|
||||
dev->regs[0x49] |= (dev->values->temperatures[1] & 0x3) << 4;
|
||||
dev->regs[0x4b] = (dev->values->temperatures[0] & 0x3) << 6;
|
||||
dev->regs[0x4b] |= 0x15;
|
||||
dev->regs[0x4b] = 0x15;
|
||||
|
||||
if (!initialization)
|
||||
vt82c686_hwm_write(0x85, 0x00, dev);
|
||||
vt82c686_hwm_write(0x74, 0x00, dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,18 +165,18 @@ vt82c686_init(const device_t *info)
|
||||
the values struct contains voltage values *before* applying their respective factors. */
|
||||
hwm_values_t defaults = {
|
||||
{ /* fan speeds */
|
||||
3000, /* CPU */
|
||||
3000 /* Chassis */
|
||||
3000, /* usually CPU */
|
||||
3000 /* usually Chassis */
|
||||
}, { /* temperatures */
|
||||
30, /* CPU */
|
||||
30, /* System */
|
||||
0 /* unused */
|
||||
30, /* usually CPU */
|
||||
30, /* usually System */
|
||||
30
|
||||
}, { /* voltages */
|
||||
hwm_get_vcore(), /* Vcore */
|
||||
2500, /* 2.5V */
|
||||
3300, /* 3.3V */
|
||||
5000, /* 5V */
|
||||
12000 /* 12V */
|
||||
2500, /* +2.5V */
|
||||
3300, /* +3.3V */
|
||||
5000, /* +5V */
|
||||
12000 /* +12V */
|
||||
}
|
||||
};
|
||||
hwm_values = defaults;
|
||||
|
@@ -25,7 +25,7 @@
|
||||
typedef struct {
|
||||
uint16_t fans[4];
|
||||
uint8_t temperatures[4];
|
||||
uint16_t voltages[9];
|
||||
uint16_t voltages[10];
|
||||
} hwm_values_t;
|
||||
|
||||
typedef struct {
|
||||
|
@@ -135,7 +135,10 @@ machine_at_ficva503a_init(const machine_t *model)
|
||||
device_add(&via_vt82c686_sio_device);
|
||||
device_add(&sst_flash_39sf020_device);
|
||||
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
|
||||
device_add(&via_vt82c686_hwm_device);
|
||||
device_add(&via_vt82c686_hwm_device); /* fans: CPU1, Chassis; temperatures: CPU, System, unused */
|
||||
hwm_values.temperatures[0] += 2; /* CPU offset */
|
||||
hwm_values.temperatures[1] += 2; /* System offset */
|
||||
hwm_values.temperatures[2] = 0; /* unused */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user