32#include "opt_platform.h"
36#include <sys/kernel.h>
37#include <sys/module.h>
38#include <sys/sysctl.h>
41#include <machine/bus.h>
47#include <dev/ofw/ofw_bus.h>
48#include <dev/ofw/ofw_bus_subr.h>
61#define HTU21_ADDR 0x40
63#define HTU21_GET_TEMP 0xe3
64#define HTU21_GET_HUM 0xe5
65#define HTU21_GET_TEMP_NH 0xf3
66#define HTU21_GET_HUM_NH 0xf5
67#define HTU21_WRITE_CFG 0xe6
68#define HTU21_READ_CFG 0xe7
69#define HTU21_RESET 0xfe
71#define HTU2x_SERIAL0_0 0xfa
72#define HTU2x_SERIAL0_1 0x0f
73#define HTU2x_SERIAL1_0 0xfc
74#define HTU2x_SERIAL1_1 0xc9
86 {
"meas,htu21",
true },
94 static const uint16_t polynomial = 0x3100;
97 for (i = 0; i < 16; i++) {
98 int msb_neq =
data & 0x8000;
113 return (crc == expected);
122 return (crc == expected);
133 sc = device_get_softc(
dev);
150 uint8_t *
data,
int count)
157 sc = device_get_softc(
dev);
173 for (i = 0; i < hz; i++) {
193 sc = device_get_softc(
dev);
195 if (req->oldptr != NULL) {
198 raw_data, nitems(raw_data));
209 temp = (((uint16_t)raw_data[0]) << 8) |
210 (raw_data[1] & 0xfc);
211 temp = ((temp * 17572) >> 16 ) + 27315 - 4685;
215 error = sysctl_handle_int(oidp, &temp, 0, req);
228 sc = device_get_softc(
dev);
230 if (req->oldptr != NULL) {
233 raw_data, nitems(raw_data));
244 rh = (((uint16_t)raw_data[0]) << 8) |
245 (raw_data[1] & 0xfc);
246 rh = ((rh * 12500) >> 16 ) - 600;
250 error = sysctl_handle_int(oidp, &rh, 0, req);
263 sc = device_get_softc(
dev);
288 sc = device_get_softc(
dev);
309 if (req->oldptr != NULL) {
313 heater = (cfg & 0x04) != 0;
315 error = sysctl_handle_int(oidp, &heater, 0, req);
316 if (error != 0 || req->newptr == NULL)
320 cfg |= (heater > 0) << 2;
322 return (error != 0 ? EIO : 0);
334 if (req->oldptr != NULL) {
338 power = (cfg & 0x40) == 0;
340 error = sysctl_handle_int(oidp, &power, 0, req);
355 int error, cksum_err;
358 sc = device_get_softc(
dev);
376 for (i = 0; i < nitems(
data); i += 2) {
416 struct sysctl_ctx_list *ctx;
417 struct sysctl_oid *tree_node;
418 struct sysctl_oid_list *tree;
424 for (
int i = 0; i < 5; i++) {
430 device_printf(
dev,
"serial number: %8D (checksum %scorrect)\n",
431 sc->
sc_serial,
":", error == 0 ?
"" :
"in");
433 device_printf(
dev,
"failed to get serial number, err = %d\n",
437 ctx = device_get_sysctl_ctx(
dev);
438 tree_node = device_get_sysctl_tree(
dev);
439 tree = SYSCTL_CHILDREN(tree_node);
441 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO,
"temperature",
442 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
dev, 0,
444 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO,
"humidity",
445 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
dev, 0,
447 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO,
"heater",
448 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
dev, 0,
450 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO,
"power",
451 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
dev, 0,
453 SYSCTL_ADD_BOOL(ctx, tree, OID_AUTO,
"hold_bus",
455 "Whether device should hold I2C bus while measuring");
456 SYSCTL_ADD_INT(ctx, tree, OID_AUTO,
"crc_errors",
457 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, &sc->
sc_errcount, 0,
458 "Number of checksum errors");
468 if (!ofw_bus_status_okay(
dev))
471 rc = BUS_PROBE_GENERIC;
474 rc = BUS_PROBE_NOWILDCARD;
478 device_printf(
dev,
"non-standard slave address 0x%02x\n",
482 device_set_desc(
dev,
"HTU21 temperature and humidity sensor");
491 sc = device_get_softc(
dev);
static ds13_compat_data compat_data[]
static int htu21_temp_sysctl(SYSCTL_HANDLER_ARGS)
static uint8_t calc_crc(uint16_t data)
static int htu21_heater_sysctl(SYSCTL_HANDLER_ARGS)
static void htu21_start(void *arg)
static int htu21_get_measurement_nohold(device_t dev, uint8_t cmd, uint8_t *data, int count)
static int htu21_get_serial(device_t dev)
static int htu21_probe(device_t dev)
static driver_t htu21_driver
MODULE_DEPEND(htu21, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER)
static int check_crc_8(const uint8_t data, uint8_t expected)
static int htu21_attach(device_t dev)
static device_method_t htu21_methods[]
#define HTU21_GET_TEMP_NH
DRIVER_MODULE(htu21, iicbus, htu21_driver, htu21_devclass, 0, 0)
static int htu21_get_cfg(device_t dev, uint8_t *cfg)
static int htu21_power_sysctl(SYSCTL_HANDLER_ARGS)
static devclass_t htu21_devclass
static int htu21_detach(device_t dev)
static int htu21_get_measurement(device_t dev, uint8_t cmd, uint8_t *data, int count)
IICBUS_FDT_PNP_INFO(compat_data)
static int htu21_set_cfg(device_t dev, uint8_t cfg)
static int htu21_rh_sysctl(SYSCTL_HANDLER_ARGS)
static int check_crc_16(const uint8_t *data, uint8_t expected)
int iicbus_transfer_excl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs, int how)