aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm90.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/lm90.c')
-rw-r--r--drivers/hwmon/lm90.c452
1 files changed, 155 insertions, 297 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index b20be0cb28b5..f162391eafc2 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -343,6 +343,7 @@ struct lm90_params {
u16 alert_alarms; /* Which alarm bits trigger ALERT# */
/* Upper 8 bits for max6695/96 */
u8 max_convrate; /* Maximum conversion rate register value */
+ u8 resolution; /* 16-bit resolution (default 11 bit) */
u8 reg_local_ext; /* Extended local temp register (optional) */
};
@@ -365,6 +366,7 @@ static const struct lm90_params lm90_params[] = {
| LM90_HAVE_CRIT | LM90_HAVE_PARTIAL_PEC,
.alert_alarms = 0x7c,
.max_convrate = 10,
+ .resolution = 10,
},
[adt7461a] = {
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
@@ -462,6 +464,7 @@ static const struct lm90_params lm90_params[] = {
| LM90_HAVE_UNSIGNED_TEMP,
.alert_alarms = 0x7c,
.max_convrate = 9,
+ .resolution = 12,
.reg_local_ext = TMP451_REG_LOCAL_TEMPL,
},
[tmp461] = {
@@ -469,14 +472,15 @@ static const struct lm90_params lm90_params[] = {
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT,
.alert_alarms = 0x7c,
.max_convrate = 9,
+ .resolution = 12,
.reg_local_ext = TMP451_REG_LOCAL_TEMPL,
},
};
/*
- * TEMP8 register index
+ * temperature register index
*/
-enum lm90_temp8_reg_index {
+enum lm90_temp_reg_index {
LOCAL_LOW = 0,
LOCAL_HIGH,
LOCAL_CRIT,
@@ -485,14 +489,8 @@ enum lm90_temp8_reg_index {
REMOTE_EMERG, /* max6659 and max6695/96 */
REMOTE2_CRIT, /* max6695/96 only */
REMOTE2_EMERG, /* max6695/96 only */
- TEMP8_REG_NUM
-};
-/*
- * TEMP11 register index
- */
-enum lm90_temp11_reg_index {
- REMOTE_TEMP = 0,
+ REMOTE_TEMP,
REMOTE_LOW,
REMOTE_HIGH,
REMOTE_OFFSET, /* except max6646, max6657/58/59, and max6695/96 */
@@ -500,7 +498,8 @@ enum lm90_temp11_reg_index {
REMOTE2_TEMP, /* max6695/96 only */
REMOTE2_LOW, /* max6695/96 only */
REMOTE2_HIGH, /* max6695/96 only */
- TEMP11_REG_NUM
+
+ TEMP_REG_NUM
};
/*
@@ -528,14 +527,14 @@ struct lm90_data {
u8 config; /* Current configuration register value */
u8 config_orig; /* Original configuration register value */
u8 convrate_orig; /* Original conversion rate register value */
+ u8 resolution; /* temperature resolution in bit */
u16 alert_alarms; /* Which alarm bits trigger ALERT# */
/* Upper 8 bits for max6695/96 */
u8 max_convrate; /* Maximum conversion rate */
u8 reg_local_ext; /* local extension register offset */
/* registers values */
- s8 temp8[TEMP8_REG_NUM];
- s16 temp11[TEMP11_REG_NUM];
+ u16 temp[TEMP_REG_NUM];
u8 temp_hyst;
u16 reported_alarms; /* alarms reported as sysfs/udev events */
u16 current_alarms; /* current alarms, reported by chip */
@@ -732,12 +731,12 @@ static int lm90_update_limits(struct device *dev)
val = lm90_read_reg(client, LM90_REG_LOCAL_CRIT);
if (val < 0)
return val;
- data->temp8[LOCAL_CRIT] = val;
+ data->temp[LOCAL_CRIT] = val << 8;
val = lm90_read_reg(client, LM90_REG_REMOTE_CRIT);
if (val < 0)
return val;
- data->temp8[REMOTE_CRIT] = val;
+ data->temp[REMOTE_CRIT] = val << 8;
val = lm90_read_reg(client, LM90_REG_TCRIT_HYST);
if (val < 0)
@@ -748,25 +747,25 @@ static int lm90_update_limits(struct device *dev)
val = lm90_read_reg(client, LM90_REG_REMOTE_LOWH);
if (val < 0)
return val;
- data->temp11[REMOTE_LOW] = val << 8;
+ data->temp[REMOTE_LOW] = val << 8;
if (data->flags & LM90_HAVE_REM_LIMIT_EXT) {
val = lm90_read_reg(client, LM90_REG_REMOTE_LOWL);
if (val < 0)
return val;
- data->temp11[REMOTE_LOW] |= val;
+ data->temp[REMOTE_LOW] |= val;
}
val = lm90_read_reg(client, LM90_REG_REMOTE_HIGHH);
if (val < 0)
return val;
- data->temp11[REMOTE_HIGH] = val << 8;
+ data->temp[REMOTE_HIGH] = val << 8;
if (data->flags & LM90_HAVE_REM_LIMIT_EXT) {
val = lm90_read_reg(client, LM90_REG_REMOTE_HIGHL);
if (val < 0)
return val;
- data->temp11[REMOTE_HIGH] |= val;
+ data->temp[REMOTE_HIGH] |= val;
}
if (data->flags & LM90_HAVE_OFFSET) {
@@ -774,19 +773,19 @@ static int lm90_update_limits(struct device *dev)
LM90_REG_REMOTE_OFFSL, false);
if (val < 0)
return val;
- data->temp11[REMOTE_OFFSET] = val;
+ data->temp[REMOTE_OFFSET] = val;
}
if (data->flags & LM90_HAVE_EMERGENCY) {
val = lm90_read_reg(client, MAX6659_REG_LOCAL_EMERG);
if (val < 0)
return val;
- data->temp8[LOCAL_EMERG] = val;
+ data->temp[LOCAL_EMERG] = val << 8;
val = lm90_read_reg(client, MAX6659_REG_REMOTE_EMERG);
if (val < 0)
return val;
- data->temp8[REMOTE_EMERG] = val;
+ data->temp[REMOTE_EMERG] = val << 8;
}
if (data->kind == max6696) {
@@ -797,22 +796,22 @@ static int lm90_update_limits(struct device *dev)
val = lm90_read_reg(client, LM90_REG_REMOTE_CRIT);
if (val < 0)
return val;
- data->temp8[REMOTE2_CRIT] = val;
+ data->temp[REMOTE2_CRIT] = val << 8;
val = lm90_read_reg(client, MAX6659_REG_REMOTE_EMERG);
if (val < 0)
return val;
- data->temp8[REMOTE2_EMERG] = val;
+ data->temp[REMOTE2_EMERG] = val << 8;
val = lm90_read_reg(client, LM90_REG_REMOTE_LOWH);
if (val < 0)
return val;
- data->temp11[REMOTE2_LOW] = val << 8;
+ data->temp[REMOTE2_LOW] = val << 8;
val = lm90_read_reg(client, LM90_REG_REMOTE_HIGHH);
if (val < 0)
return val;
- data->temp11[REMOTE2_HIGH] = val << 8;
+ data->temp[REMOTE2_HIGH] = val << 8;
lm90_select_remote_channel(data, 0);
}
@@ -995,30 +994,30 @@ static int lm90_update_device(struct device *dev)
val = lm90_read_reg(client, LM90_REG_LOCAL_LOW);
if (val < 0)
return val;
- data->temp8[LOCAL_LOW] = val;
+ data->temp[LOCAL_LOW] = val << 8;
val = lm90_read_reg(client, LM90_REG_LOCAL_HIGH);
if (val < 0)
return val;
- data->temp8[LOCAL_HIGH] = val;
+ data->temp[LOCAL_HIGH] = val << 8;
if (data->reg_local_ext) {
val = lm90_read16(client, LM90_REG_LOCAL_TEMP,
data->reg_local_ext, true);
if (val < 0)
return val;
- data->temp11[LOCAL_TEMP] = val;
+ data->temp[LOCAL_TEMP] = val;
} else {
val = lm90_read_reg(client, LM90_REG_LOCAL_TEMP);
if (val < 0)
return val;
- data->temp11[LOCAL_TEMP] = val << 8;
+ data->temp[LOCAL_TEMP] = val << 8;
}
val = lm90_read16(client, LM90_REG_REMOTE_TEMPH,
LM90_REG_REMOTE_TEMPL, true);
if (val < 0)
return val;
- data->temp11[REMOTE_TEMP] = val;
+ data->temp[REMOTE_TEMP] = val;
if (data->kind == max6696) {
val = lm90_select_remote_channel(data, 1);
@@ -1031,7 +1030,7 @@ static int lm90_update_device(struct device *dev)
lm90_select_remote_channel(data, 0);
return val;
}
- data->temp11[REMOTE2_TEMP] = val;
+ data->temp[REMOTE2_TEMP] = val;
lm90_select_remote_channel(data, 0);
}
@@ -1047,123 +1046,6 @@ static int lm90_update_device(struct device *dev)
return 0;
}
-/*
- * Conversions
- * For local temperatures and limits, critical limits and the hysteresis
- * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius.
- * For remote temperatures and limits, it uses signed 11-bit values with
- * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. Some
- * Maxim chips use unsigned values.
- */
-
-static inline int temp_from_s8(s8 val)
-{
- return val * 1000;
-}
-
-static inline int temp_from_u8(u8 val)
-{
- return val * 1000;
-}
-
-static inline int temp_from_s16(s16 val)
-{
- return val / 32 * 125;
-}
-
-static inline int temp_from_u16(u16 val)
-{
- return val / 32 * 125;
-}
-
-static s8 temp_to_s8(long val)
-{
- if (val <= -128000)
- return -128;
- if (val >= 127000)
- return 127;
- if (val < 0)
- return (val - 500) / 1000;
- return (val + 500) / 1000;
-}
-
-static u8 temp_to_u8(long val)
-{
- if (val <= 0)
- return 0;
- if (val >= 255000)
- return 255;
- return (val + 500) / 1000;
-}
-
-static s16 temp_to_s16(long val)
-{
- if (val <= -128000)
- return 0x8000;
- if (val >= 127875)
- return 0x7FE0;
- if (val < 0)
- return (val - 62) / 125 * 32;
- return (val + 62) / 125 * 32;
-}
-
-static u8 hyst_to_reg(long val)
-{
- if (val <= 0)
- return 0;
- if (val >= 30500)
- return 31;
- return (val + 500) / 1000;
-}
-
-/*
- * ADT7461 in compatibility mode is almost identical to LM90 except that
- * attempts to write values that are outside the range 0 < temp < 127 are
- * treated as the boundary value.
- *
- * ADT7461 in "extended mode" operation uses unsigned integers offset by
- * 64 (e.g., 0 -> -64 degC). The range is restricted to -64..191 degC.
- */
-static inline int temp_from_u8_adt7461(struct lm90_data *data, u8 val)
-{
- if (data->flags & LM90_FLAG_ADT7461_EXT)
- return (val - 64) * 1000;
- return temp_from_s8(val);
-}
-
-static inline int temp_from_u16_adt7461(struct lm90_data *data, u16 val)
-{
- if (data->flags & LM90_FLAG_ADT7461_EXT)
- return (val - 0x4000) / 64 * 250;
- return temp_from_s16(val);
-}
-
-static u8 temp_to_u8_adt7461(struct lm90_data *data, long val)
-{
- if (data->flags & LM90_FLAG_ADT7461_EXT) {
- 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);
- }
- 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) {
- 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);
- }
- return DIV_ROUND_CLOSEST(val, 1000) & 0xfff0;
-}
-
/* pec used for devices with PEC support */
static ssize_t pec_show(struct device *dev, struct device_attribute *dummy,
char *buf)
@@ -1200,159 +1082,141 @@ static ssize_t pec_store(struct device *dev, struct device_attribute *dummy,
static DEVICE_ATTR_RW(pec);
-static int lm90_get_temp11(struct lm90_data *data, int index)
+static int lm90_temp_get_resolution(struct lm90_data *data, int index)
{
- s16 temp11 = data->temp11[index];
- int temp;
-
- if (data->flags & LM90_HAVE_EXTENDED_TEMP)
- temp = temp_from_u16_adt7461(data, temp11);
- else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
- temp = temp_from_u16(temp11);
- else
- temp = temp_from_s16(temp11);
-
- /* +16 degrees offset for temp2 for the LM99 */
- if (data->kind == lm99 && index <= 2)
- temp += 16000;
-
- return temp;
+ switch (index) {
+ case REMOTE_TEMP:
+ case REMOTE_OFFSET:
+ case REMOTE2_TEMP:
+ return data->resolution;
+ case LOCAL_TEMP:
+ if (data->reg_local_ext)
+ return data->resolution;
+ return 8;
+ case REMOTE_LOW:
+ case REMOTE_HIGH:
+ case REMOTE2_LOW:
+ case REMOTE2_HIGH:
+ if (data->flags & LM90_HAVE_REM_LIMIT_EXT)
+ return data->resolution;
+ return 8;
+ default:
+ return 8;
+ }
}
-static int lm90_set_temp11(struct lm90_data *data, int index, long val)
+static int lm90_temp_from_reg(u32 flags, u16 regval, u8 resolution)
{
- static struct reg {
- u8 high;
- u8 low;
- } reg[] = {
- [REMOTE_LOW] = { LM90_REG_REMOTE_LOWH, LM90_REG_REMOTE_LOWL },
- [REMOTE_HIGH] = { LM90_REG_REMOTE_HIGHH, LM90_REG_REMOTE_HIGHL },
- [REMOTE_OFFSET] = { LM90_REG_REMOTE_OFFSH, LM90_REG_REMOTE_OFFSL },
- [REMOTE2_LOW] = { LM90_REG_REMOTE_LOWH, LM90_REG_REMOTE_LOWL },
- [REMOTE2_HIGH] = { LM90_REG_REMOTE_HIGHH, LM90_REG_REMOTE_HIGHL }
- };
- struct i2c_client *client = data->client;
- struct reg *regp = &reg[index];
- int err;
-
- /* +16 degrees offset for temp2 for the LM99 */
- if (data->kind == lm99 && index <= 2) {
- /* prevent integer underflow */
- val = max(val, -128000l);
- val -= 16000;
- }
+ int val;
- if (data->flags & LM90_HAVE_EXTENDED_TEMP)
- data->temp11[index] = temp_to_u16_adt7461(data, val);
- 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 (flags & LM90_FLAG_ADT7461_EXT)
+ val = regval - 0x4000;
+ else if (flags & LM90_HAVE_UNSIGNED_TEMP)
+ val = regval;
else
- data->temp11[index] = temp_to_s8(val) << 8;
+ val = (s16)regval;
- lm90_select_remote_channel(data, index >= 3);
- err = lm90_write_reg(client, regp->high, data->temp11[index] >> 8);
- if (err < 0)
- return err;
- if (data->flags & LM90_HAVE_REM_LIMIT_EXT)
- err = lm90_write_reg(client, regp->low,
- data->temp11[index] & 0xff);
-
- lm90_select_remote_channel(data, 0);
- return err;
+ return ((val >> (16 - resolution)) * 1000) >> (resolution - 8);
}
-static int lm90_get_temp8(struct lm90_data *data, int index)
+static int lm90_get_temp(struct lm90_data *data, int index, int channel)
{
- s8 temp8 = data->temp8[index];
- int temp;
+ int temp = lm90_temp_from_reg(data->flags, data->temp[index],
+ lm90_temp_get_resolution(data, index));
- if (data->flags & LM90_HAVE_EXTENDED_TEMP)
- temp = temp_from_u8_adt7461(data, temp8);
- else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
- temp = temp_from_u8(temp8);
- else
- temp = temp_from_s8(temp8);
-
- /* +16 degrees offset for temp2 for the LM99 */
- if (data->kind == lm99 && index == 3)
+ /* +16 degrees offset for remote temperature on LM99 */
+ if (data->kind == lm99 && channel)
temp += 16000;
return temp;
}
-static int lm90_set_temp8(struct lm90_data *data, int index, long val)
+static u16 lm90_temp_to_reg(u32 flags, long val, u8 resolution)
+{
+ int fraction = resolution > 8 ?
+ 1000 - DIV_ROUND_CLOSEST(1000, BIT(resolution - 8)) : 0;
+
+ if (flags & LM90_FLAG_ADT7461_EXT) {
+ val = clamp_val(val, -64000, 191000 + fraction);
+ val += 64000;
+ } else if (flags & LM90_HAVE_UNSIGNED_TEMP) {
+ val = clamp_val(val, 0, 127000 + fraction);
+ } else {
+ val = clamp_val(val, -128000, 127000 + fraction);
+ }
+
+ return DIV_ROUND_CLOSEST(val << (resolution - 8), 1000) << (16 - resolution);
+}
+
+static int lm90_set_temp(struct lm90_data *data, int index, int channel, long val)
{
- static const u8 reg[TEMP8_REG_NUM] = {
- LM90_REG_LOCAL_LOW,
- LM90_REG_LOCAL_HIGH,
- LM90_REG_LOCAL_CRIT,
- LM90_REG_REMOTE_CRIT,
- MAX6659_REG_LOCAL_EMERG,
- MAX6659_REG_REMOTE_EMERG,
- LM90_REG_REMOTE_CRIT,
- MAX6659_REG_REMOTE_EMERG,
+ static const u8 regs[] = {
+ [LOCAL_LOW] = LM90_REG_LOCAL_LOW,
+ [LOCAL_HIGH] = LM90_REG_LOCAL_HIGH,
+ [LOCAL_CRIT] = LM90_REG_LOCAL_CRIT,
+ [REMOTE_CRIT] = LM90_REG_REMOTE_CRIT,
+ [LOCAL_EMERG] = MAX6659_REG_LOCAL_EMERG,
+ [REMOTE_EMERG] = MAX6659_REG_REMOTE_EMERG,
+ [REMOTE2_CRIT] = LM90_REG_REMOTE_CRIT,
+ [REMOTE2_EMERG] = MAX6659_REG_REMOTE_EMERG,
+ [REMOTE_LOW] = LM90_REG_REMOTE_LOWH,
+ [REMOTE_HIGH] = LM90_REG_REMOTE_HIGHH,
+ [REMOTE2_LOW] = LM90_REG_REMOTE_LOWH,
+ [REMOTE2_HIGH] = LM90_REG_REMOTE_HIGHH,
};
struct i2c_client *client = data->client;
+ u8 regh = regs[index];
+ u8 regl = 0;
int err;
- /* +16 degrees offset for temp2 for the LM99 */
- if (data->kind == lm99 && index == 3) {
+ if (channel && (data->flags & LM90_HAVE_REM_LIMIT_EXT)) {
+ if (index == REMOTE_LOW || index == REMOTE2_LOW)
+ regl = LM90_REG_REMOTE_LOWL;
+ else if (index == REMOTE_HIGH || index == REMOTE2_HIGH)
+ regl = LM90_REG_REMOTE_HIGHL;
+ }
+
+ /* +16 degrees offset for remote temperature on LM99 */
+ if (data->kind == lm99 && channel) {
/* prevent integer underflow */
val = max(val, -128000l);
val -= 16000;
}
- if (data->flags & LM90_HAVE_EXTENDED_TEMP)
- data->temp8[index] = temp_to_u8_adt7461(data, val);
- else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
- data->temp8[index] = temp_to_u8(val);
- else
- data->temp8[index] = temp_to_s8(val);
+ data->temp[index] = lm90_temp_to_reg(data->flags, val,
+ lm90_temp_get_resolution(data, index));
+
+ if (channel > 1)
+ lm90_select_remote_channel(data, 1);
- lm90_select_remote_channel(data, index >= 6);
- err = lm90_write_reg(client, reg[index], data->temp8[index]);
- lm90_select_remote_channel(data, 0);
+ err = lm90_write_reg(client, regh, data->temp[index] >> 8);
+ if (err < 0)
+ goto deselect;
+ if (regl)
+ err = lm90_write_reg(client, regl, data->temp[index] & 0xff);
+deselect:
+ if (channel > 1)
+ lm90_select_remote_channel(data, 0);
return err;
}
-static int lm90_get_temphyst(struct lm90_data *data, int index)
+static int lm90_get_temphyst(struct lm90_data *data, int index, int channel)
{
- int temp;
-
- if (data->flags & LM90_HAVE_EXTENDED_TEMP)
- temp = temp_from_u8_adt7461(data, data->temp8[index]);
- else if (data->flags & LM90_HAVE_UNSIGNED_TEMP)
- temp = temp_from_u8(data->temp8[index]);
- else
- temp = temp_from_s8(data->temp8[index]);
+ int temp = lm90_get_temp(data, index, channel);
- /* +16 degrees offset for temp2 for the LM99 */
- if (data->kind == lm99 && index == 3)
- temp += 16000;
-
- return temp - temp_from_s8(data->temp_hyst);
+ return temp - data->temp_hyst * 1000;
}
static int lm90_set_temphyst(struct lm90_data *data, long val)
{
- struct i2c_client *client = data->client;
- int temp;
-
- if (data->flags & LM90_HAVE_EXTENDED_TEMP)
- temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]);
- 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]);
+ int temp = lm90_get_temp(data, LOCAL_CRIT, 0);
/* prevent integer overflow/underflow */
val = clamp_val(val, -128000l, 255000l);
+ data->temp_hyst = clamp_val(DIV_ROUND_CLOSEST(temp - val, 1000), 0, 31);
- data->temp_hyst = hyst_to_reg(temp - val);
- return lm90_write_reg(client, LM90_REG_TCRIT_HYST, data->temp_hyst);
+ return lm90_write_reg(data->client, LM90_REG_TCRIT_HYST, data->temp_hyst);
}
static const u8 lm90_temp_index[3] = {
@@ -1396,7 +1260,7 @@ static int lm90_temp_read(struct device *dev, u32 attr, int channel, long *val)
switch (attr) {
case hwmon_temp_input:
- *val = lm90_get_temp11(data, lm90_temp_index[channel]);
+ *val = lm90_get_temp(data, lm90_temp_index[channel], channel);
break;
case hwmon_temp_min_alarm:
case hwmon_temp_max_alarm:
@@ -1428,35 +1292,26 @@ static int lm90_temp_read(struct device *dev, u32 attr, int channel, long *val)
data->alarms |= data->current_alarms;
break;
case hwmon_temp_min:
- if (channel == 0)
- *val = lm90_get_temp8(data,
- lm90_temp_min_index[channel]);
- else
- *val = lm90_get_temp11(data,
- lm90_temp_min_index[channel]);
+ *val = lm90_get_temp(data, lm90_temp_min_index[channel], channel);
break;
case hwmon_temp_max:
- if (channel == 0)
- *val = lm90_get_temp8(data,
- lm90_temp_max_index[channel]);
- else
- *val = lm90_get_temp11(data,
- lm90_temp_max_index[channel]);
+ *val = lm90_get_temp(data, lm90_temp_max_index[channel], channel);
break;
case hwmon_temp_crit:
- *val = lm90_get_temp8(data, lm90_temp_crit_index[channel]);
+ *val = lm90_get_temp(data, lm90_temp_crit_index[channel], channel);
break;
case hwmon_temp_crit_hyst:
- *val = lm90_get_temphyst(data, lm90_temp_crit_index[channel]);
+ *val = lm90_get_temphyst(data, lm90_temp_crit_index[channel], channel);
break;
case hwmon_temp_emergency:
- *val = lm90_get_temp8(data, lm90_temp_emerg_index[channel]);
+ *val = lm90_get_temp(data, lm90_temp_emerg_index[channel], channel);
break;
case hwmon_temp_emergency_hyst:
- *val = lm90_get_temphyst(data, lm90_temp_emerg_index[channel]);
+ *val = lm90_get_temphyst(data, lm90_temp_emerg_index[channel], channel);
break;
case hwmon_temp_offset:
- *val = lm90_get_temp11(data, REMOTE_OFFSET);
+ *val = lm90_temp_from_reg(0, data->temp[REMOTE_OFFSET],
+ lm90_temp_get_resolution(data, REMOTE_OFFSET));
break;
default:
return -EOPNOTSUPP;
@@ -1477,36 +1332,38 @@ static int lm90_temp_write(struct device *dev, u32 attr, int channel, long val)
switch (attr) {
case hwmon_temp_min:
- if (channel == 0)
- err = lm90_set_temp8(data,
- lm90_temp_min_index[channel],
- val);
- else
- err = lm90_set_temp11(data,
- lm90_temp_min_index[channel],
- val);
+ err = lm90_set_temp(data, lm90_temp_min_index[channel],
+ channel, val);
break;
case hwmon_temp_max:
- if (channel == 0)
- err = lm90_set_temp8(data,
- lm90_temp_max_index[channel],
- val);
- else
- err = lm90_set_temp11(data,
- lm90_temp_max_index[channel],
- val);
+ err = lm90_set_temp(data, lm90_temp_max_index[channel],
+ channel, val);
break;
case hwmon_temp_crit:
- err = lm90_set_temp8(data, lm90_temp_crit_index[channel], val);
+ err = lm90_set_temp(data, lm90_temp_crit_index[channel],
+ channel, val);
break;
case hwmon_temp_crit_hyst:
err = lm90_set_temphyst(data, val);
break;
case hwmon_temp_emergency:
- err = lm90_set_temp8(data, lm90_temp_emerg_index[channel], val);
+ err = lm90_set_temp(data, lm90_temp_emerg_index[channel],
+ channel, val);
break;
case hwmon_temp_offset:
- err = lm90_set_temp11(data, REMOTE_OFFSET, val);
+ val = lm90_temp_to_reg(0, val,
+ lm90_temp_get_resolution(data, REMOTE_OFFSET));
+ err = i2c_smbus_write_byte_data(data->client,
+ LM90_REG_REMOTE_OFFSH,
+ val >> 8);
+ if (err)
+ break;
+ err = i2c_smbus_write_byte_data(data->client,
+ LM90_REG_REMOTE_OFFSL,
+ val & 0xff);
+ if (err)
+ break;
+ data->temp[REMOTE_OFFSET] = val;
break;
default:
err = -EOPNOTSUPP;
@@ -2035,6 +1892,7 @@ static int lm90_probe(struct i2c_client *client)
* ALERT# output
*/
data->alert_alarms = lm90_params[data->kind].alert_alarms;
+ data->resolution = lm90_params[data->kind].resolution ? : 11;
/* Set chip capabilities */
data->flags = lm90_params[data->kind].flags;