forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/hwmon/mlxreg-fan.c
....@@ -27,7 +27,9 @@
2727 #define MLXREG_FAN_SPEED_MAX (MLXREG_FAN_MAX_STATE * 2)
2828 #define MLXREG_FAN_SPEED_MIN_LEVEL 2 /* 20 percent */
2929 #define MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF 44
30
-#define MLXREG_FAN_TACHO_DIVIDER_DEF 1132
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
3133 /*
3234 * FAN datasheet defines the formula for RPM calculations as RPM = 15/t-high.
3335 * The logic in a programmable device measures the time t-high by sampling the
....@@ -51,7 +53,7 @@
5153 */
5254 #define MLXREG_FAN_GET_RPM(rval, d, s) (DIV_ROUND_CLOSEST(15000000 * 100, \
5355 ((rval) + (s)) * (d)))
54
-#define MLXREG_FAN_GET_FAULT(val, mask) (!((val) ^ (mask)))
56
+#define MLXREG_FAN_GET_FAULT(val, mask) ((val) == (mask))
5557 #define MLXREG_FAN_PWM_DUTY2STATE(duty) (DIV_ROUND_CLOSEST((duty) * \
5658 MLXREG_FAN_MAX_STATE, \
5759 MLXREG_FAN_MAX_DUTY))
....@@ -227,40 +229,22 @@
227229 return 0;
228230 }
229231
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,
243
- 0
244
-};
245
-
246
-static const struct hwmon_channel_info mlxreg_fan_hwmon_fan = {
247
- .type = hwmon_fan,
248
- .config = mlxreg_fan_hwmon_fan_config,
249
-};
250
-
251
-static const u32 mlxreg_fan_hwmon_pwm_config[] = {
252
- HWMON_PWM_INPUT,
253
- 0
254
-};
255
-
256
-static const struct hwmon_channel_info mlxreg_fan_hwmon_pwm = {
257
- .type = hwmon_pwm,
258
- .config = mlxreg_fan_hwmon_pwm_config,
259
-};
260
-
261232 static const struct hwmon_channel_info *mlxreg_fan_hwmon_info[] = {
262
- &mlxreg_fan_hwmon_fan,
263
- &mlxreg_fan_hwmon_pwm,
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),
264248 NULL
265249 };
266250
....@@ -366,15 +350,57 @@
366350 .set_cur_state = mlxreg_fan_set_cur_state,
367351 };
368352
353
+static int mlxreg_fan_connect_verify(struct mlxreg_fan *fan,
354
+ struct mlxreg_core_data *data)
355
+{
356
+ u32 regval;
357
+ int err;
358
+
359
+ err = regmap_read(fan->regmap, data->capability, &regval);
360
+ if (err) {
361
+ dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
362
+ data->capability);
363
+ return err;
364
+ }
365
+
366
+ return !!(regval & data->bit);
367
+}
368
+
369
+static int mlxreg_fan_speed_divider_get(struct mlxreg_fan *fan,
370
+ struct mlxreg_core_data *data)
371
+{
372
+ u32 regval;
373
+ int err;
374
+
375
+ err = regmap_read(fan->regmap, data->capability, &regval);
376
+ if (err) {
377
+ dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
378
+ data->capability);
379
+ return err;
380
+ }
381
+
382
+ /*
383
+ * Set divider value according to the capability register, in case it
384
+ * contains valid value. Otherwise use default value. The purpose of
385
+ * this validation is to protect against the old hardware, in which
386
+ * this register can return zero.
387
+ */
388
+ if (regval > 0 && regval <= MLXREG_FAN_TACHO_DIV_SCALE_MAX)
389
+ fan->divider = regval * MLXREG_FAN_TACHO_DIV_MIN;
390
+
391
+ return 0;
392
+}
393
+
369394 static int mlxreg_fan_config(struct mlxreg_fan *fan,
370395 struct mlxreg_core_platform_data *pdata)
371396 {
372397 struct mlxreg_core_data *data = pdata->data;
373398 bool configured = false;
374399 int tacho_num = 0, i;
400
+ int err;
375401
376402 fan->samples = MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF;
377
- fan->divider = MLXREG_FAN_TACHO_DIVIDER_DEF;
403
+ fan->divider = MLXREG_FAN_TACHO_DIV_DEF;
378404 for (i = 0; i < pdata->counter; i++, data++) {
379405 if (strnstr(data->label, "tacho", sizeof(data->label))) {
380406 if (tacho_num == MLXREG_FAN_MAX_TACHO) {
....@@ -382,6 +408,17 @@
382408 data->label);
383409 return -EINVAL;
384410 }
411
+
412
+ if (data->capability) {
413
+ err = mlxreg_fan_connect_verify(fan, data);
414
+ if (err < 0)
415
+ return err;
416
+ else if (!err) {
417
+ tacho_num++;
418
+ continue;
419
+ }
420
+ }
421
+
385422 fan->tacho[tacho_num].reg = data->reg;
386423 fan->tacho[tacho_num].mask = data->mask;
387424 fan->tacho[tacho_num++].connected = true;
....@@ -400,13 +437,21 @@
400437 return -EINVAL;
401438 }
402439 /* Validate that conf parameters are not zeros. */
403
- if (!data->mask || !data->bit) {
440
+ if (!data->mask && !data->bit && !data->capability) {
404441 dev_err(fan->dev, "invalid conf entry params: %s\n",
405442 data->label);
406443 return -EINVAL;
407444 }
408
- fan->samples = data->mask;
409
- fan->divider = data->bit;
445
+ if (data->capability) {
446
+ err = mlxreg_fan_speed_divider_get(fan, data);
447
+ if (err)
448
+ return err;
449
+ } else {
450
+ if (data->mask)
451
+ fan->samples = data->mask;
452
+ if (data->bit)
453
+ fan->divider = data->bit;
454
+ }
410455 configured = true;
411456 } else {
412457 dev_err(fan->dev, "invalid label: %s\n", data->label);
....@@ -426,55 +471,45 @@
426471 static int mlxreg_fan_probe(struct platform_device *pdev)
427472 {
428473 struct mlxreg_core_platform_data *pdata;
474
+ struct device *dev = &pdev->dev;
429475 struct mlxreg_fan *fan;
430476 struct device *hwm;
431477 int err;
432478
433
- pdata = dev_get_platdata(&pdev->dev);
479
+ pdata = dev_get_platdata(dev);
434480 if (!pdata) {
435
- dev_err(&pdev->dev, "Failed to get platform data.\n");
481
+ dev_err(dev, "Failed to get platform data.\n");
436482 return -EINVAL;
437483 }
438484
439
- fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
485
+ fan = devm_kzalloc(dev, sizeof(*fan), GFP_KERNEL);
440486 if (!fan)
441487 return -ENOMEM;
442488
443
- fan->dev = &pdev->dev;
489
+ fan->dev = dev;
444490 fan->regmap = pdata->regmap;
445
- platform_set_drvdata(pdev, fan);
446491
447492 err = mlxreg_fan_config(fan, pdata);
448493 if (err)
449494 return err;
450495
451
- hwm = devm_hwmon_device_register_with_info(&pdev->dev, "mlxreg_fan",
496
+ hwm = devm_hwmon_device_register_with_info(dev, "mlxreg_fan",
452497 fan,
453498 &mlxreg_fan_hwmon_chip_info,
454499 NULL);
455500 if (IS_ERR(hwm)) {
456
- dev_err(&pdev->dev, "Failed to register hwmon device\n");
501
+ dev_err(dev, "Failed to register hwmon device\n");
457502 return PTR_ERR(hwm);
458503 }
459504
460505 if (IS_REACHABLE(CONFIG_THERMAL)) {
461
- fan->cdev = thermal_cooling_device_register("mlxreg_fan", fan,
462
- &mlxreg_fan_cooling_ops);
506
+ fan->cdev = devm_thermal_of_cooling_device_register(dev,
507
+ NULL, "mlxreg_fan", fan, &mlxreg_fan_cooling_ops);
463508 if (IS_ERR(fan->cdev)) {
464
- dev_err(&pdev->dev, "Failed to register cooling device\n");
509
+ dev_err(dev, "Failed to register cooling device\n");
465510 return PTR_ERR(fan->cdev);
466511 }
467512 }
468
-
469
- return 0;
470
-}
471
-
472
-static int mlxreg_fan_remove(struct platform_device *pdev)
473
-{
474
- struct mlxreg_fan *fan = platform_get_drvdata(pdev);
475
-
476
- if (IS_REACHABLE(CONFIG_THERMAL))
477
- thermal_cooling_device_unregister(fan->cdev);
478513
479514 return 0;
480515 }
....@@ -484,7 +519,6 @@
484519 .name = "mlxreg-fan",
485520 },
486521 .probe = mlxreg_fan_probe,
487
- .remove = mlxreg_fan_remove,
488522 };
489523
490524 module_platform_driver(mlxreg_fan_driver);