xref: /linux/drivers/hwmon/qnap-mcu-hwmon.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 /*
4  * Driver for hwmon elements found on QNAP-MCU devices
5  *
6  * Copyright (C) 2024 Heiko Stuebner <heiko@sntech.de>
7  */
8 
9 #include <linux/fwnode.h>
10 #include <linux/hwmon.h>
11 #include <linux/mfd/qnap-mcu.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/property.h>
15 #include <linux/thermal.h>
16 
17 struct qnap_mcu_hwmon {
18 	struct qnap_mcu *mcu;
19 	struct device *dev;
20 
21 	unsigned int pwm_min;
22 	unsigned int pwm_max;
23 
24 	struct fwnode_handle *fan_node;
25 	unsigned int fan_state;
26 	unsigned int fan_max_state;
27 	unsigned int *fan_cooling_levels;
28 
29 	struct thermal_cooling_device *cdev;
30 	struct hwmon_chip_info info;
31 };
32 
33 static int qnap_mcu_hwmon_get_rpm(struct qnap_mcu_hwmon *hwm)
34 {
35 	static const u8 cmd[] = { '@', 'F', 'A' };
36 	u8 reply[6];
37 	int ret;
38 
39 	/* poll the fan rpm */
40 	ret = qnap_mcu_exec(hwm->mcu, cmd, sizeof(cmd), reply, sizeof(reply));
41 	if (ret)
42 		return ret;
43 
44 	/* First 2 bytes must mirror the sent command */
45 	if (memcmp(cmd, reply, 2))
46 		return -EIO;
47 
48 	return reply[4] * 30;
49 }
50 
51 static int qnap_mcu_hwmon_get_pwm(struct qnap_mcu_hwmon *hwm)
52 {
53 	static const u8 cmd[] = { '@', 'F', 'Z', '0' }; /* 0 = fan-id? */
54 	u8 reply[4];
55 	int ret;
56 
57 	/* poll the fan pwm */
58 	ret = qnap_mcu_exec(hwm->mcu, cmd, sizeof(cmd), reply, sizeof(reply));
59 	if (ret)
60 		return ret;
61 
62 	/* First 3 bytes must mirror the sent command */
63 	if (memcmp(cmd, reply, 3))
64 		return -EIO;
65 
66 	return reply[3];
67 }
68 
69 static int qnap_mcu_hwmon_set_pwm(struct qnap_mcu_hwmon *hwm, u8 pwm)
70 {
71 	const u8 cmd[] = { '@', 'F', 'W', '0', pwm }; /* 0 = fan-id?, pwm 0-255 */
72 
73 	/* set the fan pwm */
74 	return qnap_mcu_exec_with_ack(hwm->mcu, cmd, sizeof(cmd));
75 }
76 
77 static int qnap_mcu_hwmon_get_temp(struct qnap_mcu_hwmon *hwm)
78 {
79 	static const u8 cmd[] = { '@', 'T', '3' };
80 	u8 reply[4];
81 	int ret;
82 
83 	/* poll the fan rpm */
84 	ret = qnap_mcu_exec(hwm->mcu, cmd, sizeof(cmd), reply, sizeof(reply));
85 	if (ret)
86 		return ret;
87 
88 	/* First bytes must mirror the sent command */
89 	if (memcmp(cmd, reply, sizeof(cmd)))
90 		return -EIO;
91 
92 	/*
93 	 * There is an unknown bit set in bit7.
94 	 * Bits [6:0] report the actual temperature as returned by the
95 	 * original qnap firmware-tools, so just drop bit7 for now.
96 	 */
97 	return (reply[3] & 0x7f) * 1000;
98 }
99 
100 static int qnap_mcu_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
101 				u32 attr, int channel, long val)
102 {
103 	struct qnap_mcu_hwmon *hwm = dev_get_drvdata(dev);
104 
105 	switch (attr) {
106 	case hwmon_pwm_input:
107 		if (val < 0 || val > 255)
108 			return -EINVAL;
109 
110 		if (val != 0)
111 			val = clamp_val(val, hwm->pwm_min, hwm->pwm_max);
112 
113 		return qnap_mcu_hwmon_set_pwm(hwm, val);
114 	default:
115 		return -EOPNOTSUPP;
116 	}
117 
118 	return 0;
119 }
120 
121 static int qnap_mcu_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
122 			       u32 attr, int channel, long *val)
123 {
124 	struct qnap_mcu_hwmon *hwm = dev_get_drvdata(dev);
125 	int ret;
126 
127 	switch (type) {
128 	case hwmon_pwm:
129 		switch (attr) {
130 		case hwmon_pwm_input:
131 			ret = qnap_mcu_hwmon_get_pwm(hwm);
132 			if (ret < 0)
133 				return ret;
134 
135 			*val = ret;
136 			return 0;
137 		default:
138 			return -EOPNOTSUPP;
139 		}
140 	case hwmon_fan:
141 		ret = qnap_mcu_hwmon_get_rpm(hwm);
142 		if (ret < 0)
143 			return ret;
144 
145 		*val = ret;
146 		return 0;
147 	case hwmon_temp:
148 		ret = qnap_mcu_hwmon_get_temp(hwm);
149 		if (ret < 0)
150 			return ret;
151 
152 		*val = ret;
153 		return 0;
154 	default:
155 		return -EOPNOTSUPP;
156 	}
157 }
158 
159 static umode_t qnap_mcu_hwmon_is_visible(const void *data,
160 					 enum hwmon_sensor_types type,
161 					 u32 attr, int channel)
162 {
163 	switch (type) {
164 	case hwmon_temp:
165 		return 0444;
166 
167 	case hwmon_pwm:
168 		return 0644;
169 
170 	case hwmon_fan:
171 		return 0444;
172 
173 	default:
174 		return 0;
175 	}
176 }
177 
178 static const struct hwmon_ops qnap_mcu_hwmon_hwmon_ops = {
179 	.is_visible = qnap_mcu_hwmon_is_visible,
180 	.read = qnap_mcu_hwmon_read,
181 	.write = qnap_mcu_hwmon_write,
182 };
183 
184 /* thermal cooling device callbacks */
185 static int qnap_mcu_hwmon_get_max_state(struct thermal_cooling_device *cdev,
186 					unsigned long *state)
187 {
188 	struct qnap_mcu_hwmon *hwm = cdev->devdata;
189 
190 	if (!hwm)
191 		return -EINVAL;
192 
193 	*state = hwm->fan_max_state;
194 
195 	return 0;
196 }
197 
198 static int qnap_mcu_hwmon_get_cur_state(struct thermal_cooling_device *cdev,
199 					unsigned long *state)
200 {
201 	struct qnap_mcu_hwmon *hwm = cdev->devdata;
202 
203 	if (!hwm)
204 		return -EINVAL;
205 
206 	*state = hwm->fan_state;
207 
208 	return 0;
209 }
210 
211 static int qnap_mcu_hwmon_set_cur_state(struct thermal_cooling_device *cdev,
212 					unsigned long state)
213 {
214 	struct qnap_mcu_hwmon *hwm = cdev->devdata;
215 	int ret;
216 
217 	if (!hwm || state > hwm->fan_max_state)
218 		return -EINVAL;
219 
220 	if (state == hwm->fan_state)
221 		return 0;
222 
223 	ret = qnap_mcu_hwmon_set_pwm(hwm, hwm->fan_cooling_levels[state]);
224 	if (ret)
225 		return ret;
226 
227 	hwm->fan_state = state;
228 
229 	return ret;
230 }
231 
232 static const struct thermal_cooling_device_ops qnap_mcu_hwmon_cooling_ops = {
233 	.get_max_state = qnap_mcu_hwmon_get_max_state,
234 	.get_cur_state = qnap_mcu_hwmon_get_cur_state,
235 	.set_cur_state = qnap_mcu_hwmon_set_cur_state,
236 };
237 
238 static void devm_fan_node_release(void *data)
239 {
240 	struct qnap_mcu_hwmon *hwm = data;
241 
242 	fwnode_handle_put(hwm->fan_node);
243 }
244 
245 static int qnap_mcu_hwmon_get_cooling_data(struct device *dev, struct qnap_mcu_hwmon *hwm)
246 {
247 	struct fwnode_handle *fwnode;
248 	int num, i, ret;
249 
250 	fwnode = device_get_named_child_node(dev->parent, "fan-0");
251 	if (!fwnode)
252 		return 0;
253 
254 	/* if we found the fan-node, we're keeping it until device-unbind */
255 	hwm->fan_node = fwnode;
256 	ret = devm_add_action_or_reset(dev, devm_fan_node_release, hwm);
257 	if (ret)
258 		return ret;
259 
260 	num = fwnode_property_count_u32(fwnode, "cooling-levels");
261 	if (num <= 0)
262 		return dev_err_probe(dev, num ? : -EINVAL,
263 				     "Failed to count elements in 'cooling-levels'\n");
264 
265 	hwm->fan_cooling_levels = devm_kcalloc(dev, num, sizeof(u32),
266 					       GFP_KERNEL);
267 	if (!hwm->fan_cooling_levels)
268 		return -ENOMEM;
269 
270 	ret = fwnode_property_read_u32_array(fwnode, "cooling-levels",
271 					     hwm->fan_cooling_levels, num);
272 	if (ret)
273 		return dev_err_probe(dev, ret, "Failed to read 'cooling-levels'\n");
274 
275 	for (i = 0; i < num; i++) {
276 		if (hwm->fan_cooling_levels[i] > hwm->pwm_max)
277 			return dev_err_probe(dev, -EINVAL, "fan state[%d]:%d > %d\n", i,
278 					     hwm->fan_cooling_levels[i], hwm->pwm_max);
279 	}
280 
281 	hwm->fan_max_state = num - 1;
282 
283 	return 0;
284 }
285 
286 static const struct hwmon_channel_info * const qnap_mcu_hwmon_channels[] = {
287 	HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT),
288 	HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT),
289 	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
290 	NULL
291 };
292 
293 static int qnap_mcu_hwmon_probe(struct platform_device *pdev)
294 {
295 	struct qnap_mcu *mcu = dev_get_drvdata(pdev->dev.parent);
296 	const struct qnap_mcu_variant *variant = pdev->dev.platform_data;
297 	struct qnap_mcu_hwmon *hwm;
298 	struct thermal_cooling_device *cdev;
299 	struct device *dev = &pdev->dev;
300 	struct device *hwmon;
301 	int ret;
302 
303 	hwm = devm_kzalloc(dev, sizeof(*hwm), GFP_KERNEL);
304 	if (!hwm)
305 		return -ENOMEM;
306 
307 	hwm->mcu = mcu;
308 	hwm->dev = &pdev->dev;
309 	hwm->pwm_min = variant->fan_pwm_min;
310 	hwm->pwm_max = variant->fan_pwm_max;
311 
312 	platform_set_drvdata(pdev, hwm);
313 
314 	/*
315 	 * Set duty cycle to maximum allowed.
316 	 */
317 	ret = qnap_mcu_hwmon_set_pwm(hwm, hwm->pwm_max);
318 	if (ret)
319 		return ret;
320 
321 	hwm->info.ops = &qnap_mcu_hwmon_hwmon_ops;
322 	hwm->info.info = qnap_mcu_hwmon_channels;
323 
324 	ret = qnap_mcu_hwmon_get_cooling_data(dev, hwm);
325 	if (ret)
326 		return ret;
327 
328 	hwm->fan_state = hwm->fan_max_state;
329 
330 	hwmon = devm_hwmon_device_register_with_info(dev, "qnapmcu",
331 						     hwm, &hwm->info, NULL);
332 	if (IS_ERR(hwmon))
333 		return dev_err_probe(dev, PTR_ERR(hwmon), "Failed to register hwmon device\n");
334 
335 	/*
336 	 * Only register cooling device when we found cooling-levels.
337 	 * qnap_mcu_hwmon_get_cooling_data() will fail when reading malformed
338 	 * levels and only succeed with either no or correct cooling levels.
339 	 */
340 	if (IS_ENABLED(CONFIG_THERMAL) && hwm->fan_cooling_levels) {
341 		cdev = devm_thermal_of_cooling_device_register(dev,
342 					to_of_node(hwm->fan_node), "qnap-mcu-hwmon",
343 					hwm, &qnap_mcu_hwmon_cooling_ops);
344 		if (IS_ERR(cdev))
345 			return dev_err_probe(dev, PTR_ERR(cdev),
346 				"Failed to register qnap-mcu-hwmon as cooling device\n");
347 		hwm->cdev = cdev;
348 	}
349 
350 	return 0;
351 }
352 
353 static struct platform_driver qnap_mcu_hwmon_driver = {
354 	.probe = qnap_mcu_hwmon_probe,
355 	.driver = {
356 		.name = "qnap-mcu-hwmon",
357 	},
358 };
359 module_platform_driver(qnap_mcu_hwmon_driver);
360 
361 MODULE_ALIAS("platform:qnap-mcu-hwmon");
362 MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
363 MODULE_DESCRIPTION("QNAP MCU hwmon driver");
364 MODULE_LICENSE("GPL");
365