You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
2.1 KiB
61 lines
2.1 KiB
From f54692dc8ff6e0aecf27fdd2ebaed8e22d04f053 Mon Sep 17 00:00:00 2001
|
|
From: wm4 <wm4@nowhere>
|
|
Date: Wed, 13 Jan 2016 19:44:24 +0100
|
|
Subject: [PATCH] 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];
|
|
|