linux/drivers/media/pci/ttpci/budget-av.c
<<
>>
Prefs
   1/*
   2 * budget-av.c: driver for the SAA7146 based Budget DVB cards
   3 *              with analog video in
   4 *
   5 * Compiled from various sources by Michael Hunold <michael@mihu.de>
   6 *
   7 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
   8 *                               Andrew de Quincey <adq_dvb@lidskialf.net>
   9 *
  10 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
  11 *
  12 * Copyright (C) 1999-2002 Ralph  Metzler
  13 *                       & Marcus Metzler for convergence integrated media GmbH
  14 *
  15 * This program is free software; you can redistribute it and/or
  16 * modify it under the terms of the GNU General Public License
  17 * as published by the Free Software Foundation; either version 2
  18 * of the License, or (at your option) any later version.
  19 *
  20 *
  21 * This program is distributed in the hope that it will be useful,
  22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24 * GNU General Public License for more details.
  25 *
  26 * To obtain the license, point your browser to
  27 * http://www.gnu.org/copyleft/gpl.html
  28 *
  29 *
  30 * the project's page is at https://linuxtv.org
  31 */
  32
  33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  34
  35#include "budget.h"
  36#include "stv0299.h"
  37#include "stb0899_drv.h"
  38#include "stb0899_reg.h"
  39#include "stb0899_cfg.h"
  40#include "tda8261.h"
  41#include "tda8261_cfg.h"
  42#include "tda1002x.h"
  43#include "tda1004x.h"
  44#include "tua6100.h"
  45#include "dvb-pll.h"
  46#include <media/drv-intf/saa7146_vv.h>
  47#include <linux/module.h>
  48#include <linux/errno.h>
  49#include <linux/slab.h>
  50#include <linux/interrupt.h>
  51#include <linux/input.h>
  52#include <linux/spinlock.h>
  53
  54#include <media/dvb_ca_en50221.h>
  55
  56#define DEBICICAM               0x02420000
  57
  58#define SLOTSTATUS_NONE         1
  59#define SLOTSTATUS_PRESENT      2
  60#define SLOTSTATUS_RESET        4
  61#define SLOTSTATUS_READY        8
  62#define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
  63
  64DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  65
  66struct budget_av {
  67        struct budget budget;
  68        struct video_device vd;
  69        int cur_input;
  70        int has_saa7113;
  71        struct tasklet_struct ciintf_irq_tasklet;
  72        int slot_status;
  73        struct dvb_ca_en50221 ca;
  74        u8 reinitialise_demod:1;
  75};
  76
  77static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
  78
  79
  80/* GPIO Connections:
  81 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
  82 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
  83 * 2 - CI Card Enable (Active Low)
  84 * 3 - CI Card Detect
  85 */
  86
  87/****************************************************************************
  88 * INITIALIZATION
  89 ****************************************************************************/
  90
  91static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
  92{
  93        u8 mm1[] = { 0x00 };
  94        u8 mm2[] = { 0x00 };
  95        struct i2c_msg msgs[2];
  96
  97        msgs[0].flags = 0;
  98        msgs[1].flags = I2C_M_RD;
  99        msgs[0].addr = msgs[1].addr = id / 2;
 100        mm1[0] = reg;
 101        msgs[0].len = 1;
 102        msgs[1].len = 1;
 103        msgs[0].buf = mm1;
 104        msgs[1].buf = mm2;
 105
 106        i2c_transfer(i2c, msgs, 2);
 107
 108        return mm2[0];
 109}
 110
 111static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
 112{
 113        u8 mm1[] = { reg };
 114        struct i2c_msg msgs[2] = {
 115                {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
 116                {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
 117        };
 118
 119        if (i2c_transfer(i2c, msgs, 2) != 2)
 120                return -EIO;
 121
 122        return 0;
 123}
 124
 125static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
 126{
 127        u8 msg[2] = { reg, val };
 128        struct i2c_msg msgs;
 129
 130        msgs.flags = 0;
 131        msgs.addr = id / 2;
 132        msgs.len = 2;
 133        msgs.buf = msg;
 134        return i2c_transfer(i2c, &msgs, 1);
 135}
 136
 137static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
 138{
 139        struct budget_av *budget_av = (struct budget_av *) ca->data;
 140        int result;
 141
 142        if (slot != 0)
 143                return -EINVAL;
 144
 145        saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
 146        udelay(1);
 147
 148        result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
 149        if (result == -ETIMEDOUT) {
 150                ciintf_slot_shutdown(ca, slot);
 151                pr_info("cam ejected 1\n");
 152        }
 153        return result;
 154}
 155
 156static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
 157{
 158        struct budget_av *budget_av = (struct budget_av *) ca->data;
 159        int result;
 160
 161        if (slot != 0)
 162                return -EINVAL;
 163
 164        saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
 165        udelay(1);
 166
 167        result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
 168        if (result == -ETIMEDOUT) {
 169                ciintf_slot_shutdown(ca, slot);
 170                pr_info("cam ejected 2\n");
 171        }
 172        return result;
 173}
 174
 175static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
 176{
 177        struct budget_av *budget_av = (struct budget_av *) ca->data;
 178        int result;
 179
 180        if (slot != 0)
 181                return -EINVAL;
 182
 183        saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 184        udelay(1);
 185
 186        result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
 187        if (result == -ETIMEDOUT) {
 188                ciintf_slot_shutdown(ca, slot);
 189                pr_info("cam ejected 3\n");
 190                return -ETIMEDOUT;
 191        }
 192        return result;
 193}
 194
 195static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
 196{
 197        struct budget_av *budget_av = (struct budget_av *) ca->data;
 198        int result;
 199
 200        if (slot != 0)
 201                return -EINVAL;
 202
 203        saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 204        udelay(1);
 205
 206        result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
 207        if (result == -ETIMEDOUT) {
 208                ciintf_slot_shutdown(ca, slot);
 209                pr_info("cam ejected 5\n");
 210        }
 211        return result;
 212}
 213
 214static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
 215{
 216        struct budget_av *budget_av = (struct budget_av *) ca->data;
 217        struct saa7146_dev *saa = budget_av->budget.dev;
 218
 219        if (slot != 0)
 220                return -EINVAL;
 221
 222        dprintk(1, "ciintf_slot_reset\n");
 223        budget_av->slot_status = SLOTSTATUS_RESET;
 224
 225        saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
 226
 227        saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
 228        msleep(2);
 229        saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
 230        msleep(20); /* 20 ms Vcc settling time */
 231
 232        saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
 233        ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
 234        msleep(20);
 235
 236        /* reinitialise the frontend if necessary */
 237        if (budget_av->reinitialise_demod)
 238                dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
 239
 240        return 0;
 241}
 242
 243static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
 244{
 245        struct budget_av *budget_av = (struct budget_av *) ca->data;
 246        struct saa7146_dev *saa = budget_av->budget.dev;
 247
 248        if (slot != 0)
 249                return -EINVAL;
 250
 251        dprintk(1, "ciintf_slot_shutdown\n");
 252
 253        ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
 254        budget_av->slot_status = SLOTSTATUS_NONE;
 255
 256        return 0;
 257}
 258
 259static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
 260{
 261        struct budget_av *budget_av = (struct budget_av *) ca->data;
 262        struct saa7146_dev *saa = budget_av->budget.dev;
 263
 264        if (slot != 0)
 265                return -EINVAL;
 266
 267        dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
 268
 269        ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
 270
 271        return 0;
 272}
 273
 274static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
 275{
 276        struct budget_av *budget_av = (struct budget_av *) ca->data;
 277        struct saa7146_dev *saa = budget_av->budget.dev;
 278        int result;
 279
 280        if (slot != 0)
 281                return -EINVAL;
 282
 283        /* test the card detect line - needs to be done carefully
 284         * since it never goes high for some CAMs on this interface (e.g. topuptv) */
 285        if (budget_av->slot_status == SLOTSTATUS_NONE) {
 286                saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 287                udelay(1);
 288                if (saa7146_read(saa, PSR) & MASK_06) {
 289                        if (budget_av->slot_status == SLOTSTATUS_NONE) {
 290                                budget_av->slot_status = SLOTSTATUS_PRESENT;
 291                                pr_info("cam inserted A\n");
 292                        }
 293                }
 294                saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 295        }
 296
 297        /* We also try and read from IO memory to work round the above detection bug. If
 298         * there is no CAM, we will get a timeout. Only done if there is no cam
 299         * present, since this test actually breaks some cams :(
 300         *
 301         * if the CI interface is not open, we also do the above test since we
 302         * don't care if the cam has problems - we'll be resetting it on open() anyway */
 303        if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
 304                saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 305                result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
 306                if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
 307                        budget_av->slot_status = SLOTSTATUS_PRESENT;
 308                        pr_info("cam inserted B\n");
 309                } else if (result < 0) {
 310                        if (budget_av->slot_status != SLOTSTATUS_NONE) {
 311                                ciintf_slot_shutdown(ca, slot);
 312                                pr_info("cam ejected 5\n");
 313                                return 0;
 314                        }
 315                }
 316        }
 317
 318        /* read from attribute memory in reset/ready state to know when the CAM is ready */
 319        if (budget_av->slot_status == SLOTSTATUS_RESET) {
 320                result = ciintf_read_attribute_mem(ca, slot, 0);
 321                if (result == 0x1d) {
 322                        budget_av->slot_status = SLOTSTATUS_READY;
 323                }
 324        }
 325
 326        /* work out correct return code */
 327        if (budget_av->slot_status != SLOTSTATUS_NONE) {
 328                if (budget_av->slot_status & SLOTSTATUS_READY) {
 329                        return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
 330                }
 331                return DVB_CA_EN50221_POLL_CAM_PRESENT;
 332        }
 333        return 0;
 334}
 335
 336static int ciintf_init(struct budget_av *budget_av)
 337{
 338        struct saa7146_dev *saa = budget_av->budget.dev;
 339        int result;
 340
 341        memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
 342
 343        saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
 344        saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
 345        saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
 346        saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 347
 348        /* Enable DEBI pins */
 349        saa7146_write(saa, MC1, MASK_27 | MASK_11);
 350
 351        /* register CI interface */
 352        budget_av->ca.owner = THIS_MODULE;
 353        budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
 354        budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
 355        budget_av->ca.read_cam_control = ciintf_read_cam_control;
 356        budget_av->ca.write_cam_control = ciintf_write_cam_control;
 357        budget_av->ca.slot_reset = ciintf_slot_reset;
 358        budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
 359        budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
 360        budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
 361        budget_av->ca.data = budget_av;
 362        budget_av->budget.ci_present = 1;
 363        budget_av->slot_status = SLOTSTATUS_NONE;
 364
 365        if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
 366                                          &budget_av->ca, 0, 1)) != 0) {
 367                pr_err("ci initialisation failed\n");
 368                goto error;
 369        }
 370
 371        pr_info("ci interface initialised\n");
 372        return 0;
 373
 374error:
 375        saa7146_write(saa, MC1, MASK_27);
 376        return result;
 377}
 378
 379static void ciintf_deinit(struct budget_av *budget_av)
 380{
 381        struct saa7146_dev *saa = budget_av->budget.dev;
 382
 383        saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
 384        saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
 385        saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
 386        saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 387
 388        /* release the CA device */
 389        dvb_ca_en50221_release(&budget_av->ca);
 390
 391        /* disable DEBI pins */
 392        saa7146_write(saa, MC1, MASK_27);
 393}
 394
 395
 396static const u8 saa7113_tab[] = {
 397        0x01, 0x08,
 398        0x02, 0xc0,
 399        0x03, 0x33,
 400        0x04, 0x00,
 401        0x05, 0x00,
 402        0x06, 0xeb,
 403        0x07, 0xe0,
 404        0x08, 0x28,
 405        0x09, 0x00,
 406        0x0a, 0x80,
 407        0x0b, 0x47,
 408        0x0c, 0x40,
 409        0x0d, 0x00,
 410        0x0e, 0x01,
 411        0x0f, 0x44,
 412
 413        0x10, 0x08,
 414        0x11, 0x0c,
 415        0x12, 0x7b,
 416        0x13, 0x00,
 417        0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
 418
 419        0x57, 0xff,
 420        0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
 421        0x5b, 0x83, 0x5e, 0x00,
 422        0xff
 423};
 424
 425static int saa7113_init(struct budget_av *budget_av)
 426{
 427        struct budget *budget = &budget_av->budget;
 428        struct saa7146_dev *saa = budget->dev;
 429        const u8 *data = saa7113_tab;
 430
 431        saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
 432        msleep(200);
 433
 434        if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
 435                dprintk(1, "saa7113 not found on KNC card\n");
 436                return -ENODEV;
 437        }
 438
 439        dprintk(1, "saa7113 detected and initializing\n");
 440
 441        while (*data != 0xff) {
 442                i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
 443                data += 2;
 444        }
 445
 446        dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
 447
 448        return 0;
 449}
 450
 451static int saa7113_setinput(struct budget_av *budget_av, int input)
 452{
 453        struct budget *budget = &budget_av->budget;
 454
 455        if (1 != budget_av->has_saa7113)
 456                return -ENODEV;
 457
 458        if (input == 1) {
 459                i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
 460                i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
 461        } else if (input == 0) {
 462                i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
 463                i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
 464        } else
 465                return -EINVAL;
 466
 467        budget_av->cur_input = input;
 468        return 0;
 469}
 470
 471
 472static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
 473{
 474        u8 aclk = 0;
 475        u8 bclk = 0;
 476        u8 m1;
 477
 478        aclk = 0xb5;
 479        if (srate < 2000000)
 480                bclk = 0x86;
 481        else if (srate < 5000000)
 482                bclk = 0x89;
 483        else if (srate < 15000000)
 484                bclk = 0x8f;
 485        else if (srate < 45000000)
 486                bclk = 0x95;
 487
 488        m1 = 0x14;
 489        if (srate < 4000000)
 490                m1 = 0x10;
 491
 492        stv0299_writereg(fe, 0x13, aclk);
 493        stv0299_writereg(fe, 0x14, bclk);
 494        stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 495        stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
 496        stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
 497        stv0299_writereg(fe, 0x0f, 0x80 | m1);
 498
 499        return 0;
 500}
 501
 502static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe)
 503{
 504        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 505        u32 div;
 506        u8 buf[4];
 507        struct budget *budget = (struct budget *) fe->dvb->priv;
 508        struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
 509
 510        if ((c->frequency < 950000) || (c->frequency > 2150000))
 511                return -EINVAL;
 512
 513        div = (c->frequency + (125 - 1)) / 125; /* round correctly */
 514        buf[0] = (div >> 8) & 0x7f;
 515        buf[1] = div & 0xff;
 516        buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
 517        buf[3] = 0x20;
 518
 519        if (c->symbol_rate < 4000000)
 520                buf[3] |= 1;
 521
 522        if (c->frequency < 1250000)
 523                buf[3] |= 0;
 524        else if (c->frequency < 1550000)
 525                buf[3] |= 0x40;
 526        else if (c->frequency < 2050000)
 527                buf[3] |= 0x80;
 528        else if (c->frequency < 2150000)
 529                buf[3] |= 0xC0;
 530
 531        if (fe->ops.i2c_gate_ctrl)
 532                fe->ops.i2c_gate_ctrl(fe, 1);
 533        if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
 534                return -EIO;
 535        return 0;
 536}
 537
 538static u8 typhoon_cinergy1200s_inittab[] = {
 539        0x01, 0x15,
 540        0x02, 0x30,
 541        0x03, 0x00,
 542        0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
 543        0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
 544        0x06, 0x40,             /* DAC not used, set to high impendance mode */
 545        0x07, 0x00,             /* DAC LSB */
 546        0x08, 0x40,             /* DiSEqC off */
 547        0x09, 0x00,             /* FIFO */
 548        0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
 549        0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
 550        0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
 551        0x10, 0x3f,             // AGC2  0x3d
 552        0x11, 0x84,
 553        0x12, 0xb9,
 554        0x15, 0xc9,             // lock detector threshold
 555        0x16, 0x00,
 556        0x17, 0x00,
 557        0x18, 0x00,
 558        0x19, 0x00,
 559        0x1a, 0x00,
 560        0x1f, 0x50,
 561        0x20, 0x00,
 562        0x21, 0x00,
 563        0x22, 0x00,
 564        0x23, 0x00,
 565        0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
 566        0x29, 0x1e,             // 1/2 threshold
 567        0x2a, 0x14,             // 2/3 threshold
 568        0x2b, 0x0f,             // 3/4 threshold
 569        0x2c, 0x09,             // 5/6 threshold
 570        0x2d, 0x05,             // 7/8 threshold
 571        0x2e, 0x01,
 572        0x31, 0x1f,             // test all FECs
 573        0x32, 0x19,             // viterbi and synchro search
 574        0x33, 0xfc,             // rs control
 575        0x34, 0x93,             // error control
 576        0x0f, 0x92,
 577        0xff, 0xff
 578};
 579
 580static const struct stv0299_config typhoon_config = {
 581        .demod_address = 0x68,
 582        .inittab = typhoon_cinergy1200s_inittab,
 583        .mclk = 88000000UL,
 584        .invert = 0,
 585        .skip_reinit = 0,
 586        .lock_output = STV0299_LOCKOUTPUT_1,
 587        .volt13_op0_op1 = STV0299_VOLT13_OP0,
 588        .min_delay_ms = 100,
 589        .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
 590};
 591
 592
 593static const struct stv0299_config cinergy_1200s_config = {
 594        .demod_address = 0x68,
 595        .inittab = typhoon_cinergy1200s_inittab,
 596        .mclk = 88000000UL,
 597        .invert = 0,
 598        .skip_reinit = 0,
 599        .lock_output = STV0299_LOCKOUTPUT_0,
 600        .volt13_op0_op1 = STV0299_VOLT13_OP0,
 601        .min_delay_ms = 100,
 602        .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
 603};
 604
 605static const struct stv0299_config cinergy_1200s_1894_0010_config = {
 606        .demod_address = 0x68,
 607        .inittab = typhoon_cinergy1200s_inittab,
 608        .mclk = 88000000UL,
 609        .invert = 1,
 610        .skip_reinit = 0,
 611        .lock_output = STV0299_LOCKOUTPUT_1,
 612        .volt13_op0_op1 = STV0299_VOLT13_OP0,
 613        .min_delay_ms = 100,
 614        .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
 615};
 616
 617static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe)
 618{
 619        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 620        struct budget *budget = (struct budget *) fe->dvb->priv;
 621        u8 buf[6];
 622        struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
 623        int i;
 624
 625#define CU1216_IF 36125000
 626#define TUNER_MUL 62500
 627
 628        u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
 629
 630        buf[0] = (div >> 8) & 0x7f;
 631        buf[1] = div & 0xff;
 632        buf[2] = 0xce;
 633        buf[3] = (c->frequency < 150000000 ? 0x01 :
 634                  c->frequency < 445000000 ? 0x02 : 0x04);
 635        buf[4] = 0xde;
 636        buf[5] = 0x20;
 637
 638        if (fe->ops.i2c_gate_ctrl)
 639                fe->ops.i2c_gate_ctrl(fe, 1);
 640        if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
 641                return -EIO;
 642
 643        /* wait for the pll lock */
 644        msg.flags = I2C_M_RD;
 645        msg.len = 1;
 646        for (i = 0; i < 20; i++) {
 647                if (fe->ops.i2c_gate_ctrl)
 648                        fe->ops.i2c_gate_ctrl(fe, 1);
 649                if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
 650                        break;
 651                msleep(10);
 652        }
 653
 654        /* switch the charge pump to the lower current */
 655        msg.flags = 0;
 656        msg.len = 2;
 657        msg.buf = &buf[2];
 658        buf[2] &= ~0x40;
 659        if (fe->ops.i2c_gate_ctrl)
 660                fe->ops.i2c_gate_ctrl(fe, 1);
 661        if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
 662                return -EIO;
 663
 664        return 0;
 665}
 666
 667static struct tda1002x_config philips_cu1216_config = {
 668        .demod_address = 0x0c,
 669        .invert = 1,
 670};
 671
 672static struct tda1002x_config philips_cu1216_config_altaddress = {
 673        .demod_address = 0x0d,
 674        .invert = 0,
 675};
 676
 677static struct tda10023_config philips_cu1216_tda10023_config = {
 678        .demod_address = 0x0c,
 679        .invert = 1,
 680};
 681
 682static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
 683{
 684        struct budget *budget = (struct budget *) fe->dvb->priv;
 685        static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
 686        struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
 687
 688        // setup PLL configuration
 689        if (fe->ops.i2c_gate_ctrl)
 690                fe->ops.i2c_gate_ctrl(fe, 1);
 691        if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
 692                return -EIO;
 693        msleep(1);
 694
 695        return 0;
 696}
 697
 698static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe)
 699{
 700        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 701        struct budget *budget = (struct budget *) fe->dvb->priv;
 702        u8 tuner_buf[4];
 703        struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
 704                        sizeof(tuner_buf) };
 705        int tuner_frequency = 0;
 706        u8 band, cp, filter;
 707
 708        // determine charge pump
 709        tuner_frequency = c->frequency + 36166000;
 710        if (tuner_frequency < 87000000)
 711                return -EINVAL;
 712        else if (tuner_frequency < 130000000)
 713                cp = 3;
 714        else if (tuner_frequency < 160000000)
 715                cp = 5;
 716        else if (tuner_frequency < 200000000)
 717                cp = 6;
 718        else if (tuner_frequency < 290000000)
 719                cp = 3;
 720        else if (tuner_frequency < 420000000)
 721                cp = 5;
 722        else if (tuner_frequency < 480000000)
 723                cp = 6;
 724        else if (tuner_frequency < 620000000)
 725                cp = 3;
 726        else if (tuner_frequency < 830000000)
 727                cp = 5;
 728        else if (tuner_frequency < 895000000)
 729                cp = 7;
 730        else
 731                return -EINVAL;
 732
 733        // determine band
 734        if (c->frequency < 49000000)
 735                return -EINVAL;
 736        else if (c->frequency < 161000000)
 737                band = 1;
 738        else if (c->frequency < 444000000)
 739                band = 2;
 740        else if (c->frequency < 861000000)
 741                band = 4;
 742        else
 743                return -EINVAL;
 744
 745        // setup PLL filter
 746        switch (c->bandwidth_hz) {
 747        case 6000000:
 748                filter = 0;
 749                break;
 750
 751        case 7000000:
 752                filter = 0;
 753                break;
 754
 755        case 8000000:
 756                filter = 1;
 757                break;
 758
 759        default:
 760                return -EINVAL;
 761        }
 762
 763        // calculate divisor
 764        // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
 765        tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000;
 766
 767        // setup tuner buffer
 768        tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
 769        tuner_buf[1] = tuner_frequency & 0xff;
 770        tuner_buf[2] = 0xca;
 771        tuner_buf[3] = (cp << 5) | (filter << 3) | band;
 772
 773        if (fe->ops.i2c_gate_ctrl)
 774                fe->ops.i2c_gate_ctrl(fe, 1);
 775        if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
 776                return -EIO;
 777
 778        msleep(1);
 779        return 0;
 780}
 781
 782static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
 783                                           const struct firmware **fw, char *name)
 784{
 785        struct budget *budget = (struct budget *) fe->dvb->priv;
 786
 787        return request_firmware(fw, name, &budget->dev->pci->dev);
 788}
 789
 790static struct tda1004x_config philips_tu1216_config = {
 791
 792        .demod_address = 0x8,
 793        .invert = 1,
 794        .invert_oclk = 1,
 795        .xtal_freq = TDA10046_XTAL_4M,
 796        .agc_config = TDA10046_AGC_DEFAULT,
 797        .if_freq = TDA10046_FREQ_3617,
 798        .request_firmware = philips_tu1216_request_firmware,
 799};
 800
 801static u8 philips_sd1878_inittab[] = {
 802        0x01, 0x15,
 803        0x02, 0x30,
 804        0x03, 0x00,
 805        0x04, 0x7d,
 806        0x05, 0x35,
 807        0x06, 0x40,
 808        0x07, 0x00,
 809        0x08, 0x43,
 810        0x09, 0x02,
 811        0x0C, 0x51,
 812        0x0D, 0x82,
 813        0x0E, 0x23,
 814        0x10, 0x3f,
 815        0x11, 0x84,
 816        0x12, 0xb9,
 817        0x15, 0xc9,
 818        0x16, 0x19,
 819        0x17, 0x8c,
 820        0x18, 0x59,
 821        0x19, 0xf8,
 822        0x1a, 0xfe,
 823        0x1c, 0x7f,
 824        0x1d, 0x00,
 825        0x1e, 0x00,
 826        0x1f, 0x50,
 827        0x20, 0x00,
 828        0x21, 0x00,
 829        0x22, 0x00,
 830        0x23, 0x00,
 831        0x28, 0x00,
 832        0x29, 0x28,
 833        0x2a, 0x14,
 834        0x2b, 0x0f,
 835        0x2c, 0x09,
 836        0x2d, 0x09,
 837        0x31, 0x1f,
 838        0x32, 0x19,
 839        0x33, 0xfc,
 840        0x34, 0x93,
 841        0xff, 0xff
 842};
 843
 844static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
 845                u32 srate, u32 ratio)
 846{
 847        u8 aclk = 0;
 848        u8 bclk = 0;
 849        u8 m1;
 850
 851        aclk = 0xb5;
 852        if (srate < 2000000)
 853                bclk = 0x86;
 854        else if (srate < 5000000)
 855                bclk = 0x89;
 856        else if (srate < 15000000)
 857                bclk = 0x8f;
 858        else if (srate < 45000000)
 859                bclk = 0x95;
 860
 861        m1 = 0x14;
 862        if (srate < 4000000)
 863                m1 = 0x10;
 864
 865        stv0299_writereg(fe, 0x0e, 0x23);
 866        stv0299_writereg(fe, 0x0f, 0x94);
 867        stv0299_writereg(fe, 0x10, 0x39);
 868        stv0299_writereg(fe, 0x13, aclk);
 869        stv0299_writereg(fe, 0x14, bclk);
 870        stv0299_writereg(fe, 0x15, 0xc9);
 871        stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 872        stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
 873        stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
 874        stv0299_writereg(fe, 0x0f, 0x80 | m1);
 875
 876        return 0;
 877}
 878
 879static const struct stv0299_config philips_sd1878_config = {
 880        .demod_address = 0x68,
 881     .inittab = philips_sd1878_inittab,
 882        .mclk = 88000000UL,
 883        .invert = 0,
 884        .skip_reinit = 0,
 885        .lock_output = STV0299_LOCKOUTPUT_1,
 886        .volt13_op0_op1 = STV0299_VOLT13_OP0,
 887        .min_delay_ms = 100,
 888        .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
 889};
 890
 891/* KNC1 DVB-S (STB0899) Inittab */
 892static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
 893
 894        { STB0899_DEV_ID                , 0x81 },
 895        { STB0899_DISCNTRL1             , 0x32 },
 896        { STB0899_DISCNTRL2             , 0x80 },
 897        { STB0899_DISRX_ST0             , 0x04 },
 898        { STB0899_DISRX_ST1             , 0x00 },
 899        { STB0899_DISPARITY             , 0x00 },
 900        { STB0899_DISSTATUS             , 0x20 },
 901        { STB0899_DISF22                , 0x8c },
 902        { STB0899_DISF22RX              , 0x9a },
 903        { STB0899_SYSREG                , 0x0b },
 904        { STB0899_ACRPRESC              , 0x11 },
 905        { STB0899_ACRDIV1               , 0x0a },
 906        { STB0899_ACRDIV2               , 0x05 },
 907        { STB0899_DACR1                 , 0x00 },
 908        { STB0899_DACR2                 , 0x00 },
 909        { STB0899_OUTCFG                , 0x00 },
 910        { STB0899_MODECFG               , 0x00 },
 911        { STB0899_IRQSTATUS_3           , 0x30 },
 912        { STB0899_IRQSTATUS_2           , 0x00 },
 913        { STB0899_IRQSTATUS_1           , 0x00 },
 914        { STB0899_IRQSTATUS_0           , 0x00 },
 915        { STB0899_IRQMSK_3              , 0xf3 },
 916        { STB0899_IRQMSK_2              , 0xfc },
 917        { STB0899_IRQMSK_1              , 0xff },
 918        { STB0899_IRQMSK_0              , 0xff },
 919        { STB0899_IRQCFG                , 0x00 },
 920        { STB0899_I2CCFG                , 0x88 },
 921        { STB0899_I2CRPT                , 0x58 }, /* Repeater=8, Stop=disabled */
 922        { STB0899_IOPVALUE5             , 0x00 },
 923        { STB0899_IOPVALUE4             , 0x20 },
 924        { STB0899_IOPVALUE3             , 0xc9 },
 925        { STB0899_IOPVALUE2             , 0x90 },
 926        { STB0899_IOPVALUE1             , 0x40 },
 927        { STB0899_IOPVALUE0             , 0x00 },
 928        { STB0899_GPIO00CFG             , 0x82 },
 929        { STB0899_GPIO01CFG             , 0x82 },
 930        { STB0899_GPIO02CFG             , 0x82 },
 931        { STB0899_GPIO03CFG             , 0x82 },
 932        { STB0899_GPIO04CFG             , 0x82 },
 933        { STB0899_GPIO05CFG             , 0x82 },
 934        { STB0899_GPIO06CFG             , 0x82 },
 935        { STB0899_GPIO07CFG             , 0x82 },
 936        { STB0899_GPIO08CFG             , 0x82 },
 937        { STB0899_GPIO09CFG             , 0x82 },
 938        { STB0899_GPIO10CFG             , 0x82 },
 939        { STB0899_GPIO11CFG             , 0x82 },
 940        { STB0899_GPIO12CFG             , 0x82 },
 941        { STB0899_GPIO13CFG             , 0x82 },
 942        { STB0899_GPIO14CFG             , 0x82 },
 943        { STB0899_GPIO15CFG             , 0x82 },
 944        { STB0899_GPIO16CFG             , 0x82 },
 945        { STB0899_GPIO17CFG             , 0x82 },
 946        { STB0899_GPIO18CFG             , 0x82 },
 947        { STB0899_GPIO19CFG             , 0x82 },
 948        { STB0899_GPIO20CFG             , 0x82 },
 949        { STB0899_SDATCFG               , 0xb8 },
 950        { STB0899_SCLTCFG               , 0xba },
 951        { STB0899_AGCRFCFG              , 0x08 }, /* 0x1c */
 952        { STB0899_GPIO22                , 0x82 }, /* AGCBB2CFG */
 953        { STB0899_GPIO21                , 0x91 }, /* AGCBB1CFG */
 954        { STB0899_DIRCLKCFG             , 0x82 },
 955        { STB0899_CLKOUT27CFG           , 0x7e },
 956        { STB0899_STDBYCFG              , 0x82 },
 957        { STB0899_CS0CFG                , 0x82 },
 958        { STB0899_CS1CFG                , 0x82 },
 959        { STB0899_DISEQCOCFG            , 0x20 },
 960        { STB0899_GPIO32CFG             , 0x82 },
 961        { STB0899_GPIO33CFG             , 0x82 },
 962        { STB0899_GPIO34CFG             , 0x82 },
 963        { STB0899_GPIO35CFG             , 0x82 },
 964        { STB0899_GPIO36CFG             , 0x82 },
 965        { STB0899_GPIO37CFG             , 0x82 },
 966        { STB0899_GPIO38CFG             , 0x82 },
 967        { STB0899_GPIO39CFG             , 0x82 },
 968        { STB0899_NCOARSE               , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
 969        { STB0899_SYNTCTRL              , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
 970        { STB0899_FILTCTRL              , 0x00 },
 971        { STB0899_SYSCTRL               , 0x00 },
 972        { STB0899_STOPCLK1              , 0x20 },
 973        { STB0899_STOPCLK2              , 0x00 },
 974        { STB0899_INTBUFSTATUS          , 0x00 },
 975        { STB0899_INTBUFCTRL            , 0x0a },
 976        { 0xffff                        , 0xff },
 977};
 978
 979static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
 980        { STB0899_DEMOD                 , 0x00 },
 981        { STB0899_RCOMPC                , 0xc9 },
 982        { STB0899_AGC1CN                , 0x41 },
 983        { STB0899_AGC1REF               , 0x08 },
 984        { STB0899_RTC                   , 0x7a },
 985        { STB0899_TMGCFG                , 0x4e },
 986        { STB0899_AGC2REF               , 0x33 },
 987        { STB0899_TLSR                  , 0x84 },
 988        { STB0899_CFD                   , 0xee },
 989        { STB0899_ACLC                  , 0x87 },
 990        { STB0899_BCLC                  , 0x94 },
 991        { STB0899_EQON                  , 0x41 },
 992        { STB0899_LDT                   , 0xdd },
 993        { STB0899_LDT2                  , 0xc9 },
 994        { STB0899_EQUALREF              , 0xb4 },
 995        { STB0899_TMGRAMP               , 0x10 },
 996        { STB0899_TMGTHD                , 0x30 },
 997        { STB0899_IDCCOMP               , 0xfb },
 998        { STB0899_QDCCOMP               , 0x03 },
 999        { STB0899_POWERI                , 0x3b },
1000        { STB0899_POWERQ                , 0x3d },
1001        { STB0899_RCOMP                 , 0x81 },
1002        { STB0899_AGCIQIN               , 0x80 },
1003        { STB0899_AGC2I1                , 0x04 },
1004        { STB0899_AGC2I2                , 0xf5 },
1005        { STB0899_TLIR                  , 0x25 },
1006        { STB0899_RTF                   , 0x80 },
1007        { STB0899_DSTATUS               , 0x00 },
1008        { STB0899_LDI                   , 0xca },
1009        { STB0899_CFRM                  , 0xf1 },
1010        { STB0899_CFRL                  , 0xf3 },
1011        { STB0899_NIRM                  , 0x2a },
1012        { STB0899_NIRL                  , 0x05 },
1013        { STB0899_ISYMB                 , 0x17 },
1014        { STB0899_QSYMB                 , 0xfa },
1015        { STB0899_SFRH                  , 0x2f },
1016        { STB0899_SFRM                  , 0x68 },
1017        { STB0899_SFRL                  , 0x40 },
1018        { STB0899_SFRUPH                , 0x2f },
1019        { STB0899_SFRUPM                , 0x68 },
1020        { STB0899_SFRUPL                , 0x40 },
1021        { STB0899_EQUAI1                , 0xfd },
1022        { STB0899_EQUAQ1                , 0x04 },
1023        { STB0899_EQUAI2                , 0x0f },
1024        { STB0899_EQUAQ2                , 0xff },
1025        { STB0899_EQUAI3                , 0xdf },
1026        { STB0899_EQUAQ3                , 0xfa },
1027        { STB0899_EQUAI4                , 0x37 },
1028        { STB0899_EQUAQ4                , 0x0d },
1029        { STB0899_EQUAI5                , 0xbd },
1030        { STB0899_EQUAQ5                , 0xf7 },
1031        { STB0899_DSTATUS2              , 0x00 },
1032        { STB0899_VSTATUS               , 0x00 },
1033        { STB0899_VERROR                , 0xff },
1034        { STB0899_IQSWAP                , 0x2a },
1035        { STB0899_ECNT1M                , 0x00 },
1036        { STB0899_ECNT1L                , 0x00 },
1037        { STB0899_ECNT2M                , 0x00 },
1038        { STB0899_ECNT2L                , 0x00 },
1039        { STB0899_ECNT3M                , 0x00 },
1040        { STB0899_ECNT3L                , 0x00 },
1041        { STB0899_FECAUTO1              , 0x06 },
1042        { STB0899_FECM                  , 0x01 },
1043        { STB0899_VTH12                 , 0xf0 },
1044        { STB0899_VTH23                 , 0xa0 },
1045        { STB0899_VTH34                 , 0x78 },
1046        { STB0899_VTH56                 , 0x4e },
1047        { STB0899_VTH67                 , 0x48 },
1048        { STB0899_VTH78                 , 0x38 },
1049        { STB0899_PRVIT                 , 0xff },
1050        { STB0899_VITSYNC               , 0x19 },
1051        { STB0899_RSULC                 , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1052        { STB0899_TSULC                 , 0x42 },
1053        { STB0899_RSLLC                 , 0x40 },
1054        { STB0899_TSLPL                 , 0x12 },
1055        { STB0899_TSCFGH                , 0x0c },
1056        { STB0899_TSCFGM                , 0x00 },
1057        { STB0899_TSCFGL                , 0x0c },
1058        { STB0899_TSOUT                 , 0x4d }, /* 0x0d for CAM */
1059        { STB0899_RSSYNCDEL             , 0x00 },
1060        { STB0899_TSINHDELH             , 0x02 },
1061        { STB0899_TSINHDELM             , 0x00 },
1062        { STB0899_TSINHDELL             , 0x00 },
1063        { STB0899_TSLLSTKM              , 0x00 },
1064        { STB0899_TSLLSTKL              , 0x00 },
1065        { STB0899_TSULSTKM              , 0x00 },
1066        { STB0899_TSULSTKL              , 0xab },
1067        { STB0899_PCKLENUL              , 0x00 },
1068        { STB0899_PCKLENLL              , 0xcc },
1069        { STB0899_RSPCKLEN              , 0xcc },
1070        { STB0899_TSSTATUS              , 0x80 },
1071        { STB0899_ERRCTRL1              , 0xb6 },
1072        { STB0899_ERRCTRL2              , 0x96 },
1073        { STB0899_ERRCTRL3              , 0x89 },
1074        { STB0899_DMONMSK1              , 0x27 },
1075        { STB0899_DMONMSK0              , 0x03 },
1076        { STB0899_DEMAPVIT              , 0x5c },
1077        { STB0899_PLPARM                , 0x1f },
1078        { STB0899_PDELCTRL              , 0x48 },
1079        { STB0899_PDELCTRL2             , 0x00 },
1080        { STB0899_BBHCTRL1              , 0x00 },
1081        { STB0899_BBHCTRL2              , 0x00 },
1082        { STB0899_HYSTTHRESH            , 0x77 },
1083        { STB0899_MATCSTM               , 0x00 },
1084        { STB0899_MATCSTL               , 0x00 },
1085        { STB0899_UPLCSTM               , 0x00 },
1086        { STB0899_UPLCSTL               , 0x00 },
1087        { STB0899_DFLCSTM               , 0x00 },
1088        { STB0899_DFLCSTL               , 0x00 },
1089        { STB0899_SYNCCST               , 0x00 },
1090        { STB0899_SYNCDCSTM             , 0x00 },
1091        { STB0899_SYNCDCSTL             , 0x00 },
1092        { STB0899_ISI_ENTRY             , 0x00 },
1093        { STB0899_ISI_BIT_EN            , 0x00 },
1094        { STB0899_MATSTRM               , 0x00 },
1095        { STB0899_MATSTRL               , 0x00 },
1096        { STB0899_UPLSTRM               , 0x00 },
1097        { STB0899_UPLSTRL               , 0x00 },
1098        { STB0899_DFLSTRM               , 0x00 },
1099        { STB0899_DFLSTRL               , 0x00 },
1100        { STB0899_SYNCSTR               , 0x00 },
1101        { STB0899_SYNCDSTRM             , 0x00 },
1102        { STB0899_SYNCDSTRL             , 0x00 },
1103        { STB0899_CFGPDELSTATUS1        , 0x10 },
1104        { STB0899_CFGPDELSTATUS2        , 0x00 },
1105        { STB0899_BBFERRORM             , 0x00 },
1106        { STB0899_BBFERRORL             , 0x00 },
1107        { STB0899_UPKTERRORM            , 0x00 },
1108        { STB0899_UPKTERRORL            , 0x00 },
1109        { 0xffff                        , 0xff },
1110};
1111
1112/* STB0899 demodulator config for the KNC1 and clones */
1113static struct stb0899_config knc1_dvbs2_config = {
1114        .init_dev               = knc1_stb0899_s1_init_1,
1115        .init_s2_demod          = stb0899_s2_init_2,
1116        .init_s1_demod          = knc1_stb0899_s1_init_3,
1117        .init_s2_fec            = stb0899_s2_init_4,
1118        .init_tst               = stb0899_s1_init_5,
1119
1120        .postproc               = NULL,
1121
1122        .demod_address          = 0x68,
1123//      .ts_output_mode         = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL      */
1124        .block_sync_mode        = STB0899_SYNC_FORCED,  /* DSS, SYNC_FORCED/UNSYNCED    */
1125//      .ts_pfbit_toggle        = STB0899_MPEG_NORMAL,  /* DirecTV, MPEG toggling seq   */
1126
1127        .xtal_freq              = 27000000,
1128        .inversion              = IQ_SWAP_OFF,
1129
1130        .lo_clk                 = 76500000,
1131        .hi_clk                 = 90000000,
1132
1133        .esno_ave               = STB0899_DVBS2_ESNO_AVE,
1134        .esno_quant             = STB0899_DVBS2_ESNO_QUANT,
1135        .avframes_coarse        = STB0899_DVBS2_AVFRAMES_COARSE,
1136        .avframes_fine          = STB0899_DVBS2_AVFRAMES_FINE,
1137        .miss_threshold         = STB0899_DVBS2_MISS_THRESHOLD,
1138        .uwp_threshold_acq      = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1139        .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1140        .uwp_threshold_sof      = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1141        .sof_search_timeout     = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1142
1143        .btr_nco_bits           = STB0899_DVBS2_BTR_NCO_BITS,
1144        .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1145        .crl_nco_bits           = STB0899_DVBS2_CRL_NCO_BITS,
1146        .ldpc_max_iter          = STB0899_DVBS2_LDPC_MAX_ITER,
1147
1148        .tuner_get_frequency    = tda8261_get_frequency,
1149        .tuner_set_frequency    = tda8261_set_frequency,
1150        .tuner_set_bandwidth    = NULL,
1151        .tuner_get_bandwidth    = tda8261_get_bandwidth,
1152        .tuner_set_rfsiggain    = NULL
1153};
1154
1155/*
1156 * SD1878/SHA tuner config
1157 * 1F, Single I/P, Horizontal mount, High Sensitivity
1158 */
1159static const struct tda8261_config sd1878c_config = {
1160//      .name           = "SD1878/SHA",
1161        .addr           = 0x60,
1162        .step_size      = TDA8261_STEP_1000 /* kHz */
1163};
1164
1165static u8 read_pwm(struct budget_av *budget_av)
1166{
1167        u8 b = 0xff;
1168        u8 pwm;
1169        struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1170        {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1171        };
1172
1173        if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1174            || (pwm == 0xff))
1175                pwm = 0x48;
1176
1177        return pwm;
1178}
1179
1180#define SUBID_DVBS_KNC1                 0x0010
1181#define SUBID_DVBS_KNC1_PLUS            0x0011
1182#define SUBID_DVBS_TYPHOON              0x4f56
1183#define SUBID_DVBS_CINERGY1200          0x1154
1184#define SUBID_DVBS_CYNERGY1200N         0x1155
1185#define SUBID_DVBS_TV_STAR              0x0014
1186#define SUBID_DVBS_TV_STAR_PLUS_X4      0x0015
1187#define SUBID_DVBS_TV_STAR_CI           0x0016
1188#define SUBID_DVBS2_KNC1                0x0018
1189#define SUBID_DVBS2_KNC1_OEM            0x0019
1190#define SUBID_DVBS_EASYWATCH_1          0x001a
1191#define SUBID_DVBS_EASYWATCH_2          0x001b
1192#define SUBID_DVBS2_EASYWATCH           0x001d
1193#define SUBID_DVBS_EASYWATCH            0x001e
1194
1195#define SUBID_DVBC_EASYWATCH            0x002a
1196#define SUBID_DVBC_EASYWATCH_MK3        0x002c
1197#define SUBID_DVBC_KNC1                 0x0020
1198#define SUBID_DVBC_KNC1_PLUS            0x0021
1199#define SUBID_DVBC_KNC1_MK3             0x0022
1200#define SUBID_DVBC_KNC1_TDA10024        0x0028
1201#define SUBID_DVBC_KNC1_PLUS_MK3        0x0023
1202#define SUBID_DVBC_CINERGY1200          0x1156
1203#define SUBID_DVBC_CINERGY1200_MK3      0x1176
1204
1205#define SUBID_DVBT_EASYWATCH            0x003a
1206#define SUBID_DVBT_KNC1_PLUS            0x0031
1207#define SUBID_DVBT_KNC1                 0x0030
1208#define SUBID_DVBT_CINERGY1200          0x1157
1209
1210static void frontend_init(struct budget_av *budget_av)
1211{
1212        struct saa7146_dev * saa = budget_av->budget.dev;
1213        struct dvb_frontend * fe = NULL;
1214
1215        /* Enable / PowerON Frontend */
1216        saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1217
1218        /* Wait for PowerON */
1219        msleep(100);
1220
1221        /* additional setup necessary for the PLUS cards */
1222        switch (saa->pci->subsystem_device) {
1223                case SUBID_DVBS_KNC1_PLUS:
1224                case SUBID_DVBC_KNC1_PLUS:
1225                case SUBID_DVBT_KNC1_PLUS:
1226                case SUBID_DVBC_EASYWATCH:
1227                case SUBID_DVBC_KNC1_PLUS_MK3:
1228                case SUBID_DVBS2_KNC1:
1229                case SUBID_DVBS2_KNC1_OEM:
1230                case SUBID_DVBS2_EASYWATCH:
1231                        saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1232                        break;
1233        }
1234
1235        switch (saa->pci->subsystem_device) {
1236
1237        case SUBID_DVBS_KNC1:
1238                /*
1239                 * maybe that setting is needed for other dvb-s cards as well,
1240                 * but so far it has been only confirmed for this type
1241                 */
1242                budget_av->reinitialise_demod = 1;
1243                /* fall through */
1244        case SUBID_DVBS_KNC1_PLUS:
1245        case SUBID_DVBS_EASYWATCH_1:
1246                if (saa->pci->subsystem_vendor == 0x1894) {
1247                        fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
1248                                             &budget_av->budget.i2c_adap);
1249                        if (fe) {
1250                                dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
1251                        }
1252                } else {
1253                        fe = dvb_attach(stv0299_attach, &typhoon_config,
1254                                             &budget_av->budget.i2c_adap);
1255                        if (fe) {
1256                                fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1257                        }
1258                }
1259                break;
1260
1261        case SUBID_DVBS_TV_STAR:
1262        case SUBID_DVBS_TV_STAR_PLUS_X4:
1263        case SUBID_DVBS_TV_STAR_CI:
1264        case SUBID_DVBS_CYNERGY1200N:
1265        case SUBID_DVBS_EASYWATCH:
1266        case SUBID_DVBS_EASYWATCH_2:
1267                fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
1268                                &budget_av->budget.i2c_adap);
1269                if (fe) {
1270                        dvb_attach(dvb_pll_attach, fe, 0x60,
1271                                   &budget_av->budget.i2c_adap,
1272                                   DVB_PLL_PHILIPS_SD1878_TDA8261);
1273                }
1274                break;
1275
1276        case SUBID_DVBS_TYPHOON:
1277                fe = dvb_attach(stv0299_attach, &typhoon_config,
1278                                    &budget_av->budget.i2c_adap);
1279                if (fe) {
1280                        fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1281                }
1282                break;
1283        case SUBID_DVBS2_KNC1:
1284        case SUBID_DVBS2_KNC1_OEM:
1285        case SUBID_DVBS2_EASYWATCH:
1286                budget_av->reinitialise_demod = 1;
1287                if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1288                        dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
1289
1290                break;
1291        case SUBID_DVBS_CINERGY1200:
1292                fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1293                                    &budget_av->budget.i2c_adap);
1294                if (fe) {
1295                        fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1296                }
1297                break;
1298
1299        case SUBID_DVBC_KNC1:
1300        case SUBID_DVBC_KNC1_PLUS:
1301        case SUBID_DVBC_CINERGY1200:
1302        case SUBID_DVBC_EASYWATCH:
1303                budget_av->reinitialise_demod = 1;
1304                budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1305                fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1306                                     &budget_av->budget.i2c_adap,
1307                                     read_pwm(budget_av));
1308                if (fe == NULL)
1309                        fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1310                                             &budget_av->budget.i2c_adap,
1311                                             read_pwm(budget_av));
1312                if (fe) {
1313                        fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1314                }
1315                break;
1316
1317        case SUBID_DVBC_EASYWATCH_MK3:
1318        case SUBID_DVBC_CINERGY1200_MK3:
1319        case SUBID_DVBC_KNC1_MK3:
1320        case SUBID_DVBC_KNC1_TDA10024:
1321        case SUBID_DVBC_KNC1_PLUS_MK3:
1322                budget_av->reinitialise_demod = 1;
1323                budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1324                fe = dvb_attach(tda10023_attach,
1325                        &philips_cu1216_tda10023_config,
1326                        &budget_av->budget.i2c_adap,
1327                        read_pwm(budget_av));
1328                if (fe) {
1329                        fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1330                }
1331                break;
1332
1333        case SUBID_DVBT_EASYWATCH:
1334        case SUBID_DVBT_KNC1:
1335        case SUBID_DVBT_KNC1_PLUS:
1336        case SUBID_DVBT_CINERGY1200:
1337                budget_av->reinitialise_demod = 1;
1338                fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1339                                     &budget_av->budget.i2c_adap);
1340                if (fe) {
1341                        fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1342                        fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1343                }
1344                break;
1345        }
1346
1347        if (fe == NULL) {
1348                pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1349                       saa->pci->vendor,
1350                       saa->pci->device,
1351                       saa->pci->subsystem_vendor,
1352                       saa->pci->subsystem_device);
1353                return;
1354        }
1355
1356        budget_av->budget.dvb_frontend = fe;
1357
1358        if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1359                                  budget_av->budget.dvb_frontend)) {
1360                pr_err("Frontend registration failed!\n");
1361                dvb_frontend_detach(budget_av->budget.dvb_frontend);
1362                budget_av->budget.dvb_frontend = NULL;
1363        }
1364}
1365
1366
1367static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1368{
1369        struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1370
1371        dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1372
1373        if (*isr & MASK_10)
1374                ttpci_budget_irq10_handler(dev, isr);
1375}
1376
1377static int budget_av_detach(struct saa7146_dev *dev)
1378{
1379        struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1380        int err;
1381
1382        dprintk(2, "dev: %p\n", dev);
1383
1384        if (1 == budget_av->has_saa7113) {
1385                saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1386
1387                msleep(200);
1388
1389                saa7146_unregister_device(&budget_av->vd, dev);
1390
1391                saa7146_vv_release(dev);
1392        }
1393
1394        if (budget_av->budget.ci_present)
1395                ciintf_deinit(budget_av);
1396
1397        if (budget_av->budget.dvb_frontend != NULL) {
1398                dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1399                dvb_frontend_detach(budget_av->budget.dvb_frontend);
1400        }
1401        err = ttpci_budget_deinit(&budget_av->budget);
1402
1403        kfree(budget_av);
1404
1405        return err;
1406}
1407
1408#define KNC1_INPUTS 2
1409static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1410        { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
1411                V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1412        { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
1413                V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1414};
1415
1416static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1417{
1418        dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index);
1419        if (i->index >= KNC1_INPUTS)
1420                return -EINVAL;
1421        memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1422        return 0;
1423}
1424
1425static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1426{
1427        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1428        struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1429
1430        *i = budget_av->cur_input;
1431
1432        dprintk(1, "VIDIOC_G_INPUT %d\n", *i);
1433        return 0;
1434}
1435
1436static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
1437{
1438        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1439        struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1440
1441        dprintk(1, "VIDIOC_S_INPUT %d\n", input);
1442        return saa7113_setinput(budget_av, input);
1443}
1444
1445static struct saa7146_ext_vv vv_data;
1446
1447static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1448{
1449        struct budget_av *budget_av;
1450        u8 *mac;
1451        int err;
1452
1453        dprintk(2, "dev: %p\n", dev);
1454
1455        if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1456                return -ENOMEM;
1457
1458        budget_av->has_saa7113 = 0;
1459        budget_av->budget.ci_present = 0;
1460
1461        dev->ext_priv = budget_av;
1462
1463        err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1464                                adapter_nr);
1465        if (err) {
1466                kfree(budget_av);
1467                return err;
1468        }
1469
1470        /* knc1 initialization */
1471        saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1472        saa7146_write(dev, DD1_INIT, 0x07000600);
1473        saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1474
1475        if (saa7113_init(budget_av) == 0) {
1476                budget_av->has_saa7113 = 1;
1477                err = saa7146_vv_init(dev, &vv_data);
1478                if (err != 0) {
1479                        /* fixme: proper cleanup here */
1480                        ERR("cannot init vv subsystem\n");
1481                        return err;
1482                }
1483                vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
1484                vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
1485                vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
1486
1487                if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1488                        /* fixme: proper cleanup here */
1489                        ERR("cannot register capture v4l2 device\n");
1490                        saa7146_vv_release(dev);
1491                        return err;
1492                }
1493
1494                /* beware: this modifies dev->vv ... */
1495                saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1496                                                SAA7146_HPS_SYNC_PORT_A);
1497
1498                saa7113_setinput(budget_av, 0);
1499        }
1500
1501        /* fixme: find some sane values here... */
1502        saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1503
1504        mac = budget_av->budget.dvb_adapter.proposed_mac;
1505        if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1506                pr_err("KNC1-%d: Could not read MAC from KNC1 card\n",
1507                       budget_av->budget.dvb_adapter.num);
1508                eth_zero_addr(mac);
1509        } else {
1510                pr_info("KNC1-%d: MAC addr = %pM\n",
1511                        budget_av->budget.dvb_adapter.num, mac);
1512        }
1513
1514        budget_av->budget.dvb_adapter.priv = budget_av;
1515        frontend_init(budget_av);
1516        ciintf_init(budget_av);
1517
1518        ttpci_budget_init_hooks(&budget_av->budget);
1519
1520        return 0;
1521}
1522
1523static struct saa7146_standard standard[] = {
1524        {.name = "PAL",.id = V4L2_STD_PAL,
1525         .v_offset = 0x17,.v_field = 288,
1526         .h_offset = 0x14,.h_pixels = 680,
1527         .v_max_out = 576,.h_max_out = 768 },
1528
1529        {.name = "NTSC",.id = V4L2_STD_NTSC,
1530         .v_offset = 0x16,.v_field = 240,
1531         .h_offset = 0x06,.h_pixels = 708,
1532         .v_max_out = 480,.h_max_out = 640, },
1533};
1534
1535static struct saa7146_ext_vv vv_data = {
1536        .inputs = 2,
1537        .capabilities = 0,      // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1538        .flags = 0,
1539        .stds = &standard[0],
1540        .num_stds = ARRAY_SIZE(standard),
1541};
1542
1543static struct saa7146_extension budget_extension;
1544
1545MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1546MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
1547MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
1548MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1549MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1550MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1551MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1552MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1553MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
1554MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
1555MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
1556MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
1557MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1558MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
1559MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1560MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1561MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024);
1562MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
1563MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1564MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1565MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1566MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1567MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1568MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1569
1570static const struct pci_device_id pci_tbl[] = {
1571        MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1572        MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1573        MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1574        MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1575        MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1576        MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1577        MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
1578        MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1579        MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1580        MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
1581        MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
1582        MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1583        MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1584        MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
1585        MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
1586        MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
1587        MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
1588        MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1589        MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1590        MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1591        MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028),
1592        MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1593        MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1594        MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1595        MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1596        MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1597        MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1598        MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1599        MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1600        {
1601         .vendor = 0,
1602        }
1603};
1604
1605MODULE_DEVICE_TABLE(pci, pci_tbl);
1606
1607static struct saa7146_extension budget_extension = {
1608        .name = "budget_av",
1609        .flags = SAA7146_USE_I2C_IRQ,
1610
1611        .pci_tbl = pci_tbl,
1612
1613        .module = THIS_MODULE,
1614        .attach = budget_av_attach,
1615        .detach = budget_av_detach,
1616
1617        .irq_mask = MASK_10,
1618        .irq_func = budget_av_irq,
1619};
1620
1621static int __init budget_av_init(void)
1622{
1623        return saa7146_register_extension(&budget_extension);
1624}
1625
1626static void __exit budget_av_exit(void)
1627{
1628        saa7146_unregister_extension(&budget_extension);
1629}
1630
1631module_init(budget_av_init);
1632module_exit(budget_av_exit);
1633
1634MODULE_LICENSE("GPL");
1635MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1636MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
1637