aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2021-01-19 16:45:28 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-01-19 16:45:28 +0000
commit19a5d55fb349b0a5a9f32619122ca9f05e330161 (patch)
treea15cfd3fe3330a25bfcb374d7c9ff96fbdc9a0cc
parente6c59a83007446caffbcb8aeddf9cfa9fa0fda71 (diff)
parentf0ddfb0b029af9d18262aa147fa524b87cf2b7c1 (diff)
downloadtinyalsa-19a5d55fb349b0a5a9f32619122ca9f05e330161.tar.gz
Merge changes I22a32a3a,I7b5b5941,Ic8a1976e,I79f480bf,I5a29eb8d, ... am: a884af18d0 am: f0ddfb0b02
Original change: https://android-review.googlesource.com/c/platform/external/tinyalsa/+/1554370 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Ib91ddba674d9f76d39c71f276197f7cd53ba64d2
-rw-r--r--include/tinyalsa/pcm_plugin.h7
-rw-r--r--pcm.c25
-rw-r--r--pcm_hw.c23
-rw-r--r--pcm_io.h6
-rw-r--r--pcm_plugin.c67
5 files changed, 111 insertions, 17 deletions
diff --git a/include/tinyalsa/pcm_plugin.h b/include/tinyalsa/pcm_plugin.h
index 5d6f503..f1708b1 100644
--- a/include/tinyalsa/pcm_plugin.h
+++ b/include/tinyalsa/pcm_plugin.h
@@ -30,6 +30,8 @@
#ifndef __PCM_PLUGIN_H__
#define __PCM_PLUGIN_H__
+#include <poll.h>
+
#define PCM_PLUGIN_OPEN_FN(name) \
int name##_open(struct pcm_plugin **plugin, \
unsigned int card, \
@@ -63,6 +65,11 @@ struct pcm_plugin_ops {
int (*drop) (struct pcm_plugin *plugin);
int (*ioctl) (struct pcm_plugin *plugin,
int cmd, void *arg);
+ void* (*mmap) (struct pcm_plugin *plugin, void *addr, size_t length, int prot,
+ int flags, off_t offset);
+ int (*munmap) (struct pcm_plugin *plugin, void *addr, size_t length);
+ int (*poll) (struct pcm_plugin *plugin, struct pollfd *pfd, nfds_t nfds,
+ int timeout);
};
struct pcm_plugin_min_max {
diff --git a/pcm.c b/pcm.c
index dc347af..c885b44 100644
--- a/pcm.c
+++ b/pcm.c
@@ -363,19 +363,19 @@ static int pcm_hw_mmap_status(struct pcm *pcm) {
return 0;
int page_size = sysconf(_SC_PAGE_SIZE);
- pcm->mmap_status = mmap(NULL, page_size, PROT_READ, MAP_FILE | MAP_SHARED,
- pcm->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
+ pcm->mmap_status = pcm->ops->mmap(pcm->data, NULL, page_size, PROT_READ, MAP_FILE | MAP_SHARED,
+ SNDRV_PCM_MMAP_OFFSET_STATUS);
if (pcm->mmap_status == MAP_FAILED)
pcm->mmap_status = NULL;
if (!pcm->mmap_status)
goto mmap_error;
- pcm->mmap_control = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
- MAP_FILE | MAP_SHARED, pcm->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
+ pcm->mmap_control = pcm->ops->mmap(pcm->data, NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, SNDRV_PCM_MMAP_OFFSET_CONTROL);
if (pcm->mmap_control == MAP_FAILED)
pcm->mmap_control = NULL;
if (!pcm->mmap_control) {
- munmap(pcm->mmap_status, page_size);
+ pcm->ops->munmap(pcm->data, pcm->mmap_status, page_size);
pcm->mmap_status = NULL;
goto mmap_error;
}
@@ -410,9 +410,9 @@ static void pcm_hw_munmap_status(struct pcm *pcm) {
} else {
int page_size = sysconf(_SC_PAGE_SIZE);
if (pcm->mmap_status)
- munmap(pcm->mmap_status, page_size);
+ pcm->ops->munmap(pcm->data, pcm->mmap_status, page_size);
if (pcm->mmap_control)
- munmap(pcm->mmap_control, page_size);
+ pcm->ops->munmap(pcm->data, pcm->mmap_control, page_size);
}
pcm->mmap_status = NULL;
pcm->mmap_control = NULL;
@@ -883,7 +883,7 @@ int pcm_close(struct pcm *pcm)
if (pcm->flags & PCM_MMAP) {
pcm_stop(pcm);
- munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
+ pcm->ops->munmap(pcm->data, pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
}
if (pcm->data)
@@ -981,8 +981,9 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
pcm->buffer_size = config->period_count * config->period_size;
if (flags & PCM_MMAP) {
- pcm->mmap_buffer = mmap(NULL, pcm_frames_to_bytes(pcm, pcm->buffer_size),
- PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, pcm->fd, 0);
+ pcm->mmap_buffer = pcm->ops->mmap(pcm->data, NULL,
+ pcm_frames_to_bytes(pcm, pcm->buffer_size),
+ PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, 0);
if (pcm->mmap_buffer == MAP_FAILED) {
oops(pcm, errno, "failed to mmap buffer %d bytes\n",
pcm_frames_to_bytes(pcm, pcm->buffer_size));
@@ -1058,7 +1059,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
fail:
if (flags & PCM_MMAP)
- munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
+ pcm->ops->munmap(pcm->data, pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size));
fail_close:
pcm->ops->close(pcm->data);
pcm->data = NULL;
@@ -1225,7 +1226,7 @@ int pcm_wait(struct pcm *pcm, int timeout)
do {
/* let's wait for avail or timeout */
- err = poll(&pfd, 1, timeout);
+ err = pcm->ops->poll(pcm->data, &pfd, 1, timeout);
if (err < 0)
return -errno;
diff --git a/pcm_hw.c b/pcm_hw.c
index 8fd78fb..f19f07b 100644
--- a/pcm_hw.c
+++ b/pcm_hw.c
@@ -38,6 +38,7 @@
#include <poll.h>
#include <sys/ioctl.h>
+#include <sys/mman.h>
#include <linux/ioctl.h>
#include <sound/asound.h>
#include <tinyalsa/asoundlib.h>
@@ -74,6 +75,25 @@ static int pcm_hw_ioctl(void *data, unsigned int cmd, ...)
return ioctl(hw_data->fd, cmd, arg);
}
+static int pcm_hw_poll(void *data __attribute__((unused)),
+ struct pollfd *pfd, nfds_t nfds, int timeout)
+{
+ return poll(pfd, nfds, timeout);
+}
+
+static void* pcm_hw_mmap(void *data, void *addr, size_t length, int prot,
+ int flags, off_t offset)
+{
+ struct pcm_hw_data *hw_data = data;
+
+ return mmap(addr, length, prot, flags, hw_data->fd, offset);
+}
+
+static int pcm_hw_munmap(void *data __attribute__((unused)), void *addr, size_t length)
+{
+ return munmap(addr, length);
+}
+
static int pcm_hw_open(unsigned int card, unsigned int device,
unsigned int flags, void **data,
__attribute__((unused)) void *node)
@@ -120,4 +140,7 @@ struct pcm_ops hw_ops = {
.open = pcm_hw_open,
.close = pcm_hw_close,
.ioctl = pcm_hw_ioctl,
+ .mmap = pcm_hw_mmap,
+ .munmap = pcm_hw_munmap,
+ .poll = pcm_hw_poll,
};
diff --git a/pcm_io.h b/pcm_io.h
index 2271d76..4d9746d 100644
--- a/pcm_io.h
+++ b/pcm_io.h
@@ -31,11 +31,17 @@
#ifndef __PCM_H__
#define __PCM_H__
+#include <poll.h>
+
struct pcm_ops {
int (*open) (unsigned int card, unsigned int device,
unsigned int flags, void **data, void *node);
void (*close) (void *data);
int (*ioctl) (void *data, unsigned int cmd, ...);
+ void* (*mmap) (void *data, void *addr, size_t length, int prot, int flags,
+ off_t offset);
+ int (*munmap) (void *data, void *addr, size_t length);
+ int (*poll) (void *data, struct pollfd *pfd, nfds_t nfds, int timeout);
};
#endif /* end of __PCM_H__ */
diff --git a/pcm_plugin.c b/pcm_plugin.c
index 12ab34b..14c6cdb 100644
--- a/pcm_plugin.c
+++ b/pcm_plugin.c
@@ -510,12 +510,35 @@ static int pcm_plug_sparams(struct pcm_plug_data *plug_data,
return plugin->ops->sw_params(plugin, params);
}
+static int convert_plugin_to_pcm_state(int plugin_state)
+{
+ switch (plugin_state) {
+ case PCM_PLUG_STATE_SETUP:
+ return PCM_STATE_SETUP;
+ case PCM_PLUG_STATE_RUNNING:
+ return PCM_STATE_RUNNING;
+ case PCM_PLUG_STATE_PREPARED:
+ return PCM_STATE_PREPARED;
+ case PCM_PLUG_STATE_OPEN:
+ return PCM_STATE_OPEN;
+ }
+
+ return PCM_STATE_OPEN;
+}
+
static int pcm_plug_sync_ptr(struct pcm_plug_data *plug_data,
struct snd_pcm_sync_ptr *sync_ptr)
{
struct pcm_plugin *plugin = plug_data->plugin;
+ int ret = -EBADFD;
+
+ if (plugin->state >= PCM_PLUG_STATE_SETUP) {
+ ret = plugin->ops->sync_ptr(plugin, sync_ptr);
+ if (ret == 0)
+ sync_ptr->s.status.state = convert_plugin_to_pcm_state(plugin->state);
+ }
- return plugin->ops->sync_ptr(plugin, sync_ptr);
+ return ret;
}
static int pcm_plug_writei_frames(struct pcm_plug_data *plug_data,
@@ -546,10 +569,10 @@ static int pcm_plug_ttstamp(struct pcm_plug_data *plug_data,
{
struct pcm_plugin *plugin = plug_data->plugin;
- if (plugin->state != PCM_PLUG_STATE_RUNNING)
+ if (plugin->state >= PCM_PLUG_STATE_SETUP)
+ return plugin->ops->ttstamp(plugin, tstamp);
+ else
return -EBADFD;
-
- return plugin->ops->ttstamp(plugin, tstamp);
}
static int pcm_plug_prepare(struct pcm_plug_data *plug_data)
@@ -648,6 +671,37 @@ static int pcm_plug_ioctl(void *data, unsigned int cmd, ...)
return ret;
}
+static int pcm_plug_poll(void *data, struct pollfd *pfd, nfds_t nfds,
+ int timeout)
+{
+ struct pcm_plug_data *plug_data = data;
+ struct pcm_plugin *plugin = plug_data->plugin;
+
+ return plugin->ops->poll(plugin, pfd, nfds, timeout);
+}
+
+static void* pcm_plug_mmap(void *data, void *addr, size_t length, int prot,
+ int flags, off_t offset)
+{
+ struct pcm_plug_data *plug_data = data;
+ struct pcm_plugin *plugin = plug_data->plugin;
+
+ if (plugin->state != PCM_PLUG_STATE_SETUP)
+ return NULL;
+ return plugin->ops->mmap(plugin, addr, length, prot, flags, offset);
+}
+
+static int pcm_plug_munmap(void *data, void *addr, size_t length)
+{
+ struct pcm_plug_data *plug_data = data;
+ struct pcm_plugin *plugin = plug_data->plugin;
+
+ if (plugin->state != PCM_PLUG_STATE_SETUP)
+ return -EBADFD;
+
+ return plugin->ops->munmap(plugin, addr, length);
+}
+
static int pcm_plug_open(unsigned int card, unsigned int device,
unsigned int flags, void **data, void *pcm_node)
{
@@ -669,7 +723,7 @@ static int pcm_plug_open(unsigned int card, unsigned int device,
dl_hdl = dlopen(so_name, RTLD_NOW);
if (!dl_hdl) {
- fprintf(stderr, "%s: unable to open %s\n", __func__, so_name);
+ fprintf(stderr, "%s: unable to open %s: %s\n", __func__, so_name, dlerror());
goto err_dl_open;
} else {
fprintf(stderr, "%s: dlopen successful for %s\n", __func__, so_name);
@@ -739,4 +793,7 @@ struct pcm_ops plug_ops = {
.open = pcm_plug_open,
.close = pcm_plug_close,
.ioctl = pcm_plug_ioctl,
+ .mmap = pcm_plug_mmap,
+ .munmap = pcm_plug_munmap,
+ .poll = pcm_plug_poll,
};