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 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 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 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 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 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 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 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 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 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