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/cleanup.h>
35 #include <linux/module.h>
36 #include <linux/pci.h>
37 #include <linux/spinlock.h>
38 #include <linux/gpio/driver.h>
39 #include <linux/slab.h>
40
41 /* Steal the hardware definitions from the bttv driver. */
42 #include "../media/pci/bt8xx/bt848.h"
43
44
45 #define BT8XXGPIO_NR_GPIOS 24 /* We have 24 GPIO pins */
46
47
48 struct bt8xxgpio {
49 spinlock_t lock;
50
51 void __iomem *mmio;
52 struct pci_dev *pdev;
53 struct gpio_chip gpio;
54
55 #ifdef CONFIG_PM
56 u32 saved_outen;
57 u32 saved_data;
58 #endif
59 };
60
61 #define bgwrite(dat, adr) writel((dat), bg->mmio+(adr))
62 #define bgread(adr) readl(bg->mmio+(adr))
63
64
65 static int modparam_gpiobase = -1/* dynamic */;
66 module_param_named(gpiobase, modparam_gpiobase, int, 0444);
67 MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default.");
68
69
bt8xxgpio_gpio_direction_input(struct gpio_chip * gpio,unsigned nr)70 static int bt8xxgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
71 {
72 struct bt8xxgpio *bg = gpiochip_get_data(gpio);
73 u32 outen, data;
74
75 guard(spinlock_irqsave)(&bg->lock);
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 return 0;
86 }
87
bt8xxgpio_gpio_get(struct gpio_chip * gpio,unsigned nr)88 static int bt8xxgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
89 {
90 struct bt8xxgpio *bg = gpiochip_get_data(gpio);
91 u32 val;
92
93 guard(spinlock_irqsave)(&bg->lock);
94
95 val = bgread(BT848_GPIO_DATA);
96
97 return !!(val & (1 << nr));
98 }
99
bt8xxgpio_gpio_direction_output(struct gpio_chip * gpio,unsigned nr,int val)100 static int bt8xxgpio_gpio_direction_output(struct gpio_chip *gpio,
101 unsigned nr, int val)
102 {
103 struct bt8xxgpio *bg = gpiochip_get_data(gpio);
104 u32 outen, data;
105
106 guard(spinlock_irqsave)(&bg->lock);
107
108 outen = bgread(BT848_GPIO_OUT_EN);
109 outen |= (1 << nr);
110 bgwrite(outen, BT848_GPIO_OUT_EN);
111
112 data = bgread(BT848_GPIO_DATA);
113 if (val)
114 data |= (1 << nr);
115 else
116 data &= ~(1 << nr);
117 bgwrite(data, BT848_GPIO_DATA);
118
119 return 0;
120 }
121
bt8xxgpio_gpio_set(struct gpio_chip * gpio,unsigned int nr,int val)122 static int bt8xxgpio_gpio_set(struct gpio_chip *gpio, unsigned int nr, int val)
123 {
124 struct bt8xxgpio *bg = gpiochip_get_data(gpio);
125 u32 data;
126
127 guard(spinlock_irqsave)(&bg->lock);
128
129 data = bgread(BT848_GPIO_DATA);
130 if (val)
131 data |= (1 << nr);
132 else
133 data &= ~(1 << nr);
134 bgwrite(data, BT848_GPIO_DATA);
135
136 return 0;
137 }
138
bt8xxgpio_gpio_setup(struct bt8xxgpio * bg)139 static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
140 {
141 struct gpio_chip *c = &bg->gpio;
142
143 c->label = dev_name(&bg->pdev->dev);
144 c->owner = THIS_MODULE;
145 c->direction_input = bt8xxgpio_gpio_direction_input;
146 c->get = bt8xxgpio_gpio_get;
147 c->direction_output = bt8xxgpio_gpio_direction_output;
148 c->set_rv = bt8xxgpio_gpio_set;
149 c->dbg_show = NULL;
150 c->base = modparam_gpiobase;
151 c->ngpio = BT8XXGPIO_NR_GPIOS;
152 c->can_sleep = false;
153 }
154
bt8xxgpio_probe(struct pci_dev * dev,const struct pci_device_id * pci_id)155 static int bt8xxgpio_probe(struct pci_dev *dev,
156 const struct pci_device_id *pci_id)
157 {
158 struct bt8xxgpio *bg;
159 int err;
160
161 bg = devm_kzalloc(&dev->dev, sizeof(struct bt8xxgpio), GFP_KERNEL);
162 if (!bg)
163 return -ENOMEM;
164
165 bg->pdev = dev;
166 spin_lock_init(&bg->lock);
167
168 err = pci_enable_device(dev);
169 if (err) {
170 dev_err(&dev->dev, "can't enable device.\n");
171 return err;
172 }
173 if (!devm_request_mem_region(&dev->dev, pci_resource_start(dev, 0),
174 pci_resource_len(dev, 0),
175 "bt8xxgpio")) {
176 dev_warn(&dev->dev, "can't request iomem (0x%llx).\n",
177 (unsigned long long)pci_resource_start(dev, 0));
178 err = -EBUSY;
179 goto err_disable;
180 }
181 pci_set_master(dev);
182 pci_set_drvdata(dev, bg);
183
184 bg->mmio = devm_ioremap(&dev->dev, pci_resource_start(dev, 0), 0x1000);
185 if (!bg->mmio) {
186 dev_err(&dev->dev, "ioremap() failed\n");
187 err = -EIO;
188 goto err_disable;
189 }
190
191 /* Disable interrupts */
192 bgwrite(0, BT848_INT_MASK);
193
194 /* gpio init */
195 bgwrite(0, BT848_GPIO_DMA_CTL);
196 bgwrite(0, BT848_GPIO_REG_INP);
197 bgwrite(0, BT848_GPIO_OUT_EN);
198
199 bt8xxgpio_gpio_setup(bg);
200 err = gpiochip_add_data(&bg->gpio, bg);
201 if (err) {
202 dev_err(&dev->dev, "failed to register GPIOs\n");
203 goto err_disable;
204 }
205
206 return 0;
207
208 err_disable:
209 pci_disable_device(dev);
210
211 return err;
212 }
213
bt8xxgpio_remove(struct pci_dev * pdev)214 static void bt8xxgpio_remove(struct pci_dev *pdev)
215 {
216 struct bt8xxgpio *bg = pci_get_drvdata(pdev);
217
218 gpiochip_remove(&bg->gpio);
219
220 bgwrite(0, BT848_INT_MASK);
221 bgwrite(~0x0, BT848_INT_STAT);
222 bgwrite(0x0, BT848_GPIO_OUT_EN);
223
224 pci_disable_device(pdev);
225 }
226
227 #ifdef CONFIG_PM
bt8xxgpio_suspend(struct pci_dev * pdev,pm_message_t state)228 static int bt8xxgpio_suspend(struct pci_dev *pdev, pm_message_t state)
229 {
230 struct bt8xxgpio *bg = pci_get_drvdata(pdev);
231
232 scoped_guard(spinlock_irqsave, &bg->lock) {
233 bg->saved_outen = bgread(BT848_GPIO_OUT_EN);
234 bg->saved_data = bgread(BT848_GPIO_DATA);
235
236 bgwrite(0, BT848_INT_MASK);
237 bgwrite(~0x0, BT848_INT_STAT);
238 bgwrite(0x0, BT848_GPIO_OUT_EN);
239 }
240
241 pci_save_state(pdev);
242 pci_disable_device(pdev);
243 pci_set_power_state(pdev, pci_choose_state(pdev, state));
244
245 return 0;
246 }
247
bt8xxgpio_resume(struct pci_dev * pdev)248 static int bt8xxgpio_resume(struct pci_dev *pdev)
249 {
250 struct bt8xxgpio *bg = pci_get_drvdata(pdev);
251 int err;
252
253 pci_set_power_state(pdev, PCI_D0);
254 err = pci_enable_device(pdev);
255 if (err)
256 return err;
257 pci_restore_state(pdev);
258
259 guard(spinlock_irqsave)(&bg->lock);
260
261 bgwrite(0, BT848_INT_MASK);
262 bgwrite(0, BT848_GPIO_DMA_CTL);
263 bgwrite(0, BT848_GPIO_REG_INP);
264 bgwrite(bg->saved_outen, BT848_GPIO_OUT_EN);
265 bgwrite(bg->saved_data & bg->saved_outen,
266 BT848_GPIO_DATA);
267
268 return 0;
269 }
270 #else
271 #define bt8xxgpio_suspend NULL
272 #define bt8xxgpio_resume NULL
273 #endif /* CONFIG_PM */
274
275 static const struct pci_device_id bt8xxgpio_pci_tbl[] = {
276 { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848) },
277 { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849) },
278 { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878) },
279 { PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879) },
280 { 0, },
281 };
282 MODULE_DEVICE_TABLE(pci, bt8xxgpio_pci_tbl);
283
284 static struct pci_driver bt8xxgpio_pci_driver = {
285 .name = "bt8xxgpio",
286 .id_table = bt8xxgpio_pci_tbl,
287 .probe = bt8xxgpio_probe,
288 .remove = bt8xxgpio_remove,
289 .suspend = bt8xxgpio_suspend,
290 .resume = bt8xxgpio_resume,
291 };
292
293 module_pci_driver(bt8xxgpio_pci_driver);
294
295 MODULE_LICENSE("GPL");
296 MODULE_AUTHOR("Michael Buesch");
297 MODULE_DESCRIPTION("Abuse a BT8xx framegrabber card as generic GPIO card");
298