summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillerliang <millerliang@google.com>2021-10-06 23:23:53 +0800
committerMiller Liang <millerliang@google.com>2021-10-13 16:24:42 +0000
commit2ea06d398df00e4383e0f538b4443cc3f471dba6 (patch)
treecd6cd749eaf8c9aa5883dbadb3235fd6db3c36a7
parent07596de8fb03884e88855660209e4089ca95cd01 (diff)
downloadaoc-2ea06d398df00e4383e0f538b4443cc3f471dba6.tar.gz
aoc/alsa: return the heap address for mmap use cases
Some applications may stop the mmap stream but not close it. Audio HAL will fail to get the dma-buf fd at the next stream, then it will fall back to use the shared mode fd(/dev/snd). Since AoC hooks the ring buffer address to the dma-buf heap address, we return the same heap address in pcm mmap function for mmap playback and capture use cases. Bug:198963233 Test: 1. b/199285450#comment1, test_steal_exclusive -c0 2. OboeTester Signed-off-by: millerliang <millerliang@google.com> Change-Id: I61d6e041507a385eb9f36d4a773f6751b542ada9
-rw-r--r--alsa/aoc_alsa_pcm.c15
-rw-r--r--aoc.c30
-rw-r--r--aoc.h2
3 files changed, 43 insertions, 4 deletions
diff --git a/alsa/aoc_alsa_pcm.c b/alsa/aoc_alsa_pcm.c
index 908f908..5cbd12f 100644
--- a/alsa/aoc_alsa_pcm.c
+++ b/alsa/aoc_alsa_pcm.c
@@ -607,16 +607,23 @@ static int snd_aoc_pcm_mmap(struct snd_soc_component *component,
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct aoc_alsa_stream *alsa_stream = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
size_t ring_size;
int err;
phys_addr_t aoc_ring_base;
+ aoc_direction dir;
+
+ dir = ((alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ AOC_DOWN : AOC_UP);
- if (alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ /* return the heap base address for MMAP playback and capture */
+ if (is_aaudio_mmaped_service(rtd->dai_link->name)) {
aoc_ring_base =
- aoc_service_ring_base_phys_addr(alsa_stream->dev, AOC_DOWN, &ring_size);
- else
+ aoc_get_heap_base_phys_addr(alsa_stream->dev, dir, &ring_size);
+ } else {
aoc_ring_base =
- aoc_service_ring_base_phys_addr(alsa_stream->dev, AOC_UP, &ring_size);
+ aoc_service_ring_base_phys_addr(alsa_stream->dev, dir, &ring_size);
+ }
alsa_stream->vma = vma;
diff --git a/aoc.c b/aoc.c
index 0983597..5a13f55 100644
--- a/aoc.c
+++ b/aoc.c
@@ -903,6 +903,36 @@ phys_addr_t aoc_service_ring_base_phys_addr(struct aoc_service_dev *dev, aoc_dir
}
EXPORT_SYMBOL_GPL(aoc_service_ring_base_phys_addr);
+phys_addr_t aoc_get_heap_base_phys_addr(struct aoc_service_dev *dev, aoc_direction dir,
+ size_t *out_size)
+{
+ const struct device *parent;
+ struct aoc_prvdata *prvdata;
+ aoc_service *service;
+ phys_addr_t audio_heap_base;
+
+ if (!dev)
+ return -EINVAL;
+
+ parent = dev->dev.parent;
+ prvdata = dev_get_drvdata(parent);
+
+ service = service_at_index(prvdata, dev->service_index);
+
+ if (out_size)
+ *out_size = aoc_service_ring_size(service, dir);
+
+ if (dir == AOC_DOWN)
+ audio_heap_base = prvdata->audio_playback_heap_base;
+ else
+ audio_heap_base = prvdata->audio_capture_heap_base;
+
+ pr_debug("Get heap address(phy):%llx\n", audio_heap_base);
+
+ return audio_heap_base;
+}
+EXPORT_SYMBOL_GPL(aoc_get_heap_base_phys_addr);
+
bool aoc_service_flush_read_data(struct aoc_service_dev *dev)
{
const struct device *parent;
diff --git a/aoc.h b/aoc.h
index 506e7df..cfcf011 100644
--- a/aoc.h
+++ b/aoc.h
@@ -41,6 +41,8 @@ struct aoc_service_dev {
phys_addr_t aoc_service_ring_base_phys_addr(struct aoc_service_dev *dev, aoc_direction dir,
size_t *out_size);
+phys_addr_t aoc_get_heap_base_phys_addr(struct aoc_service_dev *dev, aoc_direction dir,
+ size_t *out_size);
ssize_t aoc_service_read(struct aoc_service_dev *dev, uint8_t *buffer,
size_t count, bool block);
ssize_t aoc_service_read_timeout(struct aoc_service_dev *dev, uint8_t *buffer,