Lines Matching +full:scaled +full:- +full:output +full:- +full:hz

1 // SPDX-License-Identifier: GPL-2.0-or-later
9 * Copyright (C) 2004-2008 Jean Delvare <jdelvare@suse.de>
17 * Voltages are scaled internally with ratios such that the nominal value of
20 * reported with a 1 deg resolution and a 3-4 deg accuracy. Complete
30 * - in0+in5 (default) or temp3
31 * - fan1 (default) or in6
32 * - fan2 (default) or in7
33 * - VID lines (default) or IRQ lines (not handled by this driver)
35 * The LM87 additionally features an analog output, supposedly usable to
52 #include <linux/hwmon-sysfs.h>
53 #include <linux/hwmon-vid.h>
105 * The LM87 uses signed 8-bit values for temperatures.
114 #define TEMP_TO_REG(val) ((val) <= -127500 ? -128 : \
116 (((val) < 0 ? (val) - 500 : \
188 mutex_lock(&data->update_lock); in lm87_update_device()
190 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { in lm87_update_device()
193 dev_dbg(&client->dev, "Updating data.\n"); in lm87_update_device()
195 i = (data->channel & CHAN_TEMP3) ? 1 : 0; in lm87_update_device()
196 j = (data->channel & CHAN_TEMP3) ? 5 : 6; in lm87_update_device()
198 data->in[i] = lm87_read_value(client, in lm87_update_device()
200 data->in_min[i] = lm87_read_value(client, in lm87_update_device()
202 data->in_max[i] = lm87_read_value(client, in lm87_update_device()
207 if (data->channel & CHAN_NO_FAN(i)) { in lm87_update_device()
208 data->in[6+i] = lm87_read_value(client, in lm87_update_device()
210 data->in_max[6+i] = lm87_read_value(client, in lm87_update_device()
212 data->in_min[6+i] = lm87_read_value(client, in lm87_update_device()
216 data->fan[i] = lm87_read_value(client, in lm87_update_device()
218 data->fan_min[i] = lm87_read_value(client, in lm87_update_device()
223 j = (data->channel & CHAN_TEMP3) ? 3 : 2; in lm87_update_device()
225 data->temp[i] = lm87_read_value(client, in lm87_update_device()
227 data->temp_high[i] = lm87_read_value(client, in lm87_update_device()
229 data->temp_low[i] = lm87_read_value(client, in lm87_update_device()
235 data->temp_crit_int = min(i, j); in lm87_update_device()
239 data->temp_crit_ext = min(i, j); in lm87_update_device()
242 data->fan_div[0] = (i >> 4) & 0x03; in lm87_update_device()
243 data->fan_div[1] = (i >> 6) & 0x03; in lm87_update_device()
244 data->vid = (i & 0x0F) in lm87_update_device()
248 data->alarms = lm87_read_value(client, LM87_REG_ALARMS1) in lm87_update_device()
251 data->aout = lm87_read_value(client, LM87_REG_AOUT); in lm87_update_device()
253 data->last_updated = jiffies; in lm87_update_device()
254 data->valid = true; in lm87_update_device()
257 mutex_unlock(&data->update_lock); in lm87_update_device()
270 int nr = to_sensor_dev_attr(attr)->index; in in_input_show()
272 return sprintf(buf, "%u\n", IN_FROM_REG(data->in[nr], in in_input_show()
273 data->in_scale[nr])); in in_input_show()
280 int nr = to_sensor_dev_attr(attr)->index; in in_min_show()
282 return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[nr], in in_min_show()
283 data->in_scale[nr])); in in_min_show()
290 int nr = to_sensor_dev_attr(attr)->index; in in_max_show()
292 return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[nr], in in_max_show()
293 data->in_scale[nr])); in in_max_show()
301 int nr = to_sensor_dev_attr(attr)->index; in in_min_store()
309 mutex_lock(&data->update_lock); in in_min_store()
310 data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]); in in_min_store()
312 LM87_REG_AIN_MIN(nr - 6), data->in_min[nr]); in in_min_store()
313 mutex_unlock(&data->update_lock); in in_min_store()
322 int nr = to_sensor_dev_attr(attr)->index; in in_max_store()
330 mutex_lock(&data->update_lock); in in_max_store()
331 data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]); in in_max_store()
333 LM87_REG_AIN_MAX(nr - 6), data->in_max[nr]); in in_max_store()
334 mutex_unlock(&data->update_lock); in in_max_store()
367 int nr = to_sensor_dev_attr(attr)->index; in temp_input_show()
369 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); in temp_input_show()
376 int nr = to_sensor_dev_attr(attr)->index; in temp_low_show()
379 TEMP_FROM_REG(data->temp_low[nr])); in temp_low_show()
386 int nr = to_sensor_dev_attr(attr)->index; in temp_high_show()
389 TEMP_FROM_REG(data->temp_high[nr])); in temp_high_show()
398 int nr = to_sensor_dev_attr(attr)->index; in temp_low_store()
406 mutex_lock(&data->update_lock); in temp_low_store()
407 data->temp_low[nr] = TEMP_TO_REG(val); in temp_low_store()
408 lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]); in temp_low_store()
409 mutex_unlock(&data->update_lock); in temp_low_store()
419 int nr = to_sensor_dev_attr(attr)->index; in temp_high_store()
427 mutex_lock(&data->update_lock); in temp_high_store()
428 data->temp_high[nr] = TEMP_TO_REG(val); in temp_high_store()
429 lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]); in temp_high_store()
430 mutex_unlock(&data->update_lock); in temp_high_store()
448 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_int)); in temp1_crit_show()
455 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_ext)); in temp2_crit_show()
466 int nr = to_sensor_dev_attr(attr)->index; in fan_input_show()
468 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], in fan_input_show()
469 FAN_DIV_FROM_REG(data->fan_div[nr]))); in fan_input_show()
476 int nr = to_sensor_dev_attr(attr)->index; in fan_min_show()
478 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], in fan_min_show()
479 FAN_DIV_FROM_REG(data->fan_div[nr]))); in fan_min_show()
486 int nr = to_sensor_dev_attr(attr)->index; in fan_div_show()
489 FAN_DIV_FROM_REG(data->fan_div[nr])); in fan_div_show()
498 int nr = to_sensor_dev_attr(attr)->index; in fan_min_store()
506 mutex_lock(&data->update_lock); in fan_min_store()
507 data->fan_min[nr] = FAN_TO_REG(val, in fan_min_store()
508 FAN_DIV_FROM_REG(data->fan_div[nr])); in fan_min_store()
509 lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]); in fan_min_store()
510 mutex_unlock(&data->update_lock); in fan_min_store()
526 int nr = to_sensor_dev_attr(attr)->index; in fan_div_store()
536 mutex_lock(&data->update_lock); in fan_div_store()
537 min = FAN_FROM_REG(data->fan_min[nr], in fan_div_store()
538 FAN_DIV_FROM_REG(data->fan_div[nr])); in fan_div_store()
542 data->fan_div[nr] = 0; in fan_div_store()
545 data->fan_div[nr] = 1; in fan_div_store()
548 data->fan_div[nr] = 2; in fan_div_store()
551 data->fan_div[nr] = 3; in fan_div_store()
554 mutex_unlock(&data->update_lock); in fan_div_store()
555 return -EINVAL; in fan_div_store()
561 reg = (reg & 0xCF) | (data->fan_div[0] << 4); in fan_div_store()
564 reg = (reg & 0x3F) | (data->fan_div[1] << 6); in fan_div_store()
569 data->fan_min[nr] = FAN_TO_REG(min, val); in fan_div_store()
571 data->fan_min[nr]); in fan_div_store()
572 mutex_unlock(&data->update_lock); in fan_div_store()
588 return sprintf(buf, "%d\n", data->alarms); in alarms_show()
596 return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); in cpu0_vid_show()
604 return sprintf(buf, "%d\n", data->vrm); in vrm_show()
618 return -EINVAL; in vrm_store()
620 data->vrm = val; in vrm_store()
629 return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout)); in aout_output_show()
644 mutex_lock(&data->update_lock); in aout_output_store()
645 data->aout = AOUT_TO_REG(val); in aout_output_store()
646 lm87_write_value(client, LM87_REG_AOUT, data->aout); in aout_output_store()
647 mutex_unlock(&data->update_lock); in aout_output_store()
656 int bitnr = to_sensor_dev_attr(attr)->index; in alarm_show()
657 return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); in alarm_show()
807 /* Return 0 if detection is successful, -ENODEV otherwise */
810 struct i2c_adapter *adapter = client->adapter; in lm87_detect()
815 return -ENODEV; in lm87_detect()
818 return -ENODEV; in lm87_detect()
831 dev_dbg(&adapter->dev, "LM87 detection failed at 0x%02x\n", in lm87_detect()
832 client->addr); in lm87_detect()
833 return -ENODEV; in lm87_detect()
836 strscpy(info->type, name, I2C_NAME_SIZE); in lm87_detect()
846 lm87_write_value(client, LM87_REG_CONFIG, data->config); in lm87_restore_config()
853 struct device_node *of_node = client->dev.of_node; in lm87_init_client()
858 if (of_property_read_bool(of_node, "has-temp3")) in lm87_init_client()
860 if (of_property_read_bool(of_node, "has-in6")) in lm87_init_client()
862 if (of_property_read_bool(of_node, "has-in7")) in lm87_init_client()
864 vcc = devm_regulator_get_optional(&client->dev, "vcc"); in lm87_init_client()
869 data->channel = val; in lm87_init_client()
871 LM87_REG_CHANNEL_MODE, data->channel); in lm87_init_client()
872 } else if (dev_get_platdata(&client->dev)) { in lm87_init_client()
873 data->channel = *(u8 *)dev_get_platdata(&client->dev); in lm87_init_client()
875 LM87_REG_CHANNEL_MODE, data->channel); in lm87_init_client()
877 data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE); in lm87_init_client()
879 data->config = lm87_read_value(client, LM87_REG_CONFIG) & 0x6F; in lm87_init_client()
881 rc = devm_add_action(&client->dev, lm87_restore_config, client); in lm87_init_client()
885 if (!(data->config & 0x01)) { in lm87_init_client()
888 /* Limits are left uninitialized after power-up */ in lm87_init_client()
899 if (data->channel & CHAN_TEMP3) { in lm87_init_client()
909 if ((data->config & 0x09) != 0x01) in lm87_init_client()
911 (data->config & 0x77) | 0x01); in lm87_init_client()
922 data = devm_kzalloc(&client->dev, sizeof(struct lm87_data), GFP_KERNEL); in lm87_probe()
924 return -ENOMEM; in lm87_probe()
927 mutex_init(&data->update_lock); in lm87_probe()
934 data->in_scale[0] = 2500; in lm87_probe()
935 data->in_scale[1] = 2700; in lm87_probe()
936 data->in_scale[2] = (data->channel & CHAN_VCC_5V) ? 5000 : 3300; in lm87_probe()
937 data->in_scale[3] = 5000; in lm87_probe()
938 data->in_scale[4] = 12000; in lm87_probe()
939 data->in_scale[5] = 2700; in lm87_probe()
940 data->in_scale[6] = 1875; in lm87_probe()
941 data->in_scale[7] = 1875; in lm87_probe()
947 data->attr_groups[group_tail++] = &lm87_group; in lm87_probe()
948 if (data->channel & CHAN_NO_FAN(0)) in lm87_probe()
949 data->attr_groups[group_tail++] = &lm87_group_in6; in lm87_probe()
951 data->attr_groups[group_tail++] = &lm87_group_fan1; in lm87_probe()
953 if (data->channel & CHAN_NO_FAN(1)) in lm87_probe()
954 data->attr_groups[group_tail++] = &lm87_group_in7; in lm87_probe()
956 data->attr_groups[group_tail++] = &lm87_group_fan2; in lm87_probe()
958 if (data->channel & CHAN_TEMP3) in lm87_probe()
959 data->attr_groups[group_tail++] = &lm87_group_temp3; in lm87_probe()
961 data->attr_groups[group_tail++] = &lm87_group_in0_5; in lm87_probe()
963 if (!(data->channel & CHAN_NO_VID)) { in lm87_probe()
964 data->vrm = vid_which_vrm(); in lm87_probe()
965 data->attr_groups[group_tail++] = &lm87_group_vid; in lm87_probe()
969 &client->dev, client->name, client, data->attr_groups); in lm87_probe()