summaryrefslogtreecommitdiff
path: root/sys/dev/spi
diff options
context:
space:
mode:
authorbrad <brad@NetBSD.org>2022-12-03 01:04:42 +0000
committerbrad <brad@NetBSD.org>2022-12-03 01:04:42 +0000
commit02b8954fe89d72e580aac9928e8f0dd91cabaedc (patch)
tree3d66e5b9ef8e2812eb0fd4eb5c10499ac92a1975 /sys/dev/spi
parenta76f61463de79fb55af1db5ff83b1f68aeca0073 (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.c205
-rw-r--r--sys/dev/spi/files.spi6
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