Annotation of sys/dev/i2c/ds1631.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ds1631.c,v 1.9 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: /* Maxim ds 1631 registers */
! 27: #define DS1631_START 0x51
! 28: #define DS1624_START 0xee
! 29: #define DS1631_TEMP 0xaa
! 30: #define DS1631_CONTROL 0xac
! 31: #define DS1631_CONTROL_DONE 0x80
! 32: #define DS1631_CONTROL_1SHOT 0x01
! 33:
! 34: /* Sensors */
! 35: #define MAXDS_TEMP 0
! 36: #define MAXDS_NUM_SENSORS 1
! 37:
! 38: struct maxds_softc {
! 39: struct device sc_dev;
! 40: i2c_tag_t sc_tag;
! 41: i2c_addr_t sc_addr;
! 42:
! 43: struct ksensor sc_sensor[MAXDS_NUM_SENSORS];
! 44: struct ksensordev sc_sensordev;
! 45: };
! 46:
! 47: int maxds_match(struct device *, void *, void *);
! 48: void maxds_attach(struct device *, struct device *, void *);
! 49: void maxds_refresh(void *);
! 50:
! 51: struct cfattach maxds_ca = {
! 52: sizeof(struct maxds_softc), maxds_match, maxds_attach
! 53: };
! 54:
! 55: struct cfdriver maxds_cd = {
! 56: NULL, "maxds", DV_DULL
! 57: };
! 58:
! 59: int
! 60: maxds_match(struct device *parent, void *match, void *aux)
! 61: {
! 62: struct i2c_attach_args *ia = aux;
! 63:
! 64: if (strcmp(ia->ia_name, "ds1631") == 0 ||
! 65: strcmp(ia->ia_name, "ds1624") == 0 ||
! 66: strcmp(ia->ia_name, "ds1721") == 0)
! 67: return (1);
! 68: return (0);
! 69: }
! 70:
! 71: void
! 72: maxds_attach(struct device *parent, struct device *self, void *aux)
! 73: {
! 74: struct maxds_softc *sc = (struct maxds_softc *)self;
! 75: struct i2c_attach_args *ia = aux;
! 76: u_int8_t cmd, data;
! 77: int i;
! 78:
! 79: printf(": %s", ia->ia_name);
! 80:
! 81: sc->sc_tag = ia->ia_tag;
! 82: sc->sc_addr = ia->ia_addr;
! 83:
! 84: iic_acquire_bus(sc->sc_tag, 0);
! 85:
! 86: cmd = DS1631_CONTROL;
! 87: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
! 88: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
! 89: if (data & DS1631_CONTROL_1SHOT) {
! 90: /*
! 91: * 1-Shot mode would require us to write every refresh
! 92: * which is stupid. Put us into continuous mode.
! 93: */
! 94: data &= ~DS1631_CONTROL_1SHOT;
! 95:
! 96: (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
! 97: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0);
! 98: //delay(10 * 1000);
! 99: printf(", continuous");
! 100: goto dostart;
! 101: }
! 102: if (data & DS1631_CONTROL_DONE) {
! 103: dostart:
! 104: cmd = DS1631_START;
! 105: if (strcmp(ia->ia_name, "ds1624") == 0)
! 106: cmd = DS1624_START;
! 107: (void) iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
! 108: sc->sc_addr, &cmd, sizeof cmd, NULL, 0, 0);
! 109: printf(", starting");
! 110: }
! 111: }
! 112:
! 113: iic_release_bus(sc->sc_tag, 0);
! 114:
! 115: /* Initialize sensor data. */
! 116: strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
! 117: sizeof(sc->sc_sensordev.xname));
! 118:
! 119: sc->sc_sensor[MAXDS_TEMP].type = SENSOR_TEMP;
! 120: strlcpy(sc->sc_sensor[MAXDS_TEMP].desc, "Internal",
! 121: sizeof(sc->sc_sensor[MAXDS_TEMP].desc));
! 122:
! 123: if (sensor_task_register(sc, maxds_refresh, 5) == NULL) {
! 124: printf(", unable to register update task\n");
! 125: return;
! 126: }
! 127:
! 128: for (i = 0; i < MAXDS_NUM_SENSORS; i++)
! 129: sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
! 130: sensordev_install(&sc->sc_sensordev);
! 131:
! 132: printf("\n");
! 133: }
! 134:
! 135: void
! 136: maxds_refresh(void *arg)
! 137: {
! 138: struct maxds_softc *sc = arg;
! 139: u_int8_t cmd, data[2];
! 140:
! 141: iic_acquire_bus(sc->sc_tag, 0);
! 142:
! 143: cmd = DS1631_TEMP;
! 144: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
! 145: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
! 146: sc->sc_sensor[MAXDS_TEMP].value = 273150000 +
! 147: ((int)((u_int16_t)data[0] << 8 | data[1])) / 8 * 31250;
! 148:
! 149: iic_release_bus(sc->sc_tag, 0);
! 150: }
CVSweb