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