diff options
| author | brad <brad@NetBSD.org> | 2022-12-03 01:04:42 +0000 |
|---|---|---|
| committer | brad <brad@NetBSD.org> | 2022-12-03 01:04:42 +0000 |
| commit | 02b8954fe89d72e580aac9928e8f0dd91cabaedc (patch) | |
| tree | 3d66e5b9ef8e2812eb0fd4eb5c10499ac92a1975 /sys/dev/spi | |
| parent | a76f61463de79fb55af1db5ff83b1f68aeca0073 (diff) | |
Split the BMP280 / BME280 driver into common code and create I2C and
SPI attachments.
Diffstat (limited to 'sys/dev/spi')
| -rw-r--r-- | sys/dev/spi/bmx280thpspi.c | 205 | ||||
| -rw-r--r-- | sys/dev/spi/files.spi | 6 |
2 files changed, 210 insertions, 1 deletions
diff --git a/sys/dev/spi/bmx280thpspi.c b/sys/dev/spi/bmx280thpspi.c new file mode 100644 index 00000000000..f3262ad5250 --- /dev/null +++ b/sys/dev/spi/bmx280thpspi.c @@ -0,0 +1,205 @@ +/* $NetBSD: bmx280thpspi.c,v 1.1 2022/12/03 01:04:43 brad Exp $ */ + +/* + * Copyright (c) 2022 Brad Spencer <brad@anduin.eldar.org> + * + * 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/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: bmx280thpspi.c,v 1.1 2022/12/03 01:04:43 brad Exp $"); + +/* + * SPI driver for the Bosch BMP280 / BME280 sensor. + * Uses the common bmx280thp driver to do the real work. +*/ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/module.h> +#include <sys/conf.h> +#include <sys/sysctl.h> +#include <sys/mutex.h> +#include <sys/condvar.h> +#include <sys/pool.h> +#include <sys/kmem.h> + +#include <dev/sysmon/sysmonvar.h> +#include <dev/i2c/i2cvar.h> +#include <dev/spi/spivar.h> +#include <dev/ic/bmx280reg.h> +#include <dev/ic/bmx280var.h> + +extern void bmx280_attach(struct bmx280_sc *); + +static int bmx280thpspi_match(device_t, cfdata_t, void *); +static void bmx280thpspi_attach(device_t, device_t, void *); +static int bmx280thpspi_detach(device_t, int); + +#define BMX280_DEBUG +#ifdef BMX280_DEBUG +#define DPRINTF(s, l, x) \ + do { \ + if (l <= s->sc_bmx280debug) \ + printf x; \ + } while (/*CONSTCOND*/0) +#else +#define DPRINTF(s, l, x) +#endif + +CFATTACH_DECL_NEW(bmx280thpspi, sizeof(struct bmx280_sc), + bmx280thpspi_match, bmx280thpspi_attach, bmx280thpspi_detach, NULL); + +/* The SPI interface of the chip, assuming that it has managed to get into that + * mode to start with, is pretty simple. Simply send the register MINUS the 7th + * bit which will be 1 and then do as many reads as you want. The chip will + * auto increment for you. + * + * The delays are only hinted at in the data sheet. + */ + +static int +bmx280thpspi_read_reg_direct(struct spi_handle *sh, uint8_t reg, + uint8_t *buf, size_t rlen) +{ + int err = 0; + uint8_t rreg = reg | 0x80; + + if (buf != NULL) { + err = spi_send_recv(sh, 1, &rreg, + rlen, buf); + } else { + err = spi_send(sh, 1, &rreg); + } + + return err; +} + +static int +bmx280thpspi_read_reg(struct bmx280_sc *sc, uint8_t reg, uint8_t *buf, size_t rlen) +{ + return bmx280thpspi_read_reg_direct(sc->sc_sh, reg, buf, rlen); +} + +/* SPI writes to this device are normal enough. You send the register + * you want making sure that the high bit, 0x80, is clear and then the + * data. These pairs can be repeated as many times as you like. + */ +static int +bmx280thpspi_write_reg_direct(struct spi_handle *sh, uint8_t *buf, size_t slen) +{ + int err = 0; + int i; + + /* XXX - + this is probably BAD thing to do... but we must insure that the + registers have a cleared bit.. otherwise it is a read .... + */ + + for(i = 0; i < slen;i+=2) { + buf[i] = buf[i] & 0x7F; + } + + err = spi_send(sh, slen, buf); + + return err; +} + +static int +bmx280thpspi_write_reg(struct bmx280_sc *sc, uint8_t *buf, size_t slen) +{ + return bmx280thpspi_write_reg_direct(sc->sc_sh, buf, slen); +} + +/* These are to satisfy the common code */ +static int +bmx280thpspi_acquire_bus(struct bmx280_sc *sc) +{ + return 0; +} + +static void +bmx280thpspi_release_bus(struct bmx280_sc *sc) +{ + return; +} + +/* Nothing more is done here. Assumptions on whether or not + * the SPI interface is set up may not be proper.... for better + * or worse... and there is setting that are needed such as the + * SPI mode and bus speed that really should not be done here, so + * any active match might not work anyway. + */ +static int +bmx280thpspi_match(device_t parent, cfdata_t match, void *aux) +{ + const bool matchdebug = false; + + if (matchdebug) { + printf("Trying to match\n"); + } + + return 1; +} + +static void +bmx280thpspi_attach(device_t parent, device_t self, void *aux) +{ + struct bmx280_sc *sc; + struct spi_attach_args *sa; + int error; + + sa = aux; + sc = device_private(self); + + sc->sc_dev = self; + sc->sc_sh = sa->sa_handle; + sc->sc_bmx280debug = 0; + sc->sc_func_acquire_bus = &bmx280thpspi_acquire_bus; + sc->sc_func_release_bus = &bmx280thpspi_release_bus; + sc->sc_func_read_register = &bmx280thpspi_read_reg; + sc->sc_func_write_register = &bmx280thpspi_write_reg; + + /* Configure for 1MHz and SPI mode 0 according to the data sheet. + * The chip will actually handle a number of different modes and + * can go a lot faster, just use this for now... + */ + error = spi_configure(self, sa->sa_handle, SPI_MODE_0, 1000000); + if (error) { + return; + } + + /* Please note that if the pins are not set up for SPI, the attachment + * will probably not work out. + */ + bmx280_attach(sc); + + return; +} + +/* These really do not do a whole lot, as SPI devices do not seem to work + * as modules. + */ +static int +bmx280thpspi_detach(device_t self, int flags) +{ + struct bmx280_sc *sc; + + sc = device_private(self); + + mutex_destroy(&sc->sc_mutex); + + return 0; +} diff --git a/sys/dev/spi/files.spi b/sys/dev/spi/files.spi index e73dde62112..f7807089bfe 100644 --- a/sys/dev/spi/files.spi +++ b/sys/dev/spi/files.spi @@ -1,4 +1,4 @@ -# $NetBSD: files.spi,v 1.9 2022/01/17 16:31:23 thorpej Exp $ +# $NetBSD: files.spi,v 1.10 2022/12/03 01:04:43 brad Exp $ define spibus { } @@ -47,3 +47,7 @@ file dev/spi/mcp3k.c mcp3kadc # Sparkfun Serial motor controller attach scmd at spi with scmdspi file dev/spi/scmdspi.c scmdspi + +# Bosch BMP280 / BME280 sensor +attach bmx280thp at spi with bmx280thpspi +file dev/spi/bmx280thpspi.c bmx280thpspi |
