Module Name:    src
Committed By:   brad
Date:           Thu Nov 11 14:16:05 UTC 2021

Modified Files:
        src/share/man/man4: si70xxtemp.4
        src/sys/dev/i2c: si70xx.c si70xxvar.h

Log Message:
Some HTU21D chips do not have a heater register and apparently no
heater element.  Disable the heater features in the driver when that
condition is detected and let the attachment succeed.  Also mention
that the SHT21 is another clone.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/share/man/man4/si70xxtemp.4
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/i2c/si70xx.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/i2c/si70xxvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man4/si70xxtemp.4
diff -u src/share/man/man4/si70xxtemp.4:1.4 src/share/man/man4/si70xxtemp.4:1.5
--- src/share/man/man4/si70xxtemp.4:1.4	Thu Feb  8 09:03:23 2018
+++ src/share/man/man4/si70xxtemp.4	Thu Nov 11 14:16:04 2021
@@ -1,4 +1,4 @@
-.\" $NetBSD: si70xxtemp.4,v 1.4 2018/02/08 09:03:23 dholland Exp $
+.\" $NetBSD: si70xxtemp.4,v 1.5 2021/11/11 14:16:04 brad Exp $
 .\"
 .\" Copyright (c) 2017 Brad Spencer <b...@anduin.eldar.org>
 .\"
@@ -19,7 +19,7 @@
 .Os
 .Sh NAME
 .Nm si70xxtemp
-.Nd Driver for Silicon Labs SI7013/SI7020/SI7021 and HTU21D sensor chip via I2C bus
+.Nd Driver for Silicon Labs SI7013/SI7020/SI7021, HTU21D and SHT21 sensor chip via I2C bus
 .Sh SYNOPSIS
 .Cd "si70xxtemp* at iic? addr 0x40"
 .Sh DESCRIPTION
@@ -57,6 +57,9 @@ Turn the heater on and off.
 .It hw.si70xxtemp0.heaterstrength
 From 1 to 6, the amount of energy put into the heater.
 The higher the number, the more power used.
+.Pp
+Some HTU21D chips do not support a heater register.  These chips are
+detected and the heater features of the driver will be disabled.
 .It hw.si70xxtemp0.debug
 If the driver is compiled with
 .Dv SI70XX_DEBUG ,

Index: src/sys/dev/i2c/si70xx.c
diff -u src/sys/dev/i2c/si70xx.c:1.8 src/sys/dev/i2c/si70xx.c:1.9
--- src/sys/dev/i2c/si70xx.c:1.8	Sat Aug 21 11:55:25 2021
+++ src/sys/dev/i2c/si70xx.c	Thu Nov 11 14:16:04 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: si70xx.c,v 1.8 2021/08/21 11:55:25 andvar Exp $	*/
+/*	$NetBSD: si70xx.c,v 1.9 2021/11/11 14:16:04 brad Exp $	*/
 
 /*
  * Copyright (c) 2017 Brad Spencer <b...@anduin.eldar.org>
@@ -17,10 +17,10 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: si70xx.c,v 1.8 2021/08/21 11:55:25 andvar Exp $");
+__KERNEL_RCSID(0, "$NetBSD: si70xx.c,v 1.9 2021/11/11 14:16:04 brad Exp $");
 
 /*
-  Driver for the Silicon Labs SI7013/SI7020/SI7021
+  Driver for the Silicon Labs SI7013/SI7020/SI7021, HTU21D and SHT21
 */
 
 #include <sys/param.h>
@@ -442,7 +442,10 @@ static int
 si70xx_update_status(struct si70xx_sc *sc)
 {
 	int error1 = si70xx_update_user(sc);
-	int error2 = si70xx_update_heater(sc);
+	int error2 = 0;
+	if (! sc->sc_noheater) {
+		error2 = si70xx_update_heater(sc);
+	}
 	return error1 ? error1 : error2;
 }
 
@@ -547,17 +550,22 @@ si70xx_sysctl_init(struct si70xx_sc *sc)
 	    CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
 		return error;
 
-	if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
-	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron",
-	    SYSCTL_DESCR("Heater on"), si70xx_verify_sysctl_heateron, 0,
-	    (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
-		return error;
+	if (! sc->sc_noheater) {
+		if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
+		    CTLFLAG_READWRITE, CTLTYPE_BOOL, "heateron",
+		    SYSCTL_DESCR("Heater on"), si70xx_verify_sysctl_heateron, 0,
+		    (void *)sc, 0, CTL_HW, sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
+			return error;
+
+		if ((error = sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
+		    CTLFLAG_READWRITE, CTLTYPE_INT, "heaterstrength",
+		    SYSCTL_DESCR("Heater strength 1 to 6"),
+		    si70xx_verify_sysctl_heatervalue, 0, (void *)sc, 0, CTL_HW,
+		    sysctlroot_num, CTL_CREATE, CTL_EOL)) != 0)
+			return error;
+	}
 
-	return sysctl_createv(&sc->sc_si70xxlog, 0, NULL, &cnode,
-	    CTLFLAG_READWRITE, CTLTYPE_INT, "heaterstrength",
-	    SYSCTL_DESCR("Heater strength 1 to 6"),
-	    si70xx_verify_sysctl_heatervalue, 0, (void *)sc, 0, CTL_HW,
-	    sysctlroot_num, CTL_CREATE, CTL_EOL);
+	return 0;
 }
 
 static int
@@ -602,7 +610,7 @@ si70xx_attach(device_t parent, device_t 
 	uint8_t testcrcpt2[4];
 	uint8_t crc1 = 0, crc2 = 0;
 	uint8_t readcrc1 = 0, readcrc2 = 0;
-	uint8_t fwversion, model;
+	uint8_t fwversion = 0, model, heaterregister;
 
 	ia = aux;
 	sc = device_private(self);
@@ -617,6 +625,8 @@ si70xx_attach(device_t parent, device_t 
 	sc->sc_readattempts = 25;
 	sc->sc_ignorecrc = false;
 	sc->sc_sme = NULL;
+	sc->sc_noheater = false;
+	sc->sc_nofw = false;
 
 	aprint_normal("\n");
 
@@ -629,10 +639,6 @@ si70xx_attach(device_t parent, device_t 
 		sc->sc_sme = NULL;
 		return;
 	}
-	if ((error = si70xx_sysctl_init(sc)) != 0) {
-		aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error);
-		goto out;
-	}
 
 	error = iic_acquire_bus(sc->sc_tag, 0);
 	if (error) {
@@ -689,14 +695,31 @@ si70xx_attach(device_t parent, device_t 
 	if (error) {
 		aprint_error_dev(self, "Failed to read firmware version: %d\n",
 		    error);
-		ecount++;
+		sc->sc_nofw = true;
+	}
+	if (! sc->sc_nofw) {
+		fwversion = buf[0];
+		DPRINTF(sc, 2, ("%s: read fw values: %#x\n", device_xname(sc->sc_dev),
+		    fwversion));
+	}
+
+	error = si70xx_cmd1(sc, SI70XX_READ_HEATER_REG, &heaterregister, 1);
+
+	if (error) {
+		aprint_error_dev(self, "Failed to read heater register: %d\n",
+		    error);
+		sc->sc_noheater = true;
 	}
-	fwversion = buf[0];
-	DPRINTF(sc, 2, ("%s: read fw values: %#x\n", device_xname(sc->sc_dev),
-	    fwversion));
 
 	error = si70xx_update_status(sc);
+
 	iic_release_bus(sc->sc_tag, 0);
+
+	if ((error = si70xx_sysctl_init(sc)) != 0) {
+		aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", error);
+		goto out;
+	}
+
 	if (error != 0) {
 		aprint_error_dev(self, "Failed to update status: %x\n", error);
 		aprint_error_dev(self, "Unable to setup device\n");
@@ -754,7 +777,7 @@ si70xx_attach(device_t parent, device_t 
 		snprintf(modelstr, sizeof(modelstr), "SI70%d", model);
 		break;
 	default:
-		snprintf(modelstr, sizeof(modelstr), "Unknown SI70%d", model);
+		snprintf(modelstr, sizeof(modelstr), "Unknown model %d (maybe an HTU21D)", model);
 		break;
 	}
 

Index: src/sys/dev/i2c/si70xxvar.h
diff -u src/sys/dev/i2c/si70xxvar.h:1.2 src/sys/dev/i2c/si70xxvar.h:1.3
--- src/sys/dev/i2c/si70xxvar.h:1.2	Fri Dec 29 02:20:47 2017
+++ src/sys/dev/i2c/si70xxvar.h	Thu Nov 11 14:16:04 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: si70xxvar.h,v 1.2 2017/12/29 02:20:47 christos Exp $	*/
+/*	$NetBSD: si70xxvar.h,v 1.3 2021/11/11 14:16:04 brad Exp $	*/
 
 /*
  * Copyright (c) 2017 Brad Spencer <b...@anduin.eldar.org>
@@ -45,6 +45,8 @@ struct si70xx_sc {
 	uint32_t 	sc_clockstretch;
 #endif
 	int 		sc_readattempts;
+	bool		sc_noheater;
+	bool		sc_nofw;
 };
 
 struct si70xx_sensor {

Reply via email to