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