--- /dev/null
+From 6ce402327a6fb714a9f40a0bb59bcbfe383839a5 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Tue, 4 Jun 2024 18:43:43 +0200
+Subject: [PATCH] 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>
+---
+ drivers/hwmon/g762.c | 33 ++++++++++++++++++++++++++++++---
+ 1 file changed, 30 insertions(+), 3 deletions(-)
+
+--- a/drivers/hwmon/g762.c
++++ b/drivers/hwmon/g762.c
+@@ -69,6 +69,7 @@ enum g762_regs {
+ #define G762_REG_FAN_CMD1_PWM_POLARITY 0x02 /* PWM polarity */
+ #define G762_REG_FAN_CMD1_PULSE_PER_REV 0x01 /* pulse per fan revolution */
+
++#define G761_REG_FAN_CMD2_FAN_CLOCK 0x20 /* choose internal clock*/
+ #define G762_REG_FAN_CMD2_GEAR_MODE_1 0x08 /* fan gear mode */
+ #define G762_REG_FAN_CMD2_GEAR_MODE_0 0x04
+ #define G762_REG_FAN_CMD2_FAN_STARTV_1 0x02 /* fan startup voltage */
+@@ -115,6 +116,7 @@ enum g762_regs {
+
+ struct g762_data {
+ struct i2c_client *client;
++ bool internal_clock;
+ struct clk *clk;
+
+ /* update mutex */
+@@ -566,6 +568,7 @@ static int do_set_fan_startv(struct devi
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id g762_dt_match[] = {
++ { .compatible = "gmt,g761" },
+ { .compatible = "gmt,g762" },
+ { .compatible = "gmt,g763" },
+ { },
+@@ -597,6 +600,21 @@ static int g762_of_clock_enable(struct i
+ if (!client->dev.of_node)
+ return 0;
+
++ data = i2c_get_clientdata(client);
++
++ /*
++ * Skip CLK detection and handling if we use internal clock.
++ * This is only valid for g761.
++ */
++ data->internal_clock = of_device_is_compatible(client->dev.of_node,
++ "gmt,g761") &&
++ !of_property_present(client->dev.of_node,
++ "clocks");
++ if (data->internal_clock) {
++ do_set_clk_freq(&client->dev, 32768);
++ return 0;
++ }
++
+ clk = of_clk_get(client->dev.of_node, 0);
+ if (IS_ERR(clk)) {
+ dev_err(&client->dev, "failed to get clock\n");
+@@ -616,7 +634,6 @@ static int g762_of_clock_enable(struct i
+ goto clk_unprep;
+ }
+
+- data = i2c_get_clientdata(client);
+ data->clk = clk;
+
+ ret = devm_add_action(&client->dev, g762_of_clock_disable, data);
+@@ -1025,16 +1042,26 @@ ATTRIBUTE_GROUPS(g762);
+ static inline int g762_fan_init(struct device *dev)
+ {
+ struct g762_data *data = g762_update_client(dev);
++ int ret;
+
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
++ /* internal_clock can only be set with compatible g761 */
++ if (data->internal_clock)
++ data->fan_cmd2 |= G761_REG_FAN_CMD2_FAN_CLOCK;
++
+ data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL;
+ data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC;
+ data->valid = false;
+
+- return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
+- data->fan_cmd1);
++ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
++ data->fan_cmd1);
++ if (ret)
++ return ret;
++
++ return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2,
++ data->fan_cmd2);
+ }
+
+ static int g762_probe(struct i2c_client *client)