Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
0002 //
0003 // Copyright (c) 2018 Mellanox Technologies. All rights reserved.
0004 // Copyright (c) 2018 Vadim Pasternak <vadimp@mellanox.com>
0005 
0006 #include <linux/bitops.h>
0007 #include <linux/device.h>
0008 #include <linux/hwmon.h>
0009 #include <linux/module.h>
0010 #include <linux/platform_data/mlxreg.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/regmap.h>
0013 #include <linux/thermal.h>
0014 
0015 #define MLXREG_FAN_MAX_TACHO        14
0016 #define MLXREG_FAN_MAX_PWM      4
0017 #define MLXREG_FAN_PWM_NOT_CONNECTED    0xff
0018 #define MLXREG_FAN_MAX_STATE        10
0019 #define MLXREG_FAN_MIN_DUTY     51  /* 20% */
0020 #define MLXREG_FAN_MAX_DUTY     255 /* 100% */
0021 #define MLXREG_FAN_SPEED_MIN_LEVEL      2   /* 20 percent */
0022 #define MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF  44
0023 #define MLXREG_FAN_TACHO_DIV_MIN        283
0024 #define MLXREG_FAN_TACHO_DIV_DEF        (MLXREG_FAN_TACHO_DIV_MIN * 4)
0025 #define MLXREG_FAN_TACHO_DIV_SCALE_MAX  64
0026 /*
0027  * FAN datasheet defines the formula for RPM calculations as RPM = 15/t-high.
0028  * The logic in a programmable device measures the time t-high by sampling the
0029  * tachometer every t-sample (with the default value 11.32 uS) and increment
0030  * a counter (N) as long as the pulse has not change:
0031  * RPM = 15 / (t-sample * (K + Regval)), where:
0032  * Regval: is the value read from the programmable device register;
0033  *  - 0xff - represents tachometer fault;
0034  *  - 0xfe - represents tachometer minimum value , which is 4444 RPM;
0035  *  - 0x00 - represents tachometer maximum value , which is 300000 RPM;
0036  * K: is 44 and it represents the minimum allowed samples per pulse;
0037  * N: is equal K + Regval;
0038  * In order to calculate RPM from the register value the following formula is
0039  * used: RPM = 15 / ((Regval + K) * 11.32) * 10^(-6)), which in  the
0040  * default case is modified to:
0041  * RPM = 15000000 * 100 / ((Regval + 44) * 1132);
0042  * - for Regval 0x00, RPM will be 15000000 * 100 / (44 * 1132) = 30115;
0043  * - for Regval 0xfe, RPM will be 15000000 * 100 / ((254 + 44) * 1132) = 4446;
0044  * In common case the formula is modified to:
0045  * RPM = 15000000 * 100 / ((Regval + samples) * divider).
0046  */
0047 #define MLXREG_FAN_GET_RPM(rval, d, s)  (DIV_ROUND_CLOSEST(15000000 * 100, \
0048                      ((rval) + (s)) * (d)))
0049 #define MLXREG_FAN_GET_FAULT(val, mask) ((val) == (mask))
0050 #define MLXREG_FAN_PWM_DUTY2STATE(duty) (DIV_ROUND_CLOSEST((duty) * \
0051                      MLXREG_FAN_MAX_STATE,      \
0052                      MLXREG_FAN_MAX_DUTY))
0053 #define MLXREG_FAN_PWM_STATE2DUTY(stat) (DIV_ROUND_CLOSEST((stat) * \
0054                      MLXREG_FAN_MAX_DUTY,       \
0055                      MLXREG_FAN_MAX_STATE))
0056 
0057 struct mlxreg_fan;
0058 
0059 /*
0060  * struct mlxreg_fan_tacho - tachometer data (internal use):
0061  *
0062  * @connected: indicates if tachometer is connected;
0063  * @reg: register offset;
0064  * @mask: fault mask;
0065  * @prsnt: present register offset;
0066  */
0067 struct mlxreg_fan_tacho {
0068     bool connected;
0069     u32 reg;
0070     u32 mask;
0071     u32 prsnt;
0072 };
0073 
0074 /*
0075  * struct mlxreg_fan_pwm - PWM data (internal use):
0076  *
0077  * @fan: private data;
0078  * @connected: indicates if PWM is connected;
0079  * @reg: register offset;
0080  * @cooling: cooling device levels;
0081  * @last_hwmon_state: last cooling state set by hwmon subsystem;
0082  * @last_thermal_state: last cooling state set by thermal subsystem;
0083  * @cdev: cooling device;
0084  */
0085 struct mlxreg_fan_pwm {
0086     struct mlxreg_fan *fan;
0087     bool connected;
0088     u32 reg;
0089     unsigned long last_hwmon_state;
0090     unsigned long last_thermal_state;
0091     struct thermal_cooling_device *cdev;
0092 };
0093 
0094 /*
0095  * struct mlxreg_fan - private data (internal use):
0096  *
0097  * @dev: basic device;
0098  * @regmap: register map of parent device;
0099  * @tacho: tachometer data;
0100  * @pwm: PWM data;
0101  * @tachos_per_drwr - number of tachometers per drawer;
0102  * @samples: minimum allowed samples per pulse;
0103  * @divider: divider value for tachometer RPM calculation;
0104  */
0105 struct mlxreg_fan {
0106     struct device *dev;
0107     void *regmap;
0108     struct mlxreg_core_platform_data *pdata;
0109     struct mlxreg_fan_tacho tacho[MLXREG_FAN_MAX_TACHO];
0110     struct mlxreg_fan_pwm pwm[MLXREG_FAN_MAX_PWM];
0111     int tachos_per_drwr;
0112     int samples;
0113     int divider;
0114 };
0115 
0116 static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
0117                     unsigned long state);
0118 
0119 static int
0120 mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
0121         int channel, long *val)
0122 {
0123     struct mlxreg_fan *fan = dev_get_drvdata(dev);
0124     struct mlxreg_fan_tacho *tacho;
0125     struct mlxreg_fan_pwm *pwm;
0126     u32 regval;
0127     int err;
0128 
0129     switch (type) {
0130     case hwmon_fan:
0131         tacho = &fan->tacho[channel];
0132         switch (attr) {
0133         case hwmon_fan_input:
0134             /*
0135              * Check FAN presence: FAN related bit in presence register is one,
0136              * if FAN is physically connected, zero - otherwise.
0137              */
0138             if (tacho->prsnt && fan->tachos_per_drwr) {
0139                 err = regmap_read(fan->regmap, tacho->prsnt, &regval);
0140                 if (err)
0141                     return err;
0142 
0143                 /*
0144                  * Map channel to presence bit - drawer can be equipped with
0145                  * one or few FANs, while presence is indicated per drawer.
0146                  */
0147                 if (BIT(channel / fan->tachos_per_drwr) & regval) {
0148                     /* FAN is not connected - return zero for FAN speed. */
0149                     *val = 0;
0150                     return 0;
0151                 }
0152             }
0153 
0154             err = regmap_read(fan->regmap, tacho->reg, &regval);
0155             if (err)
0156                 return err;
0157 
0158             *val = MLXREG_FAN_GET_RPM(regval, fan->divider,
0159                           fan->samples);
0160             break;
0161 
0162         case hwmon_fan_fault:
0163             err = regmap_read(fan->regmap, tacho->reg, &regval);
0164             if (err)
0165                 return err;
0166 
0167             *val = MLXREG_FAN_GET_FAULT(regval, tacho->mask);
0168             break;
0169 
0170         default:
0171             return -EOPNOTSUPP;
0172         }
0173         break;
0174 
0175     case hwmon_pwm:
0176         pwm = &fan->pwm[channel];
0177         switch (attr) {
0178         case hwmon_pwm_input:
0179             err = regmap_read(fan->regmap, pwm->reg, &regval);
0180             if (err)
0181                 return err;
0182 
0183             *val = regval;
0184             break;
0185 
0186         default:
0187             return -EOPNOTSUPP;
0188         }
0189         break;
0190 
0191     default:
0192         return -EOPNOTSUPP;
0193     }
0194 
0195     return 0;
0196 }
0197 
0198 static int
0199 mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
0200          int channel, long val)
0201 {
0202     struct mlxreg_fan *fan = dev_get_drvdata(dev);
0203     struct mlxreg_fan_pwm *pwm;
0204 
0205     switch (type) {
0206     case hwmon_pwm:
0207         switch (attr) {
0208         case hwmon_pwm_input:
0209             if (val < MLXREG_FAN_MIN_DUTY ||
0210                 val > MLXREG_FAN_MAX_DUTY)
0211                 return -EINVAL;
0212             pwm = &fan->pwm[channel];
0213             /* If thermal is configured - handle PWM limit setting. */
0214             if (IS_REACHABLE(CONFIG_THERMAL)) {
0215                 pwm->last_hwmon_state = MLXREG_FAN_PWM_DUTY2STATE(val);
0216                 /*
0217                  * Update PWM only in case requested state is not less than the
0218                  * last thermal state.
0219                  */
0220                 if (pwm->last_hwmon_state >= pwm->last_thermal_state)
0221                     return mlxreg_fan_set_cur_state(pwm->cdev,
0222                                     pwm->last_hwmon_state);
0223                 return 0;
0224             }
0225             return regmap_write(fan->regmap, pwm->reg, val);
0226         default:
0227             return -EOPNOTSUPP;
0228         }
0229         break;
0230 
0231     default:
0232         return -EOPNOTSUPP;
0233     }
0234 
0235     return -EOPNOTSUPP;
0236 }
0237 
0238 static umode_t
0239 mlxreg_fan_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
0240               int channel)
0241 {
0242     switch (type) {
0243     case hwmon_fan:
0244         if (!(((struct mlxreg_fan *)data)->tacho[channel].connected))
0245             return 0;
0246 
0247         switch (attr) {
0248         case hwmon_fan_input:
0249         case hwmon_fan_fault:
0250             return 0444;
0251         default:
0252             break;
0253         }
0254         break;
0255 
0256     case hwmon_pwm:
0257         if (!(((struct mlxreg_fan *)data)->pwm[channel].connected))
0258             return 0;
0259 
0260         switch (attr) {
0261         case hwmon_pwm_input:
0262             return 0644;
0263         default:
0264             break;
0265         }
0266         break;
0267 
0268     default:
0269         break;
0270     }
0271 
0272     return 0;
0273 }
0274 
0275 static char *mlxreg_fan_name[] = {
0276     "mlxreg_fan",
0277     "mlxreg_fan1",
0278     "mlxreg_fan2",
0279     "mlxreg_fan3",
0280 };
0281 
0282 static const struct hwmon_channel_info *mlxreg_fan_hwmon_info[] = {
0283     HWMON_CHANNEL_INFO(fan,
0284                HWMON_F_INPUT | HWMON_F_FAULT,
0285                HWMON_F_INPUT | HWMON_F_FAULT,
0286                HWMON_F_INPUT | HWMON_F_FAULT,
0287                HWMON_F_INPUT | HWMON_F_FAULT,
0288                HWMON_F_INPUT | HWMON_F_FAULT,
0289                HWMON_F_INPUT | HWMON_F_FAULT,
0290                HWMON_F_INPUT | HWMON_F_FAULT,
0291                HWMON_F_INPUT | HWMON_F_FAULT,
0292                HWMON_F_INPUT | HWMON_F_FAULT,
0293                HWMON_F_INPUT | HWMON_F_FAULT,
0294                HWMON_F_INPUT | HWMON_F_FAULT,
0295                HWMON_F_INPUT | HWMON_F_FAULT,
0296                HWMON_F_INPUT | HWMON_F_FAULT,
0297                HWMON_F_INPUT | HWMON_F_FAULT),
0298     HWMON_CHANNEL_INFO(pwm,
0299                HWMON_PWM_INPUT,
0300                HWMON_PWM_INPUT,
0301                HWMON_PWM_INPUT,
0302                HWMON_PWM_INPUT),
0303     NULL
0304 };
0305 
0306 static const struct hwmon_ops mlxreg_fan_hwmon_hwmon_ops = {
0307     .is_visible = mlxreg_fan_is_visible,
0308     .read = mlxreg_fan_read,
0309     .write = mlxreg_fan_write,
0310 };
0311 
0312 static const struct hwmon_chip_info mlxreg_fan_hwmon_chip_info = {
0313     .ops = &mlxreg_fan_hwmon_hwmon_ops,
0314     .info = mlxreg_fan_hwmon_info,
0315 };
0316 
0317 static int mlxreg_fan_get_max_state(struct thermal_cooling_device *cdev,
0318                     unsigned long *state)
0319 {
0320     *state = MLXREG_FAN_MAX_STATE;
0321     return 0;
0322 }
0323 
0324 static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev,
0325                     unsigned long *state)
0326 
0327 {
0328     struct mlxreg_fan_pwm *pwm = cdev->devdata;
0329     struct mlxreg_fan *fan = pwm->fan;
0330     u32 regval;
0331     int err;
0332 
0333     err = regmap_read(fan->regmap, pwm->reg, &regval);
0334     if (err) {
0335         dev_err(fan->dev, "Failed to query PWM duty\n");
0336         return err;
0337     }
0338 
0339     *state = MLXREG_FAN_PWM_DUTY2STATE(regval);
0340 
0341     return 0;
0342 }
0343 
0344 static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
0345                     unsigned long state)
0346 
0347 {
0348     struct mlxreg_fan_pwm *pwm = cdev->devdata;
0349     struct mlxreg_fan *fan = pwm->fan;
0350     int err;
0351 
0352     if (state > MLXREG_FAN_MAX_STATE)
0353         return -EINVAL;
0354 
0355     /* Save thermal state. */
0356     pwm->last_thermal_state = state;
0357 
0358     state = max_t(unsigned long, state, pwm->last_hwmon_state);
0359     err = regmap_write(fan->regmap, pwm->reg,
0360                MLXREG_FAN_PWM_STATE2DUTY(state));
0361     if (err) {
0362         dev_err(fan->dev, "Failed to write PWM duty\n");
0363         return err;
0364     }
0365     return 0;
0366 }
0367 
0368 static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = {
0369     .get_max_state  = mlxreg_fan_get_max_state,
0370     .get_cur_state  = mlxreg_fan_get_cur_state,
0371     .set_cur_state  = mlxreg_fan_set_cur_state,
0372 };
0373 
0374 static int mlxreg_fan_connect_verify(struct mlxreg_fan *fan,
0375                      struct mlxreg_core_data *data)
0376 {
0377     u32 regval;
0378     int err;
0379 
0380     err = regmap_read(fan->regmap, data->capability, &regval);
0381     if (err) {
0382         dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
0383             data->capability);
0384         return err;
0385     }
0386 
0387     return !!(regval & data->bit);
0388 }
0389 
0390 static int mlxreg_pwm_connect_verify(struct mlxreg_fan *fan,
0391                      struct mlxreg_core_data *data)
0392 {
0393     u32 regval;
0394     int err;
0395 
0396     err = regmap_read(fan->regmap, data->reg, &regval);
0397     if (err) {
0398         dev_err(fan->dev, "Failed to query pwm register 0x%08x\n",
0399             data->reg);
0400         return err;
0401     }
0402 
0403     return regval != MLXREG_FAN_PWM_NOT_CONNECTED;
0404 }
0405 
0406 static int mlxreg_fan_speed_divider_get(struct mlxreg_fan *fan,
0407                     struct mlxreg_core_data *data)
0408 {
0409     u32 regval;
0410     int err;
0411 
0412     err = regmap_read(fan->regmap, data->capability, &regval);
0413     if (err) {
0414         dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
0415             data->capability);
0416         return err;
0417     }
0418 
0419     /*
0420      * Set divider value according to the capability register, in case it
0421      * contains valid value. Otherwise use default value. The purpose of
0422      * this validation is to protect against the old hardware, in which
0423      * this register can return zero.
0424      */
0425     if (regval > 0 && regval <= MLXREG_FAN_TACHO_DIV_SCALE_MAX)
0426         fan->divider = regval * MLXREG_FAN_TACHO_DIV_MIN;
0427 
0428     return 0;
0429 }
0430 
0431 static int mlxreg_fan_config(struct mlxreg_fan *fan,
0432                  struct mlxreg_core_platform_data *pdata)
0433 {
0434     int tacho_num = 0, tacho_avail = 0, pwm_num = 0, i;
0435     struct mlxreg_core_data *data = pdata->data;
0436     bool configured = false;
0437     int err;
0438 
0439     fan->samples = MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF;
0440     fan->divider = MLXREG_FAN_TACHO_DIV_DEF;
0441     for (i = 0; i < pdata->counter; i++, data++) {
0442         if (strnstr(data->label, "tacho", sizeof(data->label))) {
0443             if (tacho_num == MLXREG_FAN_MAX_TACHO) {
0444                 dev_err(fan->dev, "too many tacho entries: %s\n",
0445                     data->label);
0446                 return -EINVAL;
0447             }
0448 
0449             if (data->capability) {
0450                 err = mlxreg_fan_connect_verify(fan, data);
0451                 if (err < 0)
0452                     return err;
0453                 else if (!err) {
0454                     tacho_num++;
0455                     continue;
0456                 }
0457             }
0458 
0459             fan->tacho[tacho_num].reg = data->reg;
0460             fan->tacho[tacho_num].mask = data->mask;
0461             fan->tacho[tacho_num].prsnt = data->reg_prsnt;
0462             fan->tacho[tacho_num++].connected = true;
0463             tacho_avail++;
0464         } else if (strnstr(data->label, "pwm", sizeof(data->label))) {
0465             if (pwm_num == MLXREG_FAN_MAX_TACHO) {
0466                 dev_err(fan->dev, "too many pwm entries: %s\n",
0467                     data->label);
0468                 return -EINVAL;
0469             }
0470 
0471             /* Validate if more then one PWM is connected. */
0472             if (pwm_num) {
0473                 err = mlxreg_pwm_connect_verify(fan, data);
0474                 if (err < 0)
0475                     return err;
0476                 else if (!err)
0477                     continue;
0478             }
0479 
0480             fan->pwm[pwm_num].reg = data->reg;
0481             fan->pwm[pwm_num].connected = true;
0482             pwm_num++;
0483         } else if (strnstr(data->label, "conf", sizeof(data->label))) {
0484             if (configured) {
0485                 dev_err(fan->dev, "duplicate conf entry: %s\n",
0486                     data->label);
0487                 return -EINVAL;
0488             }
0489             /* Validate that conf parameters are not zeros. */
0490             if (!data->mask && !data->bit && !data->capability) {
0491                 dev_err(fan->dev, "invalid conf entry params: %s\n",
0492                     data->label);
0493                 return -EINVAL;
0494             }
0495             if (data->capability) {
0496                 err = mlxreg_fan_speed_divider_get(fan, data);
0497                 if (err)
0498                     return err;
0499             } else {
0500                 if (data->mask)
0501                     fan->samples = data->mask;
0502                 if (data->bit)
0503                     fan->divider = data->bit;
0504             }
0505             configured = true;
0506         } else {
0507             dev_err(fan->dev, "invalid label: %s\n", data->label);
0508             return -EINVAL;
0509         }
0510     }
0511 
0512     if (pdata->capability) {
0513         int drwr_avail;
0514         u32 regval;
0515 
0516         /* Obtain the number of FAN drawers, supported by system. */
0517         err = regmap_read(fan->regmap, pdata->capability, &regval);
0518         if (err) {
0519             dev_err(fan->dev, "Failed to query capability register 0x%08x\n",
0520                 pdata->capability);
0521             return err;
0522         }
0523 
0524         drwr_avail = hweight32(regval);
0525         if (!tacho_avail || !drwr_avail || tacho_avail < drwr_avail) {
0526             dev_err(fan->dev, "Configuration is invalid: drawers num %d tachos num %d\n",
0527                 drwr_avail, tacho_avail);
0528             return -EINVAL;
0529         }
0530 
0531         /* Set the number of tachometers per one drawer. */
0532         fan->tachos_per_drwr = tacho_avail / drwr_avail;
0533     }
0534 
0535     return 0;
0536 }
0537 
0538 static int mlxreg_fan_cooling_config(struct device *dev, struct mlxreg_fan *fan)
0539 {
0540     int i;
0541 
0542     for (i = 0; i < MLXREG_FAN_MAX_PWM; i++) {
0543         struct mlxreg_fan_pwm *pwm = &fan->pwm[i];
0544 
0545         if (!pwm->connected)
0546             continue;
0547         pwm->fan = fan;
0548         pwm->cdev = devm_thermal_of_cooling_device_register(dev, NULL, mlxreg_fan_name[i],
0549                                     pwm, &mlxreg_fan_cooling_ops);
0550         if (IS_ERR(pwm->cdev)) {
0551             dev_err(dev, "Failed to register cooling device\n");
0552             return PTR_ERR(pwm->cdev);
0553         }
0554 
0555         /* Set minimal PWM speed. */
0556         pwm->last_hwmon_state = MLXREG_FAN_PWM_DUTY2STATE(MLXREG_FAN_MIN_DUTY);
0557     }
0558 
0559     return 0;
0560 }
0561 
0562 static int mlxreg_fan_probe(struct platform_device *pdev)
0563 {
0564     struct mlxreg_core_platform_data *pdata;
0565     struct device *dev = &pdev->dev;
0566     struct mlxreg_fan *fan;
0567     struct device *hwm;
0568     int err;
0569 
0570     pdata = dev_get_platdata(dev);
0571     if (!pdata) {
0572         dev_err(dev, "Failed to get platform data.\n");
0573         return -EINVAL;
0574     }
0575 
0576     fan = devm_kzalloc(dev, sizeof(*fan), GFP_KERNEL);
0577     if (!fan)
0578         return -ENOMEM;
0579 
0580     fan->dev = dev;
0581     fan->regmap = pdata->regmap;
0582 
0583     err = mlxreg_fan_config(fan, pdata);
0584     if (err)
0585         return err;
0586 
0587     hwm = devm_hwmon_device_register_with_info(dev, "mlxreg_fan",
0588                            fan,
0589                            &mlxreg_fan_hwmon_chip_info,
0590                            NULL);
0591     if (IS_ERR(hwm)) {
0592         dev_err(dev, "Failed to register hwmon device\n");
0593         return PTR_ERR(hwm);
0594     }
0595 
0596     if (IS_REACHABLE(CONFIG_THERMAL))
0597         err = mlxreg_fan_cooling_config(dev, fan);
0598 
0599     return err;
0600 }
0601 
0602 static struct platform_driver mlxreg_fan_driver = {
0603     .driver = {
0604         .name = "mlxreg-fan",
0605     },
0606     .probe = mlxreg_fan_probe,
0607 };
0608 
0609 module_platform_driver(mlxreg_fan_driver);
0610 
0611 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
0612 MODULE_DESCRIPTION("Mellanox FAN driver");
0613 MODULE_LICENSE("GPL");
0614 MODULE_ALIAS("platform:mlxreg-fan");