linux/drivers/media/usb/cx231xx/cx231xx-dvb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 DVB device driver for cx231xx
   4
   5 Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
   6                Based on em28xx driver
   7
   8 */
   9
  10#include "cx231xx.h"
  11#include <linux/kernel.h>
  12#include <linux/slab.h>
  13
  14#include <media/dvbdev.h>
  15#include <media/dmxdev.h>
  16#include <media/dvb_demux.h>
  17#include <media/dvb_net.h>
  18#include <media/dvb_frontend.h>
  19#include <media/v4l2-common.h>
  20#include <media/tuner.h>
  21
  22#include "xc5000.h"
  23#include "s5h1432.h"
  24#include "tda18271.h"
  25#include "s5h1411.h"
  26#include "lgdt3305.h"
  27#include "si2165.h"
  28#include "si2168.h"
  29#include "mb86a20s.h"
  30#include "si2157.h"
  31#include "lgdt3306a.h"
  32#include "r820t.h"
  33#include "mn88473.h"
  34
  35MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
  36MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
  37MODULE_LICENSE("GPL");
  38
  39static unsigned int debug;
  40module_param(debug, int, 0644);
  41MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
  42
  43DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  44
  45#define CX231XX_DVB_NUM_BUFS 5
  46#define CX231XX_DVB_MAX_PACKETSIZE 564
  47#define CX231XX_DVB_MAX_PACKETS 64
  48#define CX231XX_DVB_MAX_FRONTENDS 2
  49
  50struct cx231xx_dvb {
  51        struct dvb_frontend *frontend[CX231XX_DVB_MAX_FRONTENDS];
  52
  53        /* feed count management */
  54        struct mutex lock;
  55        int nfeeds;
  56
  57        /* general boilerplate stuff */
  58        struct dvb_adapter adapter;
  59        struct dvb_demux demux;
  60        struct dmxdev dmxdev;
  61        struct dmx_frontend fe_hw;
  62        struct dmx_frontend fe_mem;
  63        struct dvb_net net;
  64        struct i2c_client *i2c_client_demod[2];
  65        struct i2c_client *i2c_client_tuner;
  66};
  67
  68static struct s5h1432_config dvico_s5h1432_config = {
  69        .output_mode   = S5H1432_SERIAL_OUTPUT,
  70        .gpio          = S5H1432_GPIO_ON,
  71        .qam_if        = S5H1432_IF_4000,
  72        .vsb_if        = S5H1432_IF_4000,
  73        .inversion     = S5H1432_INVERSION_OFF,
  74        .status_mode   = S5H1432_DEMODLOCKING,
  75        .mpeg_timing   = S5H1432_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
  76};
  77
  78static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = {
  79        .dvbt_6   = { .if_freq = 4000, .agc_mode = 3, .std = 4,
  80                      .if_lvl = 1, .rfagc_top = 0x37, },
  81        .dvbt_7   = { .if_freq = 4000, .agc_mode = 3, .std = 5,
  82                      .if_lvl = 1, .rfagc_top = 0x37, },
  83        .dvbt_8   = { .if_freq = 4000, .agc_mode = 3, .std = 6,
  84                      .if_lvl = 1, .rfagc_top = 0x37, },
  85};
  86
  87static struct tda18271_std_map mb86a20s_tda18271_config = {
  88        .dvbt_6   = { .if_freq = 4000, .agc_mode = 3, .std = 4,
  89                      .if_lvl = 0, .rfagc_top = 0x37, },
  90};
  91
  92static struct tda18271_config cnxt_rde253s_tunerconfig = {
  93        .std_map = &cnxt_rde253s_tda18271_std_map,
  94        .gate    = TDA18271_GATE_ANALOG,
  95};
  96
  97static struct s5h1411_config tda18271_s5h1411_config = {
  98        .output_mode   = S5H1411_SERIAL_OUTPUT,
  99        .gpio          = S5H1411_GPIO_OFF,
 100        .vsb_if        = S5H1411_IF_3250,
 101        .qam_if        = S5H1411_IF_4000,
 102        .inversion     = S5H1411_INVERSION_ON,
 103        .status_mode   = S5H1411_DEMODLOCKING,
 104        .mpeg_timing   = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
 105};
 106static struct s5h1411_config xc5000_s5h1411_config = {
 107        .output_mode   = S5H1411_SERIAL_OUTPUT,
 108        .gpio          = S5H1411_GPIO_OFF,
 109        .vsb_if        = S5H1411_IF_3250,
 110        .qam_if        = S5H1411_IF_3250,
 111        .inversion     = S5H1411_INVERSION_OFF,
 112        .status_mode   = S5H1411_DEMODLOCKING,
 113        .mpeg_timing   = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
 114};
 115
 116static struct lgdt3305_config hcw_lgdt3305_config = {
 117        .i2c_addr           = 0x0e,
 118        .mpeg_mode          = LGDT3305_MPEG_SERIAL,
 119        .tpclk_edge         = LGDT3305_TPCLK_FALLING_EDGE,
 120        .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
 121        .deny_i2c_rptr      = 1,
 122        .spectral_inversion = 1,
 123        .qam_if_khz         = 4000,
 124        .vsb_if_khz         = 3250,
 125};
 126
 127static struct tda18271_std_map hauppauge_tda18271_std_map = {
 128        .atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
 129                      .if_lvl = 1, .rfagc_top = 0x58, },
 130        .qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 5,
 131                      .if_lvl = 1, .rfagc_top = 0x58, },
 132};
 133
 134static struct tda18271_config hcw_tda18271_config = {
 135        .std_map = &hauppauge_tda18271_std_map,
 136        .gate    = TDA18271_GATE_DIGITAL,
 137};
 138
 139static const struct mb86a20s_config pv_mb86a20s_config = {
 140        .demod_address = 0x10,
 141        .is_serial = true,
 142};
 143
 144static struct tda18271_config pv_tda18271_config = {
 145        .std_map = &mb86a20s_tda18271_config,
 146        .gate    = TDA18271_GATE_DIGITAL,
 147        .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
 148};
 149
 150static const struct lgdt3306a_config hauppauge_955q_lgdt3306a_config = {
 151        .qam_if_khz         = 4000,
 152        .vsb_if_khz         = 3250,
 153        .spectral_inversion = 1,
 154        .mpeg_mode          = LGDT3306A_MPEG_SERIAL,
 155        .tpclk_edge         = LGDT3306A_TPCLK_RISING_EDGE,
 156        .tpvalid_polarity   = LGDT3306A_TP_VALID_HIGH,
 157        .xtalMHz            = 25,
 158};
 159
 160static struct r820t_config astrometa_t2hybrid_r820t_config = {
 161        .i2c_addr               = 0x3a, /* 0x74 >> 1 */
 162        .xtal                   = 16000000,
 163        .rafael_chip            = CHIP_R828D,
 164        .max_i2c_msg_len        = 2,
 165};
 166
 167static inline void print_err_status(struct cx231xx *dev, int packet, int status)
 168{
 169        char *errmsg = "Unknown";
 170
 171        switch (status) {
 172        case -ENOENT:
 173                errmsg = "unlinked synchronously";
 174                break;
 175        case -ECONNRESET:
 176                errmsg = "unlinked asynchronously";
 177                break;
 178        case -ENOSR:
 179                errmsg = "Buffer error (overrun)";
 180                break;
 181        case -EPIPE:
 182                errmsg = "Stalled (device not responding)";
 183                break;
 184        case -EOVERFLOW:
 185                errmsg = "Babble (bad cable?)";
 186                break;
 187        case -EPROTO:
 188                errmsg = "Bit-stuff error (bad cable?)";
 189                break;
 190        case -EILSEQ:
 191                errmsg = "CRC/Timeout (could be anything)";
 192                break;
 193        case -ETIME:
 194                errmsg = "Device does not respond";
 195                break;
 196        }
 197        if (packet < 0) {
 198                dev_dbg(dev->dev,
 199                        "URB status %d [%s].\n", status, errmsg);
 200        } else {
 201                dev_dbg(dev->dev,
 202                        "URB packet %d, status %d [%s].\n",
 203                        packet, status, errmsg);
 204        }
 205}
 206
 207static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
 208{
 209        int i;
 210
 211        if (!dev)
 212                return 0;
 213
 214        if (dev->state & DEV_DISCONNECTED)
 215                return 0;
 216
 217        if (urb->status < 0) {
 218                print_err_status(dev, -1, urb->status);
 219                if (urb->status == -ENOENT)
 220                        return 0;
 221        }
 222
 223        for (i = 0; i < urb->number_of_packets; i++) {
 224                int status = urb->iso_frame_desc[i].status;
 225
 226                if (status < 0) {
 227                        print_err_status(dev, i, status);
 228                        if (urb->iso_frame_desc[i].status != -EPROTO)
 229                                continue;
 230                }
 231
 232                dvb_dmx_swfilter(&dev->dvb->demux,
 233                                 urb->transfer_buffer +
 234                                urb->iso_frame_desc[i].offset,
 235                                urb->iso_frame_desc[i].actual_length);
 236        }
 237
 238        return 0;
 239}
 240
 241static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb)
 242{
 243        if (!dev)
 244                return 0;
 245
 246        if (dev->state & DEV_DISCONNECTED)
 247                return 0;
 248
 249        if (urb->status < 0) {
 250                print_err_status(dev, -1, urb->status);
 251                if (urb->status == -ENOENT)
 252                        return 0;
 253        }
 254
 255        /* Feed the transport payload into the kernel demux */
 256        dvb_dmx_swfilter(&dev->dvb->demux,
 257                urb->transfer_buffer, urb->actual_length);
 258
 259        return 0;
 260}
 261
 262static int start_streaming(struct cx231xx_dvb *dvb)
 263{
 264        int rc;
 265        struct cx231xx *dev = dvb->adapter.priv;
 266
 267        if (dev->USE_ISO) {
 268                dev_dbg(dev->dev, "DVB transfer mode is ISO.\n");
 269                cx231xx_set_alt_setting(dev, INDEX_TS1, 5);
 270                rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
 271                if (rc < 0)
 272                        return rc;
 273                dev->mode_tv = 1;
 274                return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
 275                                        CX231XX_DVB_NUM_BUFS,
 276                                        dev->ts1_mode.max_pkt_size,
 277                                        dvb_isoc_copy);
 278        } else {
 279                dev_dbg(dev->dev, "DVB transfer mode is BULK.\n");
 280                cx231xx_set_alt_setting(dev, INDEX_TS1, 0);
 281                rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
 282                if (rc < 0)
 283                        return rc;
 284                dev->mode_tv = 1;
 285                return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS,
 286                                        CX231XX_DVB_NUM_BUFS,
 287                                        dev->ts1_mode.max_pkt_size,
 288                                        dvb_bulk_copy);
 289        }
 290
 291}
 292
 293static int stop_streaming(struct cx231xx_dvb *dvb)
 294{
 295        struct cx231xx *dev = dvb->adapter.priv;
 296
 297        if (dev->USE_ISO)
 298                cx231xx_uninit_isoc(dev);
 299        else
 300                cx231xx_uninit_bulk(dev);
 301
 302        cx231xx_set_mode(dev, CX231XX_SUSPEND);
 303
 304        return 0;
 305}
 306
 307static int start_feed(struct dvb_demux_feed *feed)
 308{
 309        struct dvb_demux *demux = feed->demux;
 310        struct cx231xx_dvb *dvb = demux->priv;
 311        int rc, ret;
 312
 313        if (!demux->dmx.frontend)
 314                return -EINVAL;
 315
 316        mutex_lock(&dvb->lock);
 317        dvb->nfeeds++;
 318        rc = dvb->nfeeds;
 319
 320        if (dvb->nfeeds == 1) {
 321                ret = start_streaming(dvb);
 322                if (ret < 0)
 323                        rc = ret;
 324        }
 325
 326        mutex_unlock(&dvb->lock);
 327        return rc;
 328}
 329
 330static int stop_feed(struct dvb_demux_feed *feed)
 331{
 332        struct dvb_demux *demux = feed->demux;
 333        struct cx231xx_dvb *dvb = demux->priv;
 334        int err = 0;
 335
 336        mutex_lock(&dvb->lock);
 337        dvb->nfeeds--;
 338
 339        if (0 == dvb->nfeeds)
 340                err = stop_streaming(dvb);
 341
 342        mutex_unlock(&dvb->lock);
 343        return err;
 344}
 345
 346/* ------------------------------------------------------------------ */
 347static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
 348{
 349        struct cx231xx *dev = fe->dvb->priv;
 350
 351        if (acquire)
 352                return cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
 353        else
 354                return cx231xx_set_mode(dev, CX231XX_SUSPEND);
 355}
 356
 357/* ------------------------------------------------------------------ */
 358
 359static struct xc5000_config cnxt_rde250_tunerconfig = {
 360        .i2c_address = 0x61,
 361        .if_khz = 4000,
 362};
 363static struct xc5000_config cnxt_rdu250_tunerconfig = {
 364        .i2c_address = 0x61,
 365        .if_khz = 3250,
 366};
 367
 368/* ------------------------------------------------------------------ */
 369#if 0
 370static int attach_xc5000(u8 addr, struct cx231xx *dev)
 371{
 372
 373        struct dvb_frontend *fe;
 374        struct xc5000_config cfg;
 375
 376        memset(&cfg, 0, sizeof(cfg));
 377        cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master);
 378        cfg.i2c_addr = addr;
 379
 380        if (!dev->dvb->frontend[0]) {
 381                dev_err(dev->dev, "%s/2: dvb frontend not attached. Can't attach xc5000\n",
 382                        dev->name);
 383                return -EINVAL;
 384        }
 385
 386        fe = dvb_attach(xc5000_attach, dev->dvb->frontend[0], &cfg);
 387        if (!fe) {
 388                dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name);
 389                dvb_frontend_detach(dev->dvb->frontend[0]);
 390                dev->dvb->frontend[0] = NULL;
 391                return -EINVAL;
 392        }
 393
 394        dev_info(dev->dev, "%s/2: xc5000 attached\n", dev->name);
 395
 396        return 0;
 397}
 398#endif
 399
 400int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
 401{
 402        if (dev->dvb && dev->dvb->frontend[0]) {
 403
 404                struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops;
 405
 406                if (dops->set_analog_params != NULL) {
 407                        struct analog_parameters params;
 408
 409                        params.frequency = freq;
 410                        params.std = dev->norm;
 411                        params.mode = 0;        /* 0- Air; 1 - cable */
 412                        /*params.audmode = ;       */
 413
 414                        /* Set the analog parameters to set the frequency */
 415                        dops->set_analog_params(dev->dvb->frontend[0], &params);
 416                }
 417
 418        }
 419
 420        return 0;
 421}
 422
 423int cx231xx_reset_analog_tuner(struct cx231xx *dev)
 424{
 425        int status = 0;
 426
 427        if (dev->dvb && dev->dvb->frontend[0]) {
 428
 429                struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops;
 430
 431                if (dops->init != NULL && !dev->xc_fw_load_done) {
 432
 433                        dev_dbg(dev->dev,
 434                                "Reloading firmware for XC5000\n");
 435                        status = dops->init(dev->dvb->frontend[0]);
 436                        if (status == 0) {
 437                                dev->xc_fw_load_done = 1;
 438                                dev_dbg(dev->dev,
 439                                        "XC5000 firmware download completed\n");
 440                        } else {
 441                                dev->xc_fw_load_done = 0;
 442                                dev_dbg(dev->dev,
 443                                        "XC5000 firmware download failed !!!\n");
 444                        }
 445                }
 446
 447        }
 448
 449        return status;
 450}
 451
 452/* ------------------------------------------------------------------ */
 453
 454static int register_dvb(struct cx231xx_dvb *dvb,
 455                        struct module *module,
 456                        struct cx231xx *dev, struct device *device)
 457{
 458        int result;
 459
 460        mutex_init(&dvb->lock);
 461
 462
 463        /* register adapter */
 464        result = dvb_register_adapter(&dvb->adapter, dev->name, module, device,
 465                                      adapter_nr);
 466        if (result < 0) {
 467                dev_warn(dev->dev,
 468                       "%s: dvb_register_adapter failed (errno = %d)\n",
 469                       dev->name, result);
 470                goto fail_adapter;
 471        }
 472        dvb_register_media_controller(&dvb->adapter, dev->media_dev);
 473
 474        /* Ensure all frontends negotiate bus access */
 475        dvb->frontend[0]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
 476        if (dvb->frontend[1])
 477                dvb->frontend[1]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
 478
 479        dvb->adapter.priv = dev;
 480
 481        /* register frontend */
 482        result = dvb_register_frontend(&dvb->adapter, dvb->frontend[0]);
 483        if (result < 0) {
 484                dev_warn(dev->dev,
 485                       "%s: dvb_register_frontend failed (errno = %d)\n",
 486                       dev->name, result);
 487                goto fail_frontend0;
 488        }
 489
 490        if (dvb->frontend[1]) {
 491                result = dvb_register_frontend(&dvb->adapter, dvb->frontend[1]);
 492                if (result < 0) {
 493                        dev_warn(dev->dev,
 494                                 "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
 495                                dev->name, result);
 496                        goto fail_frontend1;
 497                }
 498
 499                /* MFE lock */
 500                dvb->adapter.mfe_shared = 1;
 501        }
 502
 503        /* register demux stuff */
 504        dvb->demux.dmx.capabilities =
 505            DMX_TS_FILTERING | DMX_SECTION_FILTERING |
 506            DMX_MEMORY_BASED_FILTERING;
 507        dvb->demux.priv = dvb;
 508        dvb->demux.filternum = 256;
 509        dvb->demux.feednum = 256;
 510        dvb->demux.start_feed = start_feed;
 511        dvb->demux.stop_feed = stop_feed;
 512
 513        result = dvb_dmx_init(&dvb->demux);
 514        if (result < 0) {
 515                dev_warn(dev->dev,
 516                         "%s: dvb_dmx_init failed (errno = %d)\n",
 517                       dev->name, result);
 518                goto fail_dmx;
 519        }
 520
 521        dvb->dmxdev.filternum = 256;
 522        dvb->dmxdev.demux = &dvb->demux.dmx;
 523        dvb->dmxdev.capabilities = 0;
 524        result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
 525        if (result < 0) {
 526                dev_warn(dev->dev,
 527                         "%s: dvb_dmxdev_init failed (errno = %d)\n",
 528                         dev->name, result);
 529                goto fail_dmxdev;
 530        }
 531
 532        dvb->fe_hw.source = DMX_FRONTEND_0;
 533        result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 534        if (result < 0) {
 535                dev_warn(dev->dev,
 536                       "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
 537                       dev->name, result);
 538                goto fail_fe_hw;
 539        }
 540
 541        dvb->fe_mem.source = DMX_MEMORY_FE;
 542        result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 543        if (result < 0) {
 544                dev_warn(dev->dev,
 545                         "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
 546                         dev->name, result);
 547                goto fail_fe_mem;
 548        }
 549
 550        result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 551        if (result < 0) {
 552                dev_warn(dev->dev,
 553                         "%s: connect_frontend failed (errno = %d)\n",
 554                         dev->name, result);
 555                goto fail_fe_conn;
 556        }
 557
 558        /* register network adapter */
 559        dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
 560        result = dvb_create_media_graph(&dvb->adapter,
 561                                        dev->tuner_type == TUNER_ABSENT);
 562        if (result < 0)
 563                goto fail_create_graph;
 564
 565        return 0;
 566
 567fail_create_graph:
 568        dvb_net_release(&dvb->net);
 569fail_fe_conn:
 570        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 571fail_fe_mem:
 572        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 573fail_fe_hw:
 574        dvb_dmxdev_release(&dvb->dmxdev);
 575fail_dmxdev:
 576        dvb_dmx_release(&dvb->demux);
 577fail_dmx:
 578        if (dvb->frontend[1])
 579                dvb_unregister_frontend(dvb->frontend[1]);
 580        dvb_unregister_frontend(dvb->frontend[0]);
 581fail_frontend1:
 582        if (dvb->frontend[1])
 583                dvb_frontend_detach(dvb->frontend[1]);
 584fail_frontend0:
 585        dvb_frontend_detach(dvb->frontend[0]);
 586        dvb_unregister_adapter(&dvb->adapter);
 587fail_adapter:
 588        return result;
 589}
 590
 591static void unregister_dvb(struct cx231xx_dvb *dvb)
 592{
 593        dvb_net_release(&dvb->net);
 594        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
 595        dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 596        dvb_dmxdev_release(&dvb->dmxdev);
 597        dvb_dmx_release(&dvb->demux);
 598        if (dvb->frontend[1])
 599                dvb_unregister_frontend(dvb->frontend[1]);
 600        dvb_unregister_frontend(dvb->frontend[0]);
 601        if (dvb->frontend[1])
 602                dvb_frontend_detach(dvb->frontend[1]);
 603        dvb_frontend_detach(dvb->frontend[0]);
 604        dvb_unregister_adapter(&dvb->adapter);
 605
 606        /* remove I2C tuner */
 607        dvb_module_release(dvb->i2c_client_tuner);
 608        dvb->i2c_client_tuner = NULL;
 609        /* remove I2C demod(s) */
 610        dvb_module_release(dvb->i2c_client_demod[1]);
 611        dvb->i2c_client_demod[1] = NULL;
 612        dvb_module_release(dvb->i2c_client_demod[0]);
 613        dvb->i2c_client_demod[0] = NULL;
 614}
 615
 616static int dvb_init(struct cx231xx *dev)
 617{
 618        int result;
 619        struct cx231xx_dvb *dvb;
 620        struct i2c_adapter *tuner_i2c;
 621        struct i2c_adapter *demod_i2c;
 622        struct i2c_client *client;
 623        struct i2c_adapter *adapter;
 624
 625        if (!dev->board.has_dvb) {
 626                /* This device does not support the extension */
 627                return 0;
 628        }
 629
 630        dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL);
 631
 632        if (dvb == NULL) {
 633                dev_info(dev->dev,
 634                         "cx231xx_dvb: memory allocation failed\n");
 635                return -ENOMEM;
 636        }
 637        dev->dvb = dvb;
 638        dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
 639        dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
 640
 641        tuner_i2c = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master);
 642        demod_i2c = cx231xx_get_i2c_adap(dev, dev->board.demod_i2c_master);
 643        mutex_lock(&dev->lock);
 644        cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
 645        cx231xx_demod_reset(dev);
 646        /* init frontend */
 647        switch (dev->model) {
 648        case CX231XX_BOARD_CNXT_CARRAERA:
 649        case CX231XX_BOARD_CNXT_RDE_250:
 650
 651                dev->dvb->frontend[0] = dvb_attach(s5h1432_attach,
 652                                        &dvico_s5h1432_config,
 653                                        demod_i2c);
 654
 655                if (!dev->dvb->frontend[0]) {
 656                        dev_err(dev->dev,
 657                                "Failed to attach s5h1432 front end\n");
 658                        result = -EINVAL;
 659                        goto out_free;
 660                }
 661
 662                /* define general-purpose callback pointer */
 663                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 664
 665                if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0],
 666                               tuner_i2c,
 667                               &cnxt_rde250_tunerconfig)) {
 668                        result = -EINVAL;
 669                        goto out_free;
 670                }
 671
 672                break;
 673        case CX231XX_BOARD_CNXT_SHELBY:
 674        case CX231XX_BOARD_CNXT_RDU_250:
 675
 676                dev->dvb->frontend[0] = dvb_attach(s5h1411_attach,
 677                                               &xc5000_s5h1411_config,
 678                                               demod_i2c);
 679
 680                if (!dev->dvb->frontend[0]) {
 681                        dev_err(dev->dev,
 682                                "Failed to attach s5h1411 front end\n");
 683                        result = -EINVAL;
 684                        goto out_free;
 685                }
 686
 687                /* define general-purpose callback pointer */
 688                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 689
 690                if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0],
 691                               tuner_i2c,
 692                               &cnxt_rdu250_tunerconfig)) {
 693                        result = -EINVAL;
 694                        goto out_free;
 695                }
 696                break;
 697        case CX231XX_BOARD_CNXT_RDE_253S:
 698
 699                dev->dvb->frontend[0] = dvb_attach(s5h1432_attach,
 700                                        &dvico_s5h1432_config,
 701                                        demod_i2c);
 702
 703                if (!dev->dvb->frontend[0]) {
 704                        dev_err(dev->dev,
 705                                "Failed to attach s5h1432 front end\n");
 706                        result = -EINVAL;
 707                        goto out_free;
 708                }
 709
 710                /* define general-purpose callback pointer */
 711                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 712
 713                if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0],
 714                               dev->board.tuner_addr, tuner_i2c,
 715                               &cnxt_rde253s_tunerconfig)) {
 716                        result = -EINVAL;
 717                        goto out_free;
 718                }
 719                break;
 720        case CX231XX_BOARD_CNXT_RDU_253S:
 721        case CX231XX_BOARD_KWORLD_UB445_USB_HYBRID:
 722
 723                dev->dvb->frontend[0] = dvb_attach(s5h1411_attach,
 724                                               &tda18271_s5h1411_config,
 725                                               demod_i2c);
 726
 727                if (!dev->dvb->frontend[0]) {
 728                        dev_err(dev->dev,
 729                                "Failed to attach s5h1411 front end\n");
 730                        result = -EINVAL;
 731                        goto out_free;
 732                }
 733
 734                /* define general-purpose callback pointer */
 735                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 736
 737                if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0],
 738                               dev->board.tuner_addr, tuner_i2c,
 739                               &cnxt_rde253s_tunerconfig)) {
 740                        result = -EINVAL;
 741                        goto out_free;
 742                }
 743                break;
 744        case CX231XX_BOARD_HAUPPAUGE_EXETER:
 745
 746                dev_info(dev->dev,
 747                         "%s: looking for tuner / demod on i2c bus: %d\n",
 748                       __func__, i2c_adapter_id(tuner_i2c));
 749
 750                dev->dvb->frontend[0] = dvb_attach(lgdt3305_attach,
 751                                                &hcw_lgdt3305_config,
 752                                                demod_i2c);
 753
 754                if (!dev->dvb->frontend[0]) {
 755                        dev_err(dev->dev,
 756                                "Failed to attach LG3305 front end\n");
 757                        result = -EINVAL;
 758                        goto out_free;
 759                }
 760
 761                /* define general-purpose callback pointer */
 762                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 763
 764                dvb_attach(tda18271_attach, dev->dvb->frontend[0],
 765                           dev->board.tuner_addr, tuner_i2c,
 766                           &hcw_tda18271_config);
 767                break;
 768
 769        case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
 770        {
 771                struct si2165_platform_data si2165_pdata = {};
 772
 773                /* attach demod */
 774                si2165_pdata.fe = &dev->dvb->frontend[0];
 775                si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
 776                si2165_pdata.ref_freq_hz = 16000000;
 777
 778                /* perform probe/init/attach */
 779                client = dvb_module_probe("si2165", NULL, demod_i2c,
 780                                                dev->board.demod_addr,
 781                                                &si2165_pdata);
 782                if (!client) {
 783                        result = -ENODEV;
 784                        goto out_free;
 785                }
 786                dvb->i2c_client_demod[0] = client;
 787
 788                dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
 789
 790                /* define general-purpose callback pointer */
 791                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 792
 793                dvb_attach(tda18271_attach, dev->dvb->frontend[0],
 794                        dev->board.tuner_addr, tuner_i2c,
 795                        &hcw_tda18271_config);
 796
 797                dev->cx231xx_reset_analog_tuner = NULL;
 798                break;
 799        }
 800        case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx:
 801        {
 802                struct si2165_platform_data si2165_pdata = {};
 803                struct si2157_config si2157_config = {};
 804
 805                /* attach demod */
 806                si2165_pdata.fe = &dev->dvb->frontend[0];
 807                si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT;
 808                si2165_pdata.ref_freq_hz = 24000000;
 809
 810                /* perform probe/init/attach */
 811                client = dvb_module_probe("si2165", NULL, demod_i2c,
 812                                                dev->board.demod_addr,
 813                                                &si2165_pdata);
 814                if (!client) {
 815                        result = -ENODEV;
 816                        goto out_free;
 817                }
 818                dvb->i2c_client_demod[0] = client;
 819
 820                dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
 821
 822                /* define general-purpose callback pointer */
 823                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 824
 825                /* attach tuner */
 826                si2157_config.fe = dev->dvb->frontend[0];
 827#ifdef CONFIG_MEDIA_CONTROLLER_DVB
 828                si2157_config.mdev = dev->media_dev;
 829#endif
 830                si2157_config.if_port = 1;
 831                si2157_config.inversion = true;
 832
 833                /* perform probe/init/attach */
 834                client = dvb_module_probe("si2157", NULL, tuner_i2c,
 835                                                dev->board.tuner_addr,
 836                                                &si2157_config);
 837                if (!client) {
 838                        result = -ENODEV;
 839                        goto out_free;
 840                }
 841                dev->cx231xx_reset_analog_tuner = NULL;
 842
 843                dev->dvb->i2c_client_tuner = client;
 844                break;
 845        }
 846        case CX231XX_BOARD_HAUPPAUGE_955Q:
 847        {
 848                struct si2157_config si2157_config = {};
 849                struct lgdt3306a_config lgdt3306a_config = {};
 850
 851                lgdt3306a_config = hauppauge_955q_lgdt3306a_config;
 852                lgdt3306a_config.fe = &dev->dvb->frontend[0];
 853                lgdt3306a_config.i2c_adapter = &adapter;
 854
 855                /* perform probe/init/attach */
 856                client = dvb_module_probe("lgdt3306a", NULL, demod_i2c,
 857                                                dev->board.demod_addr,
 858                                                &lgdt3306a_config);
 859                if (!client) {
 860                        result = -ENODEV;
 861                        goto out_free;
 862                }
 863                dvb->i2c_client_demod[0] = client;
 864
 865                dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
 866
 867                /* define general-purpose callback pointer */
 868                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 869
 870                /* attach tuner */
 871                si2157_config.fe = dev->dvb->frontend[0];
 872#ifdef CONFIG_MEDIA_CONTROLLER_DVB
 873                si2157_config.mdev = dev->media_dev;
 874#endif
 875                si2157_config.if_port = 1;
 876                si2157_config.inversion = true;
 877
 878                /* perform probe/init/attach */
 879                client = dvb_module_probe("si2157", NULL, tuner_i2c,
 880                                                dev->board.tuner_addr,
 881                                                &si2157_config);
 882                if (!client) {
 883                        result = -ENODEV;
 884                        goto out_free;
 885                }
 886                dev->cx231xx_reset_analog_tuner = NULL;
 887
 888                dev->dvb->i2c_client_tuner = client;
 889                break;
 890        }
 891        case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
 892        case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
 893
 894                dev_info(dev->dev,
 895                         "%s: looking for demod on i2c bus: %d\n",
 896                         __func__, i2c_adapter_id(tuner_i2c));
 897
 898                dev->dvb->frontend[0] = dvb_attach(mb86a20s_attach,
 899                                                &pv_mb86a20s_config,
 900                                                demod_i2c);
 901
 902                if (!dev->dvb->frontend[0]) {
 903                        dev_err(dev->dev,
 904                                "Failed to attach mb86a20s demod\n");
 905                        result = -EINVAL;
 906                        goto out_free;
 907                }
 908
 909                /* define general-purpose callback pointer */
 910                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 911
 912                dvb_attach(tda18271_attach, dev->dvb->frontend[0],
 913                           dev->board.tuner_addr, tuner_i2c,
 914                           &pv_tda18271_config);
 915                break;
 916
 917        case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD:
 918        {
 919                struct si2157_config si2157_config = {};
 920                struct si2168_config si2168_config = {};
 921
 922                /* attach demodulator chip */
 923                si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */
 924                si2168_config.fe = &dev->dvb->frontend[0];
 925                si2168_config.i2c_adapter = &adapter;
 926                si2168_config.ts_clock_inv = true;
 927
 928                /* perform probe/init/attach */
 929                client = dvb_module_probe("si2168", NULL, demod_i2c,
 930                                                dev->board.demod_addr,
 931                                                &si2168_config);
 932                if (!client) {
 933                        result = -ENODEV;
 934                        goto out_free;
 935                }
 936                dvb->i2c_client_demod[0] = client;
 937
 938                /* attach tuner chip */
 939                si2157_config.fe = dev->dvb->frontend[0];
 940#ifdef CONFIG_MEDIA_CONTROLLER_DVB
 941                si2157_config.mdev = dev->media_dev;
 942#endif
 943                si2157_config.if_port = 1;
 944                si2157_config.inversion = false;
 945
 946                /* perform probe/init/attach */
 947                client = dvb_module_probe("si2157", NULL, tuner_i2c,
 948                                                dev->board.tuner_addr,
 949                                                &si2157_config);
 950                if (!client) {
 951                        result = -ENODEV;
 952                        goto out_free;
 953                }
 954                dev->cx231xx_reset_analog_tuner = NULL;
 955                dev->dvb->i2c_client_tuner = client;
 956                break;
 957        }
 958        case CX231XX_BOARD_ASTROMETA_T2HYBRID:
 959        {
 960                struct mn88473_config mn88473_config = {};
 961
 962                /* attach demodulator chip */
 963                mn88473_config.i2c_wr_max = 16;
 964                mn88473_config.xtal = 25000000;
 965                mn88473_config.fe = &dev->dvb->frontend[0];
 966
 967                /* perform probe/init/attach */
 968                client = dvb_module_probe("mn88473", NULL, demod_i2c,
 969                                                dev->board.demod_addr,
 970                                                &mn88473_config);
 971                if (!client) {
 972                        result = -ENODEV;
 973                        goto out_free;
 974                }
 975                dvb->i2c_client_demod[0] = client;
 976
 977                /* define general-purpose callback pointer */
 978                dvb->frontend[0]->callback = cx231xx_tuner_callback;
 979
 980                /* attach tuner chip */
 981                dvb_attach(r820t_attach, dev->dvb->frontend[0],
 982                           tuner_i2c,
 983                           &astrometa_t2hybrid_r820t_config);
 984                break;
 985        }
 986        case CX231XX_BOARD_HAUPPAUGE_935C:
 987        {
 988                struct si2157_config si2157_config = {};
 989                struct si2168_config si2168_config = {};
 990
 991                /* attach demodulator chip */
 992                si2168_config.ts_mode = SI2168_TS_SERIAL;
 993                si2168_config.fe = &dev->dvb->frontend[0];
 994                si2168_config.i2c_adapter = &adapter;
 995                si2168_config.ts_clock_inv = true;
 996
 997                /* perform probe/init/attach */
 998                client = dvb_module_probe("si2168", NULL, demod_i2c,
 999                                                dev->board.demod_addr,
1000                                                &si2168_config);
1001                if (!client) {
1002                        result = -ENODEV;
1003                        goto out_free;
1004                }
1005                dvb->i2c_client_demod[0] = client;
1006                dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
1007
1008                /* define general-purpose callback pointer */
1009                dvb->frontend[0]->callback = cx231xx_tuner_callback;
1010
1011                /* attach tuner */
1012                si2157_config.fe = dev->dvb->frontend[0];
1013#ifdef CONFIG_MEDIA_CONTROLLER_DVB
1014                si2157_config.mdev = dev->media_dev;
1015#endif
1016                si2157_config.if_port = 1;
1017                si2157_config.inversion = true;
1018
1019                /* perform probe/init/attach */
1020                client = dvb_module_probe("si2157", NULL, tuner_i2c,
1021                                                dev->board.tuner_addr,
1022                                                &si2157_config);
1023                if (!client) {
1024                        result = -ENODEV;
1025                        goto out_free;
1026                }
1027                dev->cx231xx_reset_analog_tuner = NULL;
1028                dev->dvb->i2c_client_tuner = client;
1029                break;
1030        }
1031        case CX231XX_BOARD_HAUPPAUGE_975:
1032        {
1033                struct i2c_adapter *adapter2;
1034                struct si2157_config si2157_config = {};
1035                struct lgdt3306a_config lgdt3306a_config = {};
1036                struct si2168_config si2168_config = {};
1037
1038                /* attach first demodulator chip */
1039                lgdt3306a_config = hauppauge_955q_lgdt3306a_config;
1040                lgdt3306a_config.fe = &dev->dvb->frontend[0];
1041                lgdt3306a_config.i2c_adapter = &adapter;
1042
1043                /* perform probe/init/attach */
1044                client = dvb_module_probe("lgdt3306a", NULL, demod_i2c,
1045                                                dev->board.demod_addr,
1046                                                &lgdt3306a_config);
1047                if (!client) {
1048                        result = -ENODEV;
1049                        goto out_free;
1050                }
1051                dvb->i2c_client_demod[0] = client;
1052
1053                /* attach second demodulator chip */
1054                si2168_config.ts_mode = SI2168_TS_SERIAL;
1055                si2168_config.fe = &dev->dvb->frontend[1];
1056                si2168_config.i2c_adapter = &adapter2;
1057                si2168_config.ts_clock_inv = true;
1058
1059                /* perform probe/init/attach */
1060                client = dvb_module_probe("si2168", NULL, adapter,
1061                                                dev->board.demod_addr2,
1062                                                &si2168_config);
1063                if (!client) {
1064                        result = -ENODEV;
1065                        goto out_free;
1066                }
1067                dvb->i2c_client_demod[1] = client;
1068                dvb->frontend[1]->id = 1;
1069
1070                /* define general-purpose callback pointer */
1071                dvb->frontend[0]->callback = cx231xx_tuner_callback;
1072                dvb->frontend[1]->callback = cx231xx_tuner_callback;
1073
1074                /* attach tuner */
1075                si2157_config.fe = dev->dvb->frontend[0];
1076#ifdef CONFIG_MEDIA_CONTROLLER_DVB
1077                si2157_config.mdev = dev->media_dev;
1078#endif
1079                si2157_config.if_port = 1;
1080                si2157_config.inversion = true;
1081
1082                /* perform probe/init/attach */
1083                client = dvb_module_probe("si2157", NULL, adapter,
1084                                                dev->board.tuner_addr,
1085                                                &si2157_config);
1086                if (!client) {
1087                        result = -ENODEV;
1088                        goto out_free;
1089                }
1090                dev->cx231xx_reset_analog_tuner = NULL;
1091                dvb->i2c_client_tuner = client;
1092
1093                dvb->frontend[1]->tuner_priv = dvb->frontend[0]->tuner_priv;
1094
1095                memcpy(&dvb->frontend[1]->ops.tuner_ops,
1096                        &dvb->frontend[0]->ops.tuner_ops,
1097                        sizeof(struct dvb_tuner_ops));
1098                break;
1099        }
1100        default:
1101                dev_err(dev->dev,
1102                        "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1103                        dev->name);
1104                break;
1105        }
1106        if (!dvb->frontend[0]) {
1107                dev_err(dev->dev,
1108                       "%s/2: frontend initialization failed\n", dev->name);
1109                result = -EINVAL;
1110                goto out_free;
1111        }
1112
1113        /* register everything */
1114        result = register_dvb(dvb, THIS_MODULE, dev, dev->dev);
1115
1116        if (result < 0)
1117                goto out_free;
1118
1119
1120        dev_info(dev->dev, "Successfully loaded cx231xx-dvb\n");
1121
1122ret:
1123        cx231xx_set_mode(dev, CX231XX_SUSPEND);
1124        mutex_unlock(&dev->lock);
1125        return result;
1126
1127out_free:
1128        /* remove I2C tuner */
1129        dvb_module_release(dvb->i2c_client_tuner);
1130        dvb->i2c_client_tuner = NULL;
1131        /* remove I2C demod(s) */
1132        dvb_module_release(dvb->i2c_client_demod[1]);
1133        dvb->i2c_client_demod[1] = NULL;
1134        dvb_module_release(dvb->i2c_client_demod[0]);
1135        dvb->i2c_client_demod[0] = NULL;
1136        kfree(dvb);
1137        dev->dvb = NULL;
1138        goto ret;
1139}
1140
1141static int dvb_fini(struct cx231xx *dev)
1142{
1143        if (!dev->board.has_dvb) {
1144                /* This device does not support the extension */
1145                return 0;
1146        }
1147
1148        if (dev->dvb) {
1149                unregister_dvb(dev->dvb);
1150                kfree(dev->dvb);
1151                dev->dvb = NULL;
1152        }
1153
1154        return 0;
1155}
1156
1157static struct cx231xx_ops dvb_ops = {
1158        .id = CX231XX_DVB,
1159        .name = "Cx231xx dvb Extension",
1160        .init = dvb_init,
1161        .fini = dvb_fini,
1162};
1163
1164static int __init cx231xx_dvb_register(void)
1165{
1166        return cx231xx_register_extension(&dvb_ops);
1167}
1168
1169static void __exit cx231xx_dvb_unregister(void)
1170{
1171        cx231xx_unregister_extension(&dvb_ops);
1172}
1173
1174module_init(cx231xx_dvb_register);
1175module_exit(cx231xx_dvb_unregister);
1176