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