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

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

1.1       nbrk        1: /*     $OpenBSD: ad741x.c,v 1.12 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: /* AD741x registers */
                     27: #define AD741X_TEMP    0x00
                     28: #define AD741X_CONFIG  0x01
                     29: #define AD741X_THYST   0x02
                     30: #define AD741X_TOTI    0x03
                     31: #define AD741X_ADC     0x04
                     32: #define AD741X_CONFIG2 0x05
                     33:
                     34: #define AD741X_CONFMASK        0xe0
                     35:
                     36: /* Sensors */
                     37: #define ADC_TEMP               0
                     38: #define ADC_ADC0               1
                     39: #define ADC_ADC1               2
                     40: #define ADC_ADC2               3
                     41: #define ADC_ADC3               4
                     42: #define ADC_MAX_SENSORS                5
                     43:
                     44: struct adc_softc {
                     45:        struct device   sc_dev;
                     46:        i2c_tag_t       sc_tag;
                     47:        i2c_addr_t      sc_addr;
                     48:        int             sc_chip;
                     49:        u_int8_t        sc_config;
                     50:
                     51:        struct ksensor sc_sensor[ADC_MAX_SENSORS];
                     52:        struct ksensordev sc_sensordev;
                     53: };
                     54:
                     55: int    adc_match(struct device *, void *, void *);
                     56: void   adc_attach(struct device *, struct device *, void *);
                     57: int    adc_check(struct i2c_attach_args *, u_int8_t *, u_int8_t *);
                     58: void   adc_refresh(void *);
                     59:
                     60: struct cfattach adc_ca = {
                     61:        sizeof(struct adc_softc), adc_match, adc_attach
                     62: };
                     63:
                     64: struct cfdriver adc_cd = {
                     65:        NULL, "adc", DV_DULL
                     66: };
                     67:
                     68: int
                     69: adc_match(struct device *parent, void *match, void *aux)
                     70: {
                     71:        struct i2c_attach_args *ia = aux;
                     72:
                     73:        if (strcmp(ia->ia_name, "ad7417") == 0 ||
                     74:            strcmp(ia->ia_name, "ad7418") == 0)
                     75:                return (1);
                     76:        return (0);
                     77: }
                     78:
                     79: void
                     80: adc_attach(struct device *parent, struct device *self, void *aux)
                     81: {
                     82:        struct adc_softc *sc = (struct adc_softc *)self;
                     83:        struct i2c_attach_args *ia = aux;
                     84:        u_int8_t cmd, data;
                     85:        int nsens = 0, i;
                     86:
                     87:        sc->sc_tag = ia->ia_tag;
                     88:        sc->sc_addr = ia->ia_addr;
                     89:
                     90:        printf(": %s", ia->ia_name);
                     91:
                     92:        sc->sc_chip = 0;
                     93:        if (strcmp(ia->ia_name, "ad7417") == 0)
                     94:                sc->sc_chip = 7417;
                     95:        if (strcmp(ia->ia_name, "ad7418") == 0)
                     96:                sc->sc_chip = 7418;
                     97:
                     98:        if (sc->sc_chip != 0) {
                     99:                cmd = AD741X_CONFIG2;
                    100:                data = 0;
                    101:                if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
                    102:                    sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
                    103:                        printf(", config2 reset failed\n");
                    104:                        return;
                    105:                }
                    106:        }
                    107:
                    108:        cmd = AD741X_CONFIG;
                    109:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    110:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
                    111:                printf(", config reset failed\n");
                    112:                return;
                    113:        }
                    114:        data &= 0xfe;
                    115:        if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
                    116:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
                    117:                printf(", config reset failed\n");
                    118:                return;
                    119:        }
                    120:        sc->sc_config = data;
                    121:
                    122:        /* Initialize sensor data. */
                    123:        strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
                    124:            sizeof(sc->sc_sensordev.xname));
                    125:
                    126:        sc->sc_sensor[ADC_TEMP].type = SENSOR_TEMP;
                    127:        strlcpy(sc->sc_sensor[ADC_TEMP].desc, "Internal",
                    128:            sizeof(sc->sc_sensor[ADC_TEMP].desc));
                    129:        nsens = 1;
                    130:
                    131:        if (sc->sc_chip == 7417 || sc->sc_chip == 7418) {
                    132:                sc->sc_sensor[ADC_ADC0].type = SENSOR_INTEGER;
                    133:                nsens++;
                    134:        }
                    135:        if (sc->sc_chip == 7417 || sc->sc_chip == 7418) {
                    136:                sc->sc_sensor[ADC_ADC1].type = SENSOR_INTEGER;
                    137:                sc->sc_sensor[ADC_ADC2].type = SENSOR_INTEGER;
                    138:                sc->sc_sensor[ADC_ADC3].type = SENSOR_INTEGER;
                    139:                nsens += 3;
                    140:        }
                    141:
                    142:        if (sensor_task_register(sc, adc_refresh, 5) == NULL) {
                    143:                printf(", unable to register update task\n");
                    144:                return;
                    145:        }
                    146:
                    147:        sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[0]);
                    148:        if (sc->sc_chip == 7417 || sc->sc_chip == 7418)
                    149:                sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[1]);
                    150:        if (sc->sc_chip == 7417)
                    151:                for (i = 2; i < nsens; i++)
                    152:                        sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
                    153:        sensordev_install(&sc->sc_sensordev);
                    154:
                    155:        printf("\n");
                    156: }
                    157:
                    158: void
                    159: adc_refresh(void *arg)
                    160: {
                    161:        struct adc_softc *sc = arg;
                    162:        u_int8_t cmd, data[2], reg;
                    163:        int i;
                    164:
                    165:        iic_acquire_bus(sc->sc_tag, 0);
                    166:
                    167:        reg = (sc->sc_config & AD741X_CONFMASK) | (0 << 5);
                    168:        if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
                    169:            sc->sc_addr, &cmd, sizeof cmd, &reg, sizeof reg, 0))
                    170:                goto done;
                    171:        delay(1000);
                    172:        cmd = AD741X_TEMP;
                    173:        if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    174:            sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
                    175:                goto done;
                    176:        sc->sc_sensor[ADC_TEMP].value = 273150000 +
                    177:            ((data[0] << 8 | data[1]) >> 6) * 250000;
                    178:
                    179:        if (sc->sc_chip == 0)
                    180:                goto done;
                    181:
                    182:        if (sc->sc_chip == 7418) {
                    183:                reg = (reg & AD741X_CONFMASK) | (4 << 5);
                    184:                if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
                    185:                    sc->sc_addr, &cmd, sizeof cmd, &reg, sizeof reg, 0))
                    186:                        goto done;
                    187:                delay(1000);
                    188:                cmd = AD741X_ADC;
                    189:                if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    190:                    sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
                    191:                        goto done;
                    192:                sc->sc_sensor[ADC_ADC0].value =
                    193:                    (data[0] << 8 | data[1]) >> 6;
                    194:                goto done;
                    195:        }
                    196:
                    197:        for (i = 0; i < 4; i++) {
                    198:                reg = (reg & AD741X_CONFMASK) | (i << 5);
                    199:                if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
                    200:                    sc->sc_addr, &cmd, sizeof cmd, &reg, sizeof reg, 0))
                    201:                        goto done;
                    202:                delay(1000);
                    203:                cmd = AD741X_ADC;
                    204:                if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
                    205:                    sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0))
                    206:                        goto done;
                    207:                sc->sc_sensor[ADC_ADC0 + i].value =
                    208:                    (data[0] << 8 | data[1]) >> 6;
                    209:        }
                    210:
                    211: done:
                    212:        iic_release_bus(sc->sc_tag, 0);
                    213: }

CVSweb