in lm95245.c [159:274]
static int lm95245_read_temp(struct device *dev, u32 attr, int channel,
long *val)
{
struct lm95245_data *data = dev_get_drvdata(dev);
struct regmap *regmap = data->regmap;
int ret, regl, regh, regvall, regvalh;
switch (attr) {
case hwmon_temp_input:
regl = channel ? LM95245_REG_R_REMOTE_TEMPL_S :
LM95245_REG_R_LOCAL_TEMPL_S;
regh = channel ? LM95245_REG_R_REMOTE_TEMPH_S :
LM95245_REG_R_LOCAL_TEMPH_S;
ret = regmap_read(regmap, regl, ®vall);
if (ret < 0)
return ret;
ret = regmap_read(regmap, regh, ®valh);
if (ret < 0)
return ret;
/*
* Local temp is always signed.
* Remote temp has both signed and unsigned data.
* Use signed calculation for remote if signed bit is set
* or if reported temperature is below signed limit.
*/
if (!channel || (regvalh & 0x80) || regvalh < 0x7f) {
*val = temp_from_reg_signed(regvalh, regvall);
return 0;
}
ret = regmap_read(regmap, LM95245_REG_R_REMOTE_TEMPL_U,
®vall);
if (ret < 0)
return ret;
ret = regmap_read(regmap, LM95245_REG_R_REMOTE_TEMPH_U,
®valh);
if (ret < 0)
return ret;
*val = temp_from_reg_unsigned(regvalh, regvall);
return 0;
case hwmon_temp_max:
ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OS_LIMIT,
®valh);
if (ret < 0)
return ret;
*val = regvalh * 1000;
return 0;
case hwmon_temp_crit:
regh = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT :
LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT;
ret = regmap_read(regmap, regh, ®valh);
if (ret < 0)
return ret;
*val = regvalh * 1000;
return 0;
case hwmon_temp_max_hyst:
ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OS_LIMIT,
®valh);
if (ret < 0)
return ret;
ret = regmap_read(regmap, LM95245_REG_RW_COMMON_HYSTERESIS,
®vall);
if (ret < 0)
return ret;
*val = (regvalh - regvall) * 1000;
return 0;
case hwmon_temp_crit_hyst:
regh = channel ? LM95245_REG_RW_REMOTE_TCRIT_LIMIT :
LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT;
ret = regmap_read(regmap, regh, ®valh);
if (ret < 0)
return ret;
ret = regmap_read(regmap, LM95245_REG_RW_COMMON_HYSTERESIS,
®vall);
if (ret < 0)
return ret;
*val = (regvalh - regvall) * 1000;
return 0;
case hwmon_temp_type:
ret = regmap_read(regmap, LM95245_REG_RW_CONFIG2, ®valh);
if (ret < 0)
return ret;
*val = (regvalh & CFG2_REMOTE_TT) ? 1 : 2;
return 0;
case hwmon_temp_offset:
ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OFFL,
®vall);
if (ret < 0)
return ret;
ret = regmap_read(regmap, LM95245_REG_RW_REMOTE_OFFH,
®valh);
if (ret < 0)
return ret;
*val = temp_from_reg_signed(regvalh, regvall);
return 0;
case hwmon_temp_max_alarm:
ret = regmap_read(regmap, LM95245_REG_R_STATUS1, ®valh);
if (ret < 0)
return ret;
*val = !!(regvalh & STATUS1_ROS);
return 0;
case hwmon_temp_crit_alarm:
ret = regmap_read(regmap, LM95245_REG_R_STATUS1, ®valh);
if (ret < 0)
return ret;
*val = !!(regvalh & (channel ? STATUS1_RTCRIT : STATUS1_LOC));
return 0;
case hwmon_temp_fault:
ret = regmap_read(regmap, LM95245_REG_R_STATUS1, ®valh);
if (ret < 0)
return ret;
*val = !!(regvalh & STATUS1_DIODE_FAULT);
return 0;
default:
return -EOPNOTSUPP;
}
}