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);
427 tscm->need_long_tx_init_skip = (rate != curr_rate);
433 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
435 unsigned int generation = tscm->rx_resources.generation;
438 if (tscm->substreams_counter == 0)
441 if (amdtp_streaming_error(&tscm->rx_stream) ||
442 amdtp_streaming_error(&tscm->tx_stream)) {
443 amdtp_domain_stop(&tscm->domain);
444 finish_session(tscm);
447 if (generation != fw_parent_device(tscm->unit)->card->generation) {
448 err = fw_iso_resources_update(&tscm->tx_resources);
452 err = fw_iso_resources_update(&tscm->rx_resources);
457 if (!amdtp_stream_running(&tscm->rx_stream)) {
458 int spd = fw_parent_device(tscm->unit)->max_speed;
461 err = set_stream_formats(tscm, rate);
465 err = begin_session(tscm);
469 err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream,
470 tscm->rx_resources.channel, spd);
474 err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream,
475 tscm->tx_resources.channel, spd);
479 if (tscm->need_long_tx_init_skip)
491 err = amdtp_domain_start(&tscm->domain, tx_init_skip_cycles, true, true);
495 if (!amdtp_domain_wait_ready(&tscm->domain, READY_TIMEOUT_MS)) {
503 amdtp_domain_stop(&tscm->domain);
504 finish_session(tscm);
509 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
511 if (tscm->substreams_counter == 0) {
512 amdtp_domain_stop(&tscm->domain);
513 finish_session(tscm);
515 fw_iso_resources_free(&tscm->tx_resources);
516 fw_iso_resources_free(&tscm->rx_resources);
518 tscm->need_long_tx_init_skip = false;
522 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm)
524 tscm->dev_lock_changed = true;
525 wake_up(&tscm->hwdep_wait);
528 int snd_tscm_stream_lock_try(struct snd_tscm *tscm)
532 spin_lock_irq(&tscm->lock);
535 if (tscm->dev_lock_count < 0) {
541 if (tscm->dev_lock_count++ == 0)
542 snd_tscm_stream_lock_changed(tscm);
545 spin_unlock_irq(&tscm->lock);
549 void snd_tscm_stream_lock_release(struct snd_tscm *tscm)
551 spin_lock_irq(&tscm->lock);
553 if (WARN_ON(tscm->dev_lock_count <= 0))
555 if (--tscm->dev_lock_count == 0)
556 snd_tscm_stream_lock_changed(tscm);
558 spin_unlock_irq(&tscm->lock);