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

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

1.1       nbrk        1: /*     $OpenBSD: adm1025.c,v 1.25 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 1025 registers */
                     27: #define ADM1025_V2_5           0x20
                     28: #define ADM1025_Vccp           0x21
                     29: #define ADM1025_V3_3           0x22
                     30: #define ADM1025_V5             0x23
                     31: #define ADM1025_V12            0x24
                     32: #define ADM1025_Vcc            0x25
                     33: #define ADM1025_EXT_TEMP       0x26
                     34: #define ADM1025_INT_TEMP       0x27
                     35: #define ADM1025_STATUS2                0x42
                     36: #define  ADM1025_STATUS2_EXT   0x40
                     37: #define ADM1025_COMPANY                0x3e    /* contains 0x41 */
                     38: #define ADM1025_STEPPING       0x3f    /* contains 0x2? */
                     39: #define ADM1025_CONFIG         0x40
                     40: #define  ADM1025_CONFIG_START  0x01
                     41: #define SMSC47M192_V1_5                0x50
                     42: #define SMSC47M192_V1_8                0x51
                     43: #define SMSC47M192_TEMP2       0x52
                     44:
                     45: /* Sensors */
                     46: #define ADMTM_INT              0
                     47: #define ADMTM_EXT              1
                     48: #define ADMTM_V2_5             2
                     49: #define ADMTM_Vccp             3
                     50: #define ADMTM_V3_3             4
                     51: #define ADMTM_V5               5
                     52: #define ADMTM_V12              6
                     53: #define ADMTM_Vcc              7
                     54: #define ADMTM_NUM_SENSORS      8
                     55: #define SMSC_V1_5              8
                     56: #define SMSC_V1_8              9
                     57: #define SMSC_TEMP2             10
                     58: #define SMSC_NUM_SENSORS       3
                     59: struct admtm_softc {
                     60:        struct device   sc_dev;
                     61:        i2c_tag_t       sc_tag;
                     62:        i2c_addr_t      sc_addr;
                     63:
                     64:        struct ksensor  sc_sensor[ADMTM_NUM_SENSORS + SMSC_NUM_SENSORS];
                     65:        struct ksensordev sc_sensordev;
                     66:        int             sc_nsensors;
                     67:        int             sc_model;
                     68: };
                     69:
                     70: int    admtm_match(struct device *, void *, void *);
                     71: void   admtm_attach(struct device *, struct device *, void *);
                     72: void   admtm_refresh(void *);
                     73:
                     74: struct cfattach admtm_ca = {
                     75:        sizeof(struct admtm_softc), admtm_match, admtm_attach
                     76: };
                     77:
                     78: struct cfdriver admtm_cd = {
                     79:        NULL, "admtm", DV_DULL
                     80: };
                     81:
                     82: int
                     83: admtm_match(struct device *parent, void *match, void *aux)
                     84: {
                     85:        struct i2c_attach_args *ia = aux;
                     86:
                     87:        if (strcmp(ia->ia_name, "adm1025") == 0 ||
                     88:            strcmp(ia->ia_name, "47m192") == 0 ||
                     89:            strcmp(ia->ia_name, "ne1619") == 0)
                     90:                return (1);
                     91:        return (0);
                     92: }
                     93:
                     94: void
                     95: admtm_attach(struct device *parent, struct device *self, void *aux)
                     96: {
                     97:        struct admtm_softc *sc = (struct admtm_softc *)self;
                     98:        struct i2c_attach_args *ia = aux;
                     99:        u_int8_t cmd, data, data2;
                    100:        int i;
                    101:
                    102:        sc->sc_tag = ia->ia_tag;
                    103:        sc->sc_addr = ia->ia_addr;
                    104:
                    105:        printf(": %s", ia->ia_name);
                    106:
                    107:        sc->sc_nsensors = ADMTM_NUM_SENSORS;
                    108:        sc->sc_model = 1025;
                    109:        if (strcmp(ia->ia_name, "47m192") == 0) {
                    110:                sc->sc_nsensors += SMSC_NUM_SENSORS;
                    111:                sc->sc_model = 192;
                    112:        }
                    113:
                    114:        iic_acquire_bus(sc->sc_tag, 0);
                    115:        cmd = ADM1025_CONFIG;
                    116:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    117:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
                    118:                iic_release_bus(sc->sc_tag, 0);
                    119:                printf(", cannot get control register\n");
                    120:                return;
                    121:        }
                    122:
                    123:        data2 = data | ADM1025_CONFIG_START;
                    124:        if (data != data2) {
                    125:                if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
                    126:                    sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
                    127:                        iic_release_bus(sc->sc_tag, 0);
                    128:                        printf(", cannot set control register\n");
                    129:                        return;
                    130:                }
                    131:        }
                    132:        iic_release_bus(sc->sc_tag, 0);
                    133:
                    134:        /* Initialize sensor data. */
                    135:        strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
                    136:            sizeof(sc->sc_sensordev.xname));
                    137:
                    138:        sc->sc_sensor[ADMTM_INT].type = SENSOR_TEMP;
                    139:        strlcpy(sc->sc_sensor[ADMTM_INT].desc, "Internal",
                    140:            sizeof(sc->sc_sensor[ADMTM_INT].desc));
                    141:
                    142:        sc->sc_sensor[ADMTM_EXT].type = SENSOR_TEMP;
                    143:        strlcpy(sc->sc_sensor[ADMTM_EXT].desc, "External",
                    144:            sizeof(sc->sc_sensor[ADMTM_EXT].desc));
                    145:
                    146:        sc->sc_sensor[ADMTM_V2_5].type = SENSOR_VOLTS_DC;
                    147:        strlcpy(sc->sc_sensor[ADMTM_V2_5].desc, "2.5 V",
                    148:            sizeof(sc->sc_sensor[ADMTM_V2_5].desc));
                    149:
                    150:        sc->sc_sensor[ADMTM_Vccp].type = SENSOR_VOLTS_DC;
                    151:        strlcpy(sc->sc_sensor[ADMTM_Vccp].desc, "Vccp",
                    152:            sizeof(sc->sc_sensor[ADMTM_Vccp].desc));
                    153:
                    154:        sc->sc_sensor[ADMTM_V3_3].type = SENSOR_VOLTS_DC;
                    155:        strlcpy(sc->sc_sensor[ADMTM_V3_3].desc, "3.3 V",
                    156:            sizeof(sc->sc_sensor[ADMTM_V3_3].desc));
                    157:
                    158:        sc->sc_sensor[ADMTM_V5].type = SENSOR_VOLTS_DC;
                    159:        strlcpy(sc->sc_sensor[ADMTM_V5].desc, "5 V",
                    160:            sizeof(sc->sc_sensor[ADMTM_V5].desc));
                    161:
                    162:        sc->sc_sensor[ADMTM_V12].type = SENSOR_VOLTS_DC;
                    163:        strlcpy(sc->sc_sensor[ADMTM_V12].desc, "12 V",
                    164:            sizeof(sc->sc_sensor[ADMTM_V12].desc));
                    165:
                    166:        sc->sc_sensor[ADMTM_Vcc].type = SENSOR_VOLTS_DC;
                    167:        strlcpy(sc->sc_sensor[ADMTM_Vcc].desc, "Vcc",
                    168:            sizeof(sc->sc_sensor[ADMTM_Vcc].desc));
                    169:
                    170:        sc->sc_sensor[SMSC_V1_5].type = SENSOR_VOLTS_DC;
                    171:        strlcpy(sc->sc_sensor[SMSC_V1_5].desc, "1.5 V",
                    172:            sizeof(sc->sc_sensor[SMSC_V1_5].desc));
                    173:
                    174:        sc->sc_sensor[SMSC_V1_8].type = SENSOR_VOLTS_DC;
                    175:        strlcpy(sc->sc_sensor[SMSC_V1_8].desc, "1.8 V",
                    176:            sizeof(sc->sc_sensor[SMSC_V1_8].desc));
                    177:
                    178:        sc->sc_sensor[SMSC_TEMP2].type = SENSOR_TEMP;
                    179:        strlcpy(sc->sc_sensor[SMSC_TEMP2].desc, "External",
                    180:            sizeof(sc->sc_sensor[SMSC_TEMP2].desc));
                    181:
                    182:        if (sensor_task_register(sc, admtm_refresh, 5) == NULL) {
                    183:                printf(", unable to register update task\n");
                    184:                return;
                    185:        }
                    186:
                    187:        for (i = 0; i < sc->sc_nsensors; i++)
                    188:                sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
                    189:        sensordev_install(&sc->sc_sensordev);
                    190:
                    191:        printf("\n");
                    192: }
                    193:
                    194: void
                    195: admtm_refresh(void *arg)
                    196: {
                    197:        struct admtm_softc *sc = arg;
                    198:        u_int8_t cmd, data;
                    199:        int8_t sdata;
                    200:
                    201:        iic_acquire_bus(sc->sc_tag, 0);
                    202:
                    203:        cmd = ADM1025_INT_TEMP;
                    204:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    205:            sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0)
                    206:                sc->sc_sensor[ADMTM_INT].value = 273150000 + 1000000 * sdata;
                    207:
                    208:        cmd = ADM1025_EXT_TEMP;
                    209:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    210:            sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0)
                    211:                sc->sc_sensor[ADMTM_EXT].value = 273150000 + 1000000 * sdata;
                    212:
                    213:        cmd = ADM1025_STATUS2;
                    214:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    215:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
                    216:                if (data & ADM1025_STATUS2_EXT)
                    217:                        sc->sc_sensor[ADMTM_EXT].flags |= SENSOR_FINVALID;
                    218:                else
                    219:                        sc->sc_sensor[ADMTM_EXT].flags &= ~SENSOR_FINVALID;
                    220:        }
                    221:
                    222:        cmd = ADM1025_V2_5;
                    223:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    224:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    225:                sc->sc_sensor[ADMTM_V2_5].value = 2500000 * data / 192;
                    226:
                    227:        cmd = ADM1025_Vccp;
                    228:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    229:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    230:                sc->sc_sensor[ADMTM_Vcc].value = 2249000 * data / 192;
                    231:
                    232:        cmd = ADM1025_V3_3;
                    233:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    234:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    235:                sc->sc_sensor[ADMTM_V3_3].value = 3300000 * data / 192;
                    236:
                    237:        cmd = ADM1025_V5;
                    238:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    239:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    240:                sc->sc_sensor[ADMTM_V5].value = 5000000 * data / 192;
                    241:
                    242:        cmd = ADM1025_V12;
                    243:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    244:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    245:                sc->sc_sensor[ADMTM_V12].value = 12000000 * data / 192;
                    246:
                    247:        cmd = ADM1025_Vcc;
                    248:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    249:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    250:                sc->sc_sensor[ADMTM_Vcc].value = 3300000 * data / 192;
                    251:
                    252:        if (sc->sc_model == 192) {
                    253:                cmd = SMSC47M192_V1_5;
                    254:                if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    255:                    sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    256:                        sc->sc_sensor[SMSC_V1_5].value = 1500000 * data / 192;
                    257:
                    258:                cmd = SMSC47M192_V1_8;
                    259:                if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    260:                    sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
                    261:                        sc->sc_sensor[SMSC_V1_8].value = 1800000 * data / 192;
                    262:
                    263:                cmd = SMSC47M192_TEMP2;
                    264:                if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    265:                    sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata,
                    266:                    0) == 0)
                    267:                        sc->sc_sensor[SMSC_TEMP2].value = 273150000 + 1000000 * sdata;
                    268:
                    269:        }
                    270:
                    271:        iic_release_bus(sc->sc_tag, 0);
                    272: }

CVSweb