Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157514618
D36464.id110220.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D36464.id110220.diff
View Options
Index: sys/dev/iicbus/tmp461.c
===================================================================
--- sys/dev/iicbus/tmp461.c
+++ sys/dev/iicbus/tmp461.c
@@ -44,94 +44,147 @@
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/ofw_bus.h>
-#define BIT(x) (1UL << (x))
+#define BIT(x) (1UL << (x))
+
+/* register map */
+#define LOCAL_TEMP_REG_MSB 0x0
+#define LOCAL_TEMP_REG_LSB 0x15
+#define REMOTE_TEMP_REG_MSB 0x1
+#define REMOTE_TEMP_REG_LSB 0x10
+#define STATUS_REG 0x2
+#define STATUS_REG_TEMP_LOCAL BIT(2)
+#define CONFIG_REG_R 0x3
+#define CONFIG_REG_W 0x9
+#define CONFIG_REG_TEMP_RANGE_BIT BIT(2)
+#define CONFIG_REG_STANDBY_BIT BIT(6)
+#define CONVERSION_RATE_REG 0x4
+#define ONESHOT_REG 0xF
+#define EXTENDED_MODE_TEMP_OFFSET 64
-#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_CONFIG_REG_TEMP_RANGE_BIT BIT(2)
-
-#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 TEMP_C_TO_K_FIX 4370
+
+#define SENSOR_MAX_CONV_TIME 16000000
+#define LOCAL_MEASURE 0
+#define REMOTE_MEASURE 1
+
+/* flags */
+#define LOCAL_TEMP_DOUBLE_REG BIT(0)
+#define 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_detach(device_t dev);
-static int tmp461_sensor_sysctl(SYSCTL_HANDLER_ARGS);
+static int temp_sensor_probe(device_t dev);
+static int temp_sensor_attach(device_t dev);
+static int temp_sensor_read_1(device_t dev, uint8_t reg, uint8_t *data);
+static int temp_sensor_write_1(device_t dev, uint8_t reg, uint8_t data);
+static int temp_sensor_read_temp(device_t dev, int32_t *temp, bool mode);
+static int temp_sensor_detach(device_t dev);
+static int temp_sensor_sysctl(SYSCTL_HANDLER_ARGS);
-static device_method_t tmp461_methods[] = {
- DEVMETHOD(device_probe, tmp461_probe),
- DEVMETHOD(device_attach, tmp461_attach),
- DEVMETHOD(device_detach, tmp461_detach),
+static device_method_t temp_sensor_methods[] = {
+ DEVMETHOD(device_probe, temp_sensor_probe),
+ DEVMETHOD(device_attach, temp_sensor_attach),
+ DEVMETHOD(device_detach, temp_sensor_detach),
DEVMETHOD_END
};
-static driver_t tmp461_driver = {
- "tmp461_dev",
- tmp461_methods,
+static driver_t temp_sensor_driver = {
+ "temp_sensor_dev",
+ temp_sensor_methods,
0
};
-static struct ofw_compat_data tmp461_compat_data[] = {
- { "ti,tmp461", 1 },
- { NULL, 0 }
+struct sensor_data {
+ const char *name;
+ const char *desc;
+ uint8_t flags;
};
-DRIVER_MODULE(tmp461, iicbus, tmp461_driver, 0, 0);
-IICBUS_FDT_PNP_INFO(tmp461_compat_data);
+static struct sensor_data sensor_list[] = {
+ {"adt7461", "ADT7461 Thernal Sensor Information",
+ REMOTE_TEMP_DOUBLE_REG},
+ {"tmp461", "TMP461 Thernal Sensor Information",
+ LOCAL_TEMP_DOUBLE_REG | REMOTE_TEMP_DOUBLE_REG}
+};
+
+static struct ofw_compat_data device_compat_data[] = {
+ {"adi,adt7461", (uintptr_t)&sensor_list[0]},
+ {"ti,tmp461", (uintptr_t)&sensor_list[1]},
+ {NULL, 0}
+};
+
+DRIVER_MODULE(generic_thermal_sensor_driver, iicbus, temp_sensor_driver, 0, 0);
+IICBUS_FDT_PNP_INFO(device_compat_data);
static int
-tmp461_attach(device_t dev)
+temp_sensor_attach(device_t dev)
{
struct sysctl_oid *sensor_root_oid;
+ struct sensor_data *local_dev;
struct sysctl_ctx_list *ctx;
+ uint8_t data;
+ local_dev = (struct sensor_data *)
+ ofw_bus_search_compatible(dev, device_compat_data)->ocd_data;
ctx = device_get_sysctl_ctx(dev);
-
+
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,
+ LOCAL_MEASURE, temp_sensor_sysctl, "IK1", local_dev->desc);
+
+ /* get status register */
+ if (temp_sensor_read_1(dev, STATUS_REG, &data) != 0)
+ return (ENXIO);
+
+ if (!(data & STATUS_REG_TEMP_LOCAL))
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(sensor_root_oid), OID_AUTO,
+ "remote_sensor", CTLTYPE_INT | CTLFLAG_RD, dev,
+ REMOTE_MEASURE, temp_sensor_sysctl, "IK1", local_dev->desc);
+
+ /* set standby mode */
+ if (temp_sensor_read_1(dev, CONFIG_REG_R, &data) != 0)
+ return (ENXIO);
+
+ data |= CONFIG_REG_STANDBY_BIT;
+ if (temp_sensor_write_1(dev, CONFIG_REG_W, data) != 0)
+ return (ENXIO);
return (0);
}
static int
-tmp461_probe(device_t dev)
+temp_sensor_probe(device_t dev)
{
+ struct sensor_data *local_dev;
if (!ofw_bus_status_okay(dev))
return (ENXIO);
- if (!ofw_bus_search_compatible(dev, tmp461_compat_data)->ocd_data)
+ local_dev = (struct sensor_data *)
+ ofw_bus_search_compatible(dev, device_compat_data)->ocd_data;
+ if (!local_dev)
return (ENXIO);
- device_set_desc(dev, "TMP461 Thermal Sensor");
+ device_set_desc(dev, local_dev->name);
return (BUS_PROBE_GENERIC);
}
static int
-tmp461_detach(device_t dev)
+temp_sensor_detach(device_t dev)
{
return (0);
}
static int
-tmp461_read_1(device_t dev, uint8_t reg, uint8_t *data)
+temp_sensor_read_1(device_t dev, uint8_t reg, uint8_t *data)
{
int error;
@@ -143,49 +196,99 @@
}
static int
-tmp461_read_temp(device_t dev, int32_t *temp)
+temp_sensor_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_WAIT);
if (error != 0)
- return (ENXIO);
+ device_printf(dev, "Failed to write to device\n");
- extended_mode = data & TMP461_CONFIG_REG_TEMP_RANGE_BIT;
+ return (error);
+}
+
+static int
+temp_sensor_read_temp(device_t dev, int32_t *temp, bool remote_measure)
+{
+ struct sensor_data *local_dev;
+ uint8_t data, offset;
+ int error;
+
+ local_dev = (struct sensor_data *)
+ ofw_bus_search_compatible(dev, device_compat_data)->ocd_data;
+
+ error = temp_sensor_read_1(dev, CONVERSION_RATE_REG, &data);
+ if (error != 0)
+ return (ENXIO);
- /* read temp MSB */
- error = tmp461_read_1(dev, TMP461_LOCAL_TEMP_REG_MSB, &data);
+ /* trigger sample*/
+ error = temp_sensor_write_1(dev, ONESHOT_REG, 0xFF);
if (error != 0)
return (ENXIO);
- *temp = signed_extend32(data, TMP461_TEMP_LSB, 8) -
- (extended_mode ? TMP461_EXTENDED_TEMP_MODIFIER : 0);
+ /* wait for conversion time */
+ DELAY(SENSOR_MAX_CONV_TIME/(1UL<<data));
- error = tmp461_read_1(dev, TMP461_LOCAL_TEMP_REG_LSB, &data);
+ /* read config register offset */
+ error = temp_sensor_read_1(dev, CONFIG_REG_R, &data);
if (error != 0)
return (ENXIO);
- *temp = (((*temp << 4) | (data >> 4)) + TMP461_C_TO_K_FIX) >> 4;
+ offset = (data & CONFIG_REG_TEMP_RANGE_BIT ?
+ EXTENDED_MODE_TEMP_OFFSET : 0);
+
+ if (remote_measure == LOCAL_MEASURE) {
+ error = temp_sensor_read_1(dev, LOCAL_TEMP_REG_MSB, &data);
+ if (error != 0)
+ return (ENXIO);
+
+ data -= offset;
+ *temp = signed_extend32(data, 0, 8) << 4;
+
+ if (local_dev->flags & LOCAL_TEMP_DOUBLE_REG) {
+ error = temp_sensor_read_1(dev,
+ LOCAL_TEMP_REG_LSB, &data);
+ if (error != 0)
+ return (ENXIO);
+
+ *temp |= data >> 4;
+ }
+ } else {
+ error = temp_sensor_read_1(dev, REMOTE_TEMP_REG_MSB, &data);
+ if (error != 0)
+ return (ENXIO);
+
+ data -= offset;
+ *temp = signed_extend32(data, 0, 8) << 4;
+
+ if (local_dev->flags & REMOTE_TEMP_DOUBLE_REG) {
+ error = temp_sensor_read_1(dev,
+ REMOTE_TEMP_REG_LSB, &data);
+ if (error != 0)
+ return (ENXIO);
+
+ *temp |= data >> 4;
+ }
+ }
+ *temp = (((*temp + TEMP_C_TO_K_FIX) * 10) >> 4);
return (0);
}
static int
-tmp461_sensor_sysctl(SYSCTL_HANDLER_ARGS)
+temp_sensor_sysctl(SYSCTL_HANDLER_ARGS)
{
device_t dev;
int32_t temp;
int error;
+ bool mode;
dev = arg1;
+ mode = arg2;
- error = tmp461_read_temp(dev, &temp);
+ error = temp_sensor_read_temp(dev, &temp, mode);
if (error != 0)
return (error);
return (sysctl_handle_int(oidp, &temp, 0, req));
}
-
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, May 23, 6:58 AM (1 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33442857
Default Alt Text
D36464.id110220.diff (8 KB)
Attached To
Mode
D36464: TMP461: Add support for ADT7461 sensor
Attached
Detach File
Event Timeline
Log In to Comment