/* * The enum passed in the .data pointer of struct of_device_id must * start with a value != 0 since that is a requirement for using * device_get_match_data().
*/ enum chips { max31827 = 1, max31828, max31829 };
/* * Before the Temperature Threshold Alarm, Alarm Hysteresis Threshold * and Resolution bits from Configuration register are changed over I2C, * the part must be in shutdown mode. * * Mutex is used to ensure, that some other process doesn't change the * configuration register.
*/
mutex_lock(&st->lock);
if (!st->enable) { if (!mask)
ret = regmap_write(st->regmap, reg, val); else
ret = regmap_update_bits(st->regmap, reg, mask, val); goto unlock;
}
ret = regmap_read(st->regmap, MAX31827_CONFIGURATION_REG, &cfg); if (ret) goto unlock;
if (!mask)
ret = regmap_write(st->regmap, reg, val); else
ret = regmap_update_bits(st->regmap, reg, mask, val);
if (ret) goto unlock;
ret = regmap_update_bits(st->regmap, MAX31827_CONFIGURATION_REG,
MAX31827_CONFIGURATION_CNV_RATE_MASK,
cnv_rate);
unlock:
mutex_unlock(&st->lock); return ret;
}
staticint write_alarm_val(struct max31827_state *st, unsignedint reg, long val)
{
val = MAX31827_M_DGR_TO_16_BIT(val);
return shutdown_write(st, reg, 0, val);
}
static umode_t max31827_is_visible(constvoid *state, enum hwmon_sensor_types type, u32 attr, int channel)
{ if (type == hwmon_temp) { switch (attr) { case hwmon_temp_enable: case hwmon_temp_max: case hwmon_temp_min: case hwmon_temp_max_hyst: case hwmon_temp_min_hyst: return 0644; case hwmon_temp_input: case hwmon_temp_min_alarm: case hwmon_temp_max_alarm: return 0444; default: return 0;
}
} elseif (type == hwmon_chip) { if (attr == hwmon_chip_update_interval) return 0644;
}
return 0;
}
staticint max31827_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{ struct max31827_state *st = dev_get_drvdata(dev); unsignedint uval; int ret = 0;
switch (type) { case hwmon_temp: switch (attr) { case hwmon_temp_enable:
ret = regmap_read(st->regmap,
MAX31827_CONFIGURATION_REG, &uval); if (ret) break;
break; case hwmon_temp_input:
mutex_lock(&st->lock);
if (!st->enable) { /* * This operation requires mutex protection, * because the chip configuration should not * be changed during the conversion process.
*/
ret = regmap_update_bits(st->regmap,
MAX31827_CONFIGURATION_REG,
MAX31827_CONFIGURATION_1SHOT_MASK,
1); if (ret) {
mutex_unlock(&st->lock); return ret;
}
msleep(max31827_conv_times[st->resolution]);
}
/* * For 12-bit resolution the conversion time is 140 ms, * thus an additional 15 ms is needed to complete the * conversion: 125 ms + 15 ms = 140 ms
*/ if (max31827_resolutions[st->resolution] == 12 &&
st->update_interval == 125)
usleep_range(15000, 20000);
ret = regmap_read(st->regmap, MAX31827_T_REG, &uval);
mutex_unlock(&st->lock);
if (ret) break;
*val = MAX31827_16_BIT_TO_M_DGR(uval);
break; case hwmon_temp_max:
ret = regmap_read(st->regmap, MAX31827_TH_REG, &uval); if (ret) break;
*val = MAX31827_16_BIT_TO_M_DGR(uval); break; case hwmon_temp_max_hyst:
ret = regmap_read(st->regmap, MAX31827_TH_HYST_REG,
&uval); if (ret) break;
*val = MAX31827_16_BIT_TO_M_DGR(uval); break; case hwmon_temp_max_alarm:
ret = regmap_read(st->regmap,
MAX31827_CONFIGURATION_REG, &uval); if (ret) break;
*val = FIELD_GET(MAX31827_CONFIGURATION_O_TEMP_STAT_MASK,
uval); break; case hwmon_temp_min:
ret = regmap_read(st->regmap, MAX31827_TL_REG, &uval); if (ret) break;
*val = MAX31827_16_BIT_TO_M_DGR(uval); break; case hwmon_temp_min_hyst:
ret = regmap_read(st->regmap, MAX31827_TL_HYST_REG,
&uval); if (ret) break;
*val = MAX31827_16_BIT_TO_M_DGR(uval); break; case hwmon_temp_min_alarm:
ret = regmap_read(st->regmap,
MAX31827_CONFIGURATION_REG, &uval); if (ret) break;
staticint max31827_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{ struct max31827_state *st = dev_get_drvdata(dev); int res = 1; int ret;
switch (type) { case hwmon_temp: switch (attr) { case hwmon_temp_enable: if (val >> 1) return -EINVAL;
mutex_lock(&st->lock); /** * The chip should not be enabled while a conversion is * performed. Neither should the chip be enabled when * the alarm values are changed.
*/
st->enable = val;
ret = regmap_update_bits(st->regmap,
MAX31827_CONFIGURATION_REG,
MAX31827_CONFIGURATION_1SHOT_MASK |
MAX31827_CONFIGURATION_CNV_RATE_MASK,
MAX31827_DEVICE_ENABLE(val));
mutex_unlock(&st->lock);
return ret;
case hwmon_temp_max: return write_alarm_val(st, MAX31827_TH_REG, val);
case hwmon_temp_max_hyst: return write_alarm_val(st, MAX31827_TH_HYST_REG, val);
case hwmon_temp_min: return write_alarm_val(st, MAX31827_TL_REG, val);
case hwmon_temp_min_hyst: return write_alarm_val(st, MAX31827_TL_HYST_REG, val);
default: return -EOPNOTSUPP;
}
case hwmon_chip: switch (attr) { case hwmon_chip_update_interval: if (!st->enable) return -EINVAL;
/* * Convert the desired conversion rate into register * bits. res is already initialized with 1. * * This was inspired by lm73 driver.
*/ while (res < ARRAY_SIZE(max31827_conversions) &&
val < max31827_conversions[res])
res++;
if (res == ARRAY_SIZE(max31827_conversions))
res = ARRAY_SIZE(max31827_conversions) - 1;
res = FIELD_PREP(MAX31827_CONFIGURATION_CNV_RATE_MASK,
res);
ret = regmap_update_bits(st->regmap,
MAX31827_CONFIGURATION_REG,
MAX31827_CONFIGURATION_CNV_RATE_MASK,
res); if (ret) return ret;
ret = kstrtouint(buf, 10, &val); if (ret) return ret;
/* * Convert the desired resolution into register * bits. idx is already initialized with 0. * * This was inspired by lm73 driver.
*/ while (idx < ARRAY_SIZE(max31827_resolutions) &&
val < max31827_resolutions[idx])
idx++;
if (idx == ARRAY_SIZE(max31827_resolutions))
idx = ARRAY_SIZE(max31827_resolutions) - 1;
st->resolution = idx;
ret = shutdown_write(st, MAX31827_CONFIGURATION_REG,
MAX31827_CONFIGURATION_RESOLUTION_MASK,
FIELD_PREP(MAX31827_CONFIGURATION_RESOLUTION_MASK,
idx));
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.