Lines Matching +full:fan +full:- +full:controller
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * g762 - Driver for the Global Mixed-mode Technology Inc. fan speed
4 * PWM controller chips from G762 family, i.e. G762 and G763
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 */
71 #define G762_REG_FAN_CMD1_PULSE_PER_REV 0x01 /* pulse per fan revolution */
73 #define G762_REG_FAN_CMD2_GEAR_MODE_1 0x08 /* fan gear mode */
75 #define G762_REG_FAN_CMD2_FAN_STARTV_1 0x02 /* fan startup voltage */
78 #define G762_REG_FAN_STA_FAIL 0x02 /* fan fail */
79 #define G762_REG_FAN_STA_OOC 0x01 /* fan out of control */
95 * Extract pulse count per fan revolution value (2 or 4) from given
102 * Extract fan clock divisor (1, 2, 4 or 8) from given FAN_CMD1
110 * Extract fan gear mode multiplier value (0, 2 or 4) from given
131 u8 set_cnt; /* controls fan rotation speed in closed-loop mode */
132 u8 act_cnt; /* provides access to current fan RPM value */
133 u8 fan_sta; /* bit 0: set when actual fan speed is more than
134 * 25% outside requested fan speed
135 * bit 1: set when no transition occurs on fan
138 u8 set_out; /* controls fan rotation speed in open-loop mode */
145 * 00: Divide fan clock by 1
146 * 01: Divide fan clock by 2
147 * 10: Divide fan clock by 4
148 * 11: Divide fan clock by 8
149 * 4: FAN_MODE 1:closed-loop, 0:open-loop
151 * 6: DET_FAN_OOC enable "fan ooc" status
152 * 7: DET_FAN_FAIL enable "fan fail" status
154 u8 fan_cmd2; /* 0,1: FAN_STARTV 0,1,2,3 -> 0,32,64,96 dac_code
164 * Convert count value from fan controller register (FAN_SET_CNT) into fan
166 * influence of additional parameters (fan clock divisor, fan gear mode)
172 if (cnt == 0xff) /* setting cnt to 255 stops the fan */ in rpm_from_cnt()
179 * Convert fan RPM value from sysfs into count value for fan controller
188 if (!rpm) /* to stop the fan, set cnt to 255 */ in cnt_from_rpm()
199 struct i2c_client *client = data->client; in g762_update_client()
202 mutex_lock(&data->update_lock); in g762_update_client()
203 if (time_before(jiffies, data->last_updated + G762_UPDATE_INTERVAL) && in g762_update_client()
204 likely(data->valid)) in g762_update_client()
210 data->set_cnt = ret; in g762_update_client()
215 data->act_cnt = ret; in g762_update_client()
220 data->fan_sta = ret; in g762_update_client()
225 data->set_out = ret; in g762_update_client()
230 data->fan_cmd1 = ret; in g762_update_client()
235 data->fan_cmd2 = ret; in g762_update_client()
237 data->last_updated = jiffies; in g762_update_client()
238 data->valid = true; in g762_update_client()
240 mutex_unlock(&data->update_lock); in g762_update_client()
261 return -EINVAL; in do_set_clk_freq()
265 data->clk_freq = val; in do_set_clk_freq()
279 mutex_lock(&data->update_lock); in do_set_pwm_mode()
282 data->fan_cmd1 |= G762_REG_FAN_CMD1_OUT_MODE; in do_set_pwm_mode()
285 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_OUT_MODE; in do_set_pwm_mode()
288 ret = -EINVAL; in do_set_pwm_mode()
291 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_pwm_mode()
292 data->fan_cmd1); in do_set_pwm_mode()
293 data->valid = false; in do_set_pwm_mode()
295 mutex_unlock(&data->update_lock); in do_set_pwm_mode()
300 /* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */
309 mutex_lock(&data->update_lock); in do_set_fan_div()
312 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
313 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
316 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
317 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
320 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
321 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
324 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID0; in do_set_fan_div()
325 data->fan_cmd1 |= G762_REG_FAN_CMD1_CLK_DIV_ID1; in do_set_fan_div()
328 ret = -EINVAL; in do_set_fan_div()
331 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_fan_div()
332 data->fan_cmd1); in do_set_fan_div()
333 data->valid = false; in do_set_fan_div()
335 mutex_unlock(&data->update_lock); in do_set_fan_div()
340 /* Set fan gear mode. Accepts either 0, 1 or 2. */
349 mutex_lock(&data->update_lock); in do_set_fan_gear_mode()
352 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0; in do_set_fan_gear_mode()
353 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1; in do_set_fan_gear_mode()
356 data->fan_cmd2 |= G762_REG_FAN_CMD2_GEAR_MODE_0; in do_set_fan_gear_mode()
357 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1; in do_set_fan_gear_mode()
360 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0; in do_set_fan_gear_mode()
361 data->fan_cmd2 |= G762_REG_FAN_CMD2_GEAR_MODE_1; in do_set_fan_gear_mode()
364 ret = -EINVAL; in do_set_fan_gear_mode()
367 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, in do_set_fan_gear_mode()
368 data->fan_cmd2); in do_set_fan_gear_mode()
369 data->valid = false; in do_set_fan_gear_mode()
371 mutex_unlock(&data->update_lock); in do_set_fan_gear_mode()
376 /* Set number of fan pulses per revolution. Accepts either 2 or 4. */
385 mutex_lock(&data->update_lock); in do_set_fan_pulses()
388 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PULSE_PER_REV; in do_set_fan_pulses()
391 data->fan_cmd1 |= G762_REG_FAN_CMD1_PULSE_PER_REV; in do_set_fan_pulses()
394 ret = -EINVAL; in do_set_fan_pulses()
397 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_fan_pulses()
398 data->fan_cmd1); in do_set_fan_pulses()
399 data->valid = false; in do_set_fan_pulses()
401 mutex_unlock(&data->update_lock); in do_set_fan_pulses()
406 /* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */
415 mutex_lock(&data->update_lock); in do_set_pwm_enable()
418 data->fan_cmd1 |= G762_REG_FAN_CMD1_FAN_MODE; in do_set_pwm_enable()
421 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_FAN_MODE; in do_set_pwm_enable()
424 * unknown reason, fan will not rotate as expected, no matter in do_set_pwm_enable()
427 * value of 254 if it is 255 when switching to open-loop. in do_set_pwm_enable()
429 if (data->set_cnt == 0xff) in do_set_pwm_enable()
430 i2c_smbus_write_byte_data(data->client, in do_set_pwm_enable()
434 ret = -EINVAL; in do_set_pwm_enable()
438 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_pwm_enable()
439 data->fan_cmd1); in do_set_pwm_enable()
440 data->valid = false; in do_set_pwm_enable()
442 mutex_unlock(&data->update_lock); in do_set_pwm_enable()
456 mutex_lock(&data->update_lock); in do_set_pwm_polarity()
459 data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PWM_POLARITY; in do_set_pwm_polarity()
462 data->fan_cmd1 |= G762_REG_FAN_CMD1_PWM_POLARITY; in do_set_pwm_polarity()
465 ret = -EINVAL; in do_set_pwm_polarity()
468 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in do_set_pwm_polarity()
469 data->fan_cmd1); in do_set_pwm_polarity()
470 data->valid = false; in do_set_pwm_polarity()
472 mutex_unlock(&data->update_lock); in do_set_pwm_polarity()
478 * Set pwm value. Accepts values between 0 (stops the fan) and
479 * 255 (full speed). This only makes sense in open-loop mode.
484 struct i2c_client *client = data->client; in do_set_pwm()
488 return -EINVAL; in do_set_pwm()
490 mutex_lock(&data->update_lock); in do_set_pwm()
492 data->valid = false; in do_set_pwm()
493 mutex_unlock(&data->update_lock); in do_set_pwm()
499 * Set fan RPM value. Can be called both in closed and open-loop mode
500 * but effect will only be seen after closed-loop mode is configured.
510 mutex_lock(&data->update_lock); in do_set_fan_target()
511 data->set_cnt = cnt_from_rpm(val, data->clk_freq, in do_set_fan_target()
512 G762_PULSE_FROM_REG(data->fan_cmd1), in do_set_fan_target()
513 G762_CLKDIV_FROM_REG(data->fan_cmd1), in do_set_fan_target()
514 G762_GEARMULT_FROM_REG(data->fan_cmd2)); in do_set_fan_target()
515 ret = i2c_smbus_write_byte_data(data->client, G762_REG_SET_CNT, in do_set_fan_target()
516 data->set_cnt); in do_set_fan_target()
517 data->valid = false; in do_set_fan_target()
518 mutex_unlock(&data->update_lock); in do_set_fan_target()
523 /* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */
532 mutex_lock(&data->update_lock); in do_set_fan_startv()
535 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
536 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
539 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
540 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
543 data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
544 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
547 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_0; in do_set_fan_startv()
548 data->fan_cmd2 |= G762_REG_FAN_CMD2_FAN_STARTV_1; in do_set_fan_startv()
551 ret = -EINVAL; in do_set_fan_startv()
554 ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, in do_set_fan_startv()
555 data->fan_cmd2); in do_set_fan_startv()
556 data->valid = false; in do_set_fan_startv()
558 mutex_unlock(&data->update_lock); in do_set_fan_startv()
587 clk_disable_unprepare(g762->clk); in g762_of_clock_disable()
588 clk_put(g762->clk); in g762_of_clock_disable()
598 if (!client->dev.of_node) in g762_of_clock_enable()
601 clk = of_clk_get(client->dev.of_node, 0); in g762_of_clock_enable()
603 dev_err(&client->dev, "failed to get clock\n"); in g762_of_clock_enable()
609 dev_err(&client->dev, "failed to enable clock\n"); in g762_of_clock_enable()
614 ret = do_set_clk_freq(&client->dev, clk_freq); in g762_of_clock_enable()
616 dev_err(&client->dev, "invalid clock freq %lu\n", clk_freq); in g762_of_clock_enable()
621 data->clk = clk; in g762_of_clock_enable()
623 devm_add_action(&client->dev, g762_of_clock_disable, data); in g762_of_clock_enable()
643 if (of_property_read_u32(client->dev.of_node, pname, &pval)) in g762_of_prop_import_one()
646 dev_dbg(&client->dev, "found %s (%d)\n", pname, pval); in g762_of_prop_import_one()
647 ret = (*psetter)(&client->dev, pval); in g762_of_prop_import_one()
649 dev_err(&client->dev, "unable to set %s (%d)\n", pname, pval); in g762_of_prop_import_one()
658 if (!client->dev.of_node) in g762_of_prop_import()
694 struct g762_platform_data *pdata = dev_get_platdata(&client->dev); in g762_pdata_prop_import()
700 ret = do_set_fan_gear_mode(&client->dev, pdata->fan_gear_mode); in g762_pdata_prop_import()
704 ret = do_set_pwm_polarity(&client->dev, pdata->pwm_polarity); in g762_pdata_prop_import()
708 ret = do_set_fan_startv(&client->dev, pdata->fan_startv); in g762_pdata_prop_import()
712 return do_set_clk_freq(&client->dev, pdata->clk_freq); in g762_pdata_prop_import()
720 * Read function for fan1_input sysfs file. Return current fan RPM value, or
721 * 0 if fan is out of control.
732 mutex_lock(&data->update_lock); in fan1_input_show()
733 /* reverse logic: fan out of control reporting is enabled low */ in fan1_input_show()
734 if (data->fan_sta & G762_REG_FAN_STA_OOC) { in fan1_input_show()
735 rpm = rpm_from_cnt(data->act_cnt, data->clk_freq, in fan1_input_show()
736 G762_PULSE_FROM_REG(data->fan_cmd1), in fan1_input_show()
737 G762_CLKDIV_FROM_REG(data->fan_cmd1), in fan1_input_show()
738 G762_GEARMULT_FROM_REG(data->fan_cmd2)); in fan1_input_show()
740 mutex_unlock(&data->update_lock); in fan1_input_show()
746 * Read and write functions for pwm1_mode sysfs file. Get and set fan speed
758 !!(data->fan_cmd1 & G762_REG_FAN_CMD1_OUT_MODE)); in pwm1_mode_show()
769 return -EINVAL; in pwm1_mode_store()
779 * Read and write functions for fan1_div sysfs file. Get and set fan
780 * controller prescaler value
790 return sprintf(buf, "%d\n", G762_CLKDIV_FROM_REG(data->fan_cmd1)); in fan1_div_show()
800 return -EINVAL; in fan1_div_store()
811 * of tachometer pulses per fan revolution.
821 return sprintf(buf, "%d\n", G762_PULSE_FROM_REG(data->fan_cmd1)); in fan1_pulses_show()
832 return -EINVAL; in fan1_pulses_store()
842 * Read and write functions for pwm1_enable. Get and set fan speed control mode
843 * (i.e. closed or open-loop).
848 * 0 : no fan speed control (i.e. fan at full speed)
849 * 1 : manual fan speed control enabled (use pwm[1-*]) (open-loop)
850 * 2+: automatic fan speed control enabled (use fan[1-*]_target) (closed-loop)
853 * and it is not emulated by g762 driver. -EINVAL is returned in this case.
864 (!!(data->fan_cmd1 & G762_REG_FAN_CMD1_FAN_MODE)) + 1); in pwm1_enable_show()
875 return -EINVAL; in pwm1_enable_store()
886 * (which affects fan speed) in open-loop mode. 0 stops the fan and 255
897 return sprintf(buf, "%d\n", data->set_out); in pwm1_show()
907 return -EINVAL; in pwm1_store()
917 * Read and write function for fan1_target sysfs file. Get/set the fan speed in
918 * closed-loop mode. Speed is given as a RPM value; then the chip will regulate
919 * the fan speed using pulses from fan tachometer.
936 mutex_lock(&data->update_lock); in fan1_target_show()
937 rpm = rpm_from_cnt(data->set_cnt, data->clk_freq, in fan1_target_show()
938 G762_PULSE_FROM_REG(data->fan_cmd1), in fan1_target_show()
939 G762_CLKDIV_FROM_REG(data->fan_cmd1), in fan1_target_show()
940 G762_GEARMULT_FROM_REG(data->fan_cmd2)); in fan1_target_show()
941 mutex_unlock(&data->update_lock); in fan1_target_show()
954 return -EINVAL; in fan1_target_store()
972 return sprintf(buf, "%u\n", !!(data->fan_sta & G762_REG_FAN_STA_FAIL)); in fan1_fault_show()
987 return sprintf(buf, "%u\n", !(data->fan_sta & G762_REG_FAN_STA_OOC)); in fan1_alarm_show()
1017 * Enable both fan failure detection and fan out of control protection. The
1028 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL; in g762_fan_init()
1029 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC; in g762_fan_init()
1030 data->valid = false; in g762_fan_init()
1032 return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, in g762_fan_init()
1033 data->fan_cmd1); in g762_fan_init()
1038 struct device *dev = &client->dev; in g762_probe()
1043 if (!i2c_check_functionality(client->adapter, in g762_probe()
1045 return -ENODEV; in g762_probe()
1049 return -ENOMEM; in g762_probe()
1052 data->client = client; in g762_probe()
1053 mutex_init(&data->update_lock); in g762_probe()
1055 /* Enable fan failure detection and fan out of control protection */ in g762_probe()
1072 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, in g762_probe()