linux/drivers/media/video/saa7164/saa7164-core.c
<<
>>
Prefs
   1/*
   2 *  Driver for the NXP SAA7164 PCIe bridge
   3 *
   4 *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
   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 *
  15 *  GNU General Public License for more details.
  16 *
  17 *  You should have received a copy of the GNU General Public License
  18 *  along with this program; if not, write to the Free Software
  19 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 */
  21
  22#include <linux/init.h>
  23#include <linux/list.h>
  24#include <linux/module.h>
  25#include <linux/moduleparam.h>
  26#include <linux/kmod.h>
  27#include <linux/kernel.h>
  28#include <linux/slab.h>
  29#include <linux/interrupt.h>
  30#include <linux/delay.h>
  31#include <asm/div64.h>
  32
  33#include "saa7164.h"
  34
  35MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
  36MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
  37MODULE_LICENSE("GPL");
  38
  39/*
  40  1 Basic
  41  2
  42  4 i2c
  43  8 api
  44 16 cmd
  45 32 bus
  46 */
  47
  48unsigned int saa_debug;
  49module_param_named(debug, saa_debug, int, 0644);
  50MODULE_PARM_DESC(debug, "enable debug messages");
  51
  52unsigned int waitsecs = 10;
  53module_param(waitsecs, int, 0644);
  54MODULE_PARM_DESC(debug, "timeout on firmware messages");
  55
  56static unsigned int card[]  = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
  57module_param_array(card,  int, NULL, 0444);
  58MODULE_PARM_DESC(card, "card type");
  59
  60static unsigned int saa7164_devcount;
  61
  62static DEFINE_MUTEX(devlist);
  63LIST_HEAD(saa7164_devlist);
  64
  65#define INT_SIZE 16
  66
  67static void saa7164_work_cmdhandler(struct work_struct *w)
  68{
  69        struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
  70
  71        /* Wake up any complete commands */
  72        saa7164_irq_dequeue(dev);
  73}
  74
  75static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
  76{
  77        struct saa7164_tsport *port = buf->port;
  78
  79        /* Feed the transport payload into the kernel demux */
  80        dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
  81                SAA7164_TS_NUMBER_OF_LINES);
  82
  83}
  84
  85static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
  86{
  87        struct saa7164_dev *dev = port->dev;
  88        struct saa7164_buffer *buf;
  89        struct list_head *c, *n;
  90        int wp, i = 0, rp;
  91
  92        /* Find the current write point from the hardware */
  93        wp = saa7164_readl(port->bufcounter);
  94        if (wp > (port->hwcfg.buffercount - 1))
  95                BUG();
  96
  97        /* Find the previous buffer to the current write point */
  98        if (wp == 0)
  99                rp = 7;
 100        else
 101                rp = wp - 1;
 102
 103        /* Lookup the WP in the buffer list */
 104        /* TODO: turn this into a worker thread */
 105        list_for_each_safe(c, n, &port->dmaqueue.list) {
 106                buf = list_entry(c, struct saa7164_buffer, list);
 107                if (i++ > port->hwcfg.buffercount)
 108                        BUG();
 109
 110                if (buf->nr == rp) {
 111                        /* Found the buffer, deal with it */
 112                        dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
 113                                __func__, wp, rp);
 114                        saa7164_buffer_deliver(buf);
 115                        break;
 116                }
 117
 118        }
 119        return 0;
 120}
 121
 122/* Primary IRQ handler and dispatch mechanism */
 123static irqreturn_t saa7164_irq(int irq, void *dev_id)
 124{
 125        struct saa7164_dev *dev = dev_id;
 126        u32 intid, intstat[INT_SIZE/4];
 127        int i, handled = 0, bit;
 128
 129        if (dev == 0) {
 130                printk(KERN_ERR "%s() No device specified\n", __func__);
 131                handled = 0;
 132                goto out;
 133        }
 134
 135        /* Check that the hardware is accessable. If the status bytes are
 136         * 0xFF then the device is not accessable, the the IRQ belongs
 137         * to another driver.
 138         * 4 x u32 interrupt registers.
 139         */
 140        for (i = 0; i < INT_SIZE/4; i++) {
 141
 142                /* TODO: Convert into saa7164_readl() */
 143                /* Read the 4 hardware interrupt registers */
 144                intstat[i] = saa7164_readl(dev->int_status + (i * 4));
 145
 146                if (intstat[i])
 147                        handled = 1;
 148        }
 149        if (handled == 0)
 150                goto out;
 151
 152        /* For each of the HW interrupt registers */
 153        for (i = 0; i < INT_SIZE/4; i++) {
 154
 155                if (intstat[i]) {
 156                        /* Each function of the board has it's own interruptid.
 157                         * Find the function that triggered then call
 158                         * it's handler.
 159                         */
 160                        for (bit = 0; bit < 32; bit++) {
 161
 162                                if (((intstat[i] >> bit) & 0x00000001) == 0)
 163                                        continue;
 164
 165                                /* Calculate the interrupt id (0x00 to 0x7f) */
 166
 167                                intid = (i * 32) + bit;
 168                                if (intid == dev->intfdesc.bInterruptId) {
 169                                        /* A response to an cmd/api call */
 170                                        schedule_work(&dev->workcmd);
 171                                } else if (intid ==
 172                                        dev->ts1.hwcfg.interruptid) {
 173
 174                                        /* Transport path 1 */
 175                                        saa7164_irq_ts(&dev->ts1);
 176
 177                                } else if (intid ==
 178                                        dev->ts2.hwcfg.interruptid) {
 179
 180                                        /* Transport path 2 */
 181                                        saa7164_irq_ts(&dev->ts2);
 182
 183                                } else {
 184                                        /* Find the function */
 185                                        dprintk(DBGLVL_IRQ,
 186                                                "%s() unhandled interrupt "
 187                                                "reg 0x%x bit 0x%x "
 188                                                "intid = 0x%x\n",
 189                                                __func__, i, bit, intid);
 190                                }
 191                        }
 192
 193                        /* Ack it */
 194                        saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
 195
 196                }
 197        }
 198out:
 199        return IRQ_RETVAL(handled);
 200}
 201
 202void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
 203{
 204        struct saa7164_fw_status *s = &dev->fw_status;
 205
 206        dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
 207        dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
 208        dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
 209        dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
 210        dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
 211        dev->fw_status.remainheap =
 212                saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
 213
 214        dprintk(1, "Firmware status:\n");
 215        dprintk(1, " .status     = 0x%08x\n", s->status);
 216        dprintk(1, " .mode       = 0x%08x\n", s->mode);
 217        dprintk(1, " .spec       = 0x%08x\n", s->spec);
 218        dprintk(1, " .inst       = 0x%08x\n", s->inst);
 219        dprintk(1, " .cpuload    = 0x%08x\n", s->cpuload);
 220        dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
 221}
 222
 223u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
 224{
 225        u32 reg;
 226
 227        reg = saa7164_readl(SAA_DEVICE_VERSION);
 228        dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
 229                (reg & 0x0000fc00) >> 10,
 230                (reg & 0x000003e0) >> 5,
 231                (reg & 0x0000001f),
 232                (reg & 0xffff0000) >> 16,
 233                reg);
 234
 235        return reg;
 236}
 237
 238/* TODO: Debugging func, remove */
 239void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
 240{
 241        int i;
 242
 243        printk(KERN_INFO "--------------------> "
 244                "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
 245
 246        for (i = 0; i < len; i += 16)
 247                printk(KERN_INFO "         [0x%08x] "
 248                        "%02x %02x %02x %02x %02x %02x %02x %02x "
 249                        "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
 250                *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
 251                *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
 252                *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
 253                *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
 254}
 255
 256/* TODO: Debugging func, remove */
 257void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
 258{
 259        int i;
 260
 261        dprintk(1, "--------------------> "
 262                "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
 263
 264        for (i = 0; i < 0x100; i += 16)
 265                dprintk(1, "region0[0x%08x] = "
 266                        "%02x %02x %02x %02x %02x %02x %02x %02x"
 267                        " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
 268                        (u8)saa7164_readb(addr + i + 0),
 269                        (u8)saa7164_readb(addr + i + 1),
 270                        (u8)saa7164_readb(addr + i + 2),
 271                        (u8)saa7164_readb(addr + i + 3),
 272                        (u8)saa7164_readb(addr + i + 4),
 273                        (u8)saa7164_readb(addr + i + 5),
 274                        (u8)saa7164_readb(addr + i + 6),
 275                        (u8)saa7164_readb(addr + i + 7),
 276                        (u8)saa7164_readb(addr + i + 8),
 277                        (u8)saa7164_readb(addr + i + 9),
 278                        (u8)saa7164_readb(addr + i + 10),
 279                        (u8)saa7164_readb(addr + i + 11),
 280                        (u8)saa7164_readb(addr + i + 12),
 281                        (u8)saa7164_readb(addr + i + 13),
 282                        (u8)saa7164_readb(addr + i + 14),
 283                        (u8)saa7164_readb(addr + i + 15)
 284                        );
 285}
 286
 287static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
 288{
 289        dprintk(1, "@0x%p hwdesc sizeof(tmComResHWDescr_t) = %d bytes\n",
 290                &dev->hwdesc, (u32)sizeof(tmComResHWDescr_t));
 291
 292        dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
 293        dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
 294        dprintk(1, " .bDescriptorSubtype = 0x%x\n",
 295                dev->hwdesc.bDescriptorSubtype);
 296
 297        dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
 298        dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
 299        dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
 300        dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
 301        dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
 302                dev->hwdesc.dwDeviceRegistersLocation);
 303
 304        dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
 305                dev->hwdesc.dwHostMemoryRegion);
 306
 307        dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
 308                dev->hwdesc.dwHostMemoryRegionSize);
 309
 310        dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
 311                dev->hwdesc.dwHostHibernatMemRegion);
 312
 313        dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
 314                dev->hwdesc.dwHostHibernatMemRegionSize);
 315}
 316
 317static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
 318{
 319        dprintk(1, "@0x%p intfdesc "
 320                "sizeof(tmComResInterfaceDescr_t) = %d bytes\n",
 321                &dev->intfdesc, (u32)sizeof(tmComResInterfaceDescr_t));
 322
 323        dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
 324        dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
 325        dprintk(1, " .bDescriptorSubtype = 0x%x\n",
 326                dev->intfdesc.bDescriptorSubtype);
 327
 328        dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
 329        dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
 330        dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
 331        dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
 332        dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
 333        dprintk(1, " .bDebugInterruptId = 0x%x\n",
 334                dev->intfdesc.bDebugInterruptId);
 335
 336        dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
 337}
 338
 339static void saa7164_dump_busdesc(struct saa7164_dev *dev)
 340{
 341        dprintk(1, "@0x%p busdesc sizeof(tmComResBusDescr_t) = %d bytes\n",
 342                &dev->busdesc, (u32)sizeof(tmComResBusDescr_t));
 343
 344        dprintk(1, " .CommandRing   = 0x%016Lx\n", dev->busdesc.CommandRing);
 345        dprintk(1, " .ResponseRing  = 0x%016Lx\n", dev->busdesc.ResponseRing);
 346        dprintk(1, " .CommandWrite  = 0x%x\n", dev->busdesc.CommandWrite);
 347        dprintk(1, " .CommandRead   = 0x%x\n", dev->busdesc.CommandRead);
 348        dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
 349        dprintk(1, " .ResponseRead  = 0x%x\n", dev->busdesc.ResponseRead);
 350}
 351
 352/* Much of the hardware configuration and PCI registers are configured
 353 * dynamically depending on firmware. We have to cache some initial
 354 * structures then use these to locate other important structures
 355 * from PCI space.
 356 */
 357static void saa7164_get_descriptors(struct saa7164_dev *dev)
 358{
 359        memcpy(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
 360        memcpy(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
 361                sizeof(tmComResInterfaceDescr_t));
 362        memcpy(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
 363                sizeof(tmComResBusDescr_t));
 364
 365        if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) {
 366                printk(KERN_ERR "Structure tmComResHWDescr_t is mangled\n");
 367                printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
 368                        (u32)sizeof(tmComResHWDescr_t));
 369        } else
 370                saa7164_dump_hwdesc(dev);
 371
 372        if (dev->intfdesc.bLength != sizeof(tmComResInterfaceDescr_t)) {
 373                printk(KERN_ERR "struct tmComResInterfaceDescr_t is mangled\n");
 374                printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
 375                        (u32)sizeof(tmComResInterfaceDescr_t));
 376        } else
 377                saa7164_dump_intfdesc(dev);
 378
 379        saa7164_dump_busdesc(dev);
 380}
 381
 382static int saa7164_pci_quirks(struct saa7164_dev *dev)
 383{
 384        return 0;
 385}
 386
 387static int get_resources(struct saa7164_dev *dev)
 388{
 389        if (request_mem_region(pci_resource_start(dev->pci, 0),
 390                pci_resource_len(dev->pci, 0), dev->name)) {
 391
 392                if (request_mem_region(pci_resource_start(dev->pci, 2),
 393                        pci_resource_len(dev->pci, 2), dev->name))
 394                        return 0;
 395        }
 396
 397        printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
 398                dev->name,
 399                (u64)pci_resource_start(dev->pci, 0),
 400                (u64)pci_resource_start(dev->pci, 2));
 401
 402        return -EBUSY;
 403}
 404
 405static int saa7164_dev_setup(struct saa7164_dev *dev)
 406{
 407        int i;
 408
 409        mutex_init(&dev->lock);
 410        atomic_inc(&dev->refcount);
 411        dev->nr = saa7164_devcount++;
 412
 413        sprintf(dev->name, "saa7164[%d]", dev->nr);
 414
 415        mutex_lock(&devlist);
 416        list_add_tail(&dev->devlist, &saa7164_devlist);
 417        mutex_unlock(&devlist);
 418
 419        /* board config */
 420        dev->board = UNSET;
 421        if (card[dev->nr] < saa7164_bcount)
 422                dev->board = card[dev->nr];
 423
 424        for (i = 0; UNSET == dev->board  &&  i < saa7164_idcount; i++)
 425                if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
 426                        dev->pci->subsystem_device ==
 427                                saa7164_subids[i].subdevice)
 428                                dev->board = saa7164_subids[i].card;
 429
 430        if (UNSET == dev->board) {
 431                dev->board = SAA7164_BOARD_UNKNOWN;
 432                saa7164_card_list(dev);
 433        }
 434
 435        dev->pci_bus  = dev->pci->bus->number;
 436        dev->pci_slot = PCI_SLOT(dev->pci->devfn);
 437
 438        /* I2C Defaults / setup */
 439        dev->i2c_bus[0].dev = dev;
 440        dev->i2c_bus[0].nr = 0;
 441        dev->i2c_bus[1].dev = dev;
 442        dev->i2c_bus[1].nr = 1;
 443        dev->i2c_bus[2].dev = dev;
 444        dev->i2c_bus[2].nr = 2;
 445
 446        /* Transport port A Defaults / setup */
 447        dev->ts1.dev = dev;
 448        dev->ts1.nr = 0;
 449        mutex_init(&dev->ts1.dvb.lock);
 450        INIT_LIST_HEAD(&dev->ts1.dmaqueue.list);
 451        INIT_LIST_HEAD(&dev->ts1.dummy_dmaqueue.list);
 452        mutex_init(&dev->ts1.dmaqueue_lock);
 453        mutex_init(&dev->ts1.dummy_dmaqueue_lock);
 454
 455        /* Transport port B Defaults / setup */
 456        dev->ts2.dev = dev;
 457        dev->ts2.nr = 1;
 458        mutex_init(&dev->ts2.dvb.lock);
 459        INIT_LIST_HEAD(&dev->ts2.dmaqueue.list);
 460        INIT_LIST_HEAD(&dev->ts2.dummy_dmaqueue.list);
 461        mutex_init(&dev->ts2.dmaqueue_lock);
 462        mutex_init(&dev->ts2.dummy_dmaqueue_lock);
 463
 464        if (get_resources(dev) < 0) {
 465                printk(KERN_ERR "CORE %s No more PCIe resources for "
 466                       "subsystem: %04x:%04x\n",
 467                       dev->name, dev->pci->subsystem_vendor,
 468                       dev->pci->subsystem_device);
 469
 470                saa7164_devcount--;
 471                return -ENODEV;
 472        }
 473
 474        /* PCI/e allocations */
 475        dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
 476                             pci_resource_len(dev->pci, 0));
 477
 478        dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
 479                             pci_resource_len(dev->pci, 2));
 480
 481        dev->bmmio = (u8 __iomem *)dev->lmmio;
 482        dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
 483
 484        /* Inerrupt and ack register locations offset of bmmio */
 485        dev->int_status = 0x183000 + 0xf80;
 486        dev->int_ack = 0x183000 + 0xf90;
 487
 488        printk(KERN_INFO
 489                "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
 490               dev->name, dev->pci->subsystem_vendor,
 491               dev->pci->subsystem_device, saa7164_boards[dev->board].name,
 492               dev->board, card[dev->nr] == dev->board ?
 493               "insmod option" : "autodetected");
 494
 495        saa7164_pci_quirks(dev);
 496
 497        return 0;
 498}
 499
 500static void saa7164_dev_unregister(struct saa7164_dev *dev)
 501{
 502        dprintk(1, "%s()\n", __func__);
 503
 504        release_mem_region(pci_resource_start(dev->pci, 0),
 505                pci_resource_len(dev->pci, 0));
 506
 507        release_mem_region(pci_resource_start(dev->pci, 2),
 508                pci_resource_len(dev->pci, 2));
 509
 510        if (!atomic_dec_and_test(&dev->refcount))
 511                return;
 512
 513        iounmap(dev->lmmio);
 514        iounmap(dev->lmmio2);
 515
 516        return;
 517}
 518
 519static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
 520                                     const struct pci_device_id *pci_id)
 521{
 522        struct saa7164_dev *dev;
 523        int err, i;
 524        u32 version;
 525
 526        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 527        if (NULL == dev)
 528                return -ENOMEM;
 529
 530        /* pci init */
 531        dev->pci = pci_dev;
 532        if (pci_enable_device(pci_dev)) {
 533                err = -EIO;
 534                goto fail_free;
 535        }
 536
 537        if (saa7164_dev_setup(dev) < 0) {
 538                err = -EINVAL;
 539                goto fail_free;
 540        }
 541
 542        /* print pci info */
 543        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
 544        pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
 545        printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
 546               "latency: %d, mmio: 0x%llx\n", dev->name,
 547               pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
 548               dev->pci_lat,
 549                (unsigned long long)pci_resource_start(pci_dev, 0));
 550
 551        pci_set_master(pci_dev);
 552        /* TODO */
 553        if (!pci_dma_supported(pci_dev, 0xffffffff)) {
 554                printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
 555                err = -EIO;
 556                goto fail_irq;
 557        }
 558
 559        err = request_irq(pci_dev->irq, saa7164_irq,
 560                IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
 561        if (err < 0) {
 562                printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
 563                        pci_dev->irq);
 564                err = -EIO;
 565                goto fail_irq;
 566        }
 567
 568        pci_set_drvdata(pci_dev, dev);
 569
 570        /* Init the internal command list */
 571        for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
 572                dev->cmds[i].seqno = i;
 573                dev->cmds[i].inuse = 0;
 574                mutex_init(&dev->cmds[i].lock);
 575                init_waitqueue_head(&dev->cmds[i].wait);
 576        }
 577
 578        /* We need a deferred interrupt handler for cmd handling */
 579        INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
 580
 581        /* Only load the firmware if we know the board */
 582        if (dev->board != SAA7164_BOARD_UNKNOWN) {
 583
 584                err = saa7164_downloadfirmware(dev);
 585                if (err < 0) {
 586                        printk(KERN_ERR
 587                                "Failed to boot firmware, no features "
 588                                "registered\n");
 589                        goto fail_fw;
 590                }
 591
 592                saa7164_get_descriptors(dev);
 593                saa7164_dumpregs(dev, 0);
 594                saa7164_getcurrentfirmwareversion(dev);
 595                saa7164_getfirmwarestatus(dev);
 596                err = saa7164_bus_setup(dev);
 597                if (err < 0)
 598                        printk(KERN_ERR
 599                                "Failed to setup the bus, will continue\n");
 600                saa7164_bus_dump(dev);
 601
 602                /* Ping the running firmware via the command bus and get the
 603                 * firmware version, this checks the bus is running OK.
 604                 */
 605                version = 0;
 606                if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
 607                        dprintk(1, "Bus is operating correctly using "
 608                                "version %d.%d.%d.%d (0x%x)\n",
 609                                (version & 0x0000fc00) >> 10,
 610                                (version & 0x000003e0) >> 5,
 611                                (version & 0x0000001f),
 612                                (version & 0xffff0000) >> 16,
 613                                version);
 614                else
 615                        printk(KERN_ERR
 616                                "Failed to communicate with the firmware\n");
 617
 618                /* Bring up the I2C buses */
 619                saa7164_i2c_register(&dev->i2c_bus[0]);
 620                saa7164_i2c_register(&dev->i2c_bus[1]);
 621                saa7164_i2c_register(&dev->i2c_bus[2]);
 622                saa7164_gpio_setup(dev);
 623                saa7164_card_setup(dev);
 624
 625
 626                /* Parse the dynamic device configuration, find various
 627                 * media endpoints (MPEG, WMV, PS, TS) and cache their
 628                 * configuration details into the driver, so we can
 629                 * reference them later during simething_register() func,
 630                 * interrupt handlers, deferred work handlers etc.
 631                 */
 632                saa7164_api_enum_subdevs(dev);
 633
 634                /* Begin to create the video sub-systems and register funcs */
 635                if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
 636                        if (saa7164_dvb_register(&dev->ts1) < 0) {
 637                                printk(KERN_ERR "%s() Failed to register "
 638                                        "dvb adapters on porta\n",
 639                                        __func__);
 640                        }
 641                }
 642
 643                if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
 644                        if (saa7164_dvb_register(&dev->ts2) < 0) {
 645                                printk(KERN_ERR"%s() Failed to register "
 646                                        "dvb adapters on portb\n",
 647                                        __func__);
 648                        }
 649                }
 650
 651        } /* != BOARD_UNKNOWN */
 652        else
 653                printk(KERN_ERR "%s() Unsupported board detected, "
 654                        "registering without firmware\n", __func__);
 655
 656        dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug);
 657        dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
 658
 659fail_fw:
 660        return 0;
 661
 662fail_irq:
 663        saa7164_dev_unregister(dev);
 664fail_free:
 665        kfree(dev);
 666        return err;
 667}
 668
 669static void saa7164_shutdown(struct saa7164_dev *dev)
 670{
 671        dprintk(1, "%s()\n", __func__);
 672}
 673
 674static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
 675{
 676        struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
 677
 678        saa7164_shutdown(dev);
 679
 680        if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
 681                saa7164_dvb_unregister(&dev->ts1);
 682
 683        if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
 684                saa7164_dvb_unregister(&dev->ts2);
 685
 686        saa7164_i2c_unregister(&dev->i2c_bus[0]);
 687        saa7164_i2c_unregister(&dev->i2c_bus[1]);
 688        saa7164_i2c_unregister(&dev->i2c_bus[2]);
 689
 690        pci_disable_device(pci_dev);
 691
 692        /* unregister stuff */
 693        free_irq(pci_dev->irq, dev);
 694        pci_set_drvdata(pci_dev, NULL);
 695
 696        mutex_lock(&devlist);
 697        list_del(&dev->devlist);
 698        mutex_unlock(&devlist);
 699
 700        saa7164_dev_unregister(dev);
 701        kfree(dev);
 702}
 703
 704static struct pci_device_id saa7164_pci_tbl[] = {
 705        {
 706                /* SAA7164 */
 707                .vendor       = 0x1131,
 708                .device       = 0x7164,
 709                .subvendor    = PCI_ANY_ID,
 710                .subdevice    = PCI_ANY_ID,
 711        }, {
 712                /* --- end of list --- */
 713        }
 714};
 715MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
 716
 717static struct pci_driver saa7164_pci_driver = {
 718        .name     = "saa7164",
 719        .id_table = saa7164_pci_tbl,
 720        .probe    = saa7164_initdev,
 721        .remove   = __devexit_p(saa7164_finidev),
 722        /* TODO */
 723        .suspend  = NULL,
 724        .resume   = NULL,
 725};
 726
 727static int saa7164_init(void)
 728{
 729        printk(KERN_INFO "saa7164 driver loaded\n");
 730        return pci_register_driver(&saa7164_pci_driver);
 731}
 732
 733static void saa7164_fini(void)
 734{
 735        pci_unregister_driver(&saa7164_pci_driver);
 736}
 737
 738module_init(saa7164_init);
 739module_exit(saa7164_fini);
 740
 741