linux/drivers/gpio/gpio-ich.c
<<
>>
Prefs
   1/*
   2 * Intel ICH6-10, Series 5 and 6 GPIO driver
   3 *
   4 * Copyright (C) 2010 Extreme Engineering Solutions.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20
  21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  22
  23#include <linux/module.h>
  24#include <linux/pci.h>
  25#include <linux/gpio.h>
  26#include <linux/platform_device.h>
  27#include <linux/mfd/lpc_ich.h>
  28
  29#define DRV_NAME "gpio_ich"
  30
  31/*
  32 * GPIO register offsets in GPIO I/O space.
  33 * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
  34 * LVLx registers.  Logic in the read/write functions takes a register and
  35 * an absolute bit number and determines the proper register offset and bit
  36 * number in that register.  For example, to read the value of GPIO bit 50
  37 * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)],
  38 * bit 18 (50%32).
  39 */
  40enum GPIO_REG {
  41        GPIO_USE_SEL = 0,
  42        GPIO_IO_SEL,
  43        GPIO_LVL,
  44        GPO_BLINK
  45};
  46
  47static const u8 ichx_regs[4][3] = {
  48        {0x00, 0x30, 0x40},     /* USE_SEL[1-3] offsets */
  49        {0x04, 0x34, 0x44},     /* IO_SEL[1-3] offsets */
  50        {0x0c, 0x38, 0x48},     /* LVL[1-3] offsets */
  51        {0x18, 0x18, 0x18},     /* BLINK offset */
  52};
  53
  54static const u8 ichx_reglen[3] = {
  55        0x30, 0x10, 0x10,
  56};
  57
  58#define ICHX_WRITE(val, reg, base_res)  outl(val, (reg) + (base_res)->start)
  59#define ICHX_READ(reg, base_res)        inl((reg) + (base_res)->start)
  60
  61struct ichx_desc {
  62        /* Max GPIO pins the chipset can have */
  63        uint ngpio;
  64
  65        /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */
  66        bool uses_gpe0;
  67
  68        /* USE_SEL is bogus on some chipsets, eg 3100 */
  69        u32 use_sel_ignore[3];
  70
  71        /* Some chipsets have quirks, let these use their own request/get */
  72        int (*request)(struct gpio_chip *chip, unsigned offset);
  73        int (*get)(struct gpio_chip *chip, unsigned offset);
  74};
  75
  76static struct {
  77        spinlock_t lock;
  78        struct platform_device *dev;
  79        struct gpio_chip chip;
  80        struct resource *gpio_base;     /* GPIO IO base */
  81        struct resource *pm_base;       /* Power Mangagment IO base */
  82        struct ichx_desc *desc; /* Pointer to chipset-specific description */
  83        u32 orig_gpio_ctrl;     /* Orig CTRL value, used to restore on exit */
  84        u8 use_gpio;            /* Which GPIO groups are usable */
  85} ichx_priv;
  86
  87static int modparam_gpiobase = -1;      /* dynamic */
  88module_param_named(gpiobase, modparam_gpiobase, int, 0444);
  89MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, "
  90                           "which is the default.");
  91
  92static int ichx_write_bit(int reg, unsigned nr, int val, int verify)
  93{
  94        unsigned long flags;
  95        u32 data, tmp;
  96        int reg_nr = nr / 32;
  97        int bit = nr & 0x1f;
  98        int ret = 0;
  99
 100        spin_lock_irqsave(&ichx_priv.lock, flags);
 101
 102        data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base);
 103        if (val)
 104                data |= 1 << bit;
 105        else
 106                data &= ~(1 << bit);
 107        ICHX_WRITE(data, ichx_regs[reg][reg_nr], ichx_priv.gpio_base);
 108        tmp = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base);
 109        if (verify && data != tmp)
 110                ret = -EPERM;
 111
 112        spin_unlock_irqrestore(&ichx_priv.lock, flags);
 113
 114        return ret;
 115}
 116
 117static int ichx_read_bit(int reg, unsigned nr)
 118{
 119        unsigned long flags;
 120        u32 data;
 121        int reg_nr = nr / 32;
 122        int bit = nr & 0x1f;
 123
 124        spin_lock_irqsave(&ichx_priv.lock, flags);
 125
 126        data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base);
 127
 128        spin_unlock_irqrestore(&ichx_priv.lock, flags);
 129
 130        return data & (1 << bit) ? 1 : 0;
 131}
 132
 133static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
 134{
 135        return !!(ichx_priv.use_gpio & (1 << (nr / 32)));
 136}
 137
 138static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
 139{
 140        /*
 141         * Try setting pin as an input and verify it worked since many pins
 142         * are output-only.
 143         */
 144        if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1))
 145                return -EINVAL;
 146
 147        return 0;
 148}
 149
 150static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
 151                                        int val)
 152{
 153        /* Disable blink hardware which is available for GPIOs from 0 to 31. */
 154        if (nr < 32)
 155                ichx_write_bit(GPO_BLINK, nr, 0, 0);
 156
 157        /* Set GPIO output value. */
 158        ichx_write_bit(GPIO_LVL, nr, val, 0);
 159
 160        /*
 161         * Try setting pin as an output and verify it worked since many pins
 162         * are input-only.
 163         */
 164        if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1))
 165                return -EINVAL;
 166
 167        return 0;
 168}
 169
 170static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
 171{
 172        return ichx_read_bit(GPIO_LVL, nr);
 173}
 174
 175static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
 176{
 177        unsigned long flags;
 178        u32 data;
 179
 180        /*
 181         * GPI 0 - 15 need to be read from the power management registers on
 182         * a ICH6/3100 bridge.
 183         */
 184        if (nr < 16) {
 185                if (!ichx_priv.pm_base)
 186                        return -ENXIO;
 187
 188                spin_lock_irqsave(&ichx_priv.lock, flags);
 189
 190                /* GPI 0 - 15 are latched, write 1 to clear*/
 191                ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base);
 192                data = ICHX_READ(0, ichx_priv.pm_base);
 193
 194                spin_unlock_irqrestore(&ichx_priv.lock, flags);
 195
 196                return (data >> 16) & (1 << nr) ? 1 : 0;
 197        } else {
 198                return ichx_gpio_get(chip, nr);
 199        }
 200}
 201
 202static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr)
 203{
 204        if (!ichx_gpio_check_available(chip, nr))
 205                return -ENXIO;
 206
 207        /*
 208         * Note we assume the BIOS properly set a bridge's USE value.  Some
 209         * chips (eg Intel 3100) have bogus USE values though, so first see if
 210         * the chipset's USE value can be trusted for this specific bit.
 211         * If it can't be trusted, assume that the pin can be used as a GPIO.
 212         */
 213        if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f)))
 214                return 0;
 215
 216        return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV;
 217}
 218
 219static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr)
 220{
 221        /*
 222         * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100
 223         * bridge as they are controlled by USE register bits 0 and 1.  See
 224         * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for
 225         * additional info.
 226         */
 227        if (nr == 16 || nr == 17)
 228                nr -= 16;
 229
 230        return ichx_gpio_request(chip, nr);
 231}
 232
 233static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
 234{
 235        ichx_write_bit(GPIO_LVL, nr, val, 0);
 236}
 237
 238static void ichx_gpiolib_setup(struct gpio_chip *chip)
 239{
 240        chip->owner = THIS_MODULE;
 241        chip->label = DRV_NAME;
 242        chip->dev = &ichx_priv.dev->dev;
 243
 244        /* Allow chip-specific overrides of request()/get() */
 245        chip->request = ichx_priv.desc->request ?
 246                ichx_priv.desc->request : ichx_gpio_request;
 247        chip->get = ichx_priv.desc->get ?
 248                ichx_priv.desc->get : ichx_gpio_get;
 249
 250        chip->set = ichx_gpio_set;
 251        chip->direction_input = ichx_gpio_direction_input;
 252        chip->direction_output = ichx_gpio_direction_output;
 253        chip->base = modparam_gpiobase;
 254        chip->ngpio = ichx_priv.desc->ngpio;
 255        chip->can_sleep = 0;
 256        chip->dbg_show = NULL;
 257}
 258
 259/* ICH6-based, 631xesb-based */
 260static struct ichx_desc ich6_desc = {
 261        /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
 262        .request = ich6_gpio_request,
 263        .get = ich6_gpio_get,
 264
 265        /* GPIO 0-15 are read in the GPE0_STS PM register */
 266        .uses_gpe0 = true,
 267
 268        .ngpio = 50,
 269};
 270
 271/* Intel 3100 */
 272static struct ichx_desc i3100_desc = {
 273        /*
 274         * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on
 275         * the Intel 3100.  See "Table 712. GPIO Summary Table" of 3100
 276         * Datasheet for more info.
 277         */
 278        .use_sel_ignore = {0x00130000, 0x00010000, 0x0},
 279
 280        /* The 3100 needs fixups for GPIO 0 - 17 */
 281        .request = ich6_gpio_request,
 282        .get = ich6_gpio_get,
 283
 284        /* GPIO 0-15 are read in the GPE0_STS PM register */
 285        .uses_gpe0 = true,
 286
 287        .ngpio = 50,
 288};
 289
 290/* ICH7 and ICH8-based */
 291static struct ichx_desc ich7_desc = {
 292        .ngpio = 50,
 293};
 294
 295/* ICH9-based */
 296static struct ichx_desc ich9_desc = {
 297        .ngpio = 61,
 298};
 299
 300/* ICH10-based - Consumer/corporate versions have different amount of GPIO */
 301static struct ichx_desc ich10_cons_desc = {
 302        .ngpio = 61,
 303};
 304static struct ichx_desc ich10_corp_desc = {
 305        .ngpio = 72,
 306};
 307
 308/* Intel 5 series, 6 series, 3400 series, and C200 series */
 309static struct ichx_desc intel5_desc = {
 310        .ngpio = 76,
 311};
 312
 313static int ichx_gpio_request_regions(struct resource *res_base,
 314                                                const char *name, u8 use_gpio)
 315{
 316        int i;
 317
 318        if (!res_base || !res_base->start || !res_base->end)
 319                return -ENODEV;
 320
 321        for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
 322                if (!(use_gpio & (1 << i)))
 323                        continue;
 324                if (!request_region(res_base->start + ichx_regs[0][i],
 325                                    ichx_reglen[i], name))
 326                        goto request_err;
 327        }
 328        return 0;
 329
 330request_err:
 331        /* Clean up: release already requested regions, if any */
 332        for (i--; i >= 0; i--) {
 333                if (!(use_gpio & (1 << i)))
 334                        continue;
 335                release_region(res_base->start + ichx_regs[0][i],
 336                               ichx_reglen[i]);
 337        }
 338        return -EBUSY;
 339}
 340
 341static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
 342{
 343        int i;
 344
 345        for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
 346                if (!(use_gpio & (1 << i)))
 347                        continue;
 348                release_region(res_base->start + ichx_regs[0][i],
 349                               ichx_reglen[i]);
 350        }
 351}
 352
 353static int ichx_gpio_probe(struct platform_device *pdev)
 354{
 355        struct resource *res_base, *res_pm;
 356        int err;
 357        struct lpc_ich_info *ich_info = pdev->dev.platform_data;
 358
 359        if (!ich_info)
 360                return -ENODEV;
 361
 362        ichx_priv.dev = pdev;
 363
 364        switch (ich_info->gpio_version) {
 365        case ICH_I3100_GPIO:
 366                ichx_priv.desc = &i3100_desc;
 367                break;
 368        case ICH_V5_GPIO:
 369                ichx_priv.desc = &intel5_desc;
 370                break;
 371        case ICH_V6_GPIO:
 372                ichx_priv.desc = &ich6_desc;
 373                break;
 374        case ICH_V7_GPIO:
 375                ichx_priv.desc = &ich7_desc;
 376                break;
 377        case ICH_V9_GPIO:
 378                ichx_priv.desc = &ich9_desc;
 379                break;
 380        case ICH_V10CORP_GPIO:
 381                ichx_priv.desc = &ich10_corp_desc;
 382                break;
 383        case ICH_V10CONS_GPIO:
 384                ichx_priv.desc = &ich10_cons_desc;
 385                break;
 386        default:
 387                return -ENODEV;
 388        }
 389
 390        spin_lock_init(&ichx_priv.lock);
 391        res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
 392        ichx_priv.use_gpio = ich_info->use_gpio;
 393        err = ichx_gpio_request_regions(res_base, pdev->name,
 394                                        ichx_priv.use_gpio);
 395        if (err)
 396                return err;
 397
 398        ichx_priv.gpio_base = res_base;
 399
 400        /*
 401         * If necessary, determine the I/O address of ACPI/power management
 402         * registers which are needed to read the the GPE0 register for GPI pins
 403         * 0 - 15 on some chipsets.
 404         */
 405        if (!ichx_priv.desc->uses_gpe0)
 406                goto init;
 407
 408        res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0);
 409        if (!res_pm) {
 410                pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n");
 411                goto init;
 412        }
 413
 414        if (!request_region(res_pm->start, resource_size(res_pm),
 415                        pdev->name)) {
 416                pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n");
 417                goto init;
 418        }
 419
 420        ichx_priv.pm_base = res_pm;
 421
 422init:
 423        ichx_gpiolib_setup(&ichx_priv.chip);
 424        err = gpiochip_add(&ichx_priv.chip);
 425        if (err) {
 426                pr_err("Failed to register GPIOs\n");
 427                goto add_err;
 428        }
 429
 430        pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base,
 431               ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME);
 432
 433        return 0;
 434
 435add_err:
 436        ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
 437        if (ichx_priv.pm_base)
 438                release_region(ichx_priv.pm_base->start,
 439                                resource_size(ichx_priv.pm_base));
 440        return err;
 441}
 442
 443static int ichx_gpio_remove(struct platform_device *pdev)
 444{
 445        int err;
 446
 447        err = gpiochip_remove(&ichx_priv.chip);
 448        if (err) {
 449                dev_err(&pdev->dev, "%s failed, %d\n",
 450                                "gpiochip_remove()", err);
 451                return err;
 452        }
 453
 454        ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
 455        if (ichx_priv.pm_base)
 456                release_region(ichx_priv.pm_base->start,
 457                                resource_size(ichx_priv.pm_base));
 458
 459        return 0;
 460}
 461
 462static struct platform_driver ichx_gpio_driver = {
 463        .driver         = {
 464                .owner  = THIS_MODULE,
 465                .name   = DRV_NAME,
 466        },
 467        .probe          = ichx_gpio_probe,
 468        .remove         = ichx_gpio_remove,
 469};
 470
 471module_platform_driver(ichx_gpio_driver);
 472
 473MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");
 474MODULE_DESCRIPTION("GPIO interface for Intel ICH series");
 475MODULE_LICENSE("GPL");
 476MODULE_ALIAS("platform:"DRV_NAME);
 477
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.