Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157930257
D36464.id110180.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.id110180.diff
View Options
Index: sys/dev/iicbus/tmp461.c
===================================================================
--- sys/dev/iicbus/tmp461.c
+++ sys/dev/iicbus/tmp461.c
@@ -44,94 +44,150 @@
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/ofw_bus.h>
-#define BIT(x) (1UL << (x))
+#define BIT(x) (1UL << (x))
-#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 16000
+#define LOCAL_MEASURE 0
+#define REMOTE_MEASURE 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);
+/* flags */
+#define LOCAL_TEMP_DOUBLE_REG BIT(0)
+#define REMOTE_TEMP_DOUBLE_REG BIT(1)
-static device_method_t tmp461_methods[] = {
- DEVMETHOD(device_probe, tmp461_probe),
- DEVMETHOD(device_attach, tmp461_attach),
- DEVMETHOD(device_detach, tmp461_detach),
+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 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;
+ uint8_t local_temp_reg_msb;
+ uint8_t local_temp_reg_lsb;
+ uint8_t remote_temp_reg_msb;
+ uint8_t remote_temp_reg_lsb;
+ uint8_t status_reg;
+ uint8_t status_reg_temp_local;
+ uint8_t config_reg_r;
+ uint8_t config_reg_w;
+ uint8_t config_reg_temp_range_bit;
+ uint8_t config_reg_standby_bit;
+ uint8_t conversion_rate_reg;
+ uint8_t oneshot_reg;
+ uint8_t extended_mode_temp_offset;
+};
+
+static struct sensor_data sensor_list[] = {
+ {"adt7461", "ADT7461 Thernal Sensor Information",
+ REMOTE_TEMP_DOUBLE_REG,
+ 0x0, 0x0, 0x1, 0x10, 0x2, BIT(2),
+ 0x3, 0x9, BIT(2), BIT(6), 0x4, 0xF, 64},
+ {"tmp461", "TMP461 Thernal Sensor Information",
+ LOCAL_TEMP_DOUBLE_REG | REMOTE_TEMP_DOUBLE_REG,
+ 0x0, 0x15, 0x1, 0x10, 0x2, BIT(2),
+ 0x3, 0x9, BIT(2), BIT(6), 0x4, 0xF, 64}
+};
+
+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(tmp461, iicbus, tmp461_driver, 0, 0);
-IICBUS_FDT_PNP_INFO(tmp461_compat_data);
+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, local_dev->status_reg, &data) != 0)
+ return (ENXIO);
+
+ if (!(data & local_dev->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, local_dev->config_reg_r, &data) != 0)
+ return (ENXIO);
+
+ data |= local_dev->config_reg_standby_bit;
+
+ if (temp_sensor_write_1(dev, local_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 +199,101 @@
}
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);
+}
- /* read temp MSB */
- error = tmp461_read_1(dev, TMP461_LOCAL_TEMP_REG_MSB, &data);
+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, local_dev->conversion_rate_reg, &data);
if (error != 0)
return (ENXIO);
- *temp = signed_extend32(data, TMP461_TEMP_LSB, 8) -
- (extended_mode ? TMP461_EXTENDED_TEMP_MODIFIER : 0);
+ /* trigger sample*/
+ error = temp_sensor_write_1(dev, local_dev->oneshot_reg, 0xFF);
+ if (error != 0)
+ return (ENXIO);
+
+ /* wait for conversion time */
+ pause("Sampling", 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, local_dev->config_reg_r, &data);
if (error != 0)
return (ENXIO);
- *temp = (((*temp << 4) | (data >> 4)) + TMP461_C_TO_K_FIX) >> 4;
+ offset = (data & local_dev->config_reg_temp_range_bit ?
+ local_dev->extended_mode_temp_offset : 0);
+
+ if (remote_measure == LOCAL_MEASURE) {
+ error = temp_sensor_read_1(dev,
+ local_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_dev->local_temp_reg_lsb, &data);
+ if (error != 0)
+ return (ENXIO);
+
+ *temp |= data >> 4;
+ }
+ } else {
+ error = temp_sensor_read_1(dev,
+ local_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,
+ local_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
Wed, May 27, 2:17 PM (19 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33560040
Default Alt Text
D36464.id110180.diff (8 KB)
Attached To
Mode
D36464: TMP461: Add support for ADT7461 sensor
Attached
Detach File
Event Timeline
Log In to Comment