GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / hwmon / mlxreg-fan.c
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_DIVIDER_DEF            1132
31 /*
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).
51  */
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,          \
57                                          MLXREG_FAN_MAX_DUTY))
58 #define MLXREG_FAN_PWM_STATE2DUTY(stat) (DIV_ROUND_CLOSEST((stat) *     \
59                                          MLXREG_FAN_MAX_DUTY,           \
60                                          MLXREG_FAN_MAX_STATE))
61
62 /*
63  * struct mlxreg_fan_tacho - tachometer data (internal use):
64  *
65  * @connected: indicates if tachometer is connected;
66  * @reg: register offset;
67  * @mask: fault mask;
68  */
69 struct mlxreg_fan_tacho {
70         bool connected;
71         u32 reg;
72         u32 mask;
73 };
74
75 /*
76  * struct mlxreg_fan_pwm - PWM data (internal use):
77  *
78  * @connected: indicates if PWM is connected;
79  * @reg: register offset;
80  */
81 struct mlxreg_fan_pwm {
82         bool connected;
83         u32 reg;
84 };
85
86 /*
87  * struct mlxreg_fan - private data (internal use):
88  *
89  * @dev: basic device;
90  * @regmap: register map of parent device;
91  * @tacho: tachometer data;
92  * @pwm: PWM 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;
97  */
98 struct mlxreg_fan {
99         struct device *dev;
100         void *regmap;
101         struct mlxreg_core_platform_data *pdata;
102         struct mlxreg_fan_tacho tacho[MLXREG_FAN_MAX_TACHO];
103         struct mlxreg_fan_pwm pwm;
104         int samples;
105         int divider;
106         u8 cooling_levels[MLXREG_FAN_MAX_STATE + 1];
107         struct thermal_cooling_device *cdev;
108 };
109
110 static int
111 mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
112                 int channel, long *val)
113 {
114         struct mlxreg_fan *fan = dev_get_drvdata(dev);
115         struct mlxreg_fan_tacho *tacho;
116         u32 regval;
117         int err;
118
119         switch (type) {
120         case hwmon_fan:
121                 tacho = &fan->tacho[channel];
122                 switch (attr) {
123                 case hwmon_fan_input:
124                         err = regmap_read(fan->regmap, tacho->reg, &regval);
125                         if (err)
126                                 return err;
127
128                         if (MLXREG_FAN_GET_FAULT(regval, tacho->mask)) {
129                                 /* FAN is broken - return zero for FAN speed. */
130                                 *val = 0;
131                                 return 0;
132                         }
133
134                         *val = MLXREG_FAN_GET_RPM(regval, fan->divider,
135                                                   fan->samples);
136                         break;
137
138                 case hwmon_fan_fault:
139                         err = regmap_read(fan->regmap, tacho->reg, &regval);
140                         if (err)
141                                 return err;
142
143                         *val = MLXREG_FAN_GET_FAULT(regval, tacho->mask);
144                         break;
145
146                 default:
147                         return -EOPNOTSUPP;
148                 }
149                 break;
150
151         case hwmon_pwm:
152                 switch (attr) {
153                 case hwmon_pwm_input:
154                         err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
155                         if (err)
156                                 return err;
157
158                         *val = regval;
159                         break;
160
161                 default:
162                         return -EOPNOTSUPP;
163                 }
164                 break;
165
166         default:
167                 return -EOPNOTSUPP;
168         }
169
170         return 0;
171 }
172
173 static int
174 mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
175                  int channel, long val)
176 {
177         struct mlxreg_fan *fan = dev_get_drvdata(dev);
178
179         switch (type) {
180         case hwmon_pwm:
181                 switch (attr) {
182                 case hwmon_pwm_input:
183                         if (val < MLXREG_FAN_MIN_DUTY ||
184                             val > MLXREG_FAN_MAX_DUTY)
185                                 return -EINVAL;
186                         return regmap_write(fan->regmap, fan->pwm.reg, val);
187                 default:
188                         return -EOPNOTSUPP;
189                 }
190                 break;
191
192         default:
193                 return -EOPNOTSUPP;
194         }
195
196         return -EOPNOTSUPP;
197 }
198
199 static umode_t
200 mlxreg_fan_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
201                       int channel)
202 {
203         switch (type) {
204         case hwmon_fan:
205                 if (!(((struct mlxreg_fan *)data)->tacho[channel].connected))
206                         return 0;
207
208                 switch (attr) {
209                 case hwmon_fan_input:
210                 case hwmon_fan_fault:
211                         return 0444;
212                 default:
213                         break;
214                 }
215                 break;
216
217         case hwmon_pwm:
218                 if (!(((struct mlxreg_fan *)data)->pwm.connected))
219                         return 0;
220
221                 switch (attr) {
222                 case hwmon_pwm_input:
223                         return 0644;
224                 default:
225                         break;
226                 }
227                 break;
228
229         default:
230                 break;
231         }
232
233         return 0;
234 }
235
236 static const u32 mlxreg_fan_hwmon_fan_config[] = {
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,
243         HWMON_F_INPUT | HWMON_F_FAULT,
244         HWMON_F_INPUT | HWMON_F_FAULT,
245         HWMON_F_INPUT | HWMON_F_FAULT,
246         HWMON_F_INPUT | HWMON_F_FAULT,
247         HWMON_F_INPUT | HWMON_F_FAULT,
248         HWMON_F_INPUT | HWMON_F_FAULT,
249         0
250 };
251
252 static const struct hwmon_channel_info mlxreg_fan_hwmon_fan = {
253         .type = hwmon_fan,
254         .config = mlxreg_fan_hwmon_fan_config,
255 };
256
257 static const u32 mlxreg_fan_hwmon_pwm_config[] = {
258         HWMON_PWM_INPUT,
259         0
260 };
261
262 static const struct hwmon_channel_info mlxreg_fan_hwmon_pwm = {
263         .type = hwmon_pwm,
264         .config = mlxreg_fan_hwmon_pwm_config,
265 };
266
267 static const struct hwmon_channel_info *mlxreg_fan_hwmon_info[] = {
268         &mlxreg_fan_hwmon_fan,
269         &mlxreg_fan_hwmon_pwm,
270         NULL
271 };
272
273 static const struct hwmon_ops mlxreg_fan_hwmon_hwmon_ops = {
274         .is_visible = mlxreg_fan_is_visible,
275         .read = mlxreg_fan_read,
276         .write = mlxreg_fan_write,
277 };
278
279 static const struct hwmon_chip_info mlxreg_fan_hwmon_chip_info = {
280         .ops = &mlxreg_fan_hwmon_hwmon_ops,
281         .info = mlxreg_fan_hwmon_info,
282 };
283
284 static int mlxreg_fan_get_max_state(struct thermal_cooling_device *cdev,
285                                     unsigned long *state)
286 {
287         *state = MLXREG_FAN_MAX_STATE;
288         return 0;
289 }
290
291 static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev,
292                                     unsigned long *state)
293
294 {
295         struct mlxreg_fan *fan = cdev->devdata;
296         u32 regval;
297         int err;
298
299         err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
300         if (err) {
301                 dev_err(fan->dev, "Failed to query PWM duty\n");
302                 return err;
303         }
304
305         *state = MLXREG_FAN_PWM_DUTY2STATE(regval);
306
307         return 0;
308 }
309
310 static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
311                                     unsigned long state)
312
313 {
314         struct mlxreg_fan *fan = cdev->devdata;
315         unsigned long cur_state;
316         int i, config = 0;
317         u32 regval;
318         int err;
319
320         /*
321          * Verify if this request is for changing allowed FAN dynamical
322          * minimum. If it is - update cooling levels accordingly and update
323          * state, if current state is below the newly requested minimum state.
324          * For example, if current state is 5, and minimal state is to be
325          * changed from 4 to 6, fan->cooling_levels[0 to 5] will be changed all
326          * from 4 to 6. And state 5 (fan->cooling_levels[4]) should be
327          * overwritten.
328          */
329         if (state >= MLXREG_FAN_SPEED_MIN && state <= MLXREG_FAN_SPEED_MAX) {
330                 /*
331                  * This is configuration change, which is only supported through sysfs.
332                  * For configuration non-zero value is to be returned to avoid thermal
333                  * statistics update.
334                  */
335                 config = 1;
336                 state -= MLXREG_FAN_MAX_STATE;
337                 for (i = 0; i < state; i++)
338                         fan->cooling_levels[i] = state;
339                 for (i = state; i <= MLXREG_FAN_MAX_STATE; i++)
340                         fan->cooling_levels[i] = i;
341
342                 err = regmap_read(fan->regmap, fan->pwm.reg, &regval);
343                 if (err) {
344                         dev_err(fan->dev, "Failed to query PWM duty\n");
345                         return err;
346                 }
347
348                 cur_state = MLXREG_FAN_PWM_DUTY2STATE(regval);
349                 if (state < cur_state)
350                         return config;
351
352                 state = cur_state;
353         }
354
355         if (state > MLXREG_FAN_MAX_STATE)
356                 return -EINVAL;
357
358         /* Normalize the state to the valid speed range. */
359         state = fan->cooling_levels[state];
360         err = regmap_write(fan->regmap, fan->pwm.reg,
361                            MLXREG_FAN_PWM_STATE2DUTY(state));
362         if (err) {
363                 dev_err(fan->dev, "Failed to write PWM duty\n");
364                 return err;
365         }
366         return config;
367 }
368
369 static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = {
370         .get_max_state  = mlxreg_fan_get_max_state,
371         .get_cur_state  = mlxreg_fan_get_cur_state,
372         .set_cur_state  = mlxreg_fan_set_cur_state,
373 };
374
375 static int mlxreg_fan_config(struct mlxreg_fan *fan,
376                              struct mlxreg_core_platform_data *pdata)
377 {
378         struct mlxreg_core_data *data = pdata->data;
379         bool configured = false;
380         int tacho_num = 0, i;
381
382         fan->samples = MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF;
383         fan->divider = MLXREG_FAN_TACHO_DIVIDER_DEF;
384         for (i = 0; i < pdata->counter; i++, data++) {
385                 if (strnstr(data->label, "tacho", sizeof(data->label))) {
386                         if (tacho_num == MLXREG_FAN_MAX_TACHO) {
387                                 dev_err(fan->dev, "too many tacho entries: %s\n",
388                                         data->label);
389                                 return -EINVAL;
390                         }
391                         fan->tacho[tacho_num].reg = data->reg;
392                         fan->tacho[tacho_num].mask = data->mask;
393                         fan->tacho[tacho_num++].connected = true;
394                 } else if (strnstr(data->label, "pwm", sizeof(data->label))) {
395                         if (fan->pwm.connected) {
396                                 dev_err(fan->dev, "duplicate pwm entry: %s\n",
397                                         data->label);
398                                 return -EINVAL;
399                         }
400                         fan->pwm.reg = data->reg;
401                         fan->pwm.connected = true;
402                 } else if (strnstr(data->label, "conf", sizeof(data->label))) {
403                         if (configured) {
404                                 dev_err(fan->dev, "duplicate conf entry: %s\n",
405                                         data->label);
406                                 return -EINVAL;
407                         }
408                         /* Validate that conf parameters are not zeros. */
409                         if (!data->mask || !data->bit) {
410                                 dev_err(fan->dev, "invalid conf entry params: %s\n",
411                                         data->label);
412                                 return -EINVAL;
413                         }
414                         fan->samples = data->mask;
415                         fan->divider = data->bit;
416                         configured = true;
417                 } else {
418                         dev_err(fan->dev, "invalid label: %s\n", data->label);
419                         return -EINVAL;
420                 }
421         }
422
423         /* Init cooling levels per PWM state. */
424         for (i = 0; i < MLXREG_FAN_SPEED_MIN_LEVEL; i++)
425                 fan->cooling_levels[i] = MLXREG_FAN_SPEED_MIN_LEVEL;
426         for (i = MLXREG_FAN_SPEED_MIN_LEVEL; i <= MLXREG_FAN_MAX_STATE; i++)
427                 fan->cooling_levels[i] = i;
428
429         return 0;
430 }
431
432 static int mlxreg_fan_probe(struct platform_device *pdev)
433 {
434         struct mlxreg_core_platform_data *pdata;
435         struct mlxreg_fan *fan;
436         struct device *hwm;
437         int err;
438
439         pdata = dev_get_platdata(&pdev->dev);
440         if (!pdata) {
441                 dev_err(&pdev->dev, "Failed to get platform data.\n");
442                 return -EINVAL;
443         }
444
445         fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
446         if (!fan)
447                 return -ENOMEM;
448
449         fan->dev = &pdev->dev;
450         fan->regmap = pdata->regmap;
451         platform_set_drvdata(pdev, fan);
452
453         err = mlxreg_fan_config(fan, pdata);
454         if (err)
455                 return err;
456
457         hwm = devm_hwmon_device_register_with_info(&pdev->dev, "mlxreg_fan",
458                                                    fan,
459                                                    &mlxreg_fan_hwmon_chip_info,
460                                                    NULL);
461         if (IS_ERR(hwm)) {
462                 dev_err(&pdev->dev, "Failed to register hwmon device\n");
463                 return PTR_ERR(hwm);
464         }
465
466         if (IS_REACHABLE(CONFIG_THERMAL)) {
467                 fan->cdev = thermal_cooling_device_register("mlxreg_fan", fan,
468                                                 &mlxreg_fan_cooling_ops);
469                 if (IS_ERR(fan->cdev)) {
470                         dev_err(&pdev->dev, "Failed to register cooling device\n");
471                         return PTR_ERR(fan->cdev);
472                 }
473         }
474
475         return 0;
476 }
477
478 static int mlxreg_fan_remove(struct platform_device *pdev)
479 {
480         struct mlxreg_fan *fan = platform_get_drvdata(pdev);
481
482         if (IS_REACHABLE(CONFIG_THERMAL))
483                 thermal_cooling_device_unregister(fan->cdev);
484
485         return 0;
486 }
487
488 static struct platform_driver mlxreg_fan_driver = {
489         .driver = {
490             .name = "mlxreg-fan",
491         },
492         .probe = mlxreg_fan_probe,
493         .remove = mlxreg_fan_remove,
494 };
495
496 module_platform_driver(mlxreg_fan_driver);
497
498 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
499 MODULE_DESCRIPTION("Mellanox FAN driver");
500 MODULE_LICENSE("GPL");
501 MODULE_ALIAS("platform:mlxreg-fan");