1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
3 // Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4 // Copyright (c) 2018 Vadim Pasternak <vadimp@mellanox.com>
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>
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% */
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.
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_DIVIDER_DEF 1132
32 * FAN datasheet defines the formula for RPM calculations as RPM = 15/t-high.
33 * The logic in a programmable device measures the time t-high by sampling the
34 * tachometer every t-sample (with the default value 11.32 uS) and increment
35 * a counter (N) as long as the pulse has not change:
36 * RPM = 15 / (t-sample * (K + Regval)), where:
37 * Regval: is the value read from the programmable device register;
38 * - 0xff - represents tachometer fault;
39 * - 0xfe - represents tachometer minimum value , which is 4444 RPM;
40 * - 0x00 - represents tachometer maximum value , which is 300000 RPM;
41 * K: is 44 and it represents the minimum allowed samples per pulse;
42 * N: is equal K + Regval;
43 * In order to calculate RPM from the register value the following formula is
44 * used: RPM = 15 / ((Regval + K) * 11.32) * 10^(-6)), which in the
45 * default case is modified to:
46 * RPM = 15000000 * 100 / ((Regval + 44) * 1132);
47 * - for Regval 0x00, RPM will be 15000000 * 100 / (44 * 1132) = 30115;
48 * - for Regval 0xfe, RPM will be 15000000 * 100 / ((254 + 44) * 1132) = 4446;
49 * In common case the formula is modified to:
50 * RPM = 15000000 * 100 / ((Regval + samples) * divider).
52 #define MLXREG_FAN_GET_RPM(rval, d, s) (DIV_ROUND_CLOSEST(15000000 * 100, \
53 ((rval) + (s)) * (d)))
54 #define MLXREG_FAN_GET_FAULT(val, mask) (!((val) ^ (mask)))
55 #define MLXREG_FAN_PWM_DUTY2STATE(duty) (DIV_ROUND_CLOSEST((duty) * \
56 MLXREG_FAN_MAX_STATE, \
58 #define MLXREG_FAN_PWM_STATE2DUTY(stat) (DIV_ROUND_CLOSEST((stat) * \
59 MLXREG_FAN_MAX_DUTY, \
60 MLXREG_FAN_MAX_STATE))
63 * struct mlxreg_fan_tacho - tachometer data (internal use):
65 * @connected: indicates if tachometer is connected;
66 * @reg: register offset;
69 struct mlxreg_fan_tacho
{
76 * struct mlxreg_fan_pwm - PWM data (internal use):
78 * @connected: indicates if PWM is connected;
79 * @reg: register offset;
81 struct mlxreg_fan_pwm
{
87 * struct mlxreg_fan - private data (internal use):
90 * @regmap: register map of parent device;
91 * @tacho: tachometer data;
93 * @samples: minimum allowed samples per pulse;
94 * @divider: divider value for tachometer RPM calculation;
95 * @cooling: cooling device levels;
96 * @cdev: cooling device;
101 struct mlxreg_core_platform_data
*pdata
;
102 struct mlxreg_fan_tacho tacho
[MLXREG_FAN_MAX_TACHO
];
103 struct mlxreg_fan_pwm pwm
;
106 u8 cooling_levels
[MLXREG_FAN_MAX_STATE
+ 1];
107 struct thermal_cooling_device
*cdev
;
111 mlxreg_fan_read(struct device
*dev
, enum hwmon_sensor_types type
, u32 attr
,
112 int channel
, long *val
)
114 struct mlxreg_fan
*fan
= dev_get_drvdata(dev
);
115 struct mlxreg_fan_tacho
*tacho
;
121 tacho
= &fan
->tacho
[channel
];
123 case hwmon_fan_input
:
124 err
= regmap_read(fan
->regmap
, tacho
->reg
, ®val
);
128 *val
= MLXREG_FAN_GET_RPM(regval
, fan
->divider
,
132 case hwmon_fan_fault
:
133 err
= regmap_read(fan
->regmap
, tacho
->reg
, ®val
);
137 *val
= MLXREG_FAN_GET_FAULT(regval
, tacho
->mask
);
147 case hwmon_pwm_input
:
148 err
= regmap_read(fan
->regmap
, fan
->pwm
.reg
, ®val
);
168 mlxreg_fan_write(struct device
*dev
, enum hwmon_sensor_types type
, u32 attr
,
169 int channel
, long val
)
171 struct mlxreg_fan
*fan
= dev_get_drvdata(dev
);
176 case hwmon_pwm_input
:
177 if (val
< MLXREG_FAN_MIN_DUTY
||
178 val
> MLXREG_FAN_MAX_DUTY
)
180 return regmap_write(fan
->regmap
, fan
->pwm
.reg
, val
);
194 mlxreg_fan_is_visible(const void *data
, enum hwmon_sensor_types type
, u32 attr
,
199 if (!(((struct mlxreg_fan
*)data
)->tacho
[channel
].connected
))
203 case hwmon_fan_input
:
204 case hwmon_fan_fault
:
212 if (!(((struct mlxreg_fan
*)data
)->pwm
.connected
))
216 case hwmon_pwm_input
:
230 static const u32 mlxreg_fan_hwmon_fan_config
[] = {
231 HWMON_F_INPUT
| HWMON_F_FAULT
,
232 HWMON_F_INPUT
| HWMON_F_FAULT
,
233 HWMON_F_INPUT
| HWMON_F_FAULT
,
234 HWMON_F_INPUT
| HWMON_F_FAULT
,
235 HWMON_F_INPUT
| HWMON_F_FAULT
,
236 HWMON_F_INPUT
| HWMON_F_FAULT
,
237 HWMON_F_INPUT
| HWMON_F_FAULT
,
238 HWMON_F_INPUT
| HWMON_F_FAULT
,
239 HWMON_F_INPUT
| HWMON_F_FAULT
,
240 HWMON_F_INPUT
| HWMON_F_FAULT
,
241 HWMON_F_INPUT
| HWMON_F_FAULT
,
242 HWMON_F_INPUT
| HWMON_F_FAULT
,
246 static const struct hwmon_channel_info mlxreg_fan_hwmon_fan
= {
248 .config
= mlxreg_fan_hwmon_fan_config
,
251 static const u32 mlxreg_fan_hwmon_pwm_config
[] = {
256 static const struct hwmon_channel_info mlxreg_fan_hwmon_pwm
= {
258 .config
= mlxreg_fan_hwmon_pwm_config
,
261 static const struct hwmon_channel_info
*mlxreg_fan_hwmon_info
[] = {
262 &mlxreg_fan_hwmon_fan
,
263 &mlxreg_fan_hwmon_pwm
,
267 static const struct hwmon_ops mlxreg_fan_hwmon_hwmon_ops
= {
268 .is_visible
= mlxreg_fan_is_visible
,
269 .read
= mlxreg_fan_read
,
270 .write
= mlxreg_fan_write
,
273 static const struct hwmon_chip_info mlxreg_fan_hwmon_chip_info
= {
274 .ops
= &mlxreg_fan_hwmon_hwmon_ops
,
275 .info
= mlxreg_fan_hwmon_info
,
278 static int mlxreg_fan_get_max_state(struct thermal_cooling_device
*cdev
,
279 unsigned long *state
)
281 *state
= MLXREG_FAN_MAX_STATE
;
285 static int mlxreg_fan_get_cur_state(struct thermal_cooling_device
*cdev
,
286 unsigned long *state
)
289 struct mlxreg_fan
*fan
= cdev
->devdata
;
293 err
= regmap_read(fan
->regmap
, fan
->pwm
.reg
, ®val
);
295 dev_err(fan
->dev
, "Failed to query PWM duty\n");
299 *state
= MLXREG_FAN_PWM_DUTY2STATE(regval
);
304 static int mlxreg_fan_set_cur_state(struct thermal_cooling_device
*cdev
,
308 struct mlxreg_fan
*fan
= cdev
->devdata
;
309 unsigned long cur_state
;
315 * Verify if this request is for changing allowed FAN dynamical
316 * minimum. If it is - update cooling levels accordingly and update
317 * state, if current state is below the newly requested minimum state.
318 * For example, if current state is 5, and minimal state is to be
319 * changed from 4 to 6, fan->cooling_levels[0 to 5] will be changed all
320 * from 4 to 6. And state 5 (fan->cooling_levels[4]) should be
323 if (state
>= MLXREG_FAN_SPEED_MIN
&& state
<= MLXREG_FAN_SPEED_MAX
) {
324 state
-= MLXREG_FAN_MAX_STATE
;
325 for (i
= 0; i
< state
; i
++)
326 fan
->cooling_levels
[i
] = state
;
327 for (i
= state
; i
<= MLXREG_FAN_MAX_STATE
; i
++)
328 fan
->cooling_levels
[i
] = i
;
330 err
= regmap_read(fan
->regmap
, fan
->pwm
.reg
, ®val
);
332 dev_err(fan
->dev
, "Failed to query PWM duty\n");
336 cur_state
= MLXREG_FAN_PWM_DUTY2STATE(regval
);
337 if (state
< cur_state
)
343 if (state
> MLXREG_FAN_MAX_STATE
)
346 /* Normalize the state to the valid speed range. */
347 state
= fan
->cooling_levels
[state
];
348 err
= regmap_write(fan
->regmap
, fan
->pwm
.reg
,
349 MLXREG_FAN_PWM_STATE2DUTY(state
));
351 dev_err(fan
->dev
, "Failed to write PWM duty\n");
357 static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops
= {
358 .get_max_state
= mlxreg_fan_get_max_state
,
359 .get_cur_state
= mlxreg_fan_get_cur_state
,
360 .set_cur_state
= mlxreg_fan_set_cur_state
,
363 static int mlxreg_fan_config(struct mlxreg_fan
*fan
,
364 struct mlxreg_core_platform_data
*pdata
)
366 struct mlxreg_core_data
*data
= pdata
->data
;
367 bool configured
= false;
368 int tacho_num
= 0, i
;
370 fan
->samples
= MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF
;
371 fan
->divider
= MLXREG_FAN_TACHO_DIVIDER_DEF
;
372 for (i
= 0; i
< pdata
->counter
; i
++, data
++) {
373 if (strnstr(data
->label
, "tacho", sizeof(data
->label
))) {
374 if (tacho_num
== MLXREG_FAN_MAX_TACHO
) {
375 dev_err(fan
->dev
, "too many tacho entries: %s\n",
379 fan
->tacho
[tacho_num
].reg
= data
->reg
;
380 fan
->tacho
[tacho_num
].mask
= data
->mask
;
381 fan
->tacho
[tacho_num
++].connected
= true;
382 } else if (strnstr(data
->label
, "pwm", sizeof(data
->label
))) {
383 if (fan
->pwm
.connected
) {
384 dev_err(fan
->dev
, "duplicate pwm entry: %s\n",
388 fan
->pwm
.reg
= data
->reg
;
389 fan
->pwm
.connected
= true;
390 } else if (strnstr(data
->label
, "conf", sizeof(data
->label
))) {
392 dev_err(fan
->dev
, "duplicate conf entry: %s\n",
396 /* Validate that conf parameters are not zeros. */
397 if (!data
->mask
|| !data
->bit
) {
398 dev_err(fan
->dev
, "invalid conf entry params: %s\n",
402 fan
->samples
= data
->mask
;
403 fan
->divider
= data
->bit
;
406 dev_err(fan
->dev
, "invalid label: %s\n", data
->label
);
411 /* Init cooling levels per PWM state. */
412 for (i
= 0; i
< MLXREG_FAN_SPEED_MIN_LEVEL
; i
++)
413 fan
->cooling_levels
[i
] = MLXREG_FAN_SPEED_MIN_LEVEL
;
414 for (i
= MLXREG_FAN_SPEED_MIN_LEVEL
; i
<= MLXREG_FAN_MAX_STATE
; i
++)
415 fan
->cooling_levels
[i
] = i
;
420 static int mlxreg_fan_probe(struct platform_device
*pdev
)
422 struct mlxreg_core_platform_data
*pdata
;
423 struct mlxreg_fan
*fan
;
427 pdata
= dev_get_platdata(&pdev
->dev
);
429 dev_err(&pdev
->dev
, "Failed to get platform data.\n");
433 fan
= devm_kzalloc(&pdev
->dev
, sizeof(*fan
), GFP_KERNEL
);
437 fan
->dev
= &pdev
->dev
;
438 fan
->regmap
= pdata
->regmap
;
439 platform_set_drvdata(pdev
, fan
);
441 err
= mlxreg_fan_config(fan
, pdata
);
445 hwm
= devm_hwmon_device_register_with_info(&pdev
->dev
, "mlxreg_fan",
447 &mlxreg_fan_hwmon_chip_info
,
450 dev_err(&pdev
->dev
, "Failed to register hwmon device\n");
454 if (IS_REACHABLE(CONFIG_THERMAL
)) {
455 fan
->cdev
= thermal_cooling_device_register("mlxreg_fan", fan
,
456 &mlxreg_fan_cooling_ops
);
457 if (IS_ERR(fan
->cdev
)) {
458 dev_err(&pdev
->dev
, "Failed to register cooling device\n");
459 return PTR_ERR(fan
->cdev
);
466 static int mlxreg_fan_remove(struct platform_device
*pdev
)
468 struct mlxreg_fan
*fan
= platform_get_drvdata(pdev
);
470 if (IS_REACHABLE(CONFIG_THERMAL
))
471 thermal_cooling_device_unregister(fan
->cdev
);
476 static struct platform_driver mlxreg_fan_driver
= {
478 .name
= "mlxreg-fan",
480 .probe
= mlxreg_fan_probe
,
481 .remove
= mlxreg_fan_remove
,
484 module_platform_driver(mlxreg_fan_driver
);
486 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
487 MODULE_DESCRIPTION("Mellanox FAN driver");
488 MODULE_LICENSE("GPL");
489 MODULE_ALIAS("platform:mlxreg-fan");