Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: g672: add support for g761

Add support for g761 PWM Fan Controller.

The g761 is a copy of the g763 with the only difference of supporting
and internal clock. The internal clock is used if no clocks property is
defined in device node and in such case the required bit is enabled and
clock handling is skipped.

The internal clock oscillator runs at 31KHz.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Link: https://lore.kernel.org/r/20240604164348.542-3-ansuelsmth@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Christian Marangi and committed by
Guenter Roeck
6ce40232 302fdb16

+30 -3
+30 -3
drivers/hwmon/g762.c
··· 69 69 #define G762_REG_FAN_CMD1_PWM_POLARITY 0x02 /* PWM polarity */ 70 70 #define G762_REG_FAN_CMD1_PULSE_PER_REV 0x01 /* pulse per fan revolution */ 71 71 72 + #define G761_REG_FAN_CMD2_FAN_CLOCK 0x20 /* choose internal clock*/ 72 73 #define G762_REG_FAN_CMD2_GEAR_MODE_1 0x08 /* fan gear mode */ 73 74 #define G762_REG_FAN_CMD2_GEAR_MODE_0 0x04 74 75 #define G762_REG_FAN_CMD2_FAN_STARTV_1 0x02 /* fan startup voltage */ ··· 116 115 117 116 struct g762_data { 118 117 struct i2c_client *client; 118 + bool internal_clock; 119 119 struct clk *clk; 120 120 121 121 /* update mutex */ ··· 568 566 569 567 #ifdef CONFIG_OF 570 568 static const struct of_device_id g762_dt_match[] = { 569 + { .compatible = "gmt,g761" }, 571 570 { .compatible = "gmt,g762" }, 572 571 { .compatible = "gmt,g763" }, 573 572 { }, ··· 600 597 if (!client->dev.of_node) 601 598 return 0; 602 599 600 + data = i2c_get_clientdata(client); 601 + 602 + /* 603 + * Skip CLK detection and handling if we use internal clock. 604 + * This is only valid for g761. 605 + */ 606 + data->internal_clock = of_device_is_compatible(client->dev.of_node, 607 + "gmt,g761") && 608 + !of_property_present(client->dev.of_node, 609 + "clocks"); 610 + if (data->internal_clock) { 611 + do_set_clk_freq(&client->dev, 32768); 612 + return 0; 613 + } 614 + 603 615 clk = of_clk_get(client->dev.of_node, 0); 604 616 if (IS_ERR(clk)) { 605 617 dev_err(&client->dev, "failed to get clock\n"); ··· 634 616 goto clk_unprep; 635 617 } 636 618 637 - data = i2c_get_clientdata(client); 638 619 data->clk = clk; 639 620 640 621 ret = devm_add_action(&client->dev, g762_of_clock_disable, data); ··· 1042 1025 static inline int g762_fan_init(struct device *dev) 1043 1026 { 1044 1027 struct g762_data *data = g762_update_client(dev); 1028 + int ret; 1045 1029 1046 1030 if (IS_ERR(data)) 1047 1031 return PTR_ERR(data); 1032 + 1033 + /* internal_clock can only be set with compatible g761 */ 1034 + if (data->internal_clock) 1035 + data->fan_cmd2 |= G761_REG_FAN_CMD2_FAN_CLOCK; 1048 1036 1049 1037 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL; 1050 1038 data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC; 1051 1039 data->valid = false; 1052 1040 1053 - return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, 1054 - data->fan_cmd1); 1041 + ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1, 1042 + data->fan_cmd1); 1043 + if (ret) 1044 + return ret; 1045 + 1046 + return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2, 1047 + data->fan_cmd2); 1055 1048 } 1056 1049 1057 1050 static int g762_probe(struct i2c_client *client)