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

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * g762 - Driver for the Global Mixed-mode Technology Inc. fan speed
15 * http://natisbad.org/NAS/refs/GMT_EDS-762_763-080710-0.2.pdf
27 * http://www.gmt.com.tw/product/datasheet/EDS-762_3.pdf
36 #include <linux/hwmon-sysfs.h>
67 #define G762_REG_FAN_CMD1_FAN_MODE 0x10 /* fan mode: closed/open-loop */
133 u8 set_cnt; /* controls fan rotation speed in closed-loop mode */
140 u8 set_out; /* controls fan rotation speed in open-loop mode */
151 * 4: FAN_MODE 1:closed-loop, 0:open-loop
156 u8 fan_cmd2; /* 0,1: FAN_STARTV 0,1,2,3 -> 0,32,64,96 dac_code
201 struct i2c_client *client = data->client; in g762_update_client()
204 mutex_lock(&data->update_lock); in g762_update_client()
205 if (time_before(jiffies, data->last_updated + G762_UPDATE_INTERVAL) && in g762_update_client()
206 likely(data->valid)) in g762_update_client()
212 data->set_cnt = ret; in g762_update_client()
217 data->act_cnt = ret; in g762_update_client()
222 data->fan_sta = ret; in g762_update_client()
227 data->set_out = ret; in g762_update_client()
232 data->fan_cmd1 = ret; in g762_update_client()
237 data->fan_cmd2 = ret; in g762_update_client()
239 data->last_updated = jiffies; in g762_update_client()
240 data->valid = true; in g762_update_client()
242 mutex_unlock(&data->update_lock); in g762_update_client()
263 return -EINVAL; in do_set_clk_freq()
267 data->clk_freq = val; in do_set_clk_freq()
281 mutex_lock(&data->update_lock); in do_set_pwm_mode()
284 data->fan_cmd1 |= G762_REG_FAN_CMD1_OUT_MODE; in do_set_pwm_mode()
287 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_OUT_MODE; in do_set_pwm_mode()
290 ret = -EINVAL; in do_set_pwm_mode()
293 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_pwm_mode()
294 data->fan_cmd1); in do_set_pwm_mode()
295 data->valid = false; in do_set_pwm_mode()
297 mutex_unlock(&data->update_lock); in do_set_pwm_mode()
311 mutex_lock(&data->update_lock); in do_set_fan_div()
314 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
315 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
318 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
319 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
322 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
323 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
326 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
327 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
330 ret = -EINVAL; in do_set_fan_div()
333 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_fan_div()
334 data->fan_cmd1); in do_set_fan_div()
335 data->valid = false; in do_set_fan_div()
337 mutex_unlock(&data->update_lock); in do_set_fan_div()
351 mutex_lock(&data->update_lock); in do_set_fan_gear_mode()
354 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0; in do_set_fan_gear_mode()
355 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1; in do_set_fan_gear_mode()
358 data->fan_cmd2 |= G762_REG_FAN_CMD2_GEAR_MODE_0; in do_set_fan_gear_mode()
359 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1; in do_set_fan_gear_mode()
362 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0; in do_set_fan_gear_mode()
363 data->fan_cmd2 |= G762_REG_FAN_CMD2_GEAR_MODE_1; in do_set_fan_gear_mode()
366 ret = -EINVAL; in do_set_fan_gear_mode()
369 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, in do_set_fan_gear_mode()
370 data->fan_cmd2); in do_set_fan_gear_mode()
371 data->valid = false; in do_set_fan_gear_mode()
373 mutex_unlock(&data->update_lock); in do_set_fan_gear_mode()
387 mutex_lock(&data->update_lock); in do_set_fan_pulses()
390 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PULSE_PER_REV; in do_set_fan_pulses()
393 data->fan_cmd1 |= G762_REG_FAN_CMD1_PULSE_PER_REV; in do_set_fan_pulses()
396 ret = -EINVAL; in do_set_fan_pulses()
399 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_fan_pulses()
400 data->fan_cmd1); in do_set_fan_pulses()
401 data->valid = false; in do_set_fan_pulses()
403 mutex_unlock(&data->update_lock); in do_set_fan_pulses()
408 /* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */
417 mutex_lock(&data->update_lock); in do_set_pwm_enable()
420 data->fan_cmd1 |= G762_REG_FAN_CMD1_FAN_MODE; in do_set_pwm_enable()
423 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_FAN_MODE; in do_set_pwm_enable()
429 * value of 254 if it is 255 when switching to open-loop. in do_set_pwm_enable()
431 if (data->set_cnt == 0xff) in do_set_pwm_enable()
432 i2c_smbus_write_byte_data(data->client, in do_set_pwm_enable()
436 ret = -EINVAL; in do_set_pwm_enable()
440 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_pwm_enable()
441 data->fan_cmd1); in do_set_pwm_enable()
442 data->valid = false; in do_set_pwm_enable()
444 mutex_unlock(&data->update_lock); in do_set_pwm_enable()
458 mutex_lock(&data->update_lock); in do_set_pwm_polarity()
461 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PWM_POLARITY; in do_set_pwm_polarity()
464 data->fan_cmd1 |= G762_REG_FAN_CMD1_PWM_POLARITY; in do_set_pwm_polarity()
467 ret = -EINVAL; in do_set_pwm_polarity()
470 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_pwm_polarity()
471 data->fan_cmd1); in do_set_pwm_polarity()
472 data->valid = false; in do_set_pwm_polarity()
474 mutex_unlock(&data->update_lock); in do_set_pwm_polarity()
481 * 255 (full speed). This only makes sense in open-loop mode.
486 struct i2c_client *client = data->client; in do_set_pwm()
490 return -EINVAL; in do_set_pwm()
492 mutex_lock(&data->update_lock); in do_set_pwm()
494 data->valid = false; in do_set_pwm()
495 mutex_unlock(&data->update_lock); in do_set_pwm()
501 * Set fan RPM value. Can be called both in closed and open-loop mode
502 * but effect will only be seen after closed-loop mode is configured.
512 mutex_lock(&data->update_lock); in do_set_fan_target()
513 data->set_cnt = cnt_from_rpm(val, data->clk_freq, in do_set_fan_target()
514 G762_PULSE_FROM_REG(data->fan_cmd1), in do_set_fan_target()
515 G762_CLKDIV_FROM_REG(data->fan_cmd1), in do_set_fan_target()
516 G762_GEARMULT_FROM_REG(data->fan_cmd2)); in do_set_fan_target()
517 ret = i2c_smbus_write_byte_data(data->client, G762_REG_SET_CNT, in do_set_fan_target()
518 data->set_cnt); in do_set_fan_target()
519 data->valid = false; in do_set_fan_target()
520 mutex_unlock(&data->update_lock); in do_set_fan_target()
534 mutex_lock(&data->update_lock); in do_set_fan_startv()
537 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
538 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
541 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
542 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
545 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
546 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
549 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
550 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
553 ret = -EINVAL; in do_set_fan_startv()
556 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, in do_set_fan_startv()
557 data->fan_cmd2); in do_set_fan_startv()
558 data->valid = false; in do_set_fan_startv()
560 mutex_unlock(&data->update_lock); in do_set_fan_startv()
590 clk_disable_unprepare(g762->clk); in g762_of_clock_disable()
591 clk_put(g762->clk); in g762_of_clock_disable()
601 if (!client->dev.of_node) in g762_of_clock_enable()
610 data->internal_clock = of_device_is_compatible(client->dev.of_node, in g762_of_clock_enable()
612 !of_property_present(client->dev.of_node, in g762_of_clock_enable()
614 if (data->internal_clock) { in g762_of_clock_enable()
615 do_set_clk_freq(&client->dev, 32768); in g762_of_clock_enable()
619 clk = of_clk_get(client->dev.of_node, 0); in g762_of_clock_enable()
621 dev_err(&client->dev, "failed to get clock\n"); in g762_of_clock_enable()
627 dev_err(&client->dev, "failed to enable clock\n"); in g762_of_clock_enable()
632 ret = do_set_clk_freq(&client->dev, clk_freq); in g762_of_clock_enable()
634 dev_err(&client->dev, "invalid clock freq %lu\n", clk_freq); in g762_of_clock_enable()
638 data->clk = clk; in g762_of_clock_enable()
640 ret = devm_add_action(&client->dev, g762_of_clock_disable, data); in g762_of_clock_enable()
642 dev_err(&client->dev, "failed to add disable clock action\n"); in g762_of_clock_enable()
665 if (of_property_read_u32(client->dev.of_node, pname, &pval)) in g762_of_prop_import_one()
668 dev_dbg(&client->dev, "found %s (%d)\n", pname, pval); in g762_of_prop_import_one()
669 ret = (*psetter)(&client->dev, pval); in g762_of_prop_import_one()
671 dev_err(&client->dev, "unable to set %s (%d)\n", pname, pval); in g762_of_prop_import_one()
680 if (!client->dev.of_node) in g762_of_prop_import()
716 struct g762_platform_data *pdata = dev_get_platdata(&client->dev); in g762_pdata_prop_import()
722 ret = do_set_fan_gear_mode(&client->dev, pdata->fan_gear_mode); in g762_pdata_prop_import()
726 ret = do_set_pwm_polarity(&client->dev, pdata->pwm_polarity); in g762_pdata_prop_import()
730 ret = do_set_fan_startv(&client->dev, pdata->fan_startv); in g762_pdata_prop_import()
734 return do_set_clk_freq(&client->dev, pdata->clk_freq); in g762_pdata_prop_import()
754 mutex_lock(&data->update_lock); in fan1_input_show()
756 if (data->fan_sta & G762_REG_FAN_STA_OOC) { in fan1_input_show()
757 rpm = rpm_from_cnt(data->act_cnt, data->clk_freq, in fan1_input_show()
758 G762_PULSE_FROM_REG(data->fan_cmd1), in fan1_input_show()
759 G762_CLKDIV_FROM_REG(data->fan_cmd1), in fan1_input_show()
760 G762_GEARMULT_FROM_REG(data->fan_cmd2)); in fan1_input_show()
762 mutex_unlock(&data->update_lock); in fan1_input_show()
780 !!(data->fan_cmd1 & G762_REG_FAN_CMD1_OUT_MODE)); in pwm1_mode_show()
791 return -EINVAL; in pwm1_mode_store()
812 return sprintf(buf, "%d\n", G762_CLKDIV_FROM_REG(data->fan_cmd1)); in fan1_div_show()
822 return -EINVAL; in fan1_div_store()
843 return sprintf(buf, "%d\n", G762_PULSE_FROM_REG(data->fan_cmd1)); in fan1_pulses_show()
854 return -EINVAL; in fan1_pulses_store()
865 * (i.e. closed or open-loop).
871 * 1 : manual fan speed control enabled (use pwm[1-*]) (open-loop)
872 * 2+: automatic fan speed control enabled (use fan[1-*]_target) (closed-loop)
875 * and it is not emulated by g762 driver. -EINVAL is returned in this case.
886 (!!(data->fan_cmd1 & G762_REG_FAN_CMD1_FAN_MODE)) + 1); in pwm1_enable_show()
897 return -EINVAL; in pwm1_enable_store()
908 * (which affects fan speed) in open-loop mode. 0 stops the fan and 255
919 return sprintf(buf, "%d\n", data->set_out); in pwm1_show()
929 return -EINVAL; in pwm1_store()
940 * closed-loop mode. Speed is given as a RPM value; then the chip will regulate
958 mutex_lock(&data->update_lock); in fan1_target_show()
959 rpm = rpm_from_cnt(data->set_cnt, data->clk_freq, in fan1_target_show()
960 G762_PULSE_FROM_REG(data->fan_cmd1), in fan1_target_show()
961 G762_CLKDIV_FROM_REG(data->fan_cmd1), in fan1_target_show()
962 G762_GEARMULT_FROM_REG(data->fan_cmd2)); in fan1_target_show()
963 mutex_unlock(&data->update_lock); in fan1_target_show()
976 return -EINVAL; in fan1_target_store()
994 return sprintf(buf, "%u\n", !!(data->fan_sta & G762_REG_FAN_STA_FAIL)); in fan1_fault_show()
1009 return sprintf(buf, "%u\n", !(data->fan_sta & G762_REG_FAN_STA_OOC)); in fan1_alarm_show()
1052 if (data->internal_clock) in g762_fan_init()
1053 data->fan_cmd2 |= G761_REG_FAN_CMD2_FAN_CLOCK; in g762_fan_init()
1055 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL; in g762_fan_init()
1056 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC; in g762_fan_init()
1057 data->valid = false; in g762_fan_init()
1059 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in g762_fan_init()
1060 data->fan_cmd1); in g762_fan_init()
1064 return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, in g762_fan_init()
1065 data->fan_cmd2); in g762_fan_init()
1070 struct device *dev = &client->dev; in g762_probe()
1075 if (!i2c_check_functionality(client->adapter, in g762_probe()
1077 return -ENODEV; in g762_probe()
1081 return -ENOMEM; in g762_probe()
1084 data->client = client; in g762_probe()
1085 mutex_init(&data->update_lock); in g762_probe()
1105 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, in g762_probe()