root/drivers/media/pci/ttpci/budget-ci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. msp430_ir_interrupt
  2. msp430_ir_init
  3. msp430_ir_deinit
  4. ciintf_read_attribute_mem
  5. ciintf_write_attribute_mem
  6. ciintf_read_cam_control
  7. ciintf_write_cam_control
  8. ciintf_slot_reset
  9. ciintf_slot_shutdown
  10. ciintf_slot_ts_enable
  11. ciintf_interrupt
  12. ciintf_poll_slot_status
  13. ciintf_init
  14. ciintf_deinit
  15. budget_ci_irq
  16. philips_su1278_tt_set_symbol_rate
  17. philips_su1278_tt_tuner_set_params
  18. philips_tdm1316l_tuner_init
  19. philips_tdm1316l_tuner_set_params
  20. philips_tdm1316l_request_firmware
  21. dvbc_philips_tdm1316l_tuner_set_params
  22. frontend_init
  23. budget_ci_attach
  24. budget_ci_detach
  25. budget_ci_init
  26. budget_ci_exit

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

/* [<][>][^][v][top][bottom][index][help] */