Lines Matching +full:spdif +full:- +full:connection
1 // SPDX-License-Identifier: GPL-2.0-only
3 * bebob_stream.c - a part of driver for BeBoB based devices
5 * Copyright (c) 2013-2014 Takashi Sakamoto
15 * For BeBoB streams, Both of input and output CMP connection are important.
17 * For most devices, each CMP connection starts to transmit/receive a
18 * corresponding stream. But for a few devices, both of CMP connection needs
19 * to start transmitting stream. An example is 'M-Audio Firewire 410'.
60 return -EINVAL; in get_formation_index()
71 err = avc_general_get_sig_fmt(bebob->unit, &tx_rate, in snd_bebob_stream_get_rate()
73 } while (err == -EAGAIN && ++trials < 3); in snd_bebob_stream_get_rate()
79 err = avc_general_get_sig_fmt(bebob->unit, &rx_rate, in snd_bebob_stream_get_rate()
81 } while (err == -EAGAIN && ++trials < 3); in snd_bebob_stream_get_rate()
90 err = avc_general_set_sig_fmt(bebob->unit, rx_rate, in snd_bebob_stream_get_rate()
101 err = avc_general_set_sig_fmt(bebob->unit, rate, in snd_bebob_stream_set_rate()
106 err = avc_general_set_sig_fmt(bebob->unit, rate, in snd_bebob_stream_set_rate()
123 const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; in snd_bebob_stream_get_clock_src()
131 err = clk_spec->get(bebob, &id); in snd_bebob_stream_get_clock_src()
133 dev_err(&bebob->unit->device, in snd_bebob_stream_get_clock_src()
138 if (id >= clk_spec->num) { in snd_bebob_stream_get_clock_src()
139 dev_err(&bebob->unit->device, in snd_bebob_stream_get_clock_src()
141 id, clk_spec->num - 1); in snd_bebob_stream_get_clock_src()
142 err = -EIO; in snd_bebob_stream_get_clock_src()
146 *src = clk_spec->types[id]; in snd_bebob_stream_get_clock_src()
154 if (bebob->sync_input_plug < 0) { in snd_bebob_stream_get_clock_src()
164 bebob->sync_input_plug); in snd_bebob_stream_get_clock_src()
165 err = avc_bridgeco_get_plug_input(bebob->unit, addr, input); in snd_bebob_stream_get_clock_src()
167 dev_err(&bebob->unit->device, in snd_bebob_stream_get_clock_src()
169 bebob->sync_input_plug, err); in snd_bebob_stream_get_clock_src()
209 * This source comes from iPCR[1-29]. This in snd_bebob_stream_get_clock_src()
222 err = avc_bridgeco_get_plug_type(bebob->unit, addr, in snd_bebob_stream_get_clock_src()
229 * SPDIF/ADAT or sometimes (not always) word in snd_bebob_stream_get_clock_src()
250 err = -EIO; in snd_bebob_stream_get_clock_src()
270 return -ENOMEM; in map_data_channels()
272 if (s == &bebob->tx_stream) in map_data_channels()
278 err = avc_bridgeco_get_plug_ch_pos(bebob->unit, addr, buf, 256); in map_data_channels()
280 dev_err(&bebob->unit->device, in map_data_channels()
299 err = avc_bridgeco_get_plug_section_type(bebob->unit, addr, in map_data_channels()
302 dev_err(&bebob->unit->device, in map_data_channels()
311 err = -ENOSYS; in map_data_channels()
320 stm_pos = buf[pos++] - 1; in map_data_channels()
322 sec_loc = buf[pos++] - 1; in map_data_channels()
327 * of M-Audio don't follow this. Its location for MIDI in map_data_channels()
338 err = -ENOSYS; in map_data_channels()
348 case 0x04: /* SPDIF */ in map_data_channels()
358 err = -ENOSYS; in map_data_channels()
384 if (s == &bebob->tx_stream) in check_connection_used_by_others()
385 conn = &bebob->out_conn; in check_connection_used_by_others()
387 conn = &bebob->in_conn; in check_connection_used_by_others()
391 dev_err(&bebob->unit->device, in check_connection_used_by_others()
392 "Connection established by others: %cPCR[%d]\n", in check_connection_used_by_others()
393 (conn->direction == CMP_OUTPUT) ? 'o' : 'i', in check_connection_used_by_others()
394 conn->pcr_index); in check_connection_used_by_others()
395 err = -EBUSY; in check_connection_used_by_others()
403 cmp_connection_break(&bebob->in_conn); in break_both_connections()
404 cmp_connection_break(&bebob->out_conn); in break_both_connections()
409 if (bebob->version < 2) in break_both_connections()
418 if (stream == &bebob->rx_stream) in start_stream()
419 conn = &bebob->in_conn; in start_stream()
421 conn = &bebob->out_conn; in start_stream()
424 if (bebob->maudio_special_quirk == NULL) { in start_stream()
434 return amdtp_domain_add_stream(&bebob->domain, stream, in start_stream()
435 conn->resources.channel, conn->speed); in start_stream()
445 if (stream == &bebob->tx_stream) { in init_stream()
447 conn = &bebob->out_conn; in init_stream()
451 conn = &bebob->in_conn; in init_stream()
455 err = cmp_connection_init(conn, bebob->unit, dir_conn, 0); in init_stream()
459 err = amdtp_am824_init(stream, bebob->unit, dir_stream, CIP_BLOCKING); in init_stream()
465 if (stream == &bebob->tx_stream) { in init_stream()
467 // - In the beginning of streaming, the value of dbc is in init_stream()
469 // - The value of dbc is reset suddenly. in init_stream()
470 if (bebob->version > 2) in init_stream()
471 bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC | in init_stream()
474 // At high sampling rate, M-Audio special firmware transmits in init_stream()
476 // others are valid to IEC 61883-1. in init_stream()
477 if (bebob->maudio_special_quirk) in init_stream()
478 bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC; in init_stream()
488 if (stream == &bebob->tx_stream) in destroy_stream()
489 cmp_connection_destroy(&bebob->out_conn); in destroy_stream()
491 cmp_connection_destroy(&bebob->in_conn); in destroy_stream()
498 err = init_stream(bebob, &bebob->tx_stream); in snd_bebob_stream_init_duplex()
502 err = init_stream(bebob, &bebob->rx_stream); in snd_bebob_stream_init_duplex()
504 destroy_stream(bebob, &bebob->tx_stream); in snd_bebob_stream_init_duplex()
508 err = amdtp_domain_init(&bebob->domain); in snd_bebob_stream_init_duplex()
510 destroy_stream(bebob, &bebob->tx_stream); in snd_bebob_stream_init_duplex()
511 destroy_stream(bebob, &bebob->rx_stream); in snd_bebob_stream_init_duplex()
525 if (stream == &bebob->tx_stream) { in keep_resources()
526 pcm_channels = bebob->tx_stream_formations[index].pcm; in keep_resources()
527 midi_ports = bebob->midi_input_ports; in keep_resources()
528 conn = &bebob->out_conn; in keep_resources()
530 pcm_channels = bebob->rx_stream_formations[index].pcm; in keep_resources()
531 midi_ports = bebob->midi_output_ports; in keep_resources()
532 conn = &bebob->in_conn; in keep_resources()
551 err = check_connection_used_by_others(bebob, &bebob->rx_stream); in snd_bebob_stream_reserve_duplex()
555 err = bebob->spec->rate->get(bebob, &curr_rate); in snd_bebob_stream_reserve_duplex()
561 amdtp_domain_stop(&bebob->domain); in snd_bebob_stream_reserve_duplex()
564 cmp_connection_release(&bebob->out_conn); in snd_bebob_stream_reserve_duplex()
565 cmp_connection_release(&bebob->in_conn); in snd_bebob_stream_reserve_duplex()
568 if (bebob->substreams_counter == 0 || curr_rate != rate) { in snd_bebob_stream_reserve_duplex()
575 // For firmware customized by M-Audio, refer to next NOTE. in snd_bebob_stream_reserve_duplex()
576 err = bebob->spec->rate->set(bebob, rate); in snd_bebob_stream_reserve_duplex()
578 dev_err(&bebob->unit->device, in snd_bebob_stream_reserve_duplex()
588 err = keep_resources(bebob, &bebob->tx_stream, rate, index); in snd_bebob_stream_reserve_duplex()
592 err = keep_resources(bebob, &bebob->rx_stream, rate, index); in snd_bebob_stream_reserve_duplex()
594 cmp_connection_release(&bebob->out_conn); in snd_bebob_stream_reserve_duplex()
598 err = amdtp_domain_set_events_per_period(&bebob->domain, in snd_bebob_stream_reserve_duplex()
601 cmp_connection_release(&bebob->out_conn); in snd_bebob_stream_reserve_duplex()
602 cmp_connection_release(&bebob->in_conn); in snd_bebob_stream_reserve_duplex()
615 if (bebob->substreams_counter == 0) in snd_bebob_stream_start_duplex()
616 return -EIO; in snd_bebob_stream_start_duplex()
619 if (amdtp_streaming_error(&bebob->rx_stream) || in snd_bebob_stream_start_duplex()
620 amdtp_streaming_error(&bebob->tx_stream)) { in snd_bebob_stream_start_duplex()
621 amdtp_domain_stop(&bebob->domain); in snd_bebob_stream_start_duplex()
625 if (!amdtp_stream_running(&bebob->rx_stream)) { in snd_bebob_stream_start_duplex()
631 if (bebob->maudio_special_quirk) { in snd_bebob_stream_start_duplex()
632 err = bebob->spec->rate->get(bebob, &curr_rate); in snd_bebob_stream_start_duplex()
642 master = &bebob->tx_stream; in snd_bebob_stream_start_duplex()
643 slave = &bebob->rx_stream; in snd_bebob_stream_start_duplex()
645 master = &bebob->rx_stream; in snd_bebob_stream_start_duplex()
646 slave = &bebob->tx_stream; in snd_bebob_stream_start_duplex()
666 if (bebob->version < 2) in snd_bebob_stream_start_duplex()
670 err = amdtp_domain_start(&bebob->domain, ir_delay_cycle); in snd_bebob_stream_start_duplex()
675 // The firmware customized by M-Audio uses these commands to in snd_bebob_stream_start_duplex()
677 if (bebob->maudio_special_quirk) { in snd_bebob_stream_start_duplex()
678 err = bebob->spec->rate->set(bebob, curr_rate); in snd_bebob_stream_start_duplex()
680 dev_err(&bebob->unit->device, in snd_bebob_stream_start_duplex()
687 if (!amdtp_stream_wait_callback(&bebob->rx_stream, in snd_bebob_stream_start_duplex()
689 !amdtp_stream_wait_callback(&bebob->tx_stream, in snd_bebob_stream_start_duplex()
691 err = -ETIMEDOUT; in snd_bebob_stream_start_duplex()
698 amdtp_domain_stop(&bebob->domain); in snd_bebob_stream_start_duplex()
705 if (bebob->substreams_counter == 0) { in snd_bebob_stream_stop_duplex()
706 amdtp_domain_stop(&bebob->domain); in snd_bebob_stream_stop_duplex()
709 cmp_connection_release(&bebob->out_conn); in snd_bebob_stream_stop_duplex()
710 cmp_connection_release(&bebob->in_conn); in snd_bebob_stream_stop_duplex()
720 amdtp_domain_destroy(&bebob->domain); in snd_bebob_stream_destroy_duplex()
722 destroy_stream(bebob, &bebob->tx_stream); in snd_bebob_stream_destroy_duplex()
723 destroy_stream(bebob, &bebob->rx_stream); in snd_bebob_stream_destroy_duplex()
729 * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
743 return -ENOSYS; in parse_stream_formation()
751 return -ENOSYS; in parse_stream_formation()
771 /* IEC 61937-3 to 7 */ in parse_stream_formation()
778 case 0x07: /* DVD-Audio */ in parse_stream_formation()
790 return -ENOSYS; /* not supported */ in parse_stream_formation()
796 return -ENOSYS; in parse_stream_formation()
813 return -ENOMEM; in fill_stream_formations()
816 formations = bebob->rx_stream_formations; in fill_stream_formations()
818 formations = bebob->tx_stream_formations; in fill_stream_formations()
824 err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf, in fill_stream_formations()
827 if (err == -EINVAL && eid > 0) { in fill_stream_formations()
831 dev_err(&bebob->unit->device, in fill_stream_formations()
858 err = avc_general_get_plug_info(bebob->unit, 0x0c, 0x00, 0x00, plugs); in seek_msu_sync_input_plug()
860 dev_err(&bebob->unit->device, in seek_msu_sync_input_plug()
867 bebob->sync_input_plug = -1; in seek_msu_sync_input_plug()
870 err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); in seek_msu_sync_input_plug()
872 dev_err(&bebob->unit->device, in seek_msu_sync_input_plug()
879 bebob->sync_input_plug = i; in seek_msu_sync_input_plug()
889 const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; in snd_bebob_stream_discover()
896 err = avc_general_get_plug_info(bebob->unit, 0x1f, 0x07, 0x00, plugs); in snd_bebob_stream_discover()
898 dev_err(&bebob->unit->device, in snd_bebob_stream_discover()
909 err = -ENOSYS; in snd_bebob_stream_discover()
915 err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); in snd_bebob_stream_discover()
917 dev_err(&bebob->unit->device, in snd_bebob_stream_discover()
921 err = -ENOSYS; in snd_bebob_stream_discover()
930 err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); in snd_bebob_stream_discover()
932 dev_err(&bebob->unit->device, in snd_bebob_stream_discover()
936 err = -ENOSYS; in snd_bebob_stream_discover()
944 bebob->midi_input_ports = 0; in snd_bebob_stream_discover()
948 err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); in snd_bebob_stream_discover()
950 dev_err(&bebob->unit->device, in snd_bebob_stream_discover()
955 bebob->midi_input_ports++; in snd_bebob_stream_discover()
960 bebob->midi_output_ports = 0; in snd_bebob_stream_discover()
964 err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); in snd_bebob_stream_discover()
966 dev_err(&bebob->unit->device, in snd_bebob_stream_discover()
971 bebob->midi_output_ports++; in snd_bebob_stream_discover()
984 bebob->dev_lock_changed = true; in snd_bebob_stream_lock_changed()
985 wake_up(&bebob->hwdep_wait); in snd_bebob_stream_lock_changed()
992 spin_lock_irq(&bebob->lock); in snd_bebob_stream_lock_try()
995 if (bebob->dev_lock_count < 0) { in snd_bebob_stream_lock_try()
996 err = -EBUSY; in snd_bebob_stream_lock_try()
1001 if (bebob->dev_lock_count++ == 0) in snd_bebob_stream_lock_try()
1005 spin_unlock_irq(&bebob->lock); in snd_bebob_stream_lock_try()
1011 spin_lock_irq(&bebob->lock); in snd_bebob_stream_lock_release()
1013 if (WARN_ON(bebob->dev_lock_count <= 0)) in snd_bebob_stream_lock_release()
1015 if (--bebob->dev_lock_count == 0) in snd_bebob_stream_lock_release()
1018 spin_unlock_irq(&bebob->lock); in snd_bebob_stream_lock_release()