Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     saa7146.o - driver for generic saa7146-based hardware
0004 
0005     Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
0006 
0007 */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #include <media/drv-intf/saa7146.h>
0012 #include <linux/module.h>
0013 
0014 static int saa7146_num;
0015 
0016 unsigned int saa7146_debug;
0017 
0018 module_param(saa7146_debug, uint, 0644);
0019 MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)");
0020 
0021 #if 0
0022 static void dump_registers(struct saa7146_dev* dev)
0023 {
0024     int i = 0;
0025 
0026     pr_info(" @ %li jiffies:\n", jiffies);
0027     for (i = 0; i <= 0x148; i += 4)
0028         pr_info("0x%03x: 0x%08x\n", i, saa7146_read(dev, i));
0029 }
0030 #endif
0031 
0032 /****************************************************************************
0033  * gpio and debi helper functions
0034  ****************************************************************************/
0035 
0036 void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
0037 {
0038     u32 value = 0;
0039 
0040     BUG_ON(port > 3);
0041 
0042     value = saa7146_read(dev, GPIO_CTRL);
0043     value &= ~(0xff << (8*port));
0044     value |= (data << (8*port));
0045     saa7146_write(dev, GPIO_CTRL, value);
0046 }
0047 
0048 /* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
0049 static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
0050                 unsigned long us1, unsigned long us2)
0051 {
0052     unsigned long timeout;
0053     int err;
0054 
0055     /* wait for registers to be programmed */
0056     timeout = jiffies + usecs_to_jiffies(us1);
0057     while (1) {
0058         err = time_after(jiffies, timeout);
0059         if (saa7146_read(dev, MC2) & 2)
0060             break;
0061         if (err) {
0062             pr_debug("%s: %s timed out while waiting for registers getting programmed\n",
0063                    dev->name, __func__);
0064             return -ETIMEDOUT;
0065         }
0066         msleep(1);
0067     }
0068 
0069     /* wait for transfer to complete */
0070     timeout = jiffies + usecs_to_jiffies(us2);
0071     while (1) {
0072         err = time_after(jiffies, timeout);
0073         if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
0074             break;
0075         saa7146_read(dev, MC2);
0076         if (err) {
0077             DEB_S("%s: %s timed out while waiting for transfer completion\n",
0078                   dev->name, __func__);
0079             return -ETIMEDOUT;
0080         }
0081         msleep(1);
0082     }
0083 
0084     return 0;
0085 }
0086 
0087 static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
0088                 unsigned long us1, unsigned long us2)
0089 {
0090     unsigned long loops;
0091 
0092     /* wait for registers to be programmed */
0093     loops = us1;
0094     while (1) {
0095         if (saa7146_read(dev, MC2) & 2)
0096             break;
0097         if (!loops--) {
0098             pr_err("%s: %s timed out while waiting for registers getting programmed\n",
0099                    dev->name, __func__);
0100             return -ETIMEDOUT;
0101         }
0102         udelay(1);
0103     }
0104 
0105     /* wait for transfer to complete */
0106     loops = us2 / 5;
0107     while (1) {
0108         if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
0109             break;
0110         saa7146_read(dev, MC2);
0111         if (!loops--) {
0112             DEB_S("%s: %s timed out while waiting for transfer completion\n",
0113                   dev->name, __func__);
0114             return -ETIMEDOUT;
0115         }
0116         udelay(5);
0117     }
0118 
0119     return 0;
0120 }
0121 
0122 int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
0123 {
0124     if (nobusyloop)
0125         return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
0126     else
0127         return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
0128 }
0129 
0130 /****************************************************************************
0131  * general helper functions
0132  ****************************************************************************/
0133 
0134 /* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c
0135    make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
0136    may be triggered on highmem machines */
0137 static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
0138 {
0139     struct scatterlist *sglist;
0140     struct page *pg;
0141     int i;
0142 
0143     sglist = kmalloc_array(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
0144     if (NULL == sglist)
0145         return NULL;
0146     sg_init_table(sglist, nr_pages);
0147     for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
0148         pg = vmalloc_to_page(virt);
0149         if (NULL == pg)
0150             goto err;
0151         BUG_ON(PageHighMem(pg));
0152         sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
0153     }
0154     return sglist;
0155 
0156  err:
0157     kfree(sglist);
0158     return NULL;
0159 }
0160 
0161 /********************************************************************************/
0162 /* common page table functions */
0163 
0164 void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt)
0165 {
0166     int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
0167     void *mem = vmalloc_32(length);
0168     int slen = 0;
0169 
0170     if (NULL == mem)
0171         goto err_null;
0172 
0173     if (!(pt->slist = vmalloc_to_sg(mem, pages)))
0174         goto err_free_mem;
0175 
0176     if (saa7146_pgtable_alloc(pci, pt))
0177         goto err_free_slist;
0178 
0179     pt->nents = pages;
0180     slen = dma_map_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE);
0181     if (0 == slen)
0182         goto err_free_pgtable;
0183 
0184     if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
0185         goto err_unmap_sg;
0186 
0187     return mem;
0188 
0189 err_unmap_sg:
0190     dma_unmap_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE);
0191 err_free_pgtable:
0192     saa7146_pgtable_free(pci, pt);
0193 err_free_slist:
0194     kfree(pt->slist);
0195     pt->slist = NULL;
0196 err_free_mem:
0197     vfree(mem);
0198 err_null:
0199     return NULL;
0200 }
0201 
0202 void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt)
0203 {
0204     dma_unmap_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE);
0205     saa7146_pgtable_free(pci, pt);
0206     kfree(pt->slist);
0207     pt->slist = NULL;
0208     vfree(mem);
0209 }
0210 
0211 void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
0212 {
0213     if (NULL == pt->cpu)
0214         return;
0215     dma_free_coherent(&pci->dev, pt->size, pt->cpu, pt->dma);
0216     pt->cpu = NULL;
0217 }
0218 
0219 int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
0220 {
0221     __le32       *cpu;
0222     dma_addr_t   dma_addr = 0;
0223 
0224     cpu = dma_alloc_coherent(&pci->dev, PAGE_SIZE, &dma_addr, GFP_KERNEL);
0225     if (NULL == cpu) {
0226         return -ENOMEM;
0227     }
0228     pt->size = PAGE_SIZE;
0229     pt->cpu  = cpu;
0230     pt->dma  = dma_addr;
0231 
0232     return 0;
0233 }
0234 
0235 int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
0236     struct scatterlist *list, int sglen  )
0237 {
0238     __le32 *ptr, fill;
0239     int nr_pages = 0;
0240     int i,p;
0241 
0242     BUG_ON(0 == sglen);
0243     BUG_ON(list->offset > PAGE_SIZE);
0244 
0245     /* if we have a user buffer, the first page may not be
0246        aligned to a page boundary. */
0247     pt->offset = list->offset;
0248 
0249     ptr = pt->cpu;
0250     for (i = 0; i < sglen; i++, list++) {
0251 /*
0252         pr_debug("i:%d, adr:0x%08x, len:%d, offset:%d\n",
0253              i, sg_dma_address(list), sg_dma_len(list),
0254              list->offset);
0255 */
0256         for (p = 0; p * 4096 < sg_dma_len(list); p++, ptr++) {
0257             *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096);
0258             nr_pages++;
0259         }
0260     }
0261 
0262 
0263     /* safety; fill the page table up with the last valid page */
0264     fill = *(ptr-1);
0265     for(i=nr_pages;i<1024;i++) {
0266         *ptr++ = fill;
0267     }
0268 
0269 /*
0270     ptr = pt->cpu;
0271     pr_debug("offset: %d\n", pt->offset);
0272     for(i=0;i<5;i++) {
0273         pr_debug("ptr1 %d: 0x%08x\n", i, ptr[i]);
0274     }
0275 */
0276     return 0;
0277 }
0278 
0279 /********************************************************************************/
0280 /* interrupt handler */
0281 static irqreturn_t interrupt_hw(int irq, void *dev_id)
0282 {
0283     struct saa7146_dev *dev = dev_id;
0284     u32 isr;
0285     u32 ack_isr;
0286 
0287     /* read out the interrupt status register */
0288     ack_isr = isr = saa7146_read(dev, ISR);
0289 
0290     /* is this our interrupt? */
0291     if ( 0 == isr ) {
0292         /* nope, some other device */
0293         return IRQ_NONE;
0294     }
0295 
0296     if (dev->ext) {
0297         if (dev->ext->irq_mask & isr) {
0298             if (dev->ext->irq_func)
0299                 dev->ext->irq_func(dev, &isr);
0300             isr &= ~dev->ext->irq_mask;
0301         }
0302     }
0303     if (0 != (isr & (MASK_27))) {
0304         DEB_INT("irq: RPS0 (0x%08x)\n", isr);
0305         if (dev->vv_data && dev->vv_callback)
0306             dev->vv_callback(dev,isr);
0307         isr &= ~MASK_27;
0308     }
0309     if (0 != (isr & (MASK_28))) {
0310         if (dev->vv_data && dev->vv_callback)
0311             dev->vv_callback(dev,isr);
0312         isr &= ~MASK_28;
0313     }
0314     if (0 != (isr & (MASK_16|MASK_17))) {
0315         SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
0316         /* only wake up if we expect something */
0317         if (0 != dev->i2c_op) {
0318             dev->i2c_op = 0;
0319             wake_up(&dev->i2c_wq);
0320         } else {
0321             u32 psr = saa7146_read(dev, PSR);
0322             u32 ssr = saa7146_read(dev, SSR);
0323             pr_warn("%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
0324                 dev->name, isr, psr, ssr);
0325         }
0326         isr &= ~(MASK_16|MASK_17);
0327     }
0328     if( 0 != isr ) {
0329         ERR("warning: interrupt enabled, but not handled properly.(0x%08x)\n",
0330             isr);
0331         ERR("disabling interrupt source(s)!\n");
0332         SAA7146_IER_DISABLE(dev,isr);
0333     }
0334     saa7146_write(dev, ISR, ack_isr);
0335     return IRQ_HANDLED;
0336 }
0337 
0338 /*********************************************************************************/
0339 /* configuration-functions                                                       */
0340 
0341 static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent)
0342 {
0343     struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;
0344     struct saa7146_extension *ext = pci_ext->ext;
0345     struct saa7146_dev *dev;
0346     int err = -ENOMEM;
0347 
0348     /* clear out mem for sure */
0349     dev = kzalloc(sizeof(struct saa7146_dev), GFP_KERNEL);
0350     if (!dev) {
0351         ERR("out of memory\n");
0352         goto out;
0353     }
0354 
0355     /* create a nice device name */
0356     sprintf(dev->name, "saa7146 (%d)", saa7146_num);
0357 
0358     DEB_EE("pci:%p\n", pci);
0359 
0360     err = pci_enable_device(pci);
0361     if (err < 0) {
0362         ERR("pci_enable_device() failed\n");
0363         goto err_free;
0364     }
0365 
0366     /* enable bus-mastering */
0367     pci_set_master(pci);
0368 
0369     dev->pci = pci;
0370 
0371     /* get chip-revision; this is needed to enable bug-fixes */
0372     dev->revision = pci->revision;
0373 
0374     /* remap the memory from virtual to physical address */
0375 
0376     err = pci_request_region(pci, 0, "saa7146");
0377     if (err < 0)
0378         goto err_disable;
0379 
0380     dev->mem = ioremap(pci_resource_start(pci, 0),
0381                pci_resource_len(pci, 0));
0382     if (!dev->mem) {
0383         ERR("ioremap() failed\n");
0384         err = -ENODEV;
0385         goto err_release;
0386     }
0387 
0388     /* we don't do a master reset here anymore, it screws up
0389        some boards that don't have an i2c-eeprom for configuration
0390        values */
0391 /*
0392     saa7146_write(dev, MC1, MASK_31);
0393 */
0394 
0395     /* disable all irqs */
0396     saa7146_write(dev, IER, 0);
0397 
0398     /* shut down all dma transfers and rps tasks */
0399     saa7146_write(dev, MC1, 0x30ff0000);
0400 
0401     /* clear out any rps-signals pending */
0402     saa7146_write(dev, MC2, 0xf8000000);
0403 
0404     /* request an interrupt for the saa7146 */
0405     err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED,
0406               dev->name, dev);
0407     if (err < 0) {
0408         ERR("request_irq() failed\n");
0409         goto err_unmap;
0410     }
0411 
0412     err = -ENOMEM;
0413 
0414     /* get memory for various stuff */
0415     dev->d_rps0.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM,
0416                           &dev->d_rps0.dma_handle,
0417                           GFP_KERNEL);
0418     if (!dev->d_rps0.cpu_addr)
0419         goto err_free_irq;
0420 
0421     dev->d_rps1.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM,
0422                           &dev->d_rps1.dma_handle,
0423                           GFP_KERNEL);
0424     if (!dev->d_rps1.cpu_addr)
0425         goto err_free_rps0;
0426 
0427     dev->d_i2c.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM,
0428                          &dev->d_i2c.dma_handle, GFP_KERNEL);
0429     if (!dev->d_i2c.cpu_addr)
0430         goto err_free_rps1;
0431 
0432     /* the rest + print status message */
0433 
0434     pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n",
0435         dev->mem, dev->revision, pci->irq,
0436         pci->subsystem_vendor, pci->subsystem_device);
0437     dev->ext = ext;
0438 
0439     mutex_init(&dev->v4l2_lock);
0440     spin_lock_init(&dev->int_slock);
0441     spin_lock_init(&dev->slock);
0442 
0443     mutex_init(&dev->i2c_lock);
0444 
0445     dev->module = THIS_MODULE;
0446     init_waitqueue_head(&dev->i2c_wq);
0447 
0448     /* set some sane pci arbitrition values */
0449     saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
0450 
0451     /* TODO: use the status code of the callback */
0452 
0453     err = -ENODEV;
0454 
0455     if (ext->probe && ext->probe(dev)) {
0456         DEB_D("ext->probe() failed for %p. skipping device.\n", dev);
0457         goto err_free_i2c;
0458     }
0459 
0460     if (ext->attach(dev, pci_ext)) {
0461         DEB_D("ext->attach() failed for %p. skipping device.\n", dev);
0462         goto err_free_i2c;
0463     }
0464     /* V4L extensions will set the pci drvdata to the v4l2_device in the
0465        attach() above. So for those cards that do not use V4L we have to
0466        set it explicitly. */
0467     pci_set_drvdata(pci, &dev->v4l2_dev);
0468 
0469     saa7146_num++;
0470 
0471     err = 0;
0472 out:
0473     return err;
0474 
0475 err_free_i2c:
0476     dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
0477               dev->d_i2c.dma_handle);
0478 err_free_rps1:
0479     dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr,
0480               dev->d_rps1.dma_handle);
0481 err_free_rps0:
0482     dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr,
0483               dev->d_rps0.dma_handle);
0484 err_free_irq:
0485     free_irq(pci->irq, (void *)dev);
0486 err_unmap:
0487     iounmap(dev->mem);
0488 err_release:
0489     pci_release_region(pci, 0);
0490 err_disable:
0491     pci_disable_device(pci);
0492 err_free:
0493     kfree(dev);
0494     goto out;
0495 }
0496 
0497 static void saa7146_remove_one(struct pci_dev *pdev)
0498 {
0499     struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
0500     struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
0501     struct {
0502         void *addr;
0503         dma_addr_t dma;
0504     } dev_map[] = {
0505         { dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle },
0506         { dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle },
0507         { dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle },
0508         { NULL, 0 }
0509     }, *p;
0510 
0511     DEB_EE("dev:%p\n", dev);
0512 
0513     dev->ext->detach(dev);
0514 
0515     /* shut down all video dma transfers */
0516     saa7146_write(dev, MC1, 0x00ff0000);
0517 
0518     /* disable all irqs, release irq-routine */
0519     saa7146_write(dev, IER, 0);
0520 
0521     free_irq(pdev->irq, dev);
0522 
0523     for (p = dev_map; p->addr; p++)
0524         dma_free_coherent(&pdev->dev, SAA7146_RPS_MEM, p->addr,
0525                   p->dma);
0526 
0527     iounmap(dev->mem);
0528     pci_release_region(pdev, 0);
0529     pci_disable_device(pdev);
0530     kfree(dev);
0531 
0532     saa7146_num--;
0533 }
0534 
0535 /*********************************************************************************/
0536 /* extension handling functions                                                  */
0537 
0538 int saa7146_register_extension(struct saa7146_extension* ext)
0539 {
0540     DEB_EE("ext:%p\n", ext);
0541 
0542     ext->driver.name = ext->name;
0543     ext->driver.id_table = ext->pci_tbl;
0544     ext->driver.probe = saa7146_init_one;
0545     ext->driver.remove = saa7146_remove_one;
0546 
0547     pr_info("register extension '%s'\n", ext->name);
0548     return pci_register_driver(&ext->driver);
0549 }
0550 
0551 int saa7146_unregister_extension(struct saa7146_extension* ext)
0552 {
0553     DEB_EE("ext:%p\n", ext);
0554     pr_info("unregister extension '%s'\n", ext->name);
0555     pci_unregister_driver(&ext->driver);
0556     return 0;
0557 }
0558 
0559 EXPORT_SYMBOL_GPL(saa7146_register_extension);
0560 EXPORT_SYMBOL_GPL(saa7146_unregister_extension);
0561 
0562 /* misc functions used by extension modules */
0563 EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
0564 EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
0565 EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
0566 EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
0567 EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
0568 EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
0569 
0570 EXPORT_SYMBOL_GPL(saa7146_setgpio);
0571 
0572 EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
0573 
0574 EXPORT_SYMBOL_GPL(saa7146_debug);
0575 
0576 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
0577 MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
0578 MODULE_LICENSE("GPL");