aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/msp3400-kthreads.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2006-03-30 17:50:34 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-04-02 03:56:06 -0400
commit0020d3ef915fc01a0184bc96eeb3c240bded5d8e (patch)
tree89685985691405ae3c407b699a1f8cefa19425ce /drivers/media/video/msp3400-kthreads.c
parent9bc7400a9d01b1fe05c7f0200e7384e17794f6e4 (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.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 1a4564a7e92..926095c6d82 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}