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