Lines Matching +full:nr +full:- +full:outputs

1 // SPDX-License-Identifier: GPL-2.0-only
3 * pc87427.c - hardware monitoring driver for the
4 * National Semiconductor PC87427 Super-I/O chip
10 * PC87427 - 8 4 6 0xF2
13 * Only fans are fully supported so far. Temperatures are in read-only
25 #include <linux/hwmon-sysfs.h>
79 * Super-I/O registers and operations
104 return -EBUSY; in superio_enter()
133 #define BANK_FM(nr) (nr) argument
134 #define BANK_FT(nr) (0x08 + (nr)) argument
135 #define BANK_FC(nr) (0x10 + (nr) * 2) argument
136 #define BANK_TM(nr) (nr) argument
137 #define BANK_VM(nr) (0x08 + (nr)) argument
146 return inb(data->address[ldi] + reg); in pc87427_read8()
149 /* Must be called with data->lock held, except during init */
153 outb(bank, data->address[ldi] + PC87427_REG_BANK); in pc87427_read8_bank()
154 return inb(data->address[ldi] + reg); in pc87427_read8_bank()
157 /* Must be called with data->lock held, except during init */
161 outb(bank, data->address[ldi] + PC87427_REG_BANK); in pc87427_write8_bank()
162 outb(value, data->address[ldi] + reg); in pc87427_write8_bank()
169 /* fan data registers are 16-bit wide */
181 * Must be called with data->lock held.
182 * nr is from 0 to 7
184 static void pc87427_readall_fan(struct pc87427_data *data, u8 nr) in pc87427_readall_fan() argument
186 int iobase = data->address[LD_FAN]; in pc87427_readall_fan()
188 outb(BANK_FM(nr), iobase + PC87427_REG_BANK); in pc87427_readall_fan()
189 data->fan[nr] = inw(iobase + PC87427_REG_FAN); in pc87427_readall_fan()
190 data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN); in pc87427_readall_fan()
191 data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS); in pc87427_readall_fan()
193 outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS); in pc87427_readall_fan()
236 * Must be called with data->lock held.
237 * nr is from 0 to 3
239 static void pc87427_readall_pwm(struct pc87427_data *data, u8 nr) in pc87427_readall_pwm() argument
241 int iobase = data->address[LD_FAN]; in pc87427_readall_pwm()
243 outb(BANK_FC(nr), iobase + PC87427_REG_BANK); in pc87427_readall_pwm()
244 data->pwm_enable[nr] = inb(iobase + PC87427_REG_PWM_ENABLE); in pc87427_readall_pwm()
245 data->pwm[nr] = inb(iobase + PC87427_REG_PWM_DUTY); in pc87427_readall_pwm()
259 return -EPROTO; in pwm_enable_from_reg()
300 * Must be called with data->lock held.
301 * nr is from 0 to 5
303 static void pc87427_readall_temp(struct pc87427_data *data, u8 nr) in pc87427_readall_temp() argument
305 int iobase = data->address[LD_TEMP]; in pc87427_readall_temp()
307 outb(BANK_TM(nr), iobase + PC87427_REG_BANK); in pc87427_readall_temp()
308 data->temp[nr] = le16_to_cpu(inw(iobase + PC87427_REG_TEMP)); in pc87427_readall_temp()
309 data->temp_max[nr] = inb(iobase + PC87427_REG_TEMP_MAX); in pc87427_readall_temp()
310 data->temp_min[nr] = inb(iobase + PC87427_REG_TEMP_MIN); in pc87427_readall_temp()
311 data->temp_crit[nr] = inb(iobase + PC87427_REG_TEMP_CRIT); in pc87427_readall_temp()
312 data->temp_type[nr] = inb(iobase + PC87427_REG_TEMP_TYPE); in pc87427_readall_temp()
313 data->temp_status[nr] = inb(iobase + PC87427_REG_TEMP_STATUS); in pc87427_readall_temp()
315 outb(data->temp_status[nr], iobase + PC87427_REG_TEMP_STATUS); in pc87427_readall_temp()
332 * We assume 8-bit thermal sensors; 9-bit thermal sensors are possible
354 mutex_lock(&data->lock); in pc87427_update_device()
355 if (!time_after(jiffies, data->last_updated + HZ) in pc87427_update_device()
356 && data->last_updated) in pc87427_update_device()
361 if (!(data->fan_enabled & (1 << i))) in pc87427_update_device()
366 /* PWM outputs */ in pc87427_update_device()
368 if (!(data->pwm_enabled & (1 << i))) in pc87427_update_device()
375 if (!(data->temp_enabled & (1 << i))) in pc87427_update_device()
380 data->last_updated = jiffies; in pc87427_update_device()
383 mutex_unlock(&data->lock); in pc87427_update_device()
391 int nr = to_sensor_dev_attr(devattr)->index; in fan_input_show() local
393 return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr])); in fan_input_show()
400 int nr = to_sensor_dev_attr(devattr)->index; in fan_min_show() local
402 return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr])); in fan_min_show()
409 int nr = to_sensor_dev_attr(devattr)->index; in fan_alarm_show() local
411 return sprintf(buf, "%d\n", !!(data->fan_status[nr] in fan_alarm_show()
419 int nr = to_sensor_dev_attr(devattr)->index; in fan_fault_show() local
421 return sprintf(buf, "%d\n", !!(data->fan_status[nr] in fan_fault_show()
430 int nr = to_sensor_dev_attr(devattr)->index; in fan_min_store() local
432 int iobase = data->address[LD_FAN]; in fan_min_store()
435 return -EINVAL; in fan_min_store()
437 mutex_lock(&data->lock); in fan_min_store()
438 outb(BANK_FM(nr), iobase + PC87427_REG_BANK); in fan_min_store()
440 * The low speed limit registers are read-only while monitoring in fan_min_store()
445 data->fan_min[nr] = fan_to_reg(val); in fan_min_store()
446 outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN); in fan_min_store()
448 mutex_unlock(&data->lock); in fan_min_store()
553 * Must be called with data->lock held and pc87427_readall_pwm() freshly
556 static void update_pwm_enable(struct pc87427_data *data, int nr, u8 mode) in update_pwm_enable() argument
558 int iobase = data->address[LD_FAN]; in update_pwm_enable()
559 data->pwm_enable[nr] &= ~PWM_ENABLE_MODE_MASK; in update_pwm_enable()
560 data->pwm_enable[nr] |= mode; in update_pwm_enable()
561 outb(data->pwm_enable[nr], iobase + PC87427_REG_PWM_ENABLE); in update_pwm_enable()
568 int nr = to_sensor_dev_attr(devattr)->index; in pwm_enable_show() local
571 pwm_enable = pwm_enable_from_reg(data->pwm_enable[nr]); in pwm_enable_show()
582 int nr = to_sensor_dev_attr(devattr)->index; in pwm_enable_store() local
586 return -EINVAL; in pwm_enable_store()
588 if (val == 2 && !(data->pwm_auto_ok & (1 << nr))) in pwm_enable_store()
589 return -EINVAL; in pwm_enable_store()
591 mutex_lock(&data->lock); in pwm_enable_store()
592 pc87427_readall_pwm(data, nr); in pwm_enable_store()
593 update_pwm_enable(data, nr, pwm_enable_to_reg(val, data->pwm[nr])); in pwm_enable_store()
594 mutex_unlock(&data->lock); in pwm_enable_store()
603 int nr = to_sensor_dev_attr(devattr)->index; in pwm_show() local
605 return sprintf(buf, "%d\n", (int)data->pwm[nr]); in pwm_show()
612 int nr = to_sensor_dev_attr(devattr)->index; in pwm_store() local
614 int iobase = data->address[LD_FAN]; in pwm_store()
618 return -EINVAL; in pwm_store()
620 mutex_lock(&data->lock); in pwm_store()
621 pc87427_readall_pwm(data, nr); in pwm_store()
622 mode = data->pwm_enable[nr] & PWM_ENABLE_MODE_MASK; in pwm_store()
626 nr + 1); in pwm_store()
627 mutex_unlock(&data->lock); in pwm_store()
628 return -EPERM; in pwm_store()
634 update_pwm_enable(data, nr, PWM_MODE_OFF); in pwm_store()
636 dev_dbg(dev, "Switching PWM%d from %s to %s\n", nr + 1, in pwm_store()
640 update_pwm_enable(data, nr, PWM_MODE_MANUAL); in pwm_store()
642 dev_dbg(dev, "Switching PWM%d from %s to %s\n", nr + 1, in pwm_store()
646 data->pwm[nr] = val; in pwm_store()
649 mutex_unlock(&data->lock); in pwm_store()
695 int nr = to_sensor_dev_attr(devattr)->index; in temp_input_show() local
697 return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr])); in temp_input_show()
704 int nr = to_sensor_dev_attr(devattr)->index; in temp_min_show() local
706 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_min[nr])); in temp_min_show()
713 int nr = to_sensor_dev_attr(devattr)->index; in temp_max_show() local
715 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_max[nr])); in temp_max_show()
722 int nr = to_sensor_dev_attr(devattr)->index; in temp_crit_show() local
724 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_crit[nr])); in temp_crit_show()
731 int nr = to_sensor_dev_attr(devattr)->index; in temp_type_show() local
733 return sprintf(buf, "%u\n", temp_type_from_reg(data->temp_type[nr])); in temp_type_show()
741 int nr = to_sensor_dev_attr(devattr)->index; in temp_min_alarm_show() local
743 return sprintf(buf, "%d\n", !!(data->temp_status[nr] in temp_min_alarm_show()
752 int nr = to_sensor_dev_attr(devattr)->index; in temp_max_alarm_show() local
754 return sprintf(buf, "%d\n", !!(data->temp_status[nr] in temp_max_alarm_show()
763 int nr = to_sensor_dev_attr(devattr)->index; in temp_crit_alarm_show() local
765 return sprintf(buf, "%d\n", !!(data->temp_status[nr] in temp_crit_alarm_show()
773 int nr = to_sensor_dev_attr(devattr)->index; in temp_fault_show() local
775 return sprintf(buf, "%d\n", !!(data->temp_status[nr] in temp_fault_show()
926 return sprintf(buf, "%s\n", data->name); in name_show()
944 dev_err(&pdev->dev, "Missing resource #%d\n", i); in pc87427_request_regions()
945 return -ENOENT; in pc87427_request_regions()
947 if (!devm_request_region(&pdev->dev, res->start, in pc87427_request_regions()
949 dev_err(&pdev->dev, in pc87427_request_regions()
950 "Failed to request region 0x%lx-0x%lx\n", in pc87427_request_regions()
951 (unsigned long)res->start, in pc87427_request_regions()
952 (unsigned long)res->end); in pc87427_request_regions()
953 return -EBUSY; in pc87427_request_regions()
973 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */ in pc87427_init_device()
978 data->fan_enabled |= (1 << i); in pc87427_init_device()
981 if (!data->fan_enabled) { in pc87427_init_device()
984 if (!(sio_data->has_fanin & (1 << i))) /* Not wired */ in pc87427_init_device()
990 data->fan_enabled = sio_data->has_fanin; in pc87427_init_device()
993 /* Check which PWM outputs are enabled */ in pc87427_init_device()
995 if (!(sio_data->has_fanout & (1 << i))) /* Not wired */ in pc87427_init_device()
1000 data->pwm_enabled |= (1 << i); in pc87427_init_device()
1010 data->pwm_auto_ok |= (1 << i); in pc87427_init_device()
1024 data->temp_enabled |= (1 << i); in pc87427_init_device()
1035 if (!(data->fan_enabled & (1 << i))) in pc87427_remove_files()
1037 sysfs_remove_group(&dev->kobj, &pc87427_group_fan[i]); in pc87427_remove_files()
1040 if (!(data->pwm_enabled & (1 << i))) in pc87427_remove_files()
1042 sysfs_remove_group(&dev->kobj, &pc87427_group_pwm[i]); in pc87427_remove_files()
1045 if (!(data->temp_enabled & (1 << i))) in pc87427_remove_files()
1047 sysfs_remove_group(&dev->kobj, &pc87427_group_temp[i]); in pc87427_remove_files()
1053 struct pc87427_sio_data *sio_data = dev_get_platdata(&pdev->dev); in pc87427_probe()
1057 data = devm_kzalloc(&pdev->dev, sizeof(struct pc87427_data), in pc87427_probe()
1060 return -ENOMEM; in pc87427_probe()
1062 data->address[0] = sio_data->address[0]; in pc87427_probe()
1063 data->address[1] = sio_data->address[1]; in pc87427_probe()
1064 res_count = (data->address[0] != 0) + (data->address[1] != 0); in pc87427_probe()
1070 mutex_init(&data->lock); in pc87427_probe()
1071 data->name = "pc87427"; in pc87427_probe()
1073 pc87427_init_device(&pdev->dev); in pc87427_probe()
1076 err = device_create_file(&pdev->dev, &dev_attr_name); in pc87427_probe()
1080 if (!(data->fan_enabled & (1 << i))) in pc87427_probe()
1082 err = sysfs_create_group(&pdev->dev.kobj, in pc87427_probe()
1088 if (!(data->pwm_enabled & (1 << i))) in pc87427_probe()
1090 err = sysfs_create_group(&pdev->dev.kobj, in pc87427_probe()
1096 if (!(data->temp_enabled & (1 << i))) in pc87427_probe()
1098 err = sysfs_create_group(&pdev->dev.kobj, in pc87427_probe()
1104 data->hwmon_dev = hwmon_device_register(&pdev->dev); in pc87427_probe()
1105 if (IS_ERR(data->hwmon_dev)) { in pc87427_probe()
1106 err = PTR_ERR(data->hwmon_dev); in pc87427_probe()
1107 dev_err(&pdev->dev, "Class registration failed (%d)\n", err); in pc87427_probe()
1114 pc87427_remove_files(&pdev->dev); in pc87427_probe()
1122 hwmon_device_unregister(data->hwmon_dev); in pc87427_remove()
1123 pc87427_remove_files(&pdev->dev); in pc87427_remove()
1147 if (!sio_data->address[i]) in pc87427_device_add()
1149 res[res_count].start = sio_data->address[i]; in pc87427_device_add()
1150 res[res_count].end = sio_data->address[i] + REGION_LENGTH - 1; in pc87427_device_add()
1162 err = -ENOMEM; in pc87427_device_add()
1207 err = -ENODEV; in pc87427_find()
1212 sio_data->address[i] = 0; in pc87427_find()
1225 pr_warn("Logical device 0x%02x is memory-mapped, can't use\n", in pc87427_find()
1237 sio_data->address[i] = val; in pc87427_find()
1241 if (!sio_data->address[0] && !sio_data->address[1]) { in pc87427_find()
1242 err = -ENODEV; in pc87427_find()
1247 sio_data->has_fanin = (1 << 2) | (1 << 3); /* FANIN2, FANIN3 */ in pc87427_find()
1251 sio_data->has_fanin |= (1 << 0); /* FANIN0 */ in pc87427_find()
1253 sio_data->has_fanin |= (1 << 4); /* FANIN4 */ in pc87427_find()
1257 sio_data->has_fanin |= (1 << 1); /* FANIN1 */ in pc87427_find()
1261 sio_data->has_fanin |= (1 << 7); /* FANIN7 */ in pc87427_find()
1264 sio_data->has_fanin |= (1 << 5); /* FANIN5 */ in pc87427_find()
1267 sio_data->has_fanin |= (1 << 6); /* FANIN6 */ in pc87427_find()
1269 /* Check which fan outputs are wired */ in pc87427_find()
1270 sio_data->has_fanout = (1 << 0); /* FANOUT0 */ in pc87427_find()
1272 sio_data->has_fanout |= (1 << 3); /* FANOUT3 */ in pc87427_find()
1277 sio_data->has_fanout |= (1 << 1); /* FANOUT1 */ in pc87427_find()
1279 sio_data->has_fanout |= (1 << 2); /* FANOUT2 */ in pc87427_find()
1285 sio_data->has_fanout |= (1 << 1); /* FANOUT1 */ in pc87427_find()
1287 sio_data->has_fanout |= (1 << 2); /* FANOUT2 */ in pc87427_find()
1301 return -ENODEV; in pc87427_init()