Lines Matching +full:sub +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright 2012-2013 (C) M2TECH S.r.l and Amarula Solutions B.V.
53 bool panic; /* if set driver won't do anymore pcm on device */
114 struct usb_device *device = rt->chip->dev; in hiface_pcm_set_rate() local
147 dev_err(&device->dev, "Unsupported rate %d\n", rate); in hiface_pcm_set_rate()
148 return -EINVAL; in hiface_pcm_set_rate()
159 ret = usb_control_msg_send(device, 0, in hiface_pcm_set_rate()
164 dev_err(&device->dev, "Error setting samplerate %d.\n", rate); in hiface_pcm_set_rate()
173 struct device *device = &rt->chip->dev->dev; in hiface_pcm_get_substream() local
175 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) in hiface_pcm_get_substream()
176 return &rt->playback; in hiface_pcm_get_substream()
178 dev_err(device, "Error getting pcm substream slot.\n"); in hiface_pcm_get_substream()
187 if (rt->stream_state != STREAM_DISABLED) { in hiface_pcm_stream_stop()
188 rt->stream_state = STREAM_STOPPING; in hiface_pcm_stream_stop()
192 &rt->out_urbs[i].submitted, 100); in hiface_pcm_stream_stop()
195 &rt->out_urbs[i].submitted); in hiface_pcm_stream_stop()
196 usb_kill_urb(&rt->out_urbs[i].instance); in hiface_pcm_stream_stop()
199 rt->stream_state = STREAM_DISABLED; in hiface_pcm_stream_stop()
209 if (rt->stream_state == STREAM_DISABLED) { in hiface_pcm_stream_start()
212 rt->panic = false; in hiface_pcm_stream_start()
215 rt->stream_state = STREAM_STARTING; in hiface_pcm_stream_start()
217 memset(rt->out_urbs[i].buffer, 0, PCM_PACKET_SIZE); in hiface_pcm_stream_start()
218 usb_anchor_urb(&rt->out_urbs[i].instance, in hiface_pcm_stream_start()
219 &rt->out_urbs[i].submitted); in hiface_pcm_stream_start()
220 ret = usb_submit_urb(&rt->out_urbs[i].instance, in hiface_pcm_stream_start()
229 wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond, in hiface_pcm_stream_start()
231 if (rt->stream_wait_cond) { in hiface_pcm_stream_start()
232 struct device *device = &rt->chip->dev->dev; in hiface_pcm_stream_start() local
233 dev_dbg(device, "%s: Stream is running wakeup event\n", in hiface_pcm_stream_start()
235 rt->stream_state = STREAM_RUNNING; in hiface_pcm_stream_start()
238 return -EIO; in hiface_pcm_stream_start()
244 /* The hardware wants word-swapped 32-bit values */
255 static bool hiface_pcm_playback(struct pcm_substream *sub, struct pcm_urb *urb) in hiface_pcm_playback() argument
257 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; in hiface_pcm_playback()
258 struct device *device = &urb->chip->dev->dev; in hiface_pcm_playback() local
262 WARN_ON(alsa_rt->format != SNDRV_PCM_FORMAT_S32_LE); in hiface_pcm_playback()
264 pcm_buffer_size = snd_pcm_lib_buffer_bytes(sub->instance); in hiface_pcm_playback()
266 if (sub->dma_off + PCM_PACKET_SIZE <= pcm_buffer_size) { in hiface_pcm_playback()
267 dev_dbg(device, "%s: (1) buffer_size %#x dma_offset %#x\n", __func__, in hiface_pcm_playback()
269 (unsigned int) sub->dma_off); in hiface_pcm_playback()
271 source = alsa_rt->dma_area + sub->dma_off; in hiface_pcm_playback()
272 memcpy_swahw32(urb->buffer, source, PCM_PACKET_SIZE); in hiface_pcm_playback()
277 dev_dbg(device, "%s: (2) buffer_size %#x dma_offset %#x\n", __func__, in hiface_pcm_playback()
279 (unsigned int) sub->dma_off); in hiface_pcm_playback()
281 len = pcm_buffer_size - sub->dma_off; in hiface_pcm_playback()
283 source = alsa_rt->dma_area + sub->dma_off; in hiface_pcm_playback()
284 memcpy_swahw32(urb->buffer, source, len); in hiface_pcm_playback()
286 source = alsa_rt->dma_area; in hiface_pcm_playback()
287 memcpy_swahw32(urb->buffer + len, source, in hiface_pcm_playback()
288 PCM_PACKET_SIZE - len); in hiface_pcm_playback()
290 sub->dma_off += PCM_PACKET_SIZE; in hiface_pcm_playback()
291 if (sub->dma_off >= pcm_buffer_size) in hiface_pcm_playback()
292 sub->dma_off -= pcm_buffer_size; in hiface_pcm_playback()
294 sub->period_off += PCM_PACKET_SIZE; in hiface_pcm_playback()
295 if (sub->period_off >= alsa_rt->period_size) { in hiface_pcm_playback()
296 sub->period_off %= alsa_rt->period_size; in hiface_pcm_playback()
304 struct pcm_urb *out_urb = usb_urb->context; in hiface_pcm_out_urb_handler()
305 struct pcm_runtime *rt = out_urb->chip->pcm; in hiface_pcm_out_urb_handler()
306 struct pcm_substream *sub; in hiface_pcm_out_urb_handler() local
311 if (rt->panic || rt->stream_state == STREAM_STOPPING) in hiface_pcm_out_urb_handler()
314 if (unlikely(usb_urb->status == -ENOENT || /* unlinked */ in hiface_pcm_out_urb_handler()
315 usb_urb->status == -ENODEV || /* device removed */ in hiface_pcm_out_urb_handler()
316 usb_urb->status == -ECONNRESET || /* unlinked */ in hiface_pcm_out_urb_handler()
317 usb_urb->status == -ESHUTDOWN)) { /* device disabled */ in hiface_pcm_out_urb_handler()
321 if (rt->stream_state == STREAM_STARTING) { in hiface_pcm_out_urb_handler()
322 rt->stream_wait_cond = true; in hiface_pcm_out_urb_handler()
323 wake_up(&rt->stream_wait_queue); in hiface_pcm_out_urb_handler()
327 sub = &rt->playback; in hiface_pcm_out_urb_handler()
328 spin_lock_irqsave(&sub->lock, flags); in hiface_pcm_out_urb_handler()
329 if (sub->active) in hiface_pcm_out_urb_handler()
330 do_period_elapsed = hiface_pcm_playback(sub, out_urb); in hiface_pcm_out_urb_handler()
332 memset(out_urb->buffer, 0, PCM_PACKET_SIZE); in hiface_pcm_out_urb_handler()
334 spin_unlock_irqrestore(&sub->lock, flags); in hiface_pcm_out_urb_handler()
337 snd_pcm_period_elapsed(sub->instance); in hiface_pcm_out_urb_handler()
339 ret = usb_submit_urb(&out_urb->instance, GFP_ATOMIC); in hiface_pcm_out_urb_handler()
346 rt->panic = true; in hiface_pcm_out_urb_handler()
352 struct pcm_substream *sub = NULL; in hiface_pcm_open() local
353 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; in hiface_pcm_open()
356 if (rt->panic) in hiface_pcm_open()
357 return -EPIPE; in hiface_pcm_open()
359 mutex_lock(&rt->stream_mutex); in hiface_pcm_open()
360 alsa_rt->hw = pcm_hw; in hiface_pcm_open()
362 if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) in hiface_pcm_open()
363 sub = &rt->playback; in hiface_pcm_open()
365 if (!sub) { in hiface_pcm_open()
366 struct device *device = &rt->chip->dev->dev; in hiface_pcm_open() local
367 mutex_unlock(&rt->stream_mutex); in hiface_pcm_open()
368 dev_err(device, "Invalid stream type\n"); in hiface_pcm_open()
369 return -EINVAL; in hiface_pcm_open()
372 if (rt->extra_freq) { in hiface_pcm_open()
373 alsa_rt->hw.rates |= SNDRV_PCM_RATE_KNOT; in hiface_pcm_open()
374 alsa_rt->hw.rate_max = 384000; in hiface_pcm_open()
377 ret = snd_pcm_hw_constraint_list(alsa_sub->runtime, 0, in hiface_pcm_open()
381 mutex_unlock(&rt->stream_mutex); in hiface_pcm_open()
386 sub->instance = alsa_sub; in hiface_pcm_open()
387 sub->active = false; in hiface_pcm_open()
388 mutex_unlock(&rt->stream_mutex); in hiface_pcm_open()
395 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub); in hiface_pcm_close() local
398 if (rt->panic) in hiface_pcm_close()
401 mutex_lock(&rt->stream_mutex); in hiface_pcm_close()
402 if (sub) { in hiface_pcm_close()
406 spin_lock_irqsave(&sub->lock, flags); in hiface_pcm_close()
407 sub->instance = NULL; in hiface_pcm_close()
408 sub->active = false; in hiface_pcm_close()
409 spin_unlock_irqrestore(&sub->lock, flags); in hiface_pcm_close()
412 mutex_unlock(&rt->stream_mutex); in hiface_pcm_close()
419 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub); in hiface_pcm_prepare() local
420 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; in hiface_pcm_prepare()
423 if (rt->panic) in hiface_pcm_prepare()
424 return -EPIPE; in hiface_pcm_prepare()
425 if (!sub) in hiface_pcm_prepare()
426 return -ENODEV; in hiface_pcm_prepare()
428 mutex_lock(&rt->stream_mutex); in hiface_pcm_prepare()
432 sub->dma_off = 0; in hiface_pcm_prepare()
433 sub->period_off = 0; in hiface_pcm_prepare()
435 if (rt->stream_state == STREAM_DISABLED) { in hiface_pcm_prepare()
437 ret = hiface_pcm_set_rate(rt, alsa_rt->rate); in hiface_pcm_prepare()
439 mutex_unlock(&rt->stream_mutex); in hiface_pcm_prepare()
444 mutex_unlock(&rt->stream_mutex); in hiface_pcm_prepare()
448 mutex_unlock(&rt->stream_mutex); in hiface_pcm_prepare()
454 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub); in hiface_pcm_trigger() local
457 if (rt->panic) in hiface_pcm_trigger()
458 return -EPIPE; in hiface_pcm_trigger()
459 if (!sub) in hiface_pcm_trigger()
460 return -ENODEV; in hiface_pcm_trigger()
465 spin_lock_irq(&sub->lock); in hiface_pcm_trigger()
466 sub->active = true; in hiface_pcm_trigger()
467 spin_unlock_irq(&sub->lock); in hiface_pcm_trigger()
472 spin_lock_irq(&sub->lock); in hiface_pcm_trigger()
473 sub->active = false; in hiface_pcm_trigger()
474 spin_unlock_irq(&sub->lock); in hiface_pcm_trigger()
478 return -EINVAL; in hiface_pcm_trigger()
484 struct pcm_substream *sub = hiface_pcm_get_substream(alsa_sub); in hiface_pcm_pointer() local
489 if (rt->panic || !sub) in hiface_pcm_pointer()
492 spin_lock_irqsave(&sub->lock, flags); in hiface_pcm_pointer()
493 dma_offset = sub->dma_off; in hiface_pcm_pointer()
494 spin_unlock_irqrestore(&sub->lock, flags); in hiface_pcm_pointer()
495 return bytes_to_frames(alsa_sub->runtime, dma_offset); in hiface_pcm_pointer()
511 urb->chip = chip; in hiface_pcm_init_urb()
512 usb_init_urb(&urb->instance); in hiface_pcm_init_urb()
514 urb->buffer = kzalloc(PCM_PACKET_SIZE, GFP_KERNEL); in hiface_pcm_init_urb()
515 if (!urb->buffer) in hiface_pcm_init_urb()
516 return -ENOMEM; in hiface_pcm_init_urb()
518 usb_fill_bulk_urb(&urb->instance, chip->dev, in hiface_pcm_init_urb()
519 usb_sndbulkpipe(chip->dev, ep), (void *)urb->buffer, in hiface_pcm_init_urb()
521 if (usb_urb_ep_type_check(&urb->instance)) in hiface_pcm_init_urb()
522 return -EINVAL; in hiface_pcm_init_urb()
523 init_usb_anchor(&urb->submitted); in hiface_pcm_init_urb()
530 struct pcm_runtime *rt = chip->pcm; in hiface_pcm_abort()
533 rt->panic = true; in hiface_pcm_abort()
535 mutex_lock(&rt->stream_mutex); in hiface_pcm_abort()
537 mutex_unlock(&rt->stream_mutex); in hiface_pcm_abort()
543 struct pcm_runtime *rt = chip->pcm; in hiface_pcm_destroy()
547 kfree(rt->out_urbs[i].buffer); in hiface_pcm_destroy()
549 kfree(chip->pcm); in hiface_pcm_destroy()
550 chip->pcm = NULL; in hiface_pcm_destroy()
555 struct pcm_runtime *rt = pcm->private_data; in hiface_pcm_free()
558 hiface_pcm_destroy(rt->chip); in hiface_pcm_free()
570 return -ENOMEM; in hiface_pcm_init()
572 rt->chip = chip; in hiface_pcm_init()
573 rt->stream_state = STREAM_DISABLED; in hiface_pcm_init()
575 rt->extra_freq = 1; in hiface_pcm_init()
577 init_waitqueue_head(&rt->stream_wait_queue); in hiface_pcm_init()
578 mutex_init(&rt->stream_mutex); in hiface_pcm_init()
579 spin_lock_init(&rt->playback.lock); in hiface_pcm_init()
582 ret = hiface_pcm_init_urb(&rt->out_urbs[i], chip, OUT_EP, in hiface_pcm_init()
588 ret = snd_pcm_new(chip->card, "USB-SPDIF Audio", 0, 1, 0, &pcm); in hiface_pcm_init()
590 dev_err(&chip->dev->dev, "Cannot create pcm instance\n"); in hiface_pcm_init()
594 pcm->private_data = rt; in hiface_pcm_init()
595 pcm->private_free = hiface_pcm_free; in hiface_pcm_init()
597 strscpy(pcm->name, "USB-SPDIF Audio", sizeof(pcm->name)); in hiface_pcm_init()
602 rt->instance = pcm; in hiface_pcm_init()
604 chip->pcm = rt; in hiface_pcm_init()
609 kfree(rt->out_urbs[i].buffer); in hiface_pcm_init()