Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003 
0004     bt8xx GPIO abuser
0005 
0006     Copyright (C) 2008 Michael Buesch <m@bues.ch>
0007 
0008     Please do _only_ contact the people listed _above_ with issues related to this driver.
0009     All the other people listed below are not related to this driver. Their names
0010     are only here, because this driver is derived from the bt848 driver.
0011 
0012 
0013     Derived from the bt848 driver:
0014 
0015     Copyright (C) 1996,97,98 Ralph  Metzler
0016                & Marcus Metzler
0017     (c) 1999-2002 Gerd Knorr
0018 
0019     some v4l2 code lines are taken from Justin's bttv2 driver which is
0020     (c) 2000 Justin Schoeman
0021 
0022     V4L1 removal from:
0023     (c) 2005-2006 Nickolay V. Shmyrev
0024 
0025     Fixes to be fully V4L2 compliant by
0026     (c) 2006 Mauro Carvalho Chehab
0027 
0028     Cropping and overscan support
0029     Copyright (C) 2005, 2006 Michael H. Schimek
0030     Sponsored by OPQ Systems AB
0031 
0032 */
0033 
0034 #include <linux/module.h>
0035 #include <linux/pci.h>
0036 #include <linux/spinlock.h>
0037 #include <linux/gpio/driver.h>
0038 #include <linux/slab.h>
0039 
0040 /* Steal the hardware definitions from the bttv driver. */
0041 #include "../media/pci/bt8xx/bt848.h"
0042 
0043 
0044 #define BT8XXGPIO_NR_GPIOS      24 /* We have 24 GPIO pins */
0045 
0046 
0047 struct bt8xxgpio {
0048     spinlock_t lock;
0049 
0050     void __iomem *mmio;
0051     struct pci_dev *pdev;
0052     struct gpio_chip gpio;
0053 
0054 #ifdef CONFIG_PM
0055     u32 saved_outen;
0056     u32 saved_data;
0057 #endif
0058 };
0059 
0060 #define bgwrite(dat, adr)   writel((dat), bg->mmio+(adr))
0061 #define bgread(adr)     readl(bg->mmio+(adr))
0062 
0063 
0064 static int modparam_gpiobase = -1/* dynamic */;
0065 module_param_named(gpiobase, modparam_gpiobase, int, 0444);
0066 MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default.");
0067 
0068 
0069 static int bt8xxgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
0070 {
0071     struct bt8xxgpio *bg = gpiochip_get_data(gpio);
0072     unsigned long flags;
0073     u32 outen, data;
0074 
0075     spin_lock_irqsave(&bg->lock, flags);
0076 
0077     data = bgread(BT848_GPIO_DATA);
0078     data &= ~(1 << nr);
0079     bgwrite(data, BT848_GPIO_DATA);
0080 
0081     outen = bgread(BT848_GPIO_OUT_EN);
0082     outen &= ~(1 << nr);
0083     bgwrite(outen, BT848_GPIO_OUT_EN);
0084 
0085     spin_unlock_irqrestore(&bg->lock, flags);
0086 
0087     return 0;
0088 }
0089 
0090 static int bt8xxgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
0091 {
0092     struct bt8xxgpio *bg = gpiochip_get_data(gpio);
0093     unsigned long flags;
0094     u32 val;
0095 
0096     spin_lock_irqsave(&bg->lock, flags);
0097     val = bgread(BT848_GPIO_DATA);
0098     spin_unlock_irqrestore(&bg->lock, flags);
0099 
0100     return !!(val & (1 << nr));
0101 }
0102 
0103 static int bt8xxgpio_gpio_direction_output(struct gpio_chip *gpio,
0104                     unsigned nr, int val)
0105 {
0106     struct bt8xxgpio *bg = gpiochip_get_data(gpio);
0107     unsigned long flags;
0108     u32 outen, data;
0109 
0110     spin_lock_irqsave(&bg->lock, flags);
0111 
0112     outen = bgread(BT848_GPIO_OUT_EN);
0113     outen |= (1 << nr);
0114     bgwrite(outen, BT848_GPIO_OUT_EN);
0115 
0116     data = bgread(BT848_GPIO_DATA);
0117     if (val)
0118         data |= (1 << nr);
0119     else
0120         data &= ~(1 << nr);
0121     bgwrite(data, BT848_GPIO_DATA);
0122 
0123     spin_unlock_irqrestore(&bg->lock, flags);
0124 
0125     return 0;
0126 }
0127 
0128 static void bt8xxgpio_gpio_set(struct gpio_chip *gpio,
0129                 unsigned nr, int val)
0130 {
0131     struct bt8xxgpio *bg = gpiochip_get_data(gpio);
0132     unsigned long flags;
0133     u32 data;
0134 
0135     spin_lock_irqsave(&bg->lock, flags);
0136 
0137     data = bgread(BT848_GPIO_DATA);
0138     if (val)
0139         data |= (1 << nr);
0140     else
0141         data &= ~(1 << nr);
0142     bgwrite(data, BT848_GPIO_DATA);
0143 
0144     spin_unlock_irqrestore(&bg->lock, flags);
0145 }
0146 
0147 static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
0148 {
0149     struct gpio_chip *c = &bg->gpio;
0150 
0151     c->label = dev_name(&bg->pdev->dev);
0152     c->owner = THIS_MODULE;
0153     c->direction_input = bt8xxgpio_gpio_direction_input;
0154     c->get = bt8xxgpio_gpio_get;
0155     c->direction_output = bt8xxgpio_gpio_direction_output;
0156     c->set = bt8xxgpio_gpio_set;
0157     c->dbg_show = NULL;
0158     c->base = modparam_gpiobase;
0159     c->ngpio = BT8XXGPIO_NR_GPIOS;
0160     c->can_sleep = false;
0161 }
0162 
0163 static int bt8xxgpio_probe(struct pci_dev *dev,
0164             const struct pci_device_id *pci_id)
0165 {
0166     struct bt8xxgpio *bg;
0167     int err;
0168 
0169     bg = devm_kzalloc(&dev->dev, sizeof(struct bt8xxgpio), GFP_KERNEL);
0170     if (!bg)
0171         return -ENOMEM;
0172 
0173     bg->pdev = dev;
0174     spin_lock_init(&bg->lock);
0175 
0176     err = pci_enable_device(dev);
0177     if (err) {
0178         dev_err(&dev->dev, "can't enable device.\n");
0179         return err;
0180     }
0181     if (!devm_request_mem_region(&dev->dev, pci_resource_start(dev, 0),
0182                 pci_resource_len(dev, 0),
0183                 "bt8xxgpio")) {
0184         dev_warn(&dev->dev, "can't request iomem (0x%llx).\n",
0185                (unsigned long long)pci_resource_start(dev, 0));
0186         err = -EBUSY;
0187         goto err_disable;
0188     }
0189     pci_set_master(dev);
0190     pci_set_drvdata(dev, bg);
0191 
0192     bg->mmio = devm_ioremap(&dev->dev, pci_resource_start(dev, 0), 0x1000);
0193     if (!bg->mmio) {
0194         dev_err(&dev->dev, "ioremap() failed\n");
0195         err = -EIO;
0196         goto err_disable;
0197     }
0198 
0199     /* Disable interrupts */
0200     bgwrite(0, BT848_INT_MASK);
0201 
0202     /* gpio init */
0203     bgwrite(0, BT848_GPIO_DMA_CTL);
0204     bgwrite(0, BT848_GPIO_REG_INP);
0205     bgwrite(0, BT848_GPIO_OUT_EN);
0206 
0207     bt8xxgpio_gpio_setup(bg);
0208     err = gpiochip_add_data(&bg->gpio, bg);
0209     if (err) {
0210         dev_err(&dev->dev, "failed to register GPIOs\n");
0211         goto err_disable;
0212     }
0213 
0214     return 0;
0215 
0216 err_disable:
0217     pci_disable_device(dev);
0218 
0219     return err;
0220 }
0221 
0222 static void bt8xxgpio_remove(struct pci_dev *pdev)
0223 {
0224     struct bt8xxgpio *bg = pci_get_drvdata(pdev);
0225 
0226     gpiochip_remove(&bg->gpio);
0227 
0228     bgwrite(0, BT848_INT_MASK);
0229     bgwrite(~0x0, BT848_INT_STAT);
0230     bgwrite(0x0, BT848_GPIO_OUT_EN);
0231 
0232     pci_disable_device(pdev);
0233 }
0234 
0235 #ifdef CONFIG_PM
0236 static int bt8xxgpio_suspend(struct pci_dev *pdev, pm_message_t state)
0237 {
0238     struct bt8xxgpio *bg = pci_get_drvdata(pdev);
0239     unsigned long flags;
0240 
0241     spin_lock_irqsave(&bg->lock, flags);
0242 
0243     bg->saved_outen = bgread(BT848_GPIO_OUT_EN);
0244     bg->saved_data = bgread(BT848_GPIO_DATA);
0245 
0246     bgwrite(0, BT848_INT_MASK);
0247     bgwrite(~0x0, BT848_INT_STAT);
0248     bgwrite(0x0, BT848_GPIO_OUT_EN);
0249 
0250     spin_unlock_irqrestore(&bg->lock, flags);
0251 
0252     pci_save_state(pdev);
0253     pci_disable_device(pdev);
0254     pci_set_power_state(pdev, pci_choose_state(pdev, state));
0255 
0256     return 0;
0257 }
0258 
0259 static int bt8xxgpio_resume(struct pci_dev *pdev)
0260 {
0261     struct bt8xxgpio *bg = pci_get_drvdata(pdev);
0262     unsigned long flags;
0263     int err;
0264 
0265     pci_set_power_state(pdev, PCI_D0);
0266     err = pci_enable_device(pdev);
0267     if (err)
0268         return err;
0269     pci_restore_state(pdev);
0270 
0271     spin_lock_irqsave(&bg->lock, flags);
0272 
0273     bgwrite(0, BT848_INT_MASK);
0274     bgwrite(0, BT848_GPIO_DMA_CTL);
0275     bgwrite(0, BT848_GPIO_REG_INP);
0276     bgwrite(bg->saved_outen, BT848_GPIO_OUT_EN);
0277     bgwrite(bg->saved_data & bg->saved_outen,
0278         BT848_GPIO_DATA);
0279 
0280     spin_unlock_irqrestore(&bg->lock, flags);
0281 
0282     return 0;
0283 }
0284 #else
0285 #define bt8xxgpio_suspend NULL
0286 #define bt8xxgpio_resume NULL
0287 #endif /* CONFIG_PM */
0288 
0289 static const struct pci_device_id bt8xxgpio_pci_tbl[] = {
0290     { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848) },
0291     { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849) },
0292     { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878) },
0293     { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879) },
0294     { 0, },
0295 };
0296 MODULE_DEVICE_TABLE(pci, bt8xxgpio_pci_tbl);
0297 
0298 static struct pci_driver bt8xxgpio_pci_driver = {
0299     .name       = "bt8xxgpio",
0300     .id_table   = bt8xxgpio_pci_tbl,
0301     .probe      = bt8xxgpio_probe,
0302     .remove     = bt8xxgpio_remove,
0303     .suspend    = bt8xxgpio_suspend,
0304     .resume     = bt8xxgpio_resume,
0305 };
0306 
0307 module_pci_driver(bt8xxgpio_pci_driver);
0308 
0309 MODULE_LICENSE("GPL");
0310 MODULE_AUTHOR("Michael Buesch");
0311 MODULE_DESCRIPTION("Abuse a BT8xx framegrabber card as generic GPIO card");