root/drivers/media/usb/dvb-usb/dibusb-mb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dib3000mb_i2c_gate_ctrl
  2. dibusb_dib3000mb_frontend_attach
  3. dibusb_thomson_tuner_attach
  4. dibusb_panasonic_tuner_attach
  5. dibusb_tuner_probe_and_attach
  6. dibusb_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* DVB USB compliant linux driver for mobile DVB-T USB devices based on
   3  * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
   4  *
   5  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
   6  *
   7  * based on GPL code from DiBcom, which has
   8  * Copyright (C) 2004 Amaury Demol for DiBcom
   9  *
  10  * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
  11  */
  12 #include "dibusb.h"
  13 
  14 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  15 
  16 static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
  17 {
  18         struct dvb_usb_adapter *adap = fe->dvb->priv;
  19         struct dibusb_state *st = adap->priv;
  20 
  21         return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr);
  22 }
  23 
  24 static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
  25 {
  26         struct dib3000_config demod_cfg;
  27         struct dibusb_state *st = adap->priv;
  28 
  29         demod_cfg.demod_address = 0x8;
  30 
  31         adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg,
  32                                          &adap->dev->i2c_adap, &st->ops);
  33         if ((adap->fe_adap[0].fe) == NULL)
  34                 return -ENODEV;
  35 
  36         adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;
  37 
  38         return 0;
  39 }
  40 
  41 static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
  42 {
  43         struct dibusb_state *st = adap->priv;
  44 
  45         st->tuner_addr = 0x61;
  46 
  47         dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap,
  48                    DVB_PLL_TUA6010XS);
  49         return 0;
  50 }
  51 
  52 static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)
  53 {
  54         struct dibusb_state *st = adap->priv;
  55 
  56         st->tuner_addr = 0x60;
  57 
  58         dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap,
  59                    DVB_PLL_TDA665X);
  60         return 0;
  61 }
  62 
  63 /* Some of the Artec 1.1 device aren't equipped with the default tuner
  64  * (Thomson Cable), but with a Panasonic ENV77H11D5.  This function figures
  65  * this out. */
  66 static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
  67 {
  68         u8 b[2] = { 0,0 }, b2[1];
  69         int ret = 0;
  70         struct i2c_msg msg[2] = {
  71                 { .flags = 0,        .buf = b,  .len = 2 },
  72                 { .flags = I2C_M_RD, .buf = b2, .len = 1 },
  73         };
  74         struct dibusb_state *st = adap->priv;
  75 
  76         /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
  77         msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;
  78 
  79         if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
  80                 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
  81 
  82         if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
  83                 err("tuner i2c write failed.");
  84                 ret = -EREMOTEIO;
  85         }
  86 
  87         if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
  88                 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
  89 
  90         if (b2[0] == 0xfe) {
  91                 info("This device has the Thomson Cable onboard. Which is default.");
  92                 ret = dibusb_thomson_tuner_attach(adap);
  93         } else {
  94                 info("This device has the Panasonic ENV77H11D5 onboard.");
  95                 ret = dibusb_panasonic_tuner_attach(adap);
  96         }
  97 
  98         return ret;
  99 }
 100 
 101 /* USB Driver stuff */
 102 static struct dvb_usb_device_properties dibusb1_1_properties;
 103 static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
 104 static struct dvb_usb_device_properties dibusb2_0b_properties;
 105 static struct dvb_usb_device_properties artec_t1_usb2_properties;
 106 
 107 static int dibusb_probe(struct usb_interface *intf,
 108                 const struct usb_device_id *id)
 109 {
 110         if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
 111                                      THIS_MODULE, NULL, adapter_nr) ||
 112             0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
 113                                      THIS_MODULE, NULL, adapter_nr) ||
 114             0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
 115                                      THIS_MODULE, NULL, adapter_nr) ||
 116             0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
 117                                      THIS_MODULE, NULL, adapter_nr))
 118                 return 0;
 119 
 120         return -EINVAL;
 121 }
 122 
 123 /* do not change the order of the ID table */
 124 static struct usb_device_id dibusb_dib3000mb_table [] = {
 125 /* 00 */        { USB_DEVICE(USB_VID_WIDEVIEW,          USB_PID_AVERMEDIA_DVBT_USB_COLD) },
 126 /* 01 */        { USB_DEVICE(USB_VID_WIDEVIEW,          USB_PID_AVERMEDIA_DVBT_USB_WARM) },
 127 /* 02 */        { USB_DEVICE(USB_VID_COMPRO,            USB_PID_COMPRO_DVBU2000_COLD) },
 128 /* 03 */        { USB_DEVICE(USB_VID_COMPRO,            USB_PID_COMPRO_DVBU2000_WARM) },
 129 /* 04 */        { USB_DEVICE(USB_VID_COMPRO_UNK,        USB_PID_COMPRO_DVBU2000_UNK_COLD) },
 130 /* 05 */        { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3000_COLD) },
 131 /* 06 */        { USB_DEVICE(USB_VID_DIBCOM,            USB_PID_DIBCOM_MOD3000_WARM) },
 132 /* 07 */        { USB_DEVICE(USB_VID_EMPIA,             USB_PID_KWORLD_VSTREAM_COLD) },
 133 /* 08 */        { USB_DEVICE(USB_VID_EMPIA,             USB_PID_KWORLD_VSTREAM_WARM) },
 134 /* 09 */        { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB_COLD) },
 135 /* 10 */        { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_GRANDTEC_DVBT_USB_WARM) },
 136 /* 11 */        { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_DIBCOM_MOD3000_COLD) },
 137 /* 12 */        { USB_DEVICE(USB_VID_GRANDTEC,          USB_PID_DIBCOM_MOD3000_WARM) },
 138 /* 13 */        { USB_DEVICE(USB_VID_HYPER_PALTEK,      USB_PID_UNK_HYPER_PALTEK_COLD) },
 139 /* 14 */        { USB_DEVICE(USB_VID_HYPER_PALTEK,      USB_PID_UNK_HYPER_PALTEK_WARM) },
 140 /* 15 */        { USB_DEVICE(USB_VID_VISIONPLUS,        USB_PID_TWINHAN_VP7041_COLD) },
 141 /* 16 */        { USB_DEVICE(USB_VID_VISIONPLUS,        USB_PID_TWINHAN_VP7041_WARM) },
 142 /* 17 */        { USB_DEVICE(USB_VID_TWINHAN,           USB_PID_TWINHAN_VP7041_COLD) },
 143 /* 18 */        { USB_DEVICE(USB_VID_TWINHAN,           USB_PID_TWINHAN_VP7041_WARM) },
 144 /* 19 */        { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
 145 /* 20 */        { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
 146 /* 21 */        { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
 147 /* 22 */        { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
 148 /* 23 */        { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_COLD) },
 149 
 150 /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
 151 /* 24 */        { USB_DEVICE(USB_VID_ADSTECH,           USB_PID_ADSTECH_USB2_WARM) },
 152 /* 25 */        { USB_DEVICE(USB_VID_KYE,               USB_PID_KYE_DVB_T_COLD) },
 153 /* 26 */        { USB_DEVICE(USB_VID_KYE,               USB_PID_KYE_DVB_T_WARM) },
 154 
 155 /* 27 */        { USB_DEVICE(USB_VID_KWORLD,            USB_PID_KWORLD_VSTREAM_COLD) },
 156 
 157 /* 28 */        { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
 158 /* 29 */        { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
 159 
 160 /*
 161  * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
 162  *      we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
 163  *      have been left on the device. If you don't have such a device but an Artec
 164  *      device that's supposed to work with this driver but is not detected by it,
 165  *      free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
 166  */
 167 
 168 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
 169 /* 30 */        { USB_DEVICE(USB_VID_ANCHOR,            USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
 170 #endif
 171 
 172                         { }             /* Terminating entry */
 173 };
 174 MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
 175 
 176 static struct dvb_usb_device_properties dibusb1_1_properties = {
 177         .caps =  DVB_USB_IS_AN_I2C_ADAPTER,
 178 
 179         .usb_ctrl = CYPRESS_AN2135,
 180 
 181         .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
 182 
 183         .num_adapters = 1,
 184         .adapter = {
 185                 {
 186                 .num_frontends = 1,
 187                 .fe = {{
 188                         .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 189                         .pid_filter_count = 16,
 190 
 191                         .streaming_ctrl   = dibusb_streaming_ctrl,
 192                         .pid_filter       = dibusb_pid_filter,
 193                         .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
 194                         .frontend_attach  = dibusb_dib3000mb_frontend_attach,
 195                         .tuner_attach     = dibusb_tuner_probe_and_attach,
 196 
 197                         /* parameter for the MPEG2-data transfer */
 198                         .stream = {
 199                                 .type = USB_BULK,
 200                                 .count = 7,
 201                                 .endpoint = 0x02,
 202                                 .u = {
 203                                         .bulk = {
 204                                                 .buffersize = 4096,
 205                                         }
 206                                 }
 207                         },
 208                 }},
 209                         .size_of_priv     = sizeof(struct dibusb_state),
 210                 }
 211         },
 212 
 213         .power_ctrl       = dibusb_power_ctrl,
 214 
 215         .rc.legacy = {
 216                 .rc_interval      = DEFAULT_RC_INTERVAL,
 217                 .rc_map_table     = rc_map_dibusb_table,
 218                 .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
 219                 .rc_query         = dibusb_rc_query,
 220         },
 221 
 222         .i2c_algo         = &dibusb_i2c_algo,
 223 
 224         .generic_bulk_ctrl_endpoint = 0x01,
 225 
 226         .num_device_descs = 9,
 227         .devices = {
 228                 {       "AVerMedia AverTV DVBT USB1.1",
 229                         { &dibusb_dib3000mb_table[0],  NULL },
 230                         { &dibusb_dib3000mb_table[1],  NULL },
 231                 },
 232                 {       "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
 233                         { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
 234                         { &dibusb_dib3000mb_table[3], NULL },
 235                 },
 236                 {       "DiBcom USB1.1 DVB-T reference design (MOD3000)",
 237                         { &dibusb_dib3000mb_table[5],  NULL },
 238                         { &dibusb_dib3000mb_table[6],  NULL },
 239                 },
 240                 {       "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
 241                         { &dibusb_dib3000mb_table[7], NULL },
 242                         { &dibusb_dib3000mb_table[8], NULL },
 243                 },
 244                 {       "Grandtec USB1.1 DVB-T",
 245                         { &dibusb_dib3000mb_table[9],  &dibusb_dib3000mb_table[11], NULL },
 246                         { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
 247                 },
 248                 {       "Unknown USB1.1 DVB-T device ???? please report the name to the author",
 249                         { &dibusb_dib3000mb_table[13], NULL },
 250                         { &dibusb_dib3000mb_table[14], NULL },
 251                 },
 252                 {       "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
 253                         { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
 254                         { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
 255                 },
 256                 {       "Artec T1 USB1.1 TVBOX with AN2135",
 257                         { &dibusb_dib3000mb_table[19], NULL },
 258                         { &dibusb_dib3000mb_table[20], NULL },
 259                 },
 260                 {       "VideoWalker DVB-T USB",
 261                         { &dibusb_dib3000mb_table[25], NULL },
 262                         { &dibusb_dib3000mb_table[26], NULL },
 263                 },
 264         }
 265 };
 266 
 267 static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
 268         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 269         .usb_ctrl = CYPRESS_AN2235,
 270 
 271         .firmware = "dvb-usb-dibusb-an2235-01.fw",
 272 
 273         .num_adapters = 1,
 274         .adapter = {
 275                 {
 276                 .num_frontends = 1,
 277                 .fe = {{
 278                         .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
 279                         .pid_filter_count = 16,
 280 
 281                         .streaming_ctrl   = dibusb_streaming_ctrl,
 282                         .pid_filter       = dibusb_pid_filter,
 283                         .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
 284                         .frontend_attach  = dibusb_dib3000mb_frontend_attach,
 285                         .tuner_attach     = dibusb_tuner_probe_and_attach,
 286 
 287                         /* parameter for the MPEG2-data transfer */
 288                         .stream = {
 289                                 .type = USB_BULK,
 290                                 .count = 7,
 291                                 .endpoint = 0x02,
 292                                 .u = {
 293                                         .bulk = {
 294                                                 .buffersize = 4096,
 295                                         }
 296                                 }
 297                         },
 298                 }},
 299                         .size_of_priv     = sizeof(struct dibusb_state),
 300                 },
 301         },
 302         .power_ctrl       = dibusb_power_ctrl,
 303 
 304         .rc.legacy = {
 305                 .rc_interval      = DEFAULT_RC_INTERVAL,
 306                 .rc_map_table     = rc_map_dibusb_table,
 307                 .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
 308                 .rc_query         = dibusb_rc_query,
 309         },
 310 
 311         .i2c_algo         = &dibusb_i2c_algo,
 312 
 313         .generic_bulk_ctrl_endpoint = 0x01,
 314 
 315 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
 316         .num_device_descs = 2,
 317 #else
 318         .num_device_descs = 1,
 319 #endif
 320         .devices = {
 321                 {       "Artec T1 USB1.1 TVBOX with AN2235",
 322                         { &dibusb_dib3000mb_table[21], NULL },
 323                         { &dibusb_dib3000mb_table[22], NULL },
 324                 },
 325 #ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
 326                 {       "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
 327                         { &dibusb_dib3000mb_table[30], NULL },
 328                         { NULL },
 329                 },
 330                 { NULL },
 331 #endif
 332         }
 333 };
 334 
 335 static struct dvb_usb_device_properties dibusb2_0b_properties = {
 336         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 337 
 338         .usb_ctrl = CYPRESS_FX2,
 339 
 340         .firmware = "dvb-usb-adstech-usb2-02.fw",
 341 
 342         .num_adapters = 1,
 343         .adapter = {
 344                 {
 345                 .num_frontends = 1,
 346                 .fe = {{
 347                         .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 348                         .pid_filter_count = 16,
 349 
 350                         .streaming_ctrl   = dibusb2_0_streaming_ctrl,
 351                         .pid_filter       = dibusb_pid_filter,
 352                         .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
 353                         .frontend_attach  = dibusb_dib3000mb_frontend_attach,
 354                         .tuner_attach     = dibusb_thomson_tuner_attach,
 355 
 356                         /* parameter for the MPEG2-data transfer */
 357                         .stream = {
 358                                 .type = USB_BULK,
 359                                 .count = 7,
 360                                 .endpoint = 0x06,
 361                                 .u = {
 362                                         .bulk = {
 363                                                 .buffersize = 4096,
 364                                         }
 365                                 }
 366                         },
 367                 }},
 368                         .size_of_priv     = sizeof(struct dibusb_state),
 369                 }
 370         },
 371         .power_ctrl       = dibusb2_0_power_ctrl,
 372 
 373         .rc.legacy = {
 374                 .rc_interval      = DEFAULT_RC_INTERVAL,
 375                 .rc_map_table     = rc_map_dibusb_table,
 376                 .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
 377                 .rc_query         = dibusb_rc_query,
 378         },
 379 
 380         .i2c_algo         = &dibusb_i2c_algo,
 381 
 382         .generic_bulk_ctrl_endpoint = 0x01,
 383 
 384         .num_device_descs = 2,
 385         .devices = {
 386                 {       "KWorld/ADSTech Instant DVB-T USB2.0",
 387                         { &dibusb_dib3000mb_table[23], NULL },
 388                         { &dibusb_dib3000mb_table[24], NULL },
 389                 },
 390                 {       "KWorld Xpert DVB-T USB2.0",
 391                         { &dibusb_dib3000mb_table[27], NULL },
 392                         { NULL }
 393                 },
 394                 { NULL },
 395         }
 396 };
 397 
 398 static struct dvb_usb_device_properties artec_t1_usb2_properties = {
 399         .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 400 
 401         .usb_ctrl = CYPRESS_FX2,
 402 
 403         .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
 404 
 405         .num_adapters = 1,
 406         .adapter = {
 407                 {
 408                 .num_frontends = 1,
 409                 .fe = {{
 410                         .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 411                         .pid_filter_count = 16,
 412 
 413                         .streaming_ctrl   = dibusb2_0_streaming_ctrl,
 414                         .pid_filter       = dibusb_pid_filter,
 415                         .pid_filter_ctrl  = dibusb_pid_filter_ctrl,
 416                         .frontend_attach  = dibusb_dib3000mb_frontend_attach,
 417                         .tuner_attach     = dibusb_tuner_probe_and_attach,
 418                         /* parameter for the MPEG2-data transfer */
 419                         .stream = {
 420                                 .type = USB_BULK,
 421                                 .count = 7,
 422                                 .endpoint = 0x06,
 423                                 .u = {
 424                                         .bulk = {
 425                                                 .buffersize = 4096,
 426                                         }
 427                                 }
 428                         },
 429                 }},
 430                         .size_of_priv     = sizeof(struct dibusb_state),
 431                 }
 432         },
 433         .power_ctrl       = dibusb2_0_power_ctrl,
 434 
 435         .rc.legacy = {
 436                 .rc_interval      = DEFAULT_RC_INTERVAL,
 437                 .rc_map_table     = rc_map_dibusb_table,
 438                 .rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
 439                 .rc_query         = dibusb_rc_query,
 440         },
 441 
 442         .i2c_algo         = &dibusb_i2c_algo,
 443 
 444         .generic_bulk_ctrl_endpoint = 0x01,
 445 
 446         .num_device_descs = 1,
 447         .devices = {
 448                 {       "Artec T1 USB2.0",
 449                         { &dibusb_dib3000mb_table[28], NULL },
 450                         { &dibusb_dib3000mb_table[29], NULL },
 451                 },
 452                 { NULL },
 453         }
 454 };
 455 
 456 static struct usb_driver dibusb_driver = {
 457         .name           = "dvb_usb_dibusb_mb",
 458         .probe          = dibusb_probe,
 459         .disconnect = dvb_usb_device_exit,
 460         .id_table       = dibusb_dib3000mb_table,
 461 };
 462 
 463 module_usb_driver(dibusb_driver);
 464 
 465 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 466 MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
 467 MODULE_VERSION("1.0");
 468 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */