summaryrefslogtreecommitdiff
path: root/drivers/hwmon/g762.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/g762.c')
-rw-r--r--drivers/hwmon/g762.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c
index af1228708e25..4fa3aa1271da 100644
--- a/drivers/hwmon/g762.c
+++ b/drivers/hwmon/g762.c
@@ -44,6 +44,7 @@
#define DRVNAME "g762"
static const struct i2c_device_id g762_id[] = {
+ { "g761" },
{ "g762" },
{ "g763" },
{ }
@@ -69,6 +70,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 +117,7 @@ enum g762_regs {
struct g762_data {
struct i2c_client *client;
+ bool internal_clock;
struct clk *clk;
/* update mutex */
@@ -566,6 +569,7 @@ static int do_set_fan_startv(struct device *dev, unsigned long val)
#ifdef CONFIG_OF
static const struct of_device_id g762_dt_match[] = {
+ { .compatible = "gmt,g761" },
{ .compatible = "gmt,g762" },
{ .compatible = "gmt,g763" },
{ },
@@ -597,6 +601,21 @@ static int g762_of_clock_enable(struct i2c_client *client)
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 +635,6 @@ static int g762_of_clock_enable(struct i2c_client *client)
goto clk_unprep;
}
- data = i2c_get_clientdata(client);
data->clk = clk;
ret = devm_add_action(&client->dev, g762_of_clock_disable, data);
@@ -1025,16 +1043,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)
@@ -1056,15 +1084,16 @@ static int g762_probe(struct i2c_client *client)
data->client = client;
mutex_init(&data->update_lock);
- /* Enable fan failure detection and fan out of control protection */
- ret = g762_fan_init(dev);
+ /* Get configuration via DT ... */
+ ret = g762_of_clock_enable(client);
if (ret)
return ret;
- /* Get configuration via DT ... */
- ret = g762_of_clock_enable(client);
+ /* Enable fan failure detection and fan out of control protection */
+ ret = g762_fan_init(dev);
if (ret)
return ret;
+
ret = g762_of_prop_import(client);
if (ret)
return ret;