openwrtv4/target/linux/brcm2708/patches-4.4/0134-bcm2835-only-allow-stereo-if-analogue-jack-is-select.patch
John Crispin b3dc9566a4 brcm2708: switch to linux 4.4 and update patches
As usual these patches were extracted from:
https://github.com/raspberrypi/linux/commits/rpi-4.4.y

Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>

SVN-Revision: 48765
2016-02-25 10:14:01 +00:00

62 lines
2.1 KiB
Diff

From 22606ad9e0d809ce0d4e12b51d5b4c6507f89c2d Mon Sep 17 00:00:00 2001
From: wm4 <wm4@nowhere>
Date: Wed, 13 Jan 2016 19:44:24 +0100
Subject: [PATCH 134/156] bcm2835: only allow stereo if analogue jack is
selected
Sending more than 2 channels to videocore while outputting to analogue
mysteriously outputs heavy artifacts. So just paint it over with a
hack: if analogue is explicitly selected as destination, do not
reporting support for anything other than stereo.
I'm not sure how to deal with the auto case (destination 0). There's
probably way to retrieve this and even to listen to plug events, but
I didn't find one yet, and it's probably not worth the trouble. Just
don't use this setting, I guess. Unless you like noise.
Changing the setting while an audio stream is active also doesn't
work properly. We could probably interrupt running streams by
returning ENODEV or using kernel hotplug stuff (maybe), but that
also doesn't seem worth the trouble.
---
sound/arm/bcm2835-ctl.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/sound/arm/bcm2835-ctl.c
+++ b/sound/arm/bcm2835-ctl.c
@@ -423,9 +423,16 @@ static struct cea_channel_speaker_alloca
{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
};
+static int uses_analogue(bcm2835_chip_t *chip)
+{
+ return chip->dest == 1;
+}
+
static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
unsigned int size, unsigned int __user *tlv)
{
+ struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+ bcm2835_chip_t *chip = info->private_data;
unsigned int __user *dst;
int count = 0;
int i;
@@ -442,6 +449,9 @@ static int snd_bcm2835_chmap_ctl_tlv(str
int chs_bytes;
int c;
+ if (i > 0 && uses_analogue(chip))
+ break;
+
for (c = 0; c < 8; c++) {
if (ch->speakers[c])
num_chs++;
@@ -552,6 +562,8 @@ static int snd_bcm2835_chmap_ctl_put(str
int matches = 1;
int cur = 0;
int x;
+ if (i > 0 && uses_analogue(chip))
+ break;
memset(remap, 0, sizeof(remap));
for (x = 0; x < substream->runtime->channels; x++) {
int sp = ucontrol->value.integer.value[x];