From nobody Fri Sep 09 11:50:15 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MPDng58WHz4cSbg; Fri, 9 Sep 2022 11:50:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MPDng4g7Qz3XPd; Fri, 9 Sep 2022 11:50:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662724215; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=tN0sqMSKLGuk3l0hthHog7VsHrgquvgWmqyl0jNIX/Y=; b=sxVTwHDPxZHhTWJm2NyZ9phGCweVcTxTpRKPVzZCs6El/KinT/0451/XUa8Vxjrp0huw+K 4KCC24zCBudFY9O/guMPOYTapxxpRxZUGmLLEKtKcPjLfl0LS10B2ctUfAXwey1fZX00uA F2yHHbDikzaMQkSjP3doIS0rizXap9uAxftyzcawsObSVmecDUf9I0gt8fiCcZFocQy8fx XSLiFFZV5ZYIwMhKCvD38efQCJpU5E1v9+ACFqrpck6tKeZ5dXgBeGqK/5hjXNZsLG4iX8 m8q/4Ch/OKJKgq/9MqhteZ0fYNbQ7eNB+mkBdk6EArCd3BPmMj+hDtsvOKET6g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MPDng3jWvz1BsP; Fri, 9 Sep 2022 11:50:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 289BoFrx037526; Fri, 9 Sep 2022 11:50:15 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 289BoFnp037520; Fri, 9 Sep 2022 11:50:15 GMT (envelope-from git) Date: Fri, 9 Sep 2022 11:50:15 GMT Message-Id: <202209091150.289BoFnp037520@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: =?utf-8?Q?Kornel=20Dul=C4=99ba?= Subject: git: 6665c7a62839 - main - TMP461: Add support for ADT7461 sensor List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kd X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6665c7a62839142e0e8e2b0c4899e20a60ad8bc5 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662724215; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=tN0sqMSKLGuk3l0hthHog7VsHrgquvgWmqyl0jNIX/Y=; b=HwuYN+aIMvFp3epRLHz6zEwHwoQsTtLigWGUw+SYZLv1dBhNnugFcGuOh5sa00lttwCN9g PjGS3zGiOCSA7hw5Eo+hn9+CbpKIEX+NNW4jtREzLWzc8fPyZoDrRYKUBWohrpMs4GSKZg zokU/uIRTmAlAyxqWiVj1zbpW9c+eqCaBY018NlIwTv8pnJbFx09+tI2NbEtVtUdvcxmdc o0qNJUhmqgroc3a1VHwNPoA5q0XKxw29StEe9w+Mmqpf6sKHgX4dznttsrRZXEH+ZjXpVb 91cV7qxdlB0xJ4ofClr7GoMeuJiIGW1tZJQElk+5SnxxjIf1ZWQUY5IHgSaveA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1662724215; a=rsa-sha256; cv=none; b=A4MTHx9MJ/Zci52xKtwh14SYOsLGNfftKgWXQ5C0ex/bmk2m9fXmEmIjKKyFaetzyTMs4M oMov8sOFuNb6dDDZAzIhRg5+3PTYkb7eNSf2P8iH+lJHTVrWSuMtKXyRcD+VWVJ0wwnRhh SvBhP5KFJGJzkoh2PFMBS6Cp/c1uox0AUfnYmrvrV2iWhbhyL+BYV65bUrGL3kZTGN77+e atbaAu097F8lpvZlYrjBx73mT8dg4aFNx8FWMiwBqlkED4QjXDSVijQI8HL4AyF+WgAjJF D8KHcBsFUHSBh9+CcSasGT6e8bymmAArnGiUUFvfoTL8Q2lFjAC1b9p/Wm4eoQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kd: URL: https://cgit.FreeBSD.org/src/commit/?id=6665c7a62839142e0e8e2b0c4899e20a60ad8bc5 commit 6665c7a62839142e0e8e2b0c4899e20a60ad8bc5 Author: Mateusz Kozyra AuthorDate: 2022-09-09 08:36:22 +0000 Commit: Kornel Dulęba CommitDate: 2022-09-09 11:42:28 +0000 TMP461: Add support for ADT7461 sensor The register map is fairly similar, with one difference in the local sensor temperature register width. Both devices support reading two sensors - "local" and "remote". While here add support for the latter one. The ADT7461 doesn't update the temperature correctly, unless a write transaction is done before every read. Do just that as a workaround for this issue. Tested on LS1046ARDB. Reviewed by: manu Obtained from: Semihalf Differential Revision: https://reviews.freebsd.org/D36464 --- sys/dev/iicbus/tmp461.c | 191 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 156 insertions(+), 35 deletions(-) diff --git a/sys/dev/iicbus/tmp461.c b/sys/dev/iicbus/tmp461.c index 3956ca6d4c21..d967f4d91db9 100644 --- a/sys/dev/iicbus/tmp461.c +++ b/sys/dev/iicbus/tmp461.c @@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include @@ -46,22 +48,37 @@ __FBSDID("$FreeBSD$"); #define BIT(x) (1UL << (x)) +/* register map */ #define TMP461_LOCAL_TEMP_REG_MSB 0x0 #define TMP461_LOCAL_TEMP_REG_LSB 0x15 #define TMP461_GLOBAL_TEMP_REG_MSB 0x1 #define TMP461_GLOBAL_TEMP_REG_LSB 0x10 -#define TMP461_CONFIG_REG 0x3 +#define TMP461_STATUS_REG 0x2 +#define TMP461_STATUS_REG_TEMP_LOCAL BIT(2) +#define TMP461_CONFIG_REG_R 0x3 +#define TMP461_CONFIG_REG_W 0x9 #define TMP461_CONFIG_REG_TEMP_RANGE_BIT BIT(2) - +#define TMP461_CONFIG_REG_STANDBY_BIT BIT(6) +#define TMP461_CONVERSION_RATE_REG 0x4 +#define TMP461_ONESHOT_REG 0xF #define TMP461_EXTENDED_TEMP_MODIFIER 64 + /* 28.4 fixed point representation of 273.15f */ #define TMP461_C_TO_K_FIX 4370 -#define TMP461_TEMP_LSB 0 + +#define TMP461_SENSOR_MAX_CONV_TIME 16000000 +#define TMP461_LOCAL_MEASURE 0 +#define TMP461_REMOTE_MEASURE 1 + +/* flags */ +#define TMP461_LOCAL_TEMP_DOUBLE_REG BIT(0) +#define TMP461_REMOTE_TEMP_DOUBLE_REG BIT(1) static int tmp461_probe(device_t dev); static int tmp461_attach(device_t dev); static int tmp461_read_1(device_t dev, uint8_t reg, uint8_t *data); -static int tmp461_read_temp(device_t dev, int32_t *temp); +static int tmp461_write_1(device_t dev, uint8_t reg, uint8_t data); +static int tmp461_read_temperature(device_t dev, int32_t *temperature, bool mode); static int tmp461_detach(device_t dev); static int tmp461_sensor_sysctl(SYSCTL_HANDLER_ARGS); @@ -73,15 +90,34 @@ static device_method_t tmp461_methods[] = { DEVMETHOD_END }; +struct tmp461_softc { + struct mtx mtx; + uint8_t conf; +}; + static driver_t tmp461_driver = { "tmp461_dev", tmp461_methods, - 0 + sizeof(struct tmp461_softc) +}; + +struct tmp461_data { + const char *compat; + const char *desc; + uint8_t flags; +}; + +static struct tmp461_data sensor_list[] = { + {"adt7461", "ADT7461 Thernal Sensor Information", + TMP461_REMOTE_TEMP_DOUBLE_REG}, + {"tmp461", "TMP461 Thernal Sensor Information", + TMP461_LOCAL_TEMP_DOUBLE_REG | TMP461_REMOTE_TEMP_DOUBLE_REG} }; static struct ofw_compat_data tmp461_compat_data[] = { - { "ti,tmp461", 1 }, - { NULL, 0 } + {"adi,adt7461", (uintptr_t)&sensor_list[0]}, + {"ti,tmp461", (uintptr_t)&sensor_list[1]}, + {NULL, 0} }; DRIVER_MODULE(tmp461, iicbus, tmp461_driver, 0, 0); @@ -91,19 +127,47 @@ static int tmp461_attach(device_t dev) { struct sysctl_oid *sensor_root_oid; + struct tmp461_data *compat_data; struct sysctl_ctx_list *ctx; + struct tmp461_softc *sc; + uint8_t data; + sc = device_get_softc(dev); + compat_data = (struct tmp461_data *) + ofw_bus_search_compatible(dev, tmp461_compat_data)->ocd_data; + sc->conf = compat_data->flags; ctx = device_get_sysctl_ctx(dev); - + + mtx_init(&sc->mtx, "tmp461 temperature", "temperature", MTX_DEF); + sensor_root_oid = SYSCTL_ADD_NODE(ctx, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "temperature", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, - "TMP 461 Thermal Sensor Information"); + "Thermal Sensor Information"); if (sensor_root_oid == NULL) return (ENXIO); SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(sensor_root_oid), OID_AUTO, - "tmp461", CTLTYPE_INT | CTLFLAG_RD, dev, 0, - tmp461_sensor_sysctl, "IK0", "TMP461 Thermal Sensor"); + "local_sensor", CTLTYPE_INT | CTLFLAG_RD, dev, + TMP461_LOCAL_MEASURE, tmp461_sensor_sysctl, + "IK1", compat_data->desc); + + /* get status register */ + if (tmp461_read_1(dev, TMP461_STATUS_REG, &data) != 0) + return (ENXIO); + + if (!(data & TMP461_STATUS_REG_TEMP_LOCAL)) + SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(sensor_root_oid), OID_AUTO, + "remote_sensor", CTLTYPE_INT | CTLFLAG_RD, dev, + TMP461_REMOTE_MEASURE, tmp461_sensor_sysctl, + "IK1", compat_data->desc); + + /* set standby mode */ + if (tmp461_read_1(dev, TMP461_CONFIG_REG_R, &data) != 0) + return (ENXIO); + + data |= TMP461_CONFIG_REG_STANDBY_BIT; + if (tmp461_write_1(dev, TMP461_CONFIG_REG_W, data) != 0) + return (ENXIO); return (0); } @@ -111,14 +175,17 @@ tmp461_attach(device_t dev) static int tmp461_probe(device_t dev) { + struct tmp461_data *compat_data; if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_search_compatible(dev, tmp461_compat_data)->ocd_data) + compat_data = (struct tmp461_data *) + ofw_bus_search_compatible(dev, tmp461_compat_data)->ocd_data; + if (!compat_data) return (ENXIO); - device_set_desc(dev, "TMP461 Thermal Sensor"); + device_set_desc(dev, compat_data->compat); return (BUS_PROBE_GENERIC); } @@ -126,16 +193,20 @@ tmp461_probe(device_t dev) static int tmp461_detach(device_t dev) { + struct tmp461_softc *sc; + + sc = device_get_softc(dev); + mtx_destroy(&sc->mtx); return (0); } static int -tmp461_read_1(device_t dev, uint8_t reg, uint8_t *data) +tmp461_read_1(device_t dev, uint8_t reg, uint8_t *data) { int error; - error = iicdev_readfrom(dev, reg, (void *) data, 1, IIC_WAIT); + error = iicdev_readfrom(dev, reg, (void *) data, 1, IIC_DONTWAIT); if (error != 0) device_printf(dev, "Failed to read from device\n"); @@ -143,49 +214,99 @@ tmp461_read_1(device_t dev, uint8_t reg, uint8_t *data) } static int -tmp461_read_temp(device_t dev, int32_t *temp) +tmp461_write_1(device_t dev, uint8_t reg, uint8_t data) { - bool extended_mode; - uint8_t data; int error; - /* read temperature range */ - error = tmp461_read_1(dev, TMP461_CONFIG_REG, &data); + error = iicdev_writeto(dev, reg, (void *) &data, 1, IIC_DONTWAIT); if (error != 0) - return (ENXIO); + device_printf(dev, "Failed to write to device\n"); + + return (error); +} + +static int +tmp461_read_temperature(device_t dev, int32_t *temperature, bool remote_measure) +{ + uint8_t data, offset, reg; + struct tmp461_softc *sc; + int error; - extended_mode = data & TMP461_CONFIG_REG_TEMP_RANGE_BIT; + sc = device_get_softc(dev); - /* read temp MSB */ - error = tmp461_read_1(dev, TMP461_LOCAL_TEMP_REG_MSB, &data); + mtx_lock(&sc->mtx); + + error = tmp461_read_1(dev, TMP461_CONVERSION_RATE_REG, &data); if (error != 0) - return (ENXIO); + goto fail; - *temp = signed_extend32(data, TMP461_TEMP_LSB, 8) - - (extended_mode ? TMP461_EXTENDED_TEMP_MODIFIER : 0); + /* trigger sample*/ + error = tmp461_write_1(dev, TMP461_ONESHOT_REG, 0xFF); + if (error != 0) + goto fail; - error = tmp461_read_1(dev, TMP461_LOCAL_TEMP_REG_LSB, &data); + /* wait for conversion time */ + DELAY(TMP461_SENSOR_MAX_CONV_TIME/(1UL<> 4)) + TMP461_C_TO_K_FIX) >> 4; + offset = (data & TMP461_CONFIG_REG_TEMP_RANGE_BIT ? + TMP461_EXTENDED_TEMP_MODIFIER : 0); - return (0); + reg = remote_measure ? + TMP461_GLOBAL_TEMP_REG_MSB : TMP461_LOCAL_TEMP_REG_MSB; + + /* read temeperature value*/ + error = tmp461_read_1(dev, reg, &data); + if (error != 0) + goto fail; + + data -= offset; + *temperature = signed_extend32(data, 0, 8) << 4; + + if (remote_measure) { + if (sc->conf & TMP461_REMOTE_TEMP_DOUBLE_REG) { + error = tmp461_read_1(dev, + TMP461_GLOBAL_TEMP_REG_LSB, &data); + if (error != 0) + goto fail; + + *temperature |= data >> 4; + } + } else { + if (sc->conf & TMP461_LOCAL_TEMP_DOUBLE_REG) { + error = tmp461_read_1(dev, + TMP461_LOCAL_TEMP_REG_LSB, &data); + if (error != 0) + goto fail; + + *temperature |= data >> 4; + } + } + *temperature = (((*temperature + TMP461_C_TO_K_FIX) * 10) >> 4); + +fail: + mtx_unlock(&sc->mtx); + return (error); } static int tmp461_sensor_sysctl(SYSCTL_HANDLER_ARGS) { + int32_t temperature; device_t dev; - int32_t temp; int error; + bool mode; dev = arg1; + mode = arg2; - error = tmp461_read_temp(dev, &temp); + error = tmp461_read_temperature(dev, &temperature, mode); if (error != 0) return (error); - return (sysctl_handle_int(oidp, &temp, 0, req)); + return (sysctl_handle_int(oidp, &temperature, 0, req)); } -