linux/drivers/media/common/saa7146_core.c
<<
>>
Prefs
   1/*
   2    saa7146.o - driver for generic saa7146-based hardware
   3
   4    Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
   5
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 2 of the License, or
   9    (at your option) any later version.
  10
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15
  16    You should have received a copy of the GNU General Public License
  17    along with this program; if not, write to the Free Software
  18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19*/
  20
  21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  22
  23#include <media/saa7146.h>
  24#include <linux/module.h>
  25
  26LIST_HEAD(saa7146_devices);
  27DEFINE_MUTEX(saa7146_devices_lock);
  28
  29static int saa7146_num;
  30
  31unsigned int saa7146_debug;
  32
  33module_param(saa7146_debug, uint, 0644);
  34MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)");
  35
  36#if 0
  37static void dump_registers(struct saa7146_dev* dev)
  38{
  39        int i = 0;
  40
  41        pr_info(" @ %li jiffies:\n", jiffies);
  42        for (i = 0; i <= 0x148; i += 4)
  43                pr_info("0x%03x: 0x%08x\n", i, saa7146_read(dev, i));
  44}
  45#endif
  46
  47/****************************************************************************
  48 * gpio and debi helper functions
  49 ****************************************************************************/
  50
  51void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
  52{
  53        u32 value = 0;
  54
  55        BUG_ON(port > 3);
  56
  57        value = saa7146_read(dev, GPIO_CTRL);
  58        value &= ~(0xff << (8*port));
  59        value |= (data << (8*port));
  60        saa7146_write(dev, GPIO_CTRL, value);
  61}
  62
  63/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
  64static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
  65                                unsigned long us1, unsigned long us2)
  66{
  67        unsigned long timeout;
  68        int err;
  69
  70        /* wait for registers to be programmed */
  71        timeout = jiffies + usecs_to_jiffies(us1);
  72        while (1) {
  73                err = time_after(jiffies, timeout);
  74                if (saa7146_read(dev, MC2) & 2)
  75                        break;
  76                if (err) {
  77                        pr_err("%s: %s timed out while waiting for registers getting programmed\n",
  78                               dev->name, __func__);
  79                        return -ETIMEDOUT;
  80                }
  81                msleep(1);
  82        }
  83
  84        /* wait for transfer to complete */
  85        timeout = jiffies + usecs_to_jiffies(us2);
  86        while (1) {
  87                err = time_after(jiffies, timeout);
  88                if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
  89                        break;
  90                saa7146_read(dev, MC2);
  91                if (err) {
  92                        DEB_S("%s: %s timed out while waiting for transfer completion\n",
  93                              dev->name, __func__);
  94                        return -ETIMEDOUT;
  95                }
  96                msleep(1);
  97        }
  98
  99        return 0;
 100}
 101
 102static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
 103                                unsigned long us1, unsigned long us2)
 104{
 105        unsigned long loops;
 106
 107        /* wait for registers to be programmed */
 108        loops = us1;
 109        while (1) {
 110                if (saa7146_read(dev, MC2) & 2)
 111                        break;
 112                if (!loops--) {
 113                        pr_err("%s: %s timed out while waiting for registers getting programmed\n",
 114                               dev->name, __func__);
 115                        return -ETIMEDOUT;
 116                }
 117                udelay(1);
 118        }
 119
 120        /* wait for transfer to complete */
 121        loops = us2 / 5;
 122        while (1) {
 123                if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
 124                        break;
 125                saa7146_read(dev, MC2);
 126                if (!loops--) {
 127                        DEB_S("%s: %s timed out while waiting for transfer completion\n",
 128                              dev->name, __func__);
 129                        return -ETIMEDOUT;
 130                }
 131                udelay(5);
 132        }
 133
 134        return 0;
 135}
 136
 137int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
 138{
 139        if (nobusyloop)
 140                return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
 141        else
 142                return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
 143}
 144
 145/****************************************************************************
 146 * general helper functions
 147 ****************************************************************************/
 148
 149/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c
 150   make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
 151   may be triggered on highmem machines */
 152static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
 153{
 154        struct scatterlist *sglist;
 155        struct page *pg;
 156        int i;
 157
 158        sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 159        if (NULL == sglist)
 160                return NULL;
 161        sg_init_table(sglist, nr_pages);
 162        for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 163                pg = vmalloc_to_page(virt);
 164                if (NULL == pg)
 165                        goto err;
 166                BUG_ON(PageHighMem(pg));
 167                sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
 168        }
 169        return sglist;
 170
 171 err:
 172        kfree(sglist);
 173        return NULL;
 174}
 175
 176/********************************************************************************/
 177/* common page table functions */
 178
 179void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt)
 180{
 181        int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
 182        void *mem = vmalloc_32(length);
 183        int slen = 0;
 184
 185        if (NULL == mem)
 186                goto err_null;
 187
 188        if (!(pt->slist = vmalloc_to_sg(mem, pages)))
 189                goto err_free_mem;
 190
 191        if (saa7146_pgtable_alloc(pci, pt))
 192                goto err_free_slist;
 193
 194        pt->nents = pages;
 195        slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
 196        if (0 == slen)
 197                goto err_free_pgtable;
 198
 199        if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
 200                goto err_unmap_sg;
 201
 202        return mem;
 203
 204err_unmap_sg:
 205        pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
 206err_free_pgtable:
 207        saa7146_pgtable_free(pci, pt);
 208err_free_slist:
 209        kfree(pt->slist);
 210        pt->slist = NULL;
 211err_free_mem:
 212        vfree(mem);
 213err_null:
 214        return NULL;
 215}
 216
 217void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt)
 218{
 219        pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
 220        saa7146_pgtable_free(pci, pt);
 221        kfree(pt->slist);
 222        pt->slist = NULL;
 223        vfree(mem);
 224}
 225
 226void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
 227{
 228        if (NULL == pt->cpu)
 229                return;
 230        pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
 231        pt->cpu = NULL;
 232}
 233
 234int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
 235{
 236        __le32       *cpu;
 237        dma_addr_t   dma_addr = 0;
 238
 239        cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr);
 240        if (NULL == cpu) {
 241                return -ENOMEM;
 242        }
 243        pt->size = PAGE_SIZE;
 244        pt->cpu  = cpu;
 245        pt->dma  = dma_addr;
 246
 247        return 0;
 248}
 249
 250int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
 251        struct scatterlist *list, int sglen  )
 252{
 253        __le32 *ptr, fill;
 254        int nr_pages = 0;
 255        int i,p;
 256
 257        BUG_ON(0 == sglen);
 258        BUG_ON(list->offset > PAGE_SIZE);
 259
 260        /* if we have a user buffer, the first page may not be
 261           aligned to a page boundary. */
 262        pt->offset = list->offset;
 263
 264        ptr = pt->cpu;
 265        for (i = 0; i < sglen; i++, list++) {
 266/*
 267                pr_debug("i:%d, adr:0x%08x, len:%d, offset:%d\n",
 268                         i, sg_dma_address(list), sg_dma_len(list),
 269                         list->offset);
 270*/
 271                for (p = 0; p * 4096 < list->length; p++, ptr++) {
 272                        *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096);
 273                        nr_pages++;
 274                }
 275        }
 276
 277
 278        /* safety; fill the page table up with the last valid page */
 279        fill = *(ptr-1);
 280        for(i=nr_pages;i<1024;i++) {
 281                *ptr++ = fill;
 282        }
 283
 284/*
 285        ptr = pt->cpu;
 286        pr_debug("offset: %d\n", pt->offset);
 287        for(i=0;i<5;i++) {
 288                pr_debug("ptr1 %d: 0x%08x\n", i, ptr[i]);
 289        }
 290*/
 291        return 0;
 292}
 293
 294/********************************************************************************/
 295/* interrupt handler */
 296static irqreturn_t interrupt_hw(int irq, void *dev_id)
 297{
 298        struct saa7146_dev *dev = dev_id;
 299        u32 isr;
 300        u32 ack_isr;
 301
 302        /* read out the interrupt status register */
 303        ack_isr = isr = saa7146_read(dev, ISR);
 304
 305        /* is this our interrupt? */
 306        if ( 0 == isr ) {
 307                /* nope, some other device */
 308                return IRQ_NONE;
 309        }
 310
 311        if (dev->ext) {
 312                if (dev->ext->irq_mask & isr) {
 313                        if (dev->ext->irq_func)
 314                                dev->ext->irq_func(dev, &isr);
 315                        isr &= ~dev->ext->irq_mask;
 316                }
 317        }
 318        if (0 != (isr & (MASK_27))) {
 319                DEB_INT("irq: RPS0 (0x%08x)\n", isr);
 320                if (dev->vv_data && dev->vv_callback)
 321                        dev->vv_callback(dev,isr);
 322                isr &= ~MASK_27;
 323        }
 324        if (0 != (isr & (MASK_28))) {
 325                if (dev->vv_data && dev->vv_callback)
 326                        dev->vv_callback(dev,isr);
 327                isr &= ~MASK_28;
 328        }
 329        if (0 != (isr & (MASK_16|MASK_17))) {
 330                SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
 331                /* only wake up if we expect something */
 332                if (0 != dev->i2c_op) {
 333                        dev->i2c_op = 0;
 334                        wake_up(&dev->i2c_wq);
 335                } else {
 336                        u32 psr = saa7146_read(dev, PSR);
 337                        u32 ssr = saa7146_read(dev, SSR);
 338                        pr_warn("%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
 339                                dev->name, isr, psr, ssr);
 340                }
 341                isr &= ~(MASK_16|MASK_17);
 342        }
 343        if( 0 != isr ) {
 344                ERR("warning: interrupt enabled, but not handled properly.(0x%08x)\n",
 345                    isr);
 346                ERR("disabling interrupt source(s)!\n");
 347                SAA7146_IER_DISABLE(dev,isr);
 348        }
 349        saa7146_write(dev, ISR, ack_isr);
 350        return IRQ_HANDLED;
 351}
 352
 353/*********************************************************************************/
 354/* configuration-functions                                                       */
 355
 356static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent)
 357{
 358        struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;
 359        struct saa7146_extension *ext = pci_ext->ext;
 360        struct saa7146_dev *dev;
 361        int err = -ENOMEM;
 362
 363        /* clear out mem for sure */
 364        dev = kzalloc(sizeof(struct saa7146_dev), GFP_KERNEL);
 365        if (!dev) {
 366                ERR("out of memory\n");
 367                goto out;
 368        }
 369
 370        DEB_EE("pci:%p\n", pci);
 371
 372        err = pci_enable_device(pci);
 373        if (err < 0) {
 374                ERR("pci_enable_device() failed\n");
 375                goto err_free;
 376        }
 377
 378        /* enable bus-mastering */
 379        pci_set_master(pci);
 380
 381        dev->pci = pci;
 382
 383        /* get chip-revision; this is needed to enable bug-fixes */
 384        dev->revision = pci->revision;
 385
 386        /* remap the memory from virtual to physical address */
 387
 388        err = pci_request_region(pci, 0, "saa7146");
 389        if (err < 0)
 390                goto err_disable;
 391
 392        dev->mem = ioremap(pci_resource_start(pci, 0),
 393                           pci_resource_len(pci, 0));
 394        if (!dev->mem) {
 395                ERR("ioremap() failed\n");
 396                err = -ENODEV;
 397                goto err_release;
 398        }
 399
 400        /* we don't do a master reset here anymore, it screws up
 401           some boards that don't have an i2c-eeprom for configuration
 402           values */
 403/*
 404        saa7146_write(dev, MC1, MASK_31);
 405*/
 406
 407        /* disable all irqs */
 408        saa7146_write(dev, IER, 0);
 409
 410        /* shut down all dma transfers and rps tasks */
 411        saa7146_write(dev, MC1, 0x30ff0000);
 412
 413        /* clear out any rps-signals pending */
 414        saa7146_write(dev, MC2, 0xf8000000);
 415
 416        /* request an interrupt for the saa7146 */
 417        err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED | IRQF_DISABLED,
 418                          dev->name, dev);
 419        if (err < 0) {
 420                ERR("request_irq() failed\n");
 421                goto err_unmap;
 422        }
 423
 424        err = -ENOMEM;
 425
 426        /* get memory for various stuff */
 427        dev->d_rps0.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
 428                                                    &dev->d_rps0.dma_handle);
 429        if (!dev->d_rps0.cpu_addr)
 430                goto err_free_irq;
 431        memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM);
 432
 433        dev->d_rps1.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
 434                                                    &dev->d_rps1.dma_handle);
 435        if (!dev->d_rps1.cpu_addr)
 436                goto err_free_rps0;
 437        memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM);
 438
 439        dev->d_i2c.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
 440                                                   &dev->d_i2c.dma_handle);
 441        if (!dev->d_i2c.cpu_addr)
 442                goto err_free_rps1;
 443        memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM);
 444
 445        /* the rest + print status message */
 446
 447        /* create a nice device name */
 448        sprintf(dev->name, "saa7146 (%d)", saa7146_num);
 449
 450        pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n",
 451                dev->mem, dev->revision, pci->irq,
 452                pci->subsystem_vendor, pci->subsystem_device);
 453        dev->ext = ext;
 454
 455        mutex_init(&dev->v4l2_lock);
 456        spin_lock_init(&dev->int_slock);
 457        spin_lock_init(&dev->slock);
 458
 459        mutex_init(&dev->i2c_lock);
 460
 461        dev->module = THIS_MODULE;
 462        init_waitqueue_head(&dev->i2c_wq);
 463
 464        /* set some sane pci arbitrition values */
 465        saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
 466
 467        /* TODO: use the status code of the callback */
 468
 469        err = -ENODEV;
 470
 471        if (ext->probe && ext->probe(dev)) {
 472                DEB_D("ext->probe() failed for %p. skipping device.\n", dev);
 473                goto err_free_i2c;
 474        }
 475
 476        if (ext->attach(dev, pci_ext)) {
 477                DEB_D("ext->attach() failed for %p. skipping device.\n", dev);
 478                goto err_free_i2c;
 479        }
 480        /* V4L extensions will set the pci drvdata to the v4l2_device in the
 481           attach() above. So for those cards that do not use V4L we have to
 482           set it explicitly. */
 483        pci_set_drvdata(pci, &dev->v4l2_dev);
 484
 485        INIT_LIST_HEAD(&dev->item);
 486        list_add_tail(&dev->item,&saa7146_devices);
 487        saa7146_num++;
 488
 489        err = 0;
 490out:
 491        return err;
 492
 493err_free_i2c:
 494        pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
 495                            dev->d_i2c.dma_handle);
 496err_free_rps1:
 497        pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr,
 498                            dev->d_rps1.dma_handle);
 499err_free_rps0:
 500        pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr,
 501                            dev->d_rps0.dma_handle);
 502err_free_irq:
 503        free_irq(pci->irq, (void *)dev);
 504err_unmap:
 505        iounmap(dev->mem);
 506err_release:
 507        pci_release_region(pci, 0);
 508err_disable:
 509        pci_disable_device(pci);
 510err_free:
 511        kfree(dev);
 512        goto out;
 513}
 514
 515static void saa7146_remove_one(struct pci_dev *pdev)
 516{
 517        struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
 518        struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
 519        struct {
 520                void *addr;
 521                dma_addr_t dma;
 522        } dev_map[] = {
 523                { dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle },
 524                { dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle },
 525                { dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle },
 526                { NULL, 0 }
 527        }, *p;
 528
 529        DEB_EE("dev:%p\n", dev);
 530
 531        dev->ext->detach(dev);
 532        /* Zero the PCI drvdata after use. */
 533        pci_set_drvdata(pdev, NULL);
 534
 535        /* shut down all video dma transfers */
 536        saa7146_write(dev, MC1, 0x00ff0000);
 537
 538        /* disable all irqs, release irq-routine */
 539        saa7146_write(dev, IER, 0);
 540
 541        free_irq(pdev->irq, dev);
 542
 543        for (p = dev_map; p->addr; p++)
 544                pci_free_consistent(pdev, SAA7146_RPS_MEM, p->addr, p->dma);
 545
 546        iounmap(dev->mem);
 547        pci_release_region(pdev, 0);
 548        list_del(&dev->item);
 549        pci_disable_device(pdev);
 550        kfree(dev);
 551
 552        saa7146_num--;
 553}
 554
 555/*********************************************************************************/
 556/* extension handling functions                                                  */
 557
 558int saa7146_register_extension(struct saa7146_extension* ext)
 559{
 560        DEB_EE("ext:%p\n", ext);
 561
 562        ext->driver.name = ext->name;
 563        ext->driver.id_table = ext->pci_tbl;
 564        ext->driver.probe = saa7146_init_one;
 565        ext->driver.remove = saa7146_remove_one;
 566
 567        pr_info("register extension '%s'\n", ext->name);
 568        return pci_register_driver(&ext->driver);
 569}
 570
 571int saa7146_unregister_extension(struct saa7146_extension* ext)
 572{
 573        DEB_EE("ext:%p\n", ext);
 574        pr_info("unregister extension '%s'\n", ext->name);
 575        pci_unregister_driver(&ext->driver);
 576        return 0;
 577}
 578
 579EXPORT_SYMBOL_GPL(saa7146_register_extension);
 580EXPORT_SYMBOL_GPL(saa7146_unregister_extension);
 581
 582/* misc functions used by extension modules */
 583EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
 584EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
 585EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
 586EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
 587EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
 588EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
 589
 590EXPORT_SYMBOL_GPL(saa7146_setgpio);
 591
 592EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
 593
 594EXPORT_SYMBOL_GPL(saa7146_debug);
 595EXPORT_SYMBOL_GPL(saa7146_devices);
 596EXPORT_SYMBOL_GPL(saa7146_devices_lock);
 597
 598MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
 599MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
 600MODULE_LICENSE("GPL");
 601