diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-03-19 10:35:57 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-03-24 14:26:57 -0500 |
commit | 2474ed444b475614ef795523076be7cc8437ae00 (patch) | |
tree | 87808b3c7ff145b63a638e6e42ffce9db7db1b8c /drivers | |
parent | 49965a80a4c4f5cbe15fb3bb1f8f8b0ec4ef02bc (diff) |
V4L/DVB (3582): Implement correct msp3400 input/output routing
- implement VIDIOC_INT_S_AUDIO_ROUTING for msp3400 and tvaudio
- use the new command in bttv, pvrusb2 and em28xx.
- remove the now obsolete MSP_SET_MATRIX from msp3400 (yeah!)
- remove the obsolete VIDIOC_S_AUDIO from msp3400.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 52 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 8 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 8 | ||||
-rw-r--r-- | drivers/media/video/msp3400-driver.c | 67 | ||||
-rw-r--r-- | drivers/media/video/msp3400-driver.h | 4 | ||||
-rw-r--r-- | drivers/media/video/msp3400-kthreads.c | 111 | ||||
-rw-r--r-- | drivers/media/video/tvaudio.c | 24 | ||||
-rw-r--r-- | drivers/media/video/v4l2-common.c | 13 |
8 files changed, 176 insertions, 111 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index be567ec9e145..80e4a7406ac2 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "bttvp.h" | 37 | #include "bttvp.h" |
38 | #include <media/v4l2-common.h> | 38 | #include <media/v4l2-common.h> |
39 | #include <media/tvaudio.h> | 39 | #include <media/tvaudio.h> |
40 | #include <media/msp3400.h> | ||
40 | 41 | ||
41 | #include <linux/dma-mapping.h> | 42 | #include <linux/dma-mapping.h> |
42 | 43 | ||
@@ -934,11 +935,9 @@ static int | |||
934 | audio_mux(struct bttv *btv, int input, int mute) | 935 | audio_mux(struct bttv *btv, int input, int mute) |
935 | { | 936 | { |
936 | int gpio_val, signal; | 937 | int gpio_val, signal; |
937 | struct v4l2_audio aud_input; | ||
938 | struct v4l2_control ctrl; | 938 | struct v4l2_control ctrl; |
939 | struct i2c_client *c; | 939 | struct i2c_client *c; |
940 | 940 | ||
941 | memset(&aud_input, 0, sizeof(aud_input)); | ||
942 | gpio_inout(bttv_tvcards[btv->c.type].gpiomask, | 941 | gpio_inout(bttv_tvcards[btv->c.type].gpiomask, |
943 | bttv_tvcards[btv->c.type].gpiomask); | 942 | bttv_tvcards[btv->c.type].gpiomask); |
944 | signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; | 943 | signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; |
@@ -953,7 +952,6 @@ audio_mux(struct bttv *btv, int input, int mute) | |||
953 | gpio_val = bttv_tvcards[btv->c.type].gpiomute; | 952 | gpio_val = bttv_tvcards[btv->c.type].gpiomute; |
954 | else | 953 | else |
955 | gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; | 954 | gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; |
956 | aud_input.index = btv->audio; | ||
957 | 955 | ||
958 | gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); | 956 | gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); |
959 | if (bttv_gpio) | 957 | if (bttv_gpio) |
@@ -962,15 +960,51 @@ audio_mux(struct bttv *btv, int input, int mute) | |||
962 | return 0; | 960 | return 0; |
963 | 961 | ||
964 | ctrl.id = V4L2_CID_AUDIO_MUTE; | 962 | ctrl.id = V4L2_CID_AUDIO_MUTE; |
965 | /* take automute into account, just btv->mute is not enough */ | 963 | ctrl.value = btv->mute; |
966 | ctrl.value = mute; | ||
967 | bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl); | 964 | bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl); |
968 | c = btv->i2c_msp34xx_client; | 965 | c = btv->i2c_msp34xx_client; |
969 | if (c) | 966 | if (c) { |
970 | c->driver->command(c, VIDIOC_S_AUDIO, &aud_input); | 967 | struct v4l2_routing route; |
968 | |||
969 | /* Note: the inputs tuner/radio/extern/intern are translated | ||
970 | to msp routings. This assumes common behavior for all msp3400 | ||
971 | based TV cards. When this assumption fails, then the | ||
972 | specific MSP routing must be added to the card table. | ||
973 | For now this is sufficient. */ | ||
974 | switch (input) { | ||
975 | case TVAUDIO_INPUT_RADIO: | ||
976 | route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1, | ||
977 | MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); | ||
978 | break; | ||
979 | case TVAUDIO_INPUT_EXTERN: | ||
980 | route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, | ||
981 | MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); | ||
982 | break; | ||
983 | case TVAUDIO_INPUT_INTERN: | ||
984 | /* Yes, this is the same input as for RADIO. I doubt | ||
985 | if this is ever used. The only board with an INTERN | ||
986 | input is the BTTV_BOARD_AVERMEDIA98. I wonder how | ||
987 | that was tested. My guess is that the whole INTERN | ||
988 | input does not work. */ | ||
989 | route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1, | ||
990 | MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART); | ||
991 | break; | ||
992 | case TVAUDIO_INPUT_TUNER: | ||
993 | default: | ||
994 | route.input = MSP_INPUT_DEFAULT; | ||
995 | break; | ||
996 | } | ||
997 | route.output = MSP_OUTPUT_DEFAULT; | ||
998 | c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route); | ||
999 | } | ||
971 | c = btv->i2c_tvaudio_client; | 1000 | c = btv->i2c_tvaudio_client; |
972 | if (c) | 1001 | if (c) { |
973 | c->driver->command(c, VIDIOC_S_AUDIO, &aud_input); | 1002 | struct v4l2_routing route; |
1003 | |||
1004 | route.input = input; | ||
1005 | route.output = 0; | ||
1006 | c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route); | ||
1007 | } | ||
974 | return 0; | 1008 | return 0; |
975 | } | 1009 | } |
976 | 1010 | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 2d68a27417eb..f62fd706b45a 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -28,8 +28,9 @@ | |||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/usb.h> | 29 | #include <linux/usb.h> |
30 | #include <media/tuner.h> | 30 | #include <media/tuner.h> |
31 | #include <media/audiochip.h> | 31 | #include <media/msp3400.h> |
32 | #include <media/tveeprom.h> | 32 | #include <media/tveeprom.h> |
33 | #include <media/audiochip.h> | ||
33 | #include <media/v4l2-common.h> | 34 | #include <media/v4l2-common.h> |
34 | 35 | ||
35 | #include "em28xx.h" | 36 | #include "em28xx.h" |
@@ -146,11 +147,12 @@ struct em28xx_board em28xx_boards[] = { | |||
146 | .input = {{ | 147 | .input = {{ |
147 | .type = EM28XX_VMUX_TELEVISION, | 148 | .type = EM28XX_VMUX_TELEVISION, |
148 | .vmux = 0, | 149 | .vmux = 0, |
149 | .amux = 6, | 150 | .amux = MSP_INPUT_DEFAULT, |
150 | },{ | 151 | },{ |
151 | .type = EM28XX_VMUX_SVIDEO, | 152 | .type = EM28XX_VMUX_SVIDEO, |
152 | .vmux = 2, | 153 | .vmux = 2, |
153 | .amux = 1, | 154 | .amux = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1, |
155 | MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART), | ||
154 | }}, | 156 | }}, |
155 | }, | 157 | }, |
156 | [EM2820_BOARD_MSI_VOX_USB_2] = { | 158 | [EM2820_BOARD_MSI_VOX_USB_2] = { |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 780342f7b239..dfba33d0fa61 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "em28xx.h" | 38 | #include "em28xx.h" |
39 | #include <media/tuner.h> | 39 | #include <media/tuner.h> |
40 | #include <media/v4l2-common.h> | 40 | #include <media/v4l2-common.h> |
41 | #include <media/msp3400.h> | ||
41 | 42 | ||
42 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | 43 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
43 | "Markus Rechberger <mrechberger@gmail.com>, " \ | 44 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
@@ -216,9 +217,14 @@ static void video_mux(struct em28xx *dev, int index) | |||
216 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); | 217 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); |
217 | 218 | ||
218 | if (dev->has_msp34xx) { | 219 | if (dev->has_msp34xx) { |
220 | struct v4l2_routing route; | ||
221 | |||
219 | if (dev->i2s_speed) | 222 | if (dev->i2s_speed) |
220 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); | 223 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); |
221 | em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput); | 224 | route.input = dev->ctl_ainput; |
225 | route.output = MSP_OUTPUT(MSP_OUT_SCART1_DA); | ||
226 | /* Note: this is msp3400 specific */ | ||
227 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route); | ||
222 | ainput = EM28XX_AUDIO_SRC_TUNER; | 228 | ainput = EM28XX_AUDIO_SRC_TUNER; |
223 | em28xx_audio_source(dev, ainput); | 229 | em28xx_audio_source(dev, ainput); |
224 | } else { | 230 | } else { |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 04250284ff1e..8ba1c960388a 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -555,7 +555,6 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
555 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | 555 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) |
556 | { | 556 | { |
557 | struct msp_state *state = i2c_get_clientdata(client); | 557 | struct msp_state *state = i2c_get_clientdata(client); |
558 | int scart = -1; | ||
559 | 558 | ||
560 | if (msp_debug >= 2) | 559 | if (msp_debug >= 2) |
561 | v4l_i2c_print_ioctl(client, cmd); | 560 | v4l_i2c_print_ioctl(client, cmd); |
@@ -660,15 +659,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
660 | break; | 659 | break; |
661 | } | 660 | } |
662 | 661 | ||
663 | /* msp34xx specific */ | ||
664 | case MSP_SET_MATRIX: | ||
665 | { | ||
666 | struct msp_matrix *mspm = arg; | ||
667 | |||
668 | msp_set_scart(client, mspm->input - 1, mspm->output); | ||
669 | break; | ||
670 | } | ||
671 | |||
672 | /* --- v4l2 ioctls --- */ | 662 | /* --- v4l2 ioctls --- */ |
673 | case VIDIOC_S_STD: | 663 | case VIDIOC_S_STD: |
674 | { | 664 | { |
@@ -682,36 +672,38 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
682 | return 0; | 672 | return 0; |
683 | } | 673 | } |
684 | 674 | ||
685 | case VIDIOC_S_AUDIO: | 675 | case VIDIOC_INT_G_AUDIO_ROUTING: |
686 | { | 676 | { |
687 | struct v4l2_audio *sarg = arg; | 677 | struct v4l2_routing *rt = arg; |
688 | 678 | ||
689 | switch (sarg->index) { | 679 | *rt = state->routing; |
690 | case TVAUDIO_INPUT_RADIO: | 680 | break; |
691 | /* Hauppauge uses IN2 for the radio */ | 681 | } |
692 | state->mode = MSP_MODE_FM_RADIO; | 682 | |
693 | scart = SCART_IN2; | 683 | case VIDIOC_INT_S_AUDIO_ROUTING: |
694 | break; | 684 | { |
695 | case TVAUDIO_INPUT_EXTERN: | 685 | struct v4l2_routing *rt = arg; |
696 | /* IN1 is often used for external input ... */ | 686 | int tuner = (rt->input >> 3) & 1; |
697 | state->mode = MSP_MODE_EXTERN; | 687 | int old_tuner = (state->routing.input >> 3) & 1; |
698 | scart = SCART_IN1; | 688 | int sc_in = rt->input & 0x7; |
699 | break; | 689 | int sc1_out = rt->output & 0xf; |
700 | case TVAUDIO_INPUT_INTERN: | 690 | int sc2_out = (rt->output >> 4) & 0xf; |
701 | /* ... sometimes it is IN2 through ;) */ | 691 | u16 val; |
702 | state->mode = MSP_MODE_EXTERN; | 692 | |
703 | scart = SCART_IN2; | 693 | state->routing = *rt; |
704 | break; | 694 | if (state->opmode == OPMODE_AUTOSELECT) { |
705 | case TVAUDIO_INPUT_TUNER: | 695 | val = msp_read_dem(client, 0x30) & ~0x100; |
706 | state->mode = -1; | 696 | msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0)); |
707 | break; | 697 | } else { |
708 | } | 698 | val = msp_read_dem(client, 0xbb) & ~0x100; |
709 | if (scart >= 0) { | 699 | msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0)); |
710 | state->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
711 | msp_set_scart(client, scart, 0); | ||
712 | } | 700 | } |
701 | msp_set_scart(client, sc_in, 0); | ||
702 | msp_set_scart(client, sc1_out, 1); | ||
703 | msp_set_scart(client, sc2_out, 2); | ||
713 | msp_set_audmode(client); | 704 | msp_set_audmode(client); |
714 | msp_wake_thread(client); | 705 | if (tuner != old_tuner) |
706 | msp_wake_thread(client); | ||
715 | break; | 707 | break; |
716 | } | 708 | } |
717 | 709 | ||
@@ -941,6 +933,9 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
941 | state->muted = 0; | 933 | state->muted = 0; |
942 | state->i2s_mode = 0; | 934 | state->i2s_mode = 0; |
943 | init_waitqueue_head(&state->wq); | 935 | init_waitqueue_head(&state->wq); |
936 | /* These are the reset input/output positions */ | ||
937 | state->routing.input = MSP_INPUT_DEFAULT; | ||
938 | state->routing.output = MSP_OUTPUT_DEFAULT; | ||
944 | 939 | ||
945 | state->rev1 = msp_read_dsp(client, 0x1e); | 940 | state->rev1 = msp_read_dsp(client, 0x1e); |
946 | if (state->rev1 != -1) | 941 | if (state->rev1 != -1) |
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h index 04821ebfe04a..1940748bb633 100644 --- a/drivers/media/video/msp3400-driver.h +++ b/drivers/media/video/msp3400-driver.h | |||
@@ -4,6 +4,8 @@ | |||
4 | #ifndef MSP3400_DRIVER_H | 4 | #ifndef MSP3400_DRIVER_H |
5 | #define MSP3400_DRIVER_H | 5 | #define MSP3400_DRIVER_H |
6 | 6 | ||
7 | #include <media/msp3400.h> | ||
8 | |||
7 | /* ---------------------------------------------------------------------- */ | 9 | /* ---------------------------------------------------------------------- */ |
8 | 10 | ||
9 | /* This macro is allowed for *constants* only, gcc must calculate it | 11 | /* This macro is allowed for *constants* only, gcc must calculate it |
@@ -72,7 +74,7 @@ struct msp_state { | |||
72 | int i2s_mode; | 74 | int i2s_mode; |
73 | int main, second; /* sound carrier */ | 75 | int main, second; /* sound carrier */ |
74 | int input; | 76 | int input; |
75 | int source; /* see msp34xxg_set_source */ | 77 | struct v4l2_routing routing; |
76 | 78 | ||
77 | /* v4l2 */ | 79 | /* v4l2 */ |
78 | int audmode; | 80 | int audmode; |
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 9ee8dc216d7f..1c794c3b9f21 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c | |||
@@ -187,13 +187,14 @@ void msp3400c_set_mode(struct i2c_client *client, int mode) | |||
187 | { | 187 | { |
188 | struct msp_state *state = i2c_get_clientdata(client); | 188 | struct msp_state *state = i2c_get_clientdata(client); |
189 | struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode]; | 189 | struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode]; |
190 | int tuner = (state->routing.input >> 3) & 1; | ||
190 | int i; | 191 | int i; |
191 | 192 | ||
192 | v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode); | 193 | v4l_dbg(1, msp_debug, client, "set_mode: %d\n", mode); |
193 | state->mode = mode; | 194 | state->mode = mode; |
194 | state->rxsubchans = V4L2_TUNER_SUB_MONO; | 195 | state->rxsubchans = V4L2_TUNER_SUB_MONO; |
195 | 196 | ||
196 | msp_write_dem(client, 0x00bb, data->ad_cv); | 197 | msp_write_dem(client, 0x00bb, data->ad_cv | (tuner ? 0x100 : 0)); |
197 | 198 | ||
198 | for (i = 5; i >= 0; i--) /* fir 1 */ | 199 | for (i = 5; i >= 0; i--) /* fir 1 */ |
199 | msp_write_dem(client, 0x0001, data->fir1[i]); | 200 | msp_write_dem(client, 0x0001, data->fir1[i]); |
@@ -783,34 +784,6 @@ int msp3410d_thread(void *data) | |||
783 | * struct msp: only norm, acb and source are really used in this mode | 784 | * struct msp: only norm, acb and source are really used in this mode |
784 | */ | 785 | */ |
785 | 786 | ||
786 | /* set the same 'source' for the loudspeaker, scart and quasi-peak detector | ||
787 | * the value for source is the same as bit 15:8 of DSP registers 0x08, | ||
788 | * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B | ||
789 | */ | ||
790 | static void msp34xxg_set_source(struct i2c_client *client, int source) | ||
791 | { | ||
792 | struct msp_state *state = i2c_get_clientdata(client); | ||
793 | |||
794 | /* fix matrix mode to stereo and let the msp choose what | ||
795 | * to output according to 'source', as recommended | ||
796 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | ||
797 | */ | ||
798 | int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20); | ||
799 | |||
800 | v4l_dbg(1, msp_debug, client, "set source to %d (0x%x)\n", source, value); | ||
801 | msp_set_source(client, value); | ||
802 | /* | ||
803 | * set identification threshold. Personally, I | ||
804 | * I set it to a higher value that the default | ||
805 | * of 0x190 to ignore noisy stereo signals. | ||
806 | * this needs tuning. (recommended range 0x00a0-0x03c0) | ||
807 | * 0x7f0 = forced mono mode | ||
808 | */ | ||
809 | /* a2 threshold for stereo/bilingual */ | ||
810 | msp_write_dem(client, 0x22, msp_stereo_thresh); | ||
811 | state->source = source; | ||
812 | } | ||
813 | |||
814 | static int msp34xxg_modus(struct i2c_client *client) | 787 | static int msp34xxg_modus(struct i2c_client *client) |
815 | { | 788 | { |
816 | struct msp_state *state = i2c_get_clientdata(client); | 789 | struct msp_state *state = i2c_get_clientdata(client); |
@@ -843,10 +816,65 @@ static int msp34xxg_modus(struct i2c_client *client) | |||
843 | return 0x0001; | 816 | return 0x0001; |
844 | } | 817 | } |
845 | 818 | ||
819 | static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) | ||
820 | { | ||
821 | struct msp_state *state = i2c_get_clientdata(client); | ||
822 | int source, matrix; | ||
823 | |||
824 | switch (state->audmode) { | ||
825 | case V4L2_TUNER_MODE_MONO: | ||
826 | source = 0; /* mono only */ | ||
827 | matrix = 0x30; | ||
828 | break; | ||
829 | case V4L2_TUNER_MODE_LANG1: | ||
830 | source = 3; /* stereo or A */ | ||
831 | matrix = 0x00; | ||
832 | break; | ||
833 | case V4L2_TUNER_MODE_LANG2: | ||
834 | source = 4; /* stereo or B */ | ||
835 | matrix = 0x10; | ||
836 | break; | ||
837 | case V4L2_TUNER_MODE_STEREO: | ||
838 | default: | ||
839 | source = 1; /* stereo or A|B */ | ||
840 | matrix = 0x20; | ||
841 | break; | ||
842 | } | ||
843 | |||
844 | if (in == MSP_DSP_OUT_TUNER) | ||
845 | source = (source << 8) | 0x20; | ||
846 | /* the msp34x2g puts the MAIN_AVC, MAIN and AUX sources in 12, 13, 14 | ||
847 | instead of 11, 12, 13. So we add one for that msp version. */ | ||
848 | else if (in >= MSP_DSP_OUT_MAIN_AVC && state->has_dolby_pro_logic) | ||
849 | source = ((in + 1) << 8) | matrix; | ||
850 | else | ||
851 | source = (in << 8) | matrix; | ||
852 | |||
853 | v4l_dbg(1, msp_debug, client, "set source to %d (0x%x) for output %02x\n", | ||
854 | in, source, reg); | ||
855 | msp_write_dsp(client, reg, source); | ||
856 | } | ||
857 | |||
858 | static void msp34xxg_set_sources(struct i2c_client *client) | ||
859 | { | ||
860 | struct msp_state *state = i2c_get_clientdata(client); | ||
861 | u32 in = state->routing.input; | ||
862 | |||
863 | msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf); | ||
864 | /* quasi-peak detector is set to same input as the loudspeaker (MAIN) */ | ||
865 | msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf); | ||
866 | msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf); | ||
867 | msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf); | ||
868 | if (state->has_scart23_in_scart2_out) | ||
869 | msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf); | ||
870 | msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf); | ||
871 | } | ||
872 | |||
846 | /* (re-)initialize the msp34xxg */ | 873 | /* (re-)initialize the msp34xxg */ |
847 | static void msp34xxg_reset(struct i2c_client *client) | 874 | static void msp34xxg_reset(struct i2c_client *client) |
848 | { | 875 | { |
849 | struct msp_state *state = i2c_get_clientdata(client); | 876 | struct msp_state *state = i2c_get_clientdata(client); |
877 | int tuner = (state->routing.input >> 3) & 1; | ||
850 | int modus; | 878 | int modus; |
851 | 879 | ||
852 | /* initialize std to 1 (autodetect) to signal that no standard is | 880 | /* initialize std to 1 (autodetect) to signal that no standard is |
@@ -864,11 +892,12 @@ static void msp34xxg_reset(struct i2c_client *client) | |||
864 | 892 | ||
865 | /* step-by-step initialisation, as described in the manual */ | 893 | /* step-by-step initialisation, as described in the manual */ |
866 | modus = msp34xxg_modus(client); | 894 | modus = msp34xxg_modus(client); |
895 | modus |= tuner ? 0x100 : 0; | ||
867 | msp_write_dem(client, 0x30, modus); | 896 | msp_write_dem(client, 0x30, modus); |
868 | 897 | ||
869 | /* write the dsps that may have an influence on | 898 | /* write the dsps that may have an influence on |
870 | standard/audio autodetection right now */ | 899 | standard/audio autodetection right now */ |
871 | msp34xxg_set_source(client, state->source); | 900 | msp34xxg_set_sources(client); |
872 | 901 | ||
873 | msp_write_dsp(client, 0x0d, 0x1900); /* scart */ | 902 | msp_write_dsp(client, 0x0d, 0x1900); /* scart */ |
874 | msp_write_dsp(client, 0x0e, 0x3000); /* FM */ | 903 | msp_write_dsp(client, 0x0e, 0x3000); /* FM */ |
@@ -896,7 +925,6 @@ int msp34xxg_thread(void *data) | |||
896 | 925 | ||
897 | v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); | 926 | v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); |
898 | 927 | ||
899 | state->source = 1; /* default */ | ||
900 | for (;;) { | 928 | for (;;) { |
901 | v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n"); | 929 | v4l_dbg(2, msp_debug, client, "msp34xxg thread: sleep\n"); |
902 | msp_sleep(state, -1); | 930 | msp_sleep(state, -1); |
@@ -993,7 +1021,6 @@ static int msp34xxg_detect_stereo(struct i2c_client *client) | |||
993 | static void msp34xxg_set_audmode(struct i2c_client *client) | 1021 | static void msp34xxg_set_audmode(struct i2c_client *client) |
994 | { | 1022 | { |
995 | struct msp_state *state = i2c_get_clientdata(client); | 1023 | struct msp_state *state = i2c_get_clientdata(client); |
996 | int source; | ||
997 | 1024 | ||
998 | if (state->std == 0x20) { | 1025 | if (state->std == 0x20) { |
999 | if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) && | 1026 | if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) && |
@@ -1005,25 +1032,7 @@ static void msp34xxg_set_audmode(struct i2c_client *client) | |||
1005 | } | 1032 | } |
1006 | } | 1033 | } |
1007 | 1034 | ||
1008 | switch (state->audmode) { | 1035 | msp34xxg_set_sources(client); |
1009 | case V4L2_TUNER_MODE_MONO: | ||
1010 | source = 0; /* mono only */ | ||
1011 | break; | ||
1012 | case V4L2_TUNER_MODE_STEREO: | ||
1013 | source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ | ||
1014 | /* problem: that could also mean 2 (scart input) */ | ||
1015 | break; | ||
1016 | case V4L2_TUNER_MODE_LANG1: | ||
1017 | source = 3; /* stereo or A */ | ||
1018 | break; | ||
1019 | case V4L2_TUNER_MODE_LANG2: | ||
1020 | source = 4; /* stereo or B */ | ||
1021 | break; | ||
1022 | default: | ||
1023 | source = 1; | ||
1024 | break; | ||
1025 | } | ||
1026 | msp34xxg_set_source(client, source); | ||
1027 | } | 1036 | } |
1028 | 1037 | ||
1029 | void msp_set_audmode(struct i2c_client *client) | 1038 | void msp_set_audmode(struct i2c_client *client) |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 15fd55ff69ca..4e6d030d83c0 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -1682,6 +1682,30 @@ static int chip_command(struct i2c_client *client, | |||
1682 | case VIDIOC_S_CTRL: | 1682 | case VIDIOC_S_CTRL: |
1683 | return tvaudio_set_ctrl(chip, arg); | 1683 | return tvaudio_set_ctrl(chip, arg); |
1684 | 1684 | ||
1685 | case VIDIOC_INT_G_AUDIO_ROUTING: | ||
1686 | { | ||
1687 | struct v4l2_routing *rt = arg; | ||
1688 | |||
1689 | rt->input = chip->input; | ||
1690 | rt->output = 0; | ||
1691 | break; | ||
1692 | } | ||
1693 | |||
1694 | case VIDIOC_INT_S_AUDIO_ROUTING: | ||
1695 | { | ||
1696 | struct v4l2_routing *rt = arg; | ||
1697 | |||
1698 | if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4) | ||
1699 | return -EINVAL; | ||
1700 | /* There are four inputs: tuner, radio, extern and intern. */ | ||
1701 | chip->input = rt->input; | ||
1702 | if (chip->muted) | ||
1703 | break; | ||
1704 | chip_write_masked(chip, desc->inputreg, | ||
1705 | desc->inputmap[chip->input], desc->inputmask); | ||
1706 | break; | ||
1707 | } | ||
1708 | |||
1685 | case VIDIOC_S_AUDIO: | 1709 | case VIDIOC_S_AUDIO: |
1686 | { | 1710 | { |
1687 | struct v4l2_audio *sarg = arg; | 1711 | struct v4l2_audio *sarg = arg; |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index d1234d781e16..6824ee045fe6 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -312,7 +312,6 @@ static const char *v4l2_int_ioctls[] = { | |||
312 | [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", | 312 | [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", |
313 | #endif | 313 | #endif |
314 | [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", | 314 | [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", |
315 | [_IOC_NR(MSP_SET_MATRIX)] = "MSP_SET_MATRIX", | ||
316 | 315 | ||
317 | [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", | 316 | [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", |
318 | [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", | 317 | [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", |
@@ -431,12 +430,6 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
431 | printk ("%s: value=%d\n", s, *p); | 430 | printk ("%s: value=%d\n", s, *p); |
432 | break; | 431 | break; |
433 | } | 432 | } |
434 | case MSP_SET_MATRIX: | ||
435 | { | ||
436 | struct msp_matrix *p=arg; | ||
437 | printk ("%s: input=%d, output=%d\n", s, p->input, p->output); | ||
438 | break; | ||
439 | } | ||
440 | case VIDIOC_G_AUDIO: | 433 | case VIDIOC_G_AUDIO: |
441 | case VIDIOC_S_AUDIO: | 434 | case VIDIOC_S_AUDIO: |
442 | case VIDIOC_ENUMAUDIO: | 435 | case VIDIOC_ENUMAUDIO: |
@@ -465,7 +458,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
465 | struct v4l2_buffer *p=arg; | 458 | struct v4l2_buffer *p=arg; |
466 | struct v4l2_timecode *tc=&p->timecode; | 459 | struct v4l2_timecode *tc=&p->timecode; |
467 | printk ("%s: %02ld:%02d:%02d.%08ld index=%d, type=%s, " | 460 | printk ("%s: %02ld:%02d:%02d.%08ld index=%d, type=%s, " |
468 | "bytesused=%d, flags=0x%08d, " | 461 | "bytesused=%d, flags=0x%08x, " |
469 | "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n", | 462 | "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n", |
470 | s, | 463 | s, |
471 | (p->timestamp.tv_sec/3600), | 464 | (p->timestamp.tv_sec/3600), |
@@ -479,7 +472,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
479 | prt_names(p->memory,v4l2_memory_names), | 472 | prt_names(p->memory,v4l2_memory_names), |
480 | p->m.userptr); | 473 | p->m.userptr); |
481 | printk ("%s: timecode= %02d:%02d:%02d type=%d, " | 474 | printk ("%s: timecode= %02d:%02d:%02d type=%d, " |
482 | "flags=0x%08d, frames=%d, userbits=0x%p", | 475 | "flags=0x%08x, frames=%d, userbits=0x%08p\n", |
483 | s,tc->hours,tc->minutes,tc->seconds, | 476 | s,tc->hours,tc->minutes,tc->seconds, |
484 | tc->type, tc->flags, tc->frames, tc->userbits); | 477 | tc->type, tc->flags, tc->frames, tc->userbits); |
485 | break; | 478 | break; |
@@ -665,7 +658,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
665 | case VIDIOC_INT_G_VIDEO_ROUTING: | 658 | case VIDIOC_INT_G_VIDEO_ROUTING: |
666 | { | 659 | { |
667 | struct v4l2_routing *p=arg; | 660 | struct v4l2_routing *p=arg; |
668 | printk ("%s: input=%d, output=%d\n", s, p->input, p->output); | 661 | printk ("%s: input=0x%x, output=0x%x\n", s, p->input, p->output); |
669 | break; | 662 | break; |
670 | } | 663 | } |
671 | case VIDIOC_G_SLICED_VBI_CAP: | 664 | case VIDIOC_G_SLICED_VBI_CAP: |