From f29b8df6261e72d9a426d6d8c175a896931654e2 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Wed, 19 Aug 2020 15:19:33 +0530 Subject: tinyalsa: add plugin support for mmap/poll ops --- include/tinyalsa/plugin.h | 6 ++++++ src/pcm.c | 24 ++++++++++++------------ src/pcm_hw.c | 23 +++++++++++++++++++++++ src/pcm_io.h | 5 +++++ src/pcm_plugin.c | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 12 deletions(-) diff --git a/include/tinyalsa/plugin.h b/include/tinyalsa/plugin.h index a140754..b2f97b9 100644 --- a/include/tinyalsa/plugin.h +++ b/include/tinyalsa/plugin.h @@ -30,6 +30,7 @@ #ifndef TINYALSA_PLUGIN_H #define TINYALSA_PLUGIN_H +#include #include #include #include @@ -128,6 +129,11 @@ struct pcm_plugin_ops { /** Any custom or alsa specific ioctl implementation */ 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); }; /** Minimum and maximum values for hardware parameter constraints. diff --git a/src/pcm.c b/src/pcm.c index ac82042..3f5ae0a 100644 --- a/src/pcm.c +++ b/src/pcm.c @@ -404,8 +404,8 @@ int pcm_set_config(struct pcm *pcm, const struct pcm_config *config) pcm->buffer_size = config->period_count * config->period_size; if (pcm->flags & PCM_MMAP) { - pcm->mmap_buffer = mmap(NULL, pcm_frames_to_bytes(pcm, pcm->buffer_size), - PROT_READ | PROT_WRITE, 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_SHARED, 0); if (pcm->mmap_buffer == MAP_FAILED) { int errno_copy = errno; oops(pcm, errno, "failed to mmap buffer %d bytes\n", @@ -544,19 +544,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_SHARED, - pcm->fd, SNDRV_PCM_MMAP_OFFSET_STATUS); + pcm->mmap_status = pcm->ops->mmap(pcm->data, NULL, page_size, PROT_READ, 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_SHARED, pcm->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL); + pcm->mmap_control = pcm->ops->mmap(pcm->data, NULL, page_size, PROT_READ | PROT_WRITE, + 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; } @@ -581,9 +581,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; @@ -813,7 +813,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)); } snd_utils_close_dev_node(pcm->snd_node); @@ -948,7 +948,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, fail: pcm_hw_munmap_status(pcm); 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); fail_close_dev_node: @@ -1264,7 +1264,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/src/pcm_hw.c b/src/pcm_hw.c index e25cdae..38b2e83 100644 --- a/src/pcm_hw.c +++ b/src/pcm_hw.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -77,6 +78,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, struct snd_node *node) { @@ -115,5 +135,8 @@ const 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/src/pcm_io.h b/src/pcm_io.h index 1b68ac8..3c622fd 100644 --- a/src/pcm_io.h +++ b/src/pcm_io.h @@ -30,6 +30,7 @@ #ifndef TINYALSA_SRC_PCM_IO_H #define TINYALSA_SRC_PCM_IO_H +#include #include struct snd_node; @@ -39,6 +40,10 @@ struct pcm_ops { unsigned int flags, void **data, struct snd_node *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); }; extern const struct pcm_ops hw_ops; diff --git a/src/pcm_plugin.c b/src/pcm_plugin.c index 5d5f79c..8b633aa 100644 --- a/src/pcm_plugin.c +++ b/src/pcm_plugin.c @@ -672,6 +672,38 @@ 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 plug_data->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 plug_data->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 plug_data->ops->munmap(plugin, addr, length); +} + static int pcm_plug_open(unsigned int card, unsigned int device, unsigned int flags, void **data, struct snd_node *pcm_node) { @@ -740,4 +772,7 @@ const 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, }; -- cgit v1.2.3