Lines Matching refs:tscm

16 static int get_clock(struct snd_tscm *tscm, u32 *data)
23 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST,
44 static int set_clock(struct snd_tscm *tscm, unsigned int rate,
51 err = get_clock(tscm, &data);
81 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
92 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
97 int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate)
102 err = get_clock(tscm, &data);
125 int snd_tscm_stream_get_clock(struct snd_tscm *tscm, enum snd_tscm_clock *clock)
130 err = get_clock(tscm, &data);
141 static int enable_data_channels(struct snd_tscm *tscm)
149 for (i = 0; i < tscm->spec->pcm_capture_analog_channels; ++i)
151 if (tscm->spec->has_adat)
153 if (tscm->spec->has_spdif)
157 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
164 for (i = 0; i < tscm->spec->pcm_playback_analog_channels; ++i)
166 if (tscm->spec->has_adat)
168 if (tscm->spec->has_spdif)
172 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
177 static int set_stream_formats(struct snd_tscm *tscm, unsigned int rate)
184 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
190 return enable_data_channels(tscm);
193 static void finish_session(struct snd_tscm *tscm)
198 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
203 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
209 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
213 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
217 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
222 static int begin_session(struct snd_tscm *tscm)
228 reg = cpu_to_be32(tscm->tx_resources.channel);
229 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
237 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
244 reg = cpu_to_be32(tscm->rx_resources.channel);
245 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
252 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
259 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
267 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
275 return snd_fw_transaction(tscm->unit,
281 static int keep_resources(struct snd_tscm *tscm, unsigned int rate,
287 if (stream == &tscm->tx_stream)
288 resources = &tscm->tx_resources;
290 resources = &tscm->rx_resources;
298 fw_parent_device(tscm->unit)->max_speed);
301 static int init_stream(struct snd_tscm *tscm, struct amdtp_stream *s)
308 if (s == &tscm->tx_stream) {
309 resources = &tscm->tx_resources;
311 pcm_channels = tscm->spec->pcm_capture_analog_channels;
313 resources = &tscm->rx_resources;
315 pcm_channels = tscm->spec->pcm_playback_analog_channels;
318 if (tscm->spec->has_adat)
320 if (tscm->spec->has_spdif)
323 err = fw_iso_resources_init(resources, tscm->unit);
327 err = amdtp_tscm_init(s, tscm->unit, dir, pcm_channels);
334 static void destroy_stream(struct snd_tscm *tscm, struct amdtp_stream *s)
338 if (s == &tscm->tx_stream)
339 fw_iso_resources_destroy(&tscm->tx_resources);
341 fw_iso_resources_destroy(&tscm->rx_resources);
344 int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
348 err = init_stream(tscm, &tscm->tx_stream);
352 err = init_stream(tscm, &tscm->rx_stream);
354 destroy_stream(tscm, &tscm->tx_stream);
358 err = amdtp_domain_init(&tscm->domain);
360 destroy_stream(tscm, &tscm->tx_stream);
361 destroy_stream(tscm, &tscm->rx_stream);
368 void snd_tscm_stream_update_duplex(struct snd_tscm *tscm)
370 amdtp_domain_stop(&tscm->domain);
372 amdtp_stream_pcm_abort(&tscm->tx_stream);
373 amdtp_stream_pcm_abort(&tscm->rx_stream);
378 void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm)
380 amdtp_domain_destroy(&tscm->domain);
382 destroy_stream(tscm, &tscm->rx_stream);
383 destroy_stream(tscm, &tscm->tx_stream);
386 int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate,
393 err = snd_tscm_stream_get_rate(tscm, &curr_rate);
397 if (tscm->substreams_counter == 0 || rate != curr_rate) {
398 amdtp_domain_stop(&tscm->domain);
400 finish_session(tscm);
402 fw_iso_resources_free(&tscm->tx_resources);
403 fw_iso_resources_free(&tscm->rx_resources);
405 err = set_clock(tscm, rate, INT_MAX);
409 err = keep_resources(tscm, rate, &tscm->tx_stream);
413 err = keep_resources(tscm, rate, &tscm->rx_stream);
415 fw_iso_resources_free(&tscm->tx_resources);
419 err = amdtp_domain_set_events_per_period(&tscm->domain,
422 fw_iso_resources_free(&tscm->tx_resources);
423 fw_iso_resources_free(&tscm->rx_resources);
431 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
433 unsigned int generation = tscm->rx_resources.generation;
436 if (tscm->substreams_counter == 0)
439 if (amdtp_streaming_error(&tscm->rx_stream) ||
440 amdtp_streaming_error(&tscm->tx_stream)) {
441 amdtp_domain_stop(&tscm->domain);
442 finish_session(tscm);
445 if (generation != fw_parent_device(tscm->unit)->card->generation) {
446 err = fw_iso_resources_update(&tscm->tx_resources);
450 err = fw_iso_resources_update(&tscm->rx_resources);
455 if (!amdtp_stream_running(&tscm->rx_stream)) {
456 int spd = fw_parent_device(tscm->unit)->max_speed;
458 err = set_stream_formats(tscm, rate);
462 err = begin_session(tscm);
466 err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream,
467 tscm->rx_resources.channel, spd);
471 err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream,
472 tscm->tx_resources.channel, spd);
476 err = amdtp_domain_start(&tscm->domain, 0);
480 if (!amdtp_stream_wait_callback(&tscm->rx_stream,
482 !amdtp_stream_wait_callback(&tscm->tx_stream,
491 amdtp_domain_stop(&tscm->domain);
492 finish_session(tscm);
497 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
499 if (tscm->substreams_counter == 0) {
500 amdtp_domain_stop(&tscm->domain);
501 finish_session(tscm);
503 fw_iso_resources_free(&tscm->tx_resources);
504 fw_iso_resources_free(&tscm->rx_resources);
508 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm)
510 tscm->dev_lock_changed = true;
511 wake_up(&tscm->hwdep_wait);
514 int snd_tscm_stream_lock_try(struct snd_tscm *tscm)
518 spin_lock_irq(&tscm->lock);
521 if (tscm->dev_lock_count < 0) {
527 if (tscm->dev_lock_count++ == 0)
528 snd_tscm_stream_lock_changed(tscm);
531 spin_unlock_irq(&tscm->lock);
535 void snd_tscm_stream_lock_release(struct snd_tscm *tscm)
537 spin_lock_irq(&tscm->lock);
539 if (WARN_ON(tscm->dev_lock_count <= 0))
541 if (--tscm->dev_lock_count == 0)
542 snd_tscm_stream_lock_changed(tscm);
544 spin_unlock_irq(&tscm->lock);