linux/drivers/gpio/pch_gpio.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; version 2 of the License.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program; if not, write to the Free Software
  15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  16 */
  17#include <linux/kernel.h>
  18#include <linux/pci.h>
  19#include <linux/gpio.h>
  20
  21#define PCH_GPIO_ALL_PINS       0xfff /* Mask for GPIO pins 0 to 11 */
  22#define GPIO_NUM_PINS   12      /* Specifies number of GPIO PINS GPIO0-GPIO11 */
  23
  24struct pch_regs {
  25        u32     ien;
  26        u32     istatus;
  27        u32     idisp;
  28        u32     iclr;
  29        u32     imask;
  30        u32     imaskclr;
  31        u32     po;
  32        u32     pi;
  33        u32     pm;
  34        u32     im0;
  35        u32     im1;
  36        u32     reserved[4];
  37        u32     reset;
  38};
  39
  40/**
  41 * struct pch_gpio_reg_data - The register store data.
  42 * @po_reg:     To store contents of PO register.
  43 * @pm_reg:     To store contents of PM register.
  44 */
  45struct pch_gpio_reg_data {
  46        u32 po_reg;
  47        u32 pm_reg;
  48};
  49
  50/**
  51 * struct pch_gpio - GPIO private data structure.
  52 * @base:                       PCI base address of Memory mapped I/O register.
  53 * @reg:                        Memory mapped PCH GPIO register list.
  54 * @dev:                        Pointer to device structure.
  55 * @gpio:                       Data for GPIO infrastructure.
  56 * @pch_gpio_reg:               Memory mapped Register data is saved here
  57 *                              when suspend.
  58 */
  59struct pch_gpio {
  60        void __iomem *base;
  61        struct pch_regs __iomem *reg;
  62        struct device *dev;
  63        struct gpio_chip gpio;
  64        struct pch_gpio_reg_data pch_gpio_reg;
  65        struct mutex lock;
  66};
  67
  68static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
  69{
  70        u32 reg_val;
  71        struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
  72
  73        mutex_lock(&chip->lock);
  74        reg_val = ioread32(&chip->reg->po);
  75        if (val)
  76                reg_val |= (1 << nr);
  77        else
  78                reg_val &= ~(1 << nr);
  79
  80        iowrite32(reg_val, &chip->reg->po);
  81        mutex_unlock(&chip->lock);
  82}
  83
  84static int pch_gpio_get(struct gpio_chip *gpio, unsigned nr)
  85{
  86        struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
  87
  88        return ioread32(&chip->reg->pi) & (1 << nr);
  89}
  90
  91static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
  92                                     int val)
  93{
  94        struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
  95        u32 pm;
  96        u32 reg_val;
  97
  98        mutex_lock(&chip->lock);
  99        pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS;
 100        pm |= (1 << nr);
 101        iowrite32(pm, &chip->reg->pm);
 102
 103        reg_val = ioread32(&chip->reg->po);
 104        if (val)
 105                reg_val |= (1 << nr);
 106        else
 107                reg_val &= ~(1 << nr);
 108
 109        mutex_unlock(&chip->lock);
 110
 111        return 0;
 112}
 113
 114static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
 115{
 116        struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
 117        u32 pm;
 118
 119        mutex_lock(&chip->lock);
 120        pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS; /*bits 0-11*/
 121        pm &= ~(1 << nr);
 122        iowrite32(pm, &chip->reg->pm);
 123        mutex_unlock(&chip->lock);
 124
 125        return 0;
 126}
 127
 128/*
 129 * Save register configuration and disable interrupts.
 130 */
 131static void pch_gpio_save_reg_conf(struct pch_gpio *chip)
 132{
 133        chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po);
 134        chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm);
 135}
 136
 137/*
 138 * This function restores the register configuration of the GPIO device.
 139 */
 140static void pch_gpio_restore_reg_conf(struct pch_gpio *chip)
 141{
 142        /* to store contents of PO register */
 143        iowrite32(chip->pch_gpio_reg.po_reg, &chip->reg->po);
 144        /* to store contents of PM register */
 145        iowrite32(chip->pch_gpio_reg.pm_reg, &chip->reg->pm);
 146}
 147
 148static void pch_gpio_setup(struct pch_gpio *chip)
 149{
 150        struct gpio_chip *gpio = &chip->gpio;
 151
 152        gpio->label = dev_name(chip->dev);
 153        gpio->owner = THIS_MODULE;
 154        gpio->direction_input = pch_gpio_direction_input;
 155        gpio->get = pch_gpio_get;
 156        gpio->direction_output = pch_gpio_direction_output;
 157        gpio->set = pch_gpio_set;
 158        gpio->dbg_show = NULL;
 159        gpio->base = -1;
 160        gpio->ngpio = GPIO_NUM_PINS;
 161        gpio->can_sleep = 0;
 162}
 163
 164static int __devinit pch_gpio_probe(struct pci_dev *pdev,
 165                                    const struct pci_device_id *id)
 166{
 167        s32 ret;
 168        struct pch_gpio *chip;
 169
 170        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 171        if (chip == NULL)
 172                return -ENOMEM;
 173
 174        chip->dev = &pdev->dev;
 175        ret = pci_enable_device(pdev);
 176        if (ret) {
 177                dev_err(&pdev->dev, "%s : pci_enable_device FAILED", __func__);
 178                goto err_pci_enable;
 179        }
 180
 181        ret = pci_request_regions(pdev, KBUILD_MODNAME);
 182        if (ret) {
 183                dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret);
 184                goto err_request_regions;
 185        }
 186
 187        chip->base = pci_iomap(pdev, 1, 0);
 188        if (chip->base == 0) {
 189                dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
 190                ret = -ENOMEM;
 191                goto err_iomap;
 192        }
 193
 194        chip->reg = chip->base;
 195        pci_set_drvdata(pdev, chip);
 196        mutex_init(&chip->lock);
 197        pch_gpio_setup(chip);
 198        ret = gpiochip_add(&chip->gpio);
 199        if (ret) {
 200                dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n");
 201                goto err_gpiochip_add;
 202        }
 203
 204        return 0;
 205
 206err_gpiochip_add:
 207        pci_iounmap(pdev, chip->base);
 208
 209err_iomap:
 210        pci_release_regions(pdev);
 211
 212err_request_regions:
 213        pci_disable_device(pdev);
 214
 215err_pci_enable:
 216        kfree(chip);
 217        dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret);
 218        return ret;
 219}
 220
 221static void __devexit pch_gpio_remove(struct pci_dev *pdev)
 222{
 223        int err;
 224        struct pch_gpio *chip = pci_get_drvdata(pdev);
 225
 226        err = gpiochip_remove(&chip->gpio);
 227        if (err)
 228                dev_err(&pdev->dev, "Failed gpiochip_remove\n");
 229
 230        pci_iounmap(pdev, chip->base);
 231        pci_release_regions(pdev);
 232        pci_disable_device(pdev);
 233        kfree(chip);
 234}
 235
 236#ifdef CONFIG_PM
 237static int pch_gpio_suspend(struct pci_dev *pdev, pm_message_t state)
 238{
 239        s32 ret;
 240        struct pch_gpio *chip = pci_get_drvdata(pdev);
 241
 242        pch_gpio_save_reg_conf(chip);
 243        pch_gpio_restore_reg_conf(chip);
 244
 245        ret = pci_save_state(pdev);
 246        if (ret) {
 247                dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret);
 248                return ret;
 249        }
 250        pci_disable_device(pdev);
 251        pci_set_power_state(pdev, PCI_D0);
 252        ret = pci_enable_wake(pdev, PCI_D0, 1);
 253        if (ret)
 254                dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret);
 255
 256        return 0;
 257}
 258
 259static int pch_gpio_resume(struct pci_dev *pdev)
 260{
 261        s32 ret;
 262        struct pch_gpio *chip = pci_get_drvdata(pdev);
 263
 264        ret = pci_enable_wake(pdev, PCI_D0, 0);
 265
 266        pci_set_power_state(pdev, PCI_D0);
 267        ret = pci_enable_device(pdev);
 268        if (ret) {
 269                dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret);
 270                return ret;
 271        }
 272        pci_restore_state(pdev);
 273
 274        iowrite32(0x01, &chip->reg->reset);
 275        iowrite32(0x00, &chip->reg->reset);
 276        pch_gpio_restore_reg_conf(chip);
 277
 278        return 0;
 279}
 280#else
 281#define pch_gpio_suspend NULL
 282#define pch_gpio_resume NULL
 283#endif
 284
 285static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = {
 286        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) },
 287        { 0, }
 288};
 289MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id);
 290
 291static struct pci_driver pch_gpio_driver = {
 292        .name = "pch_gpio",
 293        .id_table = pch_gpio_pcidev_id,
 294        .probe = pch_gpio_probe,
 295        .remove = __devexit_p(pch_gpio_remove),
 296        .suspend = pch_gpio_suspend,
 297        .resume = pch_gpio_resume
 298};
 299
 300static int __init pch_gpio_pci_init(void)
 301{
 302        return pci_register_driver(&pch_gpio_driver);
 303}
 304module_init(pch_gpio_pci_init);
 305
 306static void __exit pch_gpio_pci_exit(void)
 307{
 308        pci_unregister_driver(&pch_gpio_driver);
 309}
 310module_exit(pch_gpio_pci_exit);
 311
 312MODULE_DESCRIPTION("PCH GPIO PCI Driver");
 313MODULE_LICENSE("GPL");
 314