diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-03-30 17:50:34 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-04-02 03:56:06 -0400 |
commit | 0020d3ef915fc01a0184bc96eeb3c240bded5d8e (patch) | |
tree | 89685985691405ae3c407b699a1f8cefa19425ce /drivers/media/video/msp3400-kthreads.c | |
parent | 9bc7400a9d01b1fe05c7f0200e7384e17794f6e4 (diff) |
V4L/DVB (3693): Fix msp3400c and bttv stereo/mono/bilingual detection/handling
- msp3400c did not detect the second carrier, thus being always mono.
- properly mute the msp3400c while detecting the carrier.
- fix checks on the presence of scart2/3 inputs and scart 2 output.
- implement proper audio mode fallbacks for msp3400c/d, identical to the
way msp3400g works.
- MODE_STEREO no longer produces dual languages when set for a bilingual
transmission, instead it falls back to LANG1. Use LANG1_LANG2 to hear
both languages of a bilingual transmission. This is much more intuitive
for the user and is in accordance with the preferred usage in the v4l2
specification.
- bttv tried to implement v4l2 calls with v4l1 calls to the i2c devices,
completely mangling the audmode/rxsubchans handling. v4l2 calls now do
v4l2 calls to the i2c devices.
- fixed broken i2c_vidiocschan in bttv.
- add start/end lines to LOG_STATUS.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/msp3400-kthreads.c')
-rw-r--r-- | drivers/media/video/msp3400-kthreads.c | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 1a4564a7e92f..926095c6d826 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c | |||
@@ -170,7 +170,7 @@ static void msp_set_source(struct i2c_client *client, u16 src) | |||
170 | msp_write_dsp(client, 0x000a, src); | 170 | msp_write_dsp(client, 0x000a, src); |
171 | msp_write_dsp(client, 0x000b, src); | 171 | msp_write_dsp(client, 0x000b, src); |
172 | msp_write_dsp(client, 0x000c, src); | 172 | msp_write_dsp(client, 0x000c, src); |
173 | if (state->has_scart23_in_scart2_out) | 173 | if (state->has_scart2_out) |
174 | msp_write_dsp(client, 0x0041, src); | 174 | msp_write_dsp(client, 0x0041, src); |
175 | } | 175 | } |
176 | 176 | ||
@@ -240,15 +240,22 @@ static void msp3400c_set_audmode(struct i2c_client *client) | |||
240 | return; | 240 | return; |
241 | } | 241 | } |
242 | 242 | ||
243 | /* If no second language is available, switch to the first language */ | 243 | /* Note: for the C and D revs no NTSC stereo + SAP is possible as |
244 | if ((audmode == V4L2_TUNER_MODE_LANG2 || | 244 | the hardware does not support SAP. So the rxsubchans combination |
245 | audmode == V4L2_TUNER_MODE_LANG1_LANG2) && | 245 | of STEREO | LANG2 does not occur. */ |
246 | !(state->rxsubchans & V4L2_TUNER_SUB_LANG2)) | 246 | |
247 | audmode = V4L2_TUNER_MODE_LANG1; | 247 | /* switch to mono if only mono is available */ |
248 | /* switch to stereo for stereo transmission, otherwise | 248 | if (state->rxsubchans == V4L2_TUNER_SUB_MONO) |
249 | keep first language */ | 249 | audmode = V4L2_TUNER_MODE_MONO; |
250 | if (audmode == V4L2_TUNER_MODE_LANG1 && | 250 | /* if bilingual */ |
251 | (state->rxsubchans & V4L2_TUNER_SUB_STEREO)) | 251 | else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { |
252 | /* and mono or stereo, then fallback to lang1 */ | ||
253 | if (audmode == V4L2_TUNER_MODE_MONO || | ||
254 | audmode == V4L2_TUNER_MODE_STEREO) | ||
255 | audmode = V4L2_TUNER_MODE_LANG1; | ||
256 | } | ||
257 | /* if stereo, and audmode is not mono, then switch to stereo */ | ||
258 | else if (audmode != V4L2_TUNER_MODE_MONO) | ||
252 | audmode = V4L2_TUNER_MODE_STEREO; | 259 | audmode = V4L2_TUNER_MODE_STEREO; |
253 | 260 | ||
254 | /* switch demodulator */ | 261 | /* switch demodulator */ |
@@ -308,6 +315,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) | |||
308 | } | 315 | } |
309 | 316 | ||
310 | /* switch audio */ | 317 | /* switch audio */ |
318 | v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode); | ||
311 | switch (audmode) { | 319 | switch (audmode) { |
312 | case V4L2_TUNER_MODE_STEREO: | 320 | case V4L2_TUNER_MODE_STEREO: |
313 | case V4L2_TUNER_MODE_LANG1_LANG2: | 321 | case V4L2_TUNER_MODE_LANG1_LANG2: |
@@ -476,8 +484,9 @@ int msp3400c_thread(void *data) | |||
476 | continue; | 484 | continue; |
477 | } | 485 | } |
478 | 486 | ||
479 | /* mute */ | 487 | /* put into sane state (and mute) */ |
480 | msp_set_mute(client); | 488 | msp_reset(client); |
489 | |||
481 | msp3400c_set_mode(client, MSP_MODE_AM_DETECT); | 490 | msp3400c_set_mode(client, MSP_MODE_AM_DETECT); |
482 | val1 = val2 = 0; | 491 | val1 = val2 = 0; |
483 | max1 = max2 = -1; | 492 | max1 = max2 = -1; |
@@ -560,7 +569,6 @@ int msp3400c_thread(void *data) | |||
560 | /* B/G NICAM */ | 569 | /* B/G NICAM */ |
561 | state->second = msp3400c_carrier_detect_55[max2].cdo; | 570 | state->second = msp3400c_carrier_detect_55[max2].cdo; |
562 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); | 571 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); |
563 | msp3400c_set_carrier(client, state->second, state->main); | ||
564 | state->nicam_on = 1; | 572 | state->nicam_on = 1; |
565 | state->watch_stereo = 1; | 573 | state->watch_stereo = 1; |
566 | } else { | 574 | } else { |
@@ -571,7 +579,6 @@ int msp3400c_thread(void *data) | |||
571 | /* PAL I NICAM */ | 579 | /* PAL I NICAM */ |
572 | state->second = MSP_CARRIER(6.552); | 580 | state->second = MSP_CARRIER(6.552); |
573 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM2); | 581 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM2); |
574 | msp3400c_set_carrier(client, state->second, state->main); | ||
575 | state->nicam_on = 1; | 582 | state->nicam_on = 1; |
576 | state->watch_stereo = 1; | 583 | state->watch_stereo = 1; |
577 | break; | 584 | break; |
@@ -585,13 +592,11 @@ int msp3400c_thread(void *data) | |||
585 | /* L NICAM or AM-mono */ | 592 | /* L NICAM or AM-mono */ |
586 | state->second = msp3400c_carrier_detect_65[max2].cdo; | 593 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
587 | msp3400c_set_mode(client, MSP_MODE_AM_NICAM); | 594 | msp3400c_set_mode(client, MSP_MODE_AM_NICAM); |
588 | msp3400c_set_carrier(client, state->second, state->main); | ||
589 | state->watch_stereo = 1; | 595 | state->watch_stereo = 1; |
590 | } else if (max2 == 0 && state->has_nicam) { | 596 | } else if (max2 == 0 && state->has_nicam) { |
591 | /* D/K NICAM */ | 597 | /* D/K NICAM */ |
592 | state->second = msp3400c_carrier_detect_65[max2].cdo; | 598 | state->second = msp3400c_carrier_detect_65[max2].cdo; |
593 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); | 599 | msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); |
594 | msp3400c_set_carrier(client, state->second, state->main); | ||
595 | state->nicam_on = 1; | 600 | state->nicam_on = 1; |
596 | state->watch_stereo = 1; | 601 | state->watch_stereo = 1; |
597 | } else { | 602 | } else { |
@@ -603,13 +608,15 @@ int msp3400c_thread(void *data) | |||
603 | no_second: | 608 | no_second: |
604 | state->second = msp3400c_carrier_detect_main[max1].cdo; | 609 | state->second = msp3400c_carrier_detect_main[max1].cdo; |
605 | msp3400c_set_mode(client, MSP_MODE_FM_TERRA); | 610 | msp3400c_set_mode(client, MSP_MODE_FM_TERRA); |
606 | msp3400c_set_carrier(client, state->second, state->main); | ||
607 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | 611 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
608 | break; | 612 | break; |
609 | } | 613 | } |
614 | msp3400c_set_carrier(client, state->second, state->main); | ||
610 | 615 | ||
611 | /* unmute */ | 616 | /* unmute, restore misc registers */ |
612 | msp_set_audio(client); | 617 | msp_set_audio(client); |
618 | |||
619 | msp_write_dsp(client, 0x13, state->acb); | ||
613 | msp3400c_set_audmode(client); | 620 | msp3400c_set_audmode(client); |
614 | 621 | ||
615 | if (msp_debug) | 622 | if (msp_debug) |
@@ -617,12 +624,12 @@ int msp3400c_thread(void *data) | |||
617 | 624 | ||
618 | /* monitor tv audio mode, the first time don't wait | 625 | /* monitor tv audio mode, the first time don't wait |
619 | so long to get a quick stereo/bilingual result */ | 626 | so long to get a quick stereo/bilingual result */ |
620 | if (msp_sleep(state, 1000)) | 627 | count = 20; |
621 | goto restart; | ||
622 | while (state->watch_stereo) { | 628 | while (state->watch_stereo) { |
623 | watch_stereo(client); | 629 | watch_stereo(client); |
624 | if (msp_sleep(state, 5000)) | 630 | if (msp_sleep(state, count ? 200 : 5000)) |
625 | goto restart; | 631 | goto restart; |
632 | if (count) count--; | ||
626 | } | 633 | } |
627 | } | 634 | } |
628 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); | 635 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); |
@@ -634,7 +641,7 @@ int msp3410d_thread(void *data) | |||
634 | { | 641 | { |
635 | struct i2c_client *client = data; | 642 | struct i2c_client *client = data; |
636 | struct msp_state *state = i2c_get_clientdata(client); | 643 | struct msp_state *state = i2c_get_clientdata(client); |
637 | int val, i, std; | 644 | int val, i, std, count; |
638 | 645 | ||
639 | v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); | 646 | v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); |
640 | 647 | ||
@@ -775,12 +782,12 @@ int msp3410d_thread(void *data) | |||
775 | 782 | ||
776 | /* monitor tv audio mode, the first time don't wait | 783 | /* monitor tv audio mode, the first time don't wait |
777 | so long to get a quick stereo/bilingual result */ | 784 | so long to get a quick stereo/bilingual result */ |
778 | if (msp_sleep(state, 1000)) | 785 | count = 20; |
779 | goto restart; | ||
780 | while (state->watch_stereo) { | 786 | while (state->watch_stereo) { |
781 | watch_stereo(client); | 787 | watch_stereo(client); |
782 | if (msp_sleep(state, 5000)) | 788 | if (msp_sleep(state, count ? 200 : 5000)) |
783 | goto restart; | 789 | goto restart; |
790 | if (count) count--; | ||
784 | } | 791 | } |
785 | } | 792 | } |
786 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); | 793 | v4l_dbg(1, msp_debug, client, "thread: exit\n"); |
@@ -837,20 +844,20 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) | |||
837 | source = 0; /* mono only */ | 844 | source = 0; /* mono only */ |
838 | matrix = 0x30; | 845 | matrix = 0x30; |
839 | break; | 846 | break; |
840 | case V4L2_TUNER_MODE_LANG1: | ||
841 | source = 3; /* stereo or A */ | ||
842 | matrix = 0x00; | ||
843 | break; | ||
844 | case V4L2_TUNER_MODE_LANG2: | 847 | case V4L2_TUNER_MODE_LANG2: |
845 | source = 4; /* stereo or B */ | 848 | source = 4; /* stereo or B */ |
846 | matrix = 0x10; | 849 | matrix = 0x10; |
847 | break; | 850 | break; |
848 | case V4L2_TUNER_MODE_STEREO: | ||
849 | case V4L2_TUNER_MODE_LANG1_LANG2: | 851 | case V4L2_TUNER_MODE_LANG1_LANG2: |
850 | default: | ||
851 | source = 1; /* stereo or A|B */ | 852 | source = 1; /* stereo or A|B */ |
852 | matrix = 0x20; | 853 | matrix = 0x20; |
853 | break; | 854 | break; |
855 | case V4L2_TUNER_MODE_STEREO: | ||
856 | case V4L2_TUNER_MODE_LANG1: | ||
857 | default: | ||
858 | source = 3; /* stereo or A */ | ||
859 | matrix = 0x00; | ||
860 | break; | ||
854 | } | 861 | } |
855 | 862 | ||
856 | if (in == MSP_DSP_OUT_TUNER) | 863 | if (in == MSP_DSP_OUT_TUNER) |
@@ -877,7 +884,7 @@ static void msp34xxg_set_sources(struct i2c_client *client) | |||
877 | msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf); | 884 | msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf); |
878 | msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf); | 885 | msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf); |
879 | msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf); | 886 | msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf); |
880 | if (state->has_scart23_in_scart2_out) | 887 | if (state->has_scart2_out) |
881 | msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf); | 888 | msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf); |
882 | msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf); | 889 | msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf); |
883 | } | 890 | } |