diff options
-rw-r--r-- | drivers/media/video/msp3400-driver.c | 190 | ||||
-rw-r--r-- | drivers/media/video/msp3400-kthreads.c | 40 | ||||
-rw-r--r-- | drivers/media/video/msp3400.h | 6 |
3 files changed, 156 insertions, 80 deletions
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 0c2ab7e9d1cc..04a05d7dd470 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -283,33 +283,57 @@ void msp_set_scart(struct i2c_client *client, int in, int out) | |||
283 | 283 | ||
284 | void msp_set_mute(struct i2c_client *client) | 284 | void msp_set_mute(struct i2c_client *client) |
285 | { | 285 | { |
286 | struct msp_state *state = i2c_get_clientdata(client); | ||
287 | |||
286 | v4l_dbg(1, client, "mute audio\n"); | 288 | v4l_dbg(1, client, "mute audio\n"); |
287 | msp_write_dsp(client, 0x0000, 0); /* loudspeaker */ | 289 | msp_write_dsp(client, 0x0000, 0); |
288 | msp_write_dsp(client, 0x0006, 0); /* headphones */ | 290 | msp_write_dsp(client, 0x0007, 1); |
291 | if (state->has_scart2_out_volume) | ||
292 | msp_write_dsp(client, 0x0040, 1); | ||
293 | if (state->has_headphones) | ||
294 | msp_write_dsp(client, 0x0006, 0); | ||
289 | } | 295 | } |
290 | 296 | ||
291 | void msp_set_audio(struct i2c_client *client) | 297 | void msp_set_audio(struct i2c_client *client) |
292 | { | 298 | { |
293 | struct msp_state *state = i2c_get_clientdata(client); | 299 | struct msp_state *state = i2c_get_clientdata(client); |
294 | int val = 0, bal = 0, bass, treble; | 300 | int bal = 0, bass, treble, loudness; |
301 | int val = 0; | ||
295 | 302 | ||
296 | if (!state->muted) | 303 | if (!state->muted) |
297 | val = (state->volume * 0x7f / 65535) << 8; | 304 | val = (state->volume * 0x7f / 65535) << 8; |
305 | |||
306 | v4l_dbg(1, client, "mute=%s volume=%d\n", | ||
307 | state->muted ? "on" : "off", state->volume); | ||
308 | |||
309 | msp_write_dsp(client, 0x0000, val); | ||
310 | msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); | ||
311 | if (state->has_scart2_out_volume) | ||
312 | msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1)); | ||
313 | if (state->has_headphones) | ||
314 | msp_write_dsp(client, 0x0006, val); | ||
315 | if (!state->has_sound_processing) | ||
316 | return; | ||
317 | |||
298 | if (val) | 318 | if (val) |
299 | bal = (state->balance / 256) - 128; | 319 | bal = (u8)((state->balance / 256) - 128); |
300 | bass = ((state->bass - 32768) * 0x60 / 65535) << 8; | 320 | bass = ((state->bass - 32768) * 0x60 / 65535) << 8; |
301 | treble = ((state->treble - 32768) * 0x60 / 65535) << 8; | 321 | treble = ((state->treble - 32768) * 0x60 / 65535) << 8; |
322 | loudness = state->loudness ? ((5 * 4) << 8) : 0; | ||
302 | 323 | ||
303 | v4l_dbg(1, client, "mute=%s volume=%d balance=%d bass=%d treble=%d\n", | 324 | v4l_dbg(1, client, "balance=%d bass=%d treble=%d loudness=%d\n", |
304 | state->muted ? "on" : "off", state->volume, state->balance, | 325 | state->balance, state->bass, state->treble, state->loudness); |
305 | state->bass, state->treble); | ||
306 | 326 | ||
307 | msp_write_dsp(client, 0x0000, val); /* loudspeaker */ | ||
308 | msp_write_dsp(client, 0x0006, val); /* headphones */ | ||
309 | msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); | ||
310 | msp_write_dsp(client, 0x0001, bal << 8); | 327 | msp_write_dsp(client, 0x0001, bal << 8); |
311 | msp_write_dsp(client, 0x0002, bass); /* loudspeaker */ | 328 | msp_write_dsp(client, 0x0002, bass); |
312 | msp_write_dsp(client, 0x0003, treble); /* loudspeaker */ | 329 | msp_write_dsp(client, 0x0003, treble); |
330 | msp_write_dsp(client, 0x0004, loudness); | ||
331 | if (!state->has_headphones) | ||
332 | return; | ||
333 | msp_write_dsp(client, 0x0030, bal << 8); | ||
334 | msp_write_dsp(client, 0x0031, bass); | ||
335 | msp_write_dsp(client, 0x0032, treble); | ||
336 | msp_write_dsp(client, 0x0033, loudness); | ||
313 | } | 337 | } |
314 | 338 | ||
315 | int msp_modus(struct i2c_client *client) | 339 | int msp_modus(struct i2c_client *client) |
@@ -421,7 +445,7 @@ static void msp_any_detect_stereo(struct i2c_client *client) | |||
421 | } | 445 | } |
422 | } | 446 | } |
423 | 447 | ||
424 | static struct v4l2_queryctrl msp_qctrl[] = { | 448 | static struct v4l2_queryctrl msp_qctrl_std[] = { |
425 | { | 449 | { |
426 | .id = V4L2_CID_AUDIO_VOLUME, | 450 | .id = V4L2_CID_AUDIO_VOLUME, |
427 | .name = "Volume", | 451 | .name = "Volume", |
@@ -432,15 +456,6 @@ static struct v4l2_queryctrl msp_qctrl[] = { | |||
432 | .flags = 0, | 456 | .flags = 0, |
433 | .type = V4L2_CTRL_TYPE_INTEGER, | 457 | .type = V4L2_CTRL_TYPE_INTEGER, |
434 | },{ | 458 | },{ |
435 | .id = V4L2_CID_AUDIO_BALANCE, | ||
436 | .name = "Balance", | ||
437 | .minimum = 0, | ||
438 | .maximum = 65535, | ||
439 | .step = 65535/100, | ||
440 | .default_value = 32768, | ||
441 | .flags = 0, | ||
442 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
443 | },{ | ||
444 | .id = V4L2_CID_AUDIO_MUTE, | 459 | .id = V4L2_CID_AUDIO_MUTE, |
445 | .name = "Mute", | 460 | .name = "Mute", |
446 | .minimum = 0, | 461 | .minimum = 0, |
@@ -449,6 +464,19 @@ static struct v4l2_queryctrl msp_qctrl[] = { | |||
449 | .default_value = 1, | 464 | .default_value = 1, |
450 | .flags = 0, | 465 | .flags = 0, |
451 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 466 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
467 | }, | ||
468 | }; | ||
469 | |||
470 | static struct v4l2_queryctrl msp_qctrl_sound_processing[] = { | ||
471 | { | ||
472 | .id = V4L2_CID_AUDIO_BALANCE, | ||
473 | .name = "Balance", | ||
474 | .minimum = 0, | ||
475 | .maximum = 65535, | ||
476 | .step = 65535/100, | ||
477 | .default_value = 32768, | ||
478 | .flags = 0, | ||
479 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
452 | },{ | 480 | },{ |
453 | .id = V4L2_CID_AUDIO_BASS, | 481 | .id = V4L2_CID_AUDIO_BASS, |
454 | .name = "Bass", | 482 | .name = "Bass", |
@@ -465,6 +493,15 @@ static struct v4l2_queryctrl msp_qctrl[] = { | |||
465 | .step = 65535/100, | 493 | .step = 65535/100, |
466 | .default_value = 32768, | 494 | .default_value = 32768, |
467 | .type = V4L2_CTRL_TYPE_INTEGER, | 495 | .type = V4L2_CTRL_TYPE_INTEGER, |
496 | },{ | ||
497 | .id = V4L2_CID_AUDIO_LOUDNESS, | ||
498 | .name = "Loudness", | ||
499 | .minimum = 0, | ||
500 | .maximum = 1, | ||
501 | .step = 1, | ||
502 | .default_value = 1, | ||
503 | .flags = 0, | ||
504 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
468 | }, | 505 | }, |
469 | }; | 506 | }; |
470 | 507 | ||
@@ -490,24 +527,36 @@ static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
490 | struct msp_state *state = i2c_get_clientdata(client); | 527 | struct msp_state *state = i2c_get_clientdata(client); |
491 | 528 | ||
492 | switch (ctrl->id) { | 529 | switch (ctrl->id) { |
530 | case V4L2_CID_AUDIO_VOLUME: | ||
531 | ctrl->value = state->volume; | ||
532 | break; | ||
533 | |||
493 | case V4L2_CID_AUDIO_MUTE: | 534 | case V4L2_CID_AUDIO_MUTE: |
494 | ctrl->value = state->muted; | 535 | ctrl->value = state->muted; |
495 | break; | 536 | break; |
496 | 537 | ||
497 | case V4L2_CID_AUDIO_BALANCE: | 538 | case V4L2_CID_AUDIO_BALANCE: |
539 | if (!state->has_sound_processing) | ||
540 | return -EINVAL; | ||
498 | ctrl->value = state->balance; | 541 | ctrl->value = state->balance; |
499 | break; | 542 | break; |
500 | 543 | ||
501 | case V4L2_CID_AUDIO_BASS: | 544 | case V4L2_CID_AUDIO_BASS: |
545 | if (!state->has_sound_processing) | ||
546 | return -EINVAL; | ||
502 | ctrl->value = state->bass; | 547 | ctrl->value = state->bass; |
503 | break; | 548 | break; |
504 | 549 | ||
505 | case V4L2_CID_AUDIO_TREBLE: | 550 | case V4L2_CID_AUDIO_TREBLE: |
551 | if (!state->has_sound_processing) | ||
552 | return -EINVAL; | ||
506 | ctrl->value = state->treble; | 553 | ctrl->value = state->treble; |
507 | break; | 554 | break; |
508 | 555 | ||
509 | case V4L2_CID_AUDIO_VOLUME: | 556 | case V4L2_CID_AUDIO_LOUDNESS: |
510 | ctrl->value = state->volume; | 557 | if (!state->has_sound_processing) |
558 | return -EINVAL; | ||
559 | ctrl->value = state->loudness; | ||
511 | break; | 560 | break; |
512 | 561 | ||
513 | default: | 562 | default: |
@@ -521,6 +570,12 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
521 | struct msp_state *state = i2c_get_clientdata(client); | 570 | struct msp_state *state = i2c_get_clientdata(client); |
522 | 571 | ||
523 | switch (ctrl->id) { | 572 | switch (ctrl->id) { |
573 | case V4L2_CID_AUDIO_VOLUME: | ||
574 | state->volume = ctrl->value; | ||
575 | if (state->volume == 0) | ||
576 | state->balance = 32768; | ||
577 | break; | ||
578 | |||
524 | case V4L2_CID_AUDIO_MUTE: | 579 | case V4L2_CID_AUDIO_MUTE: |
525 | if (ctrl->value < 0 || ctrl->value >= 2) | 580 | if (ctrl->value < 0 || ctrl->value >= 2) |
526 | return -ERANGE; | 581 | return -ERANGE; |
@@ -528,21 +583,27 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
528 | break; | 583 | break; |
529 | 584 | ||
530 | case V4L2_CID_AUDIO_BASS: | 585 | case V4L2_CID_AUDIO_BASS: |
586 | if (!state->has_sound_processing) | ||
587 | return -EINVAL; | ||
531 | state->bass = ctrl->value; | 588 | state->bass = ctrl->value; |
532 | break; | 589 | break; |
533 | 590 | ||
534 | case V4L2_CID_AUDIO_TREBLE: | 591 | case V4L2_CID_AUDIO_TREBLE: |
592 | if (!state->has_sound_processing) | ||
593 | return -EINVAL; | ||
535 | state->treble = ctrl->value; | 594 | state->treble = ctrl->value; |
536 | break; | 595 | break; |
537 | 596 | ||
538 | case V4L2_CID_AUDIO_BALANCE: | 597 | case V4L2_CID_AUDIO_LOUDNESS: |
539 | state->balance = ctrl->value; | 598 | if (!state->has_sound_processing) |
599 | return -EINVAL; | ||
600 | state->loudness = ctrl->value; | ||
540 | break; | 601 | break; |
541 | 602 | ||
542 | case V4L2_CID_AUDIO_VOLUME: | 603 | case V4L2_CID_AUDIO_BALANCE: |
543 | state->volume = ctrl->value; | 604 | if (!state->has_sound_processing) |
544 | if (state->volume == 0) | 605 | return -EINVAL; |
545 | state->balance = 32768; | 606 | state->balance = ctrl->value; |
546 | break; | 607 | break; |
547 | 608 | ||
548 | default: | 609 | default: |
@@ -628,13 +689,11 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
628 | { | 689 | { |
629 | struct video_audio *va = arg; | 690 | struct video_audio *va = arg; |
630 | 691 | ||
631 | va->flags |= VIDEO_AUDIO_VOLUME | | 692 | va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE; |
632 | VIDEO_AUDIO_BASS | | 693 | if (state->has_sound_processing) |
633 | VIDEO_AUDIO_TREBLE | | 694 | va->flags |= VIDEO_AUDIO_BALANCE | |
634 | VIDEO_AUDIO_MUTABLE; | 695 | VIDEO_AUDIO_BASS | |
635 | if (state->muted) | 696 | VIDEO_AUDIO_TREBLE; |
636 | va->flags |= VIDEO_AUDIO_MUTE; | ||
637 | |||
638 | if (state->muted) | 697 | if (state->muted) |
639 | va->flags |= VIDEO_AUDIO_MUTE; | 698 | va->flags |= VIDEO_AUDIO_MUTE; |
640 | va->volume = state->volume; | 699 | va->volume = state->volume; |
@@ -642,7 +701,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
642 | va->bass = state->bass; | 701 | va->bass = state->bass; |
643 | va->treble = state->treble; | 702 | va->treble = state->treble; |
644 | 703 | ||
645 | msp_any_detect_stereo(client); | 704 | if (state->opmode == OPMODE_AUTOSELECT) |
705 | msp_any_detect_stereo(client); | ||
646 | va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); | 706 | va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); |
647 | break; | 707 | break; |
648 | } | 708 | } |
@@ -666,15 +726,24 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
666 | case VIDIOCSCHAN: | 726 | case VIDIOCSCHAN: |
667 | { | 727 | { |
668 | struct video_channel *vc = arg; | 728 | struct video_channel *vc = arg; |
729 | int update = 0; | ||
730 | v4l2_std_id std; | ||
669 | 731 | ||
732 | if (state->radio) | ||
733 | update = 1; | ||
670 | state->radio = 0; | 734 | state->radio = 0; |
671 | if (vc->norm == VIDEO_MODE_PAL) | 735 | if (vc->norm == VIDEO_MODE_PAL) |
672 | state->std = V4L2_STD_PAL; | 736 | std = V4L2_STD_PAL; |
673 | else if (vc->norm == VIDEO_MODE_SECAM) | 737 | else if (vc->norm == VIDEO_MODE_SECAM) |
674 | state->std = V4L2_STD_SECAM; | 738 | std = V4L2_STD_SECAM; |
675 | else | 739 | else |
676 | state->std = V4L2_STD_NTSC; | 740 | std = V4L2_STD_NTSC; |
677 | msp_wake_thread(client); | 741 | if (std != state->std) { |
742 | state->std = std; | ||
743 | update = 1; | ||
744 | } | ||
745 | if (update) | ||
746 | msp_wake_thread(client); | ||
678 | break; | 747 | break; |
679 | } | 748 | } |
680 | 749 | ||
@@ -699,10 +768,12 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
699 | case VIDIOC_S_STD: | 768 | case VIDIOC_S_STD: |
700 | { | 769 | { |
701 | v4l2_std_id *id = arg; | 770 | v4l2_std_id *id = arg; |
771 | int update = state->radio || state->std != *id; | ||
702 | 772 | ||
703 | state->std = *id; | 773 | state->std = *id; |
704 | state->radio = 0; | 774 | state->radio = 0; |
705 | msp_wake_thread(client); | 775 | if (update) |
776 | msp_wake_thread(client); | ||
706 | return 0; | 777 | return 0; |
707 | } | 778 | } |
708 | 779 | ||
@@ -808,7 +879,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
808 | { | 879 | { |
809 | struct v4l2_tuner *vt = arg; | 880 | struct v4l2_tuner *vt = arg; |
810 | 881 | ||
811 | msp_any_detect_stereo(client); | 882 | if (state->opmode == OPMODE_AUTOSELECT) |
883 | msp_any_detect_stereo(client); | ||
812 | vt->audmode = state->audmode; | 884 | vt->audmode = state->audmode; |
813 | vt->rxsubchans = state->rxsubchans; | 885 | vt->rxsubchans = state->rxsubchans; |
814 | vt->capability = V4L2_TUNER_CAP_STEREO | | 886 | vt->capability = V4L2_TUNER_CAP_STEREO | |
@@ -887,9 +959,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
887 | struct v4l2_queryctrl *qc = arg; | 959 | struct v4l2_queryctrl *qc = arg; |
888 | int i; | 960 | int i; |
889 | 961 | ||
890 | for (i = 0; i < ARRAY_SIZE(msp_qctrl); i++) | 962 | for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++) |
891 | if (qc->id && qc->id == msp_qctrl[i].id) { | 963 | if (qc->id && qc->id == msp_qctrl_std[i].id) { |
892 | memcpy(qc, &msp_qctrl[i], sizeof(*qc)); | 964 | memcpy(qc, &msp_qctrl_std[i], sizeof(*qc)); |
965 | return 0; | ||
966 | } | ||
967 | if (!state->has_sound_processing) | ||
968 | return -EINVAL; | ||
969 | for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++) | ||
970 | if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) { | ||
971 | memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc)); | ||
893 | return 0; | 972 | return 0; |
894 | } | 973 | } |
895 | return -EINVAL; | 974 | return -EINVAL; |
@@ -902,13 +981,17 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
902 | return msp_set_ctrl(client, arg); | 981 | return msp_set_ctrl(client, arg); |
903 | 982 | ||
904 | case VIDIOC_LOG_STATUS: | 983 | case VIDIOC_LOG_STATUS: |
905 | msp_any_detect_stereo(client); | 984 | if (state->opmode == OPMODE_AUTOSELECT) |
985 | msp_any_detect_stereo(client); | ||
906 | v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", | 986 | v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", |
907 | client->name, state->rev1, state->rev2); | 987 | client->name, state->rev1, state->rev2); |
908 | v4l_info(client, "Audio: volume %d balance %d bass %d treble %d%s\n", | 988 | v4l_info(client, "Audio: volume %d%s\n", |
909 | state->volume, state->balance, | 989 | state->volume, state->muted ? " (muted)" : ""); |
910 | state->bass, state->treble, | 990 | if (state->has_sound_processing) { |
911 | state->muted ? " (muted)" : ""); | 991 | v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n", |
992 | state->balance, state->bass, state->treble, | ||
993 | state->loudness ? "on" : "off"); | ||
994 | } | ||
912 | v4l_info(client, "Mode: %s (%s%s)\n", msp_standard_mode_name(state->mode), | 995 | v4l_info(client, "Mode: %s (%s%s)\n", msp_standard_mode_name(state->mode), |
913 | (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", | 996 | (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", |
914 | (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); | 997 | (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); |
@@ -983,6 +1066,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
983 | state->balance = 32768; /* 0db gain */ | 1066 | state->balance = 32768; /* 0db gain */ |
984 | state->bass = 32768; | 1067 | state->bass = 32768; |
985 | state->treble = 32768; | 1068 | state->treble = 32768; |
1069 | state->loudness = 0; | ||
986 | state->input = -1; | 1070 | state->input = -1; |
987 | state->muted = 0; | 1071 | state->muted = 0; |
988 | state->i2s_mode = 0; | 1072 | state->i2s_mode = 0; |
@@ -1023,6 +1107,8 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1023 | /* Has scart2 and scart3 inputs and scart2 output: not in stripped | 1107 | /* Has scart2 and scart3 inputs and scart2 output: not in stripped |
1024 | down products of the '3' family */ | 1108 | down products of the '3' family */ |
1025 | state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; | 1109 | state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; |
1110 | /* Has scart2 a volume control? Not in pre-D revisions. */ | ||
1111 | state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out; | ||
1026 | /* Has subwoofer output: not in pre-D revs and not in stripped down products */ | 1112 | /* Has subwoofer output: not in pre-D revs and not in stripped down products */ |
1027 | state->has_subwoofer = msp_revision >= 'D' && msp_prod_lo < 5; | 1113 | state->has_subwoofer = msp_revision >= 'D' && msp_prod_lo < 5; |
1028 | /* Has soundprocessing (bass/treble/balance/loudness/equalizer): not in | 1114 | /* Has soundprocessing (bass/treble/balance/loudness/equalizer): not in |
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 4ecbf56b008e..14a425a6ff85 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c | |||
@@ -209,24 +209,10 @@ void msp3400c_setmode(struct i2c_client *client, int type) | |||
209 | } | 209 | } |
210 | } | 210 | } |
211 | 211 | ||
212 | /* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */ | ||
213 | static int msp3400c_best_video_sound(int rxsubchans) | ||
214 | { | ||
215 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | ||
216 | return V4L2_TUNER_MODE_STEREO; | ||
217 | if (rxsubchans & V4L2_TUNER_SUB_LANG1) | ||
218 | return V4L2_TUNER_MODE_LANG1; | ||
219 | if (rxsubchans & V4L2_TUNER_SUB_LANG2) | ||
220 | return V4L2_TUNER_MODE_LANG2; | ||
221 | return V4L2_TUNER_MODE_MONO; | ||
222 | } | ||
223 | |||
224 | /* turn on/off nicam + stereo */ | 212 | /* turn on/off nicam + stereo */ |
225 | void msp3400c_setstereo(struct i2c_client *client, int mode) | 213 | void msp3400c_setstereo(struct i2c_client *client, int mode) |
226 | { | 214 | { |
227 | static char *strmode[] = { "0", "mono", "stereo", "3", | 215 | static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; |
228 | "lang1", "5", "6", "7", "lang2" | ||
229 | }; | ||
230 | struct msp_state *state = i2c_get_clientdata(client); | 216 | struct msp_state *state = i2c_get_clientdata(client); |
231 | int nicam = 0; /* channel source: FM/AM or nicam */ | 217 | int nicam = 0; /* channel source: FM/AM or nicam */ |
232 | int src = 0; | 218 | int src = 0; |
@@ -244,7 +230,7 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) | |||
244 | switch (state->mode) { | 230 | switch (state->mode) { |
245 | case MSP_MODE_FM_TERRA: | 231 | case MSP_MODE_FM_TERRA: |
246 | v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]); | 232 | v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]); |
247 | msp3400c_setcarrier(client,state->second,state->main); | 233 | msp3400c_setcarrier(client, state->second, state->main); |
248 | switch (mode) { | 234 | switch (mode) { |
249 | case V4L2_TUNER_MODE_STEREO: | 235 | case V4L2_TUNER_MODE_STEREO: |
250 | msp_write_dsp(client, 0x000e, 0x3001); | 236 | msp_write_dsp(client, 0x000e, 0x3001); |
@@ -298,7 +284,7 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) | |||
298 | } | 284 | } |
299 | 285 | ||
300 | /* switch audio */ | 286 | /* switch audio */ |
301 | switch (msp3400c_best_video_sound(mode)) { | 287 | switch (mode) { |
302 | case V4L2_TUNER_MODE_STEREO: | 288 | case V4L2_TUNER_MODE_STEREO: |
303 | src = 0x0020 | nicam; | 289 | src = 0x0020 | nicam; |
304 | break; | 290 | break; |
@@ -330,6 +316,9 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) | |||
330 | msp_write_dsp(client, 0x0009, src); | 316 | msp_write_dsp(client, 0x0009, src); |
331 | msp_write_dsp(client, 0x000a, src); | 317 | msp_write_dsp(client, 0x000a, src); |
332 | msp_write_dsp(client, 0x000b, src); | 318 | msp_write_dsp(client, 0x000b, src); |
319 | msp_write_dsp(client, 0x000c, src); | ||
320 | if (state->has_scart23_in_scart2_out) | ||
321 | msp_write_dsp(client, 0x0041, src); | ||
333 | } | 322 | } |
334 | } | 323 | } |
335 | 324 | ||
@@ -455,9 +444,9 @@ static void watch_stereo(struct i2c_client *client) | |||
455 | struct msp_state *state = i2c_get_clientdata(client); | 444 | struct msp_state *state = i2c_get_clientdata(client); |
456 | 445 | ||
457 | if (autodetect_stereo(client)) { | 446 | if (autodetect_stereo(client)) { |
458 | if (state->stereo & V4L2_TUNER_MODE_STEREO) | 447 | if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) |
459 | msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); | 448 | msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); |
460 | else if (state->stereo & VIDEO_SOUND_LANG1) | 449 | else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1) |
461 | msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); | 450 | msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); |
462 | else | 451 | else |
463 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | 452 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
@@ -657,7 +646,7 @@ int msp3410d_thread(void *data) | |||
657 | { | 646 | { |
658 | struct i2c_client *client = data; | 647 | struct i2c_client *client = data; |
659 | struct msp_state *state = i2c_get_clientdata(client); | 648 | struct msp_state *state = i2c_get_clientdata(client); |
660 | int mode,val,i,std; | 649 | int val, i, std; |
661 | 650 | ||
662 | v4l_dbg(1, client, "msp3410 daemon started\n"); | 651 | v4l_dbg(1, client, "msp3410 daemon started\n"); |
663 | 652 | ||
@@ -687,10 +676,11 @@ int msp3410d_thread(void *data) | |||
687 | goto restart; | 676 | goto restart; |
688 | 677 | ||
689 | /* start autodetect */ | 678 | /* start autodetect */ |
690 | mode = msp_modus(client); | 679 | std = 1; |
691 | std = (state->std & V4L2_STD_NTSC) ? 0x20 : 1; | 680 | if (state->std & V4L2_STD_NTSC) |
692 | msp_write_dem(client, 0x30, mode); | 681 | std = 0x20; |
693 | msp_write_dem(client, 0x20, std); | 682 | else |
683 | msp_write_dem(client, 0x20, std); | ||
694 | state->watch_stereo = 0; | 684 | state->watch_stereo = 0; |
695 | 685 | ||
696 | if (debug) | 686 | if (debug) |
@@ -703,7 +693,7 @@ int msp3410d_thread(void *data) | |||
703 | } else { | 693 | } else { |
704 | /* triggered autodetect */ | 694 | /* triggered autodetect */ |
705 | for (;;) { | 695 | for (;;) { |
706 | if (msp_sleep(state,100)) | 696 | if (msp_sleep(state, 100)) |
707 | goto restart; | 697 | goto restart; |
708 | 698 | ||
709 | /* check results */ | 699 | /* check results */ |
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h index 70327506f895..fb44eef5d513 100644 --- a/drivers/media/video/msp3400.h +++ b/drivers/media/video/msp3400.h | |||
@@ -63,6 +63,7 @@ struct msp_state { | |||
63 | int has_ntsc_jp_d_k3; | 63 | int has_ntsc_jp_d_k3; |
64 | int has_scart4; | 64 | int has_scart4; |
65 | int has_scart23_in_scart2_out; | 65 | int has_scart23_in_scart2_out; |
66 | int has_scart2_out_volume; | ||
66 | int has_subwoofer; | 67 | int has_subwoofer; |
67 | int has_sound_processing; | 68 | int has_sound_processing; |
68 | int has_virtual_dolby_surround; | 69 | int has_virtual_dolby_surround; |
@@ -72,7 +73,6 @@ struct msp_state { | |||
72 | int opmode; | 73 | int opmode; |
73 | int mode; | 74 | int mode; |
74 | v4l2_std_id std; | 75 | v4l2_std_id std; |
75 | int stereo; | ||
76 | int nicam_on; | 76 | int nicam_on; |
77 | int acb; | 77 | int acb; |
78 | int in_scart; | 78 | int in_scart; |
@@ -85,8 +85,8 @@ struct msp_state { | |||
85 | int audmode; | 85 | int audmode; |
86 | int rxsubchans; | 86 | int rxsubchans; |
87 | 87 | ||
88 | int muted; | 88 | int volume, muted; |
89 | int volume, balance; | 89 | int balance, loudness; |
90 | int bass, treble; | 90 | int bass, treble; |
91 | 91 | ||
92 | /* thread */ | 92 | /* thread */ |