Lines Matching +full:sub +full:- +full:frame
1 // SPDX-License-Identifier: GPL-2.0-or-later
64 .period_bytes_min = PCM_N_PACKETS_PER_URB * (PCM_MAX_PACKET_SIZE - 4),
73 struct control_runtime *ctrl_rt = rt->chip->control; in usb6fire_pcm_set_rate()
75 ctrl_rt->usb_streaming = false; in usb6fire_pcm_set_rate()
76 ret = ctrl_rt->update_streaming(ctrl_rt); in usb6fire_pcm_set_rate()
78 dev_err(&rt->chip->dev->dev, in usb6fire_pcm_set_rate()
80 rates[rt->rate]); in usb6fire_pcm_set_rate()
84 ret = ctrl_rt->set_rate(ctrl_rt, rt->rate); in usb6fire_pcm_set_rate()
86 dev_err(&rt->chip->dev->dev, in usb6fire_pcm_set_rate()
88 rates[rt->rate]); in usb6fire_pcm_set_rate()
92 ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS, in usb6fire_pcm_set_rate()
95 dev_err(&rt->chip->dev->dev, in usb6fire_pcm_set_rate()
97 rates[rt->rate]); in usb6fire_pcm_set_rate()
101 ctrl_rt->usb_streaming = true; in usb6fire_pcm_set_rate()
102 ret = ctrl_rt->update_streaming(ctrl_rt); in usb6fire_pcm_set_rate()
104 dev_err(&rt->chip->dev->dev, in usb6fire_pcm_set_rate()
106 rates[rt->rate]); in usb6fire_pcm_set_rate()
110 rt->in_n_analog = IN_N_CHANNELS; in usb6fire_pcm_set_rate()
111 rt->out_n_analog = OUT_N_CHANNELS; in usb6fire_pcm_set_rate()
112 rt->in_packet_size = rates_in_packet_size[rt->rate]; in usb6fire_pcm_set_rate()
113 rt->out_packet_size = rates_out_packet_size[rt->rate]; in usb6fire_pcm_set_rate()
122 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) in usb6fire_pcm_get_substream()
123 return &rt->playback; in usb6fire_pcm_get_substream()
124 else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) in usb6fire_pcm_get_substream()
125 return &rt->capture; in usb6fire_pcm_get_substream()
126 dev_err(&rt->chip->dev->dev, "error getting pcm substream slot.\n"); in usb6fire_pcm_get_substream()
134 struct control_runtime *ctrl_rt = rt->chip->control; in usb6fire_pcm_stream_stop()
136 if (rt->stream_state != STREAM_DISABLED) { in usb6fire_pcm_stream_stop()
138 rt->stream_state = STREAM_STOPPING; in usb6fire_pcm_stream_stop()
141 usb_kill_urb(&rt->in_urbs[i].instance); in usb6fire_pcm_stream_stop()
142 usb_kill_urb(&rt->out_urbs[i].instance); in usb6fire_pcm_stream_stop()
144 ctrl_rt->usb_streaming = false; in usb6fire_pcm_stream_stop()
145 ctrl_rt->update_streaming(ctrl_rt); in usb6fire_pcm_stream_stop()
146 rt->stream_state = STREAM_DISABLED; in usb6fire_pcm_stream_stop()
158 if (rt->stream_state == STREAM_DISABLED) { in usb6fire_pcm_stream_start()
160 rt->stream_wait_cond = false; in usb6fire_pcm_stream_start()
161 rt->stream_state = STREAM_STARTING; in usb6fire_pcm_stream_start()
164 packet = &rt->in_urbs[i].packets[k]; in usb6fire_pcm_stream_start()
165 packet->offset = k * rt->in_packet_size; in usb6fire_pcm_stream_start()
166 packet->length = rt->in_packet_size; in usb6fire_pcm_stream_start()
167 packet->actual_length = 0; in usb6fire_pcm_stream_start()
168 packet->status = 0; in usb6fire_pcm_stream_start()
170 ret = usb_submit_urb(&rt->in_urbs[i].instance, in usb6fire_pcm_stream_start()
179 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond, in usb6fire_pcm_stream_start()
181 if (rt->stream_wait_cond) in usb6fire_pcm_stream_start()
182 rt->stream_state = STREAM_RUNNING; in usb6fire_pcm_stream_start()
185 return -EIO; in usb6fire_pcm_stream_start()
192 static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) in usb6fire_pcm_capture() argument
195 int frame; in usb6fire_pcm_capture() local
198 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); in usb6fire_pcm_capture()
199 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; in usb6fire_pcm_capture()
201 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off in usb6fire_pcm_capture()
202 * (alsa_rt->frame_bits >> 3)); in usb6fire_pcm_capture()
203 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size in usb6fire_pcm_capture()
204 * (alsa_rt->frame_bits >> 3)); in usb6fire_pcm_capture()
205 int bytes_per_frame = alsa_rt->channels << 2; in usb6fire_pcm_capture()
210 if (urb->packets[i].actual_length > 4) in usb6fire_pcm_capture()
211 frame_count = (urb->packets[i].actual_length - 4) in usb6fire_pcm_capture()
212 / (rt->in_n_analog << 2); in usb6fire_pcm_capture()
216 if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) in usb6fire_pcm_capture()
217 src = (u32 *) (urb->buffer + total_length); in usb6fire_pcm_capture()
218 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) in usb6fire_pcm_capture()
219 src = (u32 *) (urb->buffer - 1 + total_length); in usb6fire_pcm_capture()
223 total_length += urb->packets[i].length; in usb6fire_pcm_capture()
224 for (frame = 0; frame < frame_count; frame++) { in usb6fire_pcm_capture()
226 dest += alsa_rt->channels; in usb6fire_pcm_capture()
227 src += rt->in_n_analog; in usb6fire_pcm_capture()
228 sub->dma_off++; in usb6fire_pcm_capture()
229 sub->period_off++; in usb6fire_pcm_capture()
231 sub->dma_off = 0; in usb6fire_pcm_capture()
232 dest = (u32 *) alsa_rt->dma_area; in usb6fire_pcm_capture()
239 static void usb6fire_pcm_playback(struct pcm_substream *sub, in usb6fire_pcm_playback() argument
243 int frame; in usb6fire_pcm_playback() local
245 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); in usb6fire_pcm_playback()
246 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; in usb6fire_pcm_playback()
247 u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off in usb6fire_pcm_playback()
248 * (alsa_rt->frame_bits >> 3)); in usb6fire_pcm_playback()
249 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size in usb6fire_pcm_playback()
250 * (alsa_rt->frame_bits >> 3)); in usb6fire_pcm_playback()
252 int bytes_per_frame = alsa_rt->channels << 2; in usb6fire_pcm_playback()
254 if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) in usb6fire_pcm_playback()
255 dest = (u32 *) (urb->buffer - 1); in usb6fire_pcm_playback()
256 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) in usb6fire_pcm_playback()
257 dest = (u32 *) (urb->buffer); in usb6fire_pcm_playback()
259 dev_err(&rt->chip->dev->dev, "Unknown sample format."); in usb6fire_pcm_playback()
266 if (urb->packets[i].length > 4) in usb6fire_pcm_playback()
267 frame_count = (urb->packets[i].length - 4) in usb6fire_pcm_playback()
268 / (rt->out_n_analog << 2); in usb6fire_pcm_playback()
271 dest++; /* skip leading 4 bytes of every frame */ in usb6fire_pcm_playback()
272 for (frame = 0; frame < frame_count; frame++) { in usb6fire_pcm_playback()
274 src += alsa_rt->channels; in usb6fire_pcm_playback()
275 dest += rt->out_n_analog; in usb6fire_pcm_playback()
276 sub->dma_off++; in usb6fire_pcm_playback()
277 sub->period_off++; in usb6fire_pcm_playback()
279 src = (u32 *) alsa_rt->dma_area; in usb6fire_pcm_playback()
280 sub->dma_off = 0; in usb6fire_pcm_playback()
288 struct pcm_urb *in_urb = usb_urb->context; in usb6fire_pcm_in_urb_handler()
289 struct pcm_urb *out_urb = in_urb->peer; in usb6fire_pcm_in_urb_handler()
290 struct pcm_runtime *rt = in_urb->chip->pcm; in usb6fire_pcm_in_urb_handler()
291 struct pcm_substream *sub; in usb6fire_pcm_in_urb_handler() local
295 int frame; in usb6fire_pcm_in_urb_handler() local
300 if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING) in usb6fire_pcm_in_urb_handler()
303 if (in_urb->packets[i].status) { in usb6fire_pcm_in_urb_handler()
304 rt->panic = true; in usb6fire_pcm_in_urb_handler()
308 if (rt->stream_state == STREAM_DISABLED) { in usb6fire_pcm_in_urb_handler()
309 dev_err(&rt->chip->dev->dev, in usb6fire_pcm_in_urb_handler()
310 "internal error: stream disabled in in-urb handler.\n"); in usb6fire_pcm_in_urb_handler()
315 sub = &rt->capture; in usb6fire_pcm_in_urb_handler()
316 spin_lock_irqsave(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
317 if (sub->active) { in usb6fire_pcm_in_urb_handler()
318 usb6fire_pcm_capture(sub, in_urb); in usb6fire_pcm_in_urb_handler()
319 if (sub->period_off >= sub->instance->runtime->period_size) { in usb6fire_pcm_in_urb_handler()
320 sub->period_off %= sub->instance->runtime->period_size; in usb6fire_pcm_in_urb_handler()
321 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
322 snd_pcm_period_elapsed(sub->instance); in usb6fire_pcm_in_urb_handler()
324 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
326 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
330 out_urb->packets[i].offset = total_length; in usb6fire_pcm_in_urb_handler()
331 out_urb->packets[i].length = (in_urb->packets[i].actual_length in usb6fire_pcm_in_urb_handler()
332 - 4) / (rt->in_n_analog << 2) in usb6fire_pcm_in_urb_handler()
333 * (rt->out_n_analog << 2) + 4; in usb6fire_pcm_in_urb_handler()
334 out_urb->packets[i].status = 0; in usb6fire_pcm_in_urb_handler()
335 total_length += out_urb->packets[i].length; in usb6fire_pcm_in_urb_handler()
337 memset(out_urb->buffer, 0, total_length); in usb6fire_pcm_in_urb_handler()
340 sub = &rt->playback; in usb6fire_pcm_in_urb_handler()
341 spin_lock_irqsave(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
342 if (sub->active) { in usb6fire_pcm_in_urb_handler()
343 usb6fire_pcm_playback(sub, out_urb); in usb6fire_pcm_in_urb_handler()
344 if (sub->period_off >= sub->instance->runtime->period_size) { in usb6fire_pcm_in_urb_handler()
345 sub->period_off %= sub->instance->runtime->period_size; in usb6fire_pcm_in_urb_handler()
346 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
347 snd_pcm_period_elapsed(sub->instance); in usb6fire_pcm_in_urb_handler()
349 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
351 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_in_urb_handler()
354 dest = out_urb->buffer; in usb6fire_pcm_in_urb_handler()
356 if (out_urb->packets[i].length >= 4) { in usb6fire_pcm_in_urb_handler()
357 frame_count = (out_urb->packets[i].length - 4) in usb6fire_pcm_in_urb_handler()
358 / (rt->out_n_analog << 2); in usb6fire_pcm_in_urb_handler()
363 for (frame = 0; frame < frame_count; frame++) in usb6fire_pcm_in_urb_handler()
365 channel < rt->out_n_analog; in usb6fire_pcm_in_urb_handler()
371 usb_submit_urb(&out_urb->instance, GFP_ATOMIC); in usb6fire_pcm_in_urb_handler()
372 usb_submit_urb(&in_urb->instance, GFP_ATOMIC); in usb6fire_pcm_in_urb_handler()
377 struct pcm_urb *urb = usb_urb->context; in usb6fire_pcm_out_urb_handler()
378 struct pcm_runtime *rt = urb->chip->pcm; in usb6fire_pcm_out_urb_handler()
380 if (rt->stream_state == STREAM_STARTING) { in usb6fire_pcm_out_urb_handler()
381 rt->stream_wait_cond = true; in usb6fire_pcm_out_urb_handler()
382 wake_up(&rt->stream_wait_queue); in usb6fire_pcm_out_urb_handler()
389 struct pcm_substream *sub = NULL; in usb6fire_pcm_open() local
390 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; in usb6fire_pcm_open()
392 if (rt->panic) in usb6fire_pcm_open()
393 return -EPIPE; in usb6fire_pcm_open()
395 mutex_lock(&rt->stream_mutex); in usb6fire_pcm_open()
396 alsa_rt->hw = pcm_hw; in usb6fire_pcm_open()
398 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) { in usb6fire_pcm_open()
399 if (rt->rate < ARRAY_SIZE(rates)) in usb6fire_pcm_open()
400 alsa_rt->hw.rates = rates_alsaid[rt->rate]; in usb6fire_pcm_open()
401 alsa_rt->hw.channels_max = OUT_N_CHANNELS; in usb6fire_pcm_open()
402 sub = &rt->playback; in usb6fire_pcm_open()
403 } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) { in usb6fire_pcm_open()
404 if (rt->rate < ARRAY_SIZE(rates)) in usb6fire_pcm_open()
405 alsa_rt->hw.rates = rates_alsaid[rt->rate]; in usb6fire_pcm_open()
406 alsa_rt->hw.channels_max = IN_N_CHANNELS; in usb6fire_pcm_open()
407 sub = &rt->capture; in usb6fire_pcm_open()
410 if (!sub) { in usb6fire_pcm_open()
411 mutex_unlock(&rt->stream_mutex); in usb6fire_pcm_open()
412 dev_err(&rt->chip->dev->dev, "invalid stream type.\n"); in usb6fire_pcm_open()
413 return -EINVAL; in usb6fire_pcm_open()
416 sub->instance = alsa_sub; in usb6fire_pcm_open()
417 sub->active = false; in usb6fire_pcm_open()
418 mutex_unlock(&rt->stream_mutex); in usb6fire_pcm_open()
425 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); in usb6fire_pcm_close() local
428 if (rt->panic) in usb6fire_pcm_close()
431 mutex_lock(&rt->stream_mutex); in usb6fire_pcm_close()
432 if (sub) { in usb6fire_pcm_close()
434 spin_lock_irqsave(&sub->lock, flags); in usb6fire_pcm_close()
435 sub->instance = NULL; in usb6fire_pcm_close()
436 sub->active = false; in usb6fire_pcm_close()
437 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_close()
440 if (!rt->playback.instance && !rt->capture.instance) { in usb6fire_pcm_close()
442 rt->rate = ARRAY_SIZE(rates); in usb6fire_pcm_close()
445 mutex_unlock(&rt->stream_mutex); in usb6fire_pcm_close()
452 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); in usb6fire_pcm_prepare() local
453 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; in usb6fire_pcm_prepare()
456 if (rt->panic) in usb6fire_pcm_prepare()
457 return -EPIPE; in usb6fire_pcm_prepare()
458 if (!sub) in usb6fire_pcm_prepare()
459 return -ENODEV; in usb6fire_pcm_prepare()
461 mutex_lock(&rt->stream_mutex); in usb6fire_pcm_prepare()
462 sub->dma_off = 0; in usb6fire_pcm_prepare()
463 sub->period_off = 0; in usb6fire_pcm_prepare()
465 if (rt->stream_state == STREAM_DISABLED) { in usb6fire_pcm_prepare()
466 for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++) in usb6fire_pcm_prepare()
467 if (alsa_rt->rate == rates[rt->rate]) in usb6fire_pcm_prepare()
469 if (rt->rate == ARRAY_SIZE(rates)) { in usb6fire_pcm_prepare()
470 mutex_unlock(&rt->stream_mutex); in usb6fire_pcm_prepare()
471 dev_err(&rt->chip->dev->dev, in usb6fire_pcm_prepare()
473 alsa_rt->rate); in usb6fire_pcm_prepare()
474 return -EINVAL; in usb6fire_pcm_prepare()
479 mutex_unlock(&rt->stream_mutex); in usb6fire_pcm_prepare()
484 mutex_unlock(&rt->stream_mutex); in usb6fire_pcm_prepare()
485 dev_err(&rt->chip->dev->dev, in usb6fire_pcm_prepare()
490 mutex_unlock(&rt->stream_mutex); in usb6fire_pcm_prepare()
496 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); in usb6fire_pcm_trigger() local
500 if (rt->panic) in usb6fire_pcm_trigger()
501 return -EPIPE; in usb6fire_pcm_trigger()
502 if (!sub) in usb6fire_pcm_trigger()
503 return -ENODEV; in usb6fire_pcm_trigger()
508 spin_lock_irqsave(&sub->lock, flags); in usb6fire_pcm_trigger()
509 sub->active = true; in usb6fire_pcm_trigger()
510 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_trigger()
515 spin_lock_irqsave(&sub->lock, flags); in usb6fire_pcm_trigger()
516 sub->active = false; in usb6fire_pcm_trigger()
517 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_trigger()
521 return -EINVAL; in usb6fire_pcm_trigger()
528 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); in usb6fire_pcm_pointer() local
533 if (rt->panic || !sub) in usb6fire_pcm_pointer()
536 spin_lock_irqsave(&sub->lock, flags); in usb6fire_pcm_pointer()
537 ret = sub->dma_off; in usb6fire_pcm_pointer()
538 spin_unlock_irqrestore(&sub->lock, flags); in usb6fire_pcm_pointer()
554 urb->chip = chip; in usb6fire_pcm_init_urb()
555 usb_init_urb(&urb->instance); in usb6fire_pcm_init_urb()
556 urb->instance.transfer_buffer = urb->buffer; in usb6fire_pcm_init_urb()
557 urb->instance.transfer_buffer_length = in usb6fire_pcm_init_urb()
559 urb->instance.dev = chip->dev; in usb6fire_pcm_init_urb()
560 urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep) in usb6fire_pcm_init_urb()
561 : usb_sndisocpipe(chip->dev, ep); in usb6fire_pcm_init_urb()
562 urb->instance.interval = 1; in usb6fire_pcm_init_urb()
563 urb->instance.complete = handler; in usb6fire_pcm_init_urb()
564 urb->instance.context = urb; in usb6fire_pcm_init_urb()
565 urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; in usb6fire_pcm_init_urb()
573 rt->out_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, in usb6fire_pcm_buffers_init()
576 if (!rt->out_urbs[i].buffer) in usb6fire_pcm_buffers_init()
577 return -ENOMEM; in usb6fire_pcm_buffers_init()
578 rt->in_urbs[i].buffer = kcalloc(PCM_MAX_PACKET_SIZE, in usb6fire_pcm_buffers_init()
581 if (!rt->in_urbs[i].buffer) in usb6fire_pcm_buffers_init()
582 return -ENOMEM; in usb6fire_pcm_buffers_init()
592 kfree(rt->out_urbs[i].buffer); in usb6fire_pcm_buffers_destroy()
593 kfree(rt->in_urbs[i].buffer); in usb6fire_pcm_buffers_destroy()
606 return -ENOMEM; in usb6fire_pcm_init()
615 rt->chip = chip; in usb6fire_pcm_init()
616 rt->stream_state = STREAM_DISABLED; in usb6fire_pcm_init()
617 rt->rate = ARRAY_SIZE(rates); in usb6fire_pcm_init()
618 init_waitqueue_head(&rt->stream_wait_queue); in usb6fire_pcm_init()
619 mutex_init(&rt->stream_mutex); in usb6fire_pcm_init()
621 spin_lock_init(&rt->playback.lock); in usb6fire_pcm_init()
622 spin_lock_init(&rt->capture.lock); in usb6fire_pcm_init()
625 usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP, in usb6fire_pcm_init()
627 usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP, in usb6fire_pcm_init()
630 rt->in_urbs[i].peer = &rt->out_urbs[i]; in usb6fire_pcm_init()
631 rt->out_urbs[i].peer = &rt->in_urbs[i]; in usb6fire_pcm_init()
634 ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm); in usb6fire_pcm_init()
638 dev_err(&chip->dev->dev, "cannot create pcm instance.\n"); in usb6fire_pcm_init()
642 pcm->private_data = rt; in usb6fire_pcm_init()
643 strcpy(pcm->name, "DMX 6Fire USB"); in usb6fire_pcm_init()
648 rt->instance = pcm; in usb6fire_pcm_init()
650 chip->pcm = rt; in usb6fire_pcm_init()
656 struct pcm_runtime *rt = chip->pcm; in usb6fire_pcm_abort()
660 rt->panic = true; in usb6fire_pcm_abort()
662 if (rt->playback.instance) in usb6fire_pcm_abort()
663 snd_pcm_stop_xrun(rt->playback.instance); in usb6fire_pcm_abort()
665 if (rt->capture.instance) in usb6fire_pcm_abort()
666 snd_pcm_stop_xrun(rt->capture.instance); in usb6fire_pcm_abort()
669 usb_poison_urb(&rt->in_urbs[i].instance); in usb6fire_pcm_abort()
670 usb_poison_urb(&rt->out_urbs[i].instance); in usb6fire_pcm_abort()
678 struct pcm_runtime *rt = chip->pcm; in usb6fire_pcm_destroy()
682 chip->pcm = NULL; in usb6fire_pcm_destroy()