Lines Matching +full:alert +full:- +full:celsius

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * lm63.c - driver for the National Semiconductor LM63 temperature sensor
5 * Copyright (C) 2004-2008 Jean Delvare <jdelvare@suse.de>
16 * - No low limit for local temperature.
17 * - No critical limit for local temperature.
18 * - Critical limit for remote temperature can be changed only once. We
19 * will consider that the critical limit is read-only.
32 #include <linux/hwmon-sysfs.h>
102 * For tachometer counts, the LM63 uses 16-bit values.
104 * value, it uses signed 8-bit values with LSB = 1 degree Celsius.
105 * For remote temperature, low and high limits, it uses signed 11-bit values
106 * with LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
107 * For LM64 the actual remote diode temperature is 16 degree Celsius higher
117 #define TEMP8_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
122 #define TEMP11_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
130 ((1000 << (LM63_MAX_CONVRATE - (rate))) / (max))
159 1-12: lookup table */
163 3-14: lookup table */
180 if (data->remote_unsigned) in temp8_from_reg()
181 return TEMP8_FROM_REG((u8)data->temp8[nr]); in temp8_from_reg()
182 return TEMP8_FROM_REG(data->temp8[nr]); in temp8_from_reg()
187 return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000); in lut_temp_from_reg()
192 val -= data->temp2_offset; in lut_temp_to_reg()
193 if (data->lut_temp_highres) in lut_temp_to_reg()
201 * client->update_lock must be held when calling this function.
205 struct i2c_client *client = data->client; in lm63_update_lut()
208 if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || in lm63_update_lut()
209 !data->lut_valid) { in lm63_update_lut()
210 for (i = 0; i < data->lut_size; i++) { in lm63_update_lut()
211 data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, in lm63_update_lut()
213 data->temp8[3 + i] = i2c_smbus_read_byte_data(client, in lm63_update_lut()
216 data->lut_temp_hyst = i2c_smbus_read_byte_data(client, in lm63_update_lut()
219 data->lut_last_updated = jiffies; in lm63_update_lut()
220 data->lut_valid = 1; in lm63_update_lut()
227 struct i2c_client *client = data->client; in lm63_update_device()
230 mutex_lock(&data->update_lock); in lm63_update_device()
232 next_update = data->last_updated + in lm63_update_device()
233 msecs_to_jiffies(data->update_interval); in lm63_update_device()
234 if (time_after(jiffies, next_update) || !data->valid) { in lm63_update_device()
235 if (data->config & 0x04) { /* tachometer enabled */ in lm63_update_device()
237 data->fan[0] = i2c_smbus_read_byte_data(client, in lm63_update_device()
239 data->fan[0] |= i2c_smbus_read_byte_data(client, in lm63_update_device()
241 data->fan[1] = (i2c_smbus_read_byte_data(client, in lm63_update_device()
247 data->pwm1_freq = i2c_smbus_read_byte_data(client, in lm63_update_device()
249 if (data->pwm1_freq == 0) in lm63_update_device()
250 data->pwm1_freq = 1; in lm63_update_device()
251 data->pwm1[0] = i2c_smbus_read_byte_data(client, in lm63_update_device()
254 data->temp8[0] = i2c_smbus_read_byte_data(client, in lm63_update_device()
256 data->temp8[1] = i2c_smbus_read_byte_data(client, in lm63_update_device()
260 data->temp11[0] = i2c_smbus_read_byte_data(client, in lm63_update_device()
262 data->temp11[0] |= i2c_smbus_read_byte_data(client, in lm63_update_device()
264 data->temp11[1] = (i2c_smbus_read_byte_data(client, in lm63_update_device()
268 data->temp11[2] = (i2c_smbus_read_byte_data(client, in lm63_update_device()
272 data->temp11[3] = (i2c_smbus_read_byte_data(client, in lm63_update_device()
277 if (data->kind == lm96163) in lm63_update_device()
278 data->temp11u = (i2c_smbus_read_byte_data(client, in lm63_update_device()
283 data->temp8[2] = i2c_smbus_read_byte_data(client, in lm63_update_device()
285 data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, in lm63_update_device()
288 data->alarms = i2c_smbus_read_byte_data(client, in lm63_update_device()
291 data->last_updated = jiffies; in lm63_update_device()
292 data->valid = 1; in lm63_update_device()
297 mutex_unlock(&data->update_lock); in lm63_update_device()
310 mutex_lock(&data->update_lock); in lm63_lut_looks_bad()
313 for (i = 1; i < data->lut_size; i++) { in lm63_lut_looks_bad()
314 if (data->pwm1[1 + i - 1] > data->pwm1[1 + i] in lm63_lut_looks_bad()
315 || data->temp8[3 + i - 1] > data->temp8[3 + i]) { in lm63_lut_looks_bad()
322 mutex_unlock(&data->update_lock); in lm63_lut_looks_bad()
324 return i == data->lut_size ? 0 : 1; in lm63_lut_looks_bad()
336 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index])); in show_fan()
343 struct i2c_client *client = data->client; in set_fan()
351 mutex_lock(&data->update_lock); in set_fan()
352 data->fan[1] = FAN_TO_REG(val); in set_fan()
354 data->fan[1] & 0xFF); in set_fan()
356 data->fan[1] >> 8); in set_fan()
357 mutex_unlock(&data->update_lock); in set_fan()
366 int nr = attr->index; in show_pwm1()
369 if (data->pwm_highres) in show_pwm1()
370 pwm = data->pwm1[nr]; in show_pwm1()
372 pwm = data->pwm1[nr] >= 2 * data->pwm1_freq ? in show_pwm1()
373 255 : (data->pwm1[nr] * 255 + data->pwm1_freq) / in show_pwm1()
374 (2 * data->pwm1_freq); in show_pwm1()
384 struct i2c_client *client = data->client; in set_pwm1()
385 int nr = attr->index; in set_pwm1()
390 if (!(data->config_fan & 0x20)) /* register is read-only */ in set_pwm1()
391 return -EPERM; in set_pwm1()
397 reg = nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE; in set_pwm1()
400 mutex_lock(&data->update_lock); in set_pwm1()
401 data->pwm1[nr] = data->pwm_highres ? val : in set_pwm1()
402 (val * data->pwm1_freq * 2 + 127) / 255; in set_pwm1()
403 i2c_smbus_write_byte_data(client, reg, data->pwm1[nr]); in set_pwm1()
404 mutex_unlock(&data->update_lock); in set_pwm1()
412 return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); in pwm1_enable_show()
420 struct i2c_client *client = data->client; in pwm1_enable_store()
428 return -EINVAL; in pwm1_enable_store()
435 return -EPERM; in pwm1_enable_store()
437 mutex_lock(&data->update_lock); in pwm1_enable_store()
438 data->config_fan = i2c_smbus_read_byte_data(client, in pwm1_enable_store()
441 data->config_fan |= 0x20; in pwm1_enable_store()
443 data->config_fan &= ~0x20; in pwm1_enable_store()
445 data->config_fan); in pwm1_enable_store()
446 mutex_unlock(&data->update_lock); in pwm1_enable_store()
462 return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index])); in show_local_temp8()
471 return sprintf(buf, "%d\n", temp8_from_reg(data, attr->index) in show_remote_temp8()
472 + data->temp2_offset); in show_remote_temp8()
481 return sprintf(buf, "%d\n", lut_temp_from_reg(data, attr->index) in show_lut_temp()
482 + data->temp2_offset); in show_lut_temp()
490 struct i2c_client *client = data->client; in set_temp8()
491 int nr = attr->index; in set_temp8()
501 mutex_lock(&data->update_lock); in set_temp8()
505 if (data->remote_unsigned) in set_temp8()
506 temp = TEMP8U_TO_REG(val - data->temp2_offset); in set_temp8()
508 temp = TEMP8_TO_REG(val - data->temp2_offset); in set_temp8()
515 reg = LM63_REG_LUT_TEMP(nr - 3); in set_temp8()
518 data->temp8[nr] = temp; in set_temp8()
520 mutex_unlock(&data->update_lock); in set_temp8()
529 int nr = attr->index; in show_temp11()
537 if (data->temp11u) in show_temp11()
538 temp = TEMP11_FROM_REG(data->temp11u); in show_temp11()
540 temp = TEMP11_FROM_REG(data->temp11[nr]); in show_temp11()
542 if (data->remote_unsigned && nr == 2) in show_temp11()
543 temp = TEMP11_FROM_REG((u16)data->temp11[nr]); in show_temp11()
545 temp = TEMP11_FROM_REG(data->temp11[nr]); in show_temp11()
547 return sprintf(buf, "%d\n", temp + data->temp2_offset); in show_temp11()
564 struct i2c_client *client = data->client; in set_temp11()
567 int nr = attr->index; in set_temp11()
573 mutex_lock(&data->update_lock); in set_temp11()
574 if (data->remote_unsigned && nr == 2) in set_temp11()
575 data->temp11[nr] = TEMP11U_TO_REG(val - data->temp2_offset); in set_temp11()
577 data->temp11[nr] = TEMP11_TO_REG(val - data->temp2_offset); in set_temp11()
579 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2], in set_temp11()
580 data->temp11[nr] >> 8); in set_temp11()
581 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1], in set_temp11()
582 data->temp11[nr] & 0xff); in set_temp11()
583 mutex_unlock(&data->update_lock); in set_temp11()
589 * an absolute to user-space
596 + data->temp2_offset in temp2_crit_hyst_show()
597 - TEMP8_FROM_REG(data->temp2_crit_hyst)); in temp2_crit_hyst_show()
606 return sprintf(buf, "%d\n", lut_temp_from_reg(data, attr->index) in show_lut_temp_hyst()
607 + data->temp2_offset in show_lut_temp_hyst()
608 - TEMP8_FROM_REG(data->lut_temp_hyst)); in show_lut_temp_hyst()
612 * And now the other way around, user-space provides an absolute
620 struct i2c_client *client = data->client; in temp2_crit_hyst_store()
629 mutex_lock(&data->update_lock); in temp2_crit_hyst_store()
630 hyst = temp8_from_reg(data, 2) + data->temp2_offset - val; in temp2_crit_hyst_store()
633 mutex_unlock(&data->update_lock); in temp2_crit_hyst_store()
639 * client->update_lock must be held when calling this function.
643 struct i2c_client *client = data->client; in lm63_set_convrate()
652 / data->max_convrate_hz; in lm63_set_convrate()
658 data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz, i); in lm63_set_convrate()
666 return sprintf(buf, "%u\n", data->update_interval); in update_interval_show()
681 mutex_lock(&data->update_lock); in update_interval_store()
683 mutex_unlock(&data->update_lock); in update_interval_store()
693 return sprintf(buf, data->trutherm ? "1\n" : "2\n"); in temp2_type_show()
701 struct i2c_client *client = data->client; in temp2_type_store()
710 return -EINVAL; in temp2_type_store()
712 mutex_lock(&data->update_lock); in temp2_type_store()
713 data->trutherm = val == 1; in temp2_type_store()
716 reg | (data->trutherm ? 0x02 : 0x00)); in temp2_type_store()
717 data->valid = 0; in temp2_type_store()
718 mutex_unlock(&data->update_lock); in temp2_type_store()
727 return sprintf(buf, "%u\n", data->alarms); in alarms_show()
735 int bitnr = attr->index; in show_alarm()
737 return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); in show_alarm()
938 && (data->kind == lm64 || in lm63_attribute_mode()
939 (data->kind == lm96163 && (data->config & 0x02)))) in lm63_attribute_mode()
940 return attr->mode | S_IWUSR; in lm63_attribute_mode()
942 return attr->mode; in lm63_attribute_mode()
966 /* Return 0 if detection is successful, -ENODEV otherwise */
970 struct i2c_adapter *adapter = client->adapter; in lm63_detect()
973 int address = client->addr; in lm63_detect()
976 return -ENODEV; in lm63_detect()
992 dev_dbg(&adapter->dev, in lm63_detect()
995 return -ENODEV; in lm63_detect()
999 strlcpy(info->type, "lm63", I2C_NAME_SIZE); in lm63_detect()
1001 strlcpy(info->type, "lm64", I2C_NAME_SIZE); in lm63_detect()
1003 strlcpy(info->type, "lm96163", I2C_NAME_SIZE); in lm63_detect()
1005 return -ENODEV; in lm63_detect()
1016 struct i2c_client *client = data->client; in lm63_init_client()
1017 struct device *dev = &client->dev; in lm63_init_client()
1020 data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1); in lm63_init_client()
1021 data->config_fan = i2c_smbus_read_byte_data(client, in lm63_init_client()
1025 if (data->config & 0x40) { /* standby */ in lm63_init_client()
1027 data->config &= 0xA7; in lm63_init_client()
1029 data->config); in lm63_init_client()
1032 if (data->kind == lm64) in lm63_init_client()
1033 data->config |= 0x04; in lm63_init_client()
1036 data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ); in lm63_init_client()
1037 if (data->pwm1_freq == 0) in lm63_init_client()
1038 data->pwm1_freq = 1; in lm63_init_client()
1040 switch (data->kind) { in lm63_init_client()
1043 data->max_convrate_hz = LM63_MAX_CONVRATE_HZ; in lm63_init_client()
1044 data->lut_size = 8; in lm63_init_client()
1047 data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ; in lm63_init_client()
1048 data->lut_size = 12; in lm63_init_client()
1049 data->trutherm in lm63_init_client()
1057 data->update_interval = UPDATE_INTERVAL(data->max_convrate_hz, in lm63_init_client()
1064 if (data->kind == lm96163) { in lm63_init_client()
1069 data->lut_temp_highres = true; in lm63_init_client()
1071 && !(data->config_fan & 0x08) && data->pwm1_freq == 8) in lm63_init_client()
1072 data->pwm_highres = true; in lm63_init_client()
1074 data->remote_unsigned = true; in lm63_init_client()
1078 if (data->kind == lm63) in lm63_init_client()
1079 dev_dbg(dev, "Alert/tach pin configured for %s\n", in lm63_init_client()
1080 (data->config & 0x04) ? "tachometer input" : in lm63_init_client()
1081 "alert output"); in lm63_init_client()
1083 (data->config_fan & 0x08) ? "1.4" : "360", in lm63_init_client()
1084 ((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq); in lm63_init_client()
1086 (data->config_fan & 0x10) ? "low" : "high", in lm63_init_client()
1087 (data->config_fan & 0x20) ? "manual" : "auto"); in lm63_init_client()
1094 struct device *dev = &client->dev; in lm63_probe()
1101 return -ENOMEM; in lm63_probe()
1103 data->client = client; in lm63_probe()
1104 mutex_init(&data->update_lock); in lm63_probe()
1107 if (client->dev.of_node) in lm63_probe()
1108 data->kind = (enum chips)of_device_get_match_data(&client->dev); in lm63_probe()
1110 data->kind = i2c_match_id(lm63_id, client)->driver_data; in lm63_probe()
1111 if (data->kind == lm64) in lm63_probe()
1112 data->temp2_offset = 16000; in lm63_probe()
1118 data->groups[groups++] = &lm63_group; in lm63_probe()
1119 if (data->config & 0x04) /* tachometer enabled */ in lm63_probe()
1120 data->groups[groups++] = &lm63_group_fan1; in lm63_probe()
1122 if (data->kind == lm96163) { in lm63_probe()
1123 data->groups[groups++] = &lm63_group_temp2_type; in lm63_probe()
1124 data->groups[groups++] = &lm63_group_extra_lut; in lm63_probe()
1127 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, in lm63_probe()
1128 data, data->groups); in lm63_probe()