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

Commit 00b8730f authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

V4L/DVB (7163): em28xx: makes audio settings more stable



Improves audio configurations on em28xx:
        - mutes audio before changing amux;
        - adds a delay after setting audio src;
        - waits up to 50ms for ac97 busy.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 0df8130f
Loading
Loading
Loading
Loading
+20 −8
Original line number Original line Diff line number Diff line
@@ -255,21 +255,26 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
 */
 */
static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val)
{
{
	int ret;
	int ret, i;
	u8 addr = reg & 0x7f;
	u8 addr = reg & 0x7f;
	if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
	if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
		return ret;
		return ret;
	if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
	if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
		return ret;
		return ret;

	/* Wait up to 50 ms for AC97 command to complete */
	for (i = 0; i < 10; i++) {
		if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
		if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
			return ret;
			return ret;
	else if (((u8) ret) & 0x01) {
		if (!((u8) ret) & 0x01)
		em28xx_warn ("AC97 command still being executed: not handled properly!\n");
			return 0;
		msleep(5);
	}
	}
	em28xx_warn ("AC97 command still being executed: not handled properly!\n");
	return 0;
	return 0;
}
}


int em28xx_set_audio_source(struct em28xx *dev)
static int em28xx_set_audio_source(struct em28xx *dev)
{
{
	static char *enable  = "\x08\x08";
	static char *enable  = "\x08\x08";
	static char *disable = "\x08\x88";
	static char *disable = "\x08\x88";
@@ -312,6 +317,7 @@ int em28xx_set_audio_source(struct em28xx *dev)
	ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
	ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;
	msleep(5);


	/* Sets AC97 mixer registers
	/* Sets AC97 mixer registers
	   This is seems to be needed, even for non-ac97 configs
	   This is seems to be needed, even for non-ac97 configs
@@ -334,9 +340,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
	s[0] |= 0x1f - dev->volume;
	s[0] |= 0x1f - dev->volume;
	s[1] |= 0x1f - dev->volume;
	s[1] |= 0x1f - dev->volume;


	if (dev->mute)
	/* Mute */
	s[1] |= 0x80;
	s[1] |= 0x80;
	ret = em28xx_write_ac97(dev, MASTER_AC97, s);
	ret = em28xx_write_ac97(dev, MASTER_AC97, s);

	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


@@ -354,6 +361,11 @@ int em28xx_audio_analog_set(struct em28xx *dev)
	/* Selects the proper audio input */
	/* Selects the proper audio input */
	ret = em28xx_set_audio_source(dev);
	ret = em28xx_set_audio_source(dev);


	/* Unmute device */
	if (!dev->mute)
		s[1] &= ~0x80;
	ret = em28xx_write_ac97(dev, MASTER_AC97, s);

	return ret;
	return ret;
}
}
EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
EXPORT_SYMBOL_GPL(em28xx_audio_analog_set);
+1 −2
Original line number Original line Diff line number Diff line
@@ -189,7 +189,7 @@ static void video_mux(struct em28xx *dev, int index)
		em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
		em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route);
	}
	}


	em28xx_set_audio_source(dev);
	em28xx_audio_analog_set(dev);
}
}


/* Usage lock check functions */
/* Usage lock check functions */
@@ -837,7 +837,6 @@ static int em28xx_reg_len(int reg)
	case AC97LSB_REG:
	case AC97LSB_REG:
	case HSCALELOW_REG:
	case HSCALELOW_REG:
	case VSCALELOW_REG:
	case VSCALELOW_REG:

		return 2;
		return 2;
	default:
	default:
		return 1;
		return 1;