diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2009-03-30 00:36:27 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2009-03-30 00:36:27 +0000 |
commit | 76f19d32fa666c6e21fdf4a8dfdb4f392b8fff56 (patch) | |
tree | af4e14911002bf503c1532bc98402459ba5759d3 /sys/dev/isa/fins.c | |
parent | 1f08dd635f94f957647c32a67d9839fc80df4531 (diff) |
Support for more chipset versions, written by Ian Lindsay
Diffstat (limited to 'sys/dev/isa/fins.c')
-rw-r--r-- | sys/dev/isa/fins.c | 462 |
1 files changed, 281 insertions, 181 deletions
diff --git a/sys/dev/isa/fins.c b/sys/dev/isa/fins.c index 04e3674d406..bf4ae3d2fc9 100644 --- a/sys/dev/isa/fins.c +++ b/sys/dev/isa/fins.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fins.c,v 1.1 2008/03/19 19:33:09 deraadt Exp $ */ +/* $OpenBSD: fins.c,v 1.2 2009/03/30 00:36:26 deraadt Exp $ */ /* * Copyright (c) 2005, 2006 Mark Kettenis @@ -46,30 +46,44 @@ * This section of the chip controls the fans. We don't do anything to them. */ - #define FINS_UNLOCK 0x87 /* magic constant - write 2x to select chip */ #define FINS_LOCK 0xaa /* magic constant - write 1x to deselect reg */ -#define FINS_FUNC_SEL 0x07 /* select which subchip to access */ -# define FINS_FUNC_SENSORS 0x4 - /* ISA registers index to an internal register space on chip */ #define FINS_ADDR 0x00 #define FINS_DATA 0x01 -/* Chip identification regs and values in bank 0 */ -#define FINS_MANUF 0x23 /* manufacturer ID */ -# define FINTEK_ID 0x1934 +#define FINS_FUNC_SEL 0x07 /* select which chip function to access */ #define FINS_CHIP 0x20 /* chip ID */ -# define FINS_ID 0x0406 +#define FINS_MANUF 0x23 /* manufacturer ID */ +#define FINS_BASEADDR 0x60 /* I/O base of chip function */ + +#define FINS_71806 0x0341 /* same as F71872 */ +#define FINS_71805 0x0406 +#define FINS_71882 0x0541 /* same as F71883 */ +#define FINS_71862 0x0601 /* same as F71863 */ +#define FINTEK_ID 0x1934 + +#define FINS_FUNC_SENSORS 0x04 +#define FINS_FUNC_WATCHDOG 0x07 -/* in bank sensors of config space */ -#define FINS_SENSADDR 0x60 /* sensors assigned I/O address (2 bytes) */ +/* sensors device registers */ +#define FINS_SENS_TMODE(sc) ((sc)->fins_chipid <= FINS_71805 ? 0x01 : 0x6b) +#define FINS_SENS_VDIVS 0x0e -/* in sensors space */ -#define FINS_TMODE 0x01 /* temperature mode reg */ +/* watchdog device registers (mapped straight to i/o port offsets) */ +#define FINS_WDOG_CR0 0x00 +#define FINS_WDOG_CR1 0x05 +#define FINS_WDOG_TIMER 0x06 -#define FINS_MAX_SENSORS 20 +/* CR0 flags */ +#define FINS_WDOG_OUTEN 0x80 + +/* CR1 flags */ +#define FINS_WDOG_EN 0x20 +#define FINS_WDOG_MINS 0x08 + +#define FINS_MAX_SENSORS 18 /* * Fintek chips typically measure voltages using 8mv steps. * To measure higher voltages the input is attenuated with (external) @@ -81,21 +95,14 @@ #define FRFACT(x, y) (FRFACT_NONE * ((x) + (y)) / (y)) #define FNRFACT(x, y) (-FRFACT_NONE * (x) / (y)) -#if defined(FINSDEBUG) -#define DPRINTF(x) do { printf x; } while (0) -#else -#define DPRINTF(x) -#endif - struct fins_softc; struct fins_sensor { char *fs_desc; + void (*fs_refresh)(struct fins_softc *, int); enum sensor_type fs_type; - u_int8_t fs_aux; + int fs_aux; u_int8_t fs_reg; - void (*fs_refresh)(struct fins_softc *, int); - int fs_rfact; }; struct fins_softc { @@ -105,227 +112,295 @@ struct fins_softc { struct ksensordev fins_sensordev; struct sensor_task *fins_sensortask; struct fins_sensor *fins_sensors; - u_int fins_numsensors; - void (*refresh_sensor_data) (struct fins_softc *); - u_int8_t (*fins_readreg)(struct fins_softc *, int); - void (*fins_writereg)(struct fins_softc *, int, int); - u_int fins_tempsel; + bus_space_handle_t sc_ioh_sens; + bus_space_handle_t sc_ioh_wdog; + bus_space_tag_t sc_iot; + + u_int16_t fins_chipid; + u_int8_t fins_tempsel; + u_int8_t fins_wdog_cr; }; +int fins_match(struct device *, void *, void *); +void fins_attach(struct device *, struct device *, void *); -struct fins_isa_softc { - struct fins_softc sc_finssc; +void fins_unlock(bus_space_tag_t, bus_space_handle_t); +void fins_lock(bus_space_tag_t, bus_space_handle_t); - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; -}; +u_int8_t fins_read(bus_space_tag_t, bus_space_handle_t, int); +u_int16_t fins_read_2(bus_space_tag_t, bus_space_handle_t, int); +void fins_write(bus_space_tag_t, bus_space_handle_t, int, u_int8_t); + +static __inline u_int8_t fins_read_sens(struct fins_softc *, int); +static __inline u_int16_t fins_read_sens_2(struct fins_softc *, int); -int fins_isa_match(struct device *, void *, void *); -void fins_isa_attach(struct device *, struct device *, void *); -u_int8_t fins_isa_readreg(struct fins_softc *, int); -void fins_isa_writereg(struct fins_softc *, int, int); +static __inline u_int8_t fins_read_wdog(struct fins_softc *, int); +static __inline void fins_write_wdog(struct fins_softc *, int, u_int8_t); void fins_setup_sensors(struct fins_softc *, struct fins_sensor *); void fins_refresh(void *); -void fins_refresh_volt(struct fins_softc *, int); -void fins_refresh_temp(struct fins_softc *, int); -void fins_refresh_offset(struct fins_softc *, int); -void fins_refresh_fanrpm(struct fins_softc *, int); -void fins_attach(struct fins_softc *); -int fins_detach(struct fins_softc *); +void fins_get_rpm(struct fins_softc *, int); +void fins_get_temp(struct fins_softc *, int); +void fins_get_volt(struct fins_softc *, int); + +int fins_wdog_cb(void *, int); struct cfattach fins_ca = { - sizeof(struct fins_isa_softc), - fins_isa_match, - fins_isa_attach + sizeof(struct fins_softc), + fins_match, + fins_attach }; struct cfdriver fins_cd = { NULL, "fins", DV_DULL }; -struct fins_sensor fins_sensors[] = { - /* Voltage */ - { "+3.3V", SENSOR_VOLTS_DC, 0, 0x10, fins_refresh_volt, FRFACT(100, 100) }, - { "Vtt", SENSOR_VOLTS_DC, 0, 0x11, fins_refresh_volt, FRFACT_NONE }, - { "Vram", SENSOR_VOLTS_DC, 0, 0x12, fins_refresh_volt, FRFACT(100, 100) }, - { "Vchips", SENSOR_VOLTS_DC, 0, 0x13, fins_refresh_volt, FRFACT(47, 100) }, - { "+5V", SENSOR_VOLTS_DC, 0, 0x14, fins_refresh_volt, FRFACT(200, 47) }, - { "+12V", SENSOR_VOLTS_DC, 0, 0x15, fins_refresh_volt, FRFACT(200, 20) }, - { "Vcc 1.5V", SENSOR_VOLTS_DC, 0, 0x16, fins_refresh_volt, FRFACT_NONE }, - { "VCore", SENSOR_VOLTS_DC, 0, 0x17, fins_refresh_volt, FRFACT_NONE }, - { "Vsb", SENSOR_VOLTS_DC, 0, 0x18, fins_refresh_volt, FRFACT(200, 47) }, - { "Vsbint", SENSOR_VOLTS_DC, 0, 0x19, fins_refresh_volt, FRFACT(200, 47) }, - { "Vbat", SENSOR_VOLTS_DC, 0, 0x1A, fins_refresh_volt, FRFACT(200, 47) }, - - /* Temperature */ - { "Temp1", SENSOR_TEMP, 0x01, 0x1B, fins_refresh_temp }, - { "Temp2", SENSOR_TEMP, 0x02, 0x1C, fins_refresh_temp }, - { "Temp3", SENSOR_TEMP, 0x04, 0x1D, fins_refresh_temp }, - - /* Fans */ - { "Fan1", SENSOR_FANRPM, 0, 0x20, fins_refresh_fanrpm }, - { "Fan2", SENSOR_FANRPM, 0, 0x22, fins_refresh_fanrpm }, - { "Fan3", SENSOR_FANRPM, 0, 0x24, fins_refresh_fanrpm }, +struct fins_sensor fins_71805_sensors[] = { + { "+3.3V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100), 0x10 }, + { "Vtt", fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE, 0x11 }, + { "Vram", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100), 0x12 }, + { "Vchips", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(47, 100), 0x13 }, + { "+5V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47), 0x14 }, + { "+12V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 20), 0x15 }, + { "+1.5V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE, 0x16 }, + { "Vcore", fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE, 0x17 }, + { "Vsb", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47), 0x18 }, + { "Vsbint", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47), 0x19 }, + { "Vbat", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47), 0x1a }, + + { NULL, fins_get_temp, SENSOR_TEMP, 0x01, 0x1b }, + { NULL, fins_get_temp, SENSOR_TEMP, 0x02, 0x1c }, + { NULL, fins_get_temp, SENSOR_TEMP, 0x04, 0x1d }, + + { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0x20 }, + { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0x22 }, + { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0x24 }, { NULL } }; +struct fins_sensor fins_71882_sensors[] = { + { "+3.3V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100), 0x20 }, + { "Vcore", fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE, 0x21 }, + { "Vram", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100), 0x22 }, + { "Vchips", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(47, 100), 0x23 }, + { "+5V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 47), 0x24 }, + { "+12V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(200, 20), 0x25 }, + { "+1.5V", fins_get_volt, SENSOR_VOLTS_DC, FRFACT_NONE, 0x26 }, + { "Vsb", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100), 0x27 }, + { "Vbat", fins_get_volt, SENSOR_VOLTS_DC, FRFACT(100, 100), 0x28 }, + + { NULL, fins_get_temp, SENSOR_TEMP, 0x02, 0x72 }, + { NULL, fins_get_temp, SENSOR_TEMP, 0x04, 0x74 }, + { NULL, fins_get_temp, SENSOR_TEMP, 0x08, 0x76 }, + + { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xa0 }, + { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xb0 }, + { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xc0 }, + { NULL, fins_get_rpm, SENSOR_FANRPM, 0, 0xd0 }, + + { NULL } +}; int -fins_isa_match(struct device *parent, void *match, void *aux) +fins_match(struct device *parent, void *match, void *aux) { - bus_space_tag_t iot; - bus_addr_t iobase; - bus_space_handle_t ioh; struct isa_attach_args *ia = aux; - u_int val; + bus_space_handle_t ioh; + bus_space_tag_t iot; + int ret = 0; + u_int16_t id; iot = ia->ia_iot; - iobase = ia->ipa_io[0].base; - - if (bus_space_map(iot, iobase, 2, 0, &ioh)) + if (bus_space_map(iot, ia->ipa_io[0].base, 2, 0, &ioh)) return (0); /* Fintek uses magic cookie locks to distinguish their chips */ - bus_space_write_1(iot, ioh, 0, FINS_UNLOCK); - bus_space_write_1(iot, ioh, 0, FINS_UNLOCK); - bus_space_write_1(iot, ioh, 0, FINS_FUNC_SEL); - bus_space_write_1(iot, ioh, 1, 0); /* IDs appear only in space 0 */ - bus_space_write_1(iot, ioh, 0, FINS_MANUF); - val = bus_space_read_1(iot, ioh, 1) << 8; - bus_space_write_1(iot, ioh, 0, FINS_MANUF + 1); - val |= bus_space_read_1(iot, ioh, 1); - if (val != FINTEK_ID) { - bus_space_write_1(iot, ioh, 0, FINS_LOCK); - goto notfound; - } - bus_space_write_1(iot, ioh, 0, FINS_CHIP); - val = bus_space_read_1(iot, ioh, 1) << 8; - bus_space_write_1(iot, ioh, 0, FINS_CHIP + 1); - val |= bus_space_read_1(iot, ioh, 1); - /* If we cared which Fintek chip this was we would save the chip ID here */ - if (val != FINS_ID) { - bus_space_write_1(iot, ioh, 0, FINS_LOCK); - goto notfound; + fins_unlock(iot, ioh); + + fins_write(iot, ioh, FINS_FUNC_SEL, 0); /* IDs appear only in space 0 */ + if (fins_read_2(iot, ioh, FINS_MANUF) != FINTEK_ID) + goto match_done; + id = fins_read_2(iot, ioh, FINS_CHIP); + switch(id) { + case FINS_71882: + case FINS_71862: + ia->ipa_nio = 3; + fins_write(iot, ioh, FINS_FUNC_SEL, FINS_FUNC_WATCHDOG); + ia->ipa_io[2].base = fins_read_2(iot, ioh, FINS_BASEADDR); + ia->ipa_io[2].length = 8; + fins_write(iot, ioh, FINS_FUNC_SEL, FINS_FUNC_SENSORS); + ia->ipa_io[1].base = fins_read_2(iot, ioh, FINS_BASEADDR); + ia->ipa_io[1].base += 5; + break; + case FINS_71806: + case FINS_71805: + ia->ipa_nio = 2; + fins_write(iot, ioh, FINS_FUNC_SEL, FINS_FUNC_SENSORS); + ia->ipa_io[1].base = fins_read_2(iot, ioh, FINS_BASEADDR); + break; + default: + goto match_done; } - /* select sensor function of the chip */ - bus_space_write_1(iot, ioh, FINS_ADDR, FINS_FUNC_SEL); - bus_space_write_1(iot, ioh, FINS_DATA, FINS_FUNC_SENSORS); - /* read I/O address assigned by BIOS to this function */ - bus_space_write_1(iot, ioh, FINS_ADDR, FINS_SENSADDR); - val = bus_space_read_1(iot, ioh, FINS_DATA) << 8; - bus_space_write_1(iot, ioh, FINS_ADDR, FINS_SENSADDR + 1); - val |= bus_space_read_1(iot, ioh, FINS_DATA); - bus_space_write_1(iot, ioh, 0, FINS_LOCK); - ia->ipa_io[1].length = 2; - ia->ipa_io[1].base = val; - - bus_space_unmap(iot, ioh, 2); - ia->ipa_nio = 2; - ia->ipa_io[0].length = 2; - ia->ipa_nmem = 0; - ia->ipa_nirq = 0; - ia->ipa_ndrq = 0; - return (1); - - notfound: - bus_space_unmap(iot, ioh, 2); - return (0); + ia->ipa_io[0].length = ia->ipa_io[1].length = 2; + ia->ipa_nmem = ia->ipa_nirq = ia->ipa_ndrq = 0; + ia->ia_aux = (void *)(u_long)id; + ret = 1; +match_done: + fins_lock(iot, ioh); + return (ret); } void -fins_isa_attach(struct device *parent, struct device *self, void *aux) +fins_attach(struct device *parent, struct device *self, void *aux) { - struct fins_isa_softc *sc = (struct fins_isa_softc *)self; + struct fins_softc *sc = (struct fins_softc *)self; struct isa_attach_args *ia = aux; bus_addr_t iobase; + u_int32_t iosize; + u_int i; sc->sc_iot = ia->ia_iot; + sc->fins_chipid = (u_int16_t)(u_long)ia->ia_aux; iobase = ia->ipa_io[1].base; - sc->sc_finssc.fins_writereg = fins_isa_writereg; - sc->sc_finssc.fins_readreg = fins_isa_readreg; - if (bus_space_map(sc->sc_iot, iobase, 2, 0, &sc->sc_ioh)) { - printf(": can't map i/o space\n"); + iosize = ia->ipa_io[1].length; + if (bus_space_map(sc->sc_iot, iobase, iosize, 0, &sc->sc_ioh_sens)) { + printf(": can't map sensor i/o space\n"); return; } - fins_attach(&sc->sc_finssc); + switch(sc->fins_chipid) { + case FINS_71882: + case FINS_71862: + fins_setup_sensors(sc, fins_71882_sensors); + break; + case FINS_71806: + case FINS_71805: + fins_setup_sensors(sc, fins_71805_sensors); + break; + } + sc->fins_sensortask = sensor_task_register(sc, fins_refresh, 5); + if (sc->fins_sensortask == NULL) { + printf(": can't register update task\n"); + return; + } + for (i = 0; sc->fins_sensors[i].fs_refresh != NULL; ++i) + sensor_attach(&sc->fins_sensordev, &sc->fins_ksensors[i]); + sensordev_install(&sc->fins_sensordev); + + if (sc->fins_chipid <= FINS_71805) + goto attach_done; + iobase = ia->ipa_io[2].base; + iosize = ia->ipa_io[2].length; + if (bus_space_map(sc->sc_iot, iobase, iosize, 0, &sc->sc_ioh_wdog)) { + printf(": can't map watchdog i/o space\n"); + return; + } + sc->fins_wdog_cr = fins_read_wdog(sc, FINS_WDOG_CR1); + sc->fins_wdog_cr &= ~(FINS_WDOG_MINS | FINS_WDOG_EN); + fins_write_wdog(sc, FINS_WDOG_CR1, sc->fins_wdog_cr); + wdog_register(sc, fins_wdog_cb); +attach_done: + printf("\n"); } u_int8_t -fins_isa_readreg(struct fins_softc *lmsc, int reg) +fins_read(bus_space_tag_t iot, bus_space_handle_t ioh, int reg) { - struct fins_isa_softc *sc = (struct fins_isa_softc *)lmsc; - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, FINS_ADDR, reg); - return (bus_space_read_1(sc->sc_iot, sc->sc_ioh, FINS_DATA)); + bus_space_write_1(iot, ioh, FINS_ADDR, reg); + return (bus_space_read_1(iot, ioh, FINS_DATA)); } -void -fins_isa_writereg(struct fins_softc *lmsc, int reg, int val) +u_int16_t +fins_read_2(bus_space_tag_t iot, bus_space_handle_t ioh, int reg) { - struct fins_isa_softc *sc = (struct fins_isa_softc *)lmsc; + u_int16_t val; - bus_space_write_1(sc->sc_iot, sc->sc_ioh, FINS_ADDR, reg); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, FINS_DATA, val); + bus_space_write_1(iot, ioh, FINS_ADDR, reg); + val = bus_space_read_1(iot, ioh, FINS_DATA) << 8; + bus_space_write_1(iot, ioh, FINS_ADDR, reg + 1); + return (val | bus_space_read_1(iot, ioh, FINS_DATA)); } void -fins_attach(struct fins_softc *sc) +fins_write(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, u_int8_t val) { - u_int i; - - fins_setup_sensors(sc, fins_sensors); - sc->fins_sensortask = sensor_task_register(sc, fins_refresh, 5); - if (sc->fins_sensortask == NULL) { - printf(": unable to register update task\n"); - return; - } + bus_space_write_1(iot, ioh, FINS_ADDR, reg); + bus_space_write_1(iot, ioh, FINS_DATA, val); +} - printf("\n"); - /* Add sensors */ - for (i = 0; i < sc->fins_numsensors; ++i) - sensor_attach(&sc->fins_sensordev, &sc->fins_ksensors[i]); - sensordev_install(&sc->fins_sensordev); +static __inline u_int8_t +fins_read_sens(struct fins_softc *sc, int reg) +{ + return (fins_read(sc->sc_iot, sc->sc_ioh_sens, reg)); } -int -fins_detach(struct fins_softc *sc) +static __inline u_int16_t +fins_read_sens_2(struct fins_softc *sc, int reg) { - int i; + return (fins_read_2(sc->sc_iot, sc->sc_ioh_sens, reg)); +} - /* Remove sensors */ - sensordev_deinstall(&sc->fins_sensordev); - for (i = 0; i < sc->fins_numsensors; i++) - sensor_detach(&sc->fins_sensordev, &sc->fins_ksensors[i]); +static __inline u_int8_t +fins_read_wdog(struct fins_softc *sc, int reg) +{ + return (bus_space_read_1(sc->sc_iot, sc->sc_ioh_wdog, reg)); +} - if (sc->fins_sensortask != NULL) - sensor_task_unregister(sc->fins_sensortask); +static __inline void +fins_write_wdog(struct fins_softc *sc, int reg, u_int8_t val) +{ + bus_space_write_1(sc->sc_iot, sc->sc_ioh_wdog, reg, val); +} - return 0; +void +fins_unlock(bus_space_tag_t iot, bus_space_handle_t ioh) +{ + bus_space_write_1(iot, ioh, 0, FINS_UNLOCK); + bus_space_write_1(iot, ioh, 0, FINS_UNLOCK); } +void +fins_lock(bus_space_tag_t iot, bus_space_handle_t ioh) +{ + bus_space_write_1(iot, ioh, 0, FINS_LOCK); + bus_space_unmap(iot, ioh, 2); +} void fins_setup_sensors(struct fins_softc *sc, struct fins_sensor *sensors) { int i; - struct ksensor *ksensor = sc->fins_ksensors; + for (i = 0; sensors[i].fs_refresh != NULL; ++i) { + sc->fins_ksensors[i].type = sensors[i].fs_type; + if (sensors[i].fs_desc != NULL) + strlcpy(sc->fins_ksensors[i].desc, sensors[i].fs_desc, + sizeof(sc->fins_ksensors[i].desc)); + } strlcpy(sc->fins_sensordev.xname, sc->sc_dev.dv_xname, - sizeof(sc->fins_sensordev.xname)); + sizeof(sc->fins_sensordev.xname)); + sc->fins_sensors = sensors; + sc->fins_tempsel = fins_read_sens(sc, FINS_SENS_TMODE(sc)); +} - for (i = 0; sensors[i].fs_desc; i++) { - ksensor[i].type = sensors[i].fs_type; - strlcpy(ksensor[i].desc, sensors[i].fs_desc, - sizeof(ksensor[i].desc)); +#if 0 +void +fins_get_dividers(struct fins_softc *sc) +{ + int i, p, m; + u_int16_t r = fins_read_sens_2(sc, FINS_SENS_VDIVS); + + for (i = 0; i < 6; ++i) { + p = (i < 4) ? i : i + 2; + m = (r & (0x03 << p)) >> p; + if (m == 3) + m = 4; + fins_71882_sensors[i + 1].fs_aux = FRFACT_NONE << m; } - sc->fins_numsensors = i; - sc->fins_sensors = sensors; - sc->fins_tempsel = sc->fins_readreg(sc, FINS_TMODE); } +#endif void fins_refresh(void *arg) @@ -333,30 +408,30 @@ fins_refresh(void *arg) struct fins_softc *sc = arg; int i; - for (i = 0; i < sc->fins_numsensors; i++) + for (i = 0; sc->fins_sensors[i].fs_refresh != NULL; ++i) sc->fins_sensors[i].fs_refresh(sc, i); } void -fins_refresh_volt(struct fins_softc *sc, int n) +fins_get_volt(struct fins_softc *sc, int n) { struct ksensor *sensor = &sc->fins_ksensors[n]; struct fins_sensor *fs = &sc->fins_sensors[n]; int data; - data = sc->fins_readreg(sc, fs->fs_reg); + data = fins_read_sens(sc, fs->fs_reg); if (data == 0xff || data == 0) { sensor->flags |= SENSOR_FINVALID; sensor->value = 0; } else { sensor->flags &= ~SENSOR_FINVALID; - sensor->value = data * fs->fs_rfact; + sensor->value = data * fs->fs_aux; } } /* The BIOS seems to add a fudge factor to the CPU temp of +5C */ void -fins_refresh_temp(struct fins_softc *sc, int n) +fins_get_temp(struct fins_softc *sc, int n) { struct ksensor *sensor = &sc->fins_ksensors[n]; struct fins_sensor *fs = &sc->fins_sensors[n]; @@ -369,7 +444,7 @@ fins_refresh_temp(struct fins_softc *sc, int n) * what kind of sensor is used. * A disconnected sensor seems to read over 110 or so. */ - data = sc->fins_readreg(sc, fs->fs_reg) & 0xFF; + data = fins_read_sens(sc, fs->fs_reg); max = (sc->fins_tempsel & fs->fs_aux) ? 111 : 128; if (data == 0 || data >= max) { /* disconnected? */ sensor->flags |= SENSOR_FINVALID; @@ -382,6 +457,7 @@ fins_refresh_temp(struct fins_softc *sc, int n) /* The chip holds a fudge factor for BJT sensors */ /* this is currently unused but might be reenabled */ +#if 0 void fins_refresh_offset(struct fins_softc *sc, int n) { @@ -390,22 +466,21 @@ fins_refresh_offset(struct fins_softc *sc, int n) u_int data; sensor->flags &= ~SENSOR_FINVALID; - data = sc->fins_readreg(sc, fs->fs_reg); + data = fins_read_sens(sc, fs->fs_reg); data |= ~0 * (data & 0x40); /* sign extend 7-bit value */ sensor->value = data * 1000000 + 273150000; } - +#endif /* fan speed appears to be a 12-bit number */ void -fins_refresh_fanrpm(struct fins_softc *sc, int n) +fins_get_rpm(struct fins_softc *sc, int n) { struct ksensor *sensor = &sc->fins_ksensors[n]; struct fins_sensor *fs = &sc->fins_sensors[n]; int data; - data = sc->fins_readreg(sc, fs->fs_reg) << 8; - data |= sc->fins_readreg(sc, fs->fs_reg + 1); + data = fins_read_sens_2(sc, fs->fs_reg); if (data >= 0xfff) { sensor->value = 0; sensor->flags |= SENSOR_FINVALID; @@ -414,3 +489,28 @@ fins_refresh_fanrpm(struct fins_softc *sc, int n) sensor->flags &= ~SENSOR_FINVALID; } } + +int +fins_wdog_cb(void *arg, int period) +{ + struct fins_softc *sc = arg; + u_int8_t cr0, cr1, t; + + cr0 = fins_read_wdog(sc, FINS_WDOG_CR0) & ~FINS_WDOG_OUTEN; + fins_write_wdog(sc, FINS_WDOG_CR0, cr0); + + cr1 = sc->fins_wdog_cr; + if (period > 0xff) { + cr1 |= FINS_WDOG_MINS; + t = (period + 59) / 60; + period = (int)t * 60; + } else if (period > 0) + t = period; + else + return (0); + + fins_write_wdog(sc, FINS_WDOG_TIMER, t); + fins_write_wdog(sc, FINS_WDOG_CR0, cr0 | FINS_WDOG_OUTEN); + fins_write_wdog(sc, FINS_WDOG_CR1, cr1 | FINS_WDOG_EN); + return (period); +} |