1 // SPDX-License-Identifier: GPL-2.0-or-later
6 Copyright (C) 2008 Michael Buesch <m@bues.ch>
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.
13 Derived from the bt848 driver:
15 Copyright (C) 1996,97,98 Ralph Metzler
17 (c) 1999-2002 Gerd Knorr
19 some v4l2 code lines are taken from Justin's bttv2 driver which is
20 (c) 2000 Justin Schoeman
23 (c) 2005-2006 Nickolay V. Shmyrev
25 Fixes to be fully V4L2 compliant by
26 (c) 2006 Mauro Carvalho Chehab
28 Cropping and overscan support
29 Copyright (C) 2005, 2006 Michael H. Schimek
30 Sponsored by OPQ Systems AB
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>
40 /* Steal the hardware definitions from the bttv driver. */
41 #include "../media/pci/bt8xx/bt848.h"
44 #define BT8XXGPIO_NR_GPIOS 24 /* We have 24 GPIO pins */
52 struct gpio_chip gpio
;
60 #define bgwrite(dat, adr) writel((dat), bg->mmio+(adr))
61 #define bgread(adr) readl(bg->mmio+(adr))
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.");
69 static int bt8xxgpio_gpio_direction_input(struct gpio_chip
*gpio
, unsigned nr
)
71 struct bt8xxgpio
*bg
= gpiochip_get_data(gpio
);
75 spin_lock_irqsave(&bg
->lock
, flags
);
77 data
= bgread(BT848_GPIO_DATA
);
79 bgwrite(data
, BT848_GPIO_DATA
);
81 outen
= bgread(BT848_GPIO_OUT_EN
);
83 bgwrite(outen
, BT848_GPIO_OUT_EN
);
85 spin_unlock_irqrestore(&bg
->lock
, flags
);
90 static int bt8xxgpio_gpio_get(struct gpio_chip
*gpio
, unsigned nr
)
92 struct bt8xxgpio
*bg
= gpiochip_get_data(gpio
);
96 spin_lock_irqsave(&bg
->lock
, flags
);
97 val
= bgread(BT848_GPIO_DATA
);
98 spin_unlock_irqrestore(&bg
->lock
, flags
);
100 return !!(val
& (1 << nr
));
103 static int bt8xxgpio_gpio_direction_output(struct gpio_chip
*gpio
,
104 unsigned nr
, int val
)
106 struct bt8xxgpio
*bg
= gpiochip_get_data(gpio
);
110 spin_lock_irqsave(&bg
->lock
, flags
);
112 outen
= bgread(BT848_GPIO_OUT_EN
);
114 bgwrite(outen
, BT848_GPIO_OUT_EN
);
116 data
= bgread(BT848_GPIO_DATA
);
121 bgwrite(data
, BT848_GPIO_DATA
);
123 spin_unlock_irqrestore(&bg
->lock
, flags
);
128 static void bt8xxgpio_gpio_set(struct gpio_chip
*gpio
,
129 unsigned nr
, int val
)
131 struct bt8xxgpio
*bg
= gpiochip_get_data(gpio
);
135 spin_lock_irqsave(&bg
->lock
, flags
);
137 data
= bgread(BT848_GPIO_DATA
);
142 bgwrite(data
, BT848_GPIO_DATA
);
144 spin_unlock_irqrestore(&bg
->lock
, flags
);
147 static void bt8xxgpio_gpio_setup(struct bt8xxgpio
*bg
)
149 struct gpio_chip
*c
= &bg
->gpio
;
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
;
158 c
->base
= modparam_gpiobase
;
159 c
->ngpio
= BT8XXGPIO_NR_GPIOS
;
160 c
->can_sleep
= false;
163 static int bt8xxgpio_probe(struct pci_dev
*dev
,
164 const struct pci_device_id
*pci_id
)
166 struct bt8xxgpio
*bg
;
169 bg
= devm_kzalloc(&dev
->dev
, sizeof(struct bt8xxgpio
), GFP_KERNEL
);
174 spin_lock_init(&bg
->lock
);
176 err
= pci_enable_device(dev
);
178 dev_err(&dev
->dev
, "can't enable device.\n");
181 if (!devm_request_mem_region(&dev
->dev
, pci_resource_start(dev
, 0),
182 pci_resource_len(dev
, 0),
184 dev_warn(&dev
->dev
, "can't request iomem (0x%llx).\n",
185 (unsigned long long)pci_resource_start(dev
, 0));
190 pci_set_drvdata(dev
, bg
);
192 bg
->mmio
= devm_ioremap(&dev
->dev
, pci_resource_start(dev
, 0), 0x1000);
194 dev_err(&dev
->dev
, "ioremap() failed\n");
199 /* Disable interrupts */
200 bgwrite(0, BT848_INT_MASK
);
203 bgwrite(0, BT848_GPIO_DMA_CTL
);
204 bgwrite(0, BT848_GPIO_REG_INP
);
205 bgwrite(0, BT848_GPIO_OUT_EN
);
207 bt8xxgpio_gpio_setup(bg
);
208 err
= gpiochip_add_data(&bg
->gpio
, bg
);
210 dev_err(&dev
->dev
, "failed to register GPIOs\n");
217 pci_disable_device(dev
);
222 static void bt8xxgpio_remove(struct pci_dev
*pdev
)
224 struct bt8xxgpio
*bg
= pci_get_drvdata(pdev
);
226 gpiochip_remove(&bg
->gpio
);
228 bgwrite(0, BT848_INT_MASK
);
229 bgwrite(~0x0, BT848_INT_STAT
);
230 bgwrite(0x0, BT848_GPIO_OUT_EN
);
232 pci_disable_device(pdev
);
236 static int bt8xxgpio_suspend(struct pci_dev
*pdev
, pm_message_t state
)
238 struct bt8xxgpio
*bg
= pci_get_drvdata(pdev
);
241 spin_lock_irqsave(&bg
->lock
, flags
);
243 bg
->saved_outen
= bgread(BT848_GPIO_OUT_EN
);
244 bg
->saved_data
= bgread(BT848_GPIO_DATA
);
246 bgwrite(0, BT848_INT_MASK
);
247 bgwrite(~0x0, BT848_INT_STAT
);
248 bgwrite(0x0, BT848_GPIO_OUT_EN
);
250 spin_unlock_irqrestore(&bg
->lock
, flags
);
252 pci_save_state(pdev
);
253 pci_disable_device(pdev
);
254 pci_set_power_state(pdev
, pci_choose_state(pdev
, state
));
259 static int bt8xxgpio_resume(struct pci_dev
*pdev
)
261 struct bt8xxgpio
*bg
= pci_get_drvdata(pdev
);
265 pci_set_power_state(pdev
, PCI_D0
);
266 err
= pci_enable_device(pdev
);
269 pci_restore_state(pdev
);
271 spin_lock_irqsave(&bg
->lock
, flags
);
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
,
280 spin_unlock_irqrestore(&bg
->lock
, flags
);
285 #define bt8xxgpio_suspend NULL
286 #define bt8xxgpio_resume NULL
287 #endif /* CONFIG_PM */
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
) },
296 MODULE_DEVICE_TABLE(pci
, bt8xxgpio_pci_tbl
);
298 static struct pci_driver bt8xxgpio_pci_driver
= {
300 .id_table
= bt8xxgpio_pci_tbl
,
301 .probe
= bt8xxgpio_probe
,
302 .remove
= bt8xxgpio_remove
,
303 .suspend
= bt8xxgpio_suspend
,
304 .resume
= bt8xxgpio_resume
,
307 module_pci_driver(bt8xxgpio_pci_driver
);
309 MODULE_LICENSE("GPL");
310 MODULE_AUTHOR("Michael Buesch");
311 MODULE_DESCRIPTION("Abuse a BT8xx framegrabber card as generic GPIO card");