Annotation of sys/dev/i2c/adm1025.c, Revision 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