diff options
Diffstat (limited to 'drivers/media/video/msp3400-driver.c')
-rw-r--r-- | drivers/media/video/msp3400-driver.c | 91 |
1 files changed, 42 insertions, 49 deletions
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index c40e8ba9a2ea..b806999d6e0f 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -279,20 +279,8 @@ void msp_set_scart(struct i2c_client *client, int in, int out) | |||
279 | msp_write_dsp(client, 0x13, state->acb); | 279 | msp_write_dsp(client, 0x13, state->acb); |
280 | 280 | ||
281 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ | 281 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ |
282 | msp_write_dem(client, 0x40, state->i2s_mode); | 282 | if (state->has_i2s_conf) |
283 | } | 283 | msp_write_dem(client, 0x40, state->i2s_mode); |
284 | |||
285 | void msp_set_mute(struct i2c_client *client) | ||
286 | { | ||
287 | struct msp_state *state = i2c_get_clientdata(client); | ||
288 | |||
289 | v4l_dbg(1, msp_debug, client, "mute audio\n"); | ||
290 | msp_write_dsp(client, 0x0000, 0); | ||
291 | msp_write_dsp(client, 0x0007, 1); | ||
292 | if (state->has_scart2_out_volume) | ||
293 | msp_write_dsp(client, 0x0040, 1); | ||
294 | if (state->has_headphones) | ||
295 | msp_write_dsp(client, 0x0006, 0); | ||
296 | } | 284 | } |
297 | 285 | ||
298 | void msp_set_audio(struct i2c_client *client) | 286 | void msp_set_audio(struct i2c_client *client) |
@@ -300,17 +288,19 @@ void msp_set_audio(struct i2c_client *client) | |||
300 | struct msp_state *state = i2c_get_clientdata(client); | 288 | struct msp_state *state = i2c_get_clientdata(client); |
301 | int bal = 0, bass, treble, loudness; | 289 | int bal = 0, bass, treble, loudness; |
302 | int val = 0; | 290 | int val = 0; |
291 | int reallymuted = state->muted | state->scan_in_progress; | ||
303 | 292 | ||
304 | if (!state->muted) | 293 | if (!reallymuted) |
305 | val = (state->volume * 0x7f / 65535) << 8; | 294 | val = (state->volume * 0x7f / 65535) << 8; |
306 | 295 | ||
307 | v4l_dbg(1, msp_debug, client, "mute=%s volume=%d\n", | 296 | v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n", |
308 | state->muted ? "on" : "off", state->volume); | 297 | state->muted ? "on" : "off", state->scan_in_progress ? "yes" : "no", |
298 | state->volume); | ||
309 | 299 | ||
310 | msp_write_dsp(client, 0x0000, val); | 300 | msp_write_dsp(client, 0x0000, val); |
311 | msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); | 301 | msp_write_dsp(client, 0x0007, reallymuted ? 0x1 : (val | 0x1)); |
312 | if (state->has_scart2_out_volume) | 302 | if (state->has_scart2_out_volume) |
313 | msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1)); | 303 | msp_write_dsp(client, 0x0040, reallymuted ? 0x1 : (val | 0x1)); |
314 | if (state->has_headphones) | 304 | if (state->has_headphones) |
315 | msp_write_dsp(client, 0x0006, val); | 305 | msp_write_dsp(client, 0x0006, val); |
316 | if (!state->has_sound_processing) | 306 | if (!state->has_sound_processing) |
@@ -346,7 +336,6 @@ static void msp_wake_thread(struct i2c_client *client) | |||
346 | 336 | ||
347 | if (NULL == state->kthread) | 337 | if (NULL == state->kthread) |
348 | return; | 338 | return; |
349 | msp_set_mute(client); | ||
350 | state->watch_stereo = 0; | 339 | state->watch_stereo = 0; |
351 | state->restart = 1; | 340 | state->restart = 1; |
352 | wake_up_interruptible(&state->wq); | 341 | wake_up_interruptible(&state->wq); |
@@ -374,19 +363,15 @@ int msp_sleep(struct msp_state *state, int timeout) | |||
374 | 363 | ||
375 | /* ------------------------------------------------------------------------ */ | 364 | /* ------------------------------------------------------------------------ */ |
376 | 365 | ||
377 | static int msp_mode_v4l2_to_v4l1(int rxsubchans) | 366 | static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) |
378 | { | 367 | { |
379 | int mode = 0; | 368 | if (rxsubchans == V4L2_TUNER_SUB_MONO) |
380 | 369 | return VIDEO_SOUND_MONO; | |
381 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | 370 | if (rxsubchans == V4L2_TUNER_SUB_STEREO) |
382 | mode |= VIDEO_SOUND_STEREO; | 371 | return VIDEO_SOUND_STEREO; |
383 | if (rxsubchans & V4L2_TUNER_SUB_LANG2) | 372 | if (audmode == V4L2_TUNER_MODE_LANG2) |
384 | mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO; | 373 | return VIDEO_SOUND_LANG2; |
385 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) | 374 | return VIDEO_SOUND_LANG1; |
386 | mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO; | ||
387 | if (mode == 0) | ||
388 | mode |= VIDEO_SOUND_MONO; | ||
389 | return mode; | ||
390 | } | 375 | } |
391 | 376 | ||
392 | static int msp_mode_v4l1_to_v4l2(int mode) | 377 | static int msp_mode_v4l1_to_v4l2(int mode) |
@@ -605,7 +590,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
605 | break; | 590 | break; |
606 | if (state->opmode == OPMODE_AUTOSELECT) | 591 | if (state->opmode == OPMODE_AUTOSELECT) |
607 | msp_detect_stereo(client); | 592 | msp_detect_stereo(client); |
608 | va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); | 593 | va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode); |
609 | break; | 594 | break; |
610 | } | 595 | } |
611 | 596 | ||
@@ -620,7 +605,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
620 | state->treble = va->treble; | 605 | state->treble = va->treble; |
621 | msp_set_audio(client); | 606 | msp_set_audio(client); |
622 | 607 | ||
623 | if (va->mode != 0 && state->radio == 0) { | 608 | if (va->mode != 0 && state->radio == 0 && |
609 | state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) { | ||
624 | state->audmode = msp_mode_v4l1_to_v4l2(va->mode); | 610 | state->audmode = msp_mode_v4l1_to_v4l2(va->mode); |
625 | msp_set_audmode(client); | 611 | msp_set_audmode(client); |
626 | } | 612 | } |
@@ -687,21 +673,23 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
687 | int sc_in = rt->input & 0x7; | 673 | int sc_in = rt->input & 0x7; |
688 | int sc1_out = rt->output & 0xf; | 674 | int sc1_out = rt->output & 0xf; |
689 | int sc2_out = (rt->output >> 4) & 0xf; | 675 | int sc2_out = (rt->output >> 4) & 0xf; |
690 | u16 val; | 676 | u16 val, reg; |
691 | 677 | ||
678 | if (state->routing.input == rt->input && | ||
679 | state->routing.output == rt->output) | ||
680 | break; | ||
692 | state->routing = *rt; | 681 | state->routing = *rt; |
693 | if (state->opmode == OPMODE_AUTOSELECT) { | ||
694 | val = msp_read_dem(client, 0x30) & ~0x100; | ||
695 | msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0)); | ||
696 | } else { | ||
697 | val = msp_read_dem(client, 0xbb) & ~0x100; | ||
698 | msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0)); | ||
699 | } | ||
700 | msp_set_scart(client, sc_in, 0); | 682 | msp_set_scart(client, sc_in, 0); |
701 | msp_set_scart(client, sc1_out, 1); | 683 | msp_set_scart(client, sc1_out, 1); |
702 | msp_set_scart(client, sc2_out, 2); | 684 | msp_set_scart(client, sc2_out, 2); |
703 | msp_set_audmode(client); | 685 | msp_set_audmode(client); |
704 | msp_wake_thread(client); | 686 | reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb; |
687 | val = msp_read_dem(client, reg); | ||
688 | if (tuner != ((val >> 8) & 1)) { | ||
689 | msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8)); | ||
690 | /* wake thread when a new tuner input is chosen */ | ||
691 | msp_wake_thread(client); | ||
692 | } | ||
705 | break; | 693 | break; |
706 | } | 694 | } |
707 | 695 | ||
@@ -715,7 +703,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
715 | msp_detect_stereo(client); | 703 | msp_detect_stereo(client); |
716 | vt->audmode = state->audmode; | 704 | vt->audmode = state->audmode; |
717 | vt->rxsubchans = state->rxsubchans; | 705 | vt->rxsubchans = state->rxsubchans; |
718 | vt->capability = V4L2_TUNER_CAP_STEREO | | 706 | vt->capability |= V4L2_TUNER_CAP_STEREO | |
719 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; | 707 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
720 | break; | 708 | break; |
721 | } | 709 | } |
@@ -726,6 +714,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
726 | 714 | ||
727 | if (state->radio) /* TODO: add mono/stereo support for radio */ | 715 | if (state->radio) /* TODO: add mono/stereo support for radio */ |
728 | break; | 716 | break; |
717 | if (state->audmode == vt->audmode) | ||
718 | break; | ||
729 | state->audmode = vt->audmode; | 719 | state->audmode = vt->audmode; |
730 | /* only set audmode */ | 720 | /* only set audmode */ |
731 | msp_set_audmode(client); | 721 | msp_set_audmode(client); |
@@ -887,7 +877,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
887 | 877 | ||
888 | memset(state, 0, sizeof(*state)); | 878 | memset(state, 0, sizeof(*state)); |
889 | state->v4l2_std = V4L2_STD_NTSC; | 879 | state->v4l2_std = V4L2_STD_NTSC; |
890 | state->audmode = V4L2_TUNER_MODE_LANG1; | 880 | state->audmode = V4L2_TUNER_MODE_STEREO; |
891 | state->volume = 58880; /* 0db gain */ | 881 | state->volume = 58880; /* 0db gain */ |
892 | state->balance = 32768; /* 0db gain */ | 882 | state->balance = 32768; /* 0db gain */ |
893 | state->bass = 32768; | 883 | state->bass = 32768; |
@@ -931,13 +921,16 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
931 | state->has_radio = msp_revision >= 'G'; | 921 | state->has_radio = msp_revision >= 'G'; |
932 | /* Has headphones output: not for stripped down products */ | 922 | /* Has headphones output: not for stripped down products */ |
933 | state->has_headphones = msp_prod_lo < 5; | 923 | state->has_headphones = msp_prod_lo < 5; |
924 | /* Has scart2 input: not in stripped down products of the '3' family */ | ||
925 | state->has_scart2 = msp_family >= 4 || msp_prod_lo < 7; | ||
926 | /* Has scart3 input: not in stripped down products of the '3' family */ | ||
927 | state->has_scart3 = msp_family >= 4 || msp_prod_lo < 5; | ||
934 | /* Has scart4 input: not in pre D revisions, not in stripped D revs */ | 928 | /* Has scart4 input: not in pre D revisions, not in stripped D revs */ |
935 | state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5); | 929 | state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5); |
936 | /* Has scart2 and scart3 inputs and scart2 output: not in stripped | 930 | /* Has scart2 output: not in stripped down products of the '3' family */ |
937 | down products of the '3' family */ | 931 | state->has_scart2_out = msp_family >= 4 || msp_prod_lo < 5; |
938 | state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; | ||
939 | /* Has scart2 a volume control? Not in pre-D revisions. */ | 932 | /* Has scart2 a volume control? Not in pre-D revisions. */ |
940 | state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out; | 933 | state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart2_out; |
941 | /* Has a configurable i2s out? */ | 934 | /* Has a configurable i2s out? */ |
942 | state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7; | 935 | state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7; |
943 | /* Has subwoofer output: not in pre-D revs and not in stripped down products */ | 936 | /* Has subwoofer output: not in pre-D revs and not in stripped down products */ |