Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8bf2f8e7 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (3577): Cleanup audio input handling



Cleanup audio input handling in bttv and tvaudio:
- inputs were specified that were never used
- mute was handled as a special input which led to confusing code
- confusing naming made it difficult to see if the setting was for
  i2c or gpio.
The old audiochip.h input names moved to tvaudio.h. Currently this
is used both by tvaudio and msp3400 until the msp3400 implements the
new msp3400-specific inputs.
Detect in bttv the tvaudio and msp3400 i2c clients and use these
client pointers to set the inputs directly instead of broadcasting the
command.
Removed AUDC_SET_INPUT. Now replaced by VIDIOC_S_AUDIO. This will be
replaced again later by the new ROUTING commands.
Removed VIDIOC_G_AUDIO implementations in i2c drivers: this command is
a user level command and not to be used internally. It wasn't called at
all anyway.

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent ae62e3d4
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <media/audiochip.h>
#include <media/v4l2-common.h>

#include "bttv.h"
+183 −116

File changed.

Preview size limit exceeded, changes collapsed.

+56 −35
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/kdev_t.h>
#include "bttvp.h"
#include <media/v4l2-common.h>
#include <media/tvaudio.h>

#include <linux/dma-mapping.h>

@@ -926,45 +927,65 @@ video_mux(struct bttv *btv, unsigned int input)

static char *audio_modes[] = {
	"audio: tuner", "audio: radio", "audio: extern",
	"audio: intern", "audio: off"
	"audio: intern", "audio: mute"
};

static int
audio_mux(struct bttv *btv, int mode)
audio_mux(struct bttv *btv, int input, int mute)
{
	int val,mux,i2c_mux,signal;
	int gpio_val, signal;
	struct v4l2_audio aud_input;
	struct v4l2_control ctrl;
	struct i2c_client *c;

	memset(&aud_input, 0, sizeof(aud_input));
	gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
		   bttv_tvcards[btv->c.type].gpiomask);
	signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;

	switch (mode) {
	case AUDIO_MUTE:
		btv->audio |= AUDIO_MUTE;
		break;
	case AUDIO_UNMUTE:
		btv->audio &= ~AUDIO_MUTE;
		break;
	case AUDIO_TUNER:
	case AUDIO_RADIO:
	case AUDIO_EXTERN:
	case AUDIO_INTERN:
		btv->audio &= AUDIO_MUTE;
		btv->audio |= mode;
	}
	i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
	if (btv->opt_automute && !signal && !btv->radio_user)
		mux = AUDIO_OFF;

	val = bttv_tvcards[btv->c.type].audiomux[mux];
	gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
	btv->mute = mute;
	btv->audio = input;

	/* automute */
	mute = mute || (btv->opt_automute && !signal && !btv->radio_user);

	if (mute)
		gpio_val = bttv_tvcards[btv->c.type].gpiomute;
	else
		gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
	aud_input.index = btv->audio;

	gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
	if (bttv_gpio)
		bttv_gpio_tracking(btv,audio_modes[mux]);
	if (!in_interrupt())
		bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(i2c_mux));
		bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
	if (in_interrupt())
		return 0;

	ctrl.id = V4L2_CID_AUDIO_MUTE;
	/* take automute into account, just btv->mute is not enough */
	ctrl.value = mute;
	bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
	c = btv->i2c_msp34xx_client;
	if (c)
		c->driver->command(c, VIDIOC_S_AUDIO, &aud_input);
	c = btv->i2c_tvaudio_client;
	if (c)
		c->driver->command(c, VIDIOC_S_AUDIO, &aud_input);
	return 0;
}

static inline int
audio_mute(struct bttv *btv, int mute)
{
	return audio_mux(btv, btv->audio, mute);
}

static inline int
audio_input(struct bttv *btv, int input)
{
	return audio_mux(btv, input, btv->mute);
}

static void
i2c_vidiocschan(struct bttv *btv)
{
@@ -1023,8 +1044,8 @@ set_input(struct bttv *btv, unsigned int input)
	} else {
		video_mux(btv,input);
	}
	audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ?
		       AUDIO_TUNER : AUDIO_EXTERN));
	audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
		       TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
	set_tvnorm(btv,btv->tvnorm);
	i2c_vidiocschan(btv);
}
@@ -1236,10 +1257,10 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
	case V4L2_CID_AUDIO_MUTE:
		if (c->value) {
			va.flags |= VIDEO_AUDIO_MUTE;
			audio_mux(btv, AUDIO_MUTE);
			audio_mute(btv, 1);
		} else {
			va.flags &= ~VIDEO_AUDIO_MUTE;
			audio_mux(btv, AUDIO_UNMUTE);
			audio_mute(btv, 0);
		}
		break;

@@ -1654,7 +1675,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
			return -EINVAL;

		mutex_lock(&btv->lock);
		audio_mux(btv, (v->flags&VIDEO_AUDIO_MUTE) ? AUDIO_MUTE : AUDIO_UNMUTE);
		audio_mute(btv, (v->flags&VIDEO_AUDIO_MUTE) ? 1 : 0);
		bttv_call_i2c_clients(btv,cmd,v);

		/* card specific hooks */
@@ -3163,8 +3184,8 @@ static int radio_open(struct inode *inode, struct file *file)

	file->private_data = btv;

	bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
	audio_mux(btv,AUDIO_RADIO);
	bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
	audio_input(btv,TVAUDIO_INPUT_RADIO);

	mutex_unlock(&btv->lock);
	return 0;
@@ -3750,7 +3771,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
			bttv_irq_switch_video(btv);

		if ((astat & BT848_INT_HLOCK)  &&  btv->opt_automute)
			audio_mux(btv, -1);
			audio_mute(btv, btv->mute);  /* trigger automute */

		if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
			printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
@@ -4051,7 +4072,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
		bt848_contrast(btv,32768);
		bt848_hue(btv,32768);
		bt848_sat(btv,32768);
		audio_mux(btv,AUDIO_MUTE);
		audio_mute(btv, 1);
		set_input(btv,0);
	}

+4 −0
Original line number Diff line number Diff line
@@ -302,6 +302,10 @@ static int attach_inform(struct i2c_client *client)
	if (!client->driver->command)
		return 0;

	if (client->driver->id == I2C_DRIVERID_MSP3400)
		btv->i2c_msp34xx_client = client;
	if (client->driver->id == I2C_DRIVERID_TVAUDIO)
		btv->i2c_tvaudio_client = client;
	if (btv->tuner_type != UNSET) {
		struct tuner_setup tun_setup;

+2 −1
Original line number Diff line number Diff line
@@ -234,7 +234,8 @@ struct tvcard
	unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
	u32 gpiomask;
	u32 muxsel[16];
	u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
	u32 gpiomux[4];  /* Tuner, Radio, external, internal */
	u32 gpiomute;    /* GPIO mute setting */
	u32 gpiomask2;   /* GPIO MUX mask */

	/* i2c audio flags */
Loading