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