Lines Matching +full:combined +full:- +full:sensors

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * via686a.c - Part of lm_sensors, Linux kernel modules
6 * Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
11 * (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
18 * Warning - only supports a single device.
29 #include <linux/hwmon-sysfs.h>
44 "Initialize the base address of the sensors");
49 * The Via 686a southbridge has a LM78-like chip integrated on the same IC.
61 /* ins numbered 0-4 */
66 /* fans numbered 1-2 */
70 /* temps numbered 1-3 */
74 /* bits 7-6 */
76 /* 2 = bits 5-4, 3 = bits 7-6 */
84 * The following register sets temp interrupt mode (bits 1-0 for temp1,
85 * 3-2 for temp2, 5-4 for temp3). Modes are:
86 * 00 interrupt stays as long as value is out-of-range
88 * 10 comparator mode- like 00, but ignores hysteresis
101 * From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
110 * regVal = (volts/factor-133)/25
118 * Rounding is done (120500 is actually 133000 - 12500). in IN_TO_REG()
124 return (u8) clamp_val((val * 21024 - 1205000) / 250000, 0, 255); in IN_TO_REG()
126 return (u8) clamp_val((val * 15737 - 1205000) / 250000, 0, 255); in IN_TO_REG()
128 return (u8) clamp_val((val * 10108 - 1205000) / 250000, 0, 255); in IN_TO_REG()
130 return (u8) clamp_val((val * 41714 - 12050000) / 2500000, 0, in IN_TO_REG()
170 * linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
172 * return double(temp)*0.427-32.08;
174 * return double(temp)*0.582-58.16;
176 * return double(temp)*0.924-127.33;
178 * A fifth-order polynomial fits the unofficial data (provided by Alex van
181 * Here's the fifth-order fit to the 8-bit data:
182 * temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
183 * 2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
185 * (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
188 * Alas, none of the elegant function-fit solutions will work because we
191 * look-up table stuff. The unofficial data (see below) have effectively
192 * 7-bit resolution (they are rounded to the nearest degree). I'm assuming
195 * I used the 5th-order poly fit described above and solved for
196 * VIA register values 0-255. I *10 before rounding, so we get tenth-degree
197 * precision. (I could have done all 1024 values for our 10-bit readings,
198 * but the function is very linear in the useful range (0-80 deg C), so
199 * we'll just use linear interpolation for 10-bit readings.) So, temp_lut
200 * is the temp at via register values 0-255:
203 -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
204 -503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
205 -362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
206 -255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
207 -173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
208 -108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
209 -44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
229 * (for via register values 12-240):
230 * {-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
231 * -30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
232 * -15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
233 * -3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
242 * Here's the reverse LUT. I got it by doing a 6-th order poly fit (needed
244 * solving for each temp value from -50 to 110 (the useable range for
246 * viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
247 * - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
267 * Converting temps to (8-bit) hyst and over registers
269 * The +50 is because the temps start at -50
273 return via_lut[val <= -50000 ? 0 : val >= 110000 ? 160 : in TEMP_TO_REG()
274 (val < 0 ? val - 500 : val + 500) / 1000 + 50]; in TEMP_TO_REG()
277 /* for 8-bit temperature hyst and over registers */
280 /* for 10-bit temperature readings */
291 return (temp_lut[eight_bits] * (4 - two_bits) + in TEMP_FROM_REG10()
319 u16 alarms; /* Register encoding, combined */
329 return inb_p(data->addr + reg); in via686a_read_value()
335 outb_p(value, data->addr + reg); in via686a_write_value()
343 /* 7 voltage sensors */
348 int nr = attr->index; in in_show()
349 return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); in in_show()
356 int nr = attr->index; in in_min_show()
357 return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); in in_min_show()
364 int nr = attr->index; in in_max_show()
365 return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); in in_max_show()
372 int nr = attr->index; in in_min_store()
380 mutex_lock(&data->update_lock); in in_min_store()
381 data->in_min[nr] = IN_TO_REG(val, nr); in in_min_store()
383 data->in_min[nr]); in in_min_store()
384 mutex_unlock(&data->update_lock); in in_min_store()
391 int nr = attr->index; in in_max_store()
399 mutex_lock(&data->update_lock); in in_max_store()
400 data->in_max[nr] = IN_TO_REG(val, nr); in in_max_store()
402 data->in_max[nr]); in in_max_store()
403 mutex_unlock(&data->update_lock); in in_max_store()
428 int nr = attr->index; in temp_show()
429 return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); in temp_show()
435 int nr = attr->index; in temp_over_show()
436 return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); in temp_over_show()
442 int nr = attr->index; in temp_hyst_show()
443 return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); in temp_hyst_show()
450 int nr = attr->index; in temp_over_store()
458 mutex_lock(&data->update_lock); in temp_over_store()
459 data->temp_over[nr] = TEMP_TO_REG(val); in temp_over_store()
461 data->temp_over[nr]); in temp_over_store()
462 mutex_unlock(&data->update_lock); in temp_over_store()
470 int nr = attr->index; in temp_hyst_store()
478 mutex_lock(&data->update_lock); in temp_hyst_store()
479 data->temp_hyst[nr] = TEMP_TO_REG(val); in temp_hyst_store()
481 data->temp_hyst[nr]); in temp_hyst_store()
482 mutex_unlock(&data->update_lock); in temp_hyst_store()
501 int nr = attr->index; in fan_show()
502 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], in fan_show()
503 DIV_FROM_REG(data->fan_div[nr]))); in fan_show()
509 int nr = attr->index; in fan_min_show()
511 FAN_FROM_REG(data->fan_min[nr], in fan_min_show()
512 DIV_FROM_REG(data->fan_div[nr]))); in fan_min_show()
518 int nr = attr->index; in fan_div_show()
519 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); in fan_div_show()
525 int nr = attr->index; in fan_min_store()
533 mutex_lock(&data->update_lock); in fan_min_store()
534 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); in fan_min_store()
535 via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); in fan_min_store()
536 mutex_unlock(&data->update_lock); in fan_min_store()
543 int nr = attr->index; in fan_div_store()
552 mutex_lock(&data->update_lock); in fan_div_store()
554 data->fan_div[nr] = DIV_TO_REG(val); in fan_div_store()
555 old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); in fan_div_store()
557 mutex_unlock(&data->update_lock); in fan_div_store()
573 return sprintf(buf, "%u\n", data->alarms); in alarms_show()
581 int bitnr = to_sensor_dev_attr(attr)->index; in alarm_show()
583 return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); in alarm_show()
600 return sprintf(buf, "%s\n", data->name); in name_show()
674 if (!devm_request_region(&pdev->dev, res->start, VIA686A_EXTENT, in via686a_probe()
676 dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", in via686a_probe()
677 (unsigned long)res->start, (unsigned long)res->end); in via686a_probe()
678 return -ENODEV; in via686a_probe()
681 data = devm_kzalloc(&pdev->dev, sizeof(struct via686a_data), in via686a_probe()
684 return -ENOMEM; in via686a_probe()
687 data->addr = res->start; in via686a_probe()
688 data->name = "via686a"; in via686a_probe()
689 mutex_init(&data->update_lock); in via686a_probe()
695 err = sysfs_create_group(&pdev->dev.kobj, &via686a_group); in via686a_probe()
699 data->hwmon_dev = hwmon_device_register(&pdev->dev); in via686a_probe()
700 if (IS_ERR(data->hwmon_dev)) { in via686a_probe()
701 err = PTR_ERR(data->hwmon_dev); in via686a_probe()
708 sysfs_remove_group(&pdev->dev.kobj, &via686a_group); in via686a_probe()
716 hwmon_device_unregister(data->hwmon_dev); in via686a_remove()
717 sysfs_remove_group(&pdev->dev.kobj, &via686a_group); in via686a_remove()
725 data->fan_div[0] = (reg >> 4) & 0x03; in via686a_update_fan_div()
726 data->fan_div[1] = reg >> 6; in via686a_update_fan_div()
737 /* Configure temp interrupt mode for continuous-interrupt operation */ in via686a_init_device()
743 /* Pre-read fan clock divisor values */ in via686a_init_device()
752 mutex_lock(&data->update_lock); in via686a_update_device()
754 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) in via686a_update_device()
755 || !data->valid) { in via686a_update_device()
757 data->in[i] = in via686a_update_device()
759 data->in_min[i] = via686a_read_value(data, in via686a_update_device()
762 data->in_max[i] = in via686a_update_device()
766 data->fan[i - 1] = in via686a_update_device()
768 data->fan_min[i - 1] = via686a_read_value(data, in via686a_update_device()
772 data->temp[i] = via686a_read_value(data, in via686a_update_device()
774 data->temp_over[i] = in via686a_update_device()
777 data->temp_hyst[i] = in via686a_update_device()
783 * temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1 in via686a_update_device()
784 * temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 in via686a_update_device()
785 * temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 in via686a_update_device()
787 data->temp[0] |= (via686a_read_value(data, in via686a_update_device()
790 data->temp[1] |= in via686a_update_device()
793 data->temp[2] |= in via686a_update_device()
798 data->alarms = in via686a_update_device()
802 data->last_updated = jiffies; in via686a_update_device()
803 data->valid = 1; in via686a_update_device()
806 mutex_unlock(&data->update_lock); in via686a_update_device()
821 .end = address + VIA686A_EXTENT - 1, in via686a_device_add()
833 err = -ENOMEM; in via686a_device_add()
864 address = force_addr & ~(VIA686A_EXTENT - 1); in via686a_pci_probe()
865 dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address); in via686a_pci_probe()
868 return -ENODEV; in via686a_pci_probe()
872 return -ENODEV; in via686a_pci_probe()
874 address = val & ~(VIA686A_EXTENT - 1); in via686a_pci_probe()
876 dev_err(&dev->dev, in via686a_pci_probe()
877 "base address not set - upgrade BIOS or use force_addr=0xaddr\n"); in via686a_pci_probe()
878 return -ENODEV; in via686a_pci_probe()
883 return -ENODEV; in via686a_pci_probe()
886 dev_warn(&dev->dev, in via686a_pci_probe()
887 "Sensors disabled, enable with force_addr=0x%x\n", in via686a_pci_probe()
889 return -ENODEV; in via686a_pci_probe()
892 dev_warn(&dev->dev, "Enabling sensors\n"); in via686a_pci_probe()
896 return -ENODEV; in via686a_pci_probe()
912 return -ENODEV; in via686a_pci_probe()
917 return -ENODEV; in via686a_pci_probe()