aboutsummaryrefslogtreecommitdiffstats
path: root/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcm.c')
-rw-r--r--pcm.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/pcm.c b/pcm.c
index babc8b6..73f87c9 100644
--- a/pcm.c
+++ b/pcm.c
@@ -20,6 +20,9 @@
(ap)->pcm_ops->callback((substream), ##__VA_ARGS__) : \
0)
+#define PRIVATE_DATA(substream) \
+ ((struct snd_avirt_private_data *) substream->private_data)
+
/**
* snd_avirt_pcm_period_elapsed - PCM buffer complete callback
* @substreamid: pointer to ALSA PCM substream
@@ -48,6 +51,7 @@ EXPORT_SYMBOL_GPL(snd_avirt_pcm_period_elapsed);
*/
static int pcm_open(struct snd_pcm_substream *substream)
{
+ struct snd_avirt_private_data *avirt_private_data;
struct snd_avirt_audiopath *audiopath;
struct snd_avirt_stream *stream;
struct snd_pcm_hardware *hw;
@@ -56,7 +60,8 @@ static int pcm_open(struct snd_pcm_substream *substream)
stream = snd_avirt_stream_find_by_device(substream->pcm->device);
audiopath = snd_avirt_audiopath_get(stream->map);
CHK_NULL_V(audiopath, "Cannot find Audio Path uid: '%s'!", stream->map);
- substream->private_data = audiopath;
+ avirt_private_data = substream->private_data;
+ avirt_private_data->audiopath = audiopath;
// Copy the hw params from the audiopath to the pcm
hw = &substream->runtime->hw;
@@ -87,8 +92,8 @@ static int pcm_close(struct snd_pcm_substream *substream)
{
// Do additional Audio Path 'close' callback
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data), close,
- substream);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ close, substream);
}
/**
@@ -120,7 +125,8 @@ static int pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- audiopath = ((struct snd_avirt_audiopath *)substream->private_data);
+ audiopath =
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath;
bufsz = params_buffer_bytes(hw_params) * audiopath->hw->periods_max;
retval = snd_pcm_lib_alloc_vmalloc_buffer(substream, bufsz);
@@ -145,8 +151,8 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
// Do additional Audio Path 'hw_free' callback
err = DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
- hw_free, substream);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ hw_free, substream);
return snd_pcm_lib_free_vmalloc_buffer(substream);
}
@@ -163,10 +169,11 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
*/
static int pcm_prepare(struct snd_pcm_substream *substream)
{
+
// Do additional Audio Path 'prepare' callback
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
- prepare, substream);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ prepare, substream);
}
/**
@@ -181,7 +188,8 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
*/
static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
- switch (cmd) {
+
+ switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_STOP:
@@ -194,8 +202,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
// Do additional Audio Path 'trigger' callback
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
- trigger, substream, cmd);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ trigger, substream, cmd);
}
/**
@@ -212,8 +220,8 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
{
// Do additional Audio Path 'pointer' callback
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
- pointer, substream);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ pointer, substream);
}
/**
@@ -228,14 +236,14 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
*
* Returns 0 on success or error code otherwise
*/
-static int pcm_get_time_info(
- struct snd_pcm_substream *substream, struct timespec *system_ts,
- struct timespec *audio_ts,
- struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
- struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
+static int
+pcm_get_time_info(struct snd_pcm_substream *substream,
+ struct timespec *system_ts, struct timespec *audio_ts,
+ struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
+ struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
{
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
get_time_info, substream, system_ts, audio_ts,
audio_tstamp_config, audio_tstamp_report);
}
@@ -257,6 +265,7 @@ static int pcm_copy_user(struct snd_pcm_substream *substream, int channel,
snd_pcm_uframes_t pos, void __user *src,
snd_pcm_uframes_t count)
{
+
// struct snd_pcm_runtime *runtime;
// int offset;
@@ -265,8 +274,8 @@ static int pcm_copy_user(struct snd_pcm_substream *substream, int channel,
// Do additional Audio Path 'copy_user' callback
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
- copy_user, substream, channel, pos, src, count);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ copy_user, substream, channel, pos, src, count);
}
/**
@@ -286,8 +295,8 @@ static int pcm_copy_kernel(struct snd_pcm_substream *substream, int channel,
unsigned long pos, void *buf, unsigned long count)
{
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
- copy_kernel, substream, channel, pos, buf, count);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ copy_kernel, substream, channel, pos, buf, count);
}
/**
@@ -302,16 +311,33 @@ static int pcm_copy_kernel(struct snd_pcm_substream *substream, int channel,
static int pcm_ack(struct snd_pcm_substream *substream)
{
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data), ack,
- substream);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ ack, substream);
}
static int pcm_silence(struct snd_pcm_substream *substream, int channel,
snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
{
return DO_AUDIOPATH_CB(
- ((struct snd_avirt_audiopath *)substream->private_data),
- fill_silence, substream, channel, pos, count);
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ fill_silence, substream, channel, pos, count);
+}
+
+/**
+ * pcm_mmap - Implements 'mmap' callback for PCM middle layer
+ * @substream: pointer to ALSA PCM substream
+ *
+ * This is where we need to ack
+ *
+ * Returns 0 on success or error code otherwise.
+ *
+ */
+static int pcm_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ return DO_AUDIOPATH_CB(
+ (struct snd_avirt_audiopath *)PRIVATE_DATA(substream)->audiopath,
+ mmap, substream, vma);
}
struct snd_pcm_ops pcm_ops = {
@@ -329,4 +355,5 @@ struct snd_pcm_ops pcm_ops = {
.copy_kernel = pcm_copy_kernel,
.page = snd_pcm_lib_get_vmalloc_page,
.ack = pcm_ack,
+ .mmap = pcm_mmap,
};