Lines Matching +full:closed +full:- +full:loop

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * max6650.c - Part of lm_sensors, Linux kernel modules for hardware
18 * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
27 #include <linux/hwmon-sysfs.h>
91 /* Minimum and maximum values of the FAN-RPM */
143 * Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. in dac_to_pwm()
146 return clamp_val(255 - (255 * dac) / DAC_LIMIT(v12), 0, 255); in dac_to_pwm()
153 return limit - (limit * pwm) / 255; in pwm_to_dac()
159 struct i2c_client *client = data->client; in max6650_update_device()
163 mutex_lock(&data->update_lock); in max6650_update_device()
165 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { in max6650_update_device()
166 for (i = 0; i < data->nr_fans; i++) { in max6650_update_device()
172 data->tach[i] = reg; in max6650_update_device()
185 data->alarm |= reg; in max6650_update_device()
186 data->last_updated = jiffies; in max6650_update_device()
187 data->valid = true; in max6650_update_device()
191 mutex_unlock(&data->update_lock); in max6650_update_device()
204 u8 config = data->config; in max6650_set_operating_mode()
211 result = i2c_smbus_write_byte_data(data->client, MAX6650_REG_CONFIG, in max6650_set_operating_mode()
216 data->config = config; in max6650_set_operating_mode()
223 * This works in closed loop mode only. Use pwm1 for open loop speed setting.
225 * The MAX6650/1 will automatically control fan speed when in closed loop
275 * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 in max6650_set_target()
278 kscale = DIV_FROM_REG(data->config); in max6650_set_target()
279 ktach = ((clock * kscale) / (256 * rpm / 60)) - 1; in max6650_set_target()
284 data->speed = ktach; in max6650_set_target()
286 return i2c_smbus_write_byte_data(data->client, MAX6650_REG_SPEED, in max6650_set_target()
287 data->speed); in max6650_set_target()
307 alarm = data->alarm & attr->index; in alarm_show()
309 mutex_lock(&data->update_lock); in alarm_show()
310 data->alarm &= ~attr->index; in alarm_show()
311 data->valid = false; in alarm_show()
312 mutex_unlock(&data->update_lock); in alarm_show()
335 if (!(data->alarm_en & to_sensor_dev_attr(devattr)->index)) in max6650_attrs_visible()
339 return a->mode; in max6650_attrs_visible()
361 struct device *dev = &client->dev; in max6650_init_client()
368 if (of_property_read_u32(dev->of_node, "maxim,fan-microvolt", in max6650_init_client()
373 if (of_property_read_u32(dev->of_node, "maxim,fan-prescale", in max6650_init_client()
431 data->config = reg; in max6650_init_client()
438 data->speed = reg; in max6650_init_client()
445 data->dac = reg; in max6650_init_client()
452 data->count = reg; in max6650_init_client()
459 data->alarm_en = reg; in max6650_init_client()
461 if (!of_property_read_u32(client->dev.of_node, "maxim,fan-target-rpm", in max6650_init_client()
481 struct max6650_data *data = cdev->devdata; in max6650_get_cur_state()
483 *state = data->cooling_dev_state; in max6650_get_cur_state()
491 struct max6650_data *data = cdev->devdata; in max6650_set_cur_state()
492 struct i2c_client *client = data->client; in max6650_set_cur_state()
497 mutex_lock(&data->update_lock); in max6650_set_cur_state()
499 data->dac = pwm_to_dac(state, data->config & MAX6650_CFG_V12); in max6650_set_cur_state()
500 err = i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac); in max6650_set_cur_state()
505 data->cooling_dev_state = state; in max6650_set_cur_state()
508 mutex_unlock(&data->update_lock); in max6650_set_cur_state()
532 *val = dac_to_pwm(data->dac, in max6650_read()
533 data->config & MAX6650_CFG_V12); in max6650_read()
539 * 1 = Open loop, Voltage is set according to speed, in max6650_read()
541 * 2 = Closed loop, RPM for all fans regulated by fan1 in max6650_read()
545 mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4; in max6650_read()
546 *val = (4 - mode) & 3; /* {0 1 2 3} -> {0 3 2 1} */ in max6650_read()
549 return -EOPNOTSUPP; in max6650_read()
563 *val = DIV_ROUND_CLOSEST(data->tach[channel] * 120, in max6650_read()
564 DIV_FROM_REG(data->count)); in max6650_read()
567 *val = DIV_FROM_REG(data->count); in max6650_read()
575 *val = 60 * DIV_FROM_REG(data->config) * clock / in max6650_read()
576 (256 * (data->speed + 1)); in max6650_read()
579 *val = !!(data->alarm & MAX6650_ALRM_MIN); in max6650_read()
580 data->alarm &= ~MAX6650_ALRM_MIN; in max6650_read()
581 data->valid = false; in max6650_read()
584 *val = !!(data->alarm & MAX6650_ALRM_MAX); in max6650_read()
585 data->alarm &= ~MAX6650_ALRM_MAX; in max6650_read()
586 data->valid = false; in max6650_read()
589 *val = !!(data->alarm & MAX6650_ALRM_TACH); in max6650_read()
590 data->alarm &= ~MAX6650_ALRM_TACH; in max6650_read()
591 data->valid = false; in max6650_read()
594 return -EOPNOTSUPP; in max6650_read()
598 return -EOPNOTSUPP; in max6650_read()
617 mutex_lock(&data->update_lock); in max6650_write()
624 data->config & MAX6650_CFG_V12); in max6650_write()
625 ret = i2c_smbus_write_byte_data(data->client, in max6650_write()
629 data->dac = reg; in max6650_write()
633 ret = -EINVAL; in max6650_write()
640 ret = -EOPNOTSUPP; in max6650_write()
661 ret = -EINVAL; in max6650_write()
664 ret = i2c_smbus_write_byte_data(data->client, in max6650_write()
668 data->count = reg; in max6650_write()
672 ret = -EINVAL; in max6650_write()
678 ret = -EOPNOTSUPP; in max6650_write()
683 ret = -EOPNOTSUPP; in max6650_write()
688 mutex_unlock(&data->update_lock); in max6650_write()
698 if (channel && (channel >= data->nr_fans || type != hwmon_fan)) in max6650_is_visible()
710 if (data->alarm_en & MAX6650_ALRM_MIN) in max6650_is_visible()
714 if (data->alarm_en & MAX6650_ALRM_MAX) in max6650_is_visible()
718 if (data->alarm_en & MAX6650_ALRM_TACH) in max6650_is_visible()
765 struct device *dev = &client->dev; in max6650_probe()
772 return -ENOMEM; in max6650_probe()
774 data->client = client; in max6650_probe()
776 mutex_init(&data->update_lock); in max6650_probe()
778 data->nr_fans = (uintptr_t)i2c_get_match_data(client); in max6650_probe()
788 client->name, data, in max6650_probe()
797 dev->of_node, client->name, in max6650_probe()