[BACK]Return to finsio_isa.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / isa

Annotation of src/sys/dev/isa/finsio_isa.c, Revision 1.7.12.1

1.1       xtraeme     1: /*     $OpenBSD: fins.c,v 1.1 2008/03/19 19:33:09 deraadt Exp $        */
1.7.12.1! jdolecek    2: /*     $NetBSD$        */
1.1       xtraeme     3:
                      4: /*
                      5:  * Copyright (c) 2008 Juan Romero Pardines
                      6:  * Copyright (c) 2007, 2008 Geoff Steckel
                      7:  * Copyright (c) 2005, 2006 Mark Kettenis
                      8:  *
                      9:  * Permission to use, copy, modify, and distribute this software for any
                     10:  * purpose with or without fee is hereby granted, provided that the above
                     11:  * copyright notice and this permission notice appear in all copies.
                     12:  *
                     13:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     14:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     15:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     16:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     17:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     18:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     19:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     20:  */
                     21: #include <sys/cdefs.h>
1.7.12.1! jdolecek   22: __KERNEL_RCSID(0, "$NetBSD$");
1.1       xtraeme    23:
                     24: #include <sys/param.h>
                     25: #include <sys/systm.h>
                     26: #include <sys/device.h>
1.6       jmcneill   27: #include <sys/module.h>
1.1       xtraeme    28: #include <sys/bus.h>
                     29:
                     30: #include <dev/isa/isareg.h>
                     31: #include <dev/isa/isavar.h>
                     32:
                     33: #include <dev/sysmon/sysmonvar.h>
                     34:
                     35: /* Derived from LM78 code. Only handles chips attached to ISA bus */
                     36:
                     37: /*
                     38:  * Fintek F71805/F71883 Super I/O datasheets:
                     39:  * http://www.fintek.com.tw/files/productfiles/F71805F_V025.pdf
                     40:  * http://www.fintek.com.tw/files/productfiles/F71883_V026P.pdf
                     41:  *
                     42:  * This chip is a multi-io chip with many functions.
                     43:  * Each function may be relocated in I/O space by the BIOS.
                     44:  * The base address (2E or 4E) accesses a configuration space which
                     45:  * has pointers to the individual functions. The config space must be
                     46:  * unlocked with a cookie and relocked afterwards. The chip ID is stored
                     47:  * in config space so it is not normally visible.
                     48:  *
                     49:  * The voltage dividers specified are from reading the chips on one board.
                     50:  * There is no way to determine what they are in the general case.
                     51:  */
                     52:
                     53: #define FINSIO_UNLOCK  0x87    /* magic constant - write 2x to select chip */
                     54: #define FINSIO_LOCK    0xaa    /* magic constant - write 1x to deselect reg */
                     55:
                     56: #define FINSIO_FUNC_SEL        0x07    /* select which subchip to access */
                     57: #  define FINSIO_FUNC_HWMON 0x4
                     58:
                     59: /* ISA registers index to an internal register space on chip */
1.7       jakllsch   60: #define FINSIO_DECODE_SIZE (8)
                     61: #define FINSIO_DECODE_MASK (FINSIO_DECODE_SIZE - 1)
                     62: #define FINSIO_ADDR    5       /* global configuration index */
                     63: #define FINSIO_DATA    6       /* and data registers */
1.1       xtraeme    64:
                     65: /* Global configuration registers */
                     66: #define FINSIO_MANUF   0x23    /* manufacturer ID */
                     67: # define FINTEK_ID     0x1934
                     68: #define FINSIO_CHIP    0x20    /* chip ID */
                     69: # define FINSIO_IDF71805       0x0406
                     70: # define FINSIO_IDF71806       0x0341  /* F71872 and F1806 F/FG */
                     71: # define FINSIO_IDF71883       0x0541  /* F71882 and F1883 */
                     72: # define FINSIO_IDF71862       0x0601  /* F71862FG */
1.6       jmcneill   73: # define FINSIO_IDF8000        0x0581  /* F8000 */
1.1       xtraeme    74:
                     75: /* in bank sensors of config space */
                     76: #define FINSIO_SENSADDR        0x60    /* sensors assigned I/O address (2 bytes) */
                     77:
                     78: #define FINSIO_HWMON_CONF      0x01    /* Hardware Monitor Config. Register */
                     79:
                     80: /* in sensors space */
                     81: #define FINSIO_TMODE   0x01    /* temperature mode reg */
                     82:
                     83: #define FINSIO_MAX_SENSORS     20
                     84: /*
                     85:  * Fintek chips typically measure voltages using 8mv steps.
                     86:  * To measure higher voltages the input is attenuated with (external)
                     87:  * resistors.  Negative voltages are measured using inverting op amps
                     88:  * and resistors.  So we have to convert the sensor values back to
                     89:  * real voltages by applying the appropriate resistor factor.
                     90:  */
                     91: #define FRFACT_NONE    8000
                     92: #define FRFACT(x, y)   (FRFACT_NONE * ((x) + (y)) / (y))
                     93: #define FNRFACT(x, y)  (-FRFACT_NONE * (x) / (y))
                     94:
                     95: #if defined(FINSIODEBUG)
                     96: #define DPRINTF(x)             do { printf x; } while (0)
                     97: #else
                     98: #define DPRINTF(x)
                     99: #endif
                    100:
                    101: struct finsio_softc {
                    102:        bus_space_tag_t sc_iot;
                    103:        bus_space_handle_t sc_ioh;
                    104:
                    105:        struct sysmon_envsys *sc_sme;
                    106:        envsys_data_t sc_sensor[FINSIO_MAX_SENSORS];
                    107:        struct finsio_sensor *sc_finsio_sensors;
                    108:
                    109:        u_int sc_tempsel;
                    110: };
                    111:
                    112: struct finsio_sensor {
                    113:        const char *fs_desc;
                    114:        u_int fs_type;
                    115:        uint8_t fs_aux;
                    116:        uint8_t fs_reg;
                    117:        void (*fs_refresh)(struct finsio_softc *, envsys_data_t *);
                    118:        int fs_rfact;
                    119: };
                    120:
                    121: static int     finsio_isa_match(device_t, cfdata_t, void *);
                    122: static void    finsio_isa_attach(device_t, device_t, void *);
1.3       xtraeme   123: static int     finsio_isa_detach(device_t, int);
1.1       xtraeme   124:
                    125: static void    finsio_enter(bus_space_tag_t, bus_space_handle_t);
                    126: static void    finsio_exit(bus_space_tag_t, bus_space_handle_t);
                    127: static uint8_t         finsio_readreg(bus_space_tag_t, bus_space_handle_t, int);
                    128: static void    finsio_writereg(bus_space_tag_t, bus_space_handle_t, int, int);
                    129:
                    130: static void    finsio_refresh(struct sysmon_envsys *, envsys_data_t *);
                    131: static void    finsio_refresh_volt(struct finsio_softc *, envsys_data_t *);
                    132: static void    finsio_refresh_temp(struct finsio_softc *, envsys_data_t *);
                    133: static void    finsio_refresh_fanrpm(struct finsio_softc *, envsys_data_t *);
                    134:
                    135: CFATTACH_DECL_NEW(finsio, sizeof(struct finsio_softc),
1.3       xtraeme   136:     finsio_isa_match, finsio_isa_attach, finsio_isa_detach, NULL);
1.1       xtraeme   137:
                    138: /* Sensors available in F71805/F71806 */
                    139: static struct finsio_sensor f71805_sensors[] = {
                    140:        /* Voltage */
                    141:        {
                    142:                .fs_desc = "+3.3V",
                    143:                .fs_type = ENVSYS_SVOLTS_DC,
                    144:                .fs_aux = 0,
                    145:                .fs_reg = 0x10,
                    146:                .fs_refresh = finsio_refresh_volt,
                    147:                .fs_rfact = FRFACT(100, 100)
                    148:        },
                    149:        {
                    150:                .fs_desc = "Vtt",
                    151:                .fs_type = ENVSYS_SVOLTS_DC,
                    152:                .fs_aux = 0,
                    153:                .fs_reg = 0x11,
                    154:                .fs_refresh = finsio_refresh_volt,
                    155:                .fs_rfact = FRFACT_NONE
                    156:        },
                    157:        {
                    158:                .fs_desc = "Vram",
                    159:                .fs_type = ENVSYS_SVOLTS_DC,
                    160:                .fs_aux = 0,
                    161:                .fs_reg = 0x12,
                    162:                .fs_refresh = finsio_refresh_volt,
                    163:                .fs_rfact = FRFACT(100, 100)
                    164:        },
                    165:        {
                    166:                .fs_desc = "Vchips",
                    167:                .fs_type = ENVSYS_SVOLTS_DC,
                    168:                .fs_aux = 0,
                    169:                .fs_reg = 0x13,
                    170:                .fs_refresh = finsio_refresh_volt,
                    171:                .fs_rfact = FRFACT(47, 100)
                    172:        },
                    173:        {
                    174:                .fs_desc = "+5V",
                    175:                .fs_type = ENVSYS_SVOLTS_DC,
                    176:                .fs_aux = 0,
                    177:                .fs_reg = 0x14,
                    178:                .fs_refresh = finsio_refresh_volt,
                    179:                .fs_rfact = FRFACT(200, 47)
                    180:        },
                    181:        {
                    182:                .fs_desc = "+12V",
                    183:                .fs_type = ENVSYS_SVOLTS_DC,
                    184:                .fs_aux = 0,
                    185:                .fs_reg = 0x15,
                    186:                .fs_refresh = finsio_refresh_volt,
                    187:                .fs_rfact = FRFACT(200, 20)
                    188:        },
                    189:        {
                    190:                .fs_desc = "Vcc 1.5V",
                    191:                .fs_type = ENVSYS_SVOLTS_DC,
                    192:                .fs_aux = 0,
                    193:                .fs_reg = 0x16,
                    194:                .fs_refresh = finsio_refresh_volt,
                    195:                .fs_rfact = FRFACT_NONE
                    196:        },
                    197:        {
                    198:                .fs_desc = "VCore",
                    199:                .fs_type = ENVSYS_SVOLTS_DC,
                    200:                .fs_aux = 0,
                    201:                .fs_reg = 0x17,
                    202:                .fs_refresh = finsio_refresh_volt,
                    203:                .fs_rfact = FRFACT_NONE
                    204:        },
                    205:        {
                    206:                .fs_desc = "Vsb",
                    207:                .fs_type = ENVSYS_SVOLTS_DC,
                    208:                .fs_aux = 0,
                    209:                .fs_reg = 0x18,
                    210:                .fs_refresh = finsio_refresh_volt,
                    211:                .fs_rfact = FRFACT(200, 47)
                    212:        },
                    213:        {
                    214:                .fs_desc = "Vsbint",
                    215:                .fs_type = ENVSYS_SVOLTS_DC,
                    216:                .fs_aux = 0,
                    217:                .fs_reg = 0x19,
                    218:                .fs_refresh = finsio_refresh_volt,
                    219:                .fs_rfact = FRFACT(200, 47)
                    220:        },
                    221:        {
                    222:                .fs_desc = "Vbat",
                    223:                .fs_type = ENVSYS_SVOLTS_DC,
                    224:                .fs_aux = 0,
                    225:                .fs_reg = 0x1a,
                    226:                .fs_refresh = finsio_refresh_volt,
                    227:                .fs_rfact = FRFACT(200, 47)
                    228:        },
                    229:        /* Temperature */
                    230:        {
                    231:                .fs_desc = "Temp1",
                    232:                .fs_type = ENVSYS_STEMP,
                    233:                .fs_aux = 0x01,
                    234:                .fs_reg = 0x1b,
                    235:                .fs_refresh = finsio_refresh_temp,
                    236:                .fs_rfact = 0
                    237:        },
                    238:        {
                    239:                .fs_desc = "Temp2",
                    240:                .fs_type = ENVSYS_STEMP,
                    241:                .fs_aux = 0x02,
                    242:                .fs_reg = 0x1c,
                    243:                .fs_refresh = finsio_refresh_temp,
                    244:                .fs_rfact = 0
                    245:        },
                    246:        {
                    247:                .fs_desc = "Temp3",
                    248:                .fs_type = ENVSYS_STEMP,
                    249:                .fs_aux = 0x04,
                    250:                .fs_reg = 0x1d,
                    251:                .fs_refresh = finsio_refresh_temp,
                    252:                .fs_rfact = 0
                    253:        },
                    254:        /* Fans */
                    255:        {
                    256:                .fs_desc = "Fan1",
                    257:                .fs_type = ENVSYS_SFANRPM,
                    258:                .fs_aux = 0,
                    259:                .fs_reg = 0x20,
                    260:                .fs_refresh = finsio_refresh_fanrpm,
                    261:                .fs_rfact = 0
                    262:        },
                    263:        {
                    264:                .fs_desc = "Fan2",
                    265:                .fs_type = ENVSYS_SFANRPM,
                    266:                .fs_aux = 0,
                    267:                .fs_reg = 0x22,
                    268:                .fs_refresh = finsio_refresh_fanrpm,
                    269:                .fs_rfact = 0
                    270:        },
                    271:        {
                    272:                .fs_desc = "Fan3",
                    273:                .fs_type = ENVSYS_SFANRPM,
                    274:                .fs_aux = 0,
                    275:                .fs_reg = 0x24,
                    276:                .fs_refresh = finsio_refresh_fanrpm,
                    277:                .fs_rfact = 0
                    278:        },
                    279:
                    280:        {       .fs_desc = NULL }
                    281: };
                    282:
                    283: /* Sensors available in F71862/F71882/F71883 */
                    284: static struct finsio_sensor f71883_sensors[] = {
                    285:        /* Voltage */
                    286:        {
                    287:                .fs_desc = "+3.3V",
                    288:                .fs_type = ENVSYS_SVOLTS_DC,
                    289:                .fs_aux = 0,
                    290:                .fs_reg = 0x20,
                    291:                .fs_refresh = finsio_refresh_volt,
                    292:                .fs_rfact = FRFACT(100, 100)
                    293:        },
                    294:        {
                    295:                .fs_desc = "Vcore",
                    296:                .fs_type = ENVSYS_SVOLTS_DC,
                    297:                .fs_aux = 0,
                    298:                .fs_reg = 0x21,
                    299:                .fs_refresh = finsio_refresh_volt,
                    300:                .fs_rfact = FRFACT_NONE
                    301:        },
                    302:        {
                    303:                .fs_desc = "VIN2",
                    304:                .fs_type = ENVSYS_SVOLTS_DC,
                    305:                .fs_aux = 0,
                    306:                .fs_reg = 0x22,
                    307:                .fs_refresh = finsio_refresh_volt,
                    308:                .fs_rfact = FRFACT(100, 100)
                    309:        },
                    310:        {
                    311:                .fs_desc = "VIN3",
                    312:                .fs_type = ENVSYS_SVOLTS_DC,
                    313:                .fs_aux = 0,
                    314:                .fs_reg = 0x23,
                    315:                .fs_refresh = finsio_refresh_volt,
                    316:                .fs_rfact = FRFACT(47, 100)
                    317:        },
                    318:        {
                    319:                .fs_desc = "VIN4",
                    320:                .fs_type = ENVSYS_SVOLTS_DC,
                    321:                .fs_aux = 0,
                    322:                .fs_reg = 0x24,
                    323:                .fs_refresh = finsio_refresh_volt,
                    324:                .fs_rfact = FRFACT(200, 47)
                    325:        },
                    326:        {
                    327:                .fs_desc = "VIN5",
                    328:                .fs_type = ENVSYS_SVOLTS_DC,
                    329:                .fs_aux = 0,
                    330:                .fs_reg = 0x25,
                    331:                .fs_refresh = finsio_refresh_volt,
                    332:                .fs_rfact = FRFACT(200, 20)
                    333:        },
                    334:        {
                    335:                .fs_desc = "VIN6",
                    336:                .fs_type = ENVSYS_SVOLTS_DC,
                    337:                .fs_aux = 0,
                    338:                .fs_reg = 0x26,
                    339:                .fs_refresh = finsio_refresh_volt,
                    340:                .fs_rfact = FRFACT(100, 100)
                    341:        },
                    342:        {
                    343:                .fs_desc = "VSB +3.3V",
                    344:                .fs_type = ENVSYS_SVOLTS_DC,
                    345:                .fs_aux = 0,
                    346:                .fs_reg = 0x27,
                    347:                .fs_refresh = finsio_refresh_volt,
                    348:                .fs_rfact = FRFACT(200, 47)
                    349:        },
                    350:        {
                    351:                .fs_desc = "VBAT",
                    352:                .fs_type = ENVSYS_SVOLTS_DC,
                    353:                .fs_aux = 0,
                    354:                .fs_reg = 0x28,
                    355:                .fs_refresh = finsio_refresh_volt,
                    356:                .fs_rfact = FRFACT(200, 47)
                    357:        },
                    358:        /* Temperature */
                    359:        {
                    360:                .fs_desc = "Temp1",
                    361:                .fs_type = ENVSYS_STEMP,
                    362:                .fs_aux = 0x1,
                    363:                .fs_reg = 0x72,
                    364:                .fs_refresh = finsio_refresh_temp,
                    365:                .fs_rfact = 0
                    366:        },
                    367:        {
                    368:                .fs_desc = "Temp2",
                    369:                .fs_type = ENVSYS_STEMP,
                    370:                .fs_aux = 0x2,
                    371:                .fs_reg = 0x74,
                    372:                .fs_refresh = finsio_refresh_temp,
                    373:                .fs_rfact = 0
                    374:        },
                    375:        {
                    376:                .fs_desc = "Temp3",
                    377:                .fs_type = ENVSYS_STEMP,
                    378:                .fs_aux = 0x4,
                    379:                .fs_reg = 0x76,
                    380:                .fs_refresh = finsio_refresh_temp,
                    381:                .fs_rfact = 0
                    382:        },
                    383:        /* Fan */
                    384:        {
                    385:                .fs_desc = "Fan1",
                    386:                .fs_type = ENVSYS_SFANRPM,
                    387:                .fs_aux = 0,
                    388:                .fs_reg = 0xa0,
                    389:                .fs_refresh = finsio_refresh_fanrpm,
                    390:                .fs_rfact = 0
                    391:        },
                    392:        {
                    393:                .fs_desc = "Fan2",
                    394:                .fs_type = ENVSYS_SFANRPM,
                    395:                .fs_aux = 0,
                    396:                .fs_reg = 0xb0,
                    397:                .fs_refresh = finsio_refresh_fanrpm,
                    398:                .fs_rfact = 0
                    399:        },
                    400:        {
                    401:                .fs_desc = "Fan3",
                    402:                .fs_type = ENVSYS_SFANRPM,
                    403:                .fs_aux = 0,
                    404:                .fs_reg = 0xc0,
                    405:                .fs_refresh = finsio_refresh_fanrpm,
                    406:                .fs_rfact = 0
                    407:        },
                    408:        {
                    409:                .fs_desc = "Fan4",
                    410:                .fs_type = ENVSYS_SFANRPM,
                    411:                .fs_aux = 0,
                    412:                .fs_reg = 0xd0,
                    413:                .fs_refresh = finsio_refresh_fanrpm,
                    414:                .fs_rfact = 0
                    415:        },
                    416:
                    417:        {       .fs_desc = NULL }
                    418: };
1.6       jmcneill  419:
1.1       xtraeme   420: static int
                    421: finsio_isa_match(device_t parent, cfdata_t match, void *aux)
                    422: {
                    423:        struct isa_attach_args *ia = aux;
                    424:        bus_space_handle_t ioh;
                    425:        uint16_t val;
                    426:
                    427:         /* Must supply an address */
                    428:        if (ia->ia_nio < 1)
                    429:                return 0;
                    430:
                    431:        if (ISA_DIRECT_CONFIG(ia))
                    432:                return 0;
                    433:
                    434:        if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
                    435:                return 0;
                    436:
                    437:        if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh))
                    438:                return 0;
                    439:
                    440:        finsio_enter(ia->ia_iot, ioh);
                    441:        /* Find out Manufacturer ID */
                    442:        val = finsio_readreg(ia->ia_iot, ioh, FINSIO_MANUF) << 8;
                    443:        val |= finsio_readreg(ia->ia_iot, ioh, FINSIO_MANUF + 1);
                    444:        finsio_exit(ia->ia_iot, ioh);
                    445:        bus_space_unmap(ia->ia_iot, ioh, 2);
                    446:
                    447:        if (val != FINTEK_ID)
                    448:                return 0;
                    449:
                    450:        ia->ia_nio = 1;
                    451:        ia->ia_io[0].ir_size = 2;
                    452:        ia->ia_niomem = 0;
                    453:        ia->ia_nirq = 0;
                    454:        ia->ia_ndrq = 0;
                    455:
                    456:        return 1;
                    457: }
                    458:
                    459: static void
                    460: finsio_isa_attach(device_t parent, device_t self, void *aux)
                    461: {
                    462:        struct finsio_softc *sc = device_private(self);
                    463:        struct isa_attach_args *ia = aux;
                    464:        bus_space_handle_t ioh;
                    465:        uint16_t hwmon_baddr, chipid, cr;
                    466:        int i, rv = 0;
                    467:
                    468:        aprint_naive("\n");
                    469:
                    470:        sc->sc_iot = ia->ia_iot;
                    471:
                    472:        /* Map Super I/O configuration space */
                    473:        if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, 2, 0, &ioh)) {
                    474:                aprint_error(": can't map configuration I/O space\n");
                    475:                return;
                    476:        }
                    477:
                    478:        finsio_enter(sc->sc_iot, ioh);
                    479:        /* Get the Chip ID */
                    480:        chipid = finsio_readreg(sc->sc_iot, ioh, FINSIO_CHIP) << 8;
                    481:        chipid |= finsio_readreg(sc->sc_iot, ioh, FINSIO_CHIP + 1);
                    482:        /*
                    483:         * Select the Hardware Monitor LDN to find out the I/O
                    484:         * address space.
                    485:         */
                    486:        finsio_writereg(sc->sc_iot, ioh, FINSIO_FUNC_SEL, FINSIO_FUNC_HWMON);
                    487:        hwmon_baddr = finsio_readreg(sc->sc_iot, ioh, FINSIO_SENSADDR) << 8;
                    488:        hwmon_baddr |= finsio_readreg(sc->sc_iot, ioh, FINSIO_SENSADDR + 1);
                    489:        finsio_exit(sc->sc_iot, ioh);
                    490:        bus_space_unmap(sc->sc_iot, ioh, 2);
                    491:
1.7       jakllsch  492:        /*
                    493:         * The address decoder ignores the bottom 3 bits, so do we.
                    494:         */
                    495:        hwmon_baddr &= ~FINSIO_DECODE_MASK;
                    496:
1.1       xtraeme   497:        switch (chipid) {
                    498:        case FINSIO_IDF71805:
                    499:                sc->sc_finsio_sensors = f71805_sensors;
                    500:                aprint_normal(": Fintek F71805 Super I/O\n");
                    501:                break;
                    502:        case FINSIO_IDF71806:
                    503:                sc->sc_finsio_sensors = f71805_sensors;
                    504:                aprint_normal(": Fintek F71806/F71872 Super I/O\n");
                    505:                break;
                    506:        case FINSIO_IDF71862:
                    507:                sc->sc_finsio_sensors = f71883_sensors;
                    508:                aprint_normal(": Fintek F71862 Super I/O\n");
                    509:                break;
                    510:        case FINSIO_IDF71883:
                    511:                sc->sc_finsio_sensors = f71883_sensors;
                    512:                aprint_normal(": Fintek F71882/F71883 Super I/O\n");
                    513:                break;
1.6       jmcneill  514:        case FINSIO_IDF8000:
                    515:                sc->sc_finsio_sensors = f71883_sensors;
                    516:                aprint_normal(": ASUS F8000 Super I/O\n");
                    517:                break;
1.1       xtraeme   518:        default:
                    519:                /*
                    520:                 * Unknown Chip ID, assume the same register layout
                    521:                 * than F71805 for now.
                    522:                 */
                    523:                sc->sc_finsio_sensors = f71805_sensors;
                    524:                aprint_normal(": Fintek Super I/O (unknown chip ID %x)\n",
                    525:                    chipid);
                    526:                break;
                    527:        }
                    528:
                    529:        /* Map Hardware Monitor I/O space */
1.7       jakllsch  530:        if (bus_space_map(sc->sc_iot, hwmon_baddr, FINSIO_DECODE_SIZE,
                    531:            0, &sc->sc_ioh)) {
1.1       xtraeme   532:                aprint_error(": can't map hwmon I/O space\n");
                    533:                return;
                    534:        }
                    535:
                    536:        /*
                    537:         * Enable Hardware monitoring for fan/temperature and
                    538:         * voltage sensors.
                    539:         */
                    540:        cr = finsio_readreg(sc->sc_iot, sc->sc_ioh, FINSIO_HWMON_CONF);
                    541:        finsio_writereg(sc->sc_iot, sc->sc_ioh, FINSIO_HWMON_CONF, cr | 0x3);
                    542:
                    543:        /* Find out the temperature mode */
                    544:        sc->sc_tempsel = finsio_readreg(sc->sc_iot, sc->sc_ioh, FINSIO_TMODE);
                    545:
                    546:        /*
                    547:         * Initialize and attach sensors with sysmon_envsys(9).
                    548:         */
                    549:        sc->sc_sme = sysmon_envsys_create();
                    550:        for (i = 0; sc->sc_finsio_sensors[i].fs_desc; i++) {
1.5       pgoyette  551:                sc->sc_sensor[i].state = ENVSYS_SINVALID;
1.1       xtraeme   552:                sc->sc_sensor[i].units = sc->sc_finsio_sensors[i].fs_type;
1.4       xtraeme   553:                if (sc->sc_sensor[i].units == ENVSYS_SVOLTS_DC)
                    554:                        sc->sc_sensor[i].flags = ENVSYS_FCHANGERFACT;
1.1       xtraeme   555:                strlcpy(sc->sc_sensor[i].desc, sc->sc_finsio_sensors[i].fs_desc,
                    556:                        sizeof(sc->sc_sensor[i].desc));
                    557:                if (sysmon_envsys_sensor_attach(sc->sc_sme,
                    558:                                                &sc->sc_sensor[i]))
                    559:                        goto fail;
                    560:        }
                    561:
                    562:        sc->sc_sme->sme_name = device_xname(self);
                    563:        sc->sc_sme->sme_cookie = sc;
                    564:        sc->sc_sme->sme_refresh = finsio_refresh;
                    565:        if ((rv = sysmon_envsys_register(sc->sc_sme))) {
                    566:                aprint_error(": unable to register with sysmon (%d)\n", rv);
                    567:                goto fail;
                    568:        }
                    569:
                    570:        aprint_normal_dev(self,
                    571:            "Hardware Monitor registers at 0x%x\n", hwmon_baddr);
                    572:        return;
                    573:
                    574: fail:
                    575:        sysmon_envsys_destroy(sc->sc_sme);
1.7       jakllsch  576:        bus_space_unmap(sc->sc_iot, sc->sc_ioh, FINSIO_DECODE_SIZE);
1.1       xtraeme   577: }
                    578:
1.3       xtraeme   579: static int
                    580: finsio_isa_detach(device_t self, int flags)
                    581: {
                    582:        struct finsio_softc *sc = device_private(self);
                    583:
                    584:        sysmon_envsys_unregister(sc->sc_sme);
1.7       jakllsch  585:        bus_space_unmap(sc->sc_iot, sc->sc_ioh, FINSIO_DECODE_SIZE);
1.3       xtraeme   586:        return 0;
                    587: }
                    588:
1.1       xtraeme   589: /* Enter Super I/O configuration mode */
                    590: static void
                    591: finsio_enter(bus_space_tag_t iot, bus_space_handle_t ioh)
                    592: {
                    593:        bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_UNLOCK);
                    594:        bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_UNLOCK);
                    595: }
                    596:
                    597: /* Exit Super I/O configuration mode */
                    598: static void
                    599: finsio_exit(bus_space_tag_t iot, bus_space_handle_t ioh)
                    600: {
                    601:        bus_space_write_1(iot, ioh, FINSIO_ADDR, FINSIO_LOCK);
                    602: }
                    603:
                    604: static uint8_t
                    605: finsio_readreg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg)
                    606: {
                    607:        bus_space_write_1(iot, ioh, FINSIO_ADDR, reg);
                    608:        return bus_space_read_1(iot, ioh, FINSIO_DATA);
                    609: }
                    610:
                    611: static void
                    612: finsio_writereg(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, int val)
                    613: {
                    614:        bus_space_write_1(iot, ioh, FINSIO_ADDR, reg);
                    615:        bus_space_write_1(iot, ioh, FINSIO_DATA, val);
                    616: }
                    617:
                    618: static void
                    619: finsio_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
                    620: {
                    621:        struct finsio_softc *sc = sme->sme_cookie;
                    622:        int i = edata->sensor;
                    623:
                    624:        sc->sc_finsio_sensors[i].fs_refresh(sc, edata);
                    625: }
                    626:
                    627: static void
                    628: finsio_refresh_volt(struct finsio_softc *sc, envsys_data_t *edata)
                    629: {
                    630:        struct finsio_sensor *fs = &sc->sc_finsio_sensors[edata->sensor];
                    631:        int data;
                    632:
                    633:        data = finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg);
                    634:        DPRINTF(("%s: data 0x%x\n", __func__, data));
                    635:
                    636:        if (data == 0xff || data == 0)
                    637:                edata->state = ENVSYS_SINVALID;
                    638:        else {
                    639:                edata->state = ENVSYS_SVALID;
1.4       xtraeme   640:                if (edata->rfact)
                    641:                        edata->value_cur = data * edata->rfact;
                    642:                else
                    643:                        edata->value_cur = data * fs->fs_rfact;
1.1       xtraeme   644:        }
                    645: }
                    646:
                    647: /* The BIOS seems to add a fudge factor to the CPU temp of +5C */
                    648: static void
                    649: finsio_refresh_temp(struct finsio_softc *sc, envsys_data_t *edata)
                    650: {
                    651:        struct finsio_sensor *fs = &sc->sc_finsio_sensors[edata->sensor];
                    652:        u_int data;
                    653:        u_int llmax;
                    654:
                    655:        /*
                    656:         * The data sheet says that the range of the temperature
                    657:         * sensor is between 0 and 127 or 140 degrees C depending on
                    658:         * what kind of sensor is used.
                    659:         * A disconnected sensor seems to read over 110 or so.
                    660:         */
                    661:        data = finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg) & 0xFF;
                    662:        DPRINTF(("%s: data 0x%x\n", __func__, data));
                    663:
                    664:        llmax = (sc->sc_tempsel & fs->fs_aux) ? 111 : 128;
                    665:        if (data == 0 || data >= llmax)         /* disconnected? */
                    666:                edata->state = ENVSYS_SINVALID;
                    667:        else {
                    668:                edata->state = ENVSYS_SVALID;
                    669:                edata->value_cur = data * 1000000 + 273150000;
                    670:        }
                    671: }
                    672:
                    673: /* fan speed appears to be a 12-bit number */
                    674: static void
                    675: finsio_refresh_fanrpm(struct finsio_softc *sc, envsys_data_t *edata)
                    676: {
                    677:        struct finsio_sensor *fs = &sc->sc_finsio_sensors[edata->sensor];
                    678:        int data;
                    679:
                    680:        data = finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg) << 8;
                    681:        data |= finsio_readreg(sc->sc_iot, sc->sc_ioh, fs->fs_reg + 1);
                    682:        DPRINTF(("%s: data 0x%x\n", __func__, data));
                    683:
                    684:        if (data >= 0xfff)
                    685:                edata->state = ENVSYS_SINVALID;
                    686:        else {
                    687:                edata->value_cur = 1500000 / data;
                    688:                edata->state = ENVSYS_SVALID;
                    689:        }
                    690: }
1.6       jmcneill  691:
1.7.12.1! jdolecek  692: MODULE(MODULE_CLASS_DRIVER, finsio, "sysmon_envsys");
1.6       jmcneill  693:
                    694: #ifdef _MODULE
                    695: #include "ioconf.c"
                    696: #endif
                    697:
                    698: static int
                    699: finsio_modcmd(modcmd_t cmd, void *opaque)
                    700: {
                    701:        int error = 0;
                    702:
                    703:        switch (cmd) {
                    704:        case MODULE_CMD_INIT:
                    705: #ifdef _MODULE
                    706:                error = config_init_component(cfdriver_ioconf_finsio,
                    707:                    cfattach_ioconf_finsio, cfdata_ioconf_finsio);
                    708: #endif
                    709:                return error;
                    710:        case MODULE_CMD_FINI:
                    711: #ifdef _MODULE
                    712:                error = config_fini_component(cfdriver_ioconf_finsio,
                    713:                    cfattach_ioconf_finsio, cfdata_ioconf_finsio);
                    714: #endif
                    715:                return error;
                    716:        default:
                    717:                return ENOTTY;
                    718:        }
                    719: }

CVSweb <webmaster@jp.NetBSD.org>