linux/drivers/hwmon/axi-fan-control.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Fan Control HDL CORE driver
   4 *
   5 * Copyright 2019 Analog Devices Inc.
   6 */
   7#include <linux/bits.h>
   8#include <linux/clk.h>
   9#include <linux/fpga/adi-axi-common.h>
  10#include <linux/hwmon.h>
  11#include <linux/interrupt.h>
  12#include <linux/io.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/of.h>
  16#include <linux/platform_device.h>
  17
  18/* register map */
  19#define ADI_REG_RSTN            0x0080
  20#define ADI_REG_PWM_WIDTH       0x0084
  21#define ADI_REG_TACH_PERIOD     0x0088
  22#define ADI_REG_TACH_TOLERANCE  0x008c
  23#define ADI_REG_PWM_PERIOD      0x00c0
  24#define ADI_REG_TACH_MEASUR     0x00c4
  25#define ADI_REG_TEMPERATURE     0x00c8
  26
  27#define ADI_REG_IRQ_MASK        0x0040
  28#define ADI_REG_IRQ_PENDING     0x0044
  29#define ADI_REG_IRQ_SRC         0x0048
  30
  31/* IRQ sources */
  32#define ADI_IRQ_SRC_PWM_CHANGED         BIT(0)
  33#define ADI_IRQ_SRC_TACH_ERR            BIT(1)
  34#define ADI_IRQ_SRC_TEMP_INCREASE       BIT(2)
  35#define ADI_IRQ_SRC_NEW_MEASUR          BIT(3)
  36#define ADI_IRQ_SRC_MASK                GENMASK(3, 0)
  37#define ADI_IRQ_MASK_OUT_ALL            0xFFFFFFFFU
  38
  39#define SYSFS_PWM_MAX                   255
  40
  41struct axi_fan_control_data {
  42        void __iomem *base;
  43        struct device *hdev;
  44        unsigned long clk_rate;
  45        int irq;
  46        /* pulses per revolution */
  47        u32 ppr;
  48        bool hw_pwm_req;
  49        bool update_tacho_params;
  50        u8 fan_fault;
  51};
  52
  53static inline void axi_iowrite(const u32 val, const u32 reg,
  54                               const struct axi_fan_control_data *ctl)
  55{
  56        iowrite32(val, ctl->base + reg);
  57}
  58
  59static inline u32 axi_ioread(const u32 reg,
  60                             const struct axi_fan_control_data *ctl)
  61{
  62        return ioread32(ctl->base + reg);
  63}
  64
  65static long axi_fan_control_get_pwm_duty(const struct axi_fan_control_data *ctl)
  66{
  67        u32 pwm_width = axi_ioread(ADI_REG_PWM_WIDTH, ctl);
  68        u32 pwm_period = axi_ioread(ADI_REG_PWM_PERIOD, ctl);
  69        /*
  70         * PWM_PERIOD is a RO register set by the core. It should never be 0.
  71         * For now we are trusting the HW...
  72         */
  73        return DIV_ROUND_CLOSEST(pwm_width * SYSFS_PWM_MAX, pwm_period);
  74}
  75
  76static int axi_fan_control_set_pwm_duty(const long val,
  77                                        struct axi_fan_control_data *ctl)
  78{
  79        u32 pwm_period = axi_ioread(ADI_REG_PWM_PERIOD, ctl);
  80        u32 new_width;
  81        long __val = clamp_val(val, 0, SYSFS_PWM_MAX);
  82
  83        new_width = DIV_ROUND_CLOSEST(__val * pwm_period, SYSFS_PWM_MAX);
  84
  85        axi_iowrite(new_width, ADI_REG_PWM_WIDTH, ctl);
  86
  87        return 0;
  88}
  89
  90static long axi_fan_control_get_fan_rpm(const struct axi_fan_control_data *ctl)
  91{
  92        const u32 tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl);
  93
  94        if (tach == 0)
  95                /* should we return error, EAGAIN maybe? */
  96                return 0;
  97        /*
  98         * The tacho period should be:
  99         *      TACH = 60/(ppr * rpm), where rpm is revolutions per second
 100         *      and ppr is pulses per revolution.
 101         * Given the tacho period, we can multiply it by the input clock
 102         * so that we know how many clocks we need to have this period.
 103         * From this, we can derive the RPM value.
 104         */
 105        return DIV_ROUND_CLOSEST(60 * ctl->clk_rate, ctl->ppr * tach);
 106}
 107
 108static int axi_fan_control_read_temp(struct device *dev, u32 attr, long *val)
 109{
 110        struct axi_fan_control_data *ctl = dev_get_drvdata(dev);
 111        long raw_temp;
 112
 113        switch (attr) {
 114        case hwmon_temp_input:
 115                raw_temp = axi_ioread(ADI_REG_TEMPERATURE, ctl);
 116                /*
 117                 * The formula for the temperature is:
 118                 *      T = (ADC * 501.3743 / 2^bits) - 273.6777
 119                 * It's multiplied by 1000 to have millidegrees as
 120                 * specified by the hwmon sysfs interface.
 121                 */
 122                *val = ((raw_temp * 501374) >> 16) - 273677;
 123                return 0;
 124        default:
 125                return -ENOTSUPP;
 126        }
 127}
 128
 129static int axi_fan_control_read_fan(struct device *dev, u32 attr, long *val)
 130{
 131        struct axi_fan_control_data *ctl = dev_get_drvdata(dev);
 132
 133        switch (attr) {
 134        case hwmon_fan_fault:
 135                *val = ctl->fan_fault;
 136                /* clear it now */
 137                ctl->fan_fault = 0;
 138                return 0;
 139        case hwmon_fan_input:
 140                *val = axi_fan_control_get_fan_rpm(ctl);
 141                return 0;
 142        default:
 143                return -ENOTSUPP;
 144        }
 145}
 146
 147static int axi_fan_control_read_pwm(struct device *dev, u32 attr, long *val)
 148{
 149        struct axi_fan_control_data *ctl = dev_get_drvdata(dev);
 150
 151        switch (attr) {
 152        case hwmon_pwm_input:
 153                *val = axi_fan_control_get_pwm_duty(ctl);
 154                return 0;
 155        default:
 156                return -ENOTSUPP;
 157        }
 158}
 159
 160static int axi_fan_control_write_pwm(struct device *dev, u32 attr, long val)
 161{
 162        struct axi_fan_control_data *ctl = dev_get_drvdata(dev);
 163
 164        switch (attr) {
 165        case hwmon_pwm_input:
 166                return axi_fan_control_set_pwm_duty(val, ctl);
 167        default:
 168                return -ENOTSUPP;
 169        }
 170}
 171
 172static int axi_fan_control_read_labels(struct device *dev,
 173                                       enum hwmon_sensor_types type,
 174                                       u32 attr, int channel, const char **str)
 175{
 176        switch (type) {
 177        case hwmon_fan:
 178                *str = "FAN";
 179                return 0;
 180        case hwmon_temp:
 181                *str = "SYSMON4";
 182                return 0;
 183        default:
 184                return -ENOTSUPP;
 185        }
 186}
 187
 188static int axi_fan_control_read(struct device *dev,
 189                                enum hwmon_sensor_types type,
 190                                u32 attr, int channel, long *val)
 191{
 192        switch (type) {
 193        case hwmon_fan:
 194                return axi_fan_control_read_fan(dev, attr, val);
 195        case hwmon_pwm:
 196                return axi_fan_control_read_pwm(dev, attr, val);
 197        case hwmon_temp:
 198                return axi_fan_control_read_temp(dev, attr, val);
 199        default:
 200                return -ENOTSUPP;
 201        }
 202}
 203
 204static int axi_fan_control_write(struct device *dev,
 205                                 enum hwmon_sensor_types type,
 206                                 u32 attr, int channel, long val)
 207{
 208        switch (type) {
 209        case hwmon_pwm:
 210                return axi_fan_control_write_pwm(dev, attr, val);
 211        default:
 212                return -ENOTSUPP;
 213        }
 214}
 215
 216static umode_t axi_fan_control_fan_is_visible(const u32 attr)
 217{
 218        switch (attr) {
 219        case hwmon_fan_input:
 220        case hwmon_fan_fault:
 221        case hwmon_fan_label:
 222                return 0444;
 223        default:
 224                return 0;
 225        }
 226}
 227
 228static umode_t axi_fan_control_pwm_is_visible(const u32 attr)
 229{
 230        switch (attr) {
 231        case hwmon_pwm_input:
 232                return 0644;
 233        default:
 234                return 0;
 235        }
 236}
 237
 238static umode_t axi_fan_control_temp_is_visible(const u32 attr)
 239{
 240        switch (attr) {
 241        case hwmon_temp_input:
 242        case hwmon_temp_label:
 243                return 0444;
 244        default:
 245                return 0;
 246        }
 247}
 248
 249static umode_t axi_fan_control_is_visible(const void *data,
 250                                          enum hwmon_sensor_types type,
 251                                          u32 attr, int channel)
 252{
 253        switch (type) {
 254        case hwmon_fan:
 255                return axi_fan_control_fan_is_visible(attr);
 256        case hwmon_pwm:
 257                return axi_fan_control_pwm_is_visible(attr);
 258        case hwmon_temp:
 259                return axi_fan_control_temp_is_visible(attr);
 260        default:
 261                return 0;
 262        }
 263}
 264
 265/*
 266 * This core has two main ways of changing the PWM duty cycle. It is done,
 267 * either by a request from userspace (writing on pwm1_input) or by the
 268 * core itself. When the change is done by the core, it will use predefined
 269 * parameters to evaluate the tach signal and, on that case we cannot set them.
 270 * On the other hand, when the request is done by the user, with some arbitrary
 271 * value that the core does not now about, we have to provide the tach
 272 * parameters so that, the core can evaluate the signal. On the IRQ handler we
 273 * distinguish this by using the ADI_IRQ_SRC_TEMP_INCREASE interrupt. This tell
 274 * us that the CORE requested a new duty cycle. After this, there is 5s delay
 275 * on which the core waits for the fan rotation speed to stabilize. After this
 276 * we get ADI_IRQ_SRC_PWM_CHANGED irq where we will decide if we need to set
 277 * the tach parameters or not on the next tach measurement cycle (corresponding
 278 * already to the ney duty cycle) based on the %ctl->hw_pwm_req flag.
 279 */
 280static irqreturn_t axi_fan_control_irq_handler(int irq, void *data)
 281{
 282        struct axi_fan_control_data *ctl = (struct axi_fan_control_data *)data;
 283        u32 irq_pending = axi_ioread(ADI_REG_IRQ_PENDING, ctl);
 284        u32 clear_mask;
 285
 286        if (irq_pending & ADI_IRQ_SRC_NEW_MEASUR) {
 287                if (ctl->update_tacho_params) {
 288                        u32 new_tach = axi_ioread(ADI_REG_TACH_MEASUR, ctl);
 289
 290                        /* get 25% tolerance */
 291                        u32 tach_tol = DIV_ROUND_CLOSEST(new_tach * 25, 100);
 292                        /* set new tacho parameters */
 293                        axi_iowrite(new_tach, ADI_REG_TACH_PERIOD, ctl);
 294                        axi_iowrite(tach_tol, ADI_REG_TACH_TOLERANCE, ctl);
 295                        ctl->update_tacho_params = false;
 296                }
 297        }
 298
 299        if (irq_pending & ADI_IRQ_SRC_PWM_CHANGED) {
 300                /*
 301                 * if the pwm changes on behalf of software,
 302                 * we need to provide new tacho parameters to the core.
 303                 * Wait for the next measurement for that...
 304                 */
 305                if (!ctl->hw_pwm_req) {
 306                        ctl->update_tacho_params = true;
 307                } else {
 308                        ctl->hw_pwm_req = false;
 309                        sysfs_notify(&ctl->hdev->kobj, NULL, "pwm1");
 310                }
 311        }
 312
 313        if (irq_pending & ADI_IRQ_SRC_TEMP_INCREASE)
 314                /* hardware requested a new pwm */
 315                ctl->hw_pwm_req = true;
 316
 317        if (irq_pending & ADI_IRQ_SRC_TACH_ERR)
 318                ctl->fan_fault = 1;
 319
 320        /* clear all interrupts */
 321        clear_mask = irq_pending & ADI_IRQ_SRC_MASK;
 322        axi_iowrite(clear_mask, ADI_REG_IRQ_PENDING, ctl);
 323
 324        return IRQ_HANDLED;
 325}
 326
 327static int axi_fan_control_init(struct axi_fan_control_data *ctl,
 328                                const struct device_node *np)
 329{
 330        int ret;
 331
 332        /* get fan pulses per revolution */
 333        ret = of_property_read_u32(np, "pulses-per-revolution", &ctl->ppr);
 334        if (ret)
 335                return ret;
 336
 337        /* 1, 2 and 4 are the typical and accepted values */
 338        if (ctl->ppr != 1 && ctl->ppr != 2 && ctl->ppr != 4)
 339                return -EINVAL;
 340        /*
 341         * Enable all IRQs
 342         */
 343        axi_iowrite(ADI_IRQ_MASK_OUT_ALL &
 344                    ~(ADI_IRQ_SRC_NEW_MEASUR | ADI_IRQ_SRC_TACH_ERR |
 345                      ADI_IRQ_SRC_PWM_CHANGED | ADI_IRQ_SRC_TEMP_INCREASE),
 346                    ADI_REG_IRQ_MASK, ctl);
 347
 348        /* bring the device out of reset */
 349        axi_iowrite(0x01, ADI_REG_RSTN, ctl);
 350
 351        return ret;
 352}
 353
 354static const struct hwmon_channel_info *axi_fan_control_info[] = {
 355        HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT),
 356        HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_LABEL),
 357        HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_LABEL),
 358        NULL
 359};
 360
 361static const struct hwmon_ops axi_fan_control_hwmon_ops = {
 362        .is_visible = axi_fan_control_is_visible,
 363        .read = axi_fan_control_read,
 364        .write = axi_fan_control_write,
 365        .read_string = axi_fan_control_read_labels,
 366};
 367
 368static const struct hwmon_chip_info axi_chip_info = {
 369        .ops = &axi_fan_control_hwmon_ops,
 370        .info = axi_fan_control_info,
 371};
 372
 373static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a');
 374
 375static const struct of_device_id axi_fan_control_of_match[] = {
 376        { .compatible = "adi,axi-fan-control-1.00.a",
 377                .data = (void *)&version_1_0_0},
 378        {},
 379};
 380MODULE_DEVICE_TABLE(of, axi_fan_control_of_match);
 381
 382static int axi_fan_control_probe(struct platform_device *pdev)
 383{
 384        struct axi_fan_control_data *ctl;
 385        struct clk *clk;
 386        const struct of_device_id *id;
 387        const char *name = "axi_fan_control";
 388        u32 version;
 389        int ret;
 390
 391        id = of_match_node(axi_fan_control_of_match, pdev->dev.of_node);
 392        if (!id)
 393                return -EINVAL;
 394
 395        ctl = devm_kzalloc(&pdev->dev, sizeof(*ctl), GFP_KERNEL);
 396        if (!ctl)
 397                return -ENOMEM;
 398
 399        ctl->base = devm_platform_ioremap_resource(pdev, 0);
 400        if (IS_ERR(ctl->base))
 401                return PTR_ERR(ctl->base);
 402
 403        clk = devm_clk_get(&pdev->dev, NULL);
 404        if (IS_ERR(clk)) {
 405                dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk));
 406                return PTR_ERR(clk);
 407        }
 408
 409        ctl->clk_rate = clk_get_rate(clk);
 410        if (!ctl->clk_rate)
 411                return -EINVAL;
 412
 413        version = axi_ioread(ADI_AXI_REG_VERSION, ctl);
 414        if (ADI_AXI_PCORE_VER_MAJOR(version) !=
 415            ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data))) {
 416                dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n",
 417                        ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data)),
 418                        ADI_AXI_PCORE_VER_MINOR((*(u32 *)id->data)),
 419                        ADI_AXI_PCORE_VER_PATCH((*(u32 *)id->data)),
 420                        ADI_AXI_PCORE_VER_MAJOR(version),
 421                        ADI_AXI_PCORE_VER_MINOR(version),
 422                        ADI_AXI_PCORE_VER_PATCH(version));
 423                return -ENODEV;
 424        }
 425
 426        ctl->irq = platform_get_irq(pdev, 0);
 427        if (ctl->irq < 0)
 428                return ctl->irq;
 429
 430        ret = devm_request_threaded_irq(&pdev->dev, ctl->irq, NULL,
 431                                        axi_fan_control_irq_handler,
 432                                        IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
 433                                        pdev->driver_override, ctl);
 434        if (ret) {
 435                dev_err(&pdev->dev, "failed to request an irq, %d", ret);
 436                return ret;
 437        }
 438
 439        ret = axi_fan_control_init(ctl, pdev->dev.of_node);
 440        if (ret) {
 441                dev_err(&pdev->dev, "Failed to initialize device\n");
 442                return ret;
 443        }
 444
 445        ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev,
 446                                                         name,
 447                                                         ctl,
 448                                                         &axi_chip_info,
 449                                                         NULL);
 450
 451        return PTR_ERR_OR_ZERO(ctl->hdev);
 452}
 453
 454static struct platform_driver axi_fan_control_driver = {
 455        .driver = {
 456                .name = "axi_fan_control_driver",
 457                .of_match_table = axi_fan_control_of_match,
 458        },
 459        .probe = axi_fan_control_probe,
 460};
 461module_platform_driver(axi_fan_control_driver);
 462
 463MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
 464MODULE_DESCRIPTION("Analog Devices Fan Control HDL CORE driver");
 465MODULE_LICENSE("GPL");
 466