summaryrefslogtreecommitdiff
path: root/sysutils/hytctl
diff options
context:
space:
mode:
authorkardel <kardel>2015-09-06 06:50:52 +0000
committerkardel <kardel>2015-09-06 06:50:52 +0000
commitf28904008f031e00678931240d0f15b512596bdc (patch)
treea51d7e2cee91a3ae30d341e2c01c75ef1960c558 /sysutils/hytctl
parentb17090d7e2a9bbb7360b94d0bd49d312ce698598 (diff)
downloadpkgsrc-f28904008f031e00678931240d0f15b512596bdc.tar.gz
Added hytctl utility to manage HYT 221/271/939 EEPROMS
Diffstat (limited to 'sysutils/hytctl')
-rw-r--r--sysutils/hytctl/DESCR5
-rw-r--r--sysutils/hytctl/Makefile20
-rw-r--r--sysutils/hytctl/PLIST3
-rw-r--r--sysutils/hytctl/distinfo1
-rw-r--r--sysutils/hytctl/files/sbin/Makefile11
-rw-r--r--sysutils/hytctl/files/sbin/hytctl.865
-rw-r--r--sysutils/hytctl/files/sbin/hytctl.c405
-rw-r--r--sysutils/hytctl/files/sbin/hytp14reg.h83
8 files changed, 593 insertions, 0 deletions
diff --git a/sysutils/hytctl/DESCR b/sysutils/hytctl/DESCR
new file mode 100644
index 00000000000..86e1a18d122
--- /dev/null
+++ b/sysutils/hytctl/DESCR
@@ -0,0 +1,5 @@
+hytctl allows reading and writing of EEPROM values
+of the HYT 221, 271 and 939 temperatur/hygro devices.
+This tool is mainly used to change the I2C-address
+of the device to facilitate multiple devices on a
+single I2C-bus.
diff --git a/sysutils/hytctl/Makefile b/sysutils/hytctl/Makefile
new file mode 100644
index 00000000000..a2b09a915bb
--- /dev/null
+++ b/sysutils/hytctl/Makefile
@@ -0,0 +1,20 @@
+# $NetBSD: Makefile,v 1.1 2015/09/06 06:50:52 kardel Exp $
+
+PKGNAME= hytctl-1.0
+CATEGORIES= sysutils
+ONLY_FOR_PLATFORM= NetBSD-*-*
+
+MAINTAINER= kardel@NetBSD.org
+COMMENT= Admin tool to read/write HYT 221/271/939 device EEPROM values
+LICENSE= modified-bsd
+
+USE_BSD_MAKEFILE= yes
+
+INSTALLATION_DIRS= sbin ${PKGMANDIR}/man8
+
+.include "../../mk/bsd.prefs.mk"
+
+do-extract:
+ ${CP} -R ${FILESDIR}/sbin ${WRKSRC}
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/sysutils/hytctl/PLIST b/sysutils/hytctl/PLIST
new file mode 100644
index 00000000000..46444d9d956
--- /dev/null
+++ b/sysutils/hytctl/PLIST
@@ -0,0 +1,3 @@
+@comment $NetBSD: PLIST,v 1.1 2015/09/06 06:50:52 kardel Exp $
+man/man8/hytctl.8
+sbin/hytctl
diff --git a/sysutils/hytctl/distinfo b/sysutils/hytctl/distinfo
new file mode 100644
index 00000000000..765099495ef
--- /dev/null
+++ b/sysutils/hytctl/distinfo
@@ -0,0 +1 @@
+$NetBSD: distinfo,v 1.1 2015/09/06 06:50:52 kardel Exp $
diff --git a/sysutils/hytctl/files/sbin/Makefile b/sysutils/hytctl/files/sbin/Makefile
new file mode 100644
index 00000000000..9a660cc21c9
--- /dev/null
+++ b/sysutils/hytctl/files/sbin/Makefile
@@ -0,0 +1,11 @@
+# $NetBSD: Makefile,v 1.1 2015/09/06 06:50:53 kardel Exp $
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+BINDIR=${PREFIX}/sbin
+
+MAN= hytctl.8
+
+LDADD= -lutil
+PROG= hytctl
+
+.include <bsd.prog.mk>
diff --git a/sysutils/hytctl/files/sbin/hytctl.8 b/sysutils/hytctl/files/sbin/hytctl.8
new file mode 100644
index 00000000000..43c5679cb8b
--- /dev/null
+++ b/sysutils/hytctl/files/sbin/hytctl.8
@@ -0,0 +1,65 @@
+.\" $NetBSD: hytctl.8,v 1.1 2015/09/06 06:50:53 kardel Exp $
+.\"
+.\" Copyright (c) 2015 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Frank Kardel.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"
+.Dd Sep 5, 2015
+.Dt HYTCTL 8
+.Os
+.Sh NAME
+.Nm hytctl
+.Nd read or set HYT 221/271/939 device EEPROM values
+.Sh SYNOPSIS
+.Nm
+.Op Fl d
+.Ar gpio-device
+.Ar gpio-pin#|name
+.Ar i2c-device
+.Ar i2c-address
+.Ar eeprom-address
+.Op new-eeprom-value
+.Sh DESCRIPTION
+The
+.Nm hytctl
+command will read out a value at a given EEPROM address and can optionally
+set the value at this address. The man usage is setting a new I2C-address
+of the device via EEPROM address 0x1C.
+.Pp
+To access the EEPROM of the HYT devices the CM mode is used. This mode can
+only be entered within 10ms after device power-up. Thus a GPIO pin must
+be attached to Vdd on the device in order to be able to control the device
+power. Communication is done normally via the I2C-bus.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Enable debug output.
+.El
+.Sh RETURN VALUES
+.Ex -std hytctl
+.Sh AUTHORS
+.An Frank Kardel
diff --git a/sysutils/hytctl/files/sbin/hytctl.c b/sysutils/hytctl/files/sbin/hytctl.c
new file mode 100644
index 00000000000..22c25e7b93c
--- /dev/null
+++ b/sysutils/hytctl/files/sbin/hytctl.c
@@ -0,0 +1,405 @@
+/*
+ * $Header: /cvsroot/pkgsrc/sysutils/hytctl/files/sbin/hytctl.c,v 1.1 2015/09/06 06:50:53 kardel Exp $
+ *
+ * $Created: Fri May 16 20:29:08 2014 $
+ */
+
+ /*-
+ * Copyright (c) 2015 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Frank Kardel.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: hytctl.c,v 1.1 2015/09/06 06:50:53 kardel Exp $");
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/gpio.h>
+#include "hytp14reg.h"
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <util.h>
+
+#include <dev/i2c/i2c_io.h>
+
+#define ARG_GPIODEV 1
+#define ARG_GPIOPIN 2
+#define ARG_I2CDEV 3
+#define ARG_I2CADDR 4
+#define ARG_EEPROMADDR 5
+#define ARG_EEPROMVAL 6
+
+static int debug = 0;
+
+__dead static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-d] <gpio-dev> <pin#|pin-name> <i2c-dev> <i2c-addr> <eeprom-address> [<new eeprom value>]\n", getprogname());
+ exit(EXIT_FAILURE);
+}
+
+static void
+waitfor(int usec)
+{
+ struct timeval tv1;
+ struct timeval tv2;
+
+ gettimeofday(&tv1, NULL);
+
+ tv2.tv_sec = tv1.tv_sec + usec / 1000000;
+ tv2.tv_usec = tv1.tv_usec + usec % 1000000;
+ tv2.tv_sec += tv2.tv_usec / 1000000;
+ tv2.tv_usec %= 1000000;
+
+ while (tv2.tv_sec > tv1.tv_sec || (tv2.tv_usec > tv1.tv_usec && tv2.tv_sec == tv1.tv_sec)) {
+ gettimeofday(&tv1, NULL);
+ }
+}
+
+static int
+iic_write(int fd, i2c_addr_t addr, int clen, uint8_t *cmd, int blen, uint8_t *buf)
+{
+ i2c_ioctl_exec_t iie;
+
+ iie.iie_op = I2C_OP_WRITE_WITH_STOP;
+ iie.iie_addr = addr;
+ iie.iie_cmd = cmd;
+ iie.iie_cmdlen = clen;
+ iie.iie_buf = buf;
+ iie.iie_buflen = blen;
+
+ if (ioctl(fd, I2C_IOCTL_EXEC, &iie) == -1) {
+ return errno;
+ }
+
+ return 0;
+}
+
+static int
+iic_read(int fd, i2c_addr_t addr, int clen, uint8_t *cmd, int blen, uint8_t *buf)
+{
+ i2c_ioctl_exec_t iie;
+
+ iie.iie_op = I2C_OP_READ_WITH_STOP;
+ iie.iie_addr = addr;
+ iie.iie_cmd = cmd;
+ iie.iie_cmdlen = clen;
+ iie.iie_buf = buf;
+ iie.iie_buflen = blen;
+
+ if (ioctl(fd, I2C_IOCTL_EXEC, &iie) == -1) {
+ return errno;
+ }
+
+ return 0;
+}
+
+static int
+exec_cmd(int fd, i2c_addr_t addr, int cmdlen, uint8_t *cmd, int datalen, uint8_t *data)
+{
+ int error;
+
+ /* send command */
+ if ((error = iic_write(fd, addr, cmdlen, cmd, 0, NULL)) == 0)
+ {
+ int loops = 0;
+
+ for (;;) {
+ /* read reply */
+ memset(data, 0, datalen);
+
+ if ((error = iic_read(fd, addr, 0, NULL, sizeof data, data)) == 0)
+ {
+ if (data[0] & HYTP14_RESP_CMDMODE) {
+ char b[80];
+
+ snprintb(b, sizeof b, HYT_STATUS_FMT,
+ data[0]);
+
+ if (debug) {
+ fprintf(stderr, "CM_MODE command 0x%02x status=%s\n", cmd[0], b);
+ }
+ } else {
+ if (cmd[0] != HYTP14_CMD_START_NOM)
+ fprintf(stderr, "CM mode command 0x%02x unexpectedly turned off\n", cmd[0]);
+ return 0;
+ }
+
+ switch (data[0] & HYTP14_RESP_MASK)
+ {
+ case HYTP14_RESP_ACK:
+ return 1;
+
+ case HYTP14_RESP_NACK:
+ fprintf(stderr, "Command 0x%02x failed with NACK\n", cmd[0]);
+ return 0;
+
+ case HYTP14_RESP_BUSY:
+ /* do not wait forever for an ACK */
+ if (++loops > 100) {
+ fprintf(stderr, "result wait loop count exceeded\n");
+ return 0;
+ }
+ }
+ } else {
+ if (cmd[0] != HYTP14_CMD_START_NOM)
+ fprintf(stderr, "Command 0x%02x READ failed (errno=%d)\n", cmd[0], error);
+ return 0;
+ }
+ }
+ } else {
+ fprintf(stderr, "Command 0x%02x WRITE failed (errno=%d)\n", cmd[0], error);
+ return 0;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ int argidx = 0;
+ int gfd, fd, error;
+ i2c_addr_t addr = HYTP14_DEFAULT_ADDR;
+ int eeaddr = 0;
+ uint8_t data[4];
+ uint8_t cmd[3];
+ int count = 0;
+ char *endptr;
+ long gpio_pinnumber = -1;
+ int pinstatus;
+ struct gpio_info gpioinfo;
+ struct gpio_req gpioreq;
+ struct gpio_set gpioset;
+
+ setprogname(*argv);
+
+ if ((argc > 1) && (strcmp(argv[1], "-d") == 0)) {
+ debug = 1;
+ argidx = 1;
+ }
+
+ if ((argc-argidx) <= ARG_EEPROMADDR) {
+ usage();
+ }
+
+ fd = open(argv[argidx + ARG_I2CDEV], O_RDWR);
+ if (fd == -1) {
+ err(EXIT_FAILURE, "couldn't open %s", argv[argidx + ARG_I2CDEV]);
+ }
+
+ addr = strtol(argv[argidx + ARG_I2CADDR], &endptr, 0);
+ if (addr < 1 || addr > 0x7f || argv[argidx + ARG_I2CADDR][0] == '\0' || *endptr != '\0') {
+ err(EXIT_FAILURE, "I2C address (%s) is invalid", argv[argidx + ARG_I2CADDR]);
+ }
+
+ eeaddr = strtol(argv[argidx + ARG_EEPROMADDR], &endptr, 0);
+ if (eeaddr < 0 || eeaddr >= HYTP14_NUM_WORDS || argv[argidx + ARG_EEPROMADDR][0] == '\0' || *endptr != '\0') {
+ err(EXIT_FAILURE, "HYT EEPROM address (%s) is invalid", argv[argidx + ARG_EEPROMADDR]);
+ }
+
+ gpio_pinnumber = strtol(argv[argidx + ARG_GPIOPIN], &endptr, 0);
+ if (argv[argidx + ARG_GPIOPIN][0] != '\0' && *endptr == '\0') {
+ gpioreq.gp_pin = gpio_pinnumber;
+ gpioreq.gp_name[0] = '\0';
+ gpioset.gp_pin = gpio_pinnumber;
+ gpioset.gp_name[0] = '\0';
+ } else {
+ gpioreq.gp_pin = -1;
+ strncpy(gpioreq.gp_name, argv[argidx + ARG_GPIOPIN],
+ sizeof gpioreq.gp_name);
+ gpioset.gp_pin = -1;
+ strncpy(gpioset.gp_name, argv[argidx + ARG_GPIOPIN],
+ sizeof gpioset.gp_name);
+ }
+ gpioset.gp_flags = 0;
+ gpioset.gp_name2[0] = '\0';
+
+ gfd = open(argv[argidx + ARG_GPIODEV], O_RDWR);
+ if (gfd == -1) {
+ err(EXIT_FAILURE, "couldn't open %s", argv[argidx + ARG_GPIODEV]);
+ }
+
+ if (ioctl(gfd, GPIOSET, &gpioset) == -1) {
+ err(EXIT_FAILURE, "failed getting GPIO configuration");
+ }
+
+ if (debug) {
+ printf("GPIO: Pin %d (%s) flags: 0x%x\n",
+ gpioset.gp_pin, gpioset.gp_name, gpioset.gp_flags);
+ }
+
+ if ((gpioset.gp_flags & (GPIO_PIN_OUTPUT|GPIO_PIN_INOUT)) == 0) {
+ err(EXIT_FAILURE, "Pin %d (%s) not configured for output",
+ gpioset.gp_pin, gpioset.gp_name);
+ }
+
+ if (ioctl(gfd, GPIOREAD, &gpioreq) == -1) {
+ err(EXIT_FAILURE, "failed getting GPIO status");
+ }
+
+ if (debug) {
+ printf("GPIO: Pin %d (%s) state %s\n",
+ gpioreq.gp_pin, gpioreq.gp_name,
+ (gpioreq.gp_value == GPIO_PIN_HIGH) ? "HIGH" : "LOW");
+ }
+
+ pinstatus = gpioreq.gp_value;
+
+ if (gpioreq.gp_value == GPIO_PIN_HIGH) {
+ gpioreq.gp_value = GPIO_PIN_LOW;
+
+ if (ioctl(gfd, GPIOWRITE, &gpioreq) == -1) {
+ err(EXIT_FAILURE, "failed switching off gpio pin");
+ }
+ }
+
+ waitfor(10000);
+
+ gpioreq.gp_value = GPIO_PIN_HIGH;
+
+ if (ioctl(gfd, GPIOWRITE, &gpioreq) == -1) {
+ err(EXIT_FAILURE, "failed switching on gpio pin");
+ }
+
+ waitfor(1000);
+
+ memset(data, 0, sizeof data);
+ memset(cmd, 0, sizeof cmd);
+
+ cmd[0] = HYTP14_CMD_START_CM;
+
+ /* send START_CM command */
+ while (!exec_cmd(fd, addr, sizeof cmd, cmd, sizeof data, data)
+ && ++count < 3)
+ /* empty */;
+
+ if (count >= 3) {
+ printf("FAILED entering CM mode\n");
+ } else {
+ cmd[0] = HYTP14_CMD_GET_REV;
+
+ if (exec_cmd(fd, addr, sizeof cmd, cmd, sizeof data, data))
+ {
+ printf("Revision = 0x%02x%02x\n", data[1], data[2]);
+ } else {
+ errc(EXIT_FAILURE, error,
+ "sending GET_REV command to %s address 0x%x",
+ argv[argidx + ARG_I2CDEV], addr);
+ }
+
+ cmd[0] = HYTP14_READ_EEPROM(eeaddr);
+
+ if (exec_cmd(fd, addr, sizeof cmd, cmd, sizeof data, data))
+ {
+ printf("EEPROM(0x%02x) = 0x%02x%02x\n",
+ eeaddr, data[1], data[2]);
+ } else {
+ errc(EXIT_FAILURE, error,
+ "sending READ_EEPROM command to %s address 0x%x",
+ argv[argidx + ARG_I2CDEV], addr);
+ }
+
+ if (argc > argidx + ARG_EEPROMVAL) {
+ long val;
+
+ val = strtol(argv[argidx + ARG_EEPROMVAL], &endptr, 0);
+ if (argv[argidx + ARG_EEPROMVAL][0] == '\0' || *endptr != '\0') {
+ err(EXIT_FAILURE,
+ "EEPROM value (%s) is invalid",
+ argv[argidx + ARG_EEPROMVAL]);
+ }
+
+ cmd[0] = HYTP14_WRITE_EEPROM(eeaddr);
+ cmd[1] = (val >> 8) & 0xFF;
+ cmd[2] = val & 0xFF;
+
+ if (exec_cmd(fd, addr,
+ sizeof cmd, cmd, sizeof data, data))
+ {
+ printf("EEPROM(0x%02x) set to 0x%02x%02x\n",
+ eeaddr, cmd[1], cmd[2]);
+
+ memset(cmd, 0, sizeof cmd);
+ cmd[0] = HYTP14_READ_EEPROM(eeaddr);
+
+ if (exec_cmd(fd, addr, sizeof cmd, cmd,
+ sizeof data, data))
+ {
+ printf("EEPROM(0x%02x) = 0x%02x%02x\n",
+ eeaddr, data[1], data[2]);
+ }
+ else
+ {
+ errc(EXIT_FAILURE, error,
+ "sending READ_EEPROM command to %s address 0x%x",
+ argv[argidx + ARG_I2CDEV], addr);
+ }
+ } else {
+ errc(EXIT_FAILURE, error,
+ "sending WRITE_EEPROM command to %s address 0x%x",
+ argv[argidx + ARG_I2CDEV], addr);
+ }
+ }
+
+ /* leave command mode */
+ memset(cmd, 0, sizeof cmd);
+ cmd[0] = HYTP14_CMD_START_NOM;
+
+ exec_cmd(fd, addr, sizeof cmd, cmd, sizeof data, data);
+ }
+
+ /* restore original pin status */
+ gpioreq.gp_value = pinstatus;
+
+ if (ioctl(gfd, GPIOWRITE, &gpioreq) == -1) {
+ err(EXIT_FAILURE, "failed restoring gpio pin status");
+ } else {
+ if (debug) {
+ printf("GPIO: Pin %d (%s) state %s\n",
+ gpioreq.gp_pin, gpioreq.gp_name,
+ (gpioreq.gp_value == GPIO_PIN_HIGH) ? "HIGH" : "LOW");
+ }
+ }
+
+ close(gfd);
+
+ close(fd);
+
+ return EXIT_SUCCESS;
+}
+
+/*
+ * $Log: hytctl.c,v $
+ * Revision 1.1 2015/09/06 06:50:53 kardel
+ * Added hytctl utility to manage HYT 221/271/939 EEPROMS
+ *
+ */
diff --git a/sysutils/hytctl/files/sbin/hytp14reg.h b/sysutils/hytctl/files/sbin/hytp14reg.h
new file mode 100644
index 00000000000..cc1e0e28098
--- /dev/null
+++ b/sysutils/hytctl/files/sbin/hytp14reg.h
@@ -0,0 +1,83 @@
+/* $NetBSD: hytp14reg.h,v 1.1 2015/09/06 06:50:53 kardel Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Frank Kardel.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * IST-AG P14 calibrated Hygro-/Temperature sensor module
+ * Devices: HYT-271, HYT-221 and HYT-939
+ *
+ * see:
+ * http://www.ist-ag.com/eh/ist-ag/resource.nsf/imgref/Download_AHHYTM_E2.1.pdf/
+ * $FILE/AHHYTM_E2.1.pdf
+ */
+#ifndef _DEV_I2C_HYTP14REG_H_
+#define _DEV_I2C_HYTP14REG_H_
+
+#define HYTP14_DEFAULT_ADDR 0x28
+
+#define HYTP14_CMD_START_NOM 0x80 /* end command mode (or power-off) */
+#define HYTP14_CMD_START_CM 0xA0 /* start command mode (within 10ms after power-up) */
+#define HYTP14_CMD_GET_REV 0xB0 /* get revison */
+
+#define HYTP14_NUM_WORDS 32
+#define HYTP14_READ_OFFSET 0x00 /* command offset to read EEPROM words */
+#define HYTP14_WRITE_OFFSET 0x40 /* command offset to write EEPROM words */
+
+#define HYTP14_READ_EEPROM(_X_) (HYTP14_READ_OFFSET + ((_X_) & (HYTP14_NUM_WORDS - 1)))
+#define HYTP14_WRITE_EEPROM(_X_) (HYTP14_WRITE_OFFSET + ((_X_) & (HYTP14_NUM_WORDS - 1)))
+
+#define HYTP14_EEADDR_I2CADDR 0x1C /* I2C address EEPROM word address */
+
+#define HYTP14_RESP_CMDMODE 0x80 /* command mode response */
+#define HYTP14_RESP_STALE 0x40 /* stale measurement data */
+
+#define HYT_STATUS_FMT "\177\20b\7CM\0b\6STALE\0b\5ERR_CFG\0b\4ERR_RAM\0b\3ERR_UNCEEP\0"\
+ "b\2ERR_COREEP\0f\0\2RESP\0=\0BSY\0=\1ACK\0=\2NAK\0=\3INV\0\0"
+
+#define HYTP14_DIAG_ERR_CFG 0x20 /* configuration error */
+#define HYTP14_DIAG_ERR_RAMPRTY 0x10 /* RAM parity error */
+#define HYTP14_DIAG_ERR_UNCEEP 0x08 /* uncorrectable EEPROM error */
+#define HYTP14_DIAG_ERR_COREEP 0x04 /* correctable EEPROM error */
+
+#define HYTP14_RESP_MASK 0x03
+#define HYTP14_RESP_BUSY 0x00 /* device is busy */
+#define HYTP14_RESP_ACK 0x01 /* positive acknowlege */
+#define HYTP14_RESP_NACK 0x02 /* negative acknowlege */
+
+#define HYTP14_ST_CMDMODE 0x8000 /* command mode */
+#define HYTP14_ST_STALE 0x4000 /* stale measurement data */
+#define HYTP14_HYG_RAWVAL(_X_) ((_X_) & 0x3FFF)
+#define HYTP14_HYG_SCALE (1<<14)
+#define HYTP14_TEMP_RAWVAL(_X_) (((_X_) >> 2) & 0x3FFF)
+#define HYTP14_TEMP_SCALE (1<<14)
+#define HYTP14_TEMP_FACTOR 165
+#define HYTP14_TEMP_OFFSET (-40)
+
+#endif