diff options
author | Michael Zoran <mzoran@crowfest.net> | 2017-03-14 17:01:25 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-21 08:38:33 +0100 |
commit | 325b5b6c96a863989078df402d1670d061f52d88 (patch) | |
tree | e0fd2152f21ba6a6952b7fc0b7629acf9e8ead8b /drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | |
parent | f7d51372d7d1779bf60f7de35a4b12850442a9de (diff) | |
download | op-kernel-dev-325b5b6c96a863989078df402d1670d061f52d88.zip op-kernel-dev-325b5b6c96a863989078df402d1670d061f52d88.tar.gz |
staging: bcm2835-audio: Add support for simultanous HDMI and Headphone audio
The firmware for the Raspberry PI already supports simultanous output
of audio through both the HDMI and the Headphone jack. The current
implementation of ALSA doesn't expose this well to user mode since
the firmware audio is represented as a single card.
A newer approach is taken here and a virtual card is created for each
output(HDMI, Headphones, and Traditional ALSA). The firmware has
the concept of channels or streams for which the number to use is
passed in the device tree. These streams are allocated to each of the
virtual cards.
As a side effect of this change, since each output is represented
independenly it's now very easy to use PulseAudio to control the
priorities of the outputs.
Testing:
Audacity and VLC were both loaded at the same time. Each application
was assigned to a different card. With this change I was able to play
different music files at the same time through the HDMI and Headphones
jacks and control the audio independently.
Signed-off-by: Michael Zoran <mzoran@crowfest.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c')
-rw-r--r-- | drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c index 059f54a..8bd69b9 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c @@ -479,7 +479,7 @@ static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { }; /* create a pcm device */ -int snd_bcm2835_new_pcm(struct bcm2835_chip *chip) +int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels) { struct snd_pcm *pcm; int err; @@ -490,7 +490,7 @@ int snd_bcm2835_new_pcm(struct bcm2835_chip *chip) audio_error("Interrupted whilst waiting for lock\n"); return -EINTR; } - err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, MAX_SUBSTREAMS, 0, &pcm); + err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm); if (err < 0) goto out; pcm->private_data = chip; @@ -549,3 +549,39 @@ out: return 0; } + +int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip, + const char *name, + enum snd_bcm2835_route route, + u32 numchannels) +{ + struct snd_pcm *pcm; + int err; + + mutex_init(&chip->audio_mutex); + + err = snd_pcm_new(chip->card, name, 0, numchannels, + 0, &pcm); + if (err) + return err; + + pcm->private_data = chip; + strcpy(pcm->name, name); + chip->pcm = pcm; + chip->dest = route; + chip->volume = alsa2chip(0); + chip->mute = CTRL_VOL_UNMUTE; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_bcm2835_playback_ops); + + snd_pcm_lib_preallocate_pages_for_all( + pcm, + SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + snd_bcm2835_playback_hw.buffer_bytes_max, + snd_bcm2835_playback_hw.buffer_bytes_max); + + return 0; +} + |