Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions audio/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct aaudio_subdevice {
bool is_pcm;
struct snd_pcm *pcm;
struct snd_jack *jack;
struct work_struct stop_work;
};
struct aaudio_alsa_pcm_id_mapping {
const char *name;
Expand Down
16 changes: 14 additions & 2 deletions audio/pcm.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "pcm.h"
#include "audio.h"
#include <linux/workqueue.h>

static u64 aaudio_get_alsa_fmtbit(struct aaudio_apple_description *desc)
{
Expand Down Expand Up @@ -178,23 +179,29 @@ static void aaudio_pcm_start(struct snd_pcm_substream *substream)
pr_debug("aaudio: Started the audio device in %lluns\n", ktime_to_ns(time_end - time_start));
}

static void aaudio_pcm_stop_work(struct work_struct *work)
{
struct aaudio_subdevice *sdev = container_of(work, struct aaudio_subdevice, stop_work);
aaudio_cmd_stop_io(sdev->a, sdev->dev_id);
}

static int aaudio_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct aaudio_subdevice *sdev = snd_pcm_substream_chip(substream);
struct aaudio_stream *stream = aaudio_pcm_stream(substream);
pr_debug("aaudio_pcm_trigger %x\n", cmd);

/* We only supports triggers on the #0 buffer */
if (substream->number != 0)
return 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
cancel_work_sync(&sdev->stop_work);
aaudio_pcm_start(substream);
stream->started = 1;
break;
case SNDRV_PCM_TRIGGER_STOP:
aaudio_cmd_stop_io(sdev->a, sdev->dev_id);
stream->started = 0;
schedule_work(&sdev->stop_work);
break;
default:
return -EINVAL;
Expand Down Expand Up @@ -265,6 +272,7 @@ int aaudio_create_pcm(struct aaudio_subdevice *sdev)
}
if (!id_mapping->name)
sdev->alsa_id = sdev->a->next_alsa_id++;
INIT_WORK(&sdev->stop_work, aaudio_pcm_stop_work);
err = snd_pcm_new(sdev->a->card, sdev->uid, sdev->alsa_id,
(int) sdev->out_stream_cnt, (int) sdev->in_stream_cnt, &pcm);
if (err < 0)
Expand All @@ -285,6 +293,10 @@ static void aaudio_handle_stream_timestamp(struct snd_pcm_substream *substream,

stream = aaudio_pcm_stream(substream);
snd_pcm_stream_lock_irqsave(substream, flags);
if (!stream->started) {
snd_pcm_stream_unlock_irqrestore(substream, flags);
return;
}
stream->remote_timestamp = timestamp;
if (stream->waiting_for_first_ts) {
stream->waiting_for_first_ts = false;
Expand Down