^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * bebob_stream.c - a part of driver for BeBoB based devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2013-2014 Takashi Sakamoto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "./bebob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define CALLBACK_TIMEOUT 2500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define FW_ISO_RESOURCE_DELAY 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * NOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * For BeBoB streams, Both of input and output CMP connection are important.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * For most devices, each CMP connection starts to transmit/receive a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * corresponding stream. But for a few devices, both of CMP connection needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * to start transmitting stream. An example is 'M-Audio Firewire 410'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* 128 is an arbitrary length but it seems to be enough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define FORMAT_MAXIMUM_LENGTH 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) [0] = 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) [1] = 44100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) [2] = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) [3] = 88200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) [4] = 96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) [5] = 176400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) [6] = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * See: Table 51: Extended Stream Format Info ‘Sampling Frequency’
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * in Additional AVC commands (Nov 2003, BridgeCo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static const unsigned int bridgeco_freq_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) [0] = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) [1] = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) [2] = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) [3] = 0x0a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) [4] = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) [5] = 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) [6] = 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) get_formation_index(unsigned int rate, unsigned int *index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) for (i = 0; i < ARRAY_SIZE(snd_bebob_rate_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (snd_bebob_rate_table[i] == rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) snd_bebob_stream_get_rate(struct snd_bebob *bebob, unsigned int *curr_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int tx_rate, rx_rate, trials;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) trials = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) err = avc_general_get_sig_fmt(bebob->unit, &tx_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) AVC_GENERAL_PLUG_DIR_OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) } while (err == -EAGAIN && ++trials < 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) trials = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) err = avc_general_get_sig_fmt(bebob->unit, &rx_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) AVC_GENERAL_PLUG_DIR_IN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) } while (err == -EAGAIN && ++trials < 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *curr_rate = rx_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (rx_rate == tx_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* synchronize receive stream rate to transmit stream rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) err = avc_general_set_sig_fmt(bebob->unit, rx_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) AVC_GENERAL_PLUG_DIR_IN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) snd_bebob_stream_set_rate(struct snd_bebob *bebob, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) err = avc_general_set_sig_fmt(bebob->unit, rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) AVC_GENERAL_PLUG_DIR_OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) err = avc_general_set_sig_fmt(bebob->unit, rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) AVC_GENERAL_PLUG_DIR_IN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * Some devices need a bit time for transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * 300msec is got by some experiments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) msleep(300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) enum snd_bebob_clock_type *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) enum avc_bridgeco_plug_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* 1.The device has its own operation to switch source of clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (clk_spec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) err = clk_spec->get(bebob, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "fail to get clock source: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (id >= clk_spec->num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "clock source %d out of range 0..%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) id, clk_spec->num - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *src = clk_spec->types[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * 2.The device don't support to switch source of clock then assumed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * to use internal clock always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (bebob->sync_input_plug < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * 3.The device supports to switch source of clock by an usual way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Let's check input for 'Music Sub Unit Sync Input' plug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) bebob->sync_input_plug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) err = avc_bridgeco_get_plug_input(bebob->unit, addr, input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) "fail to get an input for MSU in plug %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) bebob->sync_input_plug, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * If there are no input plugs, all of fields are 0xff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * Here check the first field. This field is used for direction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (input[0] == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* The source from any output plugs is for one purpose only. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (input[0] == AVC_BRIDGECO_PLUG_DIR_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * In BeBoB architecture, the source from music subunit may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * bypass from oPCR[0]. This means that this source gives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * synchronization to IEEE 1394 cycle start packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (input[1] == AVC_BRIDGECO_PLUG_MODE_SUBUNIT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) input[2] == 0x0c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* The source from any input units is for several purposes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) } else if (input[1] == AVC_BRIDGECO_PLUG_MODE_UNIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (input[2] == AVC_BRIDGECO_PLUG_UNIT_ISOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (input[3] == 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * This source comes from iPCR[0]. This means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * that presentation timestamp calculated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * SYT series of the received packets. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * short, this driver is the master of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * synchronization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *src = SND_BEBOB_CLOCK_TYPE_SYT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * This source comes from iPCR[1-29]. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * means that the synchronization stream is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * the Audio/MIDI compound stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) } else if (input[2] == AVC_BRIDGECO_PLUG_UNIT_EXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Check type of this plug. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) avc_bridgeco_fill_unit_addr(addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) AVC_BRIDGECO_PLUG_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) AVC_BRIDGECO_PLUG_UNIT_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) input[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) err = avc_bridgeco_get_plug_type(bebob->unit, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (type == AVC_BRIDGECO_PLUG_TYPE_DIG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * SPDIF/ADAT or sometimes (not always) word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) } else if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* Often word clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) } else if (type == AVC_BRIDGECO_PLUG_TYPE_ADDITION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * Not standard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Mostly, additional internal clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *src = SND_BEBOB_CLOCK_TYPE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Not supported. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static int map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) unsigned int sec, sections, ch, channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) unsigned int pcm, midi, location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) unsigned int stm_pos, sec_loc, pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u8 *buf, addr[AVC_BRIDGECO_ADDR_BYTES], type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) enum avc_bridgeco_plug_dir dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * The length of return value of this command cannot be expected. Here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * use the maximum length of FCP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) buf = kzalloc(256, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (s == &bebob->tx_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dir = AVC_BRIDGECO_PLUG_DIR_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) dir = AVC_BRIDGECO_PLUG_DIR_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) avc_bridgeco_fill_unit_addr(addr, dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) err = avc_bridgeco_get_plug_ch_pos(bebob->unit, addr, buf, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) "fail to get channel position for isoc %s plug 0: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : "out",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* positions in I/O buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pcm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) midi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* the number of sections in AMDTP packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) sections = buf[pos++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) for (sec = 0; sec < sections; sec++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* type of this section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) avc_bridgeco_fill_unit_addr(addr, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) err = avc_bridgeco_get_plug_section_type(bebob->unit, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sec, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) "fail to get section type for isoc %s plug 0: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) "out",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* NoType */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (type == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) err = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* the number of channels in this section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) channels = buf[pos++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) for (ch = 0; ch < channels; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* position of this channel in AMDTP packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) stm_pos = buf[pos++] - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* location of this channel in this section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) sec_loc = buf[pos++] - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Basically the number of location is within the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * number of channels in this section. But some models
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * of M-Audio don't follow this. Its location for MIDI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * is the position of MIDI channels in AMDTP packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (sec_loc >= channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) sec_loc = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* for MIDI conformant data channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) case 0x0a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* AMDTP_MAX_CHANNELS_FOR_MIDI is 1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if ((midi > 0) && (stm_pos != midi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) err = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) amdtp_am824_set_midi_position(s, stm_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) midi = stm_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* for PCM data channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case 0x01: /* Headphone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) case 0x02: /* Microphone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case 0x03: /* Line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case 0x04: /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case 0x05: /* ADAT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case 0x06: /* TDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case 0x07: /* MADI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* for undefined/changeable signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case 0x08: /* Analog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case 0x09: /* Digital */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) location = pcm + sec_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (location >= AM824_MAX_CHANNELS_FOR_PCM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) err = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) amdtp_am824_set_pcm_position(s, location,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) stm_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (type != 0x0a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pcm += channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) midi += channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) check_connection_used_by_others(struct snd_bebob *bebob, struct amdtp_stream *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct cmp_connection *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) bool used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (s == &bebob->tx_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) conn = &bebob->out_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) conn = &bebob->in_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) err = cmp_connection_check_used(conn, &used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if ((err >= 0) && used && !amdtp_stream_running(s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) "Connection established by others: %cPCR[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) conn->pcr_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static void break_both_connections(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) cmp_connection_break(&bebob->in_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) cmp_connection_break(&bebob->out_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) // These models seem to be in transition state for a longer time. When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) // accessing in the state, any transactions is corrupted. In the worst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) // case, the device is going to reboot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (bebob->version < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) msleep(600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct cmp_connection *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (stream == &bebob->rx_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) conn = &bebob->in_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) conn = &bebob->out_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) // channel mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (bebob->maudio_special_quirk == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) err = map_data_channels(bebob, stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) err = cmp_connection_establish(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return amdtp_domain_add_stream(&bebob->domain, stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) conn->resources.channel, conn->speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) enum amdtp_stream_direction dir_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct cmp_connection *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) enum cmp_direction dir_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (stream == &bebob->tx_stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dir_stream = AMDTP_IN_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) conn = &bebob->out_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dir_conn = CMP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dir_stream = AMDTP_OUT_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) conn = &bebob->in_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dir_conn = CMP_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) err = cmp_connection_init(conn, bebob->unit, dir_conn, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) err = amdtp_am824_init(stream, bebob->unit, dir_stream, CIP_BLOCKING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) cmp_connection_destroy(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (stream == &bebob->tx_stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) // BeBoB v3 transfers packets with these qurks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) // - In the beginning of streaming, the value of dbc is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) // incremented even if no data blocks are transferred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) // - The value of dbc is reset suddenly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (bebob->version > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) CIP_SKIP_DBC_ZERO_CHECK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) // At high sampling rate, M-Audio special firmware transmits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) // empty packet with the value of dbc incremented by 8 but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) // others are valid to IEC 61883-1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (bebob->maudio_special_quirk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static void destroy_stream(struct snd_bebob *bebob, struct amdtp_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) amdtp_stream_destroy(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (stream == &bebob->tx_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) cmp_connection_destroy(&bebob->out_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) cmp_connection_destroy(&bebob->in_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) err = init_stream(bebob, &bebob->tx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) err = init_stream(bebob, &bebob->rx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) destroy_stream(bebob, &bebob->tx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) err = amdtp_domain_init(&bebob->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) destroy_stream(bebob, &bebob->tx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) destroy_stream(bebob, &bebob->rx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) unsigned int rate, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) unsigned int pcm_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unsigned int midi_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct cmp_connection *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (stream == &bebob->tx_stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) pcm_channels = bebob->tx_stream_formations[index].pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) midi_ports = bebob->midi_input_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) conn = &bebob->out_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) pcm_channels = bebob->rx_stream_formations[index].pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) midi_ports = bebob->midi_output_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) conn = &bebob->in_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int snd_bebob_stream_reserve_duplex(struct snd_bebob *bebob, unsigned int rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned int frames_per_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) unsigned int frames_per_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) unsigned int curr_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) // Considering JACK/FFADO streaming:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) // TODO: This can be removed hwdep functionality becomes popular.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) err = check_connection_used_by_others(bebob, &bebob->rx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) err = bebob->spec->rate->get(bebob, &curr_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (rate == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) rate = curr_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (curr_rate != rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) amdtp_domain_stop(&bebob->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) break_both_connections(bebob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) cmp_connection_release(&bebob->out_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) cmp_connection_release(&bebob->in_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (bebob->substreams_counter == 0 || curr_rate != rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) // NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) // If establishing connections at first, Yamaha GO46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) // (and maybe Terratec X24) don't generate sound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) // For firmware customized by M-Audio, refer to next NOTE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) err = bebob->spec->rate->set(bebob, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) "fail to set sampling rate: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) err = get_formation_index(rate, &index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) err = keep_resources(bebob, &bebob->tx_stream, rate, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) err = keep_resources(bebob, &bebob->rx_stream, rate, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cmp_connection_release(&bebob->out_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) err = amdtp_domain_set_events_per_period(&bebob->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) frames_per_period, frames_per_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) cmp_connection_release(&bebob->out_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) cmp_connection_release(&bebob->in_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) // Need no substreams.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (bebob->substreams_counter == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) // packet queueing error or detecting discontinuity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (amdtp_streaming_error(&bebob->rx_stream) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) amdtp_streaming_error(&bebob->tx_stream)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) amdtp_domain_stop(&bebob->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break_both_connections(bebob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (!amdtp_stream_running(&bebob->rx_stream)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) enum snd_bebob_clock_type src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct amdtp_stream *master, *slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) unsigned int curr_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned int ir_delay_cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (bebob->maudio_special_quirk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) err = bebob->spec->rate->get(bebob, &curr_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) err = snd_bebob_stream_get_clock_src(bebob, &src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (src != SND_BEBOB_CLOCK_TYPE_SYT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) master = &bebob->tx_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) slave = &bebob->rx_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) master = &bebob->rx_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) slave = &bebob->tx_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) err = start_stream(bebob, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) err = start_stream(bebob, slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) // The device postpones start of transmission mostly for 1 sec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) // after receives packets firstly. For safe, IR context starts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) // 0.4 sec (=3200 cycles) later to version 1 or 2 firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) // 2.0 sec (=16000 cycles) for version 3 firmware. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) // within 2.5 sec (=CALLBACK_TIMEOUT).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) // Furthermore, some devices transfer isoc packets with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) // discontinuous counter in the beginning of packet streaming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) // The delay has an effect to avoid detection of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) // discontinuity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (bebob->version < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) ir_delay_cycle = 3200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ir_delay_cycle = 16000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) err = amdtp_domain_start(&bebob->domain, ir_delay_cycle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) // NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) // The firmware customized by M-Audio uses these commands to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) // start transmitting stream. This is not usual way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (bebob->maudio_special_quirk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) err = bebob->spec->rate->set(bebob, curr_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) "fail to ensure sampling rate: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (!amdtp_stream_wait_callback(&bebob->rx_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) CALLBACK_TIMEOUT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) !amdtp_stream_wait_callback(&bebob->tx_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) CALLBACK_TIMEOUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) err = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) amdtp_domain_stop(&bebob->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) break_both_connections(bebob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (bebob->substreams_counter == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) amdtp_domain_stop(&bebob->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) break_both_connections(bebob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) cmp_connection_release(&bebob->out_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) cmp_connection_release(&bebob->in_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * This function should be called before starting streams or after stopping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * streams.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) amdtp_domain_destroy(&bebob->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) destroy_stream(bebob, &bebob->tx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) destroy_stream(bebob, &bebob->rx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * See: Table 50: Extended Stream Format Info Format Hierarchy Level 2’
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * in Additional AVC commands (Nov 2003, BridgeCo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) parse_stream_formation(u8 *buf, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct snd_bebob_stream_formation *formation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) unsigned int i, e, channels, format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * this module can support a hierarchy combination that:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Root: Audio and Music (0x90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * Level 1: AM824 Compound (0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if ((buf[0] != 0x90) || (buf[1] != 0x40))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* check sampling rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) for (i = 0; i < ARRAY_SIZE(bridgeco_freq_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (buf[2] == bridgeco_freq_table[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (i == ARRAY_SIZE(bridgeco_freq_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* Avoid double count by different entries for the same rate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) memset(&formation[i], 0, sizeof(struct snd_bebob_stream_formation));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) for (e = 0; e < buf[4]; e++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) channels = buf[5 + e * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) format = buf[6 + e * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) switch (format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* IEC 60958 Conformant, currently handled as MBLA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /* Multi bit linear audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case 0x06: /* Raw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) formation[i].pcm += channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* MIDI Conformant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) case 0x0d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) formation[i].midi += channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* IEC 61937-3 to 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) case 0x01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) case 0x03:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) case 0x04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case 0x05:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /* Multi bit linear audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case 0x07: /* DVD-Audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case 0x0c: /* High Precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* One Bit Audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) case 0x08: /* (Plain) Raw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) case 0x09: /* (Plain) SACD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case 0x0a: /* (Encoded) Raw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case 0x0b: /* (Encoded) SACD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Synchronization Stream (Stereo Raw audio) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) case 0x40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* Don't care */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case 0xff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return -ENOSYS; /* not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (formation[i].pcm > AM824_MAX_CHANNELS_FOR_PCM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) formation[i].midi > AM824_MAX_CHANNELS_FOR_MIDI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) fill_stream_formations(struct snd_bebob *bebob, enum avc_bridgeco_plug_dir dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) unsigned short pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct snd_bebob_stream_formation *formations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) unsigned int len, eid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) u8 addr[AVC_BRIDGECO_ADDR_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) buf = kmalloc(FORMAT_MAXIMUM_LENGTH, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (dir == AVC_BRIDGECO_PLUG_DIR_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) formations = bebob->rx_stream_formations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) formations = bebob->tx_stream_formations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) for (eid = 0; eid < SND_BEBOB_STRM_FMT_ENTRIES; eid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) len = FORMAT_MAXIMUM_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) avc_bridgeco_fill_unit_addr(addr, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) AVC_BRIDGECO_PLUG_UNIT_ISOC, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) &len, eid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* No entries remained. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (err == -EINVAL && eid > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) } else if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) "fail to get stream format %d for isoc %s plug %d:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) eid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) "out",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) pid, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) err = parse_stream_formation(buf, len, formations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) seek_msu_sync_input_plug(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) enum avc_bridgeco_plug_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /* Get the number of Music Sub Unit for both direction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) err = avc_general_get_plug_info(bebob->unit, 0x0c, 0x00, 0x00, plugs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) "fail to get info for MSU in/out plugs: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* seek destination plugs for 'MSU sync input' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) bebob->sync_input_plug = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) for (i = 0; i < plugs[0]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) "fail to get type for MSU in plug %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) bebob->sync_input_plug = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) int snd_bebob_stream_discover(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) enum avc_bridgeco_plug_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /* the number of plugs for isoc in/out, ext in/out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) err = avc_general_get_plug_info(bebob->unit, 0x1f, 0x07, 0x00, plugs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) "fail to get info for isoc/external in/out plugs: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * This module supports at least one isoc input plug and one isoc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * output plug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if ((plugs[0] == 0) || (plugs[1] == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) err = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) "fail to get type for isoc in plug 0: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) } else if (type != AVC_BRIDGECO_PLUG_TYPE_ISOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) err = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) err = fill_stream_formations(bebob, AVC_BRIDGECO_PLUG_DIR_IN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) "fail to get type for isoc out plug 0: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) } else if (type != AVC_BRIDGECO_PLUG_TYPE_ISOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) err = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) err = fill_stream_formations(bebob, AVC_BRIDGECO_PLUG_DIR_OUT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* count external input plugs for MIDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) bebob->midi_input_ports = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) for (i = 0; i < plugs[2]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) AVC_BRIDGECO_PLUG_UNIT_EXT, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) "fail to get type for external in plug %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) } else if (type == AVC_BRIDGECO_PLUG_TYPE_MIDI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) bebob->midi_input_ports++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* count external output plugs for MIDI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) bebob->midi_output_ports = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) for (i = 0; i < plugs[3]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) AVC_BRIDGECO_PLUG_UNIT_EXT, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) dev_err(&bebob->unit->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) "fail to get type for external out plug %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) } else if (type == AVC_BRIDGECO_PLUG_TYPE_MIDI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) bebob->midi_output_ports++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* for check source of clock later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!clk_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) err = seek_msu_sync_input_plug(bebob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) void snd_bebob_stream_lock_changed(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) bebob->dev_lock_changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) wake_up(&bebob->hwdep_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) int snd_bebob_stream_lock_try(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) spin_lock_irq(&bebob->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* user land lock this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (bebob->dev_lock_count < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /* this is the first time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (bebob->dev_lock_count++ == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) snd_bebob_stream_lock_changed(bebob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) spin_unlock_irq(&bebob->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) void snd_bebob_stream_lock_release(struct snd_bebob *bebob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) spin_lock_irq(&bebob->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (WARN_ON(bebob->dev_lock_count <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (--bebob->dev_lock_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) snd_bebob_stream_lock_changed(bebob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) spin_unlock_irq(&bebob->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }