diff options
Diffstat (limited to 'drivers/media/dvb/frontends/dvb-pll.c')
-rw-r--r-- | drivers/media/dvb/frontends/dvb-pll.c | 147 |
1 files changed, 110 insertions, 37 deletions
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 11f7d5939bd9..8c8d7342d0b3 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -24,12 +24,48 @@ | |||
24 | 24 | ||
25 | #include "dvb-pll.h" | 25 | #include "dvb-pll.h" |
26 | 26 | ||
27 | struct dvb_pll_priv { | ||
28 | /* pll number */ | ||
29 | int nr; | ||
30 | |||
31 | /* i2c details */ | ||
32 | int pll_i2c_address; | ||
33 | struct i2c_adapter *i2c; | ||
34 | |||
35 | /* the PLL descriptor */ | ||
36 | struct dvb_pll_desc *pll_desc; | ||
37 | |||
38 | /* cached frequency/bandwidth */ | ||
39 | u32 frequency; | ||
40 | u32 bandwidth; | ||
41 | }; | ||
42 | |||
43 | #define DVB_PLL_MAX 64 | ||
44 | |||
45 | static unsigned int dvb_pll_devcount; | ||
46 | |||
47 | static int debug = 0; | ||
48 | module_param(debug, int, 0644); | ||
49 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
50 | |||
51 | static unsigned int input[DVB_PLL_MAX] = { [ 0 ... (DVB_PLL_MAX-1) ] = 0 }; | ||
52 | module_param_array(input, int, NULL, 0644); | ||
53 | MODULE_PARM_DESC(input,"specify rf input choice, 0 for autoselect (default)"); | ||
54 | |||
55 | static unsigned int id[DVB_PLL_MAX] = | ||
56 | { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED }; | ||
57 | module_param_array(id, int, NULL, 0644); | ||
58 | MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)"); | ||
59 | |||
60 | /* ----------------------------------------------------------- */ | ||
61 | |||
27 | struct dvb_pll_desc { | 62 | struct dvb_pll_desc { |
28 | char *name; | 63 | char *name; |
29 | u32 min; | 64 | u32 min; |
30 | u32 max; | 65 | u32 max; |
31 | u32 iffreq; | 66 | u32 iffreq; |
32 | void (*set)(u8 *buf, const struct dvb_frontend_parameters *params); | 67 | void (*set)(struct dvb_frontend *fe, u8 *buf, |
68 | const struct dvb_frontend_parameters *params); | ||
33 | u8 *initdata; | 69 | u8 *initdata; |
34 | u8 *sleepdata; | 70 | u8 *sleepdata; |
35 | int count; | 71 | int count; |
@@ -89,7 +125,7 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { | |||
89 | }, | 125 | }, |
90 | }; | 126 | }; |
91 | 127 | ||
92 | static void thomson_dtt759x_bw(u8 *buf, | 128 | static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf, |
93 | const struct dvb_frontend_parameters *params) | 129 | const struct dvb_frontend_parameters *params) |
94 | { | 130 | { |
95 | if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth) | 131 | if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth) |
@@ -210,7 +246,8 @@ static struct dvb_pll_desc dvb_pll_env57h1xd5 = { | |||
210 | /* Philips TDA6650/TDA6651 | 246 | /* Philips TDA6650/TDA6651 |
211 | * used in Panasonic ENV77H11D5 | 247 | * used in Panasonic ENV77H11D5 |
212 | */ | 248 | */ |
213 | static void tda665x_bw(u8 *buf, const struct dvb_frontend_parameters *params) | 249 | static void tda665x_bw(struct dvb_frontend *fe, u8 *buf, |
250 | const struct dvb_frontend_parameters *params) | ||
214 | { | 251 | { |
215 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) | 252 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) |
216 | buf[3] |= 0x08; | 253 | buf[3] |= 0x08; |
@@ -243,7 +280,8 @@ static struct dvb_pll_desc dvb_pll_tda665x = { | |||
243 | /* Infineon TUA6034 | 280 | /* Infineon TUA6034 |
244 | * used in LG TDTP E102P | 281 | * used in LG TDTP E102P |
245 | */ | 282 | */ |
246 | static void tua6034_bw(u8 *buf, const struct dvb_frontend_parameters *params) | 283 | static void tua6034_bw(struct dvb_frontend *fe, u8 *buf, |
284 | const struct dvb_frontend_parameters *params) | ||
247 | { | 285 | { |
248 | if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth) | 286 | if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth) |
249 | buf[3] |= 0x08; | 287 | buf[3] |= 0x08; |
@@ -283,7 +321,8 @@ static struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { | |||
283 | /* Philips FMD1216ME | 321 | /* Philips FMD1216ME |
284 | * used in Medion Hybrid PCMCIA card and USB Box | 322 | * used in Medion Hybrid PCMCIA card and USB Box |
285 | */ | 323 | */ |
286 | static void fmd1216me_bw(u8 *buf, const struct dvb_frontend_parameters *params) | 324 | static void fmd1216me_bw(struct dvb_frontend *fe, u8 *buf, |
325 | const struct dvb_frontend_parameters *params) | ||
287 | { | 326 | { |
288 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && | 327 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && |
289 | params->frequency >= 158870000) | 328 | params->frequency >= 158870000) |
@@ -313,7 +352,8 @@ static struct dvb_pll_desc dvb_pll_fmd1216me = { | |||
313 | /* ALPS TDED4 | 352 | /* ALPS TDED4 |
314 | * used in Nebula-Cards and USB boxes | 353 | * used in Nebula-Cards and USB boxes |
315 | */ | 354 | */ |
316 | static void tded4_bw(u8 *buf, const struct dvb_frontend_parameters *params) | 355 | static void tded4_bw(struct dvb_frontend *fe, u8 *buf, |
356 | const struct dvb_frontend_parameters *params) | ||
317 | { | 357 | { |
318 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) | 358 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) |
319 | buf[3] |= 0x04; | 359 | buf[3] |= 0x04; |
@@ -354,16 +394,35 @@ static struct dvb_pll_desc dvb_pll_tdhu2 = { | |||
354 | /* Philips TUV1236D | 394 | /* Philips TUV1236D |
355 | * used in ATI HDTV Wonder | 395 | * used in ATI HDTV Wonder |
356 | */ | 396 | */ |
357 | static void tuv1236d_rf(u8 *buf, const struct dvb_frontend_parameters *params) | 397 | static void tuv1236d_rf(struct dvb_frontend *fe, u8 *buf, |
398 | const struct dvb_frontend_parameters *params) | ||
358 | { | 399 | { |
359 | switch (params->u.vsb.modulation) { | 400 | struct dvb_pll_priv *priv = fe->tuner_priv; |
360 | case QAM_64: | 401 | unsigned int new_rf = input[priv->nr]; |
361 | case QAM_256: | 402 | |
403 | if ((new_rf == 0) || (new_rf > 2)) { | ||
404 | switch (params->u.vsb.modulation) { | ||
405 | case QAM_64: | ||
406 | case QAM_256: | ||
407 | new_rf = 1; | ||
408 | break; | ||
409 | case VSB_8: | ||
410 | default: | ||
411 | new_rf = 2; | ||
412 | } | ||
413 | } | ||
414 | |||
415 | switch (new_rf) { | ||
416 | case 1: | ||
362 | buf[3] |= 0x08; | 417 | buf[3] |= 0x08; |
363 | break; | 418 | break; |
364 | case VSB_8: | 419 | case 2: |
365 | default: | ||
366 | buf[3] &= ~0x08; | 420 | buf[3] &= ~0x08; |
421 | break; | ||
422 | default: | ||
423 | printk(KERN_WARNING | ||
424 | "%s: unhandled rf input selection: %d", | ||
425 | __FUNCTION__, new_rf); | ||
367 | } | 426 | } |
368 | } | 427 | } |
369 | 428 | ||
@@ -420,7 +479,8 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { | |||
420 | /* | 479 | /* |
421 | * Philips TD1316 Tuner. | 480 | * Philips TD1316 Tuner. |
422 | */ | 481 | */ |
423 | static void td1316_bw(u8 *buf, const struct dvb_frontend_parameters *params) | 482 | static void td1316_bw(struct dvb_frontend *fe, u8 *buf, |
483 | const struct dvb_frontend_parameters *params) | ||
424 | { | 484 | { |
425 | u8 band; | 485 | u8 band; |
426 | 486 | ||
@@ -474,7 +534,8 @@ static struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | |||
474 | } | 534 | } |
475 | }; | 535 | }; |
476 | 536 | ||
477 | static void opera1_bw(u8 *buf, const struct dvb_frontend_parameters *params) | 537 | static void opera1_bw(struct dvb_frontend *fe, u8 *buf, |
538 | const struct dvb_frontend_parameters *params) | ||
478 | { | 539 | { |
479 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) | 540 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) |
480 | buf[2] |= 0x08; | 541 | buf[2] |= 0x08; |
@@ -546,30 +607,13 @@ static struct dvb_pll_desc *pll_list[] = { | |||
546 | }; | 607 | }; |
547 | 608 | ||
548 | /* ----------------------------------------------------------- */ | 609 | /* ----------------------------------------------------------- */ |
549 | |||
550 | struct dvb_pll_priv { | ||
551 | /* i2c details */ | ||
552 | int pll_i2c_address; | ||
553 | struct i2c_adapter *i2c; | ||
554 | |||
555 | /* the PLL descriptor */ | ||
556 | struct dvb_pll_desc *pll_desc; | ||
557 | |||
558 | /* cached frequency/bandwidth */ | ||
559 | u32 frequency; | ||
560 | u32 bandwidth; | ||
561 | }; | ||
562 | |||
563 | /* ----------------------------------------------------------- */ | ||
564 | /* code */ | 610 | /* code */ |
565 | 611 | ||
566 | static int debug = 0; | 612 | static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, |
567 | module_param(debug, int, 0644); | ||
568 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
569 | |||
570 | static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | ||
571 | const struct dvb_frontend_parameters *params) | 613 | const struct dvb_frontend_parameters *params) |
572 | { | 614 | { |
615 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
616 | struct dvb_pll_desc *desc = priv->pll_desc; | ||
573 | u32 div; | 617 | u32 div; |
574 | int i; | 618 | int i; |
575 | 619 | ||
@@ -597,7 +641,7 @@ static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
597 | buf[3] = desc->entries[i].cb; | 641 | buf[3] = desc->entries[i].cb; |
598 | 642 | ||
599 | if (desc->set) | 643 | if (desc->set) |
600 | desc->set(buf, params); | 644 | desc->set(fe, buf, params); |
601 | 645 | ||
602 | if (debug) | 646 | if (debug) |
603 | printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", | 647 | printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", |
@@ -654,7 +698,7 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, | |||
654 | if (priv->i2c == NULL) | 698 | if (priv->i2c == NULL) |
655 | return -EINVAL; | 699 | return -EINVAL; |
656 | 700 | ||
657 | if ((result = dvb_pll_configure(priv->pll_desc, buf, params)) < 0) | 701 | if ((result = dvb_pll_configure(fe, buf, params)) < 0) |
658 | return result; | 702 | return result; |
659 | else | 703 | else |
660 | frequency = result; | 704 | frequency = result; |
@@ -682,7 +726,7 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, | |||
682 | if (buf_len < 5) | 726 | if (buf_len < 5) |
683 | return -EINVAL; | 727 | return -EINVAL; |
684 | 728 | ||
685 | if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params)) < 0) | 729 | if ((result = dvb_pll_configure(fe, buf+1, params)) < 0) |
686 | return result; | 730 | return result; |
687 | else | 731 | else |
688 | frequency = result; | 732 | frequency = result; |
@@ -755,6 +799,10 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, | |||
755 | int ret; | 799 | int ret; |
756 | struct dvb_pll_desc *desc; | 800 | struct dvb_pll_desc *desc; |
757 | 801 | ||
802 | if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) && | ||
803 | (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list))) | ||
804 | pll_desc_id = id[dvb_pll_devcount]; | ||
805 | |||
758 | BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list)); | 806 | BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list)); |
759 | 807 | ||
760 | desc = pll_list[pll_desc_id]; | 808 | desc = pll_list[pll_desc_id]; |
@@ -777,6 +825,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, | |||
777 | priv->pll_i2c_address = pll_addr; | 825 | priv->pll_i2c_address = pll_addr; |
778 | priv->i2c = i2c; | 826 | priv->i2c = i2c; |
779 | priv->pll_desc = desc; | 827 | priv->pll_desc = desc; |
828 | priv->nr = dvb_pll_devcount++; | ||
780 | 829 | ||
781 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, | 830 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, |
782 | sizeof(struct dvb_tuner_ops)); | 831 | sizeof(struct dvb_tuner_ops)); |
@@ -791,6 +840,30 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, | |||
791 | fe->ops.tuner_ops.sleep = NULL; | 840 | fe->ops.tuner_ops.sleep = NULL; |
792 | 841 | ||
793 | fe->tuner_priv = priv; | 842 | fe->tuner_priv = priv; |
843 | |||
844 | if ((debug) || (id[priv->nr] == pll_desc_id)) { | ||
845 | printk("dvb-pll[%d]", priv->nr); | ||
846 | if (i2c != NULL) | ||
847 | printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr); | ||
848 | printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name, | ||
849 | id[priv->nr] == pll_desc_id ? | ||
850 | "insmod option" : "autodetected"); | ||
851 | } | ||
852 | if ((debug) || (input[priv->nr] > 0)) { | ||
853 | printk("dvb-pll[%d]", priv->nr); | ||
854 | if (i2c != NULL) | ||
855 | printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr); | ||
856 | printk(": tuner rf input will be "); | ||
857 | switch (input[priv->nr]) { | ||
858 | case 0: | ||
859 | printk("autoselected\n"); | ||
860 | break; | ||
861 | default: | ||
862 | printk("set to input %d (insmod option)\n", | ||
863 | input[priv->nr]); | ||
864 | } | ||
865 | } | ||
866 | |||
794 | return fe; | 867 | return fe; |
795 | } | 868 | } |
796 | EXPORT_SYMBOL(dvb_pll_attach); | 869 | EXPORT_SYMBOL(dvb_pll_attach); |