1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * budget.ko: driver for the SAA7146 based Budget DVB cards 4 * without analog video input or CI 5 * 6 * Compiled from various sources by Michael Hunold <michael@mihu.de> 7 * 8 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> 9 * 10 * Copyright (C) 1999-2002 Ralph Metzler 11 * & Marcus Metzler for convergence integrated media GmbH 12 * 13 * 26feb2004 Support for FS Activy Card (Grundig tuner) by 14 * Michael Dreher <michael@5dot1.de>, 15 * Oliver Endriss <o.endriss@gmx.de> and 16 * Andreas 'randy' Weinberger 17 * 18 * the project's page is at https://linuxtv.org 19 */ 20 21 #include "budget.h" 22 #include "stv0299.h" 23 #include "ves1x93.h" 24 #include "ves1820.h" 25 #include "l64781.h" 26 #include "tda8083.h" 27 #include "s5h1420.h" 28 #include "tda10086.h" 29 #include "tda826x.h" 30 #include "lnbp21.h" 31 #include "bsru6.h" 32 #include "bsbe1.h" 33 #include "tdhd1.h" 34 #include "stv6110x.h" 35 #include "stv090x.h" 36 #include "isl6423.h" 37 #include "lnbh24.h" 38 39 40 static int diseqc_method; 41 module_param(diseqc_method, int, 0444); 42 MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); 43 44 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 45 46 static void Set22K(struct budget *budget, int state) 47 { 48 struct saa7146_dev *dev = budget->dev; 49 50 dprintk(2, "budget: %p\n", budget); 51 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); 52 } 53 54 /* 55 * Diseqc functions only for TT Budget card 56 * taken from the Skyvision DVB driver by 57 * Ralph Metzler <rjkm@metzlerbros.de> 58 */ 59 60 static void DiseqcSendBit(struct budget *budget, int data) 61 { 62 struct saa7146_dev *dev = budget->dev; 63 64 dprintk(2, "budget: %p\n", budget); 65 66 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); 67 udelay(data ? 500 : 1000); 68 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 69 udelay(data ? 1000 : 500); 70 } 71 72 static void DiseqcSendByte(struct budget *budget, int data) 73 { 74 int i, par = 1, d; 75 76 dprintk(2, "budget: %p\n", budget); 77 78 for (i = 7; i >= 0; i--) { 79 d = (data>>i)&1; 80 par ^= d; 81 DiseqcSendBit(budget, d); 82 } 83 84 DiseqcSendBit(budget, par); 85 } 86 87 static int SendDiSEqCMsg(struct budget *budget, int len, u8 *msg, unsigned long burst) 88 { 89 struct saa7146_dev *dev = budget->dev; 90 int i; 91 92 dprintk(2, "budget: %p\n", budget); 93 94 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 95 mdelay(16); 96 97 for (i = 0; i < len; i++) 98 DiseqcSendByte(budget, msg[i]); 99 100 mdelay(16); 101 102 if (burst != -1) { 103 if (burst) { 104 DiseqcSendByte(budget, 0xff); 105 } else { 106 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); 107 mdelay(12); 108 udelay(500); 109 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 110 } 111 msleep(20); 112 } 113 114 return 0; 115 } 116 117 /* 118 * Routines for the Fujitsu Siemens Activy budget card 119 * 22 kHz tone and DiSEqC are handled by the frontend. 120 * Voltage must be set here. 121 * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL 122 */ 123 static int SetVoltage_Activy(struct budget *budget, 124 enum fe_sec_voltage voltage) 125 { 126 struct saa7146_dev *dev = budget->dev; 127 128 dprintk(2, "budget: %p\n", budget); 129 130 switch (voltage) { 131 case SEC_VOLTAGE_13: 132 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); 133 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); 134 break; 135 case SEC_VOLTAGE_18: 136 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); 137 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); 138 break; 139 case SEC_VOLTAGE_OFF: 140 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); 141 break; 142 default: 143 return -EINVAL; 144 } 145 146 return 0; 147 } 148 149 static int siemens_budget_set_voltage(struct dvb_frontend *fe, 150 enum fe_sec_voltage voltage) 151 { 152 struct budget *budget = fe->dvb->priv; 153 154 return SetVoltage_Activy(budget, voltage); 155 } 156 157 static int budget_set_tone(struct dvb_frontend *fe, 158 enum fe_sec_tone_mode tone) 159 { 160 struct budget *budget = fe->dvb->priv; 161 162 switch (tone) { 163 case SEC_TONE_ON: 164 Set22K(budget, 1); 165 break; 166 167 case SEC_TONE_OFF: 168 Set22K(budget, 0); 169 break; 170 171 default: 172 return -EINVAL; 173 } 174 175 return 0; 176 } 177 178 static int budget_diseqc_send_master_cmd(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) 179 { 180 struct budget *budget = fe->dvb->priv; 181 182 SendDiSEqCMsg(budget, cmd->msg_len, cmd->msg, 0); 183 184 return 0; 185 } 186 187 static int budget_diseqc_send_burst(struct dvb_frontend *fe, 188 enum fe_sec_mini_cmd minicmd) 189 { 190 struct budget *budget = fe->dvb->priv; 191 192 SendDiSEqCMsg(budget, 0, NULL, minicmd); 193 194 return 0; 195 } 196 197 static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) 198 { 199 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 200 struct budget *budget = fe->dvb->priv; 201 u8 pwr = 0; 202 u8 buf[4]; 203 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; 204 u32 div = (c->frequency + 479500) / 125; 205 206 if (c->frequency > 2000000) 207 pwr = 3; 208 else if (c->frequency > 1800000) 209 pwr = 2; 210 else if (c->frequency > 1600000) 211 pwr = 1; 212 else if (c->frequency > 1200000) 213 pwr = 0; 214 else if (c->frequency >= 1100000) 215 pwr = 1; 216 else 217 pwr = 2; 218 219 buf[0] = (div >> 8) & 0x7f; 220 buf[1] = div & 0xff; 221 buf[2] = ((div & 0x18000) >> 10) | 0x95; 222 buf[3] = (pwr << 6) | 0x30; 223 224 // NOTE: since we're using a prescaler of 2, we set the 225 // divisor frequency to 62.5kHz and divide by 125 above 226 227 if (fe->ops.i2c_gate_ctrl) 228 fe->ops.i2c_gate_ctrl(fe, 1); 229 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 230 return -EIO; 231 return 0; 232 } 233 234 static struct ves1x93_config alps_bsrv2_config = { 235 .demod_address = 0x08, 236 .xin = 90100000UL, 237 .invert_pwm = 0, 238 }; 239 240 static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) 241 { 242 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 243 struct budget *budget = fe->dvb->priv; 244 u32 div; 245 u8 data[4]; 246 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; 247 248 div = (c->frequency + 35937500 + 31250) / 62500; 249 250 data[0] = (div >> 8) & 0x7f; 251 data[1] = div & 0xff; 252 data[2] = 0x85 | ((div >> 10) & 0x60); 253 data[3] = (c->frequency < 174000000 ? 0x88 : c->frequency < 470000000 ? 0x84 : 0x81); 254 255 if (fe->ops.i2c_gate_ctrl) 256 fe->ops.i2c_gate_ctrl(fe, 1); 257 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 258 return -EIO; 259 return 0; 260 } 261 262 static struct ves1820_config alps_tdbe2_config = { 263 .demod_address = 0x09, 264 .xin = 57840000UL, 265 .invert = 1, 266 .selagc = VES1820_SELAGC_SIGNAMPERR, 267 }; 268 269 static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe) 270 { 271 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 272 struct budget *budget = fe->dvb->priv; 273 u8 *tuner_addr = fe->tuner_priv; 274 u32 div; 275 u8 cfg, cpump, band_select; 276 u8 data[4]; 277 struct i2c_msg msg = { .flags = 0, .buf = data, .len = sizeof(data) }; 278 279 if (tuner_addr) 280 msg.addr = *tuner_addr; 281 else 282 msg.addr = 0x61; 283 284 div = (36125000 + c->frequency) / 166666; 285 286 cfg = 0x88; 287 288 if (c->frequency < 175000000) 289 cpump = 2; 290 else if (c->frequency < 390000000) 291 cpump = 1; 292 else if (c->frequency < 470000000) 293 cpump = 2; 294 else if (c->frequency < 750000000) 295 cpump = 1; 296 else 297 cpump = 3; 298 299 if (c->frequency < 175000000) 300 band_select = 0x0e; 301 else if (c->frequency < 470000000) 302 band_select = 0x05; 303 else 304 band_select = 0x03; 305 306 data[0] = (div >> 8) & 0x7f; 307 data[1] = div & 0xff; 308 data[2] = ((div >> 10) & 0x60) | cfg; 309 data[3] = (cpump << 6) | band_select; 310 311 if (fe->ops.i2c_gate_ctrl) 312 fe->ops.i2c_gate_ctrl(fe, 1); 313 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 314 return -EIO; 315 return 0; 316 } 317 318 static struct l64781_config grundig_29504_401_config = { 319 .demod_address = 0x55, 320 }; 321 322 static struct l64781_config grundig_29504_401_config_activy = { 323 .demod_address = 0x54, 324 }; 325 326 static u8 tuner_address_grundig_29504_401_activy = 0x60; 327 328 static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) 329 { 330 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 331 struct budget *budget = fe->dvb->priv; 332 u32 div; 333 u8 data[4]; 334 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 335 336 div = c->frequency / 125; 337 data[0] = (div >> 8) & 0x7f; 338 data[1] = div & 0xff; 339 data[2] = 0x8e; 340 data[3] = 0x00; 341 342 if (fe->ops.i2c_gate_ctrl) 343 fe->ops.i2c_gate_ctrl(fe, 1); 344 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 345 return -EIO; 346 return 0; 347 } 348 349 static struct tda8083_config grundig_29504_451_config = { 350 .demod_address = 0x68, 351 }; 352 353 static int s5h1420_tuner_set_params(struct dvb_frontend *fe) 354 { 355 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 356 struct budget *budget = fe->dvb->priv; 357 u32 div; 358 u8 data[4]; 359 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 360 361 div = c->frequency / 1000; 362 data[0] = (div >> 8) & 0x7f; 363 data[1] = div & 0xff; 364 data[2] = 0xc2; 365 366 if (div < 1450) 367 data[3] = 0x00; 368 else if (div < 1850) 369 data[3] = 0x40; 370 else if (div < 2000) 371 data[3] = 0x80; 372 else 373 data[3] = 0xc0; 374 375 if (fe->ops.i2c_gate_ctrl) 376 fe->ops.i2c_gate_ctrl(fe, 1); 377 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 378 return -EIO; 379 380 return 0; 381 } 382 383 static struct s5h1420_config s5h1420_config = { 384 .demod_address = 0x53, 385 .invert = 1, 386 .cdclk_polarity = 1, 387 }; 388 389 static struct tda10086_config tda10086_config = { 390 .demod_address = 0x0e, 391 .invert = 0, 392 .diseqc_tone = 1, 393 .xtal_freq = TDA10086_XTAL_16M, 394 }; 395 396 static const struct stv0299_config alps_bsru6_config_activy = { 397 .demod_address = 0x68, 398 .inittab = alps_bsru6_inittab, 399 .mclk = 88000000UL, 400 .invert = 1, 401 .op0_off = 1, 402 .min_delay_ms = 100, 403 .set_symbol_rate = alps_bsru6_set_symbol_rate, 404 }; 405 406 static const struct stv0299_config alps_bsbe1_config_activy = { 407 .demod_address = 0x68, 408 .inittab = alps_bsbe1_inittab, 409 .mclk = 88000000UL, 410 .invert = 1, 411 .op0_off = 1, 412 .min_delay_ms = 100, 413 .set_symbol_rate = alps_bsbe1_set_symbol_rate, 414 }; 415 416 static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name) 417 { 418 struct budget *budget = fe->dvb->priv; 419 420 return request_firmware(fw, name, &budget->dev->pci->dev); 421 } 422 423 424 static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) 425 { 426 u8 val; 427 struct i2c_msg msg[] = { 428 { .addr = adr, .flags = 0, .buf = ®, .len = 1 }, 429 { .addr = adr, .flags = I2C_M_RD, .buf = &val, .len = 1 } 430 }; 431 432 return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val; 433 } 434 435 static u8 read_pwm(struct budget *budget) 436 { 437 u8 b = 0xff; 438 u8 pwm; 439 struct i2c_msg msg[] = { { .addr = 0x50, .flags = 0, .buf = &b, .len = 1 }, 440 { .addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} }; 441 442 if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) 443 pwm = 0x48; 444 445 return pwm; 446 } 447 448 static struct stv090x_config tt1600_stv090x_config = { 449 .device = STV0903, 450 .demod_mode = STV090x_SINGLE, 451 .clk_mode = STV090x_CLK_EXT, 452 453 .xtal = 13500000, 454 .address = 0x68, 455 456 .ts1_mode = STV090x_TSMODE_DVBCI, 457 .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, 458 459 .repeater_level = STV090x_RPTLEVEL_16, 460 461 .tuner_init = NULL, 462 .tuner_sleep = NULL, 463 .tuner_set_mode = NULL, 464 .tuner_set_frequency = NULL, 465 .tuner_get_frequency = NULL, 466 .tuner_set_bandwidth = NULL, 467 .tuner_get_bandwidth = NULL, 468 .tuner_set_bbgain = NULL, 469 .tuner_get_bbgain = NULL, 470 .tuner_set_refclk = NULL, 471 .tuner_get_status = NULL, 472 }; 473 474 static struct stv6110x_config tt1600_stv6110x_config = { 475 .addr = 0x60, 476 .refclk = 27000000, 477 .clk_div = 2, 478 }; 479 480 static struct isl6423_config tt1600_isl6423_config = { 481 .current_max = SEC_CURRENT_515m, 482 .curlim = SEC_CURRENT_LIM_ON, 483 .mod_extern = 1, 484 .addr = 0x08, 485 }; 486 487 static void frontend_init(struct budget *budget) 488 { 489 (void)alps_bsbe1_config; /* avoid warning */ 490 491 switch (budget->dev->pci->subsystem_device) { 492 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) 493 case 0x1013: 494 // try the ALPS BSRV2 first of all 495 budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap); 496 if (budget->dvb_frontend) { 497 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; 498 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; 499 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; 500 budget->dvb_frontend->ops.set_tone = budget_set_tone; 501 break; 502 } 503 504 // try the ALPS BSRU6 now 505 budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); 506 if (budget->dvb_frontend) { 507 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; 508 budget->dvb_frontend->tuner_priv = &budget->i2c_adap; 509 if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) { 510 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; 511 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; 512 budget->dvb_frontend->ops.set_tone = budget_set_tone; 513 } 514 break; 515 } 516 break; 517 518 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) 519 520 budget->dvb_frontend = dvb_attach(ves1820_attach, &alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); 521 if (budget->dvb_frontend) { 522 budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; 523 break; 524 } 525 break; 526 527 case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) 528 529 budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap); 530 if (budget->dvb_frontend) { 531 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; 532 budget->dvb_frontend->tuner_priv = NULL; 533 break; 534 } 535 break; 536 537 case 0x4f52: /* Cards based on Philips Semi Sylt PCI ref. design */ 538 budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); 539 if (budget->dvb_frontend) { 540 pr_info("tuner ALPS BSRU6 in Philips Semi. Sylt detected\n"); 541 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; 542 budget->dvb_frontend->tuner_priv = &budget->i2c_adap; 543 break; 544 } 545 break; 546 547 case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */ 548 { 549 int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67); 550 551 if (subtype < 0) 552 break; 553 /* fixme: find a better way to identify the card */ 554 if (subtype < 0x36) { 555 /* assume ALPS BSRU6 */ 556 budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap); 557 if (budget->dvb_frontend) { 558 pr_info("tuner ALPS BSRU6 detected\n"); 559 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; 560 budget->dvb_frontend->tuner_priv = &budget->i2c_adap; 561 budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; 562 budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; 563 break; 564 } 565 } else { 566 /* assume ALPS BSBE1 */ 567 /* reset tuner */ 568 saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTLO); 569 msleep(50); 570 saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTHI); 571 msleep(250); 572 budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap); 573 if (budget->dvb_frontend) { 574 pr_info("tuner ALPS BSBE1 detected\n"); 575 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; 576 budget->dvb_frontend->tuner_priv = &budget->i2c_adap; 577 budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; 578 budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; 579 break; 580 } 581 } 582 break; 583 } 584 585 case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) 586 budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap); 587 if (budget->dvb_frontend) { 588 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; 589 budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; 590 budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; 591 } 592 break; 593 594 case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */ 595 budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap); 596 if (budget->dvb_frontend) { 597 budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params; 598 budget->dvb_frontend->tuner_priv = &budget->i2c_adap; 599 } 600 break; 601 602 case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */ 603 budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap); 604 if (budget->dvb_frontend) { 605 budget->dvb_frontend->tuner_priv = &tuner_address_grundig_29504_401_activy; 606 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; 607 } 608 break; 609 610 case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) 611 { 612 struct dvb_frontend *fe; 613 614 fe = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap); 615 if (fe) { 616 fe->ops.tuner_ops.set_params = s5h1420_tuner_set_params; 617 budget->dvb_frontend = fe; 618 if (dvb_attach(lnbp21_attach, fe, &budget->i2c_adap, 619 0, 0) == NULL) { 620 pr_err("%s(): No LNBP21 found!\n", __func__); 621 goto error_out; 622 } 623 break; 624 } 625 } 626 fallthrough; 627 case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262) 628 { 629 struct dvb_frontend *fe; 630 631 // gpio2 is connected to CLB - reset it + leave it high 632 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); 633 msleep(1); 634 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); 635 msleep(1); 636 637 fe = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap); 638 if (fe) { 639 budget->dvb_frontend = fe; 640 if (dvb_attach(tda826x_attach, fe, 0x60, 641 &budget->i2c_adap, 0) == NULL) 642 pr_err("%s(): No tda826x found!\n", __func__); 643 if (dvb_attach(lnbp21_attach, fe, 644 &budget->i2c_adap, 0, 0) == NULL) { 645 pr_err("%s(): No LNBP21 found!\n", __func__); 646 goto error_out; 647 } 648 break; 649 } 650 } 651 fallthrough; 652 653 case 0x101c: { /* TT S2-1600 */ 654 const struct stv6110x_devctl *ctl; 655 656 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); 657 msleep(50); 658 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); 659 msleep(250); 660 661 budget->dvb_frontend = dvb_attach(stv090x_attach, 662 &tt1600_stv090x_config, 663 &budget->i2c_adap, 664 STV090x_DEMODULATOR_0); 665 666 if (budget->dvb_frontend) { 667 668 ctl = dvb_attach(stv6110x_attach, 669 budget->dvb_frontend, 670 &tt1600_stv6110x_config, 671 &budget->i2c_adap); 672 673 if (ctl) { 674 tt1600_stv090x_config.tuner_init = ctl->tuner_init; 675 tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep; 676 tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; 677 tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; 678 tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; 679 tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; 680 tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; 681 tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; 682 tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; 683 tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; 684 tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; 685 686 /* 687 * call the init function once to initialize 688 * tuner's clock output divider and demod's 689 * master clock 690 */ 691 if (budget->dvb_frontend->ops.init) 692 budget->dvb_frontend->ops.init(budget->dvb_frontend); 693 694 if (dvb_attach(isl6423_attach, 695 budget->dvb_frontend, 696 &budget->i2c_adap, 697 &tt1600_isl6423_config) == NULL) { 698 pr_err("%s(): No Intersil ISL6423 found!\n", __func__); 699 goto error_out; 700 } 701 } else { 702 pr_err("%s(): No STV6110(A) Silicon Tuner found!\n", __func__); 703 goto error_out; 704 } 705 } 706 } 707 break; 708 709 case 0x1020: { /* Omicom S2 */ 710 const struct stv6110x_devctl *ctl; 711 712 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); 713 msleep(50); 714 saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); 715 msleep(250); 716 717 budget->dvb_frontend = dvb_attach(stv090x_attach, 718 &tt1600_stv090x_config, 719 &budget->i2c_adap, 720 STV090x_DEMODULATOR_0); 721 722 if (budget->dvb_frontend) { 723 pr_info("Omicom S2 detected\n"); 724 725 ctl = dvb_attach(stv6110x_attach, 726 budget->dvb_frontend, 727 &tt1600_stv6110x_config, 728 &budget->i2c_adap); 729 730 if (ctl) { 731 tt1600_stv090x_config.tuner_init = ctl->tuner_init; 732 tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep; 733 tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; 734 tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; 735 tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; 736 tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; 737 tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; 738 tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; 739 tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; 740 tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; 741 tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; 742 743 /* 744 * call the init function once to initialize 745 * tuner's clock output divider and demod's 746 * master clock 747 */ 748 if (budget->dvb_frontend->ops.init) 749 budget->dvb_frontend->ops.init(budget->dvb_frontend); 750 751 if (dvb_attach(lnbh24_attach, 752 budget->dvb_frontend, 753 &budget->i2c_adap, 754 LNBH24_PCL | LNBH24_TTX, 755 LNBH24_TEN, 0x14>>1) == NULL) { 756 pr_err("No LNBH24 found!\n"); 757 goto error_out; 758 } 759 } else { 760 pr_err("%s(): No STV6110(A) Silicon Tuner found!\n", __func__); 761 goto error_out; 762 } 763 } 764 } 765 break; 766 } 767 768 if (budget->dvb_frontend == NULL) { 769 pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", 770 budget->dev->pci->vendor, 771 budget->dev->pci->device, 772 budget->dev->pci->subsystem_vendor, 773 budget->dev->pci->subsystem_device); 774 } else { 775 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) 776 goto error_out; 777 } 778 return; 779 780 error_out: 781 pr_err("Frontend registration failed!\n"); 782 dvb_frontend_detach(budget->dvb_frontend); 783 budget->dvb_frontend = NULL; 784 } 785 786 static int budget_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) 787 { 788 struct budget *budget = NULL; 789 int err; 790 791 budget = kmalloc(sizeof(struct budget), GFP_KERNEL); 792 if (budget == NULL) 793 return -ENOMEM; 794 795 dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget); 796 797 dev->ext_priv = budget; 798 799 err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); 800 if (err) { 801 pr_err("==> failed\n"); 802 kfree(budget); 803 return err; 804 } 805 806 budget->dvb_adapter.priv = budget; 807 frontend_init(budget); 808 809 ttpci_budget_init_hooks(budget); 810 811 return 0; 812 } 813 814 static int budget_detach(struct saa7146_dev *dev) 815 { 816 struct budget *budget = dev->ext_priv; 817 int err; 818 819 if (budget->dvb_frontend) { 820 dvb_unregister_frontend(budget->dvb_frontend); 821 dvb_frontend_detach(budget->dvb_frontend); 822 } 823 824 err = ttpci_budget_deinit(budget); 825 826 kfree(budget); 827 dev->ext_priv = NULL; 828 829 return err; 830 } 831 832 static struct saa7146_extension budget_extension; 833 834 MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); 835 MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); 836 MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 837 MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); 838 MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); 839 MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT); 840 MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); 841 MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); 842 MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); 843 MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY); 844 MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT); 845 MAKE_BUDGET_INFO(sylt, "Philips Semi Sylt PCI", BUDGET_TT_HW_DISEQC); 846 847 static const struct pci_device_id pci_tbl[] = { 848 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), 849 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), 850 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), 851 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 852 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), 853 MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), 854 MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), 855 MAKE_EXTENSION_PCI(fsacs1, 0x1131, 0x4f60), 856 MAKE_EXTENSION_PCI(fsacs0, 0x1131, 0x4f61), 857 MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), 858 MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), 859 MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020), 860 MAKE_EXTENSION_PCI(sylt, 0x1131, 0x4f52), 861 { 862 .vendor = 0, 863 } 864 }; 865 866 MODULE_DEVICE_TABLE(pci, pci_tbl); 867 868 static struct saa7146_extension budget_extension = { 869 .name = "budget dvb", 870 .flags = SAA7146_USE_I2C_IRQ, 871 872 .module = THIS_MODULE, 873 .pci_tbl = pci_tbl, 874 .attach = budget_attach, 875 .detach = budget_detach, 876 877 .irq_mask = MASK_10, 878 .irq_func = ttpci_budget_irq10_handler, 879 }; 880 881 static int __init budget_init(void) 882 { 883 return saa7146_register_extension(&budget_extension); 884 } 885 886 static void __exit budget_exit(void) 887 { 888 saa7146_unregister_extension(&budget_extension); 889 } 890 891 module_init(budget_init); 892 module_exit(budget_exit); 893 894 MODULE_LICENSE("GPL"); 895 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); 896 MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards by Siemens, Technotrend, Hauppauge"); 897