Re: new bme code

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: new bme code

s_graf
Yes this works.

From dmesg:

sxitwi0 at simplebus0
iic0 at sxitwi0
bme0 at iic0 addr 0x76: BME280 60
sxitwi1 at simplebus0
iic1 at sxitwi1
bme1 at iic1 addr 0x77: BME280 60

And from sysctl:

op1bsdsnap# sysctl hw.sensors
hw.sensors.sxitemp0.temp0=187.74 degC (CPU)
hw.sensors.bme0.temp0=22.95 degC
hw.sensors.bme0.humidity0=52.01%
hw.sensors.bme0.pressure0=101.36 Pa
hw.sensors.bme1.temp0=24.02 degC
hw.sensors.bme1.humidity0=47.54%
hw.sensors.bme1.pressure0=101.33 Pa
op1bsdsnap# sysctl hw.sensors
hw.sensors.sxitemp0.temp0=187.74 degC (CPU)
hw.sensors.bme0.temp0=22.84 degC
hw.sensors.bme0.humidity0=52.32%
hw.sensors.bme0.pressure0=101.36 Pa
hw.sensors.bme1.temp0=24.01 degC
hw.sensors.bme1.humidity0=47.54%
hw.sensors.bme1.pressure0=101.34 Pa

The " hw.sensors.sxitemp0.temp0=187.74 degC (CPU)" will be the topic in another conversation.  I have added h3 to the sxitemp driver, but I can  not get the hardware to provide a reading.

-----Original Message-----
From: aa e30 <[hidden email]>
Sent: May 7, 2018 2:27 PM
To: [hidden email]
Subject: Re: new bme code

On 8 May 2018 at 00:25,  <[hidden email]> wrote:

> Would you please send me the diff as an attachment.  The inline has
> some lines wrapped and the diff does not apply cleanly.
>
> -----Original Message-----
> From: Artturi Alm <[hidden email]>
> Sent: May 6, 2018 3:05 AM
> To: [hidden email]
> Cc: [hidden email]
> Subject: Re: gtk libool slow on arm
>
> On Thu, May 03, 2018 at 09:55:21PM -0700, [hidden email] wrote:
>> Thank you for the updates.  I will build and test as soon as I get
> finished with the php build.  My system is still flailing away at gtk
> with each ld session taking about 20 minutes.  Could be days yet.
>>
>
> fixed the diff with moving dev/fdt/bme.c to dev/i2c/bme280.c, thanks
> to clue by kettenis@.
>
> -Artturi
>
>
> diff --git share/man/man4/Makefile share/man/man4/Makefile index
> 8004d8b575d..3ac02b89788 100644
> --- share/man/man4/Makefile
> +++ share/man/man4/Makefile
> @@ -15,7 +15,7 @@ MAN=  aac.4 ac97.4 acphy.4 acrtc.4 \
>         auacer.4 audio.4 aue.4 auglx.4 auich.4 auixp.4 autri.4 auvia.4 \
>         axe.4 axen.4 axppmic.4 azalia.4 \
>         bce.4 bcmaux.4 bcmdog.4  bcmrng.4 bcmtemp.4 berkwdt.4 bge.4 \
> -       bgw.4 bio.4 bktr.4 bmtphy.4 bnx.4 \
> +       bgw.4 bio.4 bktr.4 bme.4 bmtphy.4 bnx.4 \
>         boca.4 bpf.4 brgphy.4 bridge.4 brswphy.4 bwfm.4 bwi.4 bytgpio.4 \
>         cac.4 cas.4 cardbus.4 carp.4 ccp.4 cd.4 cdce.4 cfxga.4 \
>         ch.4 chvgpio.4 ciphy.4 ciss.4 clcs.4 clct.4 cmpci.4 \ diff
> --git
> share/man/man4/bme.4 share/man/man4/bme.4 new file mode 100644 index
> 00000000000..bb48513d9dc
> --- /dev/null
> +++ share/man/man4/bme.4
> @@ -0,0 +1,44 @@
> +.\"    $OpenBSD: tsl.4,v 1.10 2015/10/02 09:29:02 sobrado Exp $
> +.\"
> +.\" Copyright (c) 2005 Mark Kettenis <[hidden email]> .\"
> +Copyright (c) 2018 Artturi Alm .\"
> +.\" Permission to use, copy, modify, and distribute this software for
> +any .\" purpose with or without fee is hereby granted, provided that
> +the above .\" copyright notice and this permission notice appear in
> +all
> copies.
> +.\"
> +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
> +WARRANTIES .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
> +WARRANTIES OF .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
> +AUTHOR BE LIABLE FOR .\" ANY SPECIAL, DIRECT, INDIRECT, OR
> +CONSEQUENTIAL DAMAGES OR ANY DAMAGES .\" WHATSOEVER RESULTING FROM
> +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT,
> +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN
> +CONNECTION
> WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +.\"
> +.Dd $Mdocdate$
> +.Dt BME 4
> +.Os
> +.Sh NAME
> +.Nm bme
> +.Nd Bosch BME280 Environmental sensor .Sh SYNOPSIS .Cd "bme* at iic?"
> +.Sh DESCRIPTION
> +The
> +.Nm
> +driver provides support for the Bosch BME280 Environmental sensor.
> +These sensors contain combined digital humidity, pressure and
> +temperature sensing capabilities.
> +These values are made available through the .Xr sysctl 8 interface.
> +.Sh SEE ALSO
> +.Xr iic 4 ,
> +.Xr intro 4 ,
> +.Xr sensorsd 8 ,
> +.Xr sysctl 8
> +.Sh HISTORY
> +The
> +.Nm
> +driver first appeared in
> +.Ox 6.4 .
> diff --git sys/dev/i2c/bme280.c sys/dev/i2c/bme280.c new file mode
> 100644 index 00000000000..8d35f5ae44d
> --- /dev/null
> +++ sys/dev/i2c/bme280.c
> @@ -0,0 +1,543 @@
> +/*     $OpenBSD: tsl2560.c,v 1.7 2008/04/18 01:17:51 deraadt Exp $     */
> +
> +/*
> + * Copyright (c) 2005 Mark Kettenis
> + * Copyright (c) 2017 Artturi Alm
> + *
> + * Permission to use, copy, modify, and distribute this software for
> +any
> + * purpose with or without fee is hereby granted, provided that the
> +above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
> +WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
> +LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
> +DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
> +AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
> +OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/device.h>
> +#include <sys/kthread.h>
> +#include <sys/sensors.h>
> +
> +#include <dev/i2c/i2cvar.h>
> +
> +/*
> + * Register Name       Address b7 b6 b5 b4 b3 b2 b1 b0         Reset state
> + * hum_lsb             0xFE    hum_lsb<7:0>                    0x00
> + * hum_msb             0xFD    hum_msb<7:0>                    0x80
> + * temp_xlsb           0xFC    temp_xlsb<7:4>  0000            0x00
> + * temp_lsb            0xFB    temp_lsb<7:0>                   0x00
> + * temp_msb            0xFA    temp_msb<7:0>                   0x80
> + * press_xlsb          0xF9    press_xlsb<7:4> 0000            0x00
> + * press_lsb           0xF8    press_lsb<7:0>                  0x00
> + * press_msb           0xF7    press_msb<7:0>                  0x80
> + * config              0xF5    t_sb[2:0]filter[2:0]spi3w_en[0] 0x00
> + * ctrl_meas           0xF4    osrs_p[2:0]osrs_t[2:0]mode[1:0] 0x00
> + * status              0xF3    measuring[0]im_update[0]        0x00
> + * ctrl_hum            0xF2    osrs_h[2:0]                     0x00
> + * calib26..calib41    0xE1-0xF0       calibration data        individual
> + * reset               0xE0    reset[7:0]                      0x00
> + * id                  0xD0    chip_id[7:0]                    0x60
> + * calib00..calib25    0x88-0xA1       calibration data        individual
> +*/
> +
> +#define        BME280_CALIB00_23       0x88
> +#define        BME280_CALIB24          0xa1
> +#define        BME280_ID               0xd0
> +#define        BME280_RESET            0xe0
> +       /* soft reset magic value */
> +#define        BME280_RESET_MAGIC      0xb6
> +#define        BME280_CALIB25_31       0xe1
> +       /* changes become effective only after a write op to ctrl_meas */
> +#define        BME280_CTRL_HUM         0xf2
> +
> +#define        BME280_STATUS           0xf3
> +#define        BME280_STATUS_MASK      0x09
> +#define        BME280_STATUS_CONV      0x08    /* conversion running */
> +#define        BME280_STATUS_UPD       0x01    /* update in progress */
> +
> +#define        BME280_CTRL_MEAS                0xf4
> +#define        BME280_CTRL_MEAS_MODE_MASK      0x03
> +#define        BME280_CTRL_MEAS_MODE_SLEEP     0x00
> +#define        BME280_CTRL_MEAS_MODE_FORCED    0x01
> +#define        BME280_CTRL_MEAS_MODE_FORCE     0x02
> +#define        BME280_CTRL_MEAS_MODE_NORMAL    0x03
> +       /* writes in normal mode may be ignored, not so in sleep mode */
> +#define        BME280_CONFIG           0xf5
> +#define        BME280_CONFIG_SPI_EN    0x01
> +
> +#define        BME280_PRESS_MSB        0xf7
> +#define        BME280_PRESS_LSB        0xf8
> +#define        BME280_PRESS_XLSB       0xf9
> +#define        BME280_TEMP_MSB         0xfa
> +#define        BME280_TEMP_LSB         0xfb
> +#define        BME280_TEMP_XLSB        0xfc
> +#define        BME280_HUM_MSB          0xfd
> +#define        BME280_HUM_LSB          0xfe
> +
> +#define        BME_OVERSAMPLING_SKIP   0x00
> +#define        BME_OVERSAMPLING_X1     0x01
> +#define        BME_OVERSAMPLING_X2     0x02
> +#define        BME_OVERSAMPLING_X4     0x03
> +#define        BME_OVERSAMPLING_X8     0x04
> +#define        BME_OVERSAMPLING_X16    0x05
> +
> +#define        BME_HUMI        0
> +#define        BME_TEMP        1
> +#define        BME_PRES        2
> +
> +struct bme_softc {
> +       struct device           sc_dev;
> +       i2c_tag_t               sc_i2c;
> +       i2c_addr_t              sc_addr;
> +
> +       struct ksensor          sc_sensor[3];
> +       struct ksensordev       sc_sensordev;
> +
> +       int                     sc_calibrated;
> +       int                     sc_configured;
> +
> +       /*
> +        * fine resolution temperature value for pressure and
> +        * humidity compensation formulas.
> +        */
> +       int32_t                 sc_t_fine;
> +       /* calibration data */
> +       int32_t                 sc_t_trim[3];
> +       int64_t                 sc_p_trim[9];
> +       int32_t                 sc_h_trim[6];
> +};
> +
> +int    bme_match(struct device *, void *, void *);
> +void   bme_attach(struct device *, struct device *, void *);
> +void   bme_deferred(void *);
> +void   bme_refresh(void *);
> +void   bme_softreset(struct bme_softc *, int);
> +void   bme_configure(struct bme_softc *, int);
> +void   bme_get_calib(struct bme_softc *, int);
> +
> +int32_t                bme_comp_temp(struct bme_softc *, int32_t);
> +uint32_t       bme_comp_pres(struct bme_softc *, int32_t);
> +uint32_t       bme_comp_humi(struct bme_softc *, int32_t);
> +
> +static inline uint8_t  bme_config_filter(int); static inline uint8_t  
> +bme_config_standby(int); static inline uint8_t  
> +bme_oversample(uint8_t, uint8_t);
> +
> +struct cfattach bme_ca = {
> +       sizeof(struct bme_softc), bme_match, bme_attach };
> +
> +struct cfdriver bme_cd = {
> +       NULL, "bme", DV_DULL
> +};
> +
> +int
> +bme_match(struct device *parent, void *match, void *aux) {
> +       struct i2c_attach_args *ia = aux;
> +
> +       if (strcmp(ia->ia_name, "bosch,bme280") == 0)
> +               return 1;
> +
> +       return 0;
> +}
> +
> +void
> +bme_attach(struct device *parent, struct device *self, void *aux) {
> +       struct bme_softc *sc = (struct bme_softc *)self;
> +       struct i2c_attach_args *ia = aux;
> +       int ieflags = I2C_F_POLL;
> +       uint8_t reg_addr, data;
> +
> +       sc->sc_i2c = ia->ia_tag;
> +       sc->sc_addr = ia->ia_addr;
> +
> +       iic_acquire_bus(sc->sc_i2c, ieflags);
> +
> +       sc->sc_calibrated = 0;
> +       bme_softreset(sc, ieflags);
> +
> +       reg_addr = BME280_ID;
> +       if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP,
> +           sc->sc_addr, &reg_addr, 1, &data, 1, ieflags)) {
> +               iic_release_bus(sc->sc_i2c, ieflags);
> +               printf(": failed to read ID register\n");
> +               return;
> +       }
> +
> +       iic_release_bus(sc->sc_i2c, ieflags);
> +
> +        switch (data) {
> +       default:
> +               printf(": unknown value in ID register 0x%x\n", data);
> +               return;
> +       case 0x58:
> +       case 0x57:
> +       case 0x56:
> +               /* XXX atleast somehow register compatible with BMP280 */
> +               printf(": sorry, no BMP280 support yet\n");
> +               return;
> +       case 0x60:
> +               printf(": BME280 %x\n", data);
> +               break;
> +       }
> +
> +       kthread_create_deferred(bme_deferred, sc); }
> +
> +void
> +bme_deferred(void *arg)
> +{
> +       struct bme_softc *sc = arg;
> +       int ieflags = I2C_F_POLL; /* XXX cold ? I2C_F_POLL : 0 */
> +       int i;
> +
> +       iic_acquire_bus(sc->sc_i2c, ieflags);
> +
> +       bme_configure(sc, ieflags);
> +#ifdef DIAGNOSTIC
> +       if (sc->sc_configured != 1)     /* non-fatal */
> +               printf("%s: failed to configure\n",
> +sc->sc_dev.dv_xname);
> #endif
> +
> +       bme_get_calib(sc, ieflags);
> +
> +       iic_release_bus(sc->sc_i2c, ieflags);
> +
> +       if (sc->sc_calibrated != 1) {
> +               printf("%s: failed to read calibration data\n",
> +                   sc->sc_dev.dv_xname);
> +               /* fatal; and retrying feels bloat, fix your i2c "wiring" */
> +               return; /* XXX can't defer failure to config_detach.. :( */
> +       }
> +
> +       if (sensor_task_register(sc, bme_refresh, 1) == NULL) {
> +               printf("%s: unable to register update task\n",
> +                   sc->sc_dev.dv_xname);
> +               return;
> +       }
> +
> +       /* Initialize sensor data. */
> +       strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
> +           sizeof(sc->sc_sensordev.xname));
> +       sc->sc_sensor[BME_HUMI].type = SENSOR_HUMIDITY;
> +       sc->sc_sensor[BME_TEMP].type = SENSOR_TEMP;
> +       sc->sc_sensor[BME_PRES].type = SENSOR_PRESSURE;
> +
> +       for (i = 0; i < 3; i++) {
> +               sc->sc_sensor[i].flags = SENSOR_FINVALID;
> +               sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
> +       }
> +       sensordev_install(&sc->sc_sensordev);
> +}
> +
> +void
> +bme_refresh(void *arg)
> +{
> +       struct bme_softc *sc = arg;
> +       int32_t raw[3] = { 0, 0, 0 };
> +       int ieflags = I2C_F_POLL; /* XXX cold ? I2C_F_POLL : 0 */
> +       uint8_t addr;
> +       uint8_t data[8];
> +
> +       iic_acquire_bus(sc->sc_i2c, ieflags);
> +
> +       if (sc->sc_configured == 0) {
> +               bme_configure(sc, ieflags);
> +               if (sc->sc_configured != 1) { #ifdef DIAGNOSTIC
> +                       printf("%s: failed to configure - resetting\n",
> +                           sc->sc_dev.dv_xname); #endif
> +                       bme_softreset(sc, ieflags);
> +                       goto fail_out;
> +               }
> +       }
> +
> +       /*
> +        * read raw uncompensated values in a single read "burst",
> +        * to keep data register shadowing functional in the normal-mode
> +        * we're configured to, as we don't really synchronize with the
> +        * sensor, so we have no need to read the status register at all.
> +        */
> +       addr = BME280_PRESS_MSB;
> +       if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP,
> +           sc->sc_addr, &addr, 1, &data, sizeof data, ieflags)) {
> +               printf("%s: failed to read data - resetting\n",
> +                   sc->sc_dev.dv_xname);
> +               bme_softreset(sc, ieflags);
> +               bme_configure(sc, ieflags);
> +               goto fail_out;
> +        }
> +
> +       iic_release_bus(sc->sc_i2c, ieflags);
> +
> +       /* got raw */
> +       raw[BME_HUMI] = (data[6] << 8) | data[7];
> +       raw[BME_TEMP] = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
> +       raw[BME_PRES] = (data[0] << 12) | (data[1] << 4) | (data[2] >>
> + 4);
> +
> +       /* do compensate raw values */
> +       sc->sc_sensor[BME_TEMP].value = bme_comp_temp(sc, raw[BME_TEMP]);
> +       sc->sc_sensor[BME_PRES].value = bme_comp_pres(sc, raw[BME_PRES]);
> +       sc->sc_sensor[BME_HUMI].value = bme_comp_humi(sc,
> + raw[BME_HUMI]);
> +
> +       sc->sc_sensor[BME_TEMP].flags &= ~SENSOR_FINVALID;
> +       sc->sc_sensor[BME_PRES].flags &= ~SENSOR_FINVALID;
> +       sc->sc_sensor[BME_HUMI].flags &= ~SENSOR_FINVALID;
> +       return;
> +fail_out:
> +       iic_release_bus(sc->sc_i2c, ieflags);
> +       sc->sc_sensor[BME_TEMP].flags |= SENSOR_FINVALID;
> +       sc->sc_sensor[BME_PRES].flags |= SENSOR_FINVALID;
> +       sc->sc_sensor[BME_HUMI].flags |= SENSOR_FINVALID; }
> +
> +void
> +bme_get_calib(struct bme_softc *sc, int ieflags) {
> +       int i, j;
> +       uint8_t addr;
> +       uint8_t calib[32];
> +
> +       /* read calibration data */
> +       addr = BME280_CALIB00_23;
> +       if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP,
> +           sc->sc_addr, &addr, 1, &calib[0], 24, ieflags))
> +               return;
> +
> +       addr = BME280_CALIB24;
> +       if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP,
> +           sc->sc_addr, &addr, 1, &calib[24], 1, ieflags))
> +               return;
> +
> +       addr = BME280_CALIB25_31;
> +       if (iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP,
> +           sc->sc_addr, &addr, 1, &calib[25], 7, ieflags))
> +               return;
> +
> +       /* adjust calibration data for later compensations */
> +       for (i = 0, j = 0; i < 3; j += 2)
> +               sc->sc_t_trim[i++] = (calib[j + 1] << 8) | calib[j];
> +       for (i = 0, j = 6; i < 9; j += 2)
> +               sc->sc_p_trim[i++] = (calib[j + 1] << 8) | calib[j];
> +       sc->sc_h_trim[(i = 0)] = calib[24];
> +       sc->sc_h_trim[++i] = (calib[26] << 8) | calib[25];
> +       sc->sc_h_trim[++i] = calib[27];
> +       sc->sc_h_trim[++i] = (calib[28] << 4) | (calib[29] & 0xf);
> +       sc->sc_h_trim[++i] = (calib[30] << 4) | ((calib[29] & 0xf0) >> 4);
> +       sc->sc_h_trim[++i] = calib[31];
> +
> +       for (i = 1; i < 3; i++)
> +               if (sc->sc_t_trim[i] & 0x8000)
> +                       sc->sc_t_trim[i] = (-sc->sc_t_trim[i] ^ 0xffff) + 1;
> +       for (j = 1; j < 9; j++)
> +               if (sc->sc_p_trim[j] & 0x8000)
> +                       sc->sc_p_trim[j] = (-sc->sc_p_trim[j] ^ 0xffff) + 1;
> +       for (i = 1; i < 6; i++)         /* XXX last one is signed char? */
> +               if (sc->sc_h_trim[i] & 0x8000) /* so will never match
> + this
> */
> +                       sc->sc_h_trim[i] = (-sc->sc_h_trim[i] ^
> + 0xffff) + 1;
> +
> +       sc->sc_calibrated = 1;
> +}
> +
> +/*
> + * this is not really required, as the chip should be in this
> + * condition already after Power-On-Reset (POR), and we configure
> + * everything without reading current values in correct order,
> + * so i decided to let this fail as void, trusting sc_configured=0
> +will
> + * fix configuration registers later anyway.
> + */
> +void
> +bme_softreset(struct bme_softc *sc, int ieflags) {
> +       uint8_t addr = BME280_RESET;
> +       uint8_t data = BME280_RESET_MAGIC;
> +
> +       sc->sc_configured = 0;
> +
> +        if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP,
> +            sc->sc_addr, &addr, 1, &data, 1, ieflags)) { #ifdef
> +DIAGNOSTIC
> +               printf("%s: failed to write softreset\n",
> sc->sc_dev.dv_xname);
> +#endif
> +               return;
> +       }
> +       /*
> +        * XXX should this have some delay here? SoC-performance do vary..
> +        */
> +}
> +
> +void
> +bme_configure(struct bme_softc *sc, int ieflags) {
> +       uint8_t addr, data;
> +
> +       /* XXX do seek for devicetree bindings, for config parameters
> + */
> +
> +       addr = BME280_CTRL_HUM;
> +       data = bme_oversample(1, BME_HUMI);
> +       if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP,
> +           sc->sc_addr, &addr, 1, &data, 1, ieflags))
> +               return;
> +
> +       addr = BME280_CONFIG;
> +       data = bme_config_filter(0) | bme_config_standby(1000000);
> +       if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP,
> +           sc->sc_addr, &addr, 1, &data, 1, ieflags))
> +               return;
> +
> +       addr = BME280_CTRL_MEAS;
> +       data = BME280_CTRL_MEAS_MODE_NORMAL | bme_oversample(1, BME_TEMP) |
> +           bme_oversample(1, BME_PRES);
> +       if (iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP,
> +           sc->sc_addr, &addr, 1, &data, 1, ieflags))
> +               return;
> +
> +       sc->sc_configured = 1;
> +}
> +
> +int32_t
> +bme_comp_temp(struct bme_softc *sc, int32_t raw) {
> +       int32_t t1 = sc->sc_t_trim[0];
> +       int32_t t2 = sc->sc_t_trim[1];
> +       int32_t t3 = sc->sc_t_trim[2];
> +       int32_t var1  = ((((raw >> 3) - (t1 << 1))) * t2) >> 11;
> +       int32_t var2  = (((((raw >> 4) - t1) * ((raw >> 4) - t1)) >>
> +12) *
> t3)
> +           >> 14;
> +       int32_t rv_t;
> +
> +       sc->sc_t_fine = var1 + var2;
> +       rv_t = (sc->sc_t_fine * 5 + 128) >> 8;
> +       rv_t = (rv_t + 27315) * 10000;  /* for micro Kelvin */
> +       return rv_t;
> +}
> +
> +uint32_t
> +bme_comp_pres(struct bme_softc *sc, int32_t raw) {
> +       int64_t var1 = (int64_t)sc->sc_t_fine;
> +       int64_t var2;
> +       int64_t pa;
> +
> +       var1 -= 128000;
> +       var2 = var1 * var1 * sc->sc_p_trim[5];
> +       var2 = var2 + ((var1 * sc->sc_p_trim[4]) << 17);
> +       var2 = var2 + (sc->sc_p_trim[3] << 35);
> +
> +       var1 = ((var1 * var1 * sc->sc_p_trim[2]) >> 8) +
> +           ((var1 * sc->sc_p_trim[1]) << 12);
> +
> +       var1 = ((((int64_t)1) << 47) + var1) * sc->sc_p_trim[0] >> 33;
> +       if (var1 == 0)
> +               return 0;
> +
> +       pa = 1048576 - raw;
> +       pa = (((pa << 31) - var2) * 3125) / var1;
> +       var1 = (sc->sc_p_trim[8] * (pa >> 13) * (pa >> 13)) >> 25;
> +       var2 = (sc->sc_p_trim[7] * pa) >> 19;
> +       pa = ((pa + var1 + var2) >> 8) + (sc->sc_p_trim[6] << 4);
> +       pa /= 256;
> +       return (uint32_t)pa;
> +}
> +
> +uint32_t
> +bme_comp_humi(struct bme_softc *sc, int32_t raw) {
> +       int32_t rh = (int32_t)sc->sc_t_fine;
> +
> +       rh -= 76800;
> +       rh = (((((raw << 14) - (sc->sc_h_trim[3] << 20) -
> +           (sc->sc_h_trim[4] * rh)) + 16384) >> 15) *
> +           (((((((rh * sc->sc_h_trim[5]) >> 10) *
> +           (((rh * sc->sc_h_trim[2]) >> 11) + 32768)) >> 10) +
> +           2097152) * sc->sc_h_trim[1] + 8192) >> 14));
> +       rh -= (((((rh >> 15) * (rh >> 15)) >> 7) * sc->sc_h_trim[0]) >> 4);
> +       if (rh < 0)
> +               rh = 0;
> +       if (rh > 419430400)
> +               rh = 419430400;
> +       rh >>= 12;
> +       rh = (rh * 1000) / 1024;
> +       return (uint32_t)rh;
> +}
> +
> +uint8_t
> +bme_config_filter(int filter_coeff)
> +{
> +       switch (filter_coeff) {
> +       default:
> +       case 0: /* filter off */
> +               return 0x00;
> +       case 2:
> +               return 0x01;
> +       case 4:
> +               return 0x02;
> +       case 8:
> +               return 0x03;
> +       case 16:
> +               return 0x04;
> +       }
> +}
> +
> +uint8_t
> +bme_config_standby(int us)
> +{
> +       switch (us) {
> +       case 500:
> +               return 0x00U << 5;
> +       case 10000:
> +               return 0x06U << 5;
> +       case 20000:
> +               return 0x07U << 5;
> +       case 62500:
> +               return 0x01U << 5;
> +       case 125000:
> +               return 0x02U << 5;
> +       case 250000:
> +               return 0x03U << 5;
> +       case 500000:
> +               return 0x04U << 5;
> +       default:
> +       case 1000000:
> +               return 0x05U << 5;
> +       }
> +}
> +
> +uint8_t
> +bme_oversample(uint8_t over_sample, uint8_t sensor) {
> +       uint8_t off = 0;
> +
> +       switch (sensor) {
> +       case BME_PRES:
> +               off += 3;
> +       case BME_TEMP:
> +               off += 2;
> +       case BME_HUMI:
> +               break;
> +       default:
> +               return 0;
> +       }
> +
> +       switch (over_sample) {
> +       default:
> +       case 0:
> +               return BME_OVERSAMPLING_SKIP;
> +       case 1:
> +               return BME_OVERSAMPLING_X1 << off;
> +       case 2:
> +               return BME_OVERSAMPLING_X2 << off;
> +       case 4:
> +               return BME_OVERSAMPLING_X4 << off;
> +       case 16:
> +               return BME_OVERSAMPLING_X16 << off;
> +       }
> +}
> diff --git sys/dev/i2c/files.i2c sys/dev/i2c/files.i2c index
> 10f5bc63fa8..edb070bd11a 100644
> --- sys/dev/i2c/files.i2c
> +++ sys/dev/i2c/files.i2c
> @@ -220,6 +220,11 @@ device     bgw
>  attach bgw at i2c
>  file dev/i2c/bmc150.c                          bgw
>
> +# Bosch BME280 environmental sensor
> +device bme
> +attach bme at i2c
> +file   dev/i2c/bme280.c                        bme
> +
>  # Intersil ISL1208 Real Time Clock
>  device islrtc
>  attach islrtc at i2c
> diff --git sys/arch/armv7/conf/GENERIC sys/arch/armv7/conf/GENERIC
> index
> 052f73bf71f..59d314e5909 100644
> --- sys/arch/armv7/conf/GENERIC
> +++ sys/arch/armv7/conf/GENERIC
> @@ -179,6 +179,7 @@ rktemp*             at fdt?
>  dwdog*         at fdt?
>
>  axppmic*       at iic?                 # axp209 pmic
> +bme*           at iic?                 # BME280 environmental sensor
>  crosec*                at iic?
>  wskbd*         at crosec? mux 1
>  pcfrtc*                at iic?
>