• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 //
3 // Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4 // Copyright (c) 2018 Vadim Pasternak <vadimp@mellanox.com>
5 
6 #include <linux/bitops.h>
7 #include <linux/device.h>
8 #include <linux/hwmon.h>
9 #include <linux/module.h>
10 #include <linux/platform_data/mlxreg.h>
11 #include <linux/platform_device.h>
12 #include <linux/regmap.h>
13 #include <linux/thermal.h>
14 
15 #define MLXREG_FAN_MAX_TACHO		12
16 #define MLXREG_FAN_MAX_STATE		10
17 #define MLXREG_FAN_MIN_DUTY		51	/* 20% */
18 #define MLXREG_FAN_MAX_DUTY		255	/* 100% */
19 /*
20  * Minimum and maximum FAN allowed speed in percent: from 20% to 100%. Values
21  * MLXREG_FAN_MAX_STATE + x, where x is between 2 and 10 are used for
22  * setting FAN speed dynamic minimum. For example, if value is set to 14 (40%)
23  * cooling levels vector will be set to 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10 to
24  * introduce PWM speed in percent: 40, 40, 40, 40, 40, 50, 60. 70, 80, 90, 100.
25  */
26 #define MLXREG_FAN_SPEED_MIN			(MLXREG_FAN_MAX_STATE + 2)
27 #define MLXREG_FAN_SPEED_MAX			(MLXREG_FAN_MAX_STATE * 2)
28 #define MLXREG_FAN_SPEED_MIN_LEVEL		2	/* 20 percent */
29 #define MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF	44
30 #define MLXREG_FAN_TACHO_DIV_MIN		283
31 #define MLXREG_FAN_TACHO_DIV_DEF		(MLXREG_FAN_TACHO_DIV_MIN * 4)
32 #define MLXREG_FAN_TACHO_DIV_SCALE_MAX	64
33 /*
34  * FAN datasheet defines the formula for RPM calculations as RPM = 15/t-high.
35  * The logic in a programmable device measures the time t-high by sampling the
36  * tachometer every t-sample (with the default value 11.32 uS) and increment
37  * a counter (N) as long as the pulse has not change:
38  * RPM = 15 / (t-sample * (K + Regval)), where:
39  * Regval: is the value read from the programmable device register;
40  *  - 0xff - represents tachometer fault;
41  *  - 0xfe - represents tachometer minimum value , which is 4444 RPM;
42  *  - 0x00 - represents tachometer maximum value , which is 300000 RPM;
43  * K: is 44 and it represents the minimum allowed samples per pulse;
44  * N: is equal K + Regval;
45  * In order to calculate RPM from the register value the following formula is
46  * used: RPM = 15 / ((Regval + K) * 11.32) * 10^(-6)), which in  the
47  * default case is modified to:
48  * RPM = 15000000 * 100 / ((Regval + 44) * 1132);
49  * - for Regval 0x00, RPM will be 15000000 * 100 / (44 * 1132) = 30115;
50  * - for Regval 0xfe, RPM will be 15000000 * 100 / ((254 + 44) * 1132) = 4446;
51  * In common case the formula is modified to:
52  * RPM = 15000000 * 100 / ((Regval + samples) * divider).
53  */
54 #define MLXREG_FAN_GET_RPM(rval, d, s)	(DIV_ROUND_CLOSEST(15000000 * 100, \
55 					 ((rval) + (s)) * (d)))
56 #define MLXREG_FAN_GET_FAULT(val, mask) ((val) == (mask))
57 #define MLXREG_FAN_PWM_DUTY2STATE(duty)	(DIV_ROUND_CLOSEST((duty) *	\
58 					 MLXREG_FAN_MAX_STATE,		\
59 					 MLXREG_FAN_MAX_DUTY))
60 #define MLXREG_FAN_PWM_STATE2DUTY(stat)	(DIV_ROUND_CLOSEST((stat) *	\
61 					 MLXREG_FAN_MAX_DUTY,		\
62 					 MLXREG_FAN_MAX_STATE))
63 
64 /*
65  * struct mlxreg_fan_tacho - tachometer data (internal use):
66  *
67  * @connected: indicates if tachometer is connected;
68  * @reg: register offset;
69  * @mask: fault mask;
70  * @prsnt: present register offset;
71  */
72 struct mlxreg_fan_tacho {
73 	bool connected;
74 	u32 reg;
75 	u32 mask;
76 	u32 prsnt;
77 };
78 
79 /*
80  * struct mlxreg_fan_pwm - PWM data (internal use):
81  *
82  * @connected: indicates if PWM is connected;
83  * @reg: register offset;
84  */
85 struct mlxreg_fan_pwm {
86 	bool connected;
87 	u32 reg;
88 };
89 
90 /*
91  * struct mlxreg_fan - private data (internal use):
92  *
93  * @dev: basic device;
94  * @regmap: register map of parent device;
95  * @tacho: tachometer data;
96  * @pwm: PWM data;
97  * @tachos_per_drwr - number of tachometers per drawer;
98  * @samples: minimum allowed samples per pulse;
99  * @divider: divider value for tachometer RPM calculation;
100  * @cooling: cooling device levels;
101  * @cdev: cooling device;
102  */
103 struct mlxreg_fan {
104 	struct device *dev;
105 	void *regmap;
106 	struct mlxreg_core_platform_data *pdata;
107 	struct mlxreg_fan_tacho tacho[MLXREG_FAN_MAX_TACHO];
108 	struct mlxreg_fan_pwm pwm;
109 	int tachos_per_drwr;
110 	int samples;
111 	int divider;
112 	u8 cooling_levels[MLXREG_FAN_MAX_STATE + 1];
113 	struct thermal_cooling_device *cdev;
114 };
115 
116 static int
mlxreg_fan_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)117 mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
118 		int channel, long *val)
119 {
120 	struct mlxreg_fan *fan = dev_get_drvdata(dev);
121 	struct mlxreg_fan_tacho *tacho;
122 	u32 regval;
123 	int err;
124 
125 	switch (type) {
126 	case hwmon_fan:
127 		tacho = &fan->tacho[channel];
128 		switch (attr) {
129 		case hwmon_fan_input:
130 			/*
131 			 * Check FAN presence: FAN related bit in presence register is one,
132 			 * if FAN is physically connected, zero - otherwise.
133 			 */
134 			if (tacho->prsnt && fan->tachos_per_drwr) {
135 				err = regmap_read(fan->regmap, tacho->prsnt, &regval);
136 				if (err)
137 					return err;
138 
139 				/*
140 				 * Map channel to presence bit - drawer can be equipped with
141 				 * one or few FANs, while presence is indicated per drawer.
142 				 */
143 				if (BIT(channel / fan->tachos_per_drwr) & regval) {
144 					/* FAN is not connected - return zero for FAN speed. */
145 					*val = 0;
146 					return 0;
147 				}
148 			}
149 
150 			err = regmap_read(fan->regmap, tacho->reg, &regval);
151 			if (err)
152 				return err;
153 
154 			if (MLXREG_FAN_GET_FAULT(regval, tacho->mask)) {
155 				/* FAN is broken - return zero for FAN speed. */
156 				*val = 0;
157 				return 0;
158 			}
159 
160 			*val = MLXREG_FAN_GET_RPM(regval, fan->divider,
161 						  fan->samples);
162 			break;
163 
164 		case hwmon_fan_fault:
165 			err = regmap_read(fan->regmap, tacho->reg, &regval);
166 			if (err)
167 				return err;
168 
169 			*val = MLXREG_FAN_GET_FAULT(regval, tacho->mask);
170 			break;
171 
172 		default:
173 			return -EOPNOTSUPP;
174 		}
175 		break;
176 
177 	case hwmon_pwm:
178 		switch (attr) {
179 		case hwmon_pwm_input:
180 			err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
181 			if (err)
182 				return err;
183 
184 			*val = regval;
185 			break;
186 
187 		default:
188 			return -EOPNOTSUPP;
189 		}
190 		break;
191 
192 	default:
193 		return -EOPNOTSUPP;
194 	}
195 
196 	return 0;
197 }
198 
199 static int
mlxreg_fan_write(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long val)200 mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
201 		 int channel, long val)
202 {
203 	struct mlxreg_fan *fan = dev_get_drvdata(dev);
204 
205 	switch (type) {
206 	case hwmon_pwm:
207 		switch (attr) {
208 		case hwmon_pwm_input:
209 			if (val < MLXREG_FAN_MIN_DUTY ||
210 			    val > MLXREG_FAN_MAX_DUTY)
211 				return -EINVAL;
212 			return regmap_write(fan->regmap, fan->pwm.reg, val);
213 		default:
214 			return -EOPNOTSUPP;
215 		}
216 		break;
217 
218 	default:
219 		return -EOPNOTSUPP;
220 	}
221 
222 	return -EOPNOTSUPP;
223 }
224 
225 static umode_t
mlxreg_fan_is_visible(const void * data,enum hwmon_sensor_types type,u32 attr,int channel)226 mlxreg_fan_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
227 		      int channel)
228 {
229 	switch (type) {
230 	case hwmon_fan:
231 		if (!(((struct mlxreg_fan *)data)->tacho[channel].connected))
232 			return 0;
233 
234 		switch (attr) {
235 		case hwmon_fan_input:
236 		case hwmon_fan_fault:
237 			return 0444;
238 		default:
239 			break;
240 		}
241 		break;
242 
243 	case hwmon_pwm:
244 		if (!(((struct mlxreg_fan *)data)->pwm.connected))
245 			return 0;
246 
247 		switch (attr) {
248 		case hwmon_pwm_input:
249 			return 0644;
250 		default:
251 			break;
252 		}
253 		break;
254 
255 	default:
256 		break;
257 	}
258 
259 	return 0;
260 }
261 
262 static const struct hwmon_channel_info *mlxreg_fan_hwmon_info[] = {
263 	HWMON_CHANNEL_INFO(fan,
264 			   HWMON_F_INPUT | HWMON_F_FAULT,
265 			   HWMON_F_INPUT | HWMON_F_FAULT,
266 			   HWMON_F_INPUT | HWMON_F_FAULT,
267 			   HWMON_F_INPUT | HWMON_F_FAULT,
268 			   HWMON_F_INPUT | HWMON_F_FAULT,
269 			   HWMON_F_INPUT | HWMON_F_FAULT,
270 			   HWMON_F_INPUT | HWMON_F_FAULT,
271 			   HWMON_F_INPUT | HWMON_F_FAULT,
272 			   HWMON_F_INPUT | HWMON_F_FAULT,
273 			   HWMON_F_INPUT | HWMON_F_FAULT,
274 			   HWMON_F_INPUT | HWMON_F_FAULT,
275 			   HWMON_F_INPUT | HWMON_F_FAULT),
276 	HWMON_CHANNEL_INFO(pwm,
277 			   HWMON_PWM_INPUT),
278 	NULL
279 };
280 
281 static const struct hwmon_ops mlxreg_fan_hwmon_hwmon_ops = {
282 	.is_visible = mlxreg_fan_is_visible,
283 	.read = mlxreg_fan_read,
284 	.write = mlxreg_fan_write,
285 };
286 
287 static const struct hwmon_chip_info mlxreg_fan_hwmon_chip_info = {
288 	.ops = &mlxreg_fan_hwmon_hwmon_ops,
289 	.info = mlxreg_fan_hwmon_info,
290 };
291 
mlxreg_fan_get_max_state(struct thermal_cooling_device * cdev,unsigned long * state)292 static int mlxreg_fan_get_max_state(struct thermal_cooling_device *cdev,
293 				    unsigned long *state)
294 {
295 	*state = MLXREG_FAN_MAX_STATE;
296 	return 0;
297 }
298 
mlxreg_fan_get_cur_state(struct thermal_cooling_device * cdev,unsigned long * state)299 static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev,
300 				    unsigned long *state)
301 
302 {
303 	struct mlxreg_fan *fan = cdev->devdata;
304 	u32 regval;
305 	int err;
306 
307 	err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
308 	if (err) {
309 		dev_err(fan->dev, "Failed to query PWM duty\n");
310 		return err;
311 	}
312 
313 	*state = MLXREG_FAN_PWM_DUTY2STATE(regval);
314 
315 	return 0;
316 }
317 
mlxreg_fan_set_cur_state(struct thermal_cooling_device * cdev,unsigned long state)318 static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
319 				    unsigned long state)
320 
321 {
322 	struct mlxreg_fan *fan = cdev->devdata;
323 	unsigned long cur_state;
324 	int i, config = 0;
325 	u32 regval;
326 	int err;
327 
328 	/*
329 	 * Verify if this request is for changing allowed FAN dynamical
330 	 * minimum. If it is - update cooling levels accordingly and update
331 	 * state, if current state is below the newly requested minimum state.
332 	 * For example, if current state is 5, and minimal state is to be
333 	 * changed from 4 to 6, fan->cooling_levels[0 to 5] will be changed all
334 	 * from 4 to 6. And state 5 (fan->cooling_levels[4]) should be
335 	 * overwritten.
336 	 */
337 	if (state >= MLXREG_FAN_SPEED_MIN && state <= MLXREG_FAN_SPEED_MAX) {
338 		/*
339 		 * This is configuration change, which is only supported through sysfs.
340 		 * For configuration non-zero value is to be returned to avoid thermal
341 		 * statistics update.
342 		 */
343 		config = 1;
344 		state -= MLXREG_FAN_MAX_STATE;
345 		for (i = 0; i < state; i++)
346 			fan->cooling_levels[i] = state;
347 		for (i = state; i <= MLXREG_FAN_MAX_STATE; i++)
348 			fan->cooling_levels[i] = i;
349 
350 		err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
351 		if (err) {
352 			dev_err(fan->dev, "Failed to query PWM duty\n");
353 			return err;
354 		}
355 
356 		cur_state = MLXREG_FAN_PWM_DUTY2STATE(regval);
357 		if (state < cur_state)
358 			return config;
359 
360 		state = cur_state;
361 	}
362 
363 	if (state > MLXREG_FAN_MAX_STATE)
364 		return -EINVAL;
365 
366 	/* Normalize the state to the valid speed range. */
367 	state = fan->cooling_levels[state];
368 	err = regmap_write(fan->regmap, fan->pwm.reg,
369 			   MLXREG_FAN_PWM_STATE2DUTY(state));
370 	if (err) {
371 		dev_err(fan->dev, "Failed to write PWM duty\n");
372 		return err;
373 	}
374 	return config;
375 }
376 
377 static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = {
378 	.get_max_state	= mlxreg_fan_get_max_state,
379 	.get_cur_state	= mlxreg_fan_get_cur_state,
380 	.set_cur_state	= mlxreg_fan_set_cur_state,
381 };
382 
mlxreg_fan_connect_verify(struct mlxreg_fan * fan,struct mlxreg_core_data * data)383 static int mlxreg_fan_connect_verify(struct mlxreg_fan *fan,
384 				     struct mlxreg_core_data *data)
385 {
386 	u32 regval;
387 	int err;
388 
389 	err = regmap_read(fan->regmap, data->capability, &regval);
390 	if (err) {
391 		dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
392 			data->capability);
393 		return err;
394 	}
395 
396 	return !!(regval & data->bit);
397 }
398 
mlxreg_fan_speed_divider_get(struct mlxreg_fan * fan,struct mlxreg_core_data * data)399 static int mlxreg_fan_speed_divider_get(struct mlxreg_fan *fan,
400 					struct mlxreg_core_data *data)
401 {
402 	u32 regval;
403 	int err;
404 
405 	err = regmap_read(fan->regmap, data->capability, &regval);
406 	if (err) {
407 		dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
408 			data->capability);
409 		return err;
410 	}
411 
412 	/*
413 	 * Set divider value according to the capability register, in case it
414 	 * contains valid value. Otherwise use default value. The purpose of
415 	 * this validation is to protect against the old hardware, in which
416 	 * this register can return zero.
417 	 */
418 	if (regval > 0 && regval <= MLXREG_FAN_TACHO_DIV_SCALE_MAX)
419 		fan->divider = regval * MLXREG_FAN_TACHO_DIV_MIN;
420 
421 	return 0;
422 }
423 
mlxreg_fan_config(struct mlxreg_fan * fan,struct mlxreg_core_platform_data * pdata)424 static int mlxreg_fan_config(struct mlxreg_fan *fan,
425 			     struct mlxreg_core_platform_data *pdata)
426 {
427 	struct mlxreg_core_data *data = pdata->data;
428 	int tacho_num = 0, tacho_avail = 0, i;
429 	bool configured = false;
430 	int err;
431 
432 	fan->samples = MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF;
433 	fan->divider = MLXREG_FAN_TACHO_DIV_DEF;
434 	for (i = 0; i < pdata->counter; i++, data++) {
435 		if (strnstr(data->label, "tacho", sizeof(data->label))) {
436 			if (tacho_num == MLXREG_FAN_MAX_TACHO) {
437 				dev_err(fan->dev, "too many tacho entries: %s\n",
438 					data->label);
439 				return -EINVAL;
440 			}
441 
442 			if (data->capability) {
443 				err = mlxreg_fan_connect_verify(fan, data);
444 				if (err < 0)
445 					return err;
446 				else if (!err) {
447 					tacho_num++;
448 					continue;
449 				}
450 			}
451 
452 			fan->tacho[tacho_num].reg = data->reg;
453 			fan->tacho[tacho_num].mask = data->mask;
454 			fan->tacho[tacho_num].prsnt = data->reg_prsnt;
455 			fan->tacho[tacho_num++].connected = true;
456 			tacho_avail++;
457 		} else if (strnstr(data->label, "pwm", sizeof(data->label))) {
458 			if (fan->pwm.connected) {
459 				dev_err(fan->dev, "duplicate pwm entry: %s\n",
460 					data->label);
461 				return -EINVAL;
462 			}
463 			fan->pwm.reg = data->reg;
464 			fan->pwm.connected = true;
465 		} else if (strnstr(data->label, "conf", sizeof(data->label))) {
466 			if (configured) {
467 				dev_err(fan->dev, "duplicate conf entry: %s\n",
468 					data->label);
469 				return -EINVAL;
470 			}
471 			/* Validate that conf parameters are not zeros. */
472 			if (!data->mask && !data->bit && !data->capability) {
473 				dev_err(fan->dev, "invalid conf entry params: %s\n",
474 					data->label);
475 				return -EINVAL;
476 			}
477 			if (data->capability) {
478 				err = mlxreg_fan_speed_divider_get(fan, data);
479 				if (err)
480 					return err;
481 			} else {
482 				if (data->mask)
483 					fan->samples = data->mask;
484 				if (data->bit)
485 					fan->divider = data->bit;
486 			}
487 			configured = true;
488 		} else {
489 			dev_err(fan->dev, "invalid label: %s\n", data->label);
490 			return -EINVAL;
491 		}
492 	}
493 
494 	if (pdata->capability) {
495 		int drwr_avail;
496 		u32 regval;
497 
498 		/* Obtain the number of FAN drawers, supported by system. */
499 		err = regmap_read(fan->regmap, pdata->capability, &regval);
500 		if (err) {
501 			dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
502 				pdata->capability);
503 			return err;
504 		}
505 
506 		drwr_avail = hweight32(regval);
507 		if (!tacho_avail || !drwr_avail || tacho_avail < drwr_avail) {
508 			dev_err(fan->dev, "Configuration is invalid: drawers num %d tachos num %d\n",
509 				drwr_avail, tacho_avail);
510 			return -EINVAL;
511 		}
512 
513 		/* Set the number of tachometers per one drawer. */
514 		fan->tachos_per_drwr = tacho_avail / drwr_avail;
515 	}
516 
517 	/* Init cooling levels per PWM state. */
518 	for (i = 0; i < MLXREG_FAN_SPEED_MIN_LEVEL; i++)
519 		fan->cooling_levels[i] = MLXREG_FAN_SPEED_MIN_LEVEL;
520 	for (i = MLXREG_FAN_SPEED_MIN_LEVEL; i <= MLXREG_FAN_MAX_STATE; i++)
521 		fan->cooling_levels[i] = i;
522 
523 	return 0;
524 }
525 
mlxreg_fan_probe(struct platform_device * pdev)526 static int mlxreg_fan_probe(struct platform_device *pdev)
527 {
528 	struct mlxreg_core_platform_data *pdata;
529 	struct device *dev = &pdev->dev;
530 	struct mlxreg_fan *fan;
531 	struct device *hwm;
532 	int err;
533 
534 	pdata = dev_get_platdata(dev);
535 	if (!pdata) {
536 		dev_err(dev, "Failed to get platform data.\n");
537 		return -EINVAL;
538 	}
539 
540 	fan = devm_kzalloc(dev, sizeof(*fan), GFP_KERNEL);
541 	if (!fan)
542 		return -ENOMEM;
543 
544 	fan->dev = dev;
545 	fan->regmap = pdata->regmap;
546 
547 	err = mlxreg_fan_config(fan, pdata);
548 	if (err)
549 		return err;
550 
551 	hwm = devm_hwmon_device_register_with_info(dev, "mlxreg_fan",
552 						   fan,
553 						   &mlxreg_fan_hwmon_chip_info,
554 						   NULL);
555 	if (IS_ERR(hwm)) {
556 		dev_err(dev, "Failed to register hwmon device\n");
557 		return PTR_ERR(hwm);
558 	}
559 
560 	if (IS_REACHABLE(CONFIG_THERMAL)) {
561 		fan->cdev = devm_thermal_of_cooling_device_register(dev,
562 			NULL, "mlxreg_fan", fan, &mlxreg_fan_cooling_ops);
563 		if (IS_ERR(fan->cdev)) {
564 			dev_err(dev, "Failed to register cooling device\n");
565 			return PTR_ERR(fan->cdev);
566 		}
567 	}
568 
569 	return 0;
570 }
571 
572 static struct platform_driver mlxreg_fan_driver = {
573 	.driver = {
574 	    .name = "mlxreg-fan",
575 	},
576 	.probe = mlxreg_fan_probe,
577 };
578 
579 module_platform_driver(mlxreg_fan_driver);
580 
581 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
582 MODULE_DESCRIPTION("Mellanox FAN driver");
583 MODULE_LICENSE("GPL");
584 MODULE_ALIAS("platform:mlxreg-fan");
585