[BACK]Return to adm1031.c CVS log [TXT][DIR] Up to [local] / sys / dev / i2c

Annotation of sys/dev/i2c/adm1031.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: adm1031.c,v 1.8 2007/06/24 05:34:35 dlg Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2005 Theo de Raadt
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: #include <sys/param.h>
                     20: #include <sys/systm.h>
                     21: #include <sys/device.h>
                     22: #include <sys/sensors.h>
                     23:
                     24: #include <dev/i2c/i2cvar.h>
                     25:
                     26: /* adm 1031 registers */
                     27: #define ADM1031_INT_TEMP       0x0a
                     28: #define ADM1031_EXT_TEMP       0x0b
                     29: #define ADM1031_EXT2_TEMP      0x0c
                     30: #define ADM1031_FAN            0x08
                     31: #define ADM1031_FANC           0x20
                     32: #define ADM1031_FAN2           0x09
                     33: #define ADM1031_FAN2C          0x21
                     34: #define  ADM1024_FANC_VAL(x)   (x >> 6)
                     35:
                     36: /* Sensors */
                     37: #define ADMTT_INT              0
                     38: #define ADMTT_EXT              1
                     39: #define ADMTT_EXT2             2
                     40: #define ADMTT_FAN              3
                     41: #define ADMTT_FAN2             4
                     42: #define ADMTT_NUM_SENSORS      5
                     43:
                     44: struct admtt_softc {
                     45:        struct device   sc_dev;
                     46:        i2c_tag_t       sc_tag;
                     47:        i2c_addr_t      sc_addr;
                     48:        int             sc_fanmul;
                     49:
                     50:        struct ksensor  sc_sensor[ADMTT_NUM_SENSORS];
                     51:        struct ksensordev sc_sensordev;
                     52: };
                     53:
                     54: int    admtt_match(struct device *, void *, void *);
                     55: void   admtt_attach(struct device *, struct device *, void *);
                     56: void   admtt_refresh(void *);
                     57:
                     58: struct cfattach admtt_ca = {
                     59:        sizeof(struct admtt_softc), admtt_match, admtt_attach
                     60: };
                     61:
                     62: struct cfdriver admtt_cd = {
                     63:        NULL, "admtt", DV_DULL
                     64: };
                     65:
                     66: int
                     67: admtt_match(struct device *parent, void *match, void *aux)
                     68: {
                     69:        struct i2c_attach_args *ia = aux;
                     70:
                     71:        if (strcmp(ia->ia_name, "adm1031") == 0)
                     72:                return (1);
                     73:        return (0);
                     74: }
                     75:
                     76: void
                     77: admtt_attach(struct device *parent, struct device *self, void *aux)
                     78: {
                     79:        struct admtt_softc *sc = (struct admtt_softc *)self;
                     80:        struct i2c_attach_args *ia = aux;
                     81:        u_int8_t cmd, data;
                     82:        int i;
                     83:
                     84:        sc->sc_tag = ia->ia_tag;
                     85:        sc->sc_addr = ia->ia_addr;
                     86:
                     87:        cmd = ADM1031_FANC;
                     88:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                     89:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
                     90:                printf(", unable to read fan setting\n");
                     91:                return;
                     92:        }
                     93:        sc->sc_fanmul = 11250/8 * (1 << ADM1024_FANC_VAL(data)) * 60;
                     94:
                     95:        /* Initialize sensor data. */
                     96:        strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
                     97:            sizeof(sc->sc_sensordev.xname));
                     98:
                     99:        sc->sc_sensor[ADMTT_INT].type = SENSOR_TEMP;
                    100:        strlcpy(sc->sc_sensor[ADMTT_INT].desc, "Internal",
                    101:            sizeof(sc->sc_sensor[ADMTT_INT].desc));
                    102:
                    103:        sc->sc_sensor[ADMTT_EXT].type = SENSOR_TEMP;
                    104:        strlcpy(sc->sc_sensor[ADMTT_EXT].desc, "External",
                    105:            sizeof(sc->sc_sensor[ADMTT_EXT].desc));
                    106:
                    107:        sc->sc_sensor[ADMTT_EXT2].type = SENSOR_TEMP;
                    108:        strlcpy(sc->sc_sensor[ADMTT_EXT2].desc, "External",
                    109:            sizeof(sc->sc_sensor[ADMTT_EXT2].desc));
                    110:
                    111:        sc->sc_sensor[ADMTT_FAN].type = SENSOR_FANRPM;
                    112:
                    113:        sc->sc_sensor[ADMTT_FAN2].type = SENSOR_FANRPM;
                    114:
                    115:        if (sensor_task_register(sc, admtt_refresh, 5) == NULL) {
                    116:                printf(", unable to register update task\n");
                    117:                return;
                    118:        }
                    119:
                    120:        for (i = 0; i < ADMTT_NUM_SENSORS; i++)
                    121:                sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
                    122:        sensordev_install(&sc->sc_sensordev);
                    123:
                    124:        printf("\n");
                    125: }
                    126:
                    127: void
                    128: admtt_refresh(void *arg)
                    129: {
                    130:        struct admtt_softc *sc = arg;
                    131:        u_int8_t cmd, data;
                    132:
                    133:        iic_acquire_bus(sc->sc_tag, 0);
                    134:
                    135:        cmd = ADM1031_INT_TEMP;
                    136:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    137:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    138:                sc->sc_sensor[ADMTT_INT].value = 273150000 + 1000000 * data;
                    139:
                    140:        cmd = ADM1031_EXT_TEMP;
                    141:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    142:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    143:                sc->sc_sensor[ADMTT_EXT].value = 273150000 + 1000000 * data;
                    144:
                    145:        cmd = ADM1031_EXT2_TEMP;
                    146:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    147:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    148:                sc->sc_sensor[ADMTT_EXT2].value = 273150000 + 1000000 * data;
                    149:
                    150:        cmd = ADM1031_FAN;
                    151:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    152:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
                    153:                if (data == 0)
                    154:                        sc->sc_sensor[ADMTT_FAN].flags |= SENSOR_FINVALID;
                    155:                else {
                    156:                        sc->sc_sensor[ADMTT_FAN].value =
                    157:                            sc->sc_fanmul / (2 * (int)data);
                    158:                        sc->sc_sensor[ADMTT_FAN].flags &= ~SENSOR_FINVALID;
                    159:                }
                    160:        }
                    161:
                    162:        cmd = ADM1031_FAN2;
                    163:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    164:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
                    165:                if (data == 0)
                    166:                        sc->sc_sensor[ADMTT_FAN2].flags |= SENSOR_FINVALID;
                    167:                else {
                    168:                        sc->sc_sensor[ADMTT_FAN2].value =
                    169:                            sc->sc_fanmul / (2 * (int)data);
                    170:                        sc->sc_sensor[ADMTT_FAN2].flags &= ~SENSOR_FINVALID;
                    171:                }
                    172:        }
                    173:
                    174:        iic_release_bus(sc->sc_tag, 0);
                    175: }

CVSweb