Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * budget-av.c: driver for the SAA7146 based Budget DVB cards
0004  *              with analog video in
0005  *
0006  * Compiled from various sources by Michael Hunold <michael@mihu.de>
0007  *
0008  * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
0009  *                               Andrew de Quincey <adq_dvb@lidskialf.net>
0010  *
0011  * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
0012  *
0013  * Copyright (C) 1999-2002 Ralph  Metzler
0014  *                       & Marcus Metzler for convergence integrated media GmbH
0015  *
0016  * the project's page is at https://linuxtv.org
0017  */
0018 
0019 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0020 
0021 #include "budget.h"
0022 #include "stv0299.h"
0023 #include "stb0899_drv.h"
0024 #include "stb0899_reg.h"
0025 #include "stb0899_cfg.h"
0026 #include "tda8261.h"
0027 #include "tda8261_cfg.h"
0028 #include "tda1002x.h"
0029 #include "tda1004x.h"
0030 #include "tua6100.h"
0031 #include "dvb-pll.h"
0032 #include <media/drv-intf/saa7146_vv.h>
0033 #include <linux/module.h>
0034 #include <linux/errno.h>
0035 #include <linux/slab.h>
0036 #include <linux/interrupt.h>
0037 #include <linux/input.h>
0038 #include <linux/spinlock.h>
0039 
0040 #include <media/dvb_ca_en50221.h>
0041 
0042 #define DEBICICAM       0x02420000
0043 
0044 #define SLOTSTATUS_NONE         1
0045 #define SLOTSTATUS_PRESENT      2
0046 #define SLOTSTATUS_RESET        4
0047 #define SLOTSTATUS_READY        8
0048 #define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
0049 
0050 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
0051 
0052 struct budget_av {
0053     struct budget budget;
0054     struct video_device vd;
0055     int cur_input;
0056     int has_saa7113;
0057     struct tasklet_struct ciintf_irq_tasklet;
0058     int slot_status;
0059     struct dvb_ca_en50221 ca;
0060     u8 reinitialise_demod:1;
0061 };
0062 
0063 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
0064 
0065 
0066 /* GPIO Connections:
0067  * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
0068  * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
0069  * 2 - CI Card Enable (Active Low)
0070  * 3 - CI Card Detect
0071  */
0072 
0073 /****************************************************************************
0074  * INITIALIZATION
0075  ****************************************************************************/
0076 
0077 static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
0078 {
0079     u8 mm1[] = { 0x00 };
0080     u8 mm2[] = { 0x00 };
0081     struct i2c_msg msgs[2];
0082 
0083     msgs[0].flags = 0;
0084     msgs[1].flags = I2C_M_RD;
0085     msgs[0].addr = msgs[1].addr = id / 2;
0086     mm1[0] = reg;
0087     msgs[0].len = 1;
0088     msgs[1].len = 1;
0089     msgs[0].buf = mm1;
0090     msgs[1].buf = mm2;
0091 
0092     i2c_transfer(i2c, msgs, 2);
0093 
0094     return mm2[0];
0095 }
0096 
0097 static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
0098 {
0099     u8 mm1[] = { reg };
0100     struct i2c_msg msgs[2] = {
0101         {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
0102         {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
0103     };
0104 
0105     if (i2c_transfer(i2c, msgs, 2) != 2)
0106         return -EIO;
0107 
0108     return 0;
0109 }
0110 
0111 static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
0112 {
0113     u8 msg[2] = { reg, val };
0114     struct i2c_msg msgs;
0115 
0116     msgs.flags = 0;
0117     msgs.addr = id / 2;
0118     msgs.len = 2;
0119     msgs.buf = msg;
0120     return i2c_transfer(i2c, &msgs, 1);
0121 }
0122 
0123 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
0124 {
0125     struct budget_av *budget_av = (struct budget_av *) ca->data;
0126     int result;
0127 
0128     if (slot != 0)
0129         return -EINVAL;
0130 
0131     saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
0132     udelay(1);
0133 
0134     result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
0135     if (result == -ETIMEDOUT) {
0136         ciintf_slot_shutdown(ca, slot);
0137         pr_info("cam ejected 1\n");
0138     }
0139     return result;
0140 }
0141 
0142 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
0143 {
0144     struct budget_av *budget_av = (struct budget_av *) ca->data;
0145     int result;
0146 
0147     if (slot != 0)
0148         return -EINVAL;
0149 
0150     saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
0151     udelay(1);
0152 
0153     result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
0154     if (result == -ETIMEDOUT) {
0155         ciintf_slot_shutdown(ca, slot);
0156         pr_info("cam ejected 2\n");
0157     }
0158     return result;
0159 }
0160 
0161 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
0162 {
0163     struct budget_av *budget_av = (struct budget_av *) ca->data;
0164     int result;
0165 
0166     if (slot != 0)
0167         return -EINVAL;
0168 
0169     saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
0170     udelay(1);
0171 
0172     result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
0173     if (result == -ETIMEDOUT) {
0174         ciintf_slot_shutdown(ca, slot);
0175         pr_info("cam ejected 3\n");
0176         return -ETIMEDOUT;
0177     }
0178     return result;
0179 }
0180 
0181 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
0182 {
0183     struct budget_av *budget_av = (struct budget_av *) ca->data;
0184     int result;
0185 
0186     if (slot != 0)
0187         return -EINVAL;
0188 
0189     saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
0190     udelay(1);
0191 
0192     result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
0193     if (result == -ETIMEDOUT) {
0194         ciintf_slot_shutdown(ca, slot);
0195         pr_info("cam ejected 5\n");
0196     }
0197     return result;
0198 }
0199 
0200 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
0201 {
0202     struct budget_av *budget_av = (struct budget_av *) ca->data;
0203     struct saa7146_dev *saa = budget_av->budget.dev;
0204 
0205     if (slot != 0)
0206         return -EINVAL;
0207 
0208     dprintk(1, "ciintf_slot_reset\n");
0209     budget_av->slot_status = SLOTSTATUS_RESET;
0210 
0211     saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
0212 
0213     saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
0214     msleep(2);
0215     saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
0216     msleep(20); /* 20 ms Vcc settling time */
0217 
0218     saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
0219     ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
0220     msleep(20);
0221 
0222     /* reinitialise the frontend if necessary */
0223     if (budget_av->reinitialise_demod)
0224         dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
0225 
0226     return 0;
0227 }
0228 
0229 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
0230 {
0231     struct budget_av *budget_av = (struct budget_av *) ca->data;
0232     struct saa7146_dev *saa = budget_av->budget.dev;
0233 
0234     if (slot != 0)
0235         return -EINVAL;
0236 
0237     dprintk(1, "ciintf_slot_shutdown\n");
0238 
0239     ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
0240     budget_av->slot_status = SLOTSTATUS_NONE;
0241 
0242     return 0;
0243 }
0244 
0245 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
0246 {
0247     struct budget_av *budget_av = (struct budget_av *) ca->data;
0248     struct saa7146_dev *saa = budget_av->budget.dev;
0249 
0250     if (slot != 0)
0251         return -EINVAL;
0252 
0253     dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
0254 
0255     ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
0256 
0257     return 0;
0258 }
0259 
0260 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
0261 {
0262     struct budget_av *budget_av = (struct budget_av *) ca->data;
0263     struct saa7146_dev *saa = budget_av->budget.dev;
0264     int result;
0265 
0266     if (slot != 0)
0267         return -EINVAL;
0268 
0269     /* test the card detect line - needs to be done carefully
0270      * since it never goes high for some CAMs on this interface (e.g. topuptv) */
0271     if (budget_av->slot_status == SLOTSTATUS_NONE) {
0272         saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
0273         udelay(1);
0274         if (saa7146_read(saa, PSR) & MASK_06) {
0275             if (budget_av->slot_status == SLOTSTATUS_NONE) {
0276                 budget_av->slot_status = SLOTSTATUS_PRESENT;
0277                 pr_info("cam inserted A\n");
0278             }
0279         }
0280         saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
0281     }
0282 
0283     /* We also try and read from IO memory to work round the above detection bug. If
0284      * there is no CAM, we will get a timeout. Only done if there is no cam
0285      * present, since this test actually breaks some cams :(
0286      *
0287      * if the CI interface is not open, we also do the above test since we
0288      * don't care if the cam has problems - we'll be resetting it on open() anyway */
0289     if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
0290         saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
0291         result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
0292         if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
0293             budget_av->slot_status = SLOTSTATUS_PRESENT;
0294             pr_info("cam inserted B\n");
0295         } else if (result < 0) {
0296             if (budget_av->slot_status != SLOTSTATUS_NONE) {
0297                 ciintf_slot_shutdown(ca, slot);
0298                 pr_info("cam ejected 5\n");
0299                 return 0;
0300             }
0301         }
0302     }
0303 
0304     /* read from attribute memory in reset/ready state to know when the CAM is ready */
0305     if (budget_av->slot_status == SLOTSTATUS_RESET) {
0306         result = ciintf_read_attribute_mem(ca, slot, 0);
0307         if (result == 0x1d) {
0308             budget_av->slot_status = SLOTSTATUS_READY;
0309         }
0310     }
0311 
0312     /* work out correct return code */
0313     if (budget_av->slot_status != SLOTSTATUS_NONE) {
0314         if (budget_av->slot_status & SLOTSTATUS_READY) {
0315             return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
0316         }
0317         return DVB_CA_EN50221_POLL_CAM_PRESENT;
0318     }
0319     return 0;
0320 }
0321 
0322 static int ciintf_init(struct budget_av *budget_av)
0323 {
0324     struct saa7146_dev *saa = budget_av->budget.dev;
0325     int result;
0326 
0327     memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
0328 
0329     saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
0330     saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
0331     saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
0332     saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
0333 
0334     /* Enable DEBI pins */
0335     saa7146_write(saa, MC1, MASK_27 | MASK_11);
0336 
0337     /* register CI interface */
0338     budget_av->ca.owner = THIS_MODULE;
0339     budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
0340     budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
0341     budget_av->ca.read_cam_control = ciintf_read_cam_control;
0342     budget_av->ca.write_cam_control = ciintf_write_cam_control;
0343     budget_av->ca.slot_reset = ciintf_slot_reset;
0344     budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
0345     budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
0346     budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
0347     budget_av->ca.data = budget_av;
0348     budget_av->budget.ci_present = 1;
0349     budget_av->slot_status = SLOTSTATUS_NONE;
0350 
0351     if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
0352                       &budget_av->ca, 0, 1)) != 0) {
0353         pr_err("ci initialisation failed\n");
0354         goto error;
0355     }
0356 
0357     pr_info("ci interface initialised\n");
0358     return 0;
0359 
0360 error:
0361     saa7146_write(saa, MC1, MASK_27);
0362     return result;
0363 }
0364 
0365 static void ciintf_deinit(struct budget_av *budget_av)
0366 {
0367     struct saa7146_dev *saa = budget_av->budget.dev;
0368 
0369     saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
0370     saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
0371     saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
0372     saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
0373 
0374     /* release the CA device */
0375     dvb_ca_en50221_release(&budget_av->ca);
0376 
0377     /* disable DEBI pins */
0378     saa7146_write(saa, MC1, MASK_27);
0379 }
0380 
0381 
0382 static const u8 saa7113_tab[] = {
0383     0x01, 0x08,
0384     0x02, 0xc0,
0385     0x03, 0x33,
0386     0x04, 0x00,
0387     0x05, 0x00,
0388     0x06, 0xeb,
0389     0x07, 0xe0,
0390     0x08, 0x28,
0391     0x09, 0x00,
0392     0x0a, 0x80,
0393     0x0b, 0x47,
0394     0x0c, 0x40,
0395     0x0d, 0x00,
0396     0x0e, 0x01,
0397     0x0f, 0x44,
0398 
0399     0x10, 0x08,
0400     0x11, 0x0c,
0401     0x12, 0x7b,
0402     0x13, 0x00,
0403     0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
0404 
0405     0x57, 0xff,
0406     0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
0407     0x5b, 0x83, 0x5e, 0x00,
0408     0xff
0409 };
0410 
0411 static int saa7113_init(struct budget_av *budget_av)
0412 {
0413     struct budget *budget = &budget_av->budget;
0414     struct saa7146_dev *saa = budget->dev;
0415     const u8 *data = saa7113_tab;
0416 
0417     saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
0418     msleep(200);
0419 
0420     if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
0421         dprintk(1, "saa7113 not found on KNC card\n");
0422         return -ENODEV;
0423     }
0424 
0425     dprintk(1, "saa7113 detected and initializing\n");
0426 
0427     while (*data != 0xff) {
0428         i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
0429         data += 2;
0430     }
0431 
0432     dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
0433 
0434     return 0;
0435 }
0436 
0437 static int saa7113_setinput(struct budget_av *budget_av, int input)
0438 {
0439     struct budget *budget = &budget_av->budget;
0440 
0441     if (1 != budget_av->has_saa7113)
0442         return -ENODEV;
0443 
0444     if (input == 1) {
0445         i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
0446         i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
0447     } else if (input == 0) {
0448         i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
0449         i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
0450     } else
0451         return -EINVAL;
0452 
0453     budget_av->cur_input = input;
0454     return 0;
0455 }
0456 
0457 
0458 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
0459 {
0460     u8 aclk = 0;
0461     u8 bclk = 0;
0462     u8 m1;
0463 
0464     aclk = 0xb5;
0465     if (srate < 2000000)
0466         bclk = 0x86;
0467     else if (srate < 5000000)
0468         bclk = 0x89;
0469     else if (srate < 15000000)
0470         bclk = 0x8f;
0471     else if (srate < 45000000)
0472         bclk = 0x95;
0473 
0474     m1 = 0x14;
0475     if (srate < 4000000)
0476         m1 = 0x10;
0477 
0478     stv0299_writereg(fe, 0x13, aclk);
0479     stv0299_writereg(fe, 0x14, bclk);
0480     stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
0481     stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
0482     stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
0483     stv0299_writereg(fe, 0x0f, 0x80 | m1);
0484 
0485     return 0;
0486 }
0487 
0488 static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe)
0489 {
0490     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0491     u32 div;
0492     u8 buf[4];
0493     struct budget *budget = (struct budget *) fe->dvb->priv;
0494     struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
0495 
0496     if ((c->frequency < 950000) || (c->frequency > 2150000))
0497         return -EINVAL;
0498 
0499     div = (c->frequency + (125 - 1)) / 125; /* round correctly */
0500     buf[0] = (div >> 8) & 0x7f;
0501     buf[1] = div & 0xff;
0502     buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
0503     buf[3] = 0x20;
0504 
0505     if (c->symbol_rate < 4000000)
0506         buf[3] |= 1;
0507 
0508     if (c->frequency < 1250000)
0509         buf[3] |= 0;
0510     else if (c->frequency < 1550000)
0511         buf[3] |= 0x40;
0512     else if (c->frequency < 2050000)
0513         buf[3] |= 0x80;
0514     else if (c->frequency < 2150000)
0515         buf[3] |= 0xC0;
0516 
0517     if (fe->ops.i2c_gate_ctrl)
0518         fe->ops.i2c_gate_ctrl(fe, 1);
0519     if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
0520         return -EIO;
0521     return 0;
0522 }
0523 
0524 static u8 typhoon_cinergy1200s_inittab[] = {
0525     0x01, 0x15,
0526     0x02, 0x30,
0527     0x03, 0x00,
0528     0x04, 0x7d,     /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
0529     0x05, 0x35,     /* I2CT = 0, SCLT = 1, SDAT = 1 */
0530     0x06, 0x40,     /* DAC not used, set to high impendance mode */
0531     0x07, 0x00,     /* DAC LSB */
0532     0x08, 0x40,     /* DiSEqC off */
0533     0x09, 0x00,     /* FIFO */
0534     0x0c, 0x51,     /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
0535     0x0d, 0x82,     /* DC offset compensation = ON, beta_agc1 = 2 */
0536     0x0e, 0x23,     /* alpha_tmg = 2, beta_tmg = 3 */
0537     0x10, 0x3f,     // AGC2  0x3d
0538     0x11, 0x84,
0539     0x12, 0xb9,
0540     0x15, 0xc9,     // lock detector threshold
0541     0x16, 0x00,
0542     0x17, 0x00,
0543     0x18, 0x00,
0544     0x19, 0x00,
0545     0x1a, 0x00,
0546     0x1f, 0x50,
0547     0x20, 0x00,
0548     0x21, 0x00,
0549     0x22, 0x00,
0550     0x23, 0x00,
0551     0x28, 0x00,     // out imp: normal  out type: parallel FEC mode:0
0552     0x29, 0x1e,     // 1/2 threshold
0553     0x2a, 0x14,     // 2/3 threshold
0554     0x2b, 0x0f,     // 3/4 threshold
0555     0x2c, 0x09,     // 5/6 threshold
0556     0x2d, 0x05,     // 7/8 threshold
0557     0x2e, 0x01,
0558     0x31, 0x1f,     // test all FECs
0559     0x32, 0x19,     // viterbi and synchro search
0560     0x33, 0xfc,     // rs control
0561     0x34, 0x93,     // error control
0562     0x0f, 0x92,
0563     0xff, 0xff
0564 };
0565 
0566 static const struct stv0299_config typhoon_config = {
0567     .demod_address = 0x68,
0568     .inittab = typhoon_cinergy1200s_inittab,
0569     .mclk = 88000000UL,
0570     .invert = 0,
0571     .skip_reinit = 0,
0572     .lock_output = STV0299_LOCKOUTPUT_1,
0573     .volt13_op0_op1 = STV0299_VOLT13_OP0,
0574     .min_delay_ms = 100,
0575     .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
0576 };
0577 
0578 
0579 static const struct stv0299_config cinergy_1200s_config = {
0580     .demod_address = 0x68,
0581     .inittab = typhoon_cinergy1200s_inittab,
0582     .mclk = 88000000UL,
0583     .invert = 0,
0584     .skip_reinit = 0,
0585     .lock_output = STV0299_LOCKOUTPUT_0,
0586     .volt13_op0_op1 = STV0299_VOLT13_OP0,
0587     .min_delay_ms = 100,
0588     .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
0589 };
0590 
0591 static const struct stv0299_config cinergy_1200s_1894_0010_config = {
0592     .demod_address = 0x68,
0593     .inittab = typhoon_cinergy1200s_inittab,
0594     .mclk = 88000000UL,
0595     .invert = 1,
0596     .skip_reinit = 0,
0597     .lock_output = STV0299_LOCKOUTPUT_1,
0598     .volt13_op0_op1 = STV0299_VOLT13_OP0,
0599     .min_delay_ms = 100,
0600     .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
0601 };
0602 
0603 static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe)
0604 {
0605     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0606     struct budget *budget = (struct budget *) fe->dvb->priv;
0607     u8 buf[6];
0608     struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
0609     int i;
0610 
0611 #define CU1216_IF 36125000
0612 #define TUNER_MUL 62500
0613 
0614     u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
0615 
0616     buf[0] = (div >> 8) & 0x7f;
0617     buf[1] = div & 0xff;
0618     buf[2] = 0xce;
0619     buf[3] = (c->frequency < 150000000 ? 0x01 :
0620           c->frequency < 445000000 ? 0x02 : 0x04);
0621     buf[4] = 0xde;
0622     buf[5] = 0x20;
0623 
0624     if (fe->ops.i2c_gate_ctrl)
0625         fe->ops.i2c_gate_ctrl(fe, 1);
0626     if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
0627         return -EIO;
0628 
0629     /* wait for the pll lock */
0630     msg.flags = I2C_M_RD;
0631     msg.len = 1;
0632     for (i = 0; i < 20; i++) {
0633         if (fe->ops.i2c_gate_ctrl)
0634             fe->ops.i2c_gate_ctrl(fe, 1);
0635         if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
0636             break;
0637         msleep(10);
0638     }
0639 
0640     /* switch the charge pump to the lower current */
0641     msg.flags = 0;
0642     msg.len = 2;
0643     msg.buf = &buf[2];
0644     buf[2] &= ~0x40;
0645     if (fe->ops.i2c_gate_ctrl)
0646         fe->ops.i2c_gate_ctrl(fe, 1);
0647     if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
0648         return -EIO;
0649 
0650     return 0;
0651 }
0652 
0653 static struct tda1002x_config philips_cu1216_config = {
0654     .demod_address = 0x0c,
0655     .invert = 1,
0656 };
0657 
0658 static struct tda1002x_config philips_cu1216_config_altaddress = {
0659     .demod_address = 0x0d,
0660     .invert = 0,
0661 };
0662 
0663 static struct tda10023_config philips_cu1216_tda10023_config = {
0664     .demod_address = 0x0c,
0665     .invert = 1,
0666 };
0667 
0668 static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
0669 {
0670     struct budget *budget = (struct budget *) fe->dvb->priv;
0671     static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
0672     struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
0673 
0674     // setup PLL configuration
0675     if (fe->ops.i2c_gate_ctrl)
0676         fe->ops.i2c_gate_ctrl(fe, 1);
0677     if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
0678         return -EIO;
0679     msleep(1);
0680 
0681     return 0;
0682 }
0683 
0684 static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe)
0685 {
0686     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0687     struct budget *budget = (struct budget *) fe->dvb->priv;
0688     u8 tuner_buf[4];
0689     struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
0690             sizeof(tuner_buf) };
0691     int tuner_frequency = 0;
0692     u8 band, cp, filter;
0693 
0694     // determine charge pump
0695     tuner_frequency = c->frequency + 36166000;
0696     if (tuner_frequency < 87000000)
0697         return -EINVAL;
0698     else if (tuner_frequency < 130000000)
0699         cp = 3;
0700     else if (tuner_frequency < 160000000)
0701         cp = 5;
0702     else if (tuner_frequency < 200000000)
0703         cp = 6;
0704     else if (tuner_frequency < 290000000)
0705         cp = 3;
0706     else if (tuner_frequency < 420000000)
0707         cp = 5;
0708     else if (tuner_frequency < 480000000)
0709         cp = 6;
0710     else if (tuner_frequency < 620000000)
0711         cp = 3;
0712     else if (tuner_frequency < 830000000)
0713         cp = 5;
0714     else if (tuner_frequency < 895000000)
0715         cp = 7;
0716     else
0717         return -EINVAL;
0718 
0719     // determine band
0720     if (c->frequency < 49000000)
0721         return -EINVAL;
0722     else if (c->frequency < 161000000)
0723         band = 1;
0724     else if (c->frequency < 444000000)
0725         band = 2;
0726     else if (c->frequency < 861000000)
0727         band = 4;
0728     else
0729         return -EINVAL;
0730 
0731     // setup PLL filter
0732     switch (c->bandwidth_hz) {
0733     case 6000000:
0734         filter = 0;
0735         break;
0736 
0737     case 7000000:
0738         filter = 0;
0739         break;
0740 
0741     case 8000000:
0742         filter = 1;
0743         break;
0744 
0745     default:
0746         return -EINVAL;
0747     }
0748 
0749     // calculate divisor
0750     // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
0751     tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000;
0752 
0753     // setup tuner buffer
0754     tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
0755     tuner_buf[1] = tuner_frequency & 0xff;
0756     tuner_buf[2] = 0xca;
0757     tuner_buf[3] = (cp << 5) | (filter << 3) | band;
0758 
0759     if (fe->ops.i2c_gate_ctrl)
0760         fe->ops.i2c_gate_ctrl(fe, 1);
0761     if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
0762         return -EIO;
0763 
0764     msleep(1);
0765     return 0;
0766 }
0767 
0768 static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
0769                        const struct firmware **fw, char *name)
0770 {
0771     struct budget *budget = (struct budget *) fe->dvb->priv;
0772 
0773     return request_firmware(fw, name, &budget->dev->pci->dev);
0774 }
0775 
0776 static struct tda1004x_config philips_tu1216_config = {
0777 
0778     .demod_address = 0x8,
0779     .invert = 1,
0780     .invert_oclk = 1,
0781     .xtal_freq = TDA10046_XTAL_4M,
0782     .agc_config = TDA10046_AGC_DEFAULT,
0783     .if_freq = TDA10046_FREQ_3617,
0784     .request_firmware = philips_tu1216_request_firmware,
0785 };
0786 
0787 static u8 philips_sd1878_inittab[] = {
0788     0x01, 0x15,
0789     0x02, 0x30,
0790     0x03, 0x00,
0791     0x04, 0x7d,
0792     0x05, 0x35,
0793     0x06, 0x40,
0794     0x07, 0x00,
0795     0x08, 0x43,
0796     0x09, 0x02,
0797     0x0C, 0x51,
0798     0x0D, 0x82,
0799     0x0E, 0x23,
0800     0x10, 0x3f,
0801     0x11, 0x84,
0802     0x12, 0xb9,
0803     0x15, 0xc9,
0804     0x16, 0x19,
0805     0x17, 0x8c,
0806     0x18, 0x59,
0807     0x19, 0xf8,
0808     0x1a, 0xfe,
0809     0x1c, 0x7f,
0810     0x1d, 0x00,
0811     0x1e, 0x00,
0812     0x1f, 0x50,
0813     0x20, 0x00,
0814     0x21, 0x00,
0815     0x22, 0x00,
0816     0x23, 0x00,
0817     0x28, 0x00,
0818     0x29, 0x28,
0819     0x2a, 0x14,
0820     0x2b, 0x0f,
0821     0x2c, 0x09,
0822     0x2d, 0x09,
0823     0x31, 0x1f,
0824     0x32, 0x19,
0825     0x33, 0xfc,
0826     0x34, 0x93,
0827     0xff, 0xff
0828 };
0829 
0830 static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
0831         u32 srate, u32 ratio)
0832 {
0833     u8 aclk = 0;
0834     u8 bclk = 0;
0835     u8 m1;
0836 
0837     aclk = 0xb5;
0838     if (srate < 2000000)
0839         bclk = 0x86;
0840     else if (srate < 5000000)
0841         bclk = 0x89;
0842     else if (srate < 15000000)
0843         bclk = 0x8f;
0844     else if (srate < 45000000)
0845         bclk = 0x95;
0846 
0847     m1 = 0x14;
0848     if (srate < 4000000)
0849         m1 = 0x10;
0850 
0851     stv0299_writereg(fe, 0x0e, 0x23);
0852     stv0299_writereg(fe, 0x0f, 0x94);
0853     stv0299_writereg(fe, 0x10, 0x39);
0854     stv0299_writereg(fe, 0x13, aclk);
0855     stv0299_writereg(fe, 0x14, bclk);
0856     stv0299_writereg(fe, 0x15, 0xc9);
0857     stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
0858     stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
0859     stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
0860     stv0299_writereg(fe, 0x0f, 0x80 | m1);
0861 
0862     return 0;
0863 }
0864 
0865 static const struct stv0299_config philips_sd1878_config = {
0866     .demod_address = 0x68,
0867      .inittab = philips_sd1878_inittab,
0868     .mclk = 88000000UL,
0869     .invert = 0,
0870     .skip_reinit = 0,
0871     .lock_output = STV0299_LOCKOUTPUT_1,
0872     .volt13_op0_op1 = STV0299_VOLT13_OP0,
0873     .min_delay_ms = 100,
0874     .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
0875 };
0876 
0877 /* KNC1 DVB-S (STB0899) Inittab */
0878 static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
0879 
0880     { STB0899_DEV_ID        , 0x81 },
0881     { STB0899_DISCNTRL1     , 0x32 },
0882     { STB0899_DISCNTRL2     , 0x80 },
0883     { STB0899_DISRX_ST0     , 0x04 },
0884     { STB0899_DISRX_ST1     , 0x00 },
0885     { STB0899_DISPARITY     , 0x00 },
0886     { STB0899_DISSTATUS     , 0x20 },
0887     { STB0899_DISF22        , 0x8c },
0888     { STB0899_DISF22RX      , 0x9a },
0889     { STB0899_SYSREG        , 0x0b },
0890     { STB0899_ACRPRESC      , 0x11 },
0891     { STB0899_ACRDIV1       , 0x0a },
0892     { STB0899_ACRDIV2       , 0x05 },
0893     { STB0899_DACR1         , 0x00 },
0894     { STB0899_DACR2         , 0x00 },
0895     { STB0899_OUTCFG        , 0x00 },
0896     { STB0899_MODECFG       , 0x00 },
0897     { STB0899_IRQSTATUS_3       , 0x30 },
0898     { STB0899_IRQSTATUS_2       , 0x00 },
0899     { STB0899_IRQSTATUS_1       , 0x00 },
0900     { STB0899_IRQSTATUS_0       , 0x00 },
0901     { STB0899_IRQMSK_3      , 0xf3 },
0902     { STB0899_IRQMSK_2      , 0xfc },
0903     { STB0899_IRQMSK_1      , 0xff },
0904     { STB0899_IRQMSK_0      , 0xff },
0905     { STB0899_IRQCFG        , 0x00 },
0906     { STB0899_I2CCFG        , 0x88 },
0907     { STB0899_I2CRPT        , 0x58 }, /* Repeater=8, Stop=disabled */
0908     { STB0899_IOPVALUE5     , 0x00 },
0909     { STB0899_IOPVALUE4     , 0x20 },
0910     { STB0899_IOPVALUE3     , 0xc9 },
0911     { STB0899_IOPVALUE2     , 0x90 },
0912     { STB0899_IOPVALUE1     , 0x40 },
0913     { STB0899_IOPVALUE0     , 0x00 },
0914     { STB0899_GPIO00CFG     , 0x82 },
0915     { STB0899_GPIO01CFG     , 0x82 },
0916     { STB0899_GPIO02CFG     , 0x82 },
0917     { STB0899_GPIO03CFG     , 0x82 },
0918     { STB0899_GPIO04CFG     , 0x82 },
0919     { STB0899_GPIO05CFG     , 0x82 },
0920     { STB0899_GPIO06CFG     , 0x82 },
0921     { STB0899_GPIO07CFG     , 0x82 },
0922     { STB0899_GPIO08CFG     , 0x82 },
0923     { STB0899_GPIO09CFG     , 0x82 },
0924     { STB0899_GPIO10CFG     , 0x82 },
0925     { STB0899_GPIO11CFG     , 0x82 },
0926     { STB0899_GPIO12CFG     , 0x82 },
0927     { STB0899_GPIO13CFG     , 0x82 },
0928     { STB0899_GPIO14CFG     , 0x82 },
0929     { STB0899_GPIO15CFG     , 0x82 },
0930     { STB0899_GPIO16CFG     , 0x82 },
0931     { STB0899_GPIO17CFG     , 0x82 },
0932     { STB0899_GPIO18CFG     , 0x82 },
0933     { STB0899_GPIO19CFG     , 0x82 },
0934     { STB0899_GPIO20CFG     , 0x82 },
0935     { STB0899_SDATCFG       , 0xb8 },
0936     { STB0899_SCLTCFG       , 0xba },
0937     { STB0899_AGCRFCFG      , 0x08 }, /* 0x1c */
0938     { STB0899_GPIO22        , 0x82 }, /* AGCBB2CFG */
0939     { STB0899_GPIO21        , 0x91 }, /* AGCBB1CFG */
0940     { STB0899_DIRCLKCFG     , 0x82 },
0941     { STB0899_CLKOUT27CFG       , 0x7e },
0942     { STB0899_STDBYCFG      , 0x82 },
0943     { STB0899_CS0CFG        , 0x82 },
0944     { STB0899_CS1CFG        , 0x82 },
0945     { STB0899_DISEQCOCFG        , 0x20 },
0946     { STB0899_GPIO32CFG     , 0x82 },
0947     { STB0899_GPIO33CFG     , 0x82 },
0948     { STB0899_GPIO34CFG     , 0x82 },
0949     { STB0899_GPIO35CFG     , 0x82 },
0950     { STB0899_GPIO36CFG     , 0x82 },
0951     { STB0899_GPIO37CFG     , 0x82 },
0952     { STB0899_GPIO38CFG     , 0x82 },
0953     { STB0899_GPIO39CFG     , 0x82 },
0954     { STB0899_NCOARSE       , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
0955     { STB0899_SYNTCTRL      , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
0956     { STB0899_FILTCTRL      , 0x00 },
0957     { STB0899_SYSCTRL       , 0x00 },
0958     { STB0899_STOPCLK1      , 0x20 },
0959     { STB0899_STOPCLK2      , 0x00 },
0960     { STB0899_INTBUFSTATUS      , 0x00 },
0961     { STB0899_INTBUFCTRL        , 0x0a },
0962     { 0xffff            , 0xff },
0963 };
0964 
0965 static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
0966     { STB0899_DEMOD         , 0x00 },
0967     { STB0899_RCOMPC        , 0xc9 },
0968     { STB0899_AGC1CN        , 0x41 },
0969     { STB0899_AGC1REF       , 0x08 },
0970     { STB0899_RTC           , 0x7a },
0971     { STB0899_TMGCFG        , 0x4e },
0972     { STB0899_AGC2REF       , 0x33 },
0973     { STB0899_TLSR          , 0x84 },
0974     { STB0899_CFD           , 0xee },
0975     { STB0899_ACLC          , 0x87 },
0976     { STB0899_BCLC          , 0x94 },
0977     { STB0899_EQON          , 0x41 },
0978     { STB0899_LDT           , 0xdd },
0979     { STB0899_LDT2          , 0xc9 },
0980     { STB0899_EQUALREF      , 0xb4 },
0981     { STB0899_TMGRAMP       , 0x10 },
0982     { STB0899_TMGTHD        , 0x30 },
0983     { STB0899_IDCCOMP       , 0xfb },
0984     { STB0899_QDCCOMP       , 0x03 },
0985     { STB0899_POWERI        , 0x3b },
0986     { STB0899_POWERQ        , 0x3d },
0987     { STB0899_RCOMP         , 0x81 },
0988     { STB0899_AGCIQIN       , 0x80 },
0989     { STB0899_AGC2I1        , 0x04 },
0990     { STB0899_AGC2I2        , 0xf5 },
0991     { STB0899_TLIR          , 0x25 },
0992     { STB0899_RTF           , 0x80 },
0993     { STB0899_DSTATUS       , 0x00 },
0994     { STB0899_LDI           , 0xca },
0995     { STB0899_CFRM          , 0xf1 },
0996     { STB0899_CFRL          , 0xf3 },
0997     { STB0899_NIRM          , 0x2a },
0998     { STB0899_NIRL          , 0x05 },
0999     { STB0899_ISYMB         , 0x17 },
1000     { STB0899_QSYMB         , 0xfa },
1001     { STB0899_SFRH          , 0x2f },
1002     { STB0899_SFRM          , 0x68 },
1003     { STB0899_SFRL          , 0x40 },
1004     { STB0899_SFRUPH        , 0x2f },
1005     { STB0899_SFRUPM        , 0x68 },
1006     { STB0899_SFRUPL        , 0x40 },
1007     { STB0899_EQUAI1        , 0xfd },
1008     { STB0899_EQUAQ1        , 0x04 },
1009     { STB0899_EQUAI2        , 0x0f },
1010     { STB0899_EQUAQ2        , 0xff },
1011     { STB0899_EQUAI3        , 0xdf },
1012     { STB0899_EQUAQ3        , 0xfa },
1013     { STB0899_EQUAI4        , 0x37 },
1014     { STB0899_EQUAQ4        , 0x0d },
1015     { STB0899_EQUAI5        , 0xbd },
1016     { STB0899_EQUAQ5        , 0xf7 },
1017     { STB0899_DSTATUS2      , 0x00 },
1018     { STB0899_VSTATUS       , 0x00 },
1019     { STB0899_VERROR        , 0xff },
1020     { STB0899_IQSWAP        , 0x2a },
1021     { STB0899_ECNT1M        , 0x00 },
1022     { STB0899_ECNT1L        , 0x00 },
1023     { STB0899_ECNT2M        , 0x00 },
1024     { STB0899_ECNT2L        , 0x00 },
1025     { STB0899_ECNT3M        , 0x00 },
1026     { STB0899_ECNT3L        , 0x00 },
1027     { STB0899_FECAUTO1      , 0x06 },
1028     { STB0899_FECM          , 0x01 },
1029     { STB0899_VTH12         , 0xf0 },
1030     { STB0899_VTH23         , 0xa0 },
1031     { STB0899_VTH34         , 0x78 },
1032     { STB0899_VTH56         , 0x4e },
1033     { STB0899_VTH67         , 0x48 },
1034     { STB0899_VTH78         , 0x38 },
1035     { STB0899_PRVIT         , 0xff },
1036     { STB0899_VITSYNC       , 0x19 },
1037     { STB0899_RSULC         , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1038     { STB0899_TSULC         , 0x42 },
1039     { STB0899_RSLLC         , 0x40 },
1040     { STB0899_TSLPL         , 0x12 },
1041     { STB0899_TSCFGH        , 0x0c },
1042     { STB0899_TSCFGM        , 0x00 },
1043     { STB0899_TSCFGL        , 0x0c },
1044     { STB0899_TSOUT         , 0x4d }, /* 0x0d for CAM */
1045     { STB0899_RSSYNCDEL     , 0x00 },
1046     { STB0899_TSINHDELH     , 0x02 },
1047     { STB0899_TSINHDELM     , 0x00 },
1048     { STB0899_TSINHDELL     , 0x00 },
1049     { STB0899_TSLLSTKM      , 0x00 },
1050     { STB0899_TSLLSTKL      , 0x00 },
1051     { STB0899_TSULSTKM      , 0x00 },
1052     { STB0899_TSULSTKL      , 0xab },
1053     { STB0899_PCKLENUL      , 0x00 },
1054     { STB0899_PCKLENLL      , 0xcc },
1055     { STB0899_RSPCKLEN      , 0xcc },
1056     { STB0899_TSSTATUS      , 0x80 },
1057     { STB0899_ERRCTRL1      , 0xb6 },
1058     { STB0899_ERRCTRL2      , 0x96 },
1059     { STB0899_ERRCTRL3      , 0x89 },
1060     { STB0899_DMONMSK1      , 0x27 },
1061     { STB0899_DMONMSK0      , 0x03 },
1062     { STB0899_DEMAPVIT      , 0x5c },
1063     { STB0899_PLPARM        , 0x1f },
1064     { STB0899_PDELCTRL      , 0x48 },
1065     { STB0899_PDELCTRL2     , 0x00 },
1066     { STB0899_BBHCTRL1      , 0x00 },
1067     { STB0899_BBHCTRL2      , 0x00 },
1068     { STB0899_HYSTTHRESH        , 0x77 },
1069     { STB0899_MATCSTM       , 0x00 },
1070     { STB0899_MATCSTL       , 0x00 },
1071     { STB0899_UPLCSTM       , 0x00 },
1072     { STB0899_UPLCSTL       , 0x00 },
1073     { STB0899_DFLCSTM       , 0x00 },
1074     { STB0899_DFLCSTL       , 0x00 },
1075     { STB0899_SYNCCST       , 0x00 },
1076     { STB0899_SYNCDCSTM     , 0x00 },
1077     { STB0899_SYNCDCSTL     , 0x00 },
1078     { STB0899_ISI_ENTRY     , 0x00 },
1079     { STB0899_ISI_BIT_EN        , 0x00 },
1080     { STB0899_MATSTRM       , 0x00 },
1081     { STB0899_MATSTRL       , 0x00 },
1082     { STB0899_UPLSTRM       , 0x00 },
1083     { STB0899_UPLSTRL       , 0x00 },
1084     { STB0899_DFLSTRM       , 0x00 },
1085     { STB0899_DFLSTRL       , 0x00 },
1086     { STB0899_SYNCSTR       , 0x00 },
1087     { STB0899_SYNCDSTRM     , 0x00 },
1088     { STB0899_SYNCDSTRL     , 0x00 },
1089     { STB0899_CFGPDELSTATUS1    , 0x10 },
1090     { STB0899_CFGPDELSTATUS2    , 0x00 },
1091     { STB0899_BBFERRORM     , 0x00 },
1092     { STB0899_BBFERRORL     , 0x00 },
1093     { STB0899_UPKTERRORM        , 0x00 },
1094     { STB0899_UPKTERRORL        , 0x00 },
1095     { 0xffff            , 0xff },
1096 };
1097 
1098 /* STB0899 demodulator config for the KNC1 and clones */
1099 static struct stb0899_config knc1_dvbs2_config = {
1100     .init_dev       = knc1_stb0899_s1_init_1,
1101     .init_s2_demod      = stb0899_s2_init_2,
1102     .init_s1_demod      = knc1_stb0899_s1_init_3,
1103     .init_s2_fec        = stb0899_s2_init_4,
1104     .init_tst       = stb0899_s1_init_5,
1105 
1106     .postproc       = NULL,
1107 
1108     .demod_address      = 0x68,
1109 //  .ts_output_mode     = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL  */
1110     .block_sync_mode    = STB0899_SYNC_FORCED,  /* DSS, SYNC_FORCED/UNSYNCED    */
1111 //  .ts_pfbit_toggle    = STB0899_MPEG_NORMAL,  /* DirecTV, MPEG toggling seq   */
1112 
1113     .xtal_freq      = 27000000,
1114     .inversion      = IQ_SWAP_OFF,
1115 
1116     .lo_clk         = 76500000,
1117     .hi_clk         = 90000000,
1118 
1119     .esno_ave       = STB0899_DVBS2_ESNO_AVE,
1120     .esno_quant     = STB0899_DVBS2_ESNO_QUANT,
1121     .avframes_coarse    = STB0899_DVBS2_AVFRAMES_COARSE,
1122     .avframes_fine      = STB0899_DVBS2_AVFRAMES_FINE,
1123     .miss_threshold     = STB0899_DVBS2_MISS_THRESHOLD,
1124     .uwp_threshold_acq  = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1125     .uwp_threshold_track    = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1126     .uwp_threshold_sof  = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1127     .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1128 
1129     .btr_nco_bits       = STB0899_DVBS2_BTR_NCO_BITS,
1130     .btr_gain_shift_offset  = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1131     .crl_nco_bits       = STB0899_DVBS2_CRL_NCO_BITS,
1132     .ldpc_max_iter      = STB0899_DVBS2_LDPC_MAX_ITER,
1133 
1134     .tuner_get_frequency    = tda8261_get_frequency,
1135     .tuner_set_frequency    = tda8261_set_frequency,
1136     .tuner_set_bandwidth    = NULL,
1137     .tuner_get_bandwidth    = tda8261_get_bandwidth,
1138     .tuner_set_rfsiggain    = NULL
1139 };
1140 
1141 /*
1142  * SD1878/SHA tuner config
1143  * 1F, Single I/P, Horizontal mount, High Sensitivity
1144  */
1145 static const struct tda8261_config sd1878c_config = {
1146 //  .name       = "SD1878/SHA",
1147     .addr       = 0x60,
1148     .step_size  = TDA8261_STEP_1000 /* kHz */
1149 };
1150 
1151 static u8 read_pwm(struct budget_av *budget_av)
1152 {
1153     u8 b = 0xff;
1154     u8 pwm;
1155     struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1156     {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1157     };
1158 
1159     if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1160         || (pwm == 0xff))
1161         pwm = 0x48;
1162 
1163     return pwm;
1164 }
1165 
1166 #define SUBID_DVBS_KNC1         0x0010
1167 #define SUBID_DVBS_KNC1_PLUS        0x0011
1168 #define SUBID_DVBS_TYPHOON      0x4f56
1169 #define SUBID_DVBS_CINERGY1200      0x1154
1170 #define SUBID_DVBS_CYNERGY1200N     0x1155
1171 #define SUBID_DVBS_TV_STAR      0x0014
1172 #define SUBID_DVBS_TV_STAR_PLUS_X4  0x0015
1173 #define SUBID_DVBS_TV_STAR_CI       0x0016
1174 #define SUBID_DVBS2_KNC1        0x0018
1175 #define SUBID_DVBS2_KNC1_OEM        0x0019
1176 #define SUBID_DVBS_EASYWATCH_1      0x001a
1177 #define SUBID_DVBS_EASYWATCH_2      0x001b
1178 #define SUBID_DVBS2_EASYWATCH       0x001d
1179 #define SUBID_DVBS_EASYWATCH        0x001e
1180 
1181 #define SUBID_DVBC_EASYWATCH        0x002a
1182 #define SUBID_DVBC_EASYWATCH_MK3    0x002c
1183 #define SUBID_DVBC_KNC1         0x0020
1184 #define SUBID_DVBC_KNC1_PLUS        0x0021
1185 #define SUBID_DVBC_KNC1_MK3     0x0022
1186 #define SUBID_DVBC_KNC1_TDA10024    0x0028
1187 #define SUBID_DVBC_KNC1_PLUS_MK3    0x0023
1188 #define SUBID_DVBC_CINERGY1200      0x1156
1189 #define SUBID_DVBC_CINERGY1200_MK3  0x1176
1190 
1191 #define SUBID_DVBT_EASYWATCH        0x003a
1192 #define SUBID_DVBT_KNC1_PLUS        0x0031
1193 #define SUBID_DVBT_KNC1         0x0030
1194 #define SUBID_DVBT_CINERGY1200      0x1157
1195 
1196 static void frontend_init(struct budget_av *budget_av)
1197 {
1198     struct saa7146_dev * saa = budget_av->budget.dev;
1199     struct dvb_frontend * fe = NULL;
1200 
1201     /* Enable / PowerON Frontend */
1202     saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
1203 
1204     /* Wait for PowerON */
1205     msleep(100);
1206 
1207     /* additional setup necessary for the PLUS cards */
1208     switch (saa->pci->subsystem_device) {
1209         case SUBID_DVBS_KNC1_PLUS:
1210         case SUBID_DVBC_KNC1_PLUS:
1211         case SUBID_DVBT_KNC1_PLUS:
1212         case SUBID_DVBC_EASYWATCH:
1213         case SUBID_DVBC_KNC1_PLUS_MK3:
1214         case SUBID_DVBS2_KNC1:
1215         case SUBID_DVBS2_KNC1_OEM:
1216         case SUBID_DVBS2_EASYWATCH:
1217             saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1218             break;
1219     }
1220 
1221     switch (saa->pci->subsystem_device) {
1222 
1223     case SUBID_DVBS_KNC1:
1224         /*
1225          * maybe that setting is needed for other dvb-s cards as well,
1226          * but so far it has been only confirmed for this type
1227          */
1228         budget_av->reinitialise_demod = 1;
1229         fallthrough;
1230     case SUBID_DVBS_KNC1_PLUS:
1231     case SUBID_DVBS_EASYWATCH_1:
1232         if (saa->pci->subsystem_vendor == 0x1894) {
1233             fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
1234                          &budget_av->budget.i2c_adap);
1235             if (fe) {
1236                 dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
1237             }
1238         } else {
1239             fe = dvb_attach(stv0299_attach, &typhoon_config,
1240                          &budget_av->budget.i2c_adap);
1241             if (fe) {
1242                 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1243             }
1244         }
1245         break;
1246 
1247     case SUBID_DVBS_TV_STAR:
1248     case SUBID_DVBS_TV_STAR_PLUS_X4:
1249     case SUBID_DVBS_TV_STAR_CI:
1250     case SUBID_DVBS_CYNERGY1200N:
1251     case SUBID_DVBS_EASYWATCH:
1252     case SUBID_DVBS_EASYWATCH_2:
1253         fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
1254                 &budget_av->budget.i2c_adap);
1255         if (fe) {
1256             dvb_attach(dvb_pll_attach, fe, 0x60,
1257                    &budget_av->budget.i2c_adap,
1258                    DVB_PLL_PHILIPS_SD1878_TDA8261);
1259         }
1260         break;
1261 
1262     case SUBID_DVBS_TYPHOON:
1263         fe = dvb_attach(stv0299_attach, &typhoon_config,
1264                     &budget_av->budget.i2c_adap);
1265         if (fe) {
1266             fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1267         }
1268         break;
1269     case SUBID_DVBS2_KNC1:
1270     case SUBID_DVBS2_KNC1_OEM:
1271     case SUBID_DVBS2_EASYWATCH:
1272         budget_av->reinitialise_demod = 1;
1273         if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1274             dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
1275 
1276         break;
1277     case SUBID_DVBS_CINERGY1200:
1278         fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1279                     &budget_av->budget.i2c_adap);
1280         if (fe) {
1281             fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1282         }
1283         break;
1284 
1285     case SUBID_DVBC_KNC1:
1286     case SUBID_DVBC_KNC1_PLUS:
1287     case SUBID_DVBC_CINERGY1200:
1288     case SUBID_DVBC_EASYWATCH:
1289         budget_av->reinitialise_demod = 1;
1290         budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1291         fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1292                      &budget_av->budget.i2c_adap,
1293                      read_pwm(budget_av));
1294         if (fe == NULL)
1295             fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1296                          &budget_av->budget.i2c_adap,
1297                          read_pwm(budget_av));
1298         if (fe) {
1299             fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1300         }
1301         break;
1302 
1303     case SUBID_DVBC_EASYWATCH_MK3:
1304     case SUBID_DVBC_CINERGY1200_MK3:
1305     case SUBID_DVBC_KNC1_MK3:
1306     case SUBID_DVBC_KNC1_TDA10024:
1307     case SUBID_DVBC_KNC1_PLUS_MK3:
1308         budget_av->reinitialise_demod = 1;
1309         budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1310         fe = dvb_attach(tda10023_attach,
1311             &philips_cu1216_tda10023_config,
1312             &budget_av->budget.i2c_adap,
1313             read_pwm(budget_av));
1314         if (fe) {
1315             fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1316         }
1317         break;
1318 
1319     case SUBID_DVBT_EASYWATCH:
1320     case SUBID_DVBT_KNC1:
1321     case SUBID_DVBT_KNC1_PLUS:
1322     case SUBID_DVBT_CINERGY1200:
1323         budget_av->reinitialise_demod = 1;
1324         fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1325                      &budget_av->budget.i2c_adap);
1326         if (fe) {
1327             fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1328             fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1329         }
1330         break;
1331     }
1332 
1333     if (fe == NULL) {
1334         pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1335                saa->pci->vendor,
1336                saa->pci->device,
1337                saa->pci->subsystem_vendor,
1338                saa->pci->subsystem_device);
1339         return;
1340     }
1341 
1342     budget_av->budget.dvb_frontend = fe;
1343 
1344     if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1345                   budget_av->budget.dvb_frontend)) {
1346         pr_err("Frontend registration failed!\n");
1347         dvb_frontend_detach(budget_av->budget.dvb_frontend);
1348         budget_av->budget.dvb_frontend = NULL;
1349     }
1350 }
1351 
1352 
1353 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1354 {
1355     struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1356 
1357     dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1358 
1359     if (*isr & MASK_10)
1360         ttpci_budget_irq10_handler(dev, isr);
1361 }
1362 
1363 static int budget_av_detach(struct saa7146_dev *dev)
1364 {
1365     struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1366     int err;
1367 
1368     dprintk(2, "dev: %p\n", dev);
1369 
1370     if (1 == budget_av->has_saa7113) {
1371         saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1372 
1373         msleep(200);
1374 
1375         saa7146_unregister_device(&budget_av->vd, dev);
1376 
1377         saa7146_vv_release(dev);
1378     }
1379 
1380     if (budget_av->budget.ci_present)
1381         ciintf_deinit(budget_av);
1382 
1383     if (budget_av->budget.dvb_frontend != NULL) {
1384         dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1385         dvb_frontend_detach(budget_av->budget.dvb_frontend);
1386     }
1387     err = ttpci_budget_deinit(&budget_av->budget);
1388 
1389     kfree(budget_av);
1390 
1391     return err;
1392 }
1393 
1394 #define KNC1_INPUTS 2
1395 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1396     { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
1397         V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1398     { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
1399         V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1400 };
1401 
1402 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1403 {
1404     dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index);
1405     if (i->index >= KNC1_INPUTS)
1406         return -EINVAL;
1407     memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1408     return 0;
1409 }
1410 
1411 static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1412 {
1413     struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1414     struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1415 
1416     *i = budget_av->cur_input;
1417 
1418     dprintk(1, "VIDIOC_G_INPUT %d\n", *i);
1419     return 0;
1420 }
1421 
1422 static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
1423 {
1424     struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1425     struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1426 
1427     dprintk(1, "VIDIOC_S_INPUT %d\n", input);
1428     return saa7113_setinput(budget_av, input);
1429 }
1430 
1431 static struct saa7146_ext_vv vv_data;
1432 
1433 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1434 {
1435     struct budget_av *budget_av;
1436     u8 *mac;
1437     int err;
1438 
1439     dprintk(2, "dev: %p\n", dev);
1440 
1441     if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1442         return -ENOMEM;
1443 
1444     budget_av->has_saa7113 = 0;
1445     budget_av->budget.ci_present = 0;
1446 
1447     dev->ext_priv = budget_av;
1448 
1449     err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1450                 adapter_nr);
1451     if (err) {
1452         kfree(budget_av);
1453         return err;
1454     }
1455 
1456     /* knc1 initialization */
1457     saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1458     saa7146_write(dev, DD1_INIT, 0x07000600);
1459     saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1460 
1461     if (saa7113_init(budget_av) == 0) {
1462         budget_av->has_saa7113 = 1;
1463         err = saa7146_vv_init(dev, &vv_data);
1464         if (err != 0) {
1465             /* fixme: proper cleanup here */
1466             ERR("cannot init vv subsystem\n");
1467             return err;
1468         }
1469         vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
1470         vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
1471         vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
1472 
1473         if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) {
1474             /* fixme: proper cleanup here */
1475             ERR("cannot register capture v4l2 device\n");
1476             saa7146_vv_release(dev);
1477             return err;
1478         }
1479 
1480         /* beware: this modifies dev->vv ... */
1481         saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1482                         SAA7146_HPS_SYNC_PORT_A);
1483 
1484         saa7113_setinput(budget_av, 0);
1485     }
1486 
1487     /* fixme: find some sane values here... */
1488     saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1489 
1490     mac = budget_av->budget.dvb_adapter.proposed_mac;
1491     if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1492         pr_err("KNC1-%d: Could not read MAC from KNC1 card\n",
1493                budget_av->budget.dvb_adapter.num);
1494         eth_zero_addr(mac);
1495     } else {
1496         pr_info("KNC1-%d: MAC addr = %pM\n",
1497             budget_av->budget.dvb_adapter.num, mac);
1498     }
1499 
1500     budget_av->budget.dvb_adapter.priv = budget_av;
1501     frontend_init(budget_av);
1502     ciintf_init(budget_av);
1503 
1504     ttpci_budget_init_hooks(&budget_av->budget);
1505 
1506     return 0;
1507 }
1508 
1509 static struct saa7146_standard standard[] = {
1510     {.name = "PAL",.id = V4L2_STD_PAL,
1511      .v_offset = 0x17,.v_field = 288,
1512      .h_offset = 0x14,.h_pixels = 680,
1513      .v_max_out = 576,.h_max_out = 768 },
1514 
1515     {.name = "NTSC",.id = V4L2_STD_NTSC,
1516      .v_offset = 0x16,.v_field = 240,
1517      .h_offset = 0x06,.h_pixels = 708,
1518      .v_max_out = 480,.h_max_out = 640, },
1519 };
1520 
1521 static struct saa7146_ext_vv vv_data = {
1522     .inputs = 2,
1523     .capabilities = 0,  // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1524     .flags = 0,
1525     .stds = &standard[0],
1526     .num_stds = ARRAY_SIZE(standard),
1527 };
1528 
1529 static struct saa7146_extension budget_extension;
1530 
1531 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1532 MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
1533 MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
1534 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1535 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1536 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1537 MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1538 MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1539 MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
1540 MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
1541 MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
1542 MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
1543 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1544 MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
1545 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1546 MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1547 MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024);
1548 MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
1549 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1550 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1551 MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1552 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1553 MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1554 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1555 
1556 static const struct pci_device_id pci_tbl[] = {
1557     MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1558     MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1559     MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1560     MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1561     MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1562     MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1563     MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
1564     MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1565     MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1566     MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
1567     MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
1568     MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1569     MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1570     MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
1571     MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
1572     MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
1573     MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
1574     MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1575     MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1576     MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1577     MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028),
1578     MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1579     MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1580     MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1581     MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1582     MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1583     MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1584     MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1585     MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1586     {
1587      .vendor = 0,
1588     }
1589 };
1590 
1591 MODULE_DEVICE_TABLE(pci, pci_tbl);
1592 
1593 static struct saa7146_extension budget_extension = {
1594     .name = "budget_av",
1595     .flags = SAA7146_USE_I2C_IRQ,
1596 
1597     .pci_tbl = pci_tbl,
1598 
1599     .module = THIS_MODULE,
1600     .attach = budget_av_attach,
1601     .detach = budget_av_detach,
1602 
1603     .irq_mask = MASK_10,
1604     .irq_func = budget_av_irq,
1605 };
1606 
1607 static int __init budget_av_init(void)
1608 {
1609     return saa7146_register_extension(&budget_extension);
1610 }
1611 
1612 static void __exit budget_av_exit(void)
1613 {
1614     saa7146_unregister_extension(&budget_extension);
1615 }
1616 
1617 module_init(budget_av_init);
1618 module_exit(budget_av_exit);
1619 
1620 MODULE_LICENSE("GPL");
1621 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1622 MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");