158 lines
4.8 KiB
Diff
158 lines
4.8 KiB
Diff
From eca0f7949ff41c8dea336792e91d5863b4ed59af Mon Sep 17 00:00:00 2001
|
|
From: yangwei1 <yangwei1@eswincomputing.com>
|
|
Date: Fri, 24 May 2024 19:55:33 +0800
|
|
Subject: [PATCH 033/219] fix:modify fan control and read fan speed
|
|
|
|
Changelogs:
|
|
eswin,pwm_inverted enable pwm invert
|
|
---
|
|
arch/riscv/boot/dts/eswin/eic7700-evb-a2.dts | 1 +
|
|
.../dts/eswin/eswin-win2030-die0-soc.dtsi | 2 +-
|
|
drivers/hwmon/eswin-fan-control.c | 42 ++++++++++++++-----
|
|
3 files changed, 33 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/arch/riscv/boot/dts/eswin/eic7700-evb-a2.dts b/arch/riscv/boot/dts/eswin/eic7700-evb-a2.dts
|
|
index 93fa224c75b7..922db5ee1d4c 100644
|
|
--- a/arch/riscv/boot/dts/eswin/eic7700-evb-a2.dts
|
|
+++ b/arch/riscv/boot/dts/eswin/eic7700-evb-a2.dts
|
|
@@ -688,6 +688,7 @@ &d0_mbox7 {
|
|
|
|
&fan_control {
|
|
status = "okay";
|
|
+ eswin,pwm_inverted;
|
|
};
|
|
|
|
&d0_i2c0 {
|
|
diff --git a/arch/riscv/boot/dts/eswin/eswin-win2030-die0-soc.dtsi b/arch/riscv/boot/dts/eswin/eswin-win2030-die0-soc.dtsi
|
|
index 430c5410bdda..0371d532d2ec 100644
|
|
--- a/arch/riscv/boot/dts/eswin/eswin-win2030-die0-soc.dtsi
|
|
+++ b/arch/riscv/boot/dts/eswin/eswin-win2030-die0-soc.dtsi
|
|
@@ -1289,7 +1289,7 @@ fan_control: fan_control@50b50000 {
|
|
interrupt-parent = <&plic0>;
|
|
interrupt-names = "fanirq";
|
|
interrupts = <354>;
|
|
- pulses-per-revolution = <1>;
|
|
+ pulses-per-revolution = <2>;
|
|
pwm-minimun-period = <1000>;
|
|
pwms = <&pwm0 0 100000>;
|
|
pinctrl-names = "default";
|
|
diff --git a/drivers/hwmon/eswin-fan-control.c b/drivers/hwmon/eswin-fan-control.c
|
|
index 9c8ab39dee30..f7ca5c29520b 100644
|
|
--- a/drivers/hwmon/eswin-fan-control.c
|
|
+++ b/drivers/hwmon/eswin-fan-control.c
|
|
@@ -62,6 +62,7 @@ struct eswin_fan_control_data {
|
|
u32 ppr;
|
|
/* revolutions per minute */
|
|
u32 rpm;
|
|
+ u8 pwm_inverted;
|
|
};
|
|
|
|
static inline void fan_iowrite(const u32 val, const u32 reg,
|
|
@@ -81,9 +82,14 @@ static ssize_t eswin_fan_pwm_ctl_show(struct device *dev, struct device_attribut
|
|
struct eswin_fan_control_data *ctl = dev_get_drvdata(dev);
|
|
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
|
long temp = 0;
|
|
-
|
|
+ long period = 0;
|
|
if (FAN_PWM_DUTY == attr->index) {
|
|
temp = pwm_get_duty_cycle(ctl->pwm);
|
|
+ if(1 == ctl->pwm_inverted)
|
|
+ {
|
|
+ period = pwm_get_period(ctl->pwm);
|
|
+ temp = period- temp;
|
|
+ }
|
|
}
|
|
else if (FAN_PWM_PERIOD == attr->index) {
|
|
temp = pwm_get_period(ctl->pwm);
|
|
@@ -110,8 +116,14 @@ static ssize_t eswin_fan_pwm_ctl_store(struct device *dev, struct device_attribu
|
|
ret = kstrtoul(buf, 10, &val);
|
|
if (ret)
|
|
return ret;
|
|
-
|
|
- state.duty_cycle = val;
|
|
+ if(1 == ctl->pwm_inverted)
|
|
+ {
|
|
+ state.duty_cycle = state.period - val;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ state.duty_cycle = val;
|
|
+ }
|
|
}
|
|
else if (FAN_PWM_PERIOD == attr->index) {
|
|
long val = 0;
|
|
@@ -168,9 +180,7 @@ static long eswin_fan_control_get_fan_rpm(struct eswin_fan_control_data *ctl)
|
|
|
|
ctl->wait_flag = false;
|
|
period = pwm_get_period(ctl->pwm);
|
|
- timeout = TIMEOUT(period);
|
|
- if(!timeout)
|
|
- timeout = TIMEOUT(ctl->min_period);
|
|
+ timeout = msecs_to_jiffies(1500);
|
|
|
|
val = fan_ioread(REG_FAN_INT, ctl);
|
|
val = val | 0x1;
|
|
@@ -185,7 +195,6 @@ static long eswin_fan_control_get_fan_rpm(struct eswin_fan_control_data *ctl)
|
|
/* timeout, set rpm to 0 */
|
|
ctl->rpm = 0;
|
|
}
|
|
-
|
|
if(ctl->rpm)
|
|
ctl->rpm = DIV_ROUND_CLOSEST(60 * ctl->clk_rate, ctl->ppr * ctl->rpm);
|
|
|
|
@@ -215,6 +224,10 @@ static int eswin_fan_control_read_pwm(struct device *dev, u32 attr, long *val)
|
|
switch (attr) {
|
|
case hwmon_pwm_input:
|
|
*val = eswin_fan_control_get_pwm_duty(ctl);
|
|
+ if(1 == ctl->pwm_inverted)
|
|
+ {
|
|
+ *val = 100 - *val;
|
|
+ }
|
|
return 0;
|
|
default:
|
|
return -ENOTSUPP;
|
|
@@ -235,13 +248,21 @@ static int eswin_fan_control_set_pwm_duty(const long val, struct eswin_fan_contr
|
|
static int eswin_fan_control_write_pwm(struct device *dev, u32 attr, long val)
|
|
{
|
|
struct eswin_fan_control_data *ctl = dev_get_drvdata(dev);
|
|
-
|
|
switch (attr) {
|
|
case hwmon_pwm_input:
|
|
- if((val < 0)||(val > 100))
|
|
+ if((val < 10) || (val > 99))
|
|
+ {
|
|
+ dev_err(dev,"pwm range is form 10 to 99\n");
|
|
return -EINVAL;
|
|
+ }
|
|
else
|
|
+ {
|
|
+ if(1 == ctl->pwm_inverted)
|
|
+ {
|
|
+ val = 100 - val;
|
|
+ }
|
|
return eswin_fan_control_set_pwm_duty(val, ctl);
|
|
+ }
|
|
default:
|
|
return -ENOTSUPP;
|
|
}
|
|
@@ -413,7 +434,6 @@ MODULE_DEVICE_TABLE(of, eswin_fan_control_of_match);
|
|
static int eswin_fan_control_probe(struct platform_device *pdev)
|
|
{
|
|
struct eswin_fan_control_data *ctl;
|
|
- struct clk *clk;
|
|
const struct of_device_id *id;
|
|
const char *name = "eswin_fan_control";
|
|
struct pwm_state state;
|
|
@@ -455,7 +475,7 @@ static int eswin_fan_control_probe(struct platform_device *pdev)
|
|
}
|
|
ret = reset_control_reset(ctl->fan_rst);
|
|
WARN_ON(0 != ret);
|
|
-
|
|
+ ctl->pwm_inverted = of_property_read_bool(pdev->dev.of_node, "eswin,pwm_inverted");
|
|
init_waitqueue_head(&ctl->wq);
|
|
|
|
ctl->irq = platform_get_irq(pdev, 0);
|
|
--
|
|
2.47.0
|
|
|