// SPDX-License-Identifier: GPL-2.0-or-later /* * adt7x10.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring * This driver handles the ADT7410 and compatible digital temperature sensors. * Hartmut Knaack <knaack.h@gmx.de> 2012-07-22 * based on lm75.c by Frodo Looijaard <frodol@dds.nl> * and adt7410.c from iio-staging by Sonic Zhang <sonic.zhang@analog.com>
*/
/* straight from the datasheet */ #define ADT7X10_TEMP_MIN (-55000) #define ADT7X10_TEMP_MAX 150000
/* Each client has this additional data */ struct adt7x10_data { struct regmap *regmap; struct mutex update_lock;
u8 config;
u8 oldconfig; bool valid; /* true if temperature valid */
};
staticint ADT7X10_REG_TO_TEMP(struct adt7x10_data *data, s16 reg)
{ /* in 13 bit mode, bits 0-2 are status flags - mask them out */ if (!(data->config & ADT7X10_RESOLUTION))
reg &= ADT7X10_T13_VALUE_MASK; /* * temperature is stored in twos complement format, in steps of * 1/128°C
*/ return DIV_ROUND_CLOSEST(reg * 1000, 128);
}
staticint adt7x10_temp_write(struct adt7x10_data *data, int index, long temp)
{ int ret;
mutex_lock(&data->update_lock);
ret = regmap_write(data->regmap, ADT7X10_REG_TEMP[index],
ADT7X10_TEMP_TO_REG(temp));
mutex_unlock(&data->update_lock); return ret;
}
staticint adt7x10_hyst_read(struct adt7x10_data *data, int index, long *val)
{ unsignedint regs[2] = {ADT7X10_T_HYST, ADT7X10_REG_TEMP[index]}; int hyst, ret;
u16 regdata[2];
ret = regmap_multi_reg_read(data->regmap, regs, regdata, 2); if (ret) return ret;
hyst = (regdata[0] & ADT7X10_T_HYST_MASK) * 1000;
/* * hysteresis is stored as a 4 bit offset in the device, convert it * to an absolute value
*/ /* min has positive offset, others have negative */ if (index == adt7x10_t_alarm_low)
hyst = -hyst;
staticint adt7x10_hyst_write(struct adt7x10_data *data, long hyst)
{ unsignedint regval; int limit, ret;
mutex_lock(&data->update_lock);
/* convert absolute hysteresis value to a 4 bit delta value */
ret = regmap_read(data->regmap, ADT7X10_T_ALARM_HIGH, ®val); if (ret < 0) goto abort;
staticint adt7x10_alarm_read(struct adt7x10_data *data, int index, long *val)
{ unsignedint status; int ret;
ret = regmap_read(data->regmap, ADT7X10_STATUS, &status); if (ret < 0) return ret;
*val = !!(status & index);
return 0;
}
static umode_t adt7x10_is_visible(constvoid *data, enum hwmon_sensor_types type,
u32 attr, int channel)
{ switch (attr) { case hwmon_temp_max: case hwmon_temp_min: case hwmon_temp_crit: case hwmon_temp_max_hyst: return 0644; case hwmon_temp_input: case hwmon_temp_min_alarm: case hwmon_temp_max_alarm: case hwmon_temp_crit_alarm: case hwmon_temp_min_hyst: case hwmon_temp_crit_hyst: return 0444; default: break;
}
return 0;
}
staticint adt7x10_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{ struct adt7x10_data *data = dev_get_drvdata(dev);
switch (attr) { case hwmon_temp_input: return adt7x10_temp_read(data, adt7x10_temperature, val); case hwmon_temp_max: return adt7x10_temp_read(data, adt7x10_t_alarm_high, val); case hwmon_temp_min: return adt7x10_temp_read(data, adt7x10_t_alarm_low, val); case hwmon_temp_crit: return adt7x10_temp_read(data, adt7x10_t_crit, val); case hwmon_temp_max_hyst: return adt7x10_hyst_read(data, adt7x10_t_alarm_high, val); case hwmon_temp_min_hyst: return adt7x10_hyst_read(data, adt7x10_t_alarm_low, val); case hwmon_temp_crit_hyst: return adt7x10_hyst_read(data, adt7x10_t_crit, val); case hwmon_temp_min_alarm: return adt7x10_alarm_read(data, ADT7X10_STAT_T_LOW, val); case hwmon_temp_max_alarm: return adt7x10_alarm_read(data, ADT7X10_STAT_T_HIGH, val); case hwmon_temp_crit_alarm: return adt7x10_alarm_read(data, ADT7X10_STAT_T_CRIT, val); default: return -EOPNOTSUPP;
}
}
staticint adt7x10_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{ struct adt7x10_data *data = dev_get_drvdata(dev);
switch (attr) { case hwmon_temp_max: return adt7x10_temp_write(data, adt7x10_t_alarm_high, val); case hwmon_temp_min: return adt7x10_temp_write(data, adt7x10_t_alarm_low, val); case hwmon_temp_crit: return adt7x10_temp_write(data, adt7x10_t_crit, val); case hwmon_temp_max_hyst: return adt7x10_hyst_write(data, val); default: return -EOPNOTSUPP;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.