/* Stop PCM stream. */ void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm) { pcm_disconnect_substream(get_substream (line6pcm, SNDRV_PCM_STREAM_CAPTURE)); pcm_disconnect_substream(get_substream (line6pcm, SNDRV_PCM_STREAM_PLAYBACK)); line6_unlink_wait_clear_audio_out_urbs(line6pcm); line6_unlink_wait_clear_audio_in_urbs(line6pcm); }
void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) { struct snd_pcm_substream *substream = get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); line6pcm->bytes_in += length; if (line6pcm->bytes_in >= line6pcm->period_in) { line6pcm->bytes_in %= line6pcm->period_in; snd_pcm_period_elapsed(substream); } }
void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length) { struct snd_pcm_substream *substream = get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); line6pcm->in.bytes += length; if (line6pcm->in.bytes >= line6pcm->in.period) { line6pcm->in.bytes %= line6pcm->in.period; spin_unlock(&line6pcm->in.lock); snd_pcm_period_elapsed(substream); spin_lock(&line6pcm->in.lock); } }
/* Copy data into ALSA capture buffer. */ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize) { struct snd_pcm_substream *substream = get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE); struct snd_pcm_runtime *runtime = substream->runtime; const int bytes_per_frame = line6pcm->properties->bytes_per_channel * line6pcm->properties->capture_hw.channels_max; int frames = fsize / bytes_per_frame; if (runtime == NULL) return; if (line6pcm->in.pos_done + frames > runtime->buffer_size) { /* The transferred area goes over buffer boundary, copy two separate chunks. */ int len; len = runtime->buffer_size - line6pcm->in.pos_done; if (len > 0) { memcpy(runtime->dma_area + line6pcm->in.pos_done * bytes_per_frame, fbuf, len * bytes_per_frame); memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, (frames - len) * bytes_per_frame); } else { /* this is somewhat paranoid */ dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); } } else { /* copy single chunk */ memcpy(runtime->dma_area + line6pcm->in.pos_done * bytes_per_frame, fbuf, fsize); } line6pcm->in.pos_done += frames; if (line6pcm->in.pos_done >= runtime->buffer_size) line6pcm->in.pos_done -= runtime->buffer_size; }