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