linux/drivers/hwmon/gpio-fan.c
<<
>>
Prefs
   1/*
   2 * gpio-fan.c - Hwmon driver for fans connected to GPIO lines.
   3 *
   4 * Copyright (C) 2010 LaCie
   5 *
   6 * Author: Simon Guinot <sguinot@lacie.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 */
  22
  23#include <linux/module.h>
  24#include <linux/init.h>
  25#include <linux/slab.h>
  26#include <linux/interrupt.h>
  27#include <linux/irq.h>
  28#include <linux/platform_device.h>
  29#include <linux/err.h>
  30#include <linux/mutex.h>
  31#include <linux/hwmon.h>
  32#include <linux/gpio.h>
  33#include <linux/gpio-fan.h>
  34#include <linux/of_platform.h>
  35#include <linux/of_gpio.h>
  36
  37struct gpio_fan_data {
  38        struct platform_device  *pdev;
  39        struct device           *hwmon_dev;
  40        struct mutex            lock; /* lock GPIOs operations. */
  41        int                     num_ctrl;
  42        unsigned                *ctrl;
  43        int                     num_speed;
  44        struct gpio_fan_speed   *speed;
  45        int                     speed_index;
  46#ifdef CONFIG_PM_SLEEP
  47        int                     resume_speed;
  48#endif
  49        bool                    pwm_enable;
  50        struct gpio_fan_alarm   *alarm;
  51        struct work_struct      alarm_work;
  52};
  53
  54/*
  55 * Alarm GPIO.
  56 */
  57
  58static void fan_alarm_notify(struct work_struct *ws)
  59{
  60        struct gpio_fan_data *fan_data =
  61                container_of(ws, struct gpio_fan_data, alarm_work);
  62
  63        sysfs_notify(&fan_data->pdev->dev.kobj, NULL, "fan1_alarm");
  64        kobject_uevent(&fan_data->pdev->dev.kobj, KOBJ_CHANGE);
  65}
  66
  67static irqreturn_t fan_alarm_irq_handler(int irq, void *dev_id)
  68{
  69        struct gpio_fan_data *fan_data = dev_id;
  70
  71        schedule_work(&fan_data->alarm_work);
  72
  73        return IRQ_NONE;
  74}
  75
  76static ssize_t show_fan_alarm(struct device *dev,
  77                              struct device_attribute *attr, char *buf)
  78{
  79        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
  80        struct gpio_fan_alarm *alarm = fan_data->alarm;
  81        int value = gpio_get_value(alarm->gpio);
  82
  83        if (alarm->active_low)
  84                value = !value;
  85
  86        return sprintf(buf, "%d\n", value);
  87}
  88
  89static DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL);
  90
  91static int fan_alarm_init(struct gpio_fan_data *fan_data,
  92                          struct gpio_fan_alarm *alarm)
  93{
  94        int err;
  95        int alarm_irq;
  96        struct platform_device *pdev = fan_data->pdev;
  97
  98        fan_data->alarm = alarm;
  99
 100        err = devm_gpio_request(&pdev->dev, alarm->gpio, "GPIO fan alarm");
 101        if (err)
 102                return err;
 103
 104        err = gpio_direction_input(alarm->gpio);
 105        if (err)
 106                return err;
 107
 108        /*
 109         * If the alarm GPIO don't support interrupts, just leave
 110         * without initializing the fail notification support.
 111         */
 112        alarm_irq = gpio_to_irq(alarm->gpio);
 113        if (alarm_irq < 0)
 114                return 0;
 115
 116        INIT_WORK(&fan_data->alarm_work, fan_alarm_notify);
 117        irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
 118        err = devm_request_irq(&pdev->dev, alarm_irq, fan_alarm_irq_handler,
 119                               IRQF_SHARED, "GPIO fan alarm", fan_data);
 120        return err;
 121}
 122
 123/*
 124 * Control GPIOs.
 125 */
 126
 127/* Must be called with fan_data->lock held, except during initialization. */
 128static void __set_fan_ctrl(struct gpio_fan_data *fan_data, int ctrl_val)
 129{
 130        int i;
 131
 132        for (i = 0; i < fan_data->num_ctrl; i++)
 133                gpio_set_value(fan_data->ctrl[i], (ctrl_val >> i) & 1);
 134}
 135
 136static int __get_fan_ctrl(struct gpio_fan_data *fan_data)
 137{
 138        int i;
 139        int ctrl_val = 0;
 140
 141        for (i = 0; i < fan_data->num_ctrl; i++) {
 142                int value;
 143
 144                value = gpio_get_value(fan_data->ctrl[i]);
 145                ctrl_val |= (value << i);
 146        }
 147        return ctrl_val;
 148}
 149
 150/* Must be called with fan_data->lock held, except during initialization. */
 151static void set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
 152{
 153        if (fan_data->speed_index == speed_index)
 154                return;
 155
 156        __set_fan_ctrl(fan_data, fan_data->speed[speed_index].ctrl_val);
 157        fan_data->speed_index = speed_index;
 158}
 159
 160static int get_fan_speed_index(struct gpio_fan_data *fan_data)
 161{
 162        int ctrl_val = __get_fan_ctrl(fan_data);
 163        int i;
 164
 165        for (i = 0; i < fan_data->num_speed; i++)
 166                if (fan_data->speed[i].ctrl_val == ctrl_val)
 167                        return i;
 168
 169        dev_warn(&fan_data->pdev->dev,
 170                 "missing speed array entry for GPIO value 0x%x\n", ctrl_val);
 171
 172        return -EINVAL;
 173}
 174
 175static int rpm_to_speed_index(struct gpio_fan_data *fan_data, int rpm)
 176{
 177        struct gpio_fan_speed *speed = fan_data->speed;
 178        int i;
 179
 180        for (i = 0; i < fan_data->num_speed; i++)
 181                if (speed[i].rpm >= rpm)
 182                        return i;
 183
 184        return fan_data->num_speed - 1;
 185}
 186
 187static ssize_t show_pwm(struct device *dev,
 188                        struct device_attribute *attr, char *buf)
 189{
 190        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 191        u8 pwm = fan_data->speed_index * 255 / (fan_data->num_speed - 1);
 192
 193        return sprintf(buf, "%d\n", pwm);
 194}
 195
 196static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 197                       const char *buf, size_t count)
 198{
 199        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 200        unsigned long pwm;
 201        int speed_index;
 202        int ret = count;
 203
 204        if (kstrtoul(buf, 10, &pwm) || pwm > 255)
 205                return -EINVAL;
 206
 207        mutex_lock(&fan_data->lock);
 208
 209        if (!fan_data->pwm_enable) {
 210                ret = -EPERM;
 211                goto exit_unlock;
 212        }
 213
 214        speed_index = DIV_ROUND_UP(pwm * (fan_data->num_speed - 1), 255);
 215        set_fan_speed(fan_data, speed_index);
 216
 217exit_unlock:
 218        mutex_unlock(&fan_data->lock);
 219
 220        return ret;
 221}
 222
 223static ssize_t show_pwm_enable(struct device *dev,
 224                               struct device_attribute *attr, char *buf)
 225{
 226        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 227
 228        return sprintf(buf, "%d\n", fan_data->pwm_enable);
 229}
 230
 231static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
 232                              const char *buf, size_t count)
 233{
 234        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 235        unsigned long val;
 236
 237        if (kstrtoul(buf, 10, &val) || val > 1)
 238                return -EINVAL;
 239
 240        if (fan_data->pwm_enable == val)
 241                return count;
 242
 243        mutex_lock(&fan_data->lock);
 244
 245        fan_data->pwm_enable = val;
 246
 247        /* Disable manual control mode: set fan at full speed. */
 248        if (val == 0)
 249                set_fan_speed(fan_data, fan_data->num_speed - 1);
 250
 251        mutex_unlock(&fan_data->lock);
 252
 253        return count;
 254}
 255
 256static ssize_t show_pwm_mode(struct device *dev,
 257                             struct device_attribute *attr, char *buf)
 258{
 259        return sprintf(buf, "0\n");
 260}
 261
 262static ssize_t show_rpm_min(struct device *dev,
 263                            struct device_attribute *attr, char *buf)
 264{
 265        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 266
 267        return sprintf(buf, "%d\n", fan_data->speed[0].rpm);
 268}
 269
 270static ssize_t show_rpm_max(struct device *dev,
 271                            struct device_attribute *attr, char *buf)
 272{
 273        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 274
 275        return sprintf(buf, "%d\n",
 276                       fan_data->speed[fan_data->num_speed - 1].rpm);
 277}
 278
 279static ssize_t show_rpm(struct device *dev,
 280                        struct device_attribute *attr, char *buf)
 281{
 282        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 283
 284        return sprintf(buf, "%d\n", fan_data->speed[fan_data->speed_index].rpm);
 285}
 286
 287static ssize_t set_rpm(struct device *dev, struct device_attribute *attr,
 288                       const char *buf, size_t count)
 289{
 290        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 291        unsigned long rpm;
 292        int ret = count;
 293
 294        if (kstrtoul(buf, 10, &rpm))
 295                return -EINVAL;
 296
 297        mutex_lock(&fan_data->lock);
 298
 299        if (!fan_data->pwm_enable) {
 300                ret = -EPERM;
 301                goto exit_unlock;
 302        }
 303
 304        set_fan_speed(fan_data, rpm_to_speed_index(fan_data, rpm));
 305
 306exit_unlock:
 307        mutex_unlock(&fan_data->lock);
 308
 309        return ret;
 310}
 311
 312static ssize_t show_name(struct device *dev,
 313                         struct device_attribute *attr, char *buf)
 314{
 315        return sprintf(buf, "gpio-fan\n");
 316}
 317
 318static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm);
 319static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
 320                   show_pwm_enable, set_pwm_enable);
 321static DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL);
 322static DEVICE_ATTR(fan1_min, S_IRUGO, show_rpm_min, NULL);
 323static DEVICE_ATTR(fan1_max, S_IRUGO, show_rpm_max, NULL);
 324static DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, NULL);
 325static DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_rpm, set_rpm);
 326
 327static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 328
 329static umode_t gpio_fan_is_visible(struct kobject *kobj,
 330                                   struct attribute *attr, int index)
 331{
 332        struct device *dev = container_of(kobj, struct device, kobj);
 333        struct gpio_fan_data *data = dev_get_drvdata(dev);
 334
 335        if (index == 1 && !data->alarm)
 336                return 0;
 337        if (index > 1 && !data->ctrl)
 338                return 0;
 339
 340        return attr->mode;
 341}
 342
 343static struct attribute *gpio_fan_attributes[] = {
 344        &dev_attr_name.attr,
 345        &dev_attr_fan1_alarm.attr,              /* 1 */
 346        &dev_attr_pwm1.attr,                    /* 2 */
 347        &dev_attr_pwm1_enable.attr,
 348        &dev_attr_pwm1_mode.attr,
 349        &dev_attr_fan1_input.attr,
 350        &dev_attr_fan1_target.attr,
 351        &dev_attr_fan1_min.attr,
 352        &dev_attr_fan1_max.attr,
 353        NULL
 354};
 355
 356static const struct attribute_group gpio_fan_group = {
 357        .attrs = gpio_fan_attributes,
 358        .is_visible = gpio_fan_is_visible,
 359};
 360
 361static int fan_ctrl_init(struct gpio_fan_data *fan_data,
 362                         struct gpio_fan_platform_data *pdata)
 363{
 364        struct platform_device *pdev = fan_data->pdev;
 365        int num_ctrl = pdata->num_ctrl;
 366        unsigned *ctrl = pdata->ctrl;
 367        int i, err;
 368
 369        for (i = 0; i < num_ctrl; i++) {
 370                err = devm_gpio_request(&pdev->dev, ctrl[i],
 371                                        "GPIO fan control");
 372                if (err)
 373                        return err;
 374
 375                err = gpio_direction_output(ctrl[i], gpio_get_value(ctrl[i]));
 376                if (err)
 377                        return err;
 378        }
 379
 380        fan_data->num_ctrl = num_ctrl;
 381        fan_data->ctrl = ctrl;
 382        fan_data->num_speed = pdata->num_speed;
 383        fan_data->speed = pdata->speed;
 384        fan_data->pwm_enable = true; /* Enable manual fan speed control. */
 385        fan_data->speed_index = get_fan_speed_index(fan_data);
 386        if (fan_data->speed_index < 0)
 387                return -ENODEV;
 388
 389        return 0;
 390}
 391
 392#ifdef CONFIG_OF_GPIO
 393/*
 394 * Translate OpenFirmware node properties into platform_data
 395 */
 396static int gpio_fan_get_of_pdata(struct device *dev,
 397                            struct gpio_fan_platform_data *pdata)
 398{
 399        struct device_node *node;
 400        struct gpio_fan_speed *speed;
 401        unsigned *ctrl;
 402        unsigned i;
 403        u32 u;
 404        struct property *prop;
 405        const __be32 *p;
 406
 407        node = dev->of_node;
 408
 409        /* Fill GPIO pin array */
 410        pdata->num_ctrl = of_gpio_count(node);
 411        if (pdata->num_ctrl <= 0) {
 412                dev_err(dev, "gpios DT property empty / missing");
 413                return -ENODEV;
 414        }
 415        ctrl = devm_kzalloc(dev, pdata->num_ctrl * sizeof(unsigned),
 416                                GFP_KERNEL);
 417        if (!ctrl)
 418                return -ENOMEM;
 419        for (i = 0; i < pdata->num_ctrl; i++) {
 420                int val;
 421
 422                val = of_get_gpio(node, i);
 423                if (val < 0)
 424                        return val;
 425                ctrl[i] = val;
 426        }
 427        pdata->ctrl = ctrl;
 428
 429        /* Get number of RPM/ctrl_val pairs in speed map */
 430        prop = of_find_property(node, "gpio-fan,speed-map", &i);
 431        if (!prop) {
 432                dev_err(dev, "gpio-fan,speed-map DT property missing");
 433                return -ENODEV;
 434        }
 435        i = i / sizeof(u32);
 436        if (i == 0 || i & 1) {
 437                dev_err(dev, "gpio-fan,speed-map contains zero/odd number of entries");
 438                return -ENODEV;
 439        }
 440        pdata->num_speed = i / 2;
 441
 442        /*
 443         * Populate speed map
 444         * Speed map is in the form <RPM ctrl_val RPM ctrl_val ...>
 445         * this needs splitting into pairs to create gpio_fan_speed structs
 446         */
 447        speed = devm_kzalloc(dev,
 448                        pdata->num_speed * sizeof(struct gpio_fan_speed),
 449                        GFP_KERNEL);
 450        if (!speed)
 451                return -ENOMEM;
 452        p = NULL;
 453        for (i = 0; i < pdata->num_speed; i++) {
 454                p = of_prop_next_u32(prop, p, &u);
 455                if (!p)
 456                        return -ENODEV;
 457                speed[i].rpm = u;
 458                p = of_prop_next_u32(prop, p, &u);
 459                if (!p)
 460                        return -ENODEV;
 461                speed[i].ctrl_val = u;
 462        }
 463        pdata->speed = speed;
 464
 465        /* Alarm GPIO if one exists */
 466        if (of_gpio_named_count(node, "alarm-gpios") > 0) {
 467                struct gpio_fan_alarm *alarm;
 468                int val;
 469                enum of_gpio_flags flags;
 470
 471                alarm = devm_kzalloc(dev, sizeof(struct gpio_fan_alarm),
 472                                        GFP_KERNEL);
 473                if (!alarm)
 474                        return -ENOMEM;
 475
 476                val = of_get_named_gpio_flags(node, "alarm-gpios", 0, &flags);
 477                if (val < 0)
 478                        return val;
 479                alarm->gpio = val;
 480                alarm->active_low = flags & OF_GPIO_ACTIVE_LOW;
 481
 482                pdata->alarm = alarm;
 483        }
 484
 485        return 0;
 486}
 487
 488static struct of_device_id of_gpio_fan_match[] = {
 489        { .compatible = "gpio-fan", },
 490        {},
 491};
 492#endif /* CONFIG_OF_GPIO */
 493
 494static int gpio_fan_probe(struct platform_device *pdev)
 495{
 496        int err;
 497        struct gpio_fan_data *fan_data;
 498        struct gpio_fan_platform_data *pdata = pdev->dev.platform_data;
 499
 500#ifdef CONFIG_OF_GPIO
 501        if (!pdata) {
 502                pdata = devm_kzalloc(&pdev->dev,
 503                                        sizeof(struct gpio_fan_platform_data),
 504                                        GFP_KERNEL);
 505                if (!pdata)
 506                        return -ENOMEM;
 507
 508                err = gpio_fan_get_of_pdata(&pdev->dev, pdata);
 509                if (err)
 510                        return err;
 511        }
 512#else /* CONFIG_OF_GPIO */
 513        if (!pdata)
 514                return -EINVAL;
 515#endif /* CONFIG_OF_GPIO */
 516
 517        fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data),
 518                                GFP_KERNEL);
 519        if (!fan_data)
 520                return -ENOMEM;
 521
 522        fan_data->pdev = pdev;
 523        platform_set_drvdata(pdev, fan_data);
 524        mutex_init(&fan_data->lock);
 525
 526        /* Configure alarm GPIO if available. */
 527        if (pdata->alarm) {
 528                err = fan_alarm_init(fan_data, pdata->alarm);
 529                if (err)
 530                        return err;
 531        }
 532
 533        /* Configure control GPIOs if available. */
 534        if (pdata->ctrl && pdata->num_ctrl > 0) {
 535                if (!pdata->speed || pdata->num_speed <= 1)
 536                        return -EINVAL;
 537                err = fan_ctrl_init(fan_data, pdata);
 538                if (err)
 539                        return err;
 540        }
 541
 542        err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_group);
 543        if (err)
 544                return err;
 545
 546        /* Make this driver part of hwmon class. */
 547        fan_data->hwmon_dev = hwmon_device_register(&pdev->dev);
 548        if (IS_ERR(fan_data->hwmon_dev)) {
 549                err = PTR_ERR(fan_data->hwmon_dev);
 550                goto err_remove;
 551        }
 552
 553        dev_info(&pdev->dev, "GPIO fan initialized\n");
 554
 555        return 0;
 556
 557err_remove:
 558        sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group);
 559        return err;
 560}
 561
 562static int gpio_fan_remove(struct platform_device *pdev)
 563{
 564        struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
 565
 566        hwmon_device_unregister(fan_data->hwmon_dev);
 567        sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_group);
 568
 569        return 0;
 570}
 571
 572#ifdef CONFIG_PM_SLEEP
 573static int gpio_fan_suspend(struct device *dev)
 574{
 575        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 576
 577        if (fan_data->ctrl) {
 578                fan_data->resume_speed = fan_data->speed_index;
 579                set_fan_speed(fan_data, 0);
 580        }
 581
 582        return 0;
 583}
 584
 585static int gpio_fan_resume(struct device *dev)
 586{
 587        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 588
 589        if (fan_data->ctrl)
 590                set_fan_speed(fan_data, fan_data->resume_speed);
 591
 592        return 0;
 593}
 594
 595static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
 596#define GPIO_FAN_PM     (&gpio_fan_pm)
 597#else
 598#define GPIO_FAN_PM     NULL
 599#endif
 600
 601static struct platform_driver gpio_fan_driver = {
 602        .probe          = gpio_fan_probe,
 603        .remove         = gpio_fan_remove,
 604        .driver = {
 605                .name   = "gpio-fan",
 606                .pm     = GPIO_FAN_PM,
 607#ifdef CONFIG_OF_GPIO
 608                .of_match_table = of_match_ptr(of_gpio_fan_match),
 609#endif
 610        },
 611};
 612
 613module_platform_driver(gpio_fan_driver);
 614
 615MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
 616MODULE_DESCRIPTION("GPIO FAN driver");
 617MODULE_LICENSE("GPL");
 618MODULE_ALIAS("platform:gpio-fan");
 619
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.