mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 17:48:58 +00:00
107 lines
3.3 KiB
Diff
107 lines
3.3 KiB
Diff
|
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)
|