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