root/dev/i2c/maxim6690.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. maxtmp_match
  2. maxtmp_attach
  3. maxtmp_readport
  4. maxtmp_refresh

    1 /*      $OpenBSD: maxim6690.c,v 1.15 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 MAX6642/90 registers */
   27 #define MAX6690_INT_TEMP        0x00
   28 #define MAX6690_EXT_TEMP        0x01
   29 #define MAX6690_INT_TEMP2       0x11
   30 #define MAX6690_EXT_TEMP2       0x10
   31 #define MAX6690_STATUS          0x02
   32 #define MAX6690_DEVID           0xfe
   33 #define MAX6690_REVISION        0xff    /* absent on MAX6642 */
   34 
   35 #define MAX6642_TEMP_INVALID    0xff    /* sensor disconnected */
   36 #define MAX6690_TEMP_INVALID    0x80    /* sensor disconnected */
   37 #define MAX6690_TEMP_INVALID2   0x7f    /* open-circuit without pull-up */
   38 #define LM90_TEMP_INVALID       0x7f    /* sensor disconnected */
   39 
   40 #define MAX6642_TEMP2_MASK      0xc0    /* significant bits */
   41 #define MAX6690_TEMP2_MASK      0xe0    /* significant bits */
   42 #define LM90_TEMP2_MASK         0xe0    /* significant bits */
   43 
   44 /* Sensors */
   45 #define MAXTMP_INT              0
   46 #define MAXTMP_EXT              1
   47 #define MAXTMP_NUM_SENSORS      2
   48 
   49 struct maxtmp_softc {
   50         struct device sc_dev;
   51         i2c_tag_t sc_tag;
   52         i2c_addr_t sc_addr;
   53 
   54         u_int8_t sc_temp_invalid[2];
   55         u_int8_t sc_temp2_mask;
   56 
   57         struct ksensor sc_sensor[MAXTMP_NUM_SENSORS];
   58         struct ksensordev sc_sensordev;
   59 };
   60 
   61 int     maxtmp_match(struct device *, void *, void *);
   62 void    maxtmp_attach(struct device *, struct device *, void *);
   63 int     maxtmp_check(struct i2c_attach_args *, u_int8_t *, u_int8_t *);
   64 void    maxtmp_refresh(void *);
   65 
   66 struct cfattach maxtmp_ca = {
   67         sizeof(struct maxtmp_softc), maxtmp_match, maxtmp_attach
   68 };
   69 
   70 struct cfdriver maxtmp_cd = {
   71         NULL, "maxtmp", DV_DULL
   72 };
   73 
   74 int
   75 maxtmp_match(struct device *parent, void *match, void *aux)
   76 {
   77         struct i2c_attach_args *ia = aux;
   78 
   79         if (strcmp(ia->ia_name, "max6642") == 0 ||
   80             strcmp(ia->ia_name, "max6690") == 0 ||
   81             strcmp(ia->ia_name, "max6657") == 0 ||
   82             strcmp(ia->ia_name, "max6658") == 0 ||
   83             strcmp(ia->ia_name, "max6659") == 0 ||
   84             strcmp(ia->ia_name, "lm63") == 0 ||
   85             strcmp(ia->ia_name, "lm86") == 0 ||
   86             strcmp(ia->ia_name, "lm89") == 0 ||
   87             strcmp(ia->ia_name, "lm89-1") == 0 ||
   88             strcmp(ia->ia_name, "lm90") == 0 ||
   89             strcmp(ia->ia_name, "lm99") == 0 ||
   90             strcmp(ia->ia_name, "lm99-1") == 0)
   91                 return (1);
   92         return (0);
   93 }
   94 
   95 void
   96 maxtmp_attach(struct device *parent, struct device *self, void *aux)
   97 {
   98         struct maxtmp_softc *sc = (struct maxtmp_softc *)self;
   99         struct i2c_attach_args *ia = aux;
  100         int i;
  101 
  102         sc->sc_tag = ia->ia_tag;
  103         sc->sc_addr = ia->ia_addr;
  104 
  105         if (strcmp(ia->ia_name, "max6642") == 0) {
  106                 sc->sc_temp_invalid[0] = MAX6642_TEMP_INVALID;
  107                 sc->sc_temp_invalid[1] = MAX6642_TEMP_INVALID;
  108                 sc->sc_temp2_mask = MAX6642_TEMP2_MASK;
  109         } else if (strcmp(ia->ia_name, "max6690") == 0 ||
  110             strcmp(ia->ia_name, "max6657") == 0 ||
  111             strcmp(ia->ia_name, "max6658") == 0 ||
  112             strcmp(ia->ia_name, "max6659") == 0) {
  113                 sc->sc_temp_invalid[0] = MAX6690_TEMP_INVALID;
  114                 sc->sc_temp_invalid[1] = MAX6690_TEMP_INVALID2;
  115                 sc->sc_temp2_mask = MAX6690_TEMP2_MASK;
  116         } else {
  117                 sc->sc_temp_invalid[0] = LM90_TEMP_INVALID;
  118                 sc->sc_temp_invalid[1] = LM90_TEMP_INVALID;
  119                 sc->sc_temp2_mask = LM90_TEMP2_MASK;
  120         }
  121         printf(": %s", ia->ia_name);
  122 
  123         /* Initialize sensor data. */
  124         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
  125             sizeof(sc->sc_sensordev.xname));
  126 
  127         sc->sc_sensor[MAXTMP_INT].type = SENSOR_TEMP;
  128         strlcpy(sc->sc_sensor[MAXTMP_INT].desc, "Internal",
  129             sizeof(sc->sc_sensor[MAXTMP_INT].desc));
  130 
  131         sc->sc_sensor[MAXTMP_EXT].type = SENSOR_TEMP;
  132         strlcpy(sc->sc_sensor[MAXTMP_EXT].desc, "External",
  133             sizeof(sc->sc_sensor[MAXTMP_EXT].desc));
  134 
  135         if (sensor_task_register(sc, maxtmp_refresh, 5) == NULL) {
  136                 printf(", unable to register update task\n");
  137                 return;
  138         }
  139 
  140         for (i = 0; i < MAXTMP_NUM_SENSORS; i++)
  141                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
  142         sensordev_install(&sc->sc_sensordev);
  143 
  144         printf("\n");
  145 }
  146 
  147 void    maxtmp_readport(struct maxtmp_softc *, u_int8_t, u_int8_t, int);
  148 
  149 void
  150 maxtmp_readport(struct maxtmp_softc *sc, u_int8_t cmd1, u_int8_t cmd2,
  151     int index)
  152 {
  153         u_int8_t data, data2;
  154 
  155         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  156             sc->sc_addr, &cmd1, sizeof cmd1, &data, sizeof data, 0))
  157                 goto invalid;
  158         if (data == sc->sc_temp_invalid[0] || data == sc->sc_temp_invalid[1])
  159                 goto invalid;
  160         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
  161             sc->sc_addr, &cmd2, sizeof cmd2, &data2, sizeof data2, 0))
  162                 goto invalid;
  163 
  164         /* Set any meaningless bits to zero. */
  165         data2 &= sc->sc_temp2_mask;
  166 
  167         sc->sc_sensor[index].value = 273150000 +
  168             1000000 * data + (data2 >> 5) * 1000000 / 8;
  169         return;
  170 
  171 invalid:
  172         sc->sc_sensor[index].flags |= SENSOR_FINVALID;
  173 }
  174 
  175 void
  176 maxtmp_refresh(void *arg)
  177 {
  178         struct maxtmp_softc *sc = arg;
  179 
  180         iic_acquire_bus(sc->sc_tag, 0);
  181 
  182         maxtmp_readport(sc, MAX6690_INT_TEMP, MAX6690_INT_TEMP2, MAXTMP_INT);
  183         maxtmp_readport(sc, MAX6690_EXT_TEMP, MAX6690_EXT_TEMP2, MAXTMP_EXT);
  184 
  185         iic_release_bus(sc->sc_tag, 0);
  186 }

/* [<][>][^][v][top][bottom][index][help] */