linux/drivers/media/pci/ttpci/budget-ci.c
<<
>>
Prefs
   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
  71static int rc5_device = -1;
  72module_param(rc5_device, int, 0644);
  73MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");
  74
  75static int ir_debug;
  76module_param(ir_debug, int, 0644);
  77MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
  78
  79DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  80
  81struct 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
  92struct 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
 102static 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
 158static 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
 241static 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
 252static 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
 263static 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
 274static 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
 285static 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
 296static 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
 319static 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
 332static 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
 351static 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
 400static 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
 437static 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
 521error:
 522        saa7146_write(saa, MC1, MASK_27);
 523        return result;
 524}
 525
 526static 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
 553static 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
 569static 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
 615static 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
 647static 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
 683static 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
 698static 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
 728static 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
 814static 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
 822static 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
 833static 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
 844static 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
 920static 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
1013static 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
1020static 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
1030static struct tda827x_config tda827x_config = {
1031        .config = 0,
1032};
1033
1034/* TT S2-3200 DVB-S (STB0899) Inittab */
1035static 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
1122static 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
1255static 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
1294static struct stb6100_config tt3200_stb6100_config = {
1295        .tuner_address  = 0x60,
1296        .refclock       = 27000000,
1297};
1298
1299static 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
1453static 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
1486out3:
1487        ttpci_budget_deinit(&budget_ci->budget);
1488out2:
1489        kfree(budget_ci);
1490out1:
1491        return err;
1492}
1493
1494static 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
1517static struct saa7146_extension budget_extension;
1518
1519MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT);
1520MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1521MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T  PCI", BUDGET_TT);
1522MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1523MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1524MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1525MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
1526MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
1527
1528static 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
1543MODULE_DEVICE_TABLE(pci, pci_tbl);
1544
1545static 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
1558static int __init budget_ci_init(void)
1559{
1560        return saa7146_register_extension(&budget_extension);
1561}
1562
1563static void __exit budget_ci_exit(void)
1564{
1565        saa7146_unregister_extension(&budget_extension);
1566}
1567
1568module_init(budget_ci_init);
1569module_exit(budget_ci_exit);
1570
1571MODULE_LICENSE("GPL");
1572MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1573MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards w/ CI-module produced by Siemens, Technotrend, Hauppauge");
1574