linux/drivers/media/pci/cx88/cx88-dvb.c
<<
>>
Prefs
   1/*
   2 *
   3 * device driver for Conexant 2388x based TV cards
   4 * MPEG Transport Stream (DVB) routines
   5 *
   6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
   7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
   8 *
   9 *  This program is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License as published by
  11 *  the Free Software Foundation; either version 2 of the License, or
  12 *  (at your option) any later version.
  13 *
  14 *  This program is distributed in the hope that it will be useful,
  15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *  GNU General Public License for more details.
  18 *
  19 *  You should have received a copy of the GNU General Public License
  20 *  along with this program; if not, write to the Free Software
  21 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22 */
  23
  24#include <linux/module.h>
  25#include <linux/init.h>
  26#include <linux/device.h>
  27#include <linux/fs.h>
  28#include <linux/kthread.h>
  29#include <linux/file.h>
  30#include <linux/suspend.h>
  31
  32#include "cx88.h"
  33#include "dvb-pll.h"
  34#include <media/v4l2-common.h>
  35
  36#include "mt352.h"
  37#include "mt352_priv.h"
  38#include "cx88-vp3054-i2c.h"
  39#include "zl10353.h"
  40#include "cx22702.h"
  41#include "or51132.h"
  42#include "lgdt330x.h"
  43#include "s5h1409.h"
  44#include "xc4000.h"
  45#include "xc5000.h"
  46#include "nxt200x.h"
  47#include "cx24123.h"
  48#include "isl6421.h"
  49#include "tuner-simple.h"
  50#include "tda9887.h"
  51#include "s5h1411.h"
  52#include "stv0299.h"
  53#include "z0194a.h"
  54#include "stv0288.h"
  55#include "stb6000.h"
  56#include "cx24116.h"
  57#include "stv0900.h"
  58#include "stb6100.h"
  59#include "stb6100_proc.h"
  60#include "mb86a16.h"
  61#include "ts2020.h"
  62#include "ds3000.h"
  63
  64MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
  65MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
  66MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
  67MODULE_LICENSE("GPL");
  68MODULE_VERSION(CX88_VERSION);
  69
  70static unsigned int debug;
  71module_param(debug, int, 0644);
  72MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
  73
  74static unsigned int dvb_buf_tscnt = 32;
  75module_param(dvb_buf_tscnt, int, 0644);
  76MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
  77
  78DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  79
  80#define dprintk(level,fmt, arg...)      if (debug >= level) \
  81        printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
  82
  83/* ------------------------------------------------------------------ */
  84
  85static int dvb_buf_setup(struct videobuf_queue *q,
  86                         unsigned int *count, unsigned int *size)
  87{
  88        struct cx8802_dev *dev = q->priv_data;
  89
  90        dev->ts_packet_size  = 188 * 4;
  91        dev->ts_packet_count = dvb_buf_tscnt;
  92
  93        *size  = dev->ts_packet_size * dev->ts_packet_count;
  94        *count = dvb_buf_tscnt;
  95        return 0;
  96}
  97
  98static int dvb_buf_prepare(struct videobuf_queue *q,
  99                           struct videobuf_buffer *vb, enum v4l2_field field)
 100{
 101        struct cx8802_dev *dev = q->priv_data;
 102        return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
 103}
 104
 105static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
 106{
 107        struct cx8802_dev *dev = q->priv_data;
 108        cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
 109}
 110
 111static void dvb_buf_release(struct videobuf_queue *q,
 112                            struct videobuf_buffer *vb)
 113{
 114        cx88_free_buffer(q, (struct cx88_buffer*)vb);
 115}
 116
 117static const struct videobuf_queue_ops dvb_qops = {
 118        .buf_setup    = dvb_buf_setup,
 119        .buf_prepare  = dvb_buf_prepare,
 120        .buf_queue    = dvb_buf_queue,
 121        .buf_release  = dvb_buf_release,
 122};
 123
 124/* ------------------------------------------------------------------ */
 125
 126static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
 127{
 128        struct cx8802_dev *dev= fe->dvb->priv;
 129        struct cx8802_driver *drv = NULL;
 130        int ret = 0;
 131        int fe_id;
 132
 133        fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
 134        if (!fe_id) {
 135                printk(KERN_ERR "%s() No frontend found\n", __func__);
 136                return -EINVAL;
 137        }
 138
 139        mutex_lock(&dev->core->lock);
 140        drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
 141        if (drv) {
 142                if (acquire){
 143                        dev->frontends.active_fe_id = fe_id;
 144                        ret = drv->request_acquire(drv);
 145                } else {
 146                        ret = drv->request_release(drv);
 147                        dev->frontends.active_fe_id = 0;
 148                }
 149        }
 150        mutex_unlock(&dev->core->lock);
 151
 152        return ret;
 153}
 154
 155static void cx88_dvb_gate_ctrl(struct cx88_core  *core, int open)
 156{
 157        struct videobuf_dvb_frontends *f;
 158        struct videobuf_dvb_frontend *fe;
 159
 160        if (!core->dvbdev)
 161                return;
 162
 163        f = &core->dvbdev->frontends;
 164
 165        if (!f)
 166                return;
 167
 168        if (f->gate <= 1) /* undefined or fe0 */
 169                fe = videobuf_dvb_get_frontend(f, 1);
 170        else
 171                fe = videobuf_dvb_get_frontend(f, f->gate);
 172
 173        if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
 174                fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
 175}
 176
 177/* ------------------------------------------------------------------ */
 178
 179static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
 180{
 181        static const u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
 182        static const u8 reset []         = { RESET,      0x80 };
 183        static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
 184        static const u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
 185        static const u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
 186        static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
 187
 188        mt352_write(fe, clock_config,   sizeof(clock_config));
 189        udelay(200);
 190        mt352_write(fe, reset,          sizeof(reset));
 191        mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
 192
 193        mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
 194        mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
 195        mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
 196        return 0;
 197}
 198
 199static int dvico_dual_demod_init(struct dvb_frontend *fe)
 200{
 201        static const u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
 202        static const u8 reset []         = { RESET,      0x80 };
 203        static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
 204        static const u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
 205        static const u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
 206        static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
 207
 208        mt352_write(fe, clock_config,   sizeof(clock_config));
 209        udelay(200);
 210        mt352_write(fe, reset,          sizeof(reset));
 211        mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
 212
 213        mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
 214        mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
 215        mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
 216
 217        return 0;
 218}
 219
 220static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
 221{
 222        static const u8 clock_config []  = { 0x89, 0x38, 0x39 };
 223        static const u8 reset []         = { 0x50, 0x80 };
 224        static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
 225        static const u8 agc_cfg []       = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
 226                                       0x00, 0xFF, 0x00, 0x40, 0x40 };
 227        static const u8 dntv_extra[]     = { 0xB5, 0x7A };
 228        static const u8 capt_range_cfg[] = { 0x75, 0x32 };
 229
 230        mt352_write(fe, clock_config,   sizeof(clock_config));
 231        udelay(2000);
 232        mt352_write(fe, reset,          sizeof(reset));
 233        mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
 234
 235        mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
 236        udelay(2000);
 237        mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
 238        mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
 239
 240        return 0;
 241}
 242
 243static const struct mt352_config dvico_fusionhdtv = {
 244        .demod_address = 0x0f,
 245        .demod_init    = dvico_fusionhdtv_demod_init,
 246};
 247
 248static const struct mt352_config dntv_live_dvbt_config = {
 249        .demod_address = 0x0f,
 250        .demod_init    = dntv_live_dvbt_demod_init,
 251};
 252
 253static const struct mt352_config dvico_fusionhdtv_dual = {
 254        .demod_address = 0x0f,
 255        .demod_init    = dvico_dual_demod_init,
 256};
 257
 258static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
 259        .demod_address = (0x1e >> 1),
 260        .no_tuner      = 1,
 261        .if2           = 45600,
 262};
 263
 264static struct mb86a16_config twinhan_vp1027 = {
 265        .demod_address  = 0x08,
 266};
 267
 268#if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054)
 269static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
 270{
 271        static const u8 clock_config []  = { 0x89, 0x38, 0x38 };
 272        static const u8 reset []         = { 0x50, 0x80 };
 273        static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
 274        static const u8 agc_cfg []       = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
 275                                       0x00, 0xFF, 0x00, 0x40, 0x40 };
 276        static const u8 dntv_extra[]     = { 0xB5, 0x7A };
 277        static const u8 capt_range_cfg[] = { 0x75, 0x32 };
 278
 279        mt352_write(fe, clock_config,   sizeof(clock_config));
 280        udelay(2000);
 281        mt352_write(fe, reset,          sizeof(reset));
 282        mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
 283
 284        mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
 285        udelay(2000);
 286        mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
 287        mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
 288
 289        return 0;
 290}
 291
 292static const struct mt352_config dntv_live_dvbt_pro_config = {
 293        .demod_address = 0x0f,
 294        .no_tuner      = 1,
 295        .demod_init    = dntv_live_dvbt_pro_demod_init,
 296};
 297#endif
 298
 299static const struct zl10353_config dvico_fusionhdtv_hybrid = {
 300        .demod_address = 0x0f,
 301        .no_tuner      = 1,
 302};
 303
 304static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
 305        .demod_address = 0x0f,
 306        .if2           = 45600,
 307        .no_tuner      = 1,
 308};
 309
 310static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
 311        .demod_address = 0x0f,
 312        .if2 = 4560,
 313        .no_tuner = 1,
 314        .demod_init = dvico_fusionhdtv_demod_init,
 315};
 316
 317static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
 318        .demod_address = 0x0f,
 319};
 320
 321static const struct cx22702_config connexant_refboard_config = {
 322        .demod_address = 0x43,
 323        .output_mode   = CX22702_SERIAL_OUTPUT,
 324};
 325
 326static const struct cx22702_config hauppauge_hvr_config = {
 327        .demod_address = 0x63,
 328        .output_mode   = CX22702_SERIAL_OUTPUT,
 329};
 330
 331static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
 332{
 333        struct cx8802_dev *dev= fe->dvb->priv;
 334        dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
 335        return 0;
 336}
 337
 338static const struct or51132_config pchdtv_hd3000 = {
 339        .demod_address = 0x15,
 340        .set_ts_params = or51132_set_ts_param,
 341};
 342
 343static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
 344{
 345        struct cx8802_dev *dev= fe->dvb->priv;
 346        struct cx88_core *core = dev->core;
 347
 348        dprintk(1, "%s: index = %d\n", __func__, index);
 349        if (index == 0)
 350                cx_clear(MO_GP0_IO, 8);
 351        else
 352                cx_set(MO_GP0_IO, 8);
 353        return 0;
 354}
 355
 356static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
 357{
 358        struct cx8802_dev *dev= fe->dvb->priv;
 359        if (is_punctured)
 360                dev->ts_gen_cntrl |= 0x04;
 361        else
 362                dev->ts_gen_cntrl &= ~0x04;
 363        return 0;
 364}
 365
 366static struct lgdt330x_config fusionhdtv_3_gold = {
 367        .demod_address = 0x0e,
 368        .demod_chip    = LGDT3302,
 369        .serial_mpeg   = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
 370        .set_ts_params = lgdt330x_set_ts_param,
 371};
 372
 373static const struct lgdt330x_config fusionhdtv_5_gold = {
 374        .demod_address = 0x0e,
 375        .demod_chip    = LGDT3303,
 376        .serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
 377        .set_ts_params = lgdt330x_set_ts_param,
 378};
 379
 380static const struct lgdt330x_config pchdtv_hd5500 = {
 381        .demod_address = 0x59,
 382        .demod_chip    = LGDT3303,
 383        .serial_mpeg   = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
 384        .set_ts_params = lgdt330x_set_ts_param,
 385};
 386
 387static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
 388{
 389        struct cx8802_dev *dev= fe->dvb->priv;
 390        dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
 391        return 0;
 392}
 393
 394static const struct nxt200x_config ati_hdtvwonder = {
 395        .demod_address = 0x0a,
 396        .set_ts_params = nxt200x_set_ts_param,
 397};
 398
 399static int cx24123_set_ts_param(struct dvb_frontend* fe,
 400        int is_punctured)
 401{
 402        struct cx8802_dev *dev= fe->dvb->priv;
 403        dev->ts_gen_cntrl = 0x02;
 404        return 0;
 405}
 406
 407static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
 408                                       fe_sec_voltage_t voltage)
 409{
 410        struct cx8802_dev *dev= fe->dvb->priv;
 411        struct cx88_core *core = dev->core;
 412
 413        if (voltage == SEC_VOLTAGE_OFF)
 414                cx_write(MO_GP0_IO, 0x000006fb);
 415        else
 416                cx_write(MO_GP0_IO, 0x000006f9);
 417
 418        if (core->prev_set_voltage)
 419                return core->prev_set_voltage(fe, voltage);
 420        return 0;
 421}
 422
 423static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
 424                                      fe_sec_voltage_t voltage)
 425{
 426        struct cx8802_dev *dev= fe->dvb->priv;
 427        struct cx88_core *core = dev->core;
 428
 429        if (voltage == SEC_VOLTAGE_OFF) {
 430                dprintk(1,"LNB Voltage OFF\n");
 431                cx_write(MO_GP0_IO, 0x0000efff);
 432        }
 433
 434        if (core->prev_set_voltage)
 435                return core->prev_set_voltage(fe, voltage);
 436        return 0;
 437}
 438
 439static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
 440                                      fe_sec_voltage_t voltage)
 441{
 442        struct cx8802_dev *dev= fe->dvb->priv;
 443        struct cx88_core *core = dev->core;
 444
 445        cx_set(MO_GP0_IO, 0x6040);
 446        switch (voltage) {
 447        case SEC_VOLTAGE_13:
 448                cx_clear(MO_GP0_IO, 0x20);
 449                break;
 450        case SEC_VOLTAGE_18:
 451                cx_set(MO_GP0_IO, 0x20);
 452                break;
 453        case SEC_VOLTAGE_OFF:
 454                cx_clear(MO_GP0_IO, 0x20);
 455                break;
 456        }
 457
 458        if (core->prev_set_voltage)
 459                return core->prev_set_voltage(fe, voltage);
 460        return 0;
 461}
 462
 463static int vp1027_set_voltage(struct dvb_frontend *fe,
 464                                    fe_sec_voltage_t voltage)
 465{
 466        struct cx8802_dev *dev = fe->dvb->priv;
 467        struct cx88_core *core = dev->core;
 468
 469        switch (voltage) {
 470        case SEC_VOLTAGE_13:
 471                dprintk(1, "LNB SEC Voltage=13\n");
 472                cx_write(MO_GP0_IO, 0x00001220);
 473                break;
 474        case SEC_VOLTAGE_18:
 475                dprintk(1, "LNB SEC Voltage=18\n");
 476                cx_write(MO_GP0_IO, 0x00001222);
 477                break;
 478        case SEC_VOLTAGE_OFF:
 479                dprintk(1, "LNB Voltage OFF\n");
 480                cx_write(MO_GP0_IO, 0x00001230);
 481                break;
 482        }
 483
 484        if (core->prev_set_voltage)
 485                return core->prev_set_voltage(fe, voltage);
 486        return 0;
 487}
 488
 489static const struct cx24123_config geniatech_dvbs_config = {
 490        .demod_address = 0x55,
 491        .set_ts_params = cx24123_set_ts_param,
 492};
 493
 494static const struct cx24123_config hauppauge_novas_config = {
 495        .demod_address = 0x55,
 496        .set_ts_params = cx24123_set_ts_param,
 497};
 498
 499static const struct cx24123_config kworld_dvbs_100_config = {
 500        .demod_address = 0x15,
 501        .set_ts_params = cx24123_set_ts_param,
 502        .lnb_polarity  = 1,
 503};
 504
 505static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
 506        .demod_address = 0x32 >> 1,
 507        .output_mode   = S5H1409_PARALLEL_OUTPUT,
 508        .gpio          = S5H1409_GPIO_ON,
 509        .qam_if        = 44000,
 510        .inversion     = S5H1409_INVERSION_OFF,
 511        .status_mode   = S5H1409_DEMODLOCKING,
 512        .mpeg_timing   = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
 513};
 514
 515static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
 516        .demod_address = 0x32 >> 1,
 517        .output_mode   = S5H1409_SERIAL_OUTPUT,
 518        .gpio          = S5H1409_GPIO_OFF,
 519        .inversion     = S5H1409_INVERSION_OFF,
 520        .status_mode   = S5H1409_DEMODLOCKING,
 521        .mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
 522};
 523
 524static const struct s5h1409_config kworld_atsc_120_config = {
 525        .demod_address = 0x32 >> 1,
 526        .output_mode   = S5H1409_SERIAL_OUTPUT,
 527        .gpio          = S5H1409_GPIO_OFF,
 528        .inversion     = S5H1409_INVERSION_OFF,
 529        .status_mode   = S5H1409_DEMODLOCKING,
 530        .mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
 531};
 532
 533static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
 534        .i2c_address    = 0x64,
 535        .if_khz         = 5380,
 536};
 537
 538static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
 539        .demod_address = (0x1e >> 1),
 540        .no_tuner      = 1,
 541        .if2           = 45600,
 542};
 543
 544static const struct zl10353_config cx88_geniatech_x8000_mt = {
 545        .demod_address = (0x1e >> 1),
 546        .no_tuner = 1,
 547        .disable_i2c_gate_ctrl = 1,
 548};
 549
 550static const struct s5h1411_config dvico_fusionhdtv7_config = {
 551        .output_mode   = S5H1411_SERIAL_OUTPUT,
 552        .gpio          = S5H1411_GPIO_ON,
 553        .mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
 554        .qam_if        = S5H1411_IF_44000,
 555        .vsb_if        = S5H1411_IF_44000,
 556        .inversion     = S5H1411_INVERSION_OFF,
 557        .status_mode   = S5H1411_DEMODLOCKING
 558};
 559
 560static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
 561        .i2c_address    = 0xc2 >> 1,
 562        .if_khz         = 5380,
 563};
 564
 565static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
 566{
 567        struct dvb_frontend *fe;
 568        struct videobuf_dvb_frontend *fe0 = NULL;
 569        struct xc2028_ctrl ctl;
 570        struct xc2028_config cfg = {
 571                .i2c_adap  = &dev->core->i2c_adap,
 572                .i2c_addr  = addr,
 573                .ctrl      = &ctl,
 574        };
 575
 576        /* Get the first frontend */
 577        fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
 578        if (!fe0)
 579                return -EINVAL;
 580
 581        if (!fe0->dvb.frontend) {
 582                printk(KERN_ERR "%s/2: dvb frontend not attached. "
 583                                "Can't attach xc3028\n",
 584                       dev->core->name);
 585                return -EINVAL;
 586        }
 587
 588        /*
 589         * Some xc3028 devices may be hidden by an I2C gate. This is known
 590         * to happen with some s5h1409-based devices.
 591         * Now that I2C gate is open, sets up xc3028 configuration
 592         */
 593        cx88_setup_xc3028(dev->core, &ctl);
 594
 595        fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
 596        if (!fe) {
 597                printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 598                       dev->core->name);
 599                dvb_frontend_detach(fe0->dvb.frontend);
 600                dvb_unregister_frontend(fe0->dvb.frontend);
 601                fe0->dvb.frontend = NULL;
 602                return -EINVAL;
 603        }
 604
 605        printk(KERN_INFO "%s/2: xc3028 attached\n",
 606               dev->core->name);
 607
 608        return 0;
 609}
 610
 611static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg)
 612{
 613        struct dvb_frontend *fe;
 614        struct videobuf_dvb_frontend *fe0 = NULL;
 615
 616        /* Get the first frontend */
 617        fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
 618        if (!fe0)
 619                return -EINVAL;
 620
 621        if (!fe0->dvb.frontend) {
 622                printk(KERN_ERR "%s/2: dvb frontend not attached. "
 623                                "Can't attach xc4000\n",
 624                       dev->core->name);
 625                return -EINVAL;
 626        }
 627
 628        fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->core->i2c_adap,
 629                        cfg);
 630        if (!fe) {
 631                printk(KERN_ERR "%s/2: xc4000 attach failed\n",
 632                       dev->core->name);
 633                dvb_frontend_detach(fe0->dvb.frontend);
 634                dvb_unregister_frontend(fe0->dvb.frontend);
 635                fe0->dvb.frontend = NULL;
 636                return -EINVAL;
 637        }
 638
 639        printk(KERN_INFO "%s/2: xc4000 attached\n", dev->core->name);
 640
 641        return 0;
 642}
 643
 644static int cx24116_set_ts_param(struct dvb_frontend *fe,
 645        int is_punctured)
 646{
 647        struct cx8802_dev *dev = fe->dvb->priv;
 648        dev->ts_gen_cntrl = 0x2;
 649
 650        return 0;
 651}
 652
 653static int stv0900_set_ts_param(struct dvb_frontend *fe,
 654        int is_punctured)
 655{
 656        struct cx8802_dev *dev = fe->dvb->priv;
 657        dev->ts_gen_cntrl = 0;
 658
 659        return 0;
 660}
 661
 662static int cx24116_reset_device(struct dvb_frontend *fe)
 663{
 664        struct cx8802_dev *dev = fe->dvb->priv;
 665        struct cx88_core *core = dev->core;
 666
 667        /* Reset the part */
 668        /* Put the cx24116 into reset */
 669        cx_write(MO_SRST_IO, 0);
 670        msleep(10);
 671        /* Take the cx24116 out of reset */
 672        cx_write(MO_SRST_IO, 1);
 673        msleep(10);
 674
 675        return 0;
 676}
 677
 678static const struct cx24116_config hauppauge_hvr4000_config = {
 679        .demod_address          = 0x05,
 680        .set_ts_params          = cx24116_set_ts_param,
 681        .reset_device           = cx24116_reset_device,
 682};
 683
 684static const struct cx24116_config tevii_s460_config = {
 685        .demod_address = 0x55,
 686        .set_ts_params = cx24116_set_ts_param,
 687        .reset_device  = cx24116_reset_device,
 688};
 689
 690static int ds3000_set_ts_param(struct dvb_frontend *fe,
 691        int is_punctured)
 692{
 693        struct cx8802_dev *dev = fe->dvb->priv;
 694        dev->ts_gen_cntrl = 4;
 695
 696        return 0;
 697}
 698
 699static struct ds3000_config tevii_ds3000_config = {
 700        .demod_address = 0x68,
 701        .set_ts_params = ds3000_set_ts_param,
 702};
 703
 704static struct ts2020_config tevii_ts2020_config  = {
 705        .tuner_address = 0x60,
 706        .clk_out_div = 1,
 707};
 708
 709static const struct stv0900_config prof_7301_stv0900_config = {
 710        .demod_address = 0x6a,
 711/*      demod_mode = 0,*/
 712        .xtal = 27000000,
 713        .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
 714        .diseqc_mode = 2,/* 2/3 PWM */
 715        .tun1_maddress = 0,/* 0x60 */
 716        .tun1_adc = 0,/* 2 Vpp */
 717        .path1_mode = 3,
 718        .set_ts_params = stv0900_set_ts_param,
 719};
 720
 721static const struct stb6100_config prof_7301_stb6100_config = {
 722        .tuner_address = 0x60,
 723        .refclock = 27000000,
 724};
 725
 726static const struct stv0299_config tevii_tuner_sharp_config = {
 727        .demod_address = 0x68,
 728        .inittab = sharp_z0194a_inittab,
 729        .mclk = 88000000UL,
 730        .invert = 1,
 731        .skip_reinit = 0,
 732        .lock_output = 1,
 733        .volt13_op0_op1 = STV0299_VOLT13_OP1,
 734        .min_delay_ms = 100,
 735        .set_symbol_rate = sharp_z0194a_set_symbol_rate,
 736        .set_ts_params = cx24116_set_ts_param,
 737};
 738
 739static const struct stv0288_config tevii_tuner_earda_config = {
 740        .demod_address = 0x68,
 741        .min_delay_ms = 100,
 742        .set_ts_params = cx24116_set_ts_param,
 743};
 744
 745static int cx8802_alloc_frontends(struct cx8802_dev *dev)
 746{
 747        struct cx88_core *core = dev->core;
 748        struct videobuf_dvb_frontend *fe = NULL;
 749        int i;
 750
 751        mutex_init(&dev->frontends.lock);
 752        INIT_LIST_HEAD(&dev->frontends.felist);
 753
 754        if (!core->board.num_frontends)
 755                return -ENODEV;
 756
 757        printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
 758                         core->board.num_frontends);
 759        for (i = 1; i <= core->board.num_frontends; i++) {
 760                fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
 761                if (!fe) {
 762                        printk(KERN_ERR "%s() failed to alloc\n", __func__);
 763                        videobuf_dvb_dealloc_frontends(&dev->frontends);
 764                        return -ENOMEM;
 765                }
 766        }
 767        return 0;
 768}
 769
 770
 771
 772static const u8 samsung_smt_7020_inittab[] = {
 773             0x01, 0x15,
 774             0x02, 0x00,
 775             0x03, 0x00,
 776             0x04, 0x7D,
 777             0x05, 0x0F,
 778             0x06, 0x02,
 779             0x07, 0x00,
 780             0x08, 0x60,
 781
 782             0x0A, 0xC2,
 783             0x0B, 0x00,
 784             0x0C, 0x01,
 785             0x0D, 0x81,
 786             0x0E, 0x44,
 787             0x0F, 0x09,
 788             0x10, 0x3C,
 789             0x11, 0x84,
 790             0x12, 0xDA,
 791             0x13, 0x99,
 792             0x14, 0x8D,
 793             0x15, 0xCE,
 794             0x16, 0xE8,
 795             0x17, 0x43,
 796             0x18, 0x1C,
 797             0x19, 0x1B,
 798             0x1A, 0x1D,
 799
 800             0x1C, 0x12,
 801             0x1D, 0x00,
 802             0x1E, 0x00,
 803             0x1F, 0x00,
 804             0x20, 0x00,
 805             0x21, 0x00,
 806             0x22, 0x00,
 807             0x23, 0x00,
 808
 809             0x28, 0x02,
 810             0x29, 0x28,
 811             0x2A, 0x14,
 812             0x2B, 0x0F,
 813             0x2C, 0x09,
 814             0x2D, 0x05,
 815
 816             0x31, 0x1F,
 817             0x32, 0x19,
 818             0x33, 0xFC,
 819             0x34, 0x13,
 820             0xff, 0xff,
 821};
 822
 823
 824static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe)
 825{
 826        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 827        struct cx8802_dev *dev = fe->dvb->priv;
 828        u8 buf[4];
 829        u32 div;
 830        struct i2c_msg msg = {
 831                .addr = 0x61,
 832                .flags = 0,
 833                .buf = buf,
 834                .len = sizeof(buf) };
 835
 836        div = c->frequency / 125;
 837
 838        buf[0] = (div >> 8) & 0x7f;
 839        buf[1] = div & 0xff;
 840        buf[2] = 0x84;  /* 0xC4 */
 841        buf[3] = 0x00;
 842
 843        if (c->frequency < 1500000)
 844                buf[3] |= 0x10;
 845
 846        if (fe->ops.i2c_gate_ctrl)
 847                fe->ops.i2c_gate_ctrl(fe, 1);
 848
 849        if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
 850                return -EIO;
 851
 852        return 0;
 853}
 854
 855static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
 856        fe_sec_tone_mode_t tone)
 857{
 858        struct cx8802_dev *dev = fe->dvb->priv;
 859        struct cx88_core *core = dev->core;
 860
 861        cx_set(MO_GP0_IO, 0x0800);
 862
 863        switch (tone) {
 864        case SEC_TONE_ON:
 865                cx_set(MO_GP0_IO, 0x08);
 866                break;
 867        case SEC_TONE_OFF:
 868                cx_clear(MO_GP0_IO, 0x08);
 869                break;
 870        default:
 871                return -EINVAL;
 872        }
 873
 874        return 0;
 875}
 876
 877static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
 878        fe_sec_voltage_t voltage)
 879{
 880        struct cx8802_dev *dev = fe->dvb->priv;
 881        struct cx88_core *core = dev->core;
 882
 883        u8 data;
 884        struct i2c_msg msg = {
 885                .addr = 8,
 886                .flags = 0,
 887                .buf = &data,
 888                .len = sizeof(data) };
 889
 890        cx_set(MO_GP0_IO, 0x8000);
 891
 892        switch (voltage) {
 893        case SEC_VOLTAGE_OFF:
 894                break;
 895        case SEC_VOLTAGE_13:
 896                data = ISL6421_EN1 | ISL6421_LLC1;
 897                cx_clear(MO_GP0_IO, 0x80);
 898                break;
 899        case SEC_VOLTAGE_18:
 900                data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
 901                cx_clear(MO_GP0_IO, 0x80);
 902                break;
 903        default:
 904                return -EINVAL;
 905        }
 906
 907        return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
 908}
 909
 910static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
 911        u32 srate, u32 ratio)
 912{
 913        u8 aclk = 0;
 914        u8 bclk = 0;
 915
 916        if (srate < 1500000) {
 917                aclk = 0xb7;
 918                bclk = 0x47;
 919        } else if (srate < 3000000) {
 920                aclk = 0xb7;
 921                bclk = 0x4b;
 922        } else if (srate < 7000000) {
 923                aclk = 0xb7;
 924                bclk = 0x4f;
 925        } else if (srate < 14000000) {
 926                aclk = 0xb7;
 927                bclk = 0x53;
 928        } else if (srate < 30000000) {
 929                aclk = 0xb6;
 930                bclk = 0x53;
 931        } else if (srate < 45000000) {
 932                aclk = 0xb4;
 933                bclk = 0x51;
 934        }
 935
 936        stv0299_writereg(fe, 0x13, aclk);
 937        stv0299_writereg(fe, 0x14, bclk);
 938        stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 939        stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
 940        stv0299_writereg(fe, 0x21, ratio & 0xf0);
 941
 942        return 0;
 943}
 944
 945
 946static const struct stv0299_config samsung_stv0299_config = {
 947        .demod_address = 0x68,
 948        .inittab = samsung_smt_7020_inittab,
 949        .mclk = 88000000UL,
 950        .invert = 0,
 951        .skip_reinit = 0,
 952        .lock_output = STV0299_LOCKOUTPUT_LK,
 953        .volt13_op0_op1 = STV0299_VOLT13_OP1,
 954        .min_delay_ms = 100,
 955        .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
 956};
 957
 958static int dvb_register(struct cx8802_dev *dev)
 959{
 960        struct cx88_core *core = dev->core;
 961        struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
 962        int mfe_shared = 0; /* bus not shared by default */
 963        int res = -EINVAL;
 964
 965        if (0 != core->i2c_rc) {
 966                printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
 967                goto frontend_detach;
 968        }
 969
 970        /* Get the first frontend */
 971        fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
 972        if (!fe0)
 973                goto frontend_detach;
 974
 975        /* multi-frontend gate control is undefined or defaults to fe0 */
 976        dev->frontends.gate = 0;
 977
 978        /* Sets the gate control callback to be used by i2c command calls */
 979        core->gate_ctrl = cx88_dvb_gate_ctrl;
 980
 981        /* init frontend(s) */
 982        switch (core->boardnr) {
 983        case CX88_BOARD_HAUPPAUGE_DVB_T1:
 984                fe0->dvb.frontend = dvb_attach(cx22702_attach,
 985                                               &connexant_refboard_config,
 986                                               &core->i2c_adap);
 987                if (fe0->dvb.frontend != NULL) {
 988                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
 989                                        0x61, &core->i2c_adap,
 990                                        DVB_PLL_THOMSON_DTT759X))
 991                                goto frontend_detach;
 992                }
 993                break;
 994        case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
 995        case CX88_BOARD_CONEXANT_DVB_T1:
 996        case CX88_BOARD_KWORLD_DVB_T_CX22702:
 997        case CX88_BOARD_WINFAST_DTV1000:
 998                fe0->dvb.frontend = dvb_attach(cx22702_attach,
 999                                               &connexant_refboard_config,
1000                                               &core->i2c_adap);
1001                if (fe0->dvb.frontend != NULL) {
1002                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1003                                        0x60, &core->i2c_adap,
1004                                        DVB_PLL_THOMSON_DTT7579))
1005                                goto frontend_detach;
1006                }
1007                break;
1008        case CX88_BOARD_WINFAST_DTV2000H:
1009        case CX88_BOARD_HAUPPAUGE_HVR1100:
1010        case CX88_BOARD_HAUPPAUGE_HVR1100LP:
1011        case CX88_BOARD_HAUPPAUGE_HVR1300:
1012                fe0->dvb.frontend = dvb_attach(cx22702_attach,
1013                                               &hauppauge_hvr_config,
1014                                               &core->i2c_adap);
1015                if (fe0->dvb.frontend != NULL) {
1016                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1017                                   &core->i2c_adap, 0x61,
1018                                   TUNER_PHILIPS_FMD1216ME_MK3))
1019                                goto frontend_detach;
1020                }
1021                break;
1022        case CX88_BOARD_WINFAST_DTV2000H_J:
1023                fe0->dvb.frontend = dvb_attach(cx22702_attach,
1024                                               &hauppauge_hvr_config,
1025                                               &core->i2c_adap);
1026                if (fe0->dvb.frontend != NULL) {
1027                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1028                                   &core->i2c_adap, 0x61,
1029                                   TUNER_PHILIPS_FMD1216MEX_MK3))
1030                                goto frontend_detach;
1031                }
1032                break;
1033        case CX88_BOARD_HAUPPAUGE_HVR3000:
1034                /* MFE frontend 1 */
1035                mfe_shared = 1;
1036                dev->frontends.gate = 2;
1037                /* DVB-S init */
1038                fe0->dvb.frontend = dvb_attach(cx24123_attach,
1039                                        &hauppauge_novas_config,
1040                                        &dev->core->i2c_adap);
1041                if (fe0->dvb.frontend) {
1042                        if (!dvb_attach(isl6421_attach,
1043                                        fe0->dvb.frontend,
1044                                        &dev->core->i2c_adap,
1045                                        0x08, ISL6421_DCL, 0x00, false))
1046                                goto frontend_detach;
1047                }
1048                /* MFE frontend 2 */
1049                fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1050                if (!fe1)
1051                        goto frontend_detach;
1052                /* DVB-T init */
1053                fe1->dvb.frontend = dvb_attach(cx22702_attach,
1054                                        &hauppauge_hvr_config,
1055                                        &dev->core->i2c_adap);
1056                if (fe1->dvb.frontend) {
1057                        fe1->dvb.frontend->id = 1;
1058                        if (!dvb_attach(simple_tuner_attach,
1059                                        fe1->dvb.frontend,
1060                                        &dev->core->i2c_adap,
1061                                        0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1062                                goto frontend_detach;
1063                }
1064                break;
1065        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
1066                fe0->dvb.frontend = dvb_attach(mt352_attach,
1067                                               &dvico_fusionhdtv,
1068                                               &core->i2c_adap);
1069                if (fe0->dvb.frontend != NULL) {
1070                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1071                                        0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1072                                goto frontend_detach;
1073                        break;
1074                }
1075                /* ZL10353 replaces MT352 on later cards */
1076                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1077                                               &dvico_fusionhdtv_plus_v1_1,
1078                                               &core->i2c_adap);
1079                if (fe0->dvb.frontend != NULL) {
1080                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1081                                        0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1082                                goto frontend_detach;
1083                }
1084                break;
1085        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1086                /* The tin box says DEE1601, but it seems to be DTT7579
1087                 * compatible, with a slightly different MT352 AGC gain. */
1088                fe0->dvb.frontend = dvb_attach(mt352_attach,
1089                                               &dvico_fusionhdtv_dual,
1090                                               &core->i2c_adap);
1091                if (fe0->dvb.frontend != NULL) {
1092                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1093                                        0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1094                                goto frontend_detach;
1095                        break;
1096                }
1097                /* ZL10353 replaces MT352 on later cards */
1098                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1099                                               &dvico_fusionhdtv_plus_v1_1,
1100                                               &core->i2c_adap);
1101                if (fe0->dvb.frontend != NULL) {
1102                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1103                                        0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1104                                goto frontend_detach;
1105                }
1106                break;
1107        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1108                fe0->dvb.frontend = dvb_attach(mt352_attach,
1109                                               &dvico_fusionhdtv,
1110                                               &core->i2c_adap);
1111                if (fe0->dvb.frontend != NULL) {
1112                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1113                                        0x61, NULL, DVB_PLL_LG_Z201))
1114                                goto frontend_detach;
1115                }
1116                break;
1117        case CX88_BOARD_KWORLD_DVB_T:
1118        case CX88_BOARD_DNTV_LIVE_DVB_T:
1119        case CX88_BOARD_ADSTECH_DVB_T_PCI:
1120                fe0->dvb.frontend = dvb_attach(mt352_attach,
1121                                               &dntv_live_dvbt_config,
1122                                               &core->i2c_adap);
1123                if (fe0->dvb.frontend != NULL) {
1124                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
1125                                        0x61, NULL, DVB_PLL_UNKNOWN_1))
1126                                goto frontend_detach;
1127                }
1128                break;
1129        case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
1130#if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054)
1131                /* MT352 is on a secondary I2C bus made from some GPIO lines */
1132                fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
1133                                               &dev->vp3054->adap);
1134                if (fe0->dvb.frontend != NULL) {
1135                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1136                                        &core->i2c_adap, 0x61,
1137                                        TUNER_PHILIPS_FMD1216ME_MK3))
1138                                goto frontend_detach;
1139                }
1140#else
1141                printk(KERN_ERR "%s/2: built without vp3054 support\n",
1142                                core->name);
1143#endif
1144                break;
1145        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1146                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1147                                               &dvico_fusionhdtv_hybrid,
1148                                               &core->i2c_adap);
1149                if (fe0->dvb.frontend != NULL) {
1150                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1151                                   &core->i2c_adap, 0x61,
1152                                   TUNER_THOMSON_FE6600))
1153                                goto frontend_detach;
1154                }
1155                break;
1156        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
1157                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1158                                               &dvico_fusionhdtv_xc3028,
1159                                               &core->i2c_adap);
1160                if (fe0->dvb.frontend == NULL)
1161                        fe0->dvb.frontend = dvb_attach(mt352_attach,
1162                                                &dvico_fusionhdtv_mt352_xc3028,
1163                                                &core->i2c_adap);
1164                /*
1165                 * On this board, the demod provides the I2C bus pullup.
1166                 * We must not permit gate_ctrl to be performed, or
1167                 * the xc3028 cannot communicate on the bus.
1168                 */
1169                if (fe0->dvb.frontend)
1170                        fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1171                if (attach_xc3028(0x61, dev) < 0)
1172                        goto frontend_detach;
1173                break;
1174        case CX88_BOARD_PCHDTV_HD3000:
1175                fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
1176                                               &core->i2c_adap);
1177                if (fe0->dvb.frontend != NULL) {
1178                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1179                                        &core->i2c_adap, 0x61,
1180                                        TUNER_THOMSON_DTT761X))
1181                                goto frontend_detach;
1182                }
1183                break;
1184        case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1185                dev->ts_gen_cntrl = 0x08;
1186
1187                /* Do a hardware reset of chip before using it. */
1188                cx_clear(MO_GP0_IO, 1);
1189                mdelay(100);
1190                cx_set(MO_GP0_IO, 1);
1191                mdelay(200);
1192
1193                /* Select RF connector callback */
1194                fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
1195                fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1196                                               &fusionhdtv_3_gold,
1197                                               &core->i2c_adap);
1198                if (fe0->dvb.frontend != NULL) {
1199                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1200                                        &core->i2c_adap, 0x61,
1201                                        TUNER_MICROTUNE_4042FI5))
1202                                goto frontend_detach;
1203                }
1204                break;
1205        case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
1206                dev->ts_gen_cntrl = 0x08;
1207
1208                /* Do a hardware reset of chip before using it. */
1209                cx_clear(MO_GP0_IO, 1);
1210                mdelay(100);
1211                cx_set(MO_GP0_IO, 9);
1212                mdelay(200);
1213                fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1214                                               &fusionhdtv_3_gold,
1215                                               &core->i2c_adap);
1216                if (fe0->dvb.frontend != NULL) {
1217                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1218                                        &core->i2c_adap, 0x61,
1219                                        TUNER_THOMSON_DTT761X))
1220                                goto frontend_detach;
1221                }
1222                break;
1223        case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1224                dev->ts_gen_cntrl = 0x08;
1225
1226                /* Do a hardware reset of chip before using it. */
1227                cx_clear(MO_GP0_IO, 1);
1228                mdelay(100);
1229                cx_set(MO_GP0_IO, 1);
1230                mdelay(200);
1231                fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1232                                               &fusionhdtv_5_gold,
1233                                               &core->i2c_adap);
1234                if (fe0->dvb.frontend != NULL) {
1235                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1236                                        &core->i2c_adap, 0x61,
1237                                        TUNER_LG_TDVS_H06XF))
1238                                goto frontend_detach;
1239                        if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1240                                   &core->i2c_adap, 0x43))
1241                                goto frontend_detach;
1242                }
1243                break;
1244        case CX88_BOARD_PCHDTV_HD5500:
1245                dev->ts_gen_cntrl = 0x08;
1246
1247                /* Do a hardware reset of chip before using it. */
1248                cx_clear(MO_GP0_IO, 1);
1249                mdelay(100);
1250                cx_set(MO_GP0_IO, 1);
1251                mdelay(200);
1252                fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1253                                               &pchdtv_hd5500,
1254                                               &core->i2c_adap);
1255                if (fe0->dvb.frontend != NULL) {
1256                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1257                                        &core->i2c_adap, 0x61,
1258                                        TUNER_LG_TDVS_H06XF))
1259                                goto frontend_detach;
1260                        if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
1261                                   &core->i2c_adap, 0x43))
1262                                goto frontend_detach;
1263                }
1264                break;
1265        case CX88_BOARD_ATI_HDTVWONDER:
1266                fe0->dvb.frontend = dvb_attach(nxt200x_attach,
1267                                               &ati_hdtvwonder,
1268                                               &core->i2c_adap);
1269                if (fe0->dvb.frontend != NULL) {
1270                        if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1271                                        &core->i2c_adap, 0x61,
1272                                        TUNER_PHILIPS_TUV1236D))
1273                                goto frontend_detach;
1274                }
1275                break;
1276        case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1277        case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1278                fe0->dvb.frontend = dvb_attach(cx24123_attach,
1279                                               &hauppauge_novas_config,
1280                                               &core->i2c_adap);
1281                if (fe0->dvb.frontend) {
1282                        bool override_tone;
1283
1284                        if (core->model == 92001)
1285                                override_tone = true;
1286                        else
1287                                override_tone = false;
1288
1289                        if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1290                                        &core->i2c_adap, 0x08, ISL6421_DCL, 0x00,
1291                                        override_tone))
1292                                goto frontend_detach;
1293                }
1294                break;
1295        case CX88_BOARD_KWORLD_DVBS_100:
1296                fe0->dvb.frontend = dvb_attach(cx24123_attach,
1297                                               &kworld_dvbs_100_config,
1298                                               &core->i2c_adap);
1299                if (fe0->dvb.frontend) {
1300                        core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1301                        fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
1302                }
1303                break;
1304        case CX88_BOARD_GENIATECH_DVBS:
1305                fe0->dvb.frontend = dvb_attach(cx24123_attach,
1306                                               &geniatech_dvbs_config,
1307                                               &core->i2c_adap);
1308                if (fe0->dvb.frontend) {
1309                        core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1310                        fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
1311                }
1312                break;
1313        case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1314                fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1315                                               &pinnacle_pctv_hd_800i_config,
1316                                               &core->i2c_adap);
1317                if (fe0->dvb.frontend != NULL) {
1318                        if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1319                                        &core->i2c_adap,
1320                                        &pinnacle_pctv_hd_800i_tuner_config))
1321                                goto frontend_detach;
1322                }
1323                break;
1324        case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
1325                fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1326                                                &dvico_hdtv5_pci_nano_config,
1327                                                &core->i2c_adap);
1328                if (fe0->dvb.frontend != NULL) {
1329                        struct dvb_frontend *fe;
1330                        struct xc2028_config cfg = {
1331                                .i2c_adap  = &core->i2c_adap,
1332                                .i2c_addr  = 0x61,
1333                        };
1334                        static struct xc2028_ctrl ctl = {
1335                                .fname       = XC2028_DEFAULT_FIRMWARE,
1336                                .max_len     = 64,
1337                                .scode_table = XC3028_FE_OREN538,
1338                        };
1339
1340                        fe = dvb_attach(xc2028_attach,
1341                                        fe0->dvb.frontend, &cfg);
1342                        if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1343                                fe->ops.tuner_ops.set_config(fe, &ctl);
1344                }
1345                break;
1346        case CX88_BOARD_PINNACLE_HYBRID_PCTV:
1347        case CX88_BOARD_WINFAST_DTV1800H:
1348                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1349                                               &cx88_pinnacle_hybrid_pctv,
1350                                               &core->i2c_adap);
1351                if (fe0->dvb.frontend) {
1352                        fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1353                        if (attach_xc3028(0x61, dev) < 0)
1354                                goto frontend_detach;
1355                }
1356                break;
1357        case CX88_BOARD_WINFAST_DTV1800H_XC4000:
1358        case CX88_BOARD_WINFAST_DTV2000H_PLUS:
1359                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1360                                               &cx88_pinnacle_hybrid_pctv,
1361                                               &core->i2c_adap);
1362                if (fe0->dvb.frontend) {
1363                        struct xc4000_config cfg = {
1364                                .i2c_address      = 0x61,
1365                                .default_pm       = 0,
1366                                .dvb_amplitude    = 134,
1367                                .set_smoothedcvbs = 1,
1368                                .if_khz           = 4560
1369                        };
1370                        fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1371                        if (attach_xc4000(dev, &cfg) < 0)
1372                                goto frontend_detach;
1373                }
1374                break;
1375        case CX88_BOARD_GENIATECH_X8000_MT:
1376                dev->ts_gen_cntrl = 0x00;
1377
1378                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1379                                               &cx88_geniatech_x8000_mt,
1380                                               &core->i2c_adap);
1381                if (attach_xc3028(0x61, dev) < 0)
1382                        goto frontend_detach;
1383                break;
1384         case CX88_BOARD_KWORLD_ATSC_120:
1385                fe0->dvb.frontend = dvb_attach(s5h1409_attach,
1386                                               &kworld_atsc_120_config,
1387                                               &core->i2c_adap);
1388                if (attach_xc3028(0x61, dev) < 0)
1389                        goto frontend_detach;
1390                break;
1391        case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
1392                fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1393                                               &dvico_fusionhdtv7_config,
1394                                               &core->i2c_adap);
1395                if (fe0->dvb.frontend != NULL) {
1396                        if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
1397                                        &core->i2c_adap,
1398                                        &dvico_fusionhdtv7_tuner_config))
1399                                goto frontend_detach;
1400                }
1401                break;
1402        case CX88_BOARD_HAUPPAUGE_HVR4000:
1403                /* MFE frontend 1 */
1404                mfe_shared = 1;
1405                dev->frontends.gate = 2;
1406                /* DVB-S/S2 Init */
1407                fe0->dvb.frontend = dvb_attach(cx24116_attach,
1408                                        &hauppauge_hvr4000_config,
1409                                        &dev->core->i2c_adap);
1410                if (fe0->dvb.frontend) {
1411                        if (!dvb_attach(isl6421_attach,
1412                                        fe0->dvb.frontend,
1413                                        &dev->core->i2c_adap,
1414                                        0x08, ISL6421_DCL, 0x00, false))
1415                                goto frontend_detach;
1416                }
1417                /* MFE frontend 2 */
1418                fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1419                if (!fe1)
1420                        goto frontend_detach;
1421                /* DVB-T Init */
1422                fe1->dvb.frontend = dvb_attach(cx22702_attach,
1423                                        &hauppauge_hvr_config,
1424                                        &dev->core->i2c_adap);
1425                if (fe1->dvb.frontend) {
1426                        fe1->dvb.frontend->id = 1;
1427                        if (!dvb_attach(simple_tuner_attach,
1428                                        fe1->dvb.frontend,
1429                                        &dev->core->i2c_adap,
1430                                        0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1431                                goto frontend_detach;
1432                }
1433                break;
1434        case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1435                fe0->dvb.frontend = dvb_attach(cx24116_attach,
1436                                        &hauppauge_hvr4000_config,
1437                                        &dev->core->i2c_adap);
1438                if (fe0->dvb.frontend) {
1439                        if (!dvb_attach(isl6421_attach,
1440                                        fe0->dvb.frontend,
1441                                        &dev->core->i2c_adap,
1442                                        0x08, ISL6421_DCL, 0x00, false))
1443                                goto frontend_detach;
1444                }
1445                break;
1446        case CX88_BOARD_PROF_6200:
1447        case CX88_BOARD_TBS_8910:
1448        case CX88_BOARD_TEVII_S420:
1449                fe0->dvb.frontend = dvb_attach(stv0299_attach,
1450                                                &tevii_tuner_sharp_config,
1451                                                &core->i2c_adap);
1452                if (fe0->dvb.frontend != NULL) {
1453                        if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1454                                        &core->i2c_adap, DVB_PLL_OPERA1))
1455                                goto frontend_detach;
1456                        core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1457                        fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1458
1459                } else {
1460                        fe0->dvb.frontend = dvb_attach(stv0288_attach,
1461                                                            &tevii_tuner_earda_config,
1462                                                            &core->i2c_adap);
1463                                if (fe0->dvb.frontend != NULL) {
1464                                        if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
1465                                                &core->i2c_adap))
1466                                        goto frontend_detach;
1467                                core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1468                                fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1469                        }
1470                }
1471                break;
1472        case CX88_BOARD_TEVII_S460:
1473                fe0->dvb.frontend = dvb_attach(cx24116_attach,
1474                                               &tevii_s460_config,
1475                                               &core->i2c_adap);
1476                if (fe0->dvb.frontend != NULL)
1477                        fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1478                break;
1479        case CX88_BOARD_TEVII_S464:
1480                fe0->dvb.frontend = dvb_attach(ds3000_attach,
1481                                                &tevii_ds3000_config,
1482                                                &core->i2c_adap);
1483                if (fe0->dvb.frontend != NULL) {
1484                        dvb_attach(ts2020_attach, fe0->dvb.frontend,
1485                                &tevii_ts2020_config, &core->i2c_adap);
1486                        fe0->dvb.frontend->ops.set_voltage =
1487                                                        tevii_dvbs_set_voltage;
1488                }
1489                break;
1490        case CX88_BOARD_OMICOM_SS4_PCI:
1491        case CX88_BOARD_TBS_8920:
1492        case CX88_BOARD_PROF_7300:
1493        case CX88_BOARD_SATTRADE_ST4200:
1494                fe0->dvb.frontend = dvb_attach(cx24116_attach,
1495                                               &hauppauge_hvr4000_config,
1496                                               &core->i2c_adap);
1497                if (fe0->dvb.frontend != NULL)
1498                        fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1499                break;
1500        case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
1501                fe0->dvb.frontend = dvb_attach(zl10353_attach,
1502                                               &cx88_terratec_cinergy_ht_pci_mkii_config,
1503                                               &core->i2c_adap);
1504                if (fe0->dvb.frontend) {
1505                        fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1506                        if (attach_xc3028(0x61, dev) < 0)
1507                                goto frontend_detach;
1508                }
1509                break;
1510        case CX88_BOARD_PROF_7301:{
1511                struct dvb_tuner_ops *tuner_ops = NULL;
1512
1513                fe0->dvb.frontend = dvb_attach(stv0900_attach,
1514                                                &prof_7301_stv0900_config,
1515                                                &core->i2c_adap, 0);
1516                if (fe0->dvb.frontend != NULL) {
1517                        if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1518                                        &prof_7301_stb6100_config,
1519                                        &core->i2c_adap))
1520                                goto frontend_detach;
1521
1522                        tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1523                        tuner_ops->set_frequency = stb6100_set_freq;
1524                        tuner_ops->get_frequency = stb6100_get_freq;
1525                        tuner_ops->set_bandwidth = stb6100_set_bandw;
1526                        tuner_ops->get_bandwidth = stb6100_get_bandw;
1527
1528                        core->prev_set_voltage =
1529                                        fe0->dvb.frontend->ops.set_voltage;
1530                        fe0->dvb.frontend->ops.set_voltage =
1531                                        tevii_dvbs_set_voltage;
1532                }
1533                break;
1534                }
1535        case CX88_BOARD_SAMSUNG_SMT_7020:
1536                dev->ts_gen_cntrl = 0x08;
1537
1538                cx_set(MO_GP0_IO, 0x0101);
1539
1540                cx_clear(MO_GP0_IO, 0x01);
1541                mdelay(100);
1542                cx_set(MO_GP0_IO, 0x01);
1543                mdelay(200);
1544
1545                fe0->dvb.frontend = dvb_attach(stv0299_attach,
1546                                        &samsung_stv0299_config,
1547                                        &dev->core->i2c_adap);
1548                if (fe0->dvb.frontend) {
1549                        fe0->dvb.frontend->ops.tuner_ops.set_params =
1550                                samsung_smt_7020_tuner_set_params;
1551                        fe0->dvb.frontend->tuner_priv =
1552                                &dev->core->i2c_adap;
1553                        fe0->dvb.frontend->ops.set_voltage =
1554                                samsung_smt_7020_set_voltage;
1555                        fe0->dvb.frontend->ops.set_tone =
1556                                samsung_smt_7020_set_tone;
1557                }
1558
1559                break;
1560        case CX88_BOARD_TWINHAN_VP1027_DVBS:
1561                dev->ts_gen_cntrl = 0x00;
1562                fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1563                                                &twinhan_vp1027,
1564                                                &core->i2c_adap);
1565                if (fe0->dvb.frontend) {
1566                        core->prev_set_voltage =
1567                                        fe0->dvb.frontend->ops.set_voltage;
1568                        fe0->dvb.frontend->ops.set_voltage =
1569                                        vp1027_set_voltage;
1570                }
1571                break;
1572
1573        default:
1574                printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1575                       core->name);
1576                break;
1577        }
1578
1579        if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
1580                printk(KERN_ERR
1581                       "%s/2: frontend initialization failed\n",
1582                       core->name);
1583                goto frontend_detach;
1584        }
1585        /* define general-purpose callback pointer */
1586        fe0->dvb.frontend->callback = cx88_tuner_callback;
1587
1588        /* Ensure all frontends negotiate bus access */
1589        fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1590        if (fe1)
1591                fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1592
1593        /* Put the analog decoder in standby to keep it quiet */
1594        call_all(core, core, s_power, 0);
1595
1596        /* register everything */
1597        res = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1598                &dev->pci->dev, adapter_nr, mfe_shared);
1599        if (res)
1600                goto frontend_detach;
1601        return res;
1602
1603frontend_detach:
1604        core->gate_ctrl = NULL;
1605        videobuf_dvb_dealloc_frontends(&dev->frontends);
1606        return res;
1607}
1608
1609/* ----------------------------------------------------------- */
1610
1611/* CX8802 MPEG -> mini driver - We have been given the hardware */
1612static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1613{
1614        struct cx88_core *core = drv->core;
1615        int err = 0;
1616        dprintk( 1, "%s\n", __func__);
1617
1618        switch (core->boardnr) {
1619        case CX88_BOARD_HAUPPAUGE_HVR1300:
1620                /* We arrive here with either the cx23416 or the cx22702
1621                 * on the bus. Take the bus from the cx23416 and enable the
1622                 * cx22702 demod
1623                 */
1624                /* Toggle reset on cx22702 leaving i2c active */
1625                cx_set(MO_GP0_IO, 0x00000080);
1626                udelay(1000);
1627                cx_clear(MO_GP0_IO, 0x00000080);
1628                udelay(50);
1629                cx_set(MO_GP0_IO, 0x00000080);
1630                udelay(1000);
1631                /* enable the cx22702 pins */
1632                cx_clear(MO_GP0_IO, 0x00000004);
1633                udelay(1000);
1634                break;
1635
1636        case CX88_BOARD_HAUPPAUGE_HVR3000:
1637        case CX88_BOARD_HAUPPAUGE_HVR4000:
1638                /* Toggle reset on cx22702 leaving i2c active */
1639                cx_set(MO_GP0_IO, 0x00000080);
1640                udelay(1000);
1641                cx_clear(MO_GP0_IO, 0x00000080);
1642                udelay(50);
1643                cx_set(MO_GP0_IO, 0x00000080);
1644                udelay(1000);
1645                switch (core->dvbdev->frontends.active_fe_id) {
1646                case 1: /* DVB-S/S2 Enabled */
1647                        /* tri-state the cx22702 pins */
1648                        cx_set(MO_GP0_IO, 0x00000004);
1649                        /* Take the cx24116/cx24123 out of reset */
1650                        cx_write(MO_SRST_IO, 1);
1651                        core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1652                        break;
1653                case 2: /* DVB-T Enabled */
1654                        /* Put the cx24116/cx24123 into reset */
1655                        cx_write(MO_SRST_IO, 0);
1656                        /* enable the cx22702 pins */
1657                        cx_clear(MO_GP0_IO, 0x00000004);
1658                        core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1659                        break;
1660                }
1661                udelay(1000);
1662                break;
1663
1664        case CX88_BOARD_WINFAST_DTV2000H_PLUS:
1665                /* set RF input to AIR for DVB-T (GPIO 16) */
1666                cx_write(MO_GP2_IO, 0x0101);
1667                break;
1668
1669        default:
1670                err = -ENODEV;
1671        }
1672        return err;
1673}
1674
1675/* CX8802 MPEG -> mini driver - We no longer have the hardware */
1676static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1677{
1678        struct cx88_core *core = drv->core;
1679        int err = 0;
1680        dprintk( 1, "%s\n", __func__);
1681
1682        switch (core->boardnr) {
1683        case CX88_BOARD_HAUPPAUGE_HVR1300:
1684                /* Do Nothing, leave the cx22702 on the bus. */
1685                break;
1686        case CX88_BOARD_HAUPPAUGE_HVR3000:
1687        case CX88_BOARD_HAUPPAUGE_HVR4000:
1688                break;
1689        default:
1690                err = -ENODEV;
1691        }
1692        return err;
1693}
1694
1695static int cx8802_dvb_probe(struct cx8802_driver *drv)
1696{
1697        struct cx88_core *core = drv->core;
1698        struct cx8802_dev *dev = drv->core->dvbdev;
1699        int err;
1700        struct videobuf_dvb_frontend *fe;
1701        int i;
1702
1703        dprintk( 1, "%s\n", __func__);
1704        dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1705                core->boardnr,
1706                core->name,
1707                core->pci_bus,
1708                core->pci_slot);
1709
1710        err = -ENODEV;
1711        if (!(core->board.mpeg & CX88_MPEG_DVB))
1712                goto fail_core;
1713
1714        /* If vp3054 isn't enabled, a stub will just return 0 */
1715        err = vp3054_i2c_probe(dev);
1716        if (0 != err)
1717                goto fail_core;
1718
1719        /* dvb stuff */
1720        printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1721        dev->ts_gen_cntrl = 0x0c;
1722
1723        err = cx8802_alloc_frontends(dev);
1724        if (err)
1725                goto fail_core;
1726
1727        err = -ENODEV;
1728        for (i = 1; i <= core->board.num_frontends; i++) {
1729                fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1730                if (fe == NULL) {
1731                        printk(KERN_ERR "%s() failed to get frontend(%d)\n",
1732                                        __func__, i);
1733                        goto fail_probe;
1734                }
1735                videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1736                                    &dev->pci->dev, &dev->slock,
1737                                    V4L2_BUF_TYPE_VIDEO_CAPTURE,
1738                                    V4L2_FIELD_TOP,
1739                                    sizeof(struct cx88_buffer),
1740                                    dev, NULL);
1741                /* init struct videobuf_dvb */
1742                fe->dvb.name = dev->core->name;
1743        }
1744
1745        err = dvb_register(dev);
1746        if (err)
1747                /* frontends/adapter de-allocated in dvb_register */
1748                printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1749                       core->name, err);
1750        return err;
1751fail_probe:
1752        videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
1753fail_core:
1754        return err;
1755}
1756
1757static int cx8802_dvb_remove(struct cx8802_driver *drv)
1758{
1759        struct cx88_core *core = drv->core;
1760        struct cx8802_dev *dev = drv->core->dvbdev;
1761
1762        dprintk( 1, "%s\n", __func__);
1763
1764        videobuf_dvb_unregister_bus(&dev->frontends);
1765
1766        vp3054_i2c_remove(dev);
1767
1768        core->gate_ctrl = NULL;
1769
1770        return 0;
1771}
1772
1773static struct cx8802_driver cx8802_dvb_driver = {
1774        .type_id        = CX88_MPEG_DVB,
1775        .hw_access      = CX8802_DRVCTL_SHARED,
1776        .probe          = cx8802_dvb_probe,
1777        .remove         = cx8802_dvb_remove,
1778        .advise_acquire = cx8802_dvb_advise_acquire,
1779        .advise_release = cx8802_dvb_advise_release,
1780};
1781
1782static int __init dvb_init(void)
1783{
1784        printk(KERN_INFO "cx88/2: cx2388x dvb driver version %s loaded\n",
1785               CX88_VERSION);
1786        return cx8802_register_driver(&cx8802_dvb_driver);
1787}
1788
1789static void __exit dvb_fini(void)
1790{
1791        cx8802_unregister_driver(&cx8802_dvb_driver);
1792}
1793
1794module_init(dvb_init);
1795module_exit(dvb_fini);
1796