aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.14/0032-snd-bcm2835-Add-support-for-spdif-hdmi-passthrough.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-3.14/0032-snd-bcm2835-Add-support-for-spdif-hdmi-passthrough.patch')
-rw-r--r--target/linux/brcm2708/patches-3.14/0032-snd-bcm2835-Add-support-for-spdif-hdmi-passthrough.patch462
1 files changed, 0 insertions, 462 deletions
diff --git a/target/linux/brcm2708/patches-3.14/0032-snd-bcm2835-Add-support-for-spdif-hdmi-passthrough.patch b/target/linux/brcm2708/patches-3.14/0032-snd-bcm2835-Add-support-for-spdif-hdmi-passthrough.patch
deleted file mode 100644
index e5420d329c..0000000000
--- a/target/linux/brcm2708/patches-3.14/0032-snd-bcm2835-Add-support-for-spdif-hdmi-passthrough.patch
+++ /dev/null
@@ -1,462 +0,0 @@
-From 2172c6578ef13acb8fcf5cac643cb1ee8e824117 Mon Sep 17 00:00:00 2001
-From: Julian Scheel <julian@jusst.de>
-Date: Wed, 19 Feb 2014 16:06:59 +0100
-Subject: [PATCH 32/54] snd-bcm2835: Add support for spdif/hdmi passthrough
-
-This adds a dedicated subdevice which can be used for passthrough of non-audio
-formats (ie encoded a52) through the hdmi audio link. In addition to this
-driver extension an appropriate card config is required to make alsa-lib
-support the AES parameters for this device.
----
- sound/arm/bcm2835-ctl.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++
- sound/arm/bcm2835-pcm.c | 128 +++++++++++++++++++++++++++++++++++++++++-------
- sound/arm/bcm2835.c | 9 +++-
- sound/arm/bcm2835.h | 9 ++++
- 4 files changed, 250 insertions(+), 19 deletions(-)
-
---- a/sound/arm/bcm2835-ctl.c
-+++ b/sound/arm/bcm2835-ctl.c
-@@ -30,6 +30,7 @@
- #include <sound/rawmidi.h>
- #include <sound/initval.h>
- #include <sound/tlv.h>
-+#include <sound/asoundef.h>
-
- #include "bcm2835.h"
-
-@@ -183,6 +184,122 @@ static struct snd_kcontrol_new snd_bcm28
- },
- };
-
-+static int snd_bcm2835_spdif_default_info(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_info *uinfo)
-+{
-+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
-+ uinfo->count = 1;
-+ return 0;
-+}
-+
-+static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
-+ int i;
-+
-+ for (i = 0; i < 4; i++)
-+ ucontrol->value.iec958.status[i] =
-+ (chip->spdif_status >> (i * 8)) && 0xff;
-+
-+ return 0;
-+}
-+
-+static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
-+ unsigned int val = 0;
-+ int i, change;
-+
-+ for (i = 0; i < 4; i++)
-+ val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
-+
-+ change = val != chip->spdif_status;
-+ chip->spdif_status = val;
-+
-+ return change;
-+}
-+
-+static int snd_bcm2835_spdif_mask_info(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_info *uinfo)
-+{
-+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
-+ uinfo->count = 1;
-+ return 0;
-+}
-+
-+static int snd_bcm2835_spdif_mask_get(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ /* bcm2835 supports only consumer mode and sets all other format flags
-+ * automatically. So the only thing left is signalling non-audio
-+ * content */
-+ ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO;
-+ return 0;
-+}
-+
-+static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_info *uinfo)
-+{
-+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
-+ uinfo->count = 1;
-+ return 0;
-+}
-+
-+static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
-+ int i;
-+
-+ for (i = 0; i < 4; i++)
-+ ucontrol->value.iec958.status[i] =
-+ (chip->spdif_status >> (i * 8)) & 0xff;
-+ return 0;
-+}
-+
-+static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol,
-+ struct snd_ctl_elem_value *ucontrol)
-+{
-+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
-+ unsigned int val = 0;
-+ int i, change;
-+
-+ for (i = 0; i < 4; i++)
-+ val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
-+ change = val != chip->spdif_status;
-+ chip->spdif_status = val;
-+
-+ return change;
-+}
-+
-+static struct snd_kcontrol_new snd_bcm2835_spdif[] = {
-+ {
-+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
-+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
-+ .info = snd_bcm2835_spdif_default_info,
-+ .get = snd_bcm2835_spdif_default_get,
-+ .put = snd_bcm2835_spdif_default_put
-+ },
-+ {
-+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
-+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
-+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
-+ .info = snd_bcm2835_spdif_mask_info,
-+ .get = snd_bcm2835_spdif_mask_get,
-+ },
-+ {
-+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-+ SNDRV_CTL_ELEM_ACCESS_INACTIVE,
-+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
-+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
-+ .info = snd_bcm2835_spdif_stream_info,
-+ .get = snd_bcm2835_spdif_stream_get,
-+ .put = snd_bcm2835_spdif_stream_put,
-+ },
-+};
-+
- int snd_bcm2835_new_ctl(bcm2835_chip_t * chip)
- {
- int err;
-@@ -196,5 +313,11 @@ int snd_bcm2835_new_ctl(bcm2835_chip_t *
- if (err < 0)
- return err;
- }
-+ for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) {
-+ err = snd_ctl_add(chip->card,
-+ snd_ctl_new1(&snd_bcm2835_spdif[idx], chip));
-+ if (err < 0)
-+ return err;
-+ }
- return 0;
- }
---- a/sound/arm/bcm2835-pcm.c
-+++ b/sound/arm/bcm2835-pcm.c
-@@ -15,6 +15,8 @@
- #include <linux/interrupt.h>
- #include <linux/slab.h>
-
-+#include <sound/asoundef.h>
-+
- #include "bcm2835.h"
-
- /* hardware definition */
-@@ -34,6 +36,23 @@ static struct snd_pcm_hardware snd_bcm28
- .periods_max = 128,
- };
-
-+static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
-+ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
-+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
-+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 |
-+ SNDRV_PCM_RATE_48000,
-+ .rate_min = 44100,
-+ .rate_max = 48000,
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .buffer_bytes_max = 128 * 1024,
-+ .period_bytes_min = 1 * 1024,
-+ .period_bytes_max = 128 * 1024,
-+ .periods_min = 1,
-+ .periods_max = 128,
-+};
-+
- static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime)
- {
- audio_info("Freeing up alsa stream here ..\n");
-@@ -89,7 +108,8 @@ static irqreturn_t bcm2835_playback_fifo
- }
-
- /* open callback */
--static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream)
-+static int snd_bcm2835_playback_open_generic(
-+ struct snd_pcm_substream *substream, int spdif)
- {
- bcm2835_chip_t *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-@@ -102,6 +122,11 @@ static int snd_bcm2835_playback_open(str
- audio_info("Alsa open (%d)\n", substream->number);
- idx = substream->number;
-
-+ if (spdif && chip->opened != 0)
-+ return -EBUSY;
-+ else if (!spdif && (chip->opened & (1 << idx)))
-+ return -EBUSY;
-+
- if (idx > MAX_SUBSTREAMS) {
- audio_error
- ("substream(%d) device doesn't exist max(%d) substreams allowed\n",
-@@ -143,13 +168,20 @@ static int snd_bcm2835_playback_open(str
- }
- runtime->private_data = alsa_stream;
- runtime->private_free = snd_bcm2835_playback_free;
-- runtime->hw = snd_bcm2835_playback_hw;
-+ if (spdif) {
-+ runtime->hw = snd_bcm2835_playback_spdif_hw;
-+ } else {
-+ /* clear spdif status, as we are not in spdif mode */
-+ chip->spdif_status = 0;
-+ runtime->hw = snd_bcm2835_playback_hw;
-+ }
- /* minimum 16 bytes alignment (for vchiq bulk transfers) */
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
- 16);
-
- chip->alsa_stream[idx] = alsa_stream;
-
-+ chip->opened |= (1 << idx);
- alsa_stream->open = 1;
- alsa_stream->draining = 1;
-
-@@ -159,6 +191,16 @@ out:
- return err;
- }
-
-+static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream)
-+{
-+ return snd_bcm2835_playback_open_generic(substream, 0);
-+}
-+
-+static int snd_bcm2835_playback_spdif_open(struct snd_pcm_substream *substream)
-+{
-+ return snd_bcm2835_playback_open_generic(substream, 1);
-+}
-+
- /* close callback */
- static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
- {
-@@ -166,6 +208,7 @@ static int snd_bcm2835_playback_close(st
-
- struct snd_pcm_runtime *runtime = substream->runtime;
- bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
-+ bcm2835_chip_t *chip = snd_pcm_substream_chip(substream);
-
- audio_info(" .. IN\n");
- audio_info("Alsa close\n");
-@@ -196,6 +239,8 @@ static int snd_bcm2835_playback_close(st
- * runtime->private_free callback we registered in *_open above
- */
-
-+ chip->opened &= ~(1 << substream->number);
-+
- audio_info(" .. OUT\n");
-
- return 0;
-@@ -205,10 +250,9 @@ static int snd_bcm2835_playback_close(st
- static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
- {
-- int err;
- struct snd_pcm_runtime *runtime = substream->runtime;
-- bcm2835_alsa_stream_t *alsa_stream =
-- (bcm2835_alsa_stream_t *) runtime->private_data;
-+ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
-+ int err;
-
- audio_info(" .. IN\n");
-
-@@ -219,19 +263,9 @@ static int snd_bcm2835_pcm_hw_params(str
- return err;
- }
-
-- err = bcm2835_audio_set_params(alsa_stream, params_channels(params),
-- params_rate(params),
-- snd_pcm_format_width(params_format
-- (params)));
-- if (err < 0) {
-- audio_error(" error setting hw params\n");
-- }
--
-- bcm2835_audio_setup(alsa_stream);
--
-- /* in preparation of the stream, set the controls (volume level) of the stream */
-- bcm2835_audio_set_ctls(alsa_stream->chip);
--
-+ alsa_stream->channels = params_channels(params);
-+ alsa_stream->params_rate = params_rate(params);
-+ alsa_stream->pcm_format_width = snd_pcm_format_width(params_format (params));
- audio_info(" .. OUT\n");
-
- return err;
-@@ -247,11 +281,35 @@ static int snd_bcm2835_pcm_hw_free(struc
- /* prepare callback */
- static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
- {
-+ bcm2835_chip_t *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
-+ int channels;
-+ int err;
-
- audio_info(" .. IN\n");
-
-+ /* notify the vchiq that it should enter spdif passthrough mode by
-+ * setting channels=0 (see
-+ * https://github.com/raspberrypi/linux/issues/528) */
-+ if (chip->spdif_status & IEC958_AES0_NONAUDIO)
-+ channels = 0;
-+ else
-+ channels = alsa_stream->channels;
-+
-+ err = bcm2835_audio_set_params(alsa_stream, channels,
-+ alsa_stream->params_rate,
-+ alsa_stream->pcm_format_width);
-+ if (err < 0) {
-+ audio_error(" error setting hw params\n");
-+ }
-+
-+ bcm2835_audio_setup(alsa_stream);
-+
-+ /* in preparation of the stream, set the controls (volume level) of the stream */
-+ bcm2835_audio_set_ctls(alsa_stream->chip);
-+
-+
- memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect));
-
- alsa_stream->pcm_indirect.hw_buffer_size =
-@@ -392,6 +450,18 @@ static struct snd_pcm_ops snd_bcm2835_pl
- .ack = snd_bcm2835_pcm_ack,
- };
-
-+static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
-+ .open = snd_bcm2835_playback_spdif_open,
-+ .close = snd_bcm2835_playback_close,
-+ .ioctl = snd_bcm2835_pcm_lib_ioctl,
-+ .hw_params = snd_bcm2835_pcm_hw_params,
-+ .hw_free = snd_bcm2835_pcm_hw_free,
-+ .prepare = snd_bcm2835_pcm_prepare,
-+ .trigger = snd_bcm2835_pcm_trigger,
-+ .pointer = snd_bcm2835_pcm_pointer,
-+ .ack = snd_bcm2835_pcm_ack,
-+};
-+
- /* create a pcm device */
- int snd_bcm2835_new_pcm(bcm2835_chip_t * chip)
- {
-@@ -424,3 +494,25 @@ int snd_bcm2835_new_pcm(bcm2835_chip_t *
-
- return 0;
- }
-+
-+int snd_bcm2835_new_spdif_pcm(bcm2835_chip_t * chip)
-+{
-+ struct snd_pcm *pcm;
-+ int err;
-+
-+ err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm);
-+ if (err < 0)
-+ return err;
-+
-+ pcm->private_data = chip;
-+ strcpy(pcm->name, "bcm2835 IEC958/HDMI");
-+ chip->pcm_spdif = pcm;
-+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-+ &snd_bcm2835_playback_spdif_ops);
-+
-+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
-+ snd_dma_continuous_data (GFP_KERNEL),
-+ 64 * 1024, 64 * 1024);
-+
-+ return 0;
-+}
---- a/sound/arm/bcm2835.c
-+++ b/sound/arm/bcm2835.c
-@@ -104,7 +104,7 @@ static int snd_bcm2835_alsa_probe(struct
- goto out;
-
- snd_card_set_dev(g_card, &pdev->dev);
-- strcpy(g_card->driver, "BRCM bcm2835 ALSA Driver");
-+ strcpy(g_card->driver, "bcm2835");
- strcpy(g_card->shortname, "bcm2835 ALSA");
- sprintf(g_card->longname, "%s", g_card->shortname);
-
-@@ -121,6 +121,12 @@ static int snd_bcm2835_alsa_probe(struct
- goto out_bcm2835_new_pcm;
- }
-
-+ err = snd_bcm2835_new_spdif_pcm(chip);
-+ if (err < 0) {
-+ dev_err(&pdev->dev, "Failed to create new BCM2835 spdif pcm device\n");
-+ goto out_bcm2835_new_spdif;
-+ }
-+
- err = snd_bcm2835_new_ctl(chip);
- if (err < 0) {
- dev_err(&pdev->dev, "Failed to create new BCM2835 ctl\n");
-@@ -156,6 +162,7 @@ add_register_map:
-
- out_card_register:
- out_bcm2835_new_ctl:
-+out_bcm2835_new_spdif:
- out_bcm2835_new_pcm:
- out_bcm2835_create:
- BUG_ON(!g_card);
---- a/sound/arm/bcm2835.h
-+++ b/sound/arm/bcm2835.h
-@@ -97,6 +97,7 @@ typedef enum {
- typedef struct bcm2835_chip {
- struct snd_card *card;
- struct snd_pcm *pcm;
-+ struct snd_pcm *pcm_spdif;
- /* Bitmat for valid reg_base and irq numbers */
- uint32_t avail_substreams;
- struct platform_device *pdev[MAX_SUBSTREAMS];
-@@ -106,6 +107,9 @@ typedef struct bcm2835_chip {
- int old_volume; /* stores the volume value whist muted */
- int dest;
- int mute;
-+
-+ unsigned int opened;
-+ unsigned int spdif_status;
- } bcm2835_chip_t;
-
- typedef struct bcm2835_alsa_stream {
-@@ -123,6 +127,10 @@ typedef struct bcm2835_alsa_stream {
- int running;
- int draining;
-
-+ int channels;
-+ int params_rate;
-+ int pcm_format_width;
-+
- unsigned int pos;
- unsigned int buffer_size;
- unsigned int period_size;
-@@ -138,6 +146,7 @@ typedef struct bcm2835_alsa_stream {
-
- int snd_bcm2835_new_ctl(bcm2835_chip_t * chip);
- int snd_bcm2835_new_pcm(bcm2835_chip_t * chip);
-+int snd_bcm2835_new_spdif_pcm(bcm2835_chip_t * chip);
-
- int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream);
- int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream);