diff options
Diffstat (limited to 'drivers/media/video/bt8xx/bttv-driver.c')
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 91 |
1 files changed, 56 insertions, 35 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 71535775f2e8..be567ec9e145 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/kdev_t.h> | 36 | #include <linux/kdev_t.h> |
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 | 40 | ||
40 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
41 | 42 | ||
@@ -926,45 +927,65 @@ video_mux(struct bttv *btv, unsigned int input) | |||
926 | 927 | ||
927 | static char *audio_modes[] = { | 928 | static char *audio_modes[] = { |
928 | "audio: tuner", "audio: radio", "audio: extern", | 929 | "audio: tuner", "audio: radio", "audio: extern", |
929 | "audio: intern", "audio: off" | 930 | "audio: intern", "audio: mute" |
930 | }; | 931 | }; |
931 | 932 | ||
932 | static int | 933 | static int |
933 | audio_mux(struct bttv *btv, int mode) | 934 | audio_mux(struct bttv *btv, int input, int mute) |
934 | { | 935 | { |
935 | int val,mux,i2c_mux,signal; | 936 | int gpio_val, signal; |
937 | struct v4l2_audio aud_input; | ||
938 | struct v4l2_control ctrl; | ||
939 | struct i2c_client *c; | ||
936 | 940 | ||
941 | memset(&aud_input, 0, sizeof(aud_input)); | ||
937 | gpio_inout(bttv_tvcards[btv->c.type].gpiomask, | 942 | gpio_inout(bttv_tvcards[btv->c.type].gpiomask, |
938 | bttv_tvcards[btv->c.type].gpiomask); | 943 | bttv_tvcards[btv->c.type].gpiomask); |
939 | signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; | 944 | signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; |
940 | 945 | ||
941 | switch (mode) { | 946 | btv->mute = mute; |
942 | case AUDIO_MUTE: | 947 | btv->audio = input; |
943 | btv->audio |= AUDIO_MUTE; | 948 | |
944 | break; | 949 | /* automute */ |
945 | case AUDIO_UNMUTE: | 950 | mute = mute || (btv->opt_automute && !signal && !btv->radio_user); |
946 | btv->audio &= ~AUDIO_MUTE; | 951 | |
947 | break; | 952 | if (mute) |
948 | case AUDIO_TUNER: | 953 | gpio_val = bttv_tvcards[btv->c.type].gpiomute; |
949 | case AUDIO_RADIO: | 954 | else |
950 | case AUDIO_EXTERN: | 955 | gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; |
951 | case AUDIO_INTERN: | 956 | aud_input.index = btv->audio; |
952 | btv->audio &= AUDIO_MUTE; | 957 | |
953 | btv->audio |= mode; | 958 | gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); |
954 | } | ||
955 | i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio; | ||
956 | if (btv->opt_automute && !signal && !btv->radio_user) | ||
957 | mux = AUDIO_OFF; | ||
958 | |||
959 | val = bttv_tvcards[btv->c.type].audiomux[mux]; | ||
960 | gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val); | ||
961 | if (bttv_gpio) | 959 | if (bttv_gpio) |
962 | bttv_gpio_tracking(btv,audio_modes[mux]); | 960 | bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]); |
963 | if (!in_interrupt()) | 961 | if (in_interrupt()) |
964 | bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux)); | 962 | return 0; |
963 | |||
964 | ctrl.id = V4L2_CID_AUDIO_MUTE; | ||
965 | /* take automute into account, just btv->mute is not enough */ | ||
966 | ctrl.value = mute; | ||
967 | bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl); | ||
968 | c = btv->i2c_msp34xx_client; | ||
969 | if (c) | ||
970 | c->driver->command(c, VIDIOC_S_AUDIO, &aud_input); | ||
971 | c = btv->i2c_tvaudio_client; | ||
972 | if (c) | ||
973 | c->driver->command(c, VIDIOC_S_AUDIO, &aud_input); | ||
965 | return 0; | 974 | return 0; |
966 | } | 975 | } |
967 | 976 | ||
977 | static inline int | ||
978 | audio_mute(struct bttv *btv, int mute) | ||
979 | { | ||
980 | return audio_mux(btv, btv->audio, mute); | ||
981 | } | ||
982 | |||
983 | static inline int | ||
984 | audio_input(struct bttv *btv, int input) | ||
985 | { | ||
986 | return audio_mux(btv, input, btv->mute); | ||
987 | } | ||
988 | |||
968 | static void | 989 | static void |
969 | i2c_vidiocschan(struct bttv *btv) | 990 | i2c_vidiocschan(struct bttv *btv) |
970 | { | 991 | { |
@@ -1023,8 +1044,8 @@ set_input(struct bttv *btv, unsigned int input) | |||
1023 | } else { | 1044 | } else { |
1024 | video_mux(btv,input); | 1045 | video_mux(btv,input); |
1025 | } | 1046 | } |
1026 | audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ? | 1047 | audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ? |
1027 | AUDIO_TUNER : AUDIO_EXTERN)); | 1048 | TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN)); |
1028 | set_tvnorm(btv,btv->tvnorm); | 1049 | set_tvnorm(btv,btv->tvnorm); |
1029 | i2c_vidiocschan(btv); | 1050 | i2c_vidiocschan(btv); |
1030 | } | 1051 | } |
@@ -1236,10 +1257,10 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) | |||
1236 | case V4L2_CID_AUDIO_MUTE: | 1257 | case V4L2_CID_AUDIO_MUTE: |
1237 | if (c->value) { | 1258 | if (c->value) { |
1238 | va.flags |= VIDEO_AUDIO_MUTE; | 1259 | va.flags |= VIDEO_AUDIO_MUTE; |
1239 | audio_mux(btv, AUDIO_MUTE); | 1260 | audio_mute(btv, 1); |
1240 | } else { | 1261 | } else { |
1241 | va.flags &= ~VIDEO_AUDIO_MUTE; | 1262 | va.flags &= ~VIDEO_AUDIO_MUTE; |
1242 | audio_mux(btv, AUDIO_UNMUTE); | 1263 | audio_mute(btv, 0); |
1243 | } | 1264 | } |
1244 | break; | 1265 | break; |
1245 | 1266 | ||
@@ -1654,7 +1675,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1654 | return -EINVAL; | 1675 | return -EINVAL; |
1655 | 1676 | ||
1656 | mutex_lock(&btv->lock); | 1677 | mutex_lock(&btv->lock); |
1657 | audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE); | 1678 | audio_mute(btv, (v->flags&VIDEO_AUDIO_MUTE) ? 1 : 0); |
1658 | bttv_call_i2c_clients(btv,cmd,v); | 1679 | bttv_call_i2c_clients(btv,cmd,v); |
1659 | 1680 | ||
1660 | /* card specific hooks */ | 1681 | /* card specific hooks */ |
@@ -3163,8 +3184,8 @@ static int radio_open(struct inode *inode, struct file *file) | |||
3163 | 3184 | ||
3164 | file->private_data = btv; | 3185 | file->private_data = btv; |
3165 | 3186 | ||
3166 | bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type); | 3187 | bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL); |
3167 | audio_mux(btv,AUDIO_RADIO); | 3188 | audio_input(btv,TVAUDIO_INPUT_RADIO); |
3168 | 3189 | ||
3169 | mutex_unlock(&btv->lock); | 3190 | mutex_unlock(&btv->lock); |
3170 | return 0; | 3191 | return 0; |
@@ -3750,7 +3771,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) | |||
3750 | bttv_irq_switch_video(btv); | 3771 | bttv_irq_switch_video(btv); |
3751 | 3772 | ||
3752 | if ((astat & BT848_INT_HLOCK) && btv->opt_automute) | 3773 | if ((astat & BT848_INT_HLOCK) && btv->opt_automute) |
3753 | audio_mux(btv, -1); | 3774 | audio_mute(btv, btv->mute); /* trigger automute */ |
3754 | 3775 | ||
3755 | if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) { | 3776 | if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) { |
3756 | printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr, | 3777 | printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr, |
@@ -4051,7 +4072,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4051 | bt848_contrast(btv,32768); | 4072 | bt848_contrast(btv,32768); |
4052 | bt848_hue(btv,32768); | 4073 | bt848_hue(btv,32768); |
4053 | bt848_sat(btv,32768); | 4074 | bt848_sat(btv,32768); |
4054 | audio_mux(btv,AUDIO_MUTE); | 4075 | audio_mute(btv, 1); |
4055 | set_input(btv,0); | 4076 | set_input(btv,0); |
4056 | } | 4077 | } |
4057 | 4078 | ||