linux/drivers/media/dvb/ttpci/budget-ci.c
<<
>>
Prefs
   1/*
   2 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
   3 *
   4 * Compiled from various sources by Michael Hunold <michael@mihu.de>
   5 *
   6 *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
   7 *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
   8 *
   9 * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License
  13 * as published by the Free Software Foundation; either version 2
  14 * of the License, or (at your option) any later version.
  15 *
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  27 *
  28 *
  29 * the project's page is at http://www.linuxtv.org/dvb/
  30 */
  31
  32#include <linux/module.h>
  33#include <linux/errno.h>
  34#include <linux/slab.h>
  35#include <linux/interrupt.h>
  36#include <linux/input.h>
  37#include <linux/spinlock.h>
  38#include <media/ir-common.h>
  39
  40#include "budget.h"
  41
  42#include "dvb_ca_en50221.h"
  43#include "stv0299.h"
  44#include "stv0297.h"
  45#include "tda1004x.h"
  46#include "stb0899_drv.h"
  47#include "stb0899_reg.h"
  48#include "stb0899_cfg.h"
  49#include "stb6100.h"
  50#include "stb6100_cfg.h"
  51#include "lnbp21.h"
  52#include "bsbe1.h"
  53#include "bsru6.h"
  54#include "tda1002x.h"
  55#include "tda827x.h"
  56
  57/*
  58 * Regarding DEBIADDR_IR:
  59 * Some CI modules hang if random addresses are read.
  60 * Using address 0x4000 for the IR read means that we
  61 * use the same address as for CI version, which should
  62 * be a safe default.
  63 */
  64#define DEBIADDR_IR             0x4000
  65#define DEBIADDR_CICONTROL      0x0000
  66#define DEBIADDR_CIVERSION      0x4000
  67#define DEBIADDR_IO             0x1000
  68#define DEBIADDR_ATTR           0x3000
  69
  70#define CICONTROL_RESET         0x01
  71#define CICONTROL_ENABLETS      0x02
  72#define CICONTROL_CAMDETECT     0x08
  73
  74#define DEBICICTL               0x00420000
  75#define DEBICICAM               0x02420000
  76
  77#define SLOTSTATUS_NONE         1
  78#define SLOTSTATUS_PRESENT      2
  79#define SLOTSTATUS_RESET        4
  80#define SLOTSTATUS_READY        8
  81#define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
  82
  83/*
  84 * Milliseconds during which a key is regarded as pressed.
  85 * If an identical command arrives within this time, the timer will start over.
  86 */
  87#define IR_KEYPRESS_TIMEOUT     250
  88
  89/* RC5 device wildcard */
  90#define IR_DEVICE_ANY           255
  91
  92static int rc5_device = -1;
  93module_param(rc5_device, int, 0644);
  94MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
  95
  96static int ir_debug;
  97module_param(ir_debug, int, 0644);
  98MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
  99
 100DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 101
 102struct budget_ci_ir {
 103        struct input_dev *dev;
 104        struct tasklet_struct msp430_irq_tasklet;
 105        struct timer_list timer_keyup;
 106        char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
 107        char phys[32];
 108        struct ir_input_state state;
 109        int rc5_device;
 110        u32 last_raw;
 111        u32 ir_key;
 112        bool have_command;
 113};
 114
 115struct budget_ci {
 116        struct budget budget;
 117        struct tasklet_struct ciintf_irq_tasklet;
 118        int slot_status;
 119        int ci_irq;
 120        struct dvb_ca_en50221 ca;
 121        struct budget_ci_ir ir;
 122        u8 tuner_pll_address; /* used for philips_tdm1316l configs */
 123};
 124
 125static void msp430_ir_keyup(unsigned long data)
 126{
 127        struct budget_ci_ir *ir = (struct budget_ci_ir *) data;
 128        ir_input_nokey(ir->dev, &ir->state);
 129}
 130
 131static void msp430_ir_interrupt(unsigned long data)
 132{
 133        struct budget_ci *budget_ci = (struct budget_ci *) data;
 134        struct input_dev *dev = budget_ci->ir.dev;
 135        u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
 136        u32 raw;
 137
 138        /*
 139         * The msp430 chip can generate two different bytes, command and device
 140         *
 141         * type1: X1CCCCCC, C = command bits (0 - 63)
 142         * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
 143         *
 144         * Each signal from the remote control can generate one or more command
 145         * bytes and one or more device bytes. For the repeated bytes, the
 146         * highest bit (X) is set. The first command byte is always generated
 147         * before the first device byte. Other than that, no specific order
 148         * seems to apply. To make life interesting, bytes can also be lost.
 149         *
 150         * Only when we have a command and device byte, a keypress is
 151         * generated.
 152         */
 153
 154        if (ir_debug)
 155                printk("budget_ci: received byte 0x%02x\n", command);
 156
 157        /* Remove repeat bit, we use every command */
 158        command = command & 0x7f;
 159
 160        /* Is this a RC5 command byte? */
 161        if (command & 0x40) {
 162                budget_ci->ir.have_command = true;
 163                budget_ci->ir.ir_key = command & 0x3f;
 164                return;
 165        }
 166
 167        /* It's a RC5 device byte */
 168        if (!budget_ci->ir.have_command)
 169                return;
 170        budget_ci->ir.have_command = false;
 171
 172        if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
 173            budget_ci->ir.rc5_device != (command & 0x1f))
 174                return;
 175
 176        /* Is this a repeated key sequence? (same device, command, toggle) */
 177        raw = budget_ci->ir.ir_key | (command << 8);
 178        if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) {
 179                ir_input_nokey(dev, &budget_ci->ir.state);
 180                ir_input_keydown(dev, &budget_ci->ir.state,
 181                                 budget_ci->ir.ir_key, raw);
 182                budget_ci->ir.last_raw = raw;
 183        }
 184
 185        mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT));
 186}
 187
 188static int msp430_ir_init(struct budget_ci *budget_ci)
 189{
 190        struct saa7146_dev *saa = budget_ci->budget.dev;
 191        struct input_dev *input_dev = budget_ci->ir.dev;
 192        int error;
 193
 194        budget_ci->ir.dev = input_dev = input_allocate_device();
 195        if (!input_dev) {
 196                printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
 197                error = -ENOMEM;
 198                goto out1;
 199        }
 200
 201        snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
 202                 "Budget-CI dvb ir receiver %s", saa->name);
 203        snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
 204                 "pci-%s/ir0", pci_name(saa->pci));
 205
 206        input_dev->name = budget_ci->ir.name;
 207
 208        input_dev->phys = budget_ci->ir.phys;
 209        input_dev->id.bustype = BUS_PCI;
 210        input_dev->id.version = 1;
 211        if (saa->pci->subsystem_vendor) {
 212                input_dev->id.vendor = saa->pci->subsystem_vendor;
 213                input_dev->id.product = saa->pci->subsystem_device;
 214        } else {
 215                input_dev->id.vendor = saa->pci->vendor;
 216                input_dev->id.product = saa->pci->device;
 217        }
 218        input_dev->dev.parent = &saa->pci->dev;
 219
 220        /* Select keymap and address */
 221        switch (budget_ci->budget.dev->pci->subsystem_device) {
 222        case 0x100c:
 223        case 0x100f:
 224        case 0x1011:
 225        case 0x1012:
 226                /* The hauppauge keymap is a superset of these remotes */
 227                ir_input_init(input_dev, &budget_ci->ir.state,
 228                              IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
 229
 230                if (rc5_device < 0)
 231                        budget_ci->ir.rc5_device = 0x1f;
 232                else
 233                        budget_ci->ir.rc5_device = rc5_device;
 234                break;
 235        case 0x1010:
 236        case 0x1017:
 237        case 0x101a:
 238                /* for the Technotrend 1500 bundled remote */
 239                ir_input_init(input_dev, &budget_ci->ir.state,
 240                              IR_TYPE_RC5, &ir_codes_tt_1500_table);
 241
 242                if (rc5_device < 0)
 243                        budget_ci->ir.rc5_device = IR_DEVICE_ANY;
 244                else
 245                        budget_ci->ir.rc5_device = rc5_device;
 246                break;
 247        default:
 248                /* unknown remote */
 249                ir_input_init(input_dev, &budget_ci->ir.state,
 250                              IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
 251
 252                if (rc5_device < 0)
 253                        budget_ci->ir.rc5_device = IR_DEVICE_ANY;
 254                else
 255                        budget_ci->ir.rc5_device = rc5_device;
 256                break;
 257        }
 258
 259        /* initialise the key-up timeout handler */
 260        init_timer(&budget_ci->ir.timer_keyup);
 261        budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
 262        budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
 263        budget_ci->ir.last_raw = 0xffff; /* An impossible value */
 264        error = input_register_device(input_dev);
 265        if (error) {
 266                printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
 267                goto out2;
 268        }
 269
 270        /* note: these must be after input_register_device */
 271        input_dev->rep[REP_DELAY] = 400;
 272        input_dev->rep[REP_PERIOD] = 250;
 273
 274        tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
 275                     (unsigned long) budget_ci);
 276
 277        SAA7146_IER_ENABLE(saa, MASK_06);
 278        saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
 279
 280        return 0;
 281
 282out2:
 283        input_free_device(input_dev);
 284out1:
 285        return error;
 286}
 287
 288static void msp430_ir_deinit(struct budget_ci *budget_ci)
 289{
 290        struct saa7146_dev *saa = budget_ci->budget.dev;
 291        struct input_dev *dev = budget_ci->ir.dev;
 292
 293        SAA7146_IER_DISABLE(saa, MASK_06);
 294        saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 295        tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
 296
 297        del_timer_sync(&dev->timer);
 298        ir_input_nokey(dev, &budget_ci->ir.state);
 299
 300        input_unregister_device(dev);
 301}
 302
 303static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
 304{
 305        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 306
 307        if (slot != 0)
 308                return -EINVAL;
 309
 310        return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
 311                                     DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
 312}
 313
 314static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
 315{
 316        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 317
 318        if (slot != 0)
 319                return -EINVAL;
 320
 321        return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
 322                                      DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
 323}
 324
 325static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
 326{
 327        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 328
 329        if (slot != 0)
 330                return -EINVAL;
 331
 332        return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
 333                                     DEBIADDR_IO | (address & 3), 1, 1, 0);
 334}
 335
 336static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
 337{
 338        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 339
 340        if (slot != 0)
 341                return -EINVAL;
 342
 343        return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
 344                                      DEBIADDR_IO | (address & 3), 1, value, 1, 0);
 345}
 346
 347static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
 348{
 349        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 350        struct saa7146_dev *saa = budget_ci->budget.dev;
 351
 352        if (slot != 0)
 353                return -EINVAL;
 354
 355        if (budget_ci->ci_irq) {
 356                // trigger on RISING edge during reset so we know when READY is re-asserted
 357                saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
 358        }
 359        budget_ci->slot_status = SLOTSTATUS_RESET;
 360        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
 361        msleep(1);
 362        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
 363                               CICONTROL_RESET, 1, 0);
 364
 365        saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
 366        ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
 367        return 0;
 368}
 369
 370static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
 371{
 372        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 373        struct saa7146_dev *saa = budget_ci->budget.dev;
 374
 375        if (slot != 0)
 376                return -EINVAL;
 377
 378        saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
 379        ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
 380        return 0;
 381}
 382
 383static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
 384{
 385        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 386        struct saa7146_dev *saa = budget_ci->budget.dev;
 387        int tmp;
 388
 389        if (slot != 0)
 390                return -EINVAL;
 391
 392        saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
 393
 394        tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
 395        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
 396                               tmp | CICONTROL_ENABLETS, 1, 0);
 397
 398        ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
 399        return 0;
 400}
 401
 402static void ciintf_interrupt(unsigned long data)
 403{
 404        struct budget_ci *budget_ci = (struct budget_ci *) data;
 405        struct saa7146_dev *saa = budget_ci->budget.dev;
 406        unsigned int flags;
 407
 408        // ensure we don't get spurious IRQs during initialisation
 409        if (!budget_ci->budget.ci_present)
 410                return;
 411
 412        // read the CAM status
 413        flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
 414        if (flags & CICONTROL_CAMDETECT) {
 415
 416                // GPIO should be set to trigger on falling edge if a CAM is present
 417                saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
 418
 419                if (budget_ci->slot_status & SLOTSTATUS_NONE) {
 420                        // CAM insertion IRQ
 421                        budget_ci->slot_status = SLOTSTATUS_PRESENT;
 422                        dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
 423                                                     DVB_CA_EN50221_CAMCHANGE_INSERTED);
 424
 425                } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
 426                        // CAM ready (reset completed)
 427                        budget_ci->slot_status = SLOTSTATUS_READY;
 428                        dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
 429
 430                } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
 431                        // FR/DA IRQ
 432                        dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
 433                }
 434        } else {
 435
 436                // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
 437                // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
 438                // the CAM might not actually be ready yet.
 439                saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
 440
 441                // generate a CAM removal IRQ if we haven't already
 442                if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
 443                        // CAM removal IRQ
 444                        budget_ci->slot_status = SLOTSTATUS_NONE;
 445                        dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
 446                                                     DVB_CA_EN50221_CAMCHANGE_REMOVED);
 447                }
 448        }
 449}
 450
 451static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
 452{
 453        struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
 454        unsigned int flags;
 455
 456        // ensure we don't get spurious IRQs during initialisation
 457        if (!budget_ci->budget.ci_present)
 458                return -EINVAL;
 459
 460        // read the CAM status
 461        flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
 462        if (flags & CICONTROL_CAMDETECT) {
 463                // mark it as present if it wasn't before
 464                if (budget_ci->slot_status & SLOTSTATUS_NONE) {
 465                        budget_ci->slot_status = SLOTSTATUS_PRESENT;
 466                }
 467
 468                // during a RESET, we check if we can read from IO memory to see when CAM is ready
 469                if (budget_ci->slot_status & SLOTSTATUS_RESET) {
 470                        if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
 471                                budget_ci->slot_status = SLOTSTATUS_READY;
 472                        }
 473                }
 474        } else {
 475                budget_ci->slot_status = SLOTSTATUS_NONE;
 476        }
 477
 478        if (budget_ci->slot_status != SLOTSTATUS_NONE) {
 479                if (budget_ci->slot_status & SLOTSTATUS_READY) {
 480                        return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
 481                }
 482                return DVB_CA_EN50221_POLL_CAM_PRESENT;
 483        }
 484
 485        return 0;
 486}
 487
 488static int ciintf_init(struct budget_ci *budget_ci)
 489{
 490        struct saa7146_dev *saa = budget_ci->budget.dev;
 491        int flags;
 492        int result;
 493        int ci_version;
 494        int ca_flags;
 495
 496        memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
 497
 498        // enable DEBI pins
 499        saa7146_write(saa, MC1, MASK_27 | MASK_11);
 500
 501        // test if it is there
 502        ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
 503        if ((ci_version & 0xa0) != 0xa0) {
 504                result = -ENODEV;
 505                goto error;
 506        }
 507
 508        // determine whether a CAM is present or not
 509        flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
 510        budget_ci->slot_status = SLOTSTATUS_NONE;
 511        if (flags & CICONTROL_CAMDETECT)
 512                budget_ci->slot_status = SLOTSTATUS_PRESENT;
 513
 514        // version 0xa2 of the CI firmware doesn't generate interrupts
 515        if (ci_version == 0xa2) {
 516                ca_flags = 0;
 517                budget_ci->ci_irq = 0;
 518        } else {
 519                ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
 520                                DVB_CA_EN50221_FLAG_IRQ_FR |
 521                                DVB_CA_EN50221_FLAG_IRQ_DA;
 522                budget_ci->ci_irq = 1;
 523        }
 524
 525        // register CI interface
 526        budget_ci->ca.owner = THIS_MODULE;
 527        budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
 528        budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
 529        budget_ci->ca.read_cam_control = ciintf_read_cam_control;
 530        budget_ci->ca.write_cam_control = ciintf_write_cam_control;
 531        budget_ci->ca.slot_reset = ciintf_slot_reset;
 532        budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
 533        budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
 534        budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
 535        budget_ci->ca.data = budget_ci;
 536        if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
 537                                          &budget_ci->ca,
 538                                          ca_flags, 1)) != 0) {
 539                printk("budget_ci: CI interface detected, but initialisation failed.\n");
 540                goto error;
 541        }
 542
 543        // Setup CI slot IRQ
 544        if (budget_ci->ci_irq) {
 545                tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
 546                if (budget_ci->slot_status != SLOTSTATUS_NONE) {
 547                        saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
 548                } else {
 549                        saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
 550                }
 551                SAA7146_IER_ENABLE(saa, MASK_03);
 552        }
 553
 554        // enable interface
 555        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
 556                               CICONTROL_RESET, 1, 0);
 557
 558        // success!
 559        printk("budget_ci: CI interface initialised\n");
 560        budget_ci->budget.ci_present = 1;
 561
 562        // forge a fake CI IRQ so the CAM state is setup correctly
 563        if (budget_ci->ci_irq) {
 564                flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
 565                if (budget_ci->slot_status != SLOTSTATUS_NONE)
 566                        flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
 567                dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
 568        }
 569
 570        return 0;
 571
 572error:
 573        saa7146_write(saa, MC1, MASK_27);
 574        return result;
 575}
 576
 577static void ciintf_deinit(struct budget_ci *budget_ci)
 578{
 579        struct saa7146_dev *saa = budget_ci->budget.dev;
 580
 581        // disable CI interrupts
 582        if (budget_ci->ci_irq) {
 583                SAA7146_IER_DISABLE(saa, MASK_03);
 584                saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
 585                tasklet_kill(&budget_ci->ciintf_irq_tasklet);
 586        }
 587
 588        // reset interface
 589        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
 590        msleep(1);
 591        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
 592                               CICONTROL_RESET, 1, 0);
 593
 594        // disable TS data stream to CI interface
 595        saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
 596
 597        // release the CA device
 598        dvb_ca_en50221_release(&budget_ci->ca);
 599
 600        // disable DEBI pins
 601        saa7146_write(saa, MC1, MASK_27);
 602}
 603
 604static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
 605{
 606        struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
 607
 608        dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
 609
 610        if (*isr & MASK_06)
 611                tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet);
 612
 613        if (*isr & MASK_10)
 614                ttpci_budget_irq10_handler(dev, isr);
 615
 616        if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
 617                tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
 618}
 619
 620static u8 philips_su1278_tt_inittab[] = {
 621        0x01, 0x0f,
 622        0x02, 0x30,
 623        0x03, 0x00,
 624        0x04, 0x5b,
 625        0x05, 0x85,
 626        0x06, 0x02,
 627        0x07, 0x00,
 628        0x08, 0x02,
 629        0x09, 0x00,
 630        0x0C, 0x01,
 631        0x0D, 0x81,
 632        0x0E, 0x44,
 633        0x0f, 0x14,
 634        0x10, 0x3c,
 635        0x11, 0x84,
 636        0x12, 0xda,
 637        0x13, 0x97,
 638        0x14, 0x95,
 639        0x15, 0xc9,
 640        0x16, 0x19,
 641        0x17, 0x8c,
 642        0x18, 0x59,
 643        0x19, 0xf8,
 644        0x1a, 0xfe,
 645        0x1c, 0x7f,
 646        0x1d, 0x00,
 647        0x1e, 0x00,
 648        0x1f, 0x50,
 649        0x20, 0x00,
 650        0x21, 0x00,
 651        0x22, 0x00,
 652        0x23, 0x00,
 653        0x28, 0x00,
 654        0x29, 0x28,
 655        0x2a, 0x14,
 656        0x2b, 0x0f,
 657        0x2c, 0x09,
 658        0x2d, 0x09,
 659        0x31, 0x1f,
 660        0x32, 0x19,
 661        0x33, 0xfc,
 662        0x34, 0x93,
 663        0xff, 0xff
 664};
 665
 666static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
 667{
 668        stv0299_writereg(fe, 0x0e, 0x44);
 669        if (srate >= 10000000) {
 670                stv0299_writereg(fe, 0x13, 0x97);
 671                stv0299_writereg(fe, 0x14, 0x95);
 672                stv0299_writereg(fe, 0x15, 0xc9);
 673                stv0299_writereg(fe, 0x17, 0x8c);
 674                stv0299_writereg(fe, 0x1a, 0xfe);
 675                stv0299_writereg(fe, 0x1c, 0x7f);
 676                stv0299_writereg(fe, 0x2d, 0x09);
 677        } else {
 678                stv0299_writereg(fe, 0x13, 0x99);
 679                stv0299_writereg(fe, 0x14, 0x8d);
 680                stv0299_writereg(fe, 0x15, 0xce);
 681                stv0299_writereg(fe, 0x17, 0x43);
 682                stv0299_writereg(fe, 0x1a, 0x1d);
 683                stv0299_writereg(fe, 0x1c, 0x12);
 684                stv0299_writereg(fe, 0x2d, 0x05);
 685        }
 686        stv0299_writereg(fe, 0x0e, 0x23);
 687        stv0299_writereg(fe, 0x0f, 0x94);
 688        stv0299_writereg(fe, 0x10, 0x39);
 689        stv0299_writereg(fe, 0x15, 0xc9);
 690
 691        stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 692        stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
 693        stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
 694
 695        return 0;
 696}
 697
 698static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe,
 699                                           struct dvb_frontend_parameters *params)
 700{
 701        struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
 702        u32 div;
 703        u8 buf[4];
 704        struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
 705
 706        if ((params->frequency < 950000) || (params->frequency > 2150000))
 707                return -EINVAL;
 708
 709        div = (params->frequency + (500 - 1)) / 500;    // round correctly
 710        buf[0] = (div >> 8) & 0x7f;
 711        buf[1] = div & 0xff;
 712        buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
 713        buf[3] = 0x20;
 714
 715        if (params->u.qpsk.symbol_rate < 4000000)
 716                buf[3] |= 1;
 717
 718        if (params->frequency < 1250000)
 719                buf[3] |= 0;
 720        else if (params->frequency < 1550000)
 721                buf[3] |= 0x40;
 722        else if (params->frequency < 2050000)
 723                buf[3] |= 0x80;
 724        else if (params->frequency < 2150000)
 725                buf[3] |= 0xC0;
 726
 727        if (fe->ops.i2c_gate_ctrl)
 728                fe->ops.i2c_gate_ctrl(fe, 1);
 729        if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
 730                return -EIO;
 731        return 0;
 732}
 733
 734static struct stv0299_config philips_su1278_tt_config = {
 735
 736        .demod_address = 0x68,
 737        .inittab = philips_su1278_tt_inittab,
 738        .mclk = 64000000UL,
 739        .invert = 0,
 740        .skip_reinit = 1,
 741        .lock_output = STV0299_LOCKOUTPUT_1,
 742        .volt13_op0_op1 = STV0299_VOLT13_OP1,
 743        .min_delay_ms = 50,
 744        .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
 745};
 746
 747
 748
 749static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe)
 750{
 751        struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
 752        static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
 753        static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
 754        struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
 755                        sizeof(td1316_init) };
 756
 757        // setup PLL configuration
 758        if (fe->ops.i2c_gate_ctrl)
 759                fe->ops.i2c_gate_ctrl(fe, 1);
 760        if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
 761                return -EIO;
 762        msleep(1);
 763
 764        // disable the mc44BC374c (do not check for errors)
 765        tuner_msg.addr = 0x65;
 766        tuner_msg.buf = disable_mc44BC374c;
 767        tuner_msg.len = sizeof(disable_mc44BC374c);
 768        if (fe->ops.i2c_gate_ctrl)
 769                fe->ops.i2c_gate_ctrl(fe, 1);
 770        if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
 771                if (fe->ops.i2c_gate_ctrl)
 772                        fe->ops.i2c_gate_ctrl(fe, 1);
 773                i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
 774        }
 775
 776        return 0;
 777}
 778
 779static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
 780{
 781        struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
 782        u8 tuner_buf[4];
 783        struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
 784        int tuner_frequency = 0;
 785        u8 band, cp, filter;
 786
 787        // determine charge pump
 788        tuner_frequency = params->frequency + 36130000;
 789        if (tuner_frequency < 87000000)
 790                return -EINVAL;
 791        else if (tuner_frequency < 130000000)
 792                cp = 3;
 793        else if (tuner_frequency < 160000000)
 794                cp = 5;
 795        else if (tuner_frequency < 200000000)
 796                cp = 6;
 797        else if (tuner_frequency < 290000000)
 798                cp = 3;
 799        else if (tuner_frequency < 420000000)
 800                cp = 5;
 801        else if (tuner_frequency < 480000000)
 802                cp = 6;
 803        else if (tuner_frequency < 620000000)
 804                cp = 3;
 805        else if (tuner_frequency < 830000000)
 806                cp = 5;
 807        else if (tuner_frequency < 895000000)
 808                cp = 7;
 809        else
 810                return -EINVAL;
 811
 812        // determine band
 813        if (params->frequency < 49000000)
 814                return -EINVAL;
 815        else if (params->frequency < 159000000)
 816                band = 1;
 817        else if (params->frequency < 444000000)
 818                band = 2;
 819        else if (params->frequency < 861000000)
 820                band = 4;
 821        else
 822                return -EINVAL;
 823
 824        // setup PLL filter and TDA9889
 825        switch (params->u.ofdm.bandwidth) {
 826        case BANDWIDTH_6_MHZ:
 827                tda1004x_writereg(fe, 0x0C, 0x14);
 828                filter = 0;
 829                break;
 830
 831        case BANDWIDTH_7_MHZ:
 832                tda1004x_writereg(fe, 0x0C, 0x80);
 833                filter = 0;
 834                break;
 835
 836        case BANDWIDTH_8_MHZ:
 837                tda1004x_writereg(fe, 0x0C, 0x14);
 838                filter = 1;
 839                break;
 840
 841        default:
 842                return -EINVAL;
 843        }
 844
 845        // calculate divisor
 846        // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
 847        tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
 848
 849        // setup tuner buffer
 850        tuner_buf[0] = tuner_frequency >> 8;
 851        tuner_buf[1] = tuner_frequency & 0xff;
 852        tuner_buf[2] = 0xca;
 853        tuner_buf[3] = (cp << 5) | (filter << 3) | band;
 854
 855        if (fe->ops.i2c_gate_ctrl)
 856                fe->ops.i2c_gate_ctrl(fe, 1);
 857        if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
 858                return -EIO;
 859
 860        msleep(1);
 861        return 0;
 862}
 863
 864static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
 865                                             const struct firmware **fw, char *name)
 866{
 867        struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
 868
 869        return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
 870}
 871
 872static struct tda1004x_config philips_tdm1316l_config = {
 873
 874        .demod_address = 0x8,
 875        .invert = 0,
 876        .invert_oclk = 0,
 877        .xtal_freq = TDA10046_XTAL_4M,
 878        .agc_config = TDA10046_AGC_DEFAULT,
 879        .if_freq = TDA10046_FREQ_3617,
 880        .request_firmware = philips_tdm1316l_request_firmware,
 881};
 882
 883static struct tda1004x_config philips_tdm1316l_config_invert = {
 884
 885        .demod_address = 0x8,
 886        .invert = 1,
 887        .invert_oclk = 0,
 888        .xtal_freq = TDA10046_XTAL_4M,
 889        .agc_config = TDA10046_AGC_DEFAULT,
 890        .if_freq = TDA10046_FREQ_3617,
 891        .request_firmware = philips_tdm1316l_request_firmware,
 892};
 893
 894static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
 895{
 896        struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
 897        u8 tuner_buf[5];
 898        struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,
 899                                    .flags = 0,
 900                                    .buf = tuner_buf,
 901                                    .len = sizeof(tuner_buf) };
 902        int tuner_frequency = 0;
 903        u8 band, cp, filter;
 904
 905        // determine charge pump
 906        tuner_frequency = params->frequency + 36125000;
 907        if (tuner_frequency < 87000000)
 908                return -EINVAL;
 909        else if (tuner_frequency < 130000000) {
 910                cp = 3;
 911                band = 1;
 912        } else if (tuner_frequency < 160000000) {
 913                cp = 5;
 914                band = 1;
 915        } else if (tuner_frequency < 200000000) {
 916                cp = 6;
 917                band = 1;
 918        } else if (tuner_frequency < 290000000) {
 919                cp = 3;
 920                band = 2;
 921        } else if (tuner_frequency < 420000000) {
 922                cp = 5;
 923                band = 2;
 924        } else if (tuner_frequency < 480000000) {
 925                cp = 6;
 926                band = 2;
 927        } else if (tuner_frequency < 620000000) {
 928                cp = 3;
 929                band = 4;
 930        } else if (tuner_frequency < 830000000) {
 931                cp = 5;
 932                band = 4;
 933        } else if (tuner_frequency < 895000000) {
 934                cp = 7;
 935                band = 4;
 936        } else
 937                return -EINVAL;
 938
 939        // assume PLL filter should always be 8MHz for the moment.
 940        filter = 1;
 941
 942        // calculate divisor
 943        tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500;
 944
 945        // setup tuner buffer
 946        tuner_buf[0] = tuner_frequency >> 8;
 947        tuner_buf[1] = tuner_frequency & 0xff;
 948        tuner_buf[2] = 0xc8;
 949        tuner_buf[3] = (cp << 5) | (filter << 3) | band;
 950        tuner_buf[4] = 0x80;
 951
 952        if (fe->ops.i2c_gate_ctrl)
 953                fe->ops.i2c_gate_ctrl(fe, 1);
 954        if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
 955                return -EIO;
 956
 957        msleep(50);
 958
 959        if (fe->ops.i2c_gate_ctrl)
 960                fe->ops.i2c_gate_ctrl(fe, 1);
 961        if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
 962                return -EIO;
 963
 964        msleep(1);
 965
 966        return 0;
 967}
 968
 969static u8 dvbc_philips_tdm1316l_inittab[] = {
 970        0x80, 0x01,
 971        0x80, 0x00,
 972        0x81, 0x01,
 973        0x81, 0x00,
 974        0x00, 0x09,
 975        0x01, 0x69,
 976        0x03, 0x00,
 977        0x04, 0x00,
 978        0x07, 0x00,
 979        0x08, 0x00,
 980        0x20, 0x00,
 981        0x21, 0x40,
 982        0x22, 0x00,
 983        0x23, 0x00,
 984        0x24, 0x40,
 985        0x25, 0x88,
 986        0x30, 0xff,
 987        0x31, 0x00,
 988        0x32, 0xff,
 989        0x33, 0x00,
 990        0x34, 0x50,
 991        0x35, 0x7f,
 992        0x36, 0x00,
 993        0x37, 0x20,
 994        0x38, 0x00,
 995        0x40, 0x1c,
 996        0x41, 0xff,
 997        0x42, 0x29,
 998        0x43, 0x20,
 999        0x44, 0xff,
1000        0x45, 0x00,
1001        0x46, 0x00,
1002        0x49, 0x04,
1003        0x4a, 0x00,
1004        0x4b, 0x7b,
1005        0x52, 0x30,
1006        0x55, 0xae,
1007        0x56, 0x47,
1008        0x57, 0xe1,
1009        0x58, 0x3a,
1010        0x5a, 0x1e,
1011        0x5b, 0x34,
1012        0x60, 0x00,
1013        0x63, 0x00,
1014        0x64, 0x00,
1015        0x65, 0x00,
1016        0x66, 0x00,
1017        0x67, 0x00,
1018        0x68, 0x00,
1019        0x69, 0x00,
1020        0x6a, 0x02,
1021        0x6b, 0x00,
1022        0x70, 0xff,
1023        0x71, 0x00,
1024        0x72, 0x00,
1025        0x73, 0x00,
1026        0x74, 0x0c,
1027        0x80, 0x00,
1028        0x81, 0x00,
1029        0x82, 0x00,
1030        0x83, 0x00,
1031        0x84, 0x04,
1032        0x85, 0x80,
1033        0x86, 0x24,
1034        0x87, 0x78,
1035        0x88, 0x10,
1036        0x89, 0x00,
1037        0x90, 0x01,
1038        0x91, 0x01,
1039        0xa0, 0x04,
1040        0xa1, 0x00,
1041        0xa2, 0x00,
1042        0xb0, 0x91,
1043        0xb1, 0x0b,
1044        0xc0, 0x53,
1045        0xc1, 0x70,
1046        0xc2, 0x12,
1047        0xd0, 0x00,
1048        0xd1, 0x00,
1049        0xd2, 0x00,
1050        0xd3, 0x00,
1051        0xd4, 0x00,
1052        0xd5, 0x00,
1053        0xde, 0x00,
1054        0xdf, 0x00,
1055        0x61, 0x38,
1056        0x62, 0x0a,
1057        0x53, 0x13,
1058        0x59, 0x08,
1059        0xff, 0xff,
1060};
1061
1062static struct stv0297_config dvbc_philips_tdm1316l_config = {
1063        .demod_address = 0x1c,
1064        .inittab = dvbc_philips_tdm1316l_inittab,
1065        .invert = 0,
1066        .stop_during_read = 1,
1067};
1068
1069static struct tda10023_config tda10023_config = {
1070        .demod_address = 0xc,
1071        .invert = 0,
1072        .xtal = 16000000,
1073        .pll_m = 11,
1074        .pll_p = 3,
1075        .pll_n = 1,
1076        .deltaf = 0xa511,
1077};
1078
1079static struct tda827x_config tda827x_config = {
1080        .config = 0,
1081};
1082
1083/* TT S2-3200 DVB-S (STB0899) Inittab */
1084static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
1085
1086        { STB0899_DEV_ID                , 0x81 },
1087        { STB0899_DISCNTRL1             , 0x32 },
1088        { STB0899_DISCNTRL2             , 0x80 },
1089        { STB0899_DISRX_ST0             , 0x04 },
1090        { STB0899_DISRX_ST1             , 0x00 },
1091        { STB0899_DISPARITY             , 0x00 },
1092        { STB0899_DISFIFO               , 0x00 },
1093        { STB0899_DISSTATUS             , 0x20 },
1094        { STB0899_DISF22                , 0x8c },
1095        { STB0899_DISF22RX              , 0x9a },
1096        { STB0899_SYSREG                , 0x0b },
1097        { STB0899_ACRPRESC              , 0x11 },
1098        { STB0899_ACRDIV1               , 0x0a },
1099        { STB0899_ACRDIV2               , 0x05 },
1100        { STB0899_DACR1                 , 0x00 },
1101        { STB0899_DACR2                 , 0x00 },
1102        { STB0899_OUTCFG                , 0x00 },
1103        { STB0899_MODECFG               , 0x00 },
1104        { STB0899_IRQSTATUS_3           , 0x30 },
1105        { STB0899_IRQSTATUS_2           , 0x00 },
1106        { STB0899_IRQSTATUS_1           , 0x00 },
1107        { STB0899_IRQSTATUS_0           , 0x00 },
1108        { STB0899_IRQMSK_3              , 0xf3 },
1109        { STB0899_IRQMSK_2              , 0xfc },
1110        { STB0899_IRQMSK_1              , 0xff },
1111        { STB0899_IRQMSK_0              , 0xff },
1112        { STB0899_IRQCFG                , 0x00 },
1113        { STB0899_I2CCFG                , 0x88 },
1114        { STB0899_I2CRPT                , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
1115        { STB0899_IOPVALUE5             , 0x00 },
1116        { STB0899_IOPVALUE4             , 0x20 },
1117        { STB0899_IOPVALUE3             , 0xc9 },
1118        { STB0899_IOPVALUE2             , 0x90 },
1119        { STB0899_IOPVALUE1             , 0x40 },
1120        { STB0899_IOPVALUE0             , 0x00 },
1121        { STB0899_GPIO00CFG             , 0x82 },
1122        { STB0899_GPIO01CFG             , 0x82 },
1123        { STB0899_GPIO02CFG             , 0x82 },
1124        { STB0899_GPIO03CFG             , 0x82 },
1125        { STB0899_GPIO04CFG             , 0x82 },
1126        { STB0899_GPIO05CFG             , 0x82 },
1127        { STB0899_GPIO06CFG             , 0x82 },
1128        { STB0899_GPIO07CFG             , 0x82 },
1129        { STB0899_GPIO08CFG             , 0x82 },
1130        { STB0899_GPIO09CFG             , 0x82 },
1131        { STB0899_GPIO10CFG             , 0x82 },
1132        { STB0899_GPIO11CFG             , 0x82 },
1133        { STB0899_GPIO12CFG             , 0x82 },
1134        { STB0899_GPIO13CFG             , 0x82 },
1135        { STB0899_GPIO14CFG             , 0x82 },
1136        { STB0899_GPIO15CFG             , 0x82 },
1137        { STB0899_GPIO16CFG             , 0x82 },
1138        { STB0899_GPIO17CFG             , 0x82 },
1139        { STB0899_GPIO18CFG             , 0x82 },
1140        { STB0899_GPIO19CFG             , 0x82 },
1141        { STB0899_GPIO20CFG             , 0x82 },
1142        { STB0899_SDATCFG               , 0xb8 },
1143        { STB0899_SCLTCFG               , 0xba },
1144        { STB0899_AGCRFCFG              , 0x1c }, /* 0x11 */
1145        { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
1146        { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
1147        { STB0899_DIRCLKCFG             , 0x82 },
1148        { STB0899_CLKOUT27CFG           , 0x7e },
1149        { STB0899_STDBYCFG              , 0x82 },
1150        { STB0899_CS0CFG                , 0x82 },
1151        { STB0899_CS1CFG                , 0x82 },
1152        { STB0899_DISEQCOCFG            , 0x20 },
1153        { STB0899_GPIO32CFG             , 0x82 },
1154        { STB0899_GPIO33CFG             , 0x82 },
1155        { STB0899_GPIO34CFG             , 0x82 },
1156        { STB0899_GPIO35CFG             , 0x82 },
1157        { STB0899_GPIO36CFG             , 0x82 },
1158        { STB0899_GPIO37CFG             , 0x82 },
1159        { STB0899_GPIO38CFG             , 0x82 },
1160        { STB0899_GPIO39CFG             , 0x82 },
1161        { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
1162        { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
1163        { STB0899_FILTCTRL              , 0x00 },
1164        { STB0899_SYSCTRL               , 0x00 },
1165        { STB0899_STOPCLK1              , 0x20 },
1166        { STB0899_STOPCLK2              , 0x00 },
1167        { STB0899_INTBUFSTATUS          , 0x00 },
1168        { STB0899_INTBUFCTRL            , 0x0a },
1169        { 0xffff                        , 0xff },
1170};
1171
1172static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
1173        { STB0899_DEMOD                 , 0x00 },
1174        { STB0899_RCOMPC                , 0xc9 },
1175        { STB0899_AGC1CN                , 0x41 },
1176        { STB0899_AGC1REF               , 0x10 },
1177        { STB0899_RTC                   , 0x7a },
1178        { STB0899_TMGCFG                , 0x4e },
1179        { STB0899_AGC2REF               , 0x34 },
1180        { STB0899_TLSR                  , 0x84 },
1181        { STB0899_CFD                   , 0xc7 },
1182        { STB0899_ACLC                  , 0x87 },
1183        { STB0899_BCLC                  , 0x94 },
1184        { STB0899_EQON                  , 0x41 },
1185        { STB0899_LDT                   , 0xdd },
1186        { STB0899_LDT2                  , 0xc9 },
1187        { STB0899_EQUALREF              , 0xb4 },
1188        { STB0899_TMGRAMP               , 0x10 },
1189        { STB0899_TMGTHD                , 0x30 },
1190        { STB0899_IDCCOMP               , 0xfb },
1191        { STB0899_QDCCOMP               , 0x03 },
1192        { STB0899_POWERI                , 0x3b },
1193        { STB0899_POWERQ                , 0x3d },
1194        { STB0899_RCOMP                 , 0x81 },
1195        { STB0899_AGCIQIN               , 0x80 },
1196        { STB0899_AGC2I1                , 0x04 },
1197        { STB0899_AGC2I2                , 0xf5 },
1198        { STB0899_TLIR                  , 0x25 },
1199        { STB0899_RTF                   , 0x80 },
1200        { STB0899_DSTATUS               , 0x00 },
1201        { STB0899_LDI                   , 0xca },
1202        { STB0899_CFRM                  , 0xf1 },
1203        { STB0899_CFRL                  , 0xf3 },
1204        { STB0899_NIRM                  , 0x2a },
1205        { STB0899_NIRL                  , 0x05 },
1206        { STB0899_ISYMB                 , 0x17 },
1207        { STB0899_QSYMB                 , 0xfa },
1208        { STB0899_SFRH                  , 0x2f },
1209        { STB0899_SFRM                  , 0x68 },
1210        { STB0899_SFRL                  , 0x40 },
1211        { STB0899_SFRUPH                , 0x2f },
1212        { STB0899_SFRUPM                , 0x68 },
1213        { STB0899_SFRUPL                , 0x40 },
1214        { STB0899_EQUAI1                , 0xfd },
1215        { STB0899_EQUAQ1                , 0x04 },
1216        { STB0899_EQUAI2                , 0x0f },
1217        { STB0899_EQUAQ2                , 0xff },
1218        { STB0899_EQUAI3                , 0xdf },
1219        { STB0899_EQUAQ3                , 0xfa },
1220        { STB0899_EQUAI4                , 0x37 },
1221        { STB0899_EQUAQ4                , 0x0d },
1222        { STB0899_EQUAI5                , 0xbd },
1223        { STB0899_EQUAQ5                , 0xf7 },
1224        { STB0899_DSTATUS2              , 0x00 },
1225        { STB0899_VSTATUS               , 0x00 },
1226        { STB0899_VERROR                , 0xff },
1227        { STB0899_IQSWAP                , 0x2a },
1228        { STB0899_ECNT1M                , 0x00 },
1229        { STB0899_ECNT1L                , 0x00 },
1230        { STB0899_ECNT2M                , 0x00 },
1231        { STB0899_ECNT2L                , 0x00 },
1232        { STB0899_ECNT3M                , 0x00 },
1233        { STB0899_ECNT3L                , 0x00 },
1234        { STB0899_FECAUTO1              , 0x06 },
1235        { STB0899_FECM                  , 0x01 },
1236        { STB0899_VTH12                 , 0xf0 },
1237        { STB0899_VTH23                 , 0xa0 },
1238        { STB0899_VTH34                 , 0x78 },
1239        { STB0899_VTH56                 , 0x4e },
1240        { STB0899_VTH67                 , 0x48 },
1241        { STB0899_VTH78                 , 0x38 },
1242        { STB0899_PRVIT                 , 0xff },
1243        { STB0899_VITSYNC               , 0x19 },
1244        { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1245        { STB0899_TSULC                 , 0x42 },
1246        { STB0899_RSLLC                 , 0x40 },
1247        { STB0899_TSLPL                 , 0x12 },
1248        { STB0899_TSCFGH                , 0x0c },
1249        { STB0899_TSCFGM                , 0x00 },
1250        { STB0899_TSCFGL                , 0x0c },
1251        { STB0899_TSOUT                 , 0x0d }, /* 0x0d for CAM */
1252        { STB0899_RSSYNCDEL             , 0x00 },
1253        { STB0899_TSINHDELH             , 0x02 },
1254        { STB0899_TSINHDELM             , 0x00 },
1255        { STB0899_TSINHDELL             , 0x00 },
1256        { STB0899_TSLLSTKM              , 0x00 },
1257        { STB0899_TSLLSTKL              , 0x00 },
1258        { STB0899_TSULSTKM              , 0x00 },
1259        { STB0899_TSULSTKL              , 0xab },
1260        { STB0899_PCKLENUL              , 0x00 },
1261        { STB0899_PCKLENLL              , 0xcc },
1262        { STB0899_RSPCKLEN              , 0xcc },
1263        { STB0899_TSSTATUS              , 0x80 },
1264        { STB0899_ERRCTRL1              , 0xb6 },
1265        { STB0899_ERRCTRL2              , 0x96 },
1266        { STB0899_ERRCTRL3              , 0x89 },
1267        { STB0899_DMONMSK1              , 0x27 },
1268        { STB0899_DMONMSK0              , 0x03 },
1269        { STB0899_DEMAPVIT              , 0x5c },
1270        { STB0899_PLPARM                , 0x1f },
1271        { STB0899_PDELCTRL              , 0x48 },
1272        { STB0899_PDELCTRL2             , 0x00 },
1273        { STB0899_BBHCTRL1              , 0x00 },
1274        { STB0899_BBHCTRL2              , 0x00 },
1275        { STB0899_HYSTTHRESH            , 0x77 },
1276        { STB0899_MATCSTM               , 0x00 },
1277        { STB0899_MATCSTL               , 0x00 },
1278        { STB0899_UPLCSTM               , 0x00 },
1279        { STB0899_UPLCSTL               , 0x00 },
1280        { STB0899_DFLCSTM               , 0x00 },
1281        { STB0899_DFLCSTL               , 0x00 },
1282        { STB0899_SYNCCST               , 0x00 },
1283        { STB0899_SYNCDCSTM             , 0x00 },
1284        { STB0899_SYNCDCSTL             , 0x00 },
1285        { STB0899_ISI_ENTRY             , 0x00 },
1286        { STB0899_ISI_BIT_EN            , 0x00 },
1287        { STB0899_MATSTRM               , 0x00 },
1288        { STB0899_MATSTRL               , 0x00 },
1289        { STB0899_UPLSTRM               , 0x00 },
1290        { STB0899_UPLSTRL               , 0x00 },
1291        { STB0899_DFLSTRM               , 0x00 },
1292        { STB0899_DFLSTRL               , 0x00 },
1293        { STB0899_SYNCSTR               , 0x00 },
1294        { STB0899_SYNCDSTRM             , 0x00 },
1295        { STB0899_SYNCDSTRL             , 0x00 },
1296        { STB0899_CFGPDELSTATUS1        , 0x10 },
1297        { STB0899_CFGPDELSTATUS2        , 0x00 },
1298        { STB0899_BBFERRORM             , 0x00 },
1299        { STB0899_BBFERRORL             , 0x00 },
1300        { STB0899_UPKTERRORM            , 0x00 },
1301        { STB0899_UPKTERRORL            , 0x00 },
1302        { 0xffff                        , 0xff },
1303};
1304
1305static struct stb0899_config tt3200_config = {
1306        .init_dev               = tt3200_stb0899_s1_init_1,
1307        .init_s2_demod          = stb0899_s2_init_2,
1308        .init_s1_demod          = tt3200_stb0899_s1_init_3,
1309        .init_s2_fec            = stb0899_s2_init_4,
1310        .init_tst               = stb0899_s1_init_5,
1311
1312        .postproc               = NULL,
1313
1314        .demod_address          = 0x68,
1315
1316        .xtal_freq              = 27000000,
1317        .inversion              = IQ_SWAP_ON, /* 1 */
1318
1319        .lo_clk                 = 76500000,
1320        .hi_clk                 = 99000000,
1321
1322        .esno_ave               = STB0899_DVBS2_ESNO_AVE,
1323        .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
1324        .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
1325        .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
1326        .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
1327        .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1328        .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1329        .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1330        .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1331
1332        .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
1333        .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1334        .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
1335        .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
1336
1337        .tuner_get_frequency    = stb6100_get_frequency,
1338        .tuner_set_frequency    = stb6100_set_frequency,
1339        .tuner_set_bandwidth    = stb6100_set_bandwidth,
1340        .tuner_get_bandwidth    = stb6100_get_bandwidth,
1341        .tuner_set_rfsiggain    = NULL
1342};
1343
1344static struct stb6100_config tt3200_stb6100_config = {
1345        .tuner_address  = 0x60,
1346        .refclock       = 27000000,
1347};
1348
1349static void frontend_init(struct budget_ci *budget_ci)
1350{
1351        switch (budget_ci->budget.dev->pci->subsystem_device) {
1352        case 0x100c:            // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
1353                budget_ci->budget.dvb_frontend =
1354                        dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
1355                if (budget_ci->budget.dvb_frontend) {
1356                        budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
1357                        budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1358                        break;
1359                }
1360                break;
1361
1362        case 0x100f:            // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
1363                budget_ci->budget.dvb_frontend =
1364                        dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
1365                if (budget_ci->budget.dvb_frontend) {
1366                        budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params;
1367                        break;
1368                }
1369                break;
1370
1371        case 0x1010:            // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
1372                budget_ci->tuner_pll_address = 0x61;
1373                budget_ci->budget.dvb_frontend =
1374                        dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1375                if (budget_ci->budget.dvb_frontend) {
1376                        budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1377                        break;
1378                }
1379                break;
1380
1381        case 0x1011:            // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
1382                budget_ci->tuner_pll_address = 0x63;
1383                budget_ci->budget.dvb_frontend =
1384                        dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
1385                if (budget_ci->budget.dvb_frontend) {
1386                        budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1387                        budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1388                        break;
1389                }
1390                break;
1391
1392        case 0x1012:            // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
1393                budget_ci->tuner_pll_address = 0x60;
1394                budget_ci->budget.dvb_frontend =
1395                        dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap);
1396                if (budget_ci->budget.dvb_frontend) {
1397                        budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1398                        budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1399                        break;
1400                }
1401                break;
1402
1403        case 0x1017:            // TT S-1500 PCI
1404                budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
1405                if (budget_ci->budget.dvb_frontend) {
1406                        budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
1407                        budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap;
1408
1409                        budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL;
1410                        if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) {
1411                                printk("%s: No LNBP21 found!\n", __func__);
1412                                dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1413                                budget_ci->budget.dvb_frontend = NULL;
1414                        }
1415                }
1416                break;
1417
1418        case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1419                budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1420                if (budget_ci->budget.dvb_frontend) {
1421                        if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
1422                                printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1423                                dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1424                                budget_ci->budget.dvb_frontend = NULL;
1425                        }
1426                }
1427                break;
1428
1429        case 0x1019:            // TT S2-3200 PCI
1430                /*
1431                 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
1432                 * to settle, aka LOCK. On the older revisions of the chip, we don't see
1433                 * this, as a result on the newer chips the entire clock tree, will not
1434                 * be stable after a freshly POWER 'ed up situation.
1435                 * In this case, we should RESET the STB0899 (Active LOW) and wait for
1436                 * PLL stabilization.
1437                 *
1438                 * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is
1439                 * connected to the SAA7146 GPIO, GPIO2, Pin 142
1440                 */
1441                /* Reset Demodulator */
1442                saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO);
1443                /* Wait for everything to die */
1444                msleep(50);
1445                /* Pull it up out of Reset state */
1446                saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI);
1447                /* Wait for PLL to stabilize */
1448                msleep(250);
1449                /*
1450                 * PLL state should be stable now. Ideally, we should check
1451                 * for PLL LOCK status. But well, never mind!
1452                 */
1453                budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap);
1454                if (budget_ci->budget.dvb_frontend) {
1455                        if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) {
1456                                if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
1457                                        printk("%s: No LNBP21 found!\n", __func__);
1458                                        dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1459                                        budget_ci->budget.dvb_frontend = NULL;
1460                                }
1461                        } else {
1462                                        dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1463                                        budget_ci->budget.dvb_frontend = NULL;
1464                        }
1465                }
1466                break;
1467
1468        }
1469
1470        if (budget_ci->budget.dvb_frontend == NULL) {
1471                printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1472                       budget_ci->budget.dev->pci->vendor,
1473                       budget_ci->budget.dev->pci->device,
1474                       budget_ci->budget.dev->pci->subsystem_vendor,
1475                       budget_ci->budget.dev->pci->subsystem_device);
1476        } else {
1477                if (dvb_register_frontend
1478                    (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
1479                        printk("budget-ci: Frontend registration failed!\n");
1480                        dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1481                        budget_ci->budget.dvb_frontend = NULL;
1482                }
1483        }
1484}
1485
1486static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1487{
1488        struct budget_ci *budget_ci;
1489        int err;
1490
1491        budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL);
1492        if (!budget_ci) {
1493                err = -ENOMEM;
1494                goto out1;
1495        }
1496
1497        dprintk(2, "budget_ci: %p\n", budget_ci);
1498
1499        dev->ext_priv = budget_ci;
1500
1501        err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE,
1502                                adapter_nr);
1503        if (err)
1504                goto out2;
1505
1506        err = msp430_ir_init(budget_ci);
1507        if (err)
1508                goto out3;
1509
1510        ciintf_init(budget_ci);
1511
1512        budget_ci->budget.dvb_adapter.priv = budget_ci;
1513        frontend_init(budget_ci);
1514
1515        ttpci_budget_init_hooks(&budget_ci->budget);
1516
1517        return 0;
1518
1519out3:
1520        ttpci_budget_deinit(&budget_ci->budget);
1521out2:
1522        kfree(budget_ci);
1523out1:
1524        return err;
1525}
1526
1527static int budget_ci_detach(struct saa7146_dev *dev)
1528{
1529        struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
1530        struct saa7146_dev *saa = budget_ci->budget.dev;
1531        int err;
1532
1533        if (budget_ci->budget.ci_present)
1534                ciintf_deinit(budget_ci);
1535        msp430_ir_deinit(budget_ci);
1536        if (budget_ci->budget.dvb_frontend) {
1537                dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1538                dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1539        }
1540        err = ttpci_budget_deinit(&budget_ci->budget);
1541
1542        // disable frontend and CI interface
1543        saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1544
1545        kfree(budget_ci);
1546
1547        return err;
1548}
1549
1550static struct saa7146_extension budget_extension;
1551
1552MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1553MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1554MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T  PCI", BUDGET_TT);
1555MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1556MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1557MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1558MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1559
1560static struct pci_device_id pci_tbl[] = {
1561        MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
1562        MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
1563        MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010),
1564        MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1565        MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1566        MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1567        MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1568        MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
1569        {
1570         .vendor = 0,
1571         }
1572};
1573
1574MODULE_DEVICE_TABLE(pci, pci_tbl);
1575
1576static struct saa7146_extension budget_extension = {
1577        .name = "budget_ci dvb",
1578        .flags = SAA7146_USE_I2C_IRQ,
1579
1580        .module = THIS_MODULE,
1581        .pci_tbl = &pci_tbl[0],
1582        .attach = budget_ci_attach,
1583        .detach = budget_ci_detach,
1584
1585        .irq_mask = MASK_03 | MASK_06 | MASK_10,
1586        .irq_func = budget_ci_irq,
1587};
1588
1589static int __init budget_ci_init(void)
1590{
1591        return saa7146_register_extension(&budget_extension);
1592}
1593
1594static void __exit budget_ci_exit(void)
1595{
1596        saa7146_unregister_extension(&budget_extension);
1597}
1598
1599module_init(budget_ci_init);
1600module_exit(budget_ci_exit);
1601
1602MODULE_LICENSE("GPL");
1603MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1604MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1605                   "budget PCI DVB cards w/ CI-module produced by "
1606                   "Siemens, Technotrend, Hauppauge");
1607
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.