[openwrt/openwrt] apm821xx: WNDR4700: use upstream tc654 cooling devices

LEDE Commits lede-commits at lists.infradead.org
Sat Feb 19 11:15:36 PST 2022


chunkeey pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/b0d5939b80008aca8090832eb9918b998f08e8f3

commit b0d5939b80008aca8090832eb9918b998f08e8f3
Author: Christian Lamparter <chunkeey at gmail.com>
AuthorDate: Sat Feb 12 19:53:37 2022 +0100

    apm821xx: WNDR4700: use upstream tc654 cooling devices
    
    Upstream hwmon-maintainer had various comments about
    the changes to the tc654 driver. These have been
    addressed and the cooling device support is destined
    for inclusion.
    
    One of the comments was the change of the cooling states
    scaling. No longer the driver uses the same values as the
    hwmon interface, instead the states are now the 17 states
    the tc654 supports.
    
    Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
---
 .../base-files/etc/init.d/hwmon_fancontrol         |  15 +++
 target/linux/apm821xx/dts/netgear-wndr4700.dts     |  12 +-
 ...04-hwmon-tc654-add-thermal_cooling-device.patch | 150 ++++++++++-----------
 3 files changed, 92 insertions(+), 85 deletions(-)

diff --git a/target/linux/apm821xx/base-files/etc/init.d/hwmon_fancontrol b/target/linux/apm821xx/base-files/etc/init.d/hwmon_fancontrol
new file mode 100644
index 0000000000..d38964e015
--- /dev/null
+++ b/target/linux/apm821xx/base-files/etc/init.d/hwmon_fancontrol
@@ -0,0 +1,15 @@
+#!/bin/sh /etc/rc.common
+
+START=98
+
+boot() {
+	# configuring onboard temp/fan controller to run the fan on its own
+	# for more information, please read https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
+
+	case $(board_name) in
+	netgear,wndr4700)
+		path_to_hwmon='/sys/devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-001b/hwmon/hwmon1'
+		echo 1 > "$path_to_hwmon/pwm1_enable"
+		;;
+	esac
+}
diff --git a/target/linux/apm821xx/dts/netgear-wndr4700.dts b/target/linux/apm821xx/dts/netgear-wndr4700.dts
index 12d9dc0bfd..fe0f713943 100644
--- a/target/linux/apm821xx/dts/netgear-wndr4700.dts
+++ b/target/linux/apm821xx/dts/netgear-wndr4700.dts
@@ -105,32 +105,32 @@
 
 				map1 {
 					trip = <&cpu_alert1>;
-					cooling-device = <&fan0 1 76>;
+					cooling-device = <&fan0 1 1>;
 				};
 
 				map2 {
 					trip = <&cpu_alert2>;
-					cooling-device = <&fan0 77 101>;
+					cooling-device = <&fan0 2 4>;
 				};
 
 				map3 {
 					trip = <&cpu_alert3>;
-					cooling-device = <&fan0 102 147>;
+					cooling-device = <&fan0 4 8>;
 				};
 
 				map4 {
 					trip = <&cpu_alert4>;
-					cooling-device = <&fan0 148 207>;
+					cooling-device = <&fan0 9 12>;
 				};
 
 				map5 {
 					trip = <&cpu_alert5>;
-					cooling-device = <&fan0 208 231>;
+					cooling-device = <&fan0 13 15>;
 				};
 
 				map6 {
 					trip = <&cpu_alert6>;
-					cooling-device =<&fan0 232 THERMAL_NO_LIMIT>;
+					cooling-device =<&fan0 16 THERMAL_NO_LIMIT>;
 				};
 			};
 		};
diff --git a/target/linux/apm821xx/patches-5.10/804-hwmon-tc654-add-thermal_cooling-device.patch b/target/linux/apm821xx/patches-5.10/804-hwmon-tc654-add-thermal_cooling-device.patch
index 0d2bd79fd7..466507a8fb 100644
--- a/target/linux/apm821xx/patches-5.10/804-hwmon-tc654-add-thermal_cooling-device.patch
+++ b/target/linux/apm821xx/patches-5.10/804-hwmon-tc654-add-thermal_cooling-device.patch
@@ -1,16 +1,20 @@
-From 9cb27801b5cbad2e1aaf45aac428cb2fac5e1372 Mon Sep 17 00:00:00 2001
+From 4d49367c5303e3ebd17502a45b74de280f6be539 Mon Sep 17 00:00:00 2001
 From: Christian Lamparter <chunkeey at gmail.com>
-Date: Sun, 17 Dec 2017 17:29:13 +0100
-Subject: [PATCH] hwmon: tc654: add thermal_cooling device
+Date: Sun, 13 Feb 2022 01:47:33 +0100
+Subject: hwmon: (tc654) Add thermal_cooling device support
 
-This patch adds a thermaL_cooling device to the tc654 driver.
-This allows the chip to be used for DT-based cooling.
+Adds thermal_cooling device support to the tc654/tc655
+driver. This make it possible to integrate it into a
+device-tree supported thermal-zone node as a
+cooling device.
+
+I have been using this patch as part of the Netgear WNDR4700
+Centria NAS Router support within OpenWrt since 2016.
 
 Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
+Link: https://lore.kernel.org/r/20220213004733.2421193-1-chunkeey@gmail.com
+Signed-off-by: Guenter Roeck <linux at roeck-us.net>
 ---
- drivers/hwmon/tc654.c | 103 +++++++++++++++++++++++++++++++++++-------
- 1 file changed, 86 insertions(+), 17 deletions(-)
-
 --- a/drivers/hwmon/tc654.c
 +++ b/drivers/hwmon/tc654.c
 @@ -15,6 +15,7 @@
@@ -21,44 +25,8 @@ Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
  #include <linux/util_macros.h>
  
  enum tc654_regs {
-@@ -132,6 +133,9 @@ struct tc654_data {
- 			 * writable register used to control the duty
- 			 * cycle of the V OUT output.
- 			 */
-+
-+	/* optional cooling device */
-+	struct thermal_cooling_device *cdev;
- };
- 
- /* helper to grab and cache data, at most one time per second */
-@@ -367,36 +371,30 @@ static ssize_t pwm_mode_store(struct dev
- static const int tc654_pwm_map[16] = { 77,  88, 102, 112, 124, 136, 148, 160,
- 				      172, 184, 196, 207, 219, 231, 243, 255};
- 
-+static int get_pwm(struct tc654_data *data)
-+{
-+	if (data->config & TC654_REG_CONFIG_SDM)
-+		return 0;
-+	else
-+		return tc654_pwm_map[data->duty_cycle];
-+}
-+
- static ssize_t pwm_show(struct device *dev, struct device_attribute *da,
- 			char *buf)
- {
- 	struct tc654_data *data = tc654_update_client(dev);
--	int pwm;
- 
- 	if (IS_ERR(data))
- 		return PTR_ERR(data);
- 
--	if (data->config & TC654_REG_CONFIG_SDM)
--		pwm = 0;
--	else
--		pwm = tc654_pwm_map[data->duty_cycle];
--
--	return sprintf(buf, "%d\n", pwm);
-+	return sprintf(buf, "%d\n", get_pwm(data));
+@@ -384,28 +385,20 @@ static ssize_t pwm_show(struct device *d
+ 	return sprintf(buf, "%d\n", pwm);
  }
  
 -static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
@@ -77,8 +45,22 @@ Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
 -
  	mutex_lock(&data->update_lock);
  
- 	if (val == 0)
-@@ -416,6 +414,22 @@ static ssize_t pwm_store(struct device *
+-	if (val == 0)
++	if (val == 0) {
+ 		data->config |= TC654_REG_CONFIG_SDM;
+-	else
++		data->duty_cycle = 0;
++	} else {
+ 		data->config &= ~TC654_REG_CONFIG_SDM;
+-
+-	data->duty_cycle = find_closest(val, tc654_pwm_map,
+-					ARRAY_SIZE(tc654_pwm_map));
++		data->duty_cycle = val - 1;
++	}
+ 
+ 	ret = i2c_smbus_write_byte_data(client, TC654_REG_CONFIG, data->config);
+ 	if (ret < 0)
+@@ -416,6 +409,24 @@ static ssize_t pwm_store(struct device *
  
  out:
  	mutex_unlock(&data->update_lock);
@@ -86,7 +68,7 @@ Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
 +}
 +
 +static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
-+		       const char *buf, size_t count)
++			 const char *buf, size_t count)
 +{
 +	struct tc654_data *data = dev_get_drvdata(dev);
 +	unsigned long val;
@@ -96,48 +78,60 @@ Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
 +		return -EINVAL;
 +	if (val > 255)
 +		return -EINVAL;
++	if (val > 0)
++		val = find_closest(val, tc654_pwm_map, ARRAY_SIZE(tc654_pwm_map)) + 1;
 +
 +	ret = _set_pwm(data, val);
  	return ret < 0 ? ret : count;
  }
  
-@@ -447,6 +461,47 @@ static struct attribute *tc654_attrs[] =
- 
+@@ -448,6 +459,58 @@ static struct attribute *tc654_attrs[] =
  ATTRIBUTE_GROUPS(tc654);
  
-+/* cooling device */
-+
-+static int tc654_get_max_state(struct thermal_cooling_device *cdev,
-+			       unsigned long *state)
+ /*
++ * thermal cooling device functions
++ *
++ * Account for the "ShutDown Mode (SDM)" state by offsetting
++ * the 16 PWM duty cycle states by 1.
++ *
++ * State  0 =   0% PWM | Shutdown - Fan(s) are off
++ * State  1 =  30% PWM | duty_cycle =  0
++ * State  2 = ~35% PWM | duty_cycle =  1
++ * [...]
++ * State 15 = ~95% PWM | duty_cycle = 14
++ * State 16 = 100% PWM | duty_cycle = 15
++ */
++#define TC654_MAX_COOLING_STATE	16
++
++static int tc654_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
 +{
-+	*state = 255;
++	*state = TC654_MAX_COOLING_STATE;
 +	return 0;
 +}
 +
-+static int tc654_get_cur_state(struct thermal_cooling_device *cdev,
-+                              unsigned long *state)
++static int tc654_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
 +{
 +	struct tc654_data *data = tc654_update_client(cdev->devdata);
 +
 +	if (IS_ERR(data))
 +		return PTR_ERR(data);
 +
-+	*state = get_pwm(data);
++	if (data->config & TC654_REG_CONFIG_SDM)
++		*state = 0;	/* FAN is off */
++	else
++		*state = data->duty_cycle + 1;	/* offset PWM States by 1 */
++
 +	return 0;
 +}
 +
-+static int tc654_set_cur_state(struct thermal_cooling_device *cdev,
-+			       unsigned long state)
++static int tc654_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 +{
 +	struct tc654_data *data = tc654_update_client(cdev->devdata);
 +
 +	if (IS_ERR(data))
 +		return PTR_ERR(data);
 +
-+	if (state > 255)
-+		return -EINVAL;
-+
-+	return _set_pwm(data, state);
++	return _set_pwm(data, clamp_val(state, 0, TC654_MAX_COOLING_STATE));
 +}
 +
 +static const struct thermal_cooling_device_ops tc654_fan_cool_ops = {
@@ -146,10 +140,11 @@ Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
 +	.set_cur_state = tc654_set_cur_state,
 +};
 +
- /*
++/*
   * device probe and removal
   */
-@@ -477,7 +532,21 @@ static int tc654_probe(struct i2c_client
+ 
+@@ -477,7 +540,18 @@ static int tc654_probe(struct i2c_client
  	hwmon_dev =
  	    devm_hwmon_device_register_with_groups(dev, client->name, data,
  						   tc654_groups);
@@ -157,18 +152,15 @@ Signed-off-by: Christian Lamparter <chunkeey at gmail.com>
 +	if (IS_ERR(hwmon_dev))
 +		return PTR_ERR(hwmon_dev);
 +
-+#if IS_ENABLED(CONFIG_OF)
-+	/* Optional cooling device register for Device tree platforms */
-+	data->cdev = thermal_of_cooling_device_register(client->dev.of_node,
-+							"tc654", hwmon_dev,
-+							&tc654_fan_cool_ops);
-+#else /* CONFIG_OF */
-+	/* Optional cooling device register for non Device tree platforms */
-+	data->cdev = thermal_cooling_device_register("tc654", hwmon_dev,
-+						     &tc654_fan_cool_ops);
-+#endif /* CONFIG_OF */
-+
-+	return PTR_ERR_OR_ZERO(data->cdev);
++	if (IS_ENABLED(CONFIG_THERMAL)) {
++		struct thermal_cooling_device *cdev;
++
++		cdev = devm_thermal_of_cooling_device_register(dev, dev->of_node, client->name,
++							       hwmon_dev, &tc654_fan_cool_ops);
++		return PTR_ERR_OR_ZERO(cdev);
++	}
++
++	return 0;
  }
  
  static const struct i2c_device_id tc654_id[] = {



More information about the lede-commits mailing list