aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c196
1 files changed, 113 insertions, 83 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 3f485bf13121..efb4a6c2b57a 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -175,23 +175,23 @@ static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe,
175 return 0; 175 return 0;
176} 176}
177 177
178static void skystar2_rev23_attach(struct flexcop_device *fc, 178static int skystar2_rev23_attach(struct flexcop_device *fc,
179 struct i2c_adapter *i2c) 179 struct i2c_adapter *i2c)
180{ 180{
181 fc->fe = dvb_attach(mt312_attach, 181 fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
182 &skystar23_samsung_tbdu18132_config, i2c);
183 if (fc->fe != NULL) { 182 if (fc->fe != NULL) {
184 struct dvb_frontend_ops *ops = &fc->fe->ops; 183 struct dvb_frontend_ops *ops = &fc->fe->ops;
185 ops->tuner_ops.set_params \ 184 ops->tuner_ops.set_params =
186 = skystar23_samsung_tbdu18132_tuner_set_params; 185 skystar23_samsung_tbdu18132_tuner_set_params;
187 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; 186 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
188 ops->diseqc_send_burst = flexcop_diseqc_send_burst; 187 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
189 ops->set_tone = flexcop_set_tone; 188 ops->set_tone = flexcop_set_tone;
190 ops->set_voltage = flexcop_set_voltage; 189 ops->set_voltage = flexcop_set_voltage;
191 fc->fe_sleep = ops->sleep; 190 fc->fe_sleep = ops->sleep;
192 ops->sleep = flexcop_sleep; 191 ops->sleep = flexcop_sleep;
193 fc->dev_type = FC_SKY_REV23; 192 return 1;
194 } 193 }
194 return 0;
195} 195}
196#endif 196#endif
197 197
@@ -307,7 +307,7 @@ static struct stv0299_config samsung_tbmu24112_config = {
307 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, 307 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
308}; 308};
309 309
310static void skystar2_rev26_attach(struct flexcop_device *fc, 310static int skystar2_rev26_attach(struct flexcop_device *fc,
311 struct i2c_adapter *i2c) 311 struct i2c_adapter *i2c)
312{ 312{
313 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); 313 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
@@ -317,7 +317,9 @@ static void skystar2_rev26_attach(struct flexcop_device *fc,
317 ops->set_voltage = flexcop_set_voltage; 317 ops->set_voltage = flexcop_set_voltage;
318 fc->fe_sleep = ops->sleep; 318 fc->fe_sleep = ops->sleep;
319 ops->sleep = flexcop_sleep; 319 ops->sleep = flexcop_sleep;
320 return 1;
320 } 321 }
322 return 0;
321} 323}
322#endif 324#endif
323 325
@@ -334,43 +336,54 @@ static struct itd1000_config skystar2_rev2_7_itd1000_config = {
334 .i2c_address = 0x61, 336 .i2c_address = 0x61,
335}; 337};
336 338
337static void skystar2_rev27_attach(struct flexcop_device *fc, 339static int skystar2_rev27_attach(struct flexcop_device *fc,
338 struct i2c_adapter *i2c) 340 struct i2c_adapter *i2c)
339{ 341{
342 flexcop_ibi_value r108;
343 struct i2c_adapter *i2c_tuner;
344
340 /* enable no_base_addr - no repeated start when reading */ 345 /* enable no_base_addr - no repeated start when reading */
341 fc->fc_i2c_adap[0].no_base_addr = 1; 346 fc->fc_i2c_adap[0].no_base_addr = 1;
342 fc->fe = dvb_attach(s5h1420_attach, 347 fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
343 &skystar2_rev2_7_s5h1420_config, i2c); 348 i2c);
344 if (fc->fe != NULL) { 349 if (!fc->fe)
345 flexcop_ibi_value r108; 350 goto fail;
346 struct i2c_adapter *i2c_tuner \
347 = s5h1420_get_tuner_i2c_adapter(fc->fe);
348 struct dvb_frontend_ops *ops = &fc->fe->ops;
349 351
350 fc->fe_sleep = ops->sleep; 352 i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
351 ops->sleep = flexcop_sleep; 353 if (!i2c_tuner)
352 354 goto fail;
353 /* enable no_base_addr - no repeated start when reading */ 355
354 fc->fc_i2c_adap[2].no_base_addr = 1; 356 fc->fe_sleep = fc->fe->ops.sleep;
355 if (dvb_attach(isl6421_attach, fc->fe, 357 fc->fe->ops.sleep = flexcop_sleep;
356 &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL) 358
357 err("ISL6421 could NOT be attached"); 359 /* enable no_base_addr - no repeated start when reading */
358 else 360 fc->fc_i2c_adap[2].no_base_addr = 1;
359 info("ISL6421 successfully attached"); 361 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
360 362 0x08, 1, 1)) {
361 /* the ITD1000 requires a lower i2c clock - is it a problem ? */ 363 err("ISL6421 could NOT be attached");
362 r108.raw = 0x00000506; 364 goto fail_isl;
363 fc->write_ibi_reg(fc, tw_sm_c_108, r108); 365 }
364 if (i2c_tuner) { 366 info("ISL6421 successfully attached");
365 if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, 367
366 &skystar2_rev2_7_itd1000_config) == NULL) 368 /* the ITD1000 requires a lower i2c clock - is it a problem ? */
367 err("ITD1000 could NOT be attached"); 369 r108.raw = 0x00000506;
368 else 370 fc->write_ibi_reg(fc, tw_sm_c_108, r108);
369 info("ITD1000 successfully attached"); 371 if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
370 } 372 &skystar2_rev2_7_itd1000_config)) {
371 } else 373 err("ITD1000 could NOT be attached");
372 fc->fc_i2c_adap[0].no_base_addr = 0; 374 /* Should i2c clock be restored? */
373 /* for the next devices we need it again */ 375 goto fail_isl;
376 }
377 info("ITD1000 successfully attached");
378
379 return 1;
380
381fail_isl:
382 fc->fc_i2c_adap[2].no_base_addr = 0;
383fail:
384 /* for the next devices we need it again */
385 fc->fc_i2c_adap[0].no_base_addr = 0;
386 return 0;
374} 387}
375#endif 388#endif
376 389
@@ -387,32 +400,38 @@ static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
387 .xtal_khz = 10111, 400 .xtal_khz = 10111,
388}; 401};
389 402
390static void skystar2_rev28_attach(struct flexcop_device *fc, 403static int skystar2_rev28_attach(struct flexcop_device *fc,
391 struct i2c_adapter *i2c) 404 struct i2c_adapter *i2c)
392{ 405{
393 fc->fe = dvb_attach(cx24123_attach, 406 struct i2c_adapter *i2c_tuner;
394 &skystar2_rev2_8_cx24123_config, i2c); 407
395 if (fc->fe != NULL) { 408 fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
396 struct i2c_adapter *i2c_tuner \ 409 i2c);
397 = cx24123_get_tuner_i2c_adapter(fc->fe); 410 if (!fc->fe)
398 if (i2c_tuner != NULL) { 411 return 0;
399 if (dvb_attach(cx24113_attach, fc->fe, 412
400 &skystar2_rev2_8_cx24113_config, 413 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);;
401 i2c_tuner) == NULL) 414 if (!i2c_tuner)
402 err("CX24113 could NOT be attached"); 415 return 0;
403 else
404 info("CX24113 successfully attached");
405 }
406 416
407 fc->fc_i2c_adap[2].no_base_addr = 1; 417 if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
408 if (dvb_attach(isl6421_attach, fc->fe, 418 i2c_tuner)) {
409 &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL) 419 err("CX24113 could NOT be attached");
410 err("ISL6421 could NOT be attached"); 420 return 0;
411 else 421 }
412 info("ISL6421 successfully attached"); 422 info("CX24113 successfully attached");
423
424 fc->fc_i2c_adap[2].no_base_addr = 1;
425 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
426 0x08, 0, 0)) {
427 err("ISL6421 could NOT be attached");
428 fc->fc_i2c_adap[2].no_base_addr = 0;
429 return 0;
430 }
431 info("ISL6421 successfully attached");
413 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an 432 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
414 * IR-receiver (PIC16F818) - but the card has no input for that ??? */ 433 * IR-receiver (PIC16F818) - but the card has no input for that ??? */
415 } 434 return 1;
416} 435}
417#endif 436#endif
418 437
@@ -466,12 +485,15 @@ static struct mt352_config samsung_tdtc9251dh0_config = {
466 .demod_init = samsung_tdtc9251dh0_demod_init, 485 .demod_init = samsung_tdtc9251dh0_demod_init,
467}; 486};
468 487
469static void airstar_dvbt_attach(struct flexcop_device *fc, 488static int airstar_dvbt_attach(struct flexcop_device *fc,
470 struct i2c_adapter *i2c) 489 struct i2c_adapter *i2c)
471{ 490{
472 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); 491 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
473 if (fc->fe != NULL) 492 if (fc->fe != NULL) {
474 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; 493 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
494 return 1;
495 }
496 return 0;
475} 497}
476#endif 498#endif
477 499
@@ -489,10 +511,11 @@ static struct bcm3510_config air2pc_atsc_first_gen_config = {
489 .request_firmware = flexcop_fe_request_firmware, 511 .request_firmware = flexcop_fe_request_firmware,
490}; 512};
491 513
492static void airstar_atsc1_attach(struct flexcop_device *fc, 514static int airstar_atsc1_attach(struct flexcop_device *fc,
493 struct i2c_adapter *i2c) 515 struct i2c_adapter *i2c)
494{ 516{
495 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); 517 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
518 return fc->fe != NULL;
496} 519}
497#endif 520#endif
498 521
@@ -502,13 +525,15 @@ static struct nxt200x_config samsung_tbmv_config = {
502 .demod_address = 0x0a, 525 .demod_address = 0x0a,
503}; 526};
504 527
505static void airstar_atsc2_attach(struct flexcop_device *fc, 528static int airstar_atsc2_attach(struct flexcop_device *fc,
506 struct i2c_adapter *i2c) 529 struct i2c_adapter *i2c)
507{ 530{
508 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); 531 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
509 if (fc->fe != NULL) 532 if (!fc->fe)
510 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, 533 return 0;
511 DVB_PLL_SAMSUNG_TBMV); 534
535 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
536 DVB_PLL_SAMSUNG_TBMV);
512} 537}
513#endif 538#endif
514 539
@@ -521,14 +546,15 @@ static struct lgdt330x_config air2pc_atsc_hd5000_config = {
521 .clock_polarity_flip = 1, 546 .clock_polarity_flip = 1,
522}; 547};
523 548
524static void airstar_atsc3_attach(struct flexcop_device *fc, 549static int airstar_atsc3_attach(struct flexcop_device *fc,
525 struct i2c_adapter *i2c) 550 struct i2c_adapter *i2c)
526{ 551{
527 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); 552 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
528 if (fc->fe != NULL) { 553 if (!fc->fe)
529 dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, 554 return 0;
530 TUNER_LG_TDVS_H06XF); 555
531 } 556 return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
557 TUNER_LG_TDVS_H06XF);
532} 558}
533#endif 559#endif
534 560
@@ -659,22 +685,24 @@ static struct stv0297_config alps_tdee4_stv0297_config = {
659 .inittab = alps_tdee4_stv0297_inittab, 685 .inittab = alps_tdee4_stv0297_inittab,
660}; 686};
661 687
662static void cablestar2_attach(struct flexcop_device *fc, 688static int cablestar2_attach(struct flexcop_device *fc,
663 struct i2c_adapter *i2c) 689 struct i2c_adapter *i2c)
664{ 690{
665 fc->fc_i2c_adap[0].no_base_addr = 1; 691 fc->fc_i2c_adap[0].no_base_addr = 1;
666 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); 692 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
667 if (fc->fe != NULL) 693 if (!fc->fe) {
668 fc->fe->ops.tuner_ops.set_params \ 694 /* Reset for next frontend to try */
669 = alps_tdee4_stv0297_tuner_set_params;
670 else
671 fc->fc_i2c_adap[0].no_base_addr = 0; 695 fc->fc_i2c_adap[0].no_base_addr = 0;
696 return 0;
697 }
698 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
699 return 1;
672} 700}
673#endif 701#endif
674 702
675static struct { 703static struct {
676 flexcop_device_type_t type; 704 flexcop_device_type_t type;
677 void (*attach)(struct flexcop_device *, struct i2c_adapter *); 705 int (*attach)(struct flexcop_device *, struct i2c_adapter *);
678} flexcop_frontends[] = { 706} flexcop_frontends[] = {
679#if defined(CONFIG_DVB_S5H1420_MODULE) 707#if defined(CONFIG_DVB_S5H1420_MODULE)
680 { FC_SKY_REV27, skystar2_rev27_attach }, 708 { FC_SKY_REV27, skystar2_rev27_attach },
@@ -713,9 +741,13 @@ int flexcop_frontend_init(struct flexcop_device *fc)
713 /* type needs to be set before, because of some workarounds 741 /* type needs to be set before, because of some workarounds
714 * done based on the probed card type */ 742 * done based on the probed card type */
715 fc->dev_type = flexcop_frontends[i].type; 743 fc->dev_type = flexcop_frontends[i].type;
716 flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap); 744 if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
717 if (fc->fe != NULL)
718 goto fe_found; 745 goto fe_found;
746 /* Clean up partially attached frontend */
747 if (fc->fe) {
748 dvb_frontend_detach(fc->fe);
749 fc->fe = NULL;
750 }
719 } 751 }
720 fc->dev_type = FC_UNK; 752 fc->dev_type = FC_UNK;
721 err("no frontend driver found for this B2C2/FlexCop adapter"); 753 err("no frontend driver found for this B2C2/FlexCop adapter");
@@ -724,10 +756,8 @@ int flexcop_frontend_init(struct flexcop_device *fc)
724fe_found: 756fe_found:
725 info("found '%s' .", fc->fe->ops.info.name); 757 info("found '%s' .", fc->fe->ops.info.name);
726 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { 758 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
727 struct dvb_frontend_ops *ops = &fc->fe->ops;
728 err("frontend registration failed!"); 759 err("frontend registration failed!");
729 if (ops->release != NULL) 760 dvb_frontend_detach(fc->fe);
730 ops->release(fc->fe);
731 fc->fe = NULL; 761 fc->fe = NULL;
732 return -EINVAL; 762 return -EINVAL;
733 } 763 }