#define LM90_FLAG_ADT7461_EXT BIT(0) /* ADT7461 extended mode */
/* Device features */
#define LM90_HAVE_OFFSET BIT(1) /* temperature offset register */
+#define LM90_HAVE_UNSIGNED_TEMP BIT(2) /* temperatures are unsigned */
#define LM90_HAVE_REM_LIMIT_EXT BIT(3) /* extended remote limit */
#define LM90_HAVE_EMERGENCY BIT(4) /* 3rd upper (emergency) limit */
#define LM90_HAVE_EMERGENCY_ALARM BIT(5)/* emergency alarm */
.max_convrate = 10,
},
[adt7461] = {
+ /*
+ * Standard temperature range is supposed to be unsigned,
+ * but that does not match reality. Negative temperatures
+ * are always reported.
+ */
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP
| LM90_HAVE_CRIT | LM90_HAVE_PARTIAL_PEC,
.max_convrate = 9,
},
[max6646] = {
- .flags = LM90_HAVE_CRIT | LM90_HAVE_BROKEN_ALERT,
+ .flags = LM90_HAVE_CRIT | LM90_HAVE_BROKEN_ALERT
+ | LM90_HAVE_UNSIGNED_TEMP,
.alert_alarms = 0x7c,
.max_convrate = 6,
.reg_local_ext = MAX6657_REG_LOCAL_TEMPL,
.reg_local_ext = MAX6657_REG_LOCAL_TEMPL,
},
[max6680] = {
+ /*
+ * Apparent temperatures of 128 degrees C or higher are reported
+ * and treated as negative temperatures (meaning min_alarm will
+ * be set).
+ */
.flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT
| LM90_HAVE_CRIT_ALRM_SWP | LM90_HAVE_BROKEN_ALERT,
.alert_alarms = 0x7c,
.max_convrate = 8,
},
[sa56004] = {
+ /*
+ * Apparent temperatures of 128 degrees C or higher are reported
+ * and treated as negative temperatures (meaning min_alarm will
+ * be set).
+ */
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT,
.alert_alarms = 0x7b,
.max_convrate = 9,
},
[tmp451] = {
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
- | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT,
+ | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT
+ | LM90_HAVE_UNSIGNED_TEMP,
.alert_alarms = 0x7c,
.max_convrate = 9,
.reg_local_ext = TMP451_REG_LOCAL_TEMPL,
static u8 temp_to_u8_adt7461(struct lm90_data *data, long val)
{
if (data->flags & LM90_FLAG_ADT7461_EXT) {
- if (val <= -64000)
- return 0;
- if (val >= 191000)
- return 0xFF;
- return (val + 500 + 64000) / 1000;
+ val = clamp_val(val, -64000, 191000);
+ val += 64000;
+ } else if (data->flags & LM90_HAVE_UNSIGNED_TEMP) {
+ val = clamp_val(val, 0, 127000);
+ } else {
+ val = clamp_val(val, -128000, 127000);
}
- if (val <= 0)
- return 0;
- if (val >= 127000)
- return 127;
- return (val + 500) / 1000;
+ return DIV_ROUND_CLOSEST(val, 1000);
}
static u16 temp_to_u16_adt7461(struct lm90_data *data, long val)
{
if (data->flags & LM90_FLAG_ADT7461_EXT) {
- if (val <= -64000)
- return 0;
- if (val >= 191750)
- return 0xFFC0;
- return (val + 64000 + 125) / 250 * 64;
+ val = clamp_val(val, -64000, 191000);
+ val += 64000;
+ } else if (data->flags & LM90_HAVE_UNSIGNED_TEMP) {
+ val = clamp_val(val, 0, 127000);
+ } else {
+ val = clamp_val(val, -128000, 127000);
}
- if (val <= 0)
- return 0;
- if (val >= 127750)
- return 0x7FC0;
- return (val + 125) / 250 * 64;
+ return DIV_ROUND_CLOSEST(val, 1000) & 0xfff0;
}
/* pec used for devices with PEC support */
if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u16_adt7461(data, temp11);
- else if (data->kind == max6646)
+ else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
temp = temp_from_u16(temp11);
else
temp = temp_from_s16(temp11);
if (data->flags & LM90_HAVE_EXTENDED_TEMP)
data->temp11[index] = temp_to_u16_adt7461(data, val);
- else if (data->kind == max6646)
+ else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
data->temp11[index] = temp_to_u8(val) << 8;
else if (data->flags & LM90_HAVE_REM_LIMIT_EXT)
data->temp11[index] = temp_to_s16(val);
if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u8_adt7461(data, temp8);
- else if (data->kind == max6646)
+ else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
temp = temp_from_u8(temp8);
else
temp = temp_from_s8(temp8);
if (data->flags & LM90_HAVE_EXTENDED_TEMP)
data->temp8[index] = temp_to_u8_adt7461(data, val);
- else if (data->kind == max6646)
+ else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
data->temp8[index] = temp_to_u8(val);
else
data->temp8[index] = temp_to_s8(val);
if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u8_adt7461(data, data->temp8[index]);
- else if (data->kind == max6646)
+ else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
temp = temp_from_u8(data->temp8[index]);
else
temp = temp_from_s8(data->temp8[index]);
if (data->flags & LM90_HAVE_EXTENDED_TEMP)
temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]);
- else if (data->kind == max6646)
+ else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
temp = temp_from_u8(data->temp8[LOCAL_CRIT]);
else
temp = temp_from_s8(data->temp8[LOCAL_CRIT]);
* Put MAX6680/MAX8881 into extended resolution (bit 0x10,
* 0.125 degree resolution) and range (0x08, extend range
* to -64 degree) mode for the remote temperature sensor.
+ * Note that expeciments with an actual chip do not show a difference
+ * if bit 3 is set or not.
*/
if (data->kind == max6680)
config |= 0x18;