LCOV - code coverage report
Current view: top level - dev/i2c - bmc150.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 81 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: bmc150.c,v 1.1 2017/11/30 14:53:21 kettenis Exp $     */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2017 Mark Kettenis
       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             : #define BGW_CHIPID              0x00
      27             : #define  BGW_CHIPID_BMA222E     0xf8
      28             : #define  BGW_CHIPID_BMA250E     0xf9
      29             : #define  BGW_CHIPID_BMC150      0xfa
      30             : #define  BGW_CHIPID_BMI055      0xfa
      31             : #define  BGW_CHIPID_BMA255      0xfa
      32             : #define  BGW_CHIPID_BMA280      0xfb
      33             : #define ACCD_X_LSB              0x02
      34             : #define ACCD_X_MSB              0x03
      35             : #define ACCD_Y_LSB              0x04
      36             : #define ACCD_Y_MSB              0x05
      37             : #define ACCD_Z_LSB              0x06
      38             : #define ACCD_Z_MSB              0x07
      39             : #define ACCD_TEMP               0x08
      40             : 
      41             : #define BGW_NUM_SENSORS         4
      42             : 
      43             : #define BGW_SENSOR_XACCEL       0
      44             : #define BGW_SENSOR_YACCEL       1
      45             : #define BGW_SENSOR_ZACCEL       2
      46             : #define BGW_SENSOR_TEMP         3
      47             : 
      48             : struct bgw_softc {
      49             :         struct device sc_dev;
      50             :         i2c_tag_t sc_tag;
      51             :         i2c_addr_t sc_addr;
      52             : 
      53             :         uint8_t sc_temp0;
      54             : 
      55             :         struct ksensor sc_sensor[BGW_NUM_SENSORS];
      56             :         struct ksensordev sc_sensordev;
      57             : };
      58             : 
      59             : int     bgw_match(struct device *, void *, void *);
      60             : void    bgw_attach(struct device *, struct device *, void *);
      61             : 
      62             : struct cfattach bgw_ca = {
      63             :         sizeof(struct bgw_softc), bgw_match, bgw_attach
      64             : };
      65             : 
      66             : struct cfdriver bgw_cd = {
      67             :         NULL, "bgw", DV_DULL
      68             : };
      69             : 
      70             : void    bgw_refresh(void *);
      71             : 
      72             : int
      73           0 : bgw_match(struct device *parent, void *match, void *aux)
      74             : {
      75           0 :         struct i2c_attach_args *ia = aux;
      76             : 
      77           0 :         if (strcmp(ia->ia_name, "BSBA0150") == 0 ||
      78           0 :             strcmp(ia->ia_name, "BMC150A") == 0 ||
      79           0 :             strcmp(ia->ia_name, "BMI055A") == 0 ||
      80           0 :             strcmp(ia->ia_name, "BMA0255") == 0 ||
      81           0 :             strcmp(ia->ia_name, "BMA250E") == 0 ||
      82           0 :             strcmp(ia->ia_name, "BMA222E") == 0 ||
      83           0 :             strcmp(ia->ia_name, "BMA0280") == 0 ||
      84           0 :             strcmp(ia->ia_name, "BOSC0200") == 0)
      85           0 :                 return 1;
      86           0 :         return 0;
      87           0 : }
      88             : 
      89             : void
      90           0 : bgw_attach(struct device *parent, struct device *self, void *aux)
      91             : {
      92           0 :         struct bgw_softc *sc = (struct bgw_softc *)self;
      93           0 :         struct i2c_attach_args *ia = aux;
      94           0 :         uint8_t cmd, data;
      95             :         int i;
      96             : 
      97           0 :         sc->sc_tag = ia->ia_tag;
      98           0 :         sc->sc_addr = ia->ia_addr;
      99             : 
     100           0 :         iic_acquire_bus(sc->sc_tag, 0);
     101           0 :         cmd = BGW_CHIPID;
     102           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     103           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     104             :                 iic_release_bus(sc->sc_tag, 0);
     105           0 :                 printf(": can't read chip ID\n");
     106           0 :                 return;
     107             :         }
     108             :         iic_release_bus(sc->sc_tag, 0);
     109             : 
     110           0 :         switch (data) {
     111             :         case BGW_CHIPID_BMA222E:
     112           0 :                 sc->sc_temp0 = 23;
     113           0 :                 printf(": BMA222E");
     114           0 :                 break;
     115             :         case BGW_CHIPID_BMA250E:
     116           0 :                 sc->sc_temp0 = 23;
     117           0 :                 printf(": BMA250E");
     118           0 :                 break;
     119             :         case BGW_CHIPID_BMC150:
     120           0 :                 sc->sc_temp0 = 24;
     121           0 :                 printf(": BMC150");
     122           0 :                 break;
     123             :         case BGW_CHIPID_BMA280:
     124           0 :                 sc->sc_temp0 = 23;
     125           0 :                 printf(": BMA280");
     126           0 :                 break;
     127             :         }
     128             : 
     129           0 :         sc->sc_sensor[BGW_SENSOR_XACCEL].type = SENSOR_INTEGER;
     130           0 :         strlcpy(sc->sc_sensor[BGW_SENSOR_XACCEL].desc, "X_ACCEL",
     131             :             sizeof(sc->sc_sensor[BGW_SENSOR_XACCEL].desc));
     132           0 :         sc->sc_sensor[BGW_SENSOR_YACCEL].type = SENSOR_INTEGER;
     133           0 :         strlcpy(sc->sc_sensor[BGW_SENSOR_YACCEL].desc, "Y_ACCEL",
     134             :             sizeof(sc->sc_sensor[BGW_SENSOR_YACCEL].desc));
     135           0 :         sc->sc_sensor[BGW_SENSOR_ZACCEL].type = SENSOR_INTEGER;
     136           0 :         strlcpy(sc->sc_sensor[BGW_SENSOR_ZACCEL].desc, "Z_ACCEL",
     137             :             sizeof(sc->sc_sensor[BGW_SENSOR_ZACCEL].desc));
     138           0 :         sc->sc_sensor[BGW_SENSOR_TEMP].type = SENSOR_TEMP;
     139             : 
     140           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     141             :             sizeof(sc->sc_sensordev.xname));
     142           0 :         for (i = 0; i < BGW_NUM_SENSORS; i++)
     143           0 :                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
     144           0 :         sensordev_install(&sc->sc_sensordev);
     145             : 
     146           0 :         if (sensor_task_register(sc, bgw_refresh, 5) == NULL) {
     147           0 :                 printf(", unable to register update task\n");
     148           0 :                 return;
     149             :         }
     150             : 
     151           0 :         printf("\n");
     152           0 : }
     153             : 
     154             : void
     155           0 : bgw_refresh(void *arg)
     156             : {
     157           0 :         struct bgw_softc *sc = arg;
     158           0 :         uint8_t cmd, data[7];
     159             :         uint8_t lsb;
     160             :         int8_t msb;
     161             :         int8_t temp;
     162             :         int i;
     163             : 
     164           0 :         iic_acquire_bus(sc->sc_tag, 0);
     165           0 :         cmd = ACCD_X_LSB;
     166           0 :         if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
     167           0 :             sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
     168             :                 iic_release_bus(sc->sc_tag, 0);
     169           0 :                 for (i = 0; i < BGW_NUM_SENSORS; i++)
     170           0 :                         sc->sc_sensor[i].flags |= SENSOR_FINVALID;
     171           0 :                 return;
     172             :         }
     173             :         iic_release_bus(sc->sc_tag, 0);
     174             : 
     175           0 :         lsb = data[ACCD_X_LSB - ACCD_X_LSB];
     176           0 :         msb = data[ACCD_X_MSB - ACCD_X_LSB];
     177           0 :         sc->sc_sensor[BGW_SENSOR_XACCEL].value = (msb << 4) | (lsb >> 4);
     178           0 :         sc->sc_sensor[BGW_SENSOR_XACCEL].flags &= ~SENSOR_FINVALID;
     179             : 
     180           0 :         lsb = data[ACCD_Y_LSB - ACCD_X_LSB];
     181           0 :         msb = data[ACCD_Y_MSB - ACCD_X_LSB];
     182           0 :         sc->sc_sensor[BGW_SENSOR_YACCEL].value = (msb << 4) | (lsb >> 4);
     183           0 :         sc->sc_sensor[BGW_SENSOR_YACCEL].flags &= ~SENSOR_FINVALID;
     184             : 
     185           0 :         lsb = data[ACCD_Z_LSB - ACCD_X_LSB];
     186           0 :         msb = data[ACCD_Z_MSB - ACCD_X_LSB];
     187           0 :         sc->sc_sensor[BGW_SENSOR_ZACCEL].value = (msb << 4) | (lsb >> 4);
     188           0 :         sc->sc_sensor[BGW_SENSOR_ZACCEL].flags &= ~SENSOR_FINVALID;
     189             : 
     190           0 :         temp = data[ACCD_TEMP - ACCD_X_LSB];
     191           0 :         sc->sc_sensor[BGW_SENSOR_TEMP].value =
     192           0 :             273150000 + (sc->sc_temp0 + temp) * 1000000;
     193           0 :         sc->sc_sensor[BGW_SENSOR_TEMP].flags &= ~SENSOR_FINVALID;
     194           0 : }

Generated by: LCOV version 1.13