Merge branch 'master' of https://github.com/86Box/86Box.git into EngiNerd
This commit is contained in:
@@ -78,7 +78,7 @@ typedef struct {
|
||||
} hw_select;
|
||||
|
||||
uint8_t frequencies_ref; /* which other model to use the frequency table from (or 0) */
|
||||
ics9xxx_frequency_t *frequencies; /* frequency table, if not using another model's table */
|
||||
const ics9xxx_frequency_t *frequencies; /* frequency table, if not using another model's table */
|
||||
} ics9xxx_model_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -105,7 +105,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x00, 0xff, 0xff, 0xff, 0x6f, 0xbf},
|
||||
.fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 5000, .pci_div = 2},
|
||||
{.bus = 7500, .pci_div = 2},
|
||||
{.bus = 8333, .pci_div = 2},
|
||||
@@ -117,7 +117,6 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
{0}
|
||||
}
|
||||
ICS9xxx_MODEL_END()
|
||||
#if 0
|
||||
ICS9xxx_MODEL(ICS9248_39)
|
||||
.max_reg = 5,
|
||||
.regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff},
|
||||
@@ -125,12 +124,13 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.hw_select = {0, 3},
|
||||
.frequencies_ref = ICS9250_08
|
||||
ICS9xxx_MODEL_END()
|
||||
#if 0
|
||||
ICS9xxx_MODEL(ICS9248_81)
|
||||
.max_reg = 5,
|
||||
.regs = {0x82, 0xfe, 0x7f, 0xff, 0xff, 0xb7},
|
||||
.fs_regs = {{0, 4, 1, 0}, {0, 5, 2, 7}, {0, 6, 5, 6}, {0, 2, 5, 3}, {-1, -1, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 9000, .ram_mult = 1, .pci_div = 3},
|
||||
{.bus = 6670, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 9500, .ram_mult = 2.0/3.0, .pci_div = 3},
|
||||
@@ -155,7 +155,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x82, 0xff, 0xff, 0xff, 0xd5, 0xff},
|
||||
.fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6667, .pci_div = 2},
|
||||
{.bus = 10000, .pci_div = 3},
|
||||
{.bus = 10030, .pci_div = 3},
|
||||
@@ -180,7 +180,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x00, 0x7f, 0xff, 0xbf, 0xf5, 0xff, 0x06},
|
||||
.fs_regs = {{0, 4, 3, 6}, {0, 5, 4, 3}, {0, 6, 1, 7}, {0, 7, 4, 1}, {0, 2, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 8000, .pci_div = 2},
|
||||
{.bus = 7500, .pci_div = 2},
|
||||
{.bus = 8331, .pci_div = 2},
|
||||
@@ -221,7 +221,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x82, 0xff, 0xff, 0xff, 0xf5, 0xff},
|
||||
.fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 12400, .pci_div = 3},
|
||||
{.bus = 12000, .pci_div = 3},
|
||||
{.bus = 11499, .pci_div = 3},
|
||||
@@ -253,7 +253,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0xff, 0xff, 0xec, 0xde, 0xff, 0x06},
|
||||
.fs_regs = {{0, 4, 4, 5}, {0, 5, 3, 4}, {0, 6, 3, 0}, {0, 7, 3, 1}, {0, 2, 4, 0}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 10300, .pci_div = 3},
|
||||
{.bus = 10000, .pci_div = 3},
|
||||
{.bus = 10045, .pci_div = 3},
|
||||
@@ -294,7 +294,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x1f, 0xff, 0xff, 0xfb, 0xff, 0x06},
|
||||
.fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6680, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 6800, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 10030, .ram_mult = 1, .pci_div = 3},
|
||||
@@ -335,7 +335,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x3f, 0x7f, 0x6f, 0xff, 0xff, 0x06},
|
||||
.fs_regs = {{0, 4, 2, 7}, {0, 5, 1, 6}, {0, 6, 1, 7}, {0, 7, 3, 4}, {0, 2, 3, 7}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6667, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 6687, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 6867, .ram_mult = 1.5, .pci_div = 2},
|
||||
@@ -376,7 +376,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x6b, 0x7f, 0xff, 0xff, 0xe7, 0x06},
|
||||
.fs_regs = {{0, 4, 2, 7}, {0, 5, 5, 3}, {0, 6, 1, 7}, {0, 7, 1, 4}, {0, 2, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 9000, .pci_div = 3},
|
||||
{.bus = 9500, .pci_div = 2},
|
||||
{.bus = 10100, .pci_div = 2},
|
||||
@@ -416,7 +416,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.max_reg = 5,
|
||||
.regs = {0x82, 0xff, 0xff, 0xff, 0xd5, 0xff},
|
||||
.fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 2, 4, 1}, {-1, -1, -1, -1}},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6667, .pci_div = 2},
|
||||
{.bus = 10000, .pci_div = 3},
|
||||
{.bus = 10030, .pci_div = 3},
|
||||
@@ -441,7 +441,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x80, 0x4f, 0xff, 0x3f, 0xff, 0xff, 0x06},
|
||||
.fs_regs = {{0, 4, -1, -1}, {0, 5, -1, -1}, {0, 6, 3, 7}, {0, 1, 1, 4}, {0, 2, 1, 5}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 20000, .pci_div = 5, .agp_div = 2.5},
|
||||
{.bus = 19000, .pci_div = 5, .agp_div = 2.5},
|
||||
{.bus = 18000, .pci_div = 5, .agp_div = 2.5},
|
||||
@@ -482,7 +482,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
.fs_regs = {{0, 4, -1, -1}, {0, 5, 4, 3}, {0, 6, -1, -1}, {0, 7, -1, -1}, {0, 2, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6000, .pci_div = 2},
|
||||
{.bus = 6000, .pci_div = 2},
|
||||
{.bus = 6000, .pci_div = 2},
|
||||
@@ -524,7 +524,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x00, 0xff, 0xff, 0xff, 0x6d, 0xbf},
|
||||
.fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 12400, .pci_div = 3},
|
||||
{.bus = 7500, .pci_div = 2},
|
||||
{.bus = 8333, .pci_div = 2},
|
||||
@@ -550,7 +550,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x1f, 0xff, 0xfe, 0x00, 0x00, 0x06},
|
||||
.fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {5, 4, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {-1, -1},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6667, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7067, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7466, .ram_mult = 1.5, .pci_div = 2},
|
||||
@@ -575,7 +575,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x82, 0xcf, 0x7f, 0xff, 0xff, 0xf7},
|
||||
.fs_regs = {{0, 4, 1, 4}, {0, 5, 5, 7}, {0, 6, 1, 5}, {0, 2, 2, 7}, {-1, -1, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 9000, .ram_mult = 1, .pci_div = 2},
|
||||
{.bus = 8901, .ram_mult = 1, .pci_div = 2},
|
||||
{.bus = 8800, .ram_mult = 1, .pci_div = 2},
|
||||
@@ -600,7 +600,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff},
|
||||
.fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6781, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7000, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7201, .ram_mult = 1.5, .pci_div = 2},
|
||||
@@ -641,7 +641,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x1f, 0xff, 0xff, 0x00, 0x00, 0x06},
|
||||
.fs_regs = {{5, 0, -1, -1}, {5, 3, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {-1, -1},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6667, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7000, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7267, .ram_mult = 1.5, .pci_div = 2},
|
||||
@@ -667,7 +667,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0xff, 0xff, 0xff, 0x6d, 0xbf},
|
||||
.fs_regs = {{0, 4, 4, 7}, {0, 5, 4, 4}, {0, 6, 5, 6}, {0, 7, 4, 1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 8000, .pci_div = 2},
|
||||
{.bus = 7500, .pci_div = 2},
|
||||
{.bus = 8331, .pci_div = 2},
|
||||
@@ -716,7 +716,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff},
|
||||
.fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6900, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7000, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 7100, .ram_mult = 1.5, .pci_div = 2},
|
||||
@@ -757,7 +757,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x1f, 0xff, 0xff, 0xeb, 0xff, 0x06},
|
||||
.fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 5500, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 6000, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 6680, .ram_mult = 1.5, .pci_div = 2},
|
||||
@@ -805,7 +805,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00},
|
||||
.fs_regs = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {3, 0, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}},
|
||||
.hw_select = {-1, -1},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6666, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 13332, .ram_mult = 1, .pci_div = 4},
|
||||
{.bus = 10000, .ram_mult = 1, .pci_div = 3},
|
||||
@@ -836,7 +836,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x0f, 0xff, 0xff, 0xeb, 0xff, 0x06},
|
||||
.fs_regs = {{0, 4, 1, 6}, {0, 5, 4, 2}, {0, 6, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6667, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 6000, .ram_mult = 1.5, .pci_div = 2},
|
||||
{.bus = 6680, .ram_mult = 1.5, .pci_div = 2},
|
||||
@@ -882,7 +882,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x18, 0x07, 0xfe, 0xc7, 0xfc, 0x00, 0x80},
|
||||
.fs_regs = {{0, 0, -1, -1}, {0, 1, -1, -1}, {0, 2, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}},
|
||||
.normal_bits_fixed = 1,
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
{.bus = 6666, .ram_mult = 1, .pci_div = 1},
|
||||
{.bus = 10000, .ram_mult = 2.0/3.0, .pci_div = 3},
|
||||
{.bus = 20000, .ram_mult = 1.0/3.0, .pci_div = 6},
|
||||
@@ -899,7 +899,7 @@ static const ics9xxx_model_t ics9xxx_models[] = {
|
||||
.regs = {0x02, 0x6f, 0xff, 0xff, 0xef, 0xff, 0x06},
|
||||
.fs_regs = {{-1, -1, 1, 6}, {-1, -1, 4, 2}, {-1, -1, 1, 5}, {0, 7, 1, 7}, {0, 2, 4, 4}},
|
||||
.hw_select = {0, 3},
|
||||
.frequencies = (ics9xxx_frequency_t[]) {
|
||||
.frequencies = (const ics9xxx_frequency_t[]) {
|
||||
[0 ... 7] = {.bus = 6667, .ram_mult = 1.5, .pci_div = 2},
|
||||
[8 ... 15] = {.bus = 10000, .ram_mult = 1, .pci_div = 3},
|
||||
[16 ... 23] = {.bus = 13333, .ram_mult = 1, .pci_div = 4},
|
||||
|
||||
@@ -39,9 +39,9 @@ typedef struct {
|
||||
hwm_values_t *values;
|
||||
|
||||
uint16_t regs[32];
|
||||
uint8_t addr_register;
|
||||
uint8_t addr_register: 5;
|
||||
|
||||
uint8_t i2c_addr, i2c_state;
|
||||
uint8_t i2c_addr: 7, i2c_state: 2;
|
||||
} gl518sm_t;
|
||||
|
||||
|
||||
|
||||
@@ -30,12 +30,6 @@
|
||||
#define LM75_TEMP_TO_REG(t) ((t) << 8)
|
||||
|
||||
|
||||
static uint8_t lm75_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv);
|
||||
static uint8_t lm75_i2c_read(void *bus, uint8_t addr, void *priv);
|
||||
static uint8_t lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv);
|
||||
static void lm75_reset(lm75_t *dev);
|
||||
|
||||
|
||||
#ifdef ENABLE_LM75_LOG
|
||||
int lm75_do_log = ENABLE_LM75_LOG;
|
||||
|
||||
@@ -56,21 +50,6 @@ lm75_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
lm75_remap(lm75_t *dev, uint8_t addr)
|
||||
{
|
||||
lm75_log("LM75: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
if (dev->i2c_addr < 0x80)
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev);
|
||||
|
||||
if (addr < 0x80)
|
||||
i2c_sethandler(i2c_smbus, addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev);
|
||||
|
||||
dev->i2c_addr = addr;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm75_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv)
|
||||
{
|
||||
@@ -82,49 +61,6 @@ lm75_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm75_i2c_read(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
lm75_t *dev = (lm75_t *) priv;
|
||||
uint8_t ret = 0;
|
||||
|
||||
if (dev->i2c_state == 0)
|
||||
dev->i2c_state = 1;
|
||||
|
||||
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal I2C call, if necessary. */
|
||||
if ((dev->addr_register > 0x7) && ((dev->addr_register & 0xf8) != 0x50) && (dev->as99127f_i2c_addr < 0x80)) {
|
||||
i2c_start(i2c_smbus, dev->as99127f_i2c_addr, 1);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, dev->addr_register);
|
||||
ret = i2c_read(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
i2c_stop(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
} else {
|
||||
switch (dev->addr_register & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x0 : 0x1);
|
||||
break;
|
||||
|
||||
case 0x1: /* configuration */
|
||||
ret = lm75_read(dev, 0x2);
|
||||
break;
|
||||
|
||||
case 0x2: /* Thyst */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x3 : 0x4);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x5 : 0x6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (++dev->i2c_state > 2)
|
||||
dev->i2c_state = 2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
lm75_read(lm75_t *dev, uint8_t reg)
|
||||
{
|
||||
@@ -143,6 +79,62 @@ lm75_read(lm75_t *dev, uint8_t reg)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm75_i2c_read(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
lm75_t *dev = (lm75_t *) priv;
|
||||
uint8_t ret = 0;
|
||||
|
||||
if (dev->i2c_state == 0)
|
||||
dev->i2c_state = 1;
|
||||
|
||||
/* The AS99127F hardware monitor uses its primary LM75 device's
|
||||
address to access some of its proprietary registers. Pass this
|
||||
operation on to the main monitor code, if necessary. */
|
||||
if ((dev->addr_register & 0x80) && dev->as99127f) {
|
||||
ret = lm78_as99127f_read(dev->as99127f, dev->addr_register);
|
||||
} else {
|
||||
switch (dev->addr_register & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x0 : 0x1);
|
||||
break;
|
||||
|
||||
case 0x1: /* configuration */
|
||||
ret = lm75_read(dev, 0x2);
|
||||
break;
|
||||
|
||||
case 0x2: /* Thyst */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x3 : 0x4);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x5 : 0x6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->i2c_state < 2)
|
||||
dev->i2c_state++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
lm75_write(lm75_t *dev, uint8_t reg, uint8_t val)
|
||||
{
|
||||
lm75_log("LM75: write(%02X, %02X)\n", reg, val);
|
||||
|
||||
uint8_t reg_idx = (reg & 0x7);
|
||||
|
||||
if ((reg_idx <= 0x1) || (reg_idx == 0x7))
|
||||
return 0; /* read-only registers */
|
||||
|
||||
dev->regs[reg_idx] = val;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
{
|
||||
@@ -151,22 +143,18 @@ lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
if ((dev->i2c_state > 2) || ((dev->i2c_state == 2) && ((dev->addr_register & 0x3) == 0x1))) {
|
||||
return 0;
|
||||
} else if (dev->i2c_state == 0) {
|
||||
dev->i2c_state = 1;
|
||||
/* Linux lm75.c driver relies on the address register not changing if bit 2 is set. */
|
||||
if ((dev->as99127f_i2c_addr < 0x80) || !(data & 0x04))
|
||||
dev->i2c_state = 1;
|
||||
/* Linux lm75.c driver relies on the address register not changing if bit 2 is set. */
|
||||
if (((dev->addr_register & 0x80) && dev->as99127f) || !(data & 0x04))
|
||||
dev->addr_register = data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal I2C call, if necessary. */
|
||||
if ((dev->addr_register > 0x7) && ((dev->addr_register & 0xf8) != 0x50) && (dev->as99127f_i2c_addr < 0x80)) {
|
||||
i2c_start(i2c_smbus, dev->as99127f_i2c_addr, 0);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, dev->addr_register);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, data);
|
||||
i2c_stop(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
return 1;
|
||||
/* The AS99127F hardware monitor uses its primary LM75 device's
|
||||
address to access some of its proprietary registers. Pass this
|
||||
operation on to the main monitor code, if necessary. */
|
||||
if ((dev->addr_register & 0x80) && dev->as99127f) {
|
||||
return lm78_as99127f_write(dev->as99127f, dev->addr_register, data);
|
||||
} else {
|
||||
switch (dev->addr_register & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
@@ -188,25 +176,24 @@ lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
}
|
||||
|
||||
if (dev->i2c_state == 1)
|
||||
dev->i2c_state = 2;
|
||||
dev->i2c_state = 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
lm75_write(lm75_t *dev, uint8_t reg, uint8_t val)
|
||||
void
|
||||
lm75_remap(lm75_t *dev, uint8_t addr)
|
||||
{
|
||||
lm75_log("LM75: write(%02X, %02X)\n", reg, val);
|
||||
lm75_log("LM75: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
uint8_t reg_idx = (reg & 0x7);
|
||||
if (dev->i2c_addr < 0x80)
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev);
|
||||
|
||||
if ((reg_idx <= 0x1) || (reg_idx == 0x7))
|
||||
return 0; /* read-only registers */
|
||||
if (addr < 0x80)
|
||||
i2c_sethandler(i2c_smbus, addr, 1, lm75_i2c_start, lm75_i2c_read, lm75_i2c_write, NULL, dev);
|
||||
|
||||
dev->regs[reg_idx] = val;
|
||||
|
||||
return 1;
|
||||
dev->i2c_addr = addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -244,8 +231,6 @@ lm75_init(const device_t *info)
|
||||
hwm_values.temperatures[dev->local >> 8] = 30;
|
||||
dev->values = &hwm_values;
|
||||
|
||||
dev->as99127f_i2c_addr = 0x80;
|
||||
|
||||
lm75_reset(dev);
|
||||
|
||||
return dev;
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/nvr.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/i2c.h>
|
||||
#include <86box/hwm.h>
|
||||
@@ -48,28 +50,33 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t local;
|
||||
hwm_values_t *values;
|
||||
device_t *lm75[2];
|
||||
pc_timer_t hard_reset_timer;
|
||||
uint32_t local;
|
||||
hwm_values_t *values;
|
||||
device_t *lm75[2];
|
||||
pc_timer_t reset_timer;
|
||||
|
||||
uint8_t regs[256];
|
||||
uint8_t regs_782d[2][16];
|
||||
uint8_t addr_register;
|
||||
uint8_t data_register;
|
||||
uint8_t regs[256];
|
||||
union {
|
||||
struct {
|
||||
uint8_t regs[2][16];
|
||||
} w83782d;
|
||||
struct {
|
||||
uint8_t regs[3][128];
|
||||
|
||||
uint8_t i2c_addr, i2c_state;
|
||||
uint8_t nvram[1024], nvram_i2c_state: 2, nvram_updated: 1;
|
||||
uint16_t nvram_addr_register: 10;
|
||||
int8_t nvram_block_len: 6;
|
||||
|
||||
uint8_t security_i2c_state: 1, security_addr_register: 7;
|
||||
} as99127f;
|
||||
};
|
||||
uint8_t addr_register, data_register;
|
||||
|
||||
uint8_t i2c_addr: 7, i2c_state: 1;
|
||||
} lm78_t;
|
||||
|
||||
|
||||
static uint8_t lm78_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv);
|
||||
static uint8_t lm78_isa_read(uint16_t port, void *priv);
|
||||
static uint8_t lm78_i2c_read(void *bus, uint8_t addr, void *priv);
|
||||
static uint8_t lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank);
|
||||
static void lm78_isa_write(uint16_t port, uint8_t val, void *priv);
|
||||
static uint8_t lm78_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv);
|
||||
static uint8_t lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank);
|
||||
static void lm78_reset(lm78_t *dev, uint8_t initialization);
|
||||
static void lm78_remap(lm78_t *dev, uint8_t addr);
|
||||
|
||||
|
||||
#ifdef ENABLE_LM78_LOG
|
||||
@@ -92,31 +99,223 @@ lm78_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
lm78_remap(lm78_t *dev, uint8_t addr)
|
||||
void
|
||||
lm78_nvram(lm78_t *dev, uint8_t save)
|
||||
{
|
||||
lm75_t *lm75;
|
||||
size_t l = strlen(machine_get_internal_name_ex(machine)) + 1;
|
||||
wchar_t *machine_name = (wchar_t *) malloc(l * sizeof(wchar_t));
|
||||
mbstowcs(machine_name, machine_get_internal_name_ex(machine), l);
|
||||
l = wcslen(machine_name) + 14;
|
||||
wchar_t *nvr_path = (wchar_t *) malloc(l * sizeof(wchar_t));
|
||||
swprintf(nvr_path, l, L"%ls_as99127f.nvr", machine_name);
|
||||
|
||||
if (!(dev->local & LM78_I2C)) return;
|
||||
|
||||
lm78_log("LM78: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev);
|
||||
|
||||
if (addr < 0x80)
|
||||
i2c_sethandler(i2c_smbus, addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev);
|
||||
|
||||
dev->i2c_addr = addr;
|
||||
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* Store the main I2C address on the LM75 devices to ensure reads/writes
|
||||
to the AS99127F's proprietary registers are passed through to this side. */
|
||||
for (uint8_t i = 0; i <= 1; i++) {
|
||||
lm75 = device_get_priv(dev->lm75[i]);
|
||||
if (lm75)
|
||||
lm75->as99127f_i2c_addr = dev->i2c_addr;
|
||||
}
|
||||
FILE *f = nvr_fopen(nvr_path, save ? L"wb": L"rb");
|
||||
if (f) {
|
||||
if (save)
|
||||
fwrite(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, f);
|
||||
else
|
||||
fread(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
free(machine_name);
|
||||
free(nvr_path);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_nvram_start(void *bus, uint8_t addr, uint8_t read, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
dev->as99127f.nvram_i2c_state = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_nvram_read(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (dev->as99127f.nvram_i2c_state) {
|
||||
case 0:
|
||||
dev->as99127f.nvram_i2c_state = 1;
|
||||
/* fall-through */
|
||||
|
||||
case 1:
|
||||
ret = dev->as99127f.regs[0][0x0b] & 0x3f;
|
||||
lm78_log("LM78: nvram_read(blocklen) = %02X\n", ret);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ret = dev->as99127f.nvram[dev->as99127f.nvram_addr_register];
|
||||
lm78_log("LM78: nvram_read(%03X) = %02X\n", dev->as99127f.nvram_addr_register, ret);
|
||||
|
||||
dev->as99127f.nvram_addr_register++;
|
||||
break;
|
||||
|
||||
default:
|
||||
lm78_log("LM78: nvram_read(unknown) = %02X\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->as99127f.nvram_i2c_state < 2)
|
||||
dev->as99127f.nvram_i2c_state++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_nvram_write(void *bus, uint8_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
switch (dev->as99127f.nvram_i2c_state) {
|
||||
case 0:
|
||||
lm78_log("LM78: nvram_write(address, %02X)\n", val);
|
||||
dev->as99127f.nvram_addr_register = (addr << 8) | val;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
lm78_log("LM78: nvram_write(blocklen, %02X)\n", val);
|
||||
dev->as99127f.nvram_block_len = val & 0x3f;
|
||||
if (dev->as99127f.nvram_block_len <= 0)
|
||||
dev->as99127f.nvram_i2c_state = 3;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
lm78_log("LM78: nvram_write(%03X, %02X)\n", dev->as99127f.nvram_addr_register, val);
|
||||
dev->as99127f.nvram[dev->as99127f.nvram_addr_register++] = val;
|
||||
dev->as99127f.nvram_updated = 1;
|
||||
if (--dev->as99127f.nvram_block_len <= 0)
|
||||
dev->as99127f.nvram_i2c_state = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
lm78_log("LM78: nvram_write(unknown, %02X)\n", val);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->as99127f.nvram_i2c_state < 2)
|
||||
dev->as99127f.nvram_i2c_state++;
|
||||
|
||||
return dev->as99127f.nvram_i2c_state < 3;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_security_start(void *bus, uint8_t addr, uint8_t read, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
dev->as99127f.security_i2c_state = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_security_read(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
return dev->as99127f.regs[2][dev->as99127f.security_addr_register++];
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_security_write(void *bus, uint8_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
if (dev->as99127f.security_i2c_state == 0) {
|
||||
dev->as99127f.security_i2c_state = 1;
|
||||
dev->as99127f.security_addr_register = val;
|
||||
} else {
|
||||
switch (dev->as99127f.security_addr_register) {
|
||||
case 0xe0: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
/* read-only registers */
|
||||
return 1;
|
||||
}
|
||||
|
||||
dev->as99127f.regs[2][dev->as99127f.security_addr_register++] = val;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lm78_reset(lm78_t *dev, uint8_t initialization)
|
||||
{
|
||||
memset(dev->regs, 0, 256);
|
||||
memset(dev->regs + 0xc0, 0xff, 32); /* C0-DF are 0xFF on a real AS99127F */
|
||||
|
||||
dev->regs[0x40] = 0x08;
|
||||
dev->regs[0x46] = 0x40;
|
||||
dev->regs[0x47] = 0x50;
|
||||
if (dev->local & LM78_I2C) {
|
||||
if (!initialization) /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */
|
||||
dev->i2c_addr = 0x2d;
|
||||
dev->regs[0x48] = dev->i2c_addr;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x01;
|
||||
} else {
|
||||
dev->regs[0x48] = 0x00;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x88;
|
||||
}
|
||||
if (dev->local & LM78_WINBOND) {
|
||||
dev->regs[0x49] = 0x02;
|
||||
dev->regs[0x4b] = 0x44;
|
||||
dev->regs[0x4c] = 0x01;
|
||||
dev->regs[0x4d] = 0x15;
|
||||
dev->regs[0x4e] = 0x80;
|
||||
dev->regs[0x4f] = LM78_WINBOND_VENDOR_ID >> 8;
|
||||
dev->regs[0x57] = 0x80;
|
||||
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
dev->regs[0x49] = 0x20;
|
||||
dev->regs[0x4c] = 0x00;
|
||||
dev->regs[0x56] = 0xff;
|
||||
dev->regs[0x57] = 0xff;
|
||||
dev->regs[0x58] = 0x31;
|
||||
dev->regs[0x59] = 0x8f;
|
||||
dev->regs[0x5a] = 0x8f;
|
||||
dev->regs[0x5b] = 0x2a;
|
||||
dev->regs[0x5c] = 0xe0;
|
||||
dev->regs[0x5d] = 0x48;
|
||||
dev->regs[0x5e] = 0xe2;
|
||||
dev->regs[0x5f] = 0x1f;
|
||||
|
||||
dev->as99127f.regs[0][0x02] = 0xff;
|
||||
dev->as99127f.regs[0][0x03] = 0xff;
|
||||
dev->as99127f.regs[0][0x08] = 0xff;
|
||||
dev->as99127f.regs[0][0x09] = 0xff;
|
||||
dev->as99127f.regs[0][0x0b] = 0x01;
|
||||
|
||||
/* regs[1] and regs[2] start at 0x80 */
|
||||
dev->as99127f.regs[1][0x00] = 0x88;
|
||||
dev->as99127f.regs[1][0x01] = 0x10;
|
||||
dev->as99127f.regs[1][0x04] = 0x01;
|
||||
dev->as99127f.regs[1][0x05] = 0x1f;
|
||||
lm78_as99127f_write(dev, 0x06, 0x2f);
|
||||
|
||||
dev->as99127f.regs[2][0x60] = 0xf0;
|
||||
} else if (dev->local & LM78_W83781D) {
|
||||
dev->regs[0x58] = 0x10;
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
dev->regs[0x58] = 0x30;
|
||||
}
|
||||
} else {
|
||||
dev->regs[0x49] = 0x40;
|
||||
}
|
||||
|
||||
lm78_remap(dev, dev->i2c_addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,6 +330,53 @@ lm78_i2c_start(void *bus, uint8_t addr, uint8_t read, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank)
|
||||
{
|
||||
uint8_t ret = 0, masked_reg = reg, bankswitched = ((reg & 0xf8) == 0x50);
|
||||
lm75_t *lm75;
|
||||
|
||||
if ((dev->local & LM78_AS99127F) && (bank == 3) && (reg != 0x4e)) {
|
||||
/* AS99127F additional registers */
|
||||
if (!((dev->local & LM78_AS99127F_REV2) && ((reg == 0x80) || (reg == 0x81))))
|
||||
ret = dev->as99127f.regs[0][reg & 0x7f];
|
||||
} else 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 (bankswitched && ((bank == 4) || (bank == 5) || (bank == 6))) {
|
||||
/* W83782D additional registers */
|
||||
if (dev->local & LM78_W83782D) {
|
||||
if ((bank == 5) && ((reg == 0x50) || (reg == 0x51))) /* voltages */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[7 + (reg & 1)]);
|
||||
else if (bank < 6)
|
||||
ret = dev->w83782d.regs[bank - 4][reg & 0x0f];
|
||||
}
|
||||
} else {
|
||||
/* regular registers */
|
||||
if ((reg >= 0x60) && (reg <= 0x94)) /* read auto-increment value RAM registers from their non-auto-increment locations */
|
||||
masked_reg = reg & 0x3f;
|
||||
if ((masked_reg >= 0x20) && (masked_reg <= 0x26)) /* voltages */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[reg & 7]);
|
||||
else if ((dev->local & LM78_AS99127F) && (masked_reg <= 0x05)) /* AS99127F additional voltages */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[7 + masked_reg]);
|
||||
else if (masked_reg == 0x27) /* temperature */
|
||||
ret = dev->values->temperatures[0];
|
||||
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->regs[0x4e] & 0x80) ? (LM78_WINBOND_VENDOR_ID >> 8) : LM78_WINBOND_VENDOR_ID;
|
||||
else
|
||||
ret = dev->regs[masked_reg];
|
||||
}
|
||||
|
||||
lm78_log("LM78: read(%02X, %d) = %02X\n", reg, bank, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_isa_read(uint16_t port, void *priv)
|
||||
{
|
||||
@@ -139,7 +385,7 @@ lm78_isa_read(uint16_t port, void *priv)
|
||||
|
||||
switch (port & 0x7) {
|
||||
case 0x5:
|
||||
ret = (dev->addr_register & 0x7f);
|
||||
ret = dev->addr_register & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
@@ -147,7 +393,7 @@ lm78_isa_read(uint16_t port, void *priv)
|
||||
|
||||
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->addr_register >= 0x60) && (dev->addr_register < 0x94)))) ||
|
||||
((dev->local & LM78_W83782D) && (LM78_WINBOND_BANK == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
@@ -172,103 +418,18 @@ lm78_i2c_read(void *bus, uint8_t addr, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_read(lm78_t *dev, uint8_t reg, uint8_t bank)
|
||||
uint8_t
|
||||
lm78_as99127f_read(void *priv, uint8_t reg)
|
||||
{
|
||||
uint8_t ret = 0, masked_reg = reg, bankswitched = ((reg & 0xf8) == 0x50);
|
||||
lm75_t *lm75;
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
uint8_t ret = dev->as99127f.regs[1][reg & 0x7f];
|
||||
|
||||
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 (bankswitched && ((bank == 4) || (bank == 5) || (bank == 6))) {
|
||||
/* W83782D additional registers */
|
||||
if (dev->local & LM78_W83782D) {
|
||||
if ((bank == 5) && ((reg == 0x50) || (reg == 0x51))) /* voltages */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[7 + (reg & 1)]);
|
||||
else if (bank < 6)
|
||||
ret = dev->regs_782d[bank - 4][reg & 0x0f];
|
||||
}
|
||||
} else {
|
||||
/* regular registers */
|
||||
ret = dev->regs[reg];
|
||||
if (reg >= 0x40)
|
||||
masked_reg = reg & 0x3f; /* match both non-auto-increment and auto-increment locations */
|
||||
if ((masked_reg >= 0x20) && (masked_reg <= 0x26)) /* voltages */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[reg & 7]);
|
||||
else if (masked_reg == 0x27) /* temperature */
|
||||
ret = dev->values->temperatures[0];
|
||||
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->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 */
|
||||
masked_reg = reg & 0x7f;
|
||||
if (masked_reg == 0x00) /* IN2 Low Limit */
|
||||
ret = dev->regs[0x30];
|
||||
else if ((masked_reg == 0x01) || (masked_reg == 0x04)) /* IN3 */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[3]);
|
||||
else if (masked_reg == 0x05) /* IN2 */
|
||||
ret = LM78_VOLTAGE_TO_REG(dev->values->voltages[2]);
|
||||
else if (masked_reg == 0x08) /* IN3 Low Limit */
|
||||
ret = dev->regs[0x32];
|
||||
else if ((reg >= 0x80) && (reg <= 0x92)) /* mirror [0x00:0x12] to [0x80:0x92] */
|
||||
ret = dev->regs[masked_reg];
|
||||
}
|
||||
}
|
||||
|
||||
lm78_log("LM78: read(%02X, %d) = %02X\n", reg, bank, ret);
|
||||
lm78_log("LM78: read(%02X, AS99127F) = %02X\n", reg, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lm78_isa_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
switch (port & 0x7) {
|
||||
case 0x5:
|
||||
dev->addr_register = (val & 0x7f);
|
||||
break;
|
||||
case 0x6:
|
||||
lm78_write(dev, dev->addr_register, val, 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) && (LM78_WINBOND_BANK == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_i2c_write(void *bus, uint8_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
if (dev->i2c_state == 0) {
|
||||
dev->i2c_state = 1;
|
||||
dev->addr_register = val;
|
||||
} else
|
||||
lm78_write(dev, dev->addr_register++, val, LM78_WINBOND_BANK);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
{
|
||||
@@ -276,12 +437,27 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
|
||||
lm78_log("LM78: write(%02X, %d, %02X)\n", reg, bank, val);
|
||||
|
||||
if ((reg & 0xf8) == 0x50) {
|
||||
if ((dev->local & LM78_AS99127F) && (bank == 3) && (reg != 0x4e)) {
|
||||
/* AS99127F additional registers */
|
||||
reg &= 0x7f;
|
||||
switch (reg) {
|
||||
case 0x00: case 0x01: case 0x04: case 0x05: case 0x06: case 0x07:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
|
||||
case 0x20:
|
||||
val &= 0x7f;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->as99127f.regs[0][reg] = val;
|
||||
return 1;
|
||||
} else if ((reg & 0xf8) == 0x50) {
|
||||
if ((bank == 1) || (bank == 2)) {
|
||||
/* LM75 registers */
|
||||
lm75 = device_get_priv(dev->lm75[bank - 1]);
|
||||
if (lm75)
|
||||
lm75_write(lm75, reg, val);
|
||||
return lm75_write(lm75, reg, val);
|
||||
return 1;
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
/* W83782D additional registers */
|
||||
@@ -293,7 +469,7 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->regs_782d[0][reg & 0x0f] = val;
|
||||
dev->w83782d.regs[0][reg & 0x0f] = val;
|
||||
return 1;
|
||||
} else if (bank == 5) {
|
||||
switch (reg) {
|
||||
@@ -303,19 +479,21 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->regs_782d[1][reg & 0x0f] = val;
|
||||
dev->w83782d.regs[1][reg & 0x0f] = val;
|
||||
return 1;
|
||||
} else if (bank == 6) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* regular registers */
|
||||
switch (reg) {
|
||||
case 0x41: case 0x42: case 0x4f: case 0x58:
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a:
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a:
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
|
||||
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85:
|
||||
/* read-only registers */
|
||||
return 0;
|
||||
|
||||
@@ -326,12 +504,10 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((reg >= 0x60) && (reg <= 0x7f)) /* write auto-increment value RAM registers to their non-auto-increment locations */
|
||||
dev->regs[reg & 0x3f] = val;
|
||||
else if ((reg >= 0x80) && (reg <= 0x92)) /* AS99127F mirrors [0x00:0x12] to [0x80:0x92] */
|
||||
dev->regs[reg & 0x7f] = val;
|
||||
else
|
||||
dev->regs[reg] = val;
|
||||
if ((reg >= 0x60) && (reg <= 0x94)) /* write auto-increment value RAM registers to their non-auto-increment locations */
|
||||
reg &= 0x3f;
|
||||
uint8_t prev = dev->regs[reg];
|
||||
dev->regs[reg] = val;
|
||||
|
||||
switch (reg) {
|
||||
case 0x40:
|
||||
@@ -363,26 +539,107 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
lm75 = device_get_priv(dev->lm75[i]);
|
||||
if (!lm75)
|
||||
continue;
|
||||
if (dev->regs[0x4a] & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */
|
||||
if (val & (0x08 * (0x10 * i))) /* DIS_T2 and DIS_T3 bit disable those interfaces */
|
||||
lm75_remap(lm75, 0x80);
|
||||
else
|
||||
lm75_remap(lm75, 0x48 + ((dev->regs[0x4a] >> (i * 4)) & 0x7));
|
||||
lm75_remap(lm75, 0x48 + ((val >> (i * 4)) & 0x7));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
/* CUV4X-LS performs a hard reset through this register. */
|
||||
if ((dev->local & LM78_AS99127F) && (val == 0xa9)) {
|
||||
lm78_log("LM78: Hard reset requested through AS99127F\n");
|
||||
timer_set_delay_u64(&dev->hard_reset_timer, 1); /* hard reset on a timer to avoid issues caused by invalidation of the I2C bus */
|
||||
case 0x5c:
|
||||
/* enable/disable AS99127F NVRAM */
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
if (prev & 0x01)
|
||||
i2c_removehandler(i2c_smbus, (prev & 0xf8) >> 1, 4, lm78_nvram_start, lm78_nvram_read, lm78_nvram_write, NULL, dev);
|
||||
if (val & 0x01)
|
||||
i2c_sethandler(i2c_smbus, (val & 0xf8) >> 1, 4, lm78_nvram_start, lm78_nvram_read, lm78_nvram_write, NULL, dev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lm78_isa_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
switch (port & 0x7) {
|
||||
case 0x5:
|
||||
dev->addr_register = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
lm78_write(dev, dev->addr_register, val, 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 < 0x94)))) ||
|
||||
((dev->local & LM78_W83782D) && (LM78_WINBOND_BANK == 5) && (dev->addr_register >= 0x50) && (dev->addr_register < 0x58))) {
|
||||
/* auto-increment registers */
|
||||
dev->addr_register++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
/* Other AS99127F boards perform a soft reset through this register. */
|
||||
if ((dev->local & LM78_AS99127F) && (val == 0x01)) {
|
||||
lm78_log("LM78: Soft reset requested through AS99127F\n");
|
||||
default:
|
||||
lm78_log("LM78: Write %02X to unknown ISA port %d\n", val, port & 0x7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
lm78_i2c_write(void *bus, uint8_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
if (dev->i2c_state == 0) {
|
||||
dev->i2c_state = 1;
|
||||
dev->addr_register = val;
|
||||
} else
|
||||
lm78_write(dev, dev->addr_register++, val, LM78_WINBOND_BANK);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
lm78_as99127f_write(void *priv, uint8_t reg, uint8_t val)
|
||||
{
|
||||
lm78_t *dev = (lm78_t *) priv;
|
||||
|
||||
lm78_log("LM78: write(%02X, AS99127F, %02X)\n", reg, val);
|
||||
|
||||
reg &= 0x7f;
|
||||
uint8_t prev = dev->as99127f.regs[1][reg];
|
||||
dev->as99127f.regs[1][reg] = val;
|
||||
|
||||
switch (reg) {
|
||||
case 0x01:
|
||||
if (val & 0x40) {
|
||||
dev->as99127f.regs[1][0x00] = 0x88;
|
||||
dev->as99127f.regs[1][0x01] &= 0xe0;
|
||||
dev->as99127f.regs[1][0x03] &= 0xf7;
|
||||
dev->as99127f.regs[1][0x07] &= 0xfe;
|
||||
}
|
||||
if (!(val & 0x10)) { /* CUV4X-LS */
|
||||
lm78_log("LM78: Reset requested through AS99127F CLKRST\n");
|
||||
timer_set_delay_u64(&dev->reset_timer, 300000 * TIMER_USEC);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
/* security device I2C address */
|
||||
i2c_removehandler(i2c_smbus, prev & 0x7f, 1, lm78_security_start, lm78_security_read, lm78_security_write, NULL, dev);
|
||||
i2c_sethandler(i2c_smbus, val & 0x7f, 1, lm78_security_start, lm78_security_read, lm78_security_write, NULL, dev);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
if (val & 0x01) { /* other AS99127F boards */
|
||||
lm78_log("LM78: Reset requested through AS99127F GPO15\n");
|
||||
resetx86();
|
||||
}
|
||||
break;
|
||||
@@ -393,79 +650,34 @@ lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank)
|
||||
|
||||
|
||||
static void
|
||||
lm78_hard_reset_timer(void *priv)
|
||||
lm78_reset_timer(void *priv)
|
||||
{
|
||||
pc_reset_hard();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lm78_reset(lm78_t *dev, uint8_t initialization)
|
||||
lm78_remap(lm78_t *dev, uint8_t addr)
|
||||
{
|
||||
memset(dev->regs, 0, 256);
|
||||
memset(dev->regs + 0xc0, 0xff, 32); /* C0-DF are 0xFF at least on the AS99127F */
|
||||
lm75_t *lm75;
|
||||
|
||||
dev->regs[0x40] = 0x08;
|
||||
dev->regs[0x46] = 0x40;
|
||||
dev->regs[0x47] = 0x50;
|
||||
if (dev->local & LM78_I2C) {
|
||||
if (!initialization) /* don't reset main I2C address if the reset was triggered by the INITIALIZATION bit */
|
||||
dev->i2c_addr = 0x2d;
|
||||
dev->regs[0x48] = dev->i2c_addr;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x01;
|
||||
} else {
|
||||
dev->regs[0x48] = 0x00;
|
||||
if (dev->local & LM78_WINBOND)
|
||||
dev->regs[0x4a] = 0x88;
|
||||
if (!(dev->local & LM78_I2C)) return;
|
||||
|
||||
lm78_log("LM78: remapping to SMBus %02Xh\n", addr);
|
||||
|
||||
i2c_removehandler(i2c_smbus, dev->i2c_addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev);
|
||||
|
||||
if (addr < 0x80)
|
||||
i2c_sethandler(i2c_smbus, addr, 1, lm78_i2c_start, lm78_i2c_read, lm78_i2c_write, NULL, dev);
|
||||
|
||||
dev->i2c_addr = addr;
|
||||
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* Store our handle on the primary LM75 device to ensure reads/writes
|
||||
to the AS99127F's proprietary registers are passed through to this side. */
|
||||
if ((lm75 = device_get_priv(dev->lm75[0])))
|
||||
lm75->as99127f = dev;
|
||||
}
|
||||
if (dev->local & LM78_WINBOND) {
|
||||
dev->regs[0x49] = 0x02;
|
||||
dev->regs[0x4b] = 0x44;
|
||||
dev->regs[0x4c] = 0x01;
|
||||
dev->regs[0x4d] = 0x15;
|
||||
dev->regs[0x4e] = 0x80;
|
||||
dev->regs[0x4f] = (LM78_WINBOND_VENDOR_ID >> 8);
|
||||
dev->regs[0x57] = 0x80;
|
||||
|
||||
/* Initialize proprietary registers on the AS99127F. The BIOS accesses some
|
||||
of these on boot through read_byte_cmd on the TEMP2 address, hanging on
|
||||
POST code C1 if they're defaulted to 0. There's no documentation on what
|
||||
these are for. The following values were dumped from a live, initialized
|
||||
AS99127F Rev. 2 on a P4B motherboard, and they seem to work well enough. */
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* 0x00 appears to mirror IN2 Low Limit */
|
||||
/* 0x01 appears to mirror IN3 */
|
||||
dev->regs[0x02] = LM78_VOLTAGE_TO_REG(2800); /* appears to be a "maximum VCORE" of some kind; must read 2.8V on P3 boards */
|
||||
dev->regs[0x03] = 0x60;
|
||||
/* 0x04 appears to mirror IN3 */
|
||||
/* 0x05 appears to mirror IN2 */
|
||||
dev->regs[0x07] = 0xcd;
|
||||
/* 0x08 appears to mirror IN3 Low Limit */
|
||||
dev->regs[0x09] = dev->regs[0x0f] = dev->regs[0x11] = 0xf8; /* three instances of */
|
||||
dev->regs[0x0a] = dev->regs[0x10] = dev->regs[0x12] = 0xa5; /* the same word */
|
||||
dev->regs[0x0b] = 0xac;
|
||||
dev->regs[0x0c] = 0x8c;
|
||||
dev->regs[0x0d] = 0x68;
|
||||
dev->regs[0x0e] = 0x54;
|
||||
|
||||
dev->regs[0x53] = dev->regs[0x54] = dev->regs[0x55] = 0xff;
|
||||
dev->regs[0x58] = 0x31;
|
||||
dev->regs[0x59] = dev->regs[0x5a] = 0x8f;
|
||||
dev->regs[0x5c] = 0xe0;
|
||||
dev->regs[0x5d] = 0x48;
|
||||
dev->regs[0x5e] = 0xe2;
|
||||
dev->regs[0x5f] = 0x3f;
|
||||
} else if (dev->local & LM78_W83781D) {
|
||||
dev->regs[0x58] = 0x10;
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
dev->regs[0x58] = 0x30;
|
||||
}
|
||||
} else {
|
||||
dev->regs[0x49] = 0x40;
|
||||
}
|
||||
|
||||
lm78_remap(dev, dev->i2c_addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -478,6 +690,9 @@ lm78_close(void *priv)
|
||||
if (isa_io)
|
||||
io_removehandler(isa_io, 8, lm78_isa_read, NULL, NULL, lm78_isa_write, NULL, NULL, dev);
|
||||
|
||||
if (dev->as99127f.nvram_updated)
|
||||
lm78_nvram(dev, 1);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -508,17 +723,23 @@ lm78_init(const device_t *info)
|
||||
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 */
|
||||
RESISTOR_DIVIDER(5000, 51, 75), /* W83782D/AS99127F only: +5VSB (5.1K/7.5K divider suggested in the datasheet) */
|
||||
3000, /* W83782D/AS99127F only: Vbat */
|
||||
2500, /* AS99127F only: +2.5V */
|
||||
1500, /* AS99127F only: +1.5V */
|
||||
3000, /* AS99127F only: NVRAM */
|
||||
3300 /* AS99127F only: +3.3VSB */
|
||||
}
|
||||
};
|
||||
|
||||
/* Set chip-specific default values. */
|
||||
if (dev->local & LM78_AS99127F) {
|
||||
/* AS99127: different -12V Rin value (bruteforced) */
|
||||
/* AS99127F: different -12V Rin value (bruteforced) */
|
||||
defaults.voltages[5] = LM78_NEG_VOLTAGE(12000, 2400);
|
||||
|
||||
timer_add(&dev->hard_reset_timer, lm78_hard_reset_timer, dev, 0);
|
||||
timer_add(&dev->reset_timer, lm78_reset_timer, dev, 0);
|
||||
|
||||
lm78_nvram(dev, 0);
|
||||
} else if (dev->local & LM78_W83782D) {
|
||||
/* W83782D: different negative voltage formula */
|
||||
defaults.voltages[5] = LM78_NEG_VOLTAGE2(12000, 232);
|
||||
@@ -563,7 +784,7 @@ const device_t lm78_device = {
|
||||
};
|
||||
|
||||
|
||||
/* Winbond W83781D (or ASUS AS97127F) on ISA and SMBus. */
|
||||
/* Winbond W83781D on ISA and SMBus. */
|
||||
const device_t w83781d_device = {
|
||||
"Winbond W83781D Hardware Monitor",
|
||||
DEVICE_ISA,
|
||||
@@ -574,8 +795,8 @@ const device_t w83781d_device = {
|
||||
};
|
||||
|
||||
|
||||
/* The ASUS AS99127F is a customized W83781D with no ISA interface (I2C
|
||||
only), added proprietary registers and different chip/vendor IDs. */
|
||||
/* The AS99127F is an ASIC manufactured by Holtek for ASUS, containing an
|
||||
I2C-only W83781D clone with additional voltages, GPIOs and fan control. */
|
||||
const device_t as99127f_device = {
|
||||
"ASUS AS99127F Rev. 1 Hardware Monitor",
|
||||
DEVICE_ISA,
|
||||
@@ -586,7 +807,7 @@ const device_t as99127f_device = {
|
||||
};
|
||||
|
||||
|
||||
/* Rev. 2 changes the vendor ID back to Winbond's and brings some other changes. */
|
||||
/* Rev. 2 is manufactured by Winbond and differs only in GPI registers. */
|
||||
const device_t as99127f_rev2_device = {
|
||||
"ASUS AS99127F Rev. 2 Hardware Monitor",
|
||||
DEVICE_ISA,
|
||||
|
||||
@@ -330,7 +330,8 @@ const scancode scancode_xt[512] = {
|
||||
static uint8_t key_queue[16];
|
||||
static int key_queue_start = 0,
|
||||
key_queue_end = 0;
|
||||
static int is_t1x00 = 0;
|
||||
static int is_tandy = 0, is_t1x00 = 0,
|
||||
is_amstrad = 0;
|
||||
|
||||
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
@@ -453,42 +454,36 @@ kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val))
|
||||
if (!adddata)
|
||||
return;
|
||||
|
||||
if (is_tandy) {
|
||||
adddata(val);
|
||||
return;
|
||||
}
|
||||
|
||||
keyboard_get_states(NULL, &num_lock, NULL);
|
||||
shift_states = keyboard_get_shift() & STATE_SHIFT_MASK;
|
||||
shift_states = keyboard_get_shift() & STATE_LSHIFT;
|
||||
|
||||
if (is_amstrad)
|
||||
num_lock = !num_lock;
|
||||
|
||||
/* If NumLock is on, invert the left shift state so we can always check for
|
||||
the the same way flag being set (and with NumLock on that then means it
|
||||
is actually *NOT* set). */
|
||||
if (num_lock)
|
||||
shift_states ^= STATE_LSHIFT;
|
||||
|
||||
switch(val) {
|
||||
case FAKE_LSHIFT_ON:
|
||||
if (num_lock) {
|
||||
if (!shift_states) {
|
||||
/* Num lock on and no shifts are pressed, send non-inverted fake shift. */
|
||||
adddata(0x2a);
|
||||
}
|
||||
} else {
|
||||
if (shift_states & STATE_LSHIFT) {
|
||||
/* Num lock off and left shift pressed. */
|
||||
adddata(0xaa);
|
||||
}
|
||||
if (shift_states & STATE_RSHIFT) {
|
||||
/* Num lock off and right shift pressed. */
|
||||
adddata(0xb6);
|
||||
}
|
||||
/* If NumLock is on, fake shifts are sent when shift is *NOT* presed,
|
||||
if NumLock is off, fake shifts are sent when shift is pressed. */
|
||||
if (shift_states) {
|
||||
/* Send fake shift. */
|
||||
adddata(num_lock ? 0x2a : 0xaa);
|
||||
}
|
||||
break;
|
||||
case FAKE_LSHIFT_OFF:
|
||||
if (num_lock) {
|
||||
if (!shift_states) {
|
||||
/* Num lock on and no shifts are pressed, send non-inverted fake shift. */
|
||||
adddata(0xaa);
|
||||
}
|
||||
} else {
|
||||
if (shift_states & STATE_LSHIFT) {
|
||||
/* Num lock off and left shift pressed. */
|
||||
adddata(0x2a);
|
||||
}
|
||||
if (shift_states & STATE_RSHIFT) {
|
||||
/* Num lock off and right shift pressed. */
|
||||
adddata(0x36);
|
||||
}
|
||||
if (shift_states) {
|
||||
/* Send fake shift. */
|
||||
adddata(num_lock ? 0xaa : 0x2a);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -540,13 +535,13 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
if (kbd->type <= 1)
|
||||
kbd_log("Casette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
|
||||
kbd_log("Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
|
||||
#endif
|
||||
break;
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
case 0x62:
|
||||
if (kbd->type <= 1)
|
||||
kbd_log("Casette IN is %i\n", !!(val & 0x10));
|
||||
kbd_log("Cassette IN is %i\n", !!(val & 0x10));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
@@ -606,10 +601,8 @@ kbd_read(uint16_t port, void *priv)
|
||||
/* Olivetti M19 or Zenith Data Systems Z-151*/
|
||||
if (kbd->pb & 0x04)
|
||||
ret = kbd->pd & 0xbf;
|
||||
//return 0x00;
|
||||
else
|
||||
ret = kbd->pd >> 4;
|
||||
//return 0x00;
|
||||
}
|
||||
else {
|
||||
if (kbd->pb & 0x08)
|
||||
@@ -664,6 +657,13 @@ kbd_reset(void *priv)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
keyboard_set_is_amstrad(int ams)
|
||||
{
|
||||
is_amstrad = ams;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
kbd_init(const device_t *info)
|
||||
{
|
||||
@@ -802,8 +802,11 @@ kbd_init(const device_t *info)
|
||||
|
||||
keyboard_set_table(scancode_xt);
|
||||
|
||||
is_tandy = (kbd->type == 5);
|
||||
is_t1x00 = (kbd->type == 6);
|
||||
|
||||
is_amstrad = 0;
|
||||
|
||||
return(kbd);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user