root/drivers/gpio/gpio-bt8xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bt8xxgpio_gpio_direction_input
  2. bt8xxgpio_gpio_get
  3. bt8xxgpio_gpio_direction_output
  4. bt8xxgpio_gpio_set
  5. bt8xxgpio_gpio_setup
  6. bt8xxgpio_probe
  7. bt8xxgpio_remove
  8. bt8xxgpio_suspend
  9. bt8xxgpio_resume

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3 
   4     bt8xx GPIO abuser
   5 
   6     Copyright (C) 2008 Michael Buesch <m@bues.ch>
   7 
   8     Please do _only_ contact the people listed _above_ with issues related to this driver.
   9     All the other people listed below are not related to this driver. Their names
  10     are only here, because this driver is derived from the bt848 driver.
  11 
  12 
  13     Derived from the bt848 driver:
  14 
  15     Copyright (C) 1996,97,98 Ralph  Metzler
  16                            & Marcus Metzler
  17     (c) 1999-2002 Gerd Knorr
  18 
  19     some v4l2 code lines are taken from Justin's bttv2 driver which is
  20     (c) 2000 Justin Schoeman
  21 
  22     V4L1 removal from:
  23     (c) 2005-2006 Nickolay V. Shmyrev
  24 
  25     Fixes to be fully V4L2 compliant by
  26     (c) 2006 Mauro Carvalho Chehab
  27 
  28     Cropping and overscan support
  29     Copyright (C) 2005, 2006 Michael H. Schimek
  30     Sponsored by OPQ Systems AB
  31 
  32 */
  33 
  34 #include <linux/module.h>
  35 #include <linux/pci.h>
  36 #include <linux/spinlock.h>
  37 #include <linux/gpio/driver.h>
  38 #include <linux/slab.h>
  39 
  40 /* Steal the hardware definitions from the bttv driver. */
  41 #include "../media/pci/bt8xx/bt848.h"
  42 
  43 
  44 #define BT8XXGPIO_NR_GPIOS              24 /* We have 24 GPIO pins */
  45 
  46 
  47 struct bt8xxgpio {
  48         spinlock_t lock;
  49 
  50         void __iomem *mmio;
  51         struct pci_dev *pdev;
  52         struct gpio_chip gpio;
  53 
  54 #ifdef CONFIG_PM
  55         u32 saved_outen;
  56         u32 saved_data;
  57 #endif
  58 };
  59 
  60 #define bgwrite(dat, adr)       writel((dat), bg->mmio+(adr))
  61 #define bgread(adr)             readl(bg->mmio+(adr))
  62 
  63 
  64 static int modparam_gpiobase = -1/* dynamic */;
  65 module_param_named(gpiobase, modparam_gpiobase, int, 0444);
  66 MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default.");
  67 
  68 
  69 static int bt8xxgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
  70 {
  71         struct bt8xxgpio *bg = gpiochip_get_data(gpio);
  72         unsigned long flags;
  73         u32 outen, data;
  74 
  75         spin_lock_irqsave(&bg->lock, flags);
  76 
  77         data = bgread(BT848_GPIO_DATA);
  78         data &= ~(1 << nr);
  79         bgwrite(data, BT848_GPIO_DATA);
  80 
  81         outen = bgread(BT848_GPIO_OUT_EN);
  82         outen &= ~(1 << nr);
  83         bgwrite(outen, BT848_GPIO_OUT_EN);
  84 
  85         spin_unlock_irqrestore(&bg->lock, flags);
  86 
  87         return 0;
  88 }
  89 
  90 static int bt8xxgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
  91 {
  92         struct bt8xxgpio *bg = gpiochip_get_data(gpio);
  93         unsigned long flags;
  94         u32 val;
  95 
  96         spin_lock_irqsave(&bg->lock, flags);
  97         val = bgread(BT848_GPIO_DATA);
  98         spin_unlock_irqrestore(&bg->lock, flags);
  99 
 100         return !!(val & (1 << nr));
 101 }
 102 
 103 static int bt8xxgpio_gpio_direction_output(struct gpio_chip *gpio,
 104                                         unsigned nr, int val)
 105 {
 106         struct bt8xxgpio *bg = gpiochip_get_data(gpio);
 107         unsigned long flags;
 108         u32 outen, data;
 109 
 110         spin_lock_irqsave(&bg->lock, flags);
 111 
 112         outen = bgread(BT848_GPIO_OUT_EN);
 113         outen |= (1 << nr);
 114         bgwrite(outen, BT848_GPIO_OUT_EN);
 115 
 116         data = bgread(BT848_GPIO_DATA);
 117         if (val)
 118                 data |= (1 << nr);
 119         else
 120                 data &= ~(1 << nr);
 121         bgwrite(data, BT848_GPIO_DATA);
 122 
 123         spin_unlock_irqrestore(&bg->lock, flags);
 124 
 125         return 0;
 126 }
 127 
 128 static void bt8xxgpio_gpio_set(struct gpio_chip *gpio,
 129                             unsigned nr, int val)
 130 {
 131         struct bt8xxgpio *bg = gpiochip_get_data(gpio);
 132         unsigned long flags;
 133         u32 data;
 134 
 135         spin_lock_irqsave(&bg->lock, flags);
 136 
 137         data = bgread(BT848_GPIO_DATA);
 138         if (val)
 139                 data |= (1 << nr);
 140         else
 141                 data &= ~(1 << nr);
 142         bgwrite(data, BT848_GPIO_DATA);
 143 
 144         spin_unlock_irqrestore(&bg->lock, flags);
 145 }
 146 
 147 static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
 148 {
 149         struct gpio_chip *c = &bg->gpio;
 150 
 151         c->label = dev_name(&bg->pdev->dev);
 152         c->owner = THIS_MODULE;
 153         c->direction_input = bt8xxgpio_gpio_direction_input;
 154         c->get = bt8xxgpio_gpio_get;
 155         c->direction_output = bt8xxgpio_gpio_direction_output;
 156         c->set = bt8xxgpio_gpio_set;
 157         c->dbg_show = NULL;
 158         c->base = modparam_gpiobase;
 159         c->ngpio = BT8XXGPIO_NR_GPIOS;
 160         c->can_sleep = false;
 161 }
 162 
 163 static int bt8xxgpio_probe(struct pci_dev *dev,
 164                         const struct pci_device_id *pci_id)
 165 {
 166         struct bt8xxgpio *bg;
 167         int err;
 168 
 169         bg = devm_kzalloc(&dev->dev, sizeof(struct bt8xxgpio), GFP_KERNEL);
 170         if (!bg)
 171                 return -ENOMEM;
 172 
 173         bg->pdev = dev;
 174         spin_lock_init(&bg->lock);
 175 
 176         err = pci_enable_device(dev);
 177         if (err) {
 178                 printk(KERN_ERR "bt8xxgpio: Can't enable device.\n");
 179                 return err;
 180         }
 181         if (!devm_request_mem_region(&dev->dev, pci_resource_start(dev, 0),
 182                                 pci_resource_len(dev, 0),
 183                                 "bt8xxgpio")) {
 184                 printk(KERN_WARNING "bt8xxgpio: Can't request iomem (0x%llx).\n",
 185                        (unsigned long long)pci_resource_start(dev, 0));
 186                 err = -EBUSY;
 187                 goto err_disable;
 188         }
 189         pci_set_master(dev);
 190         pci_set_drvdata(dev, bg);
 191 
 192         bg->mmio = devm_ioremap(&dev->dev, pci_resource_start(dev, 0), 0x1000);
 193         if (!bg->mmio) {
 194                 printk(KERN_ERR "bt8xxgpio: ioremap() failed\n");
 195                 err = -EIO;
 196                 goto err_disable;
 197         }
 198 
 199         /* Disable interrupts */
 200         bgwrite(0, BT848_INT_MASK);
 201 
 202         /* gpio init */
 203         bgwrite(0, BT848_GPIO_DMA_CTL);
 204         bgwrite(0, BT848_GPIO_REG_INP);
 205         bgwrite(0, BT848_GPIO_OUT_EN);
 206 
 207         bt8xxgpio_gpio_setup(bg);
 208         err = gpiochip_add_data(&bg->gpio, bg);
 209         if (err) {
 210                 printk(KERN_ERR "bt8xxgpio: Failed to register GPIOs\n");
 211                 goto err_disable;
 212         }
 213 
 214         return 0;
 215 
 216 err_disable:
 217         pci_disable_device(dev);
 218 
 219         return err;
 220 }
 221 
 222 static void bt8xxgpio_remove(struct pci_dev *pdev)
 223 {
 224         struct bt8xxgpio *bg = pci_get_drvdata(pdev);
 225 
 226         gpiochip_remove(&bg->gpio);
 227 
 228         bgwrite(0, BT848_INT_MASK);
 229         bgwrite(~0x0, BT848_INT_STAT);
 230         bgwrite(0x0, BT848_GPIO_OUT_EN);
 231 
 232         pci_disable_device(pdev);
 233 }
 234 
 235 #ifdef CONFIG_PM
 236 static int bt8xxgpio_suspend(struct pci_dev *pdev, pm_message_t state)
 237 {
 238         struct bt8xxgpio *bg = pci_get_drvdata(pdev);
 239         unsigned long flags;
 240 
 241         spin_lock_irqsave(&bg->lock, flags);
 242 
 243         bg->saved_outen = bgread(BT848_GPIO_OUT_EN);
 244         bg->saved_data = bgread(BT848_GPIO_DATA);
 245 
 246         bgwrite(0, BT848_INT_MASK);
 247         bgwrite(~0x0, BT848_INT_STAT);
 248         bgwrite(0x0, BT848_GPIO_OUT_EN);
 249 
 250         spin_unlock_irqrestore(&bg->lock, flags);
 251 
 252         pci_save_state(pdev);
 253         pci_disable_device(pdev);
 254         pci_set_power_state(pdev, pci_choose_state(pdev, state));
 255 
 256         return 0;
 257 }
 258 
 259 static int bt8xxgpio_resume(struct pci_dev *pdev)
 260 {
 261         struct bt8xxgpio *bg = pci_get_drvdata(pdev);
 262         unsigned long flags;
 263         int err;
 264 
 265         pci_set_power_state(pdev, PCI_D0);
 266         err = pci_enable_device(pdev);
 267         if (err)
 268                 return err;
 269         pci_restore_state(pdev);
 270 
 271         spin_lock_irqsave(&bg->lock, flags);
 272 
 273         bgwrite(0, BT848_INT_MASK);
 274         bgwrite(0, BT848_GPIO_DMA_CTL);
 275         bgwrite(0, BT848_GPIO_REG_INP);
 276         bgwrite(bg->saved_outen, BT848_GPIO_OUT_EN);
 277         bgwrite(bg->saved_data & bg->saved_outen,
 278                 BT848_GPIO_DATA);
 279 
 280         spin_unlock_irqrestore(&bg->lock, flags);
 281 
 282         return 0;
 283 }
 284 #else
 285 #define bt8xxgpio_suspend NULL
 286 #define bt8xxgpio_resume NULL
 287 #endif /* CONFIG_PM */
 288 
 289 static const struct pci_device_id bt8xxgpio_pci_tbl[] = {
 290         { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848) },
 291         { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849) },
 292         { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878) },
 293         { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879) },
 294         { 0, },
 295 };
 296 MODULE_DEVICE_TABLE(pci, bt8xxgpio_pci_tbl);
 297 
 298 static struct pci_driver bt8xxgpio_pci_driver = {
 299         .name           = "bt8xxgpio",
 300         .id_table       = bt8xxgpio_pci_tbl,
 301         .probe          = bt8xxgpio_probe,
 302         .remove         = bt8xxgpio_remove,
 303         .suspend        = bt8xxgpio_suspend,
 304         .resume         = bt8xxgpio_resume,
 305 };
 306 
 307 module_pci_driver(bt8xxgpio_pci_driver);
 308 
 309 MODULE_LICENSE("GPL");
 310 MODULE_AUTHOR("Michael Buesch");
 311 MODULE_DESCRIPTION("Abuse a BT8xx framegrabber card as generic GPIO card");

/* [<][>][^][v][top][bottom][index][help] */