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