1da607e19SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2eb7b3a05STakashi Sakamoto /* 3eb7b3a05STakashi Sakamoto * bebob_stream.c - a part of driver for BeBoB based devices 4eb7b3a05STakashi Sakamoto * 5eb7b3a05STakashi Sakamoto * Copyright (c) 2013-2014 Takashi Sakamoto 6eb7b3a05STakashi Sakamoto */ 7eb7b3a05STakashi Sakamoto 8eb7b3a05STakashi Sakamoto #include "./bebob.h" 9eb7b3a05STakashi Sakamoto 105ec85c19STakashi Sakamoto #define READY_TIMEOUT_MS 4000 11eb7b3a05STakashi Sakamoto 12eb7b3a05STakashi Sakamoto /* 13eb7b3a05STakashi Sakamoto * NOTE; 14eb7b3a05STakashi Sakamoto * For BeBoB streams, Both of input and output CMP connection are important. 15eb7b3a05STakashi Sakamoto * 16eb7b3a05STakashi Sakamoto * For most devices, each CMP connection starts to transmit/receive a 17eb7b3a05STakashi Sakamoto * corresponding stream. But for a few devices, both of CMP connection needs 18eb7b3a05STakashi Sakamoto * to start transmitting stream. An example is 'M-Audio Firewire 410'. 19eb7b3a05STakashi Sakamoto */ 20eb7b3a05STakashi Sakamoto 21eb7b3a05STakashi Sakamoto /* 128 is an arbitrary length but it seems to be enough */ 22eb7b3a05STakashi Sakamoto #define FORMAT_MAXIMUM_LENGTH 128 23eb7b3a05STakashi Sakamoto 24eb7b3a05STakashi Sakamoto const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES] = { 25eb7b3a05STakashi Sakamoto [0] = 32000, 26eb7b3a05STakashi Sakamoto [1] = 44100, 27eb7b3a05STakashi Sakamoto [2] = 48000, 28eb7b3a05STakashi Sakamoto [3] = 88200, 29eb7b3a05STakashi Sakamoto [4] = 96000, 30eb7b3a05STakashi Sakamoto [5] = 176400, 31eb7b3a05STakashi Sakamoto [6] = 192000, 32eb7b3a05STakashi Sakamoto }; 33eb7b3a05STakashi Sakamoto 34eb7b3a05STakashi Sakamoto /* 35eb7b3a05STakashi Sakamoto * See: Table 51: Extended Stream Format Info ‘Sampling Frequency’ 36eb7b3a05STakashi Sakamoto * in Additional AVC commands (Nov 2003, BridgeCo) 37eb7b3a05STakashi Sakamoto */ 38eb7b3a05STakashi Sakamoto static const unsigned int bridgeco_freq_table[] = { 39eb7b3a05STakashi Sakamoto [0] = 0x02, 40eb7b3a05STakashi Sakamoto [1] = 0x03, 41eb7b3a05STakashi Sakamoto [2] = 0x04, 42eb7b3a05STakashi Sakamoto [3] = 0x0a, 43eb7b3a05STakashi Sakamoto [4] = 0x05, 44eb7b3a05STakashi Sakamoto [5] = 0x06, 45eb7b3a05STakashi Sakamoto [6] = 0x07, 46eb7b3a05STakashi Sakamoto }; 47eb7b3a05STakashi Sakamoto 4807905298SLucas Tanure static int 4907905298SLucas Tanure get_formation_index(unsigned int rate, unsigned int *index) 50eb7b3a05STakashi Sakamoto { 51eb7b3a05STakashi Sakamoto unsigned int i; 52eb7b3a05STakashi Sakamoto 53eb7b3a05STakashi Sakamoto for (i = 0; i < ARRAY_SIZE(snd_bebob_rate_table); i++) { 5407905298SLucas Tanure if (snd_bebob_rate_table[i] == rate) { 5507905298SLucas Tanure *index = i; 5607905298SLucas Tanure return 0; 5707905298SLucas Tanure } 58eb7b3a05STakashi Sakamoto } 59eb7b3a05STakashi Sakamoto return -EINVAL; 60eb7b3a05STakashi Sakamoto } 61eb7b3a05STakashi Sakamoto 62eb7b3a05STakashi Sakamoto int 63eb7b3a05STakashi Sakamoto snd_bebob_stream_get_rate(struct snd_bebob *bebob, unsigned int *curr_rate) 64eb7b3a05STakashi Sakamoto { 65eb7b3a05STakashi Sakamoto unsigned int tx_rate, rx_rate, trials; 66eb7b3a05STakashi Sakamoto int err; 67eb7b3a05STakashi Sakamoto 68eb7b3a05STakashi Sakamoto trials = 0; 69eb7b3a05STakashi Sakamoto do { 70eb7b3a05STakashi Sakamoto err = avc_general_get_sig_fmt(bebob->unit, &tx_rate, 71eb7b3a05STakashi Sakamoto AVC_GENERAL_PLUG_DIR_OUT, 0); 72eb7b3a05STakashi Sakamoto } while (err == -EAGAIN && ++trials < 3); 73eb7b3a05STakashi Sakamoto if (err < 0) 74eb7b3a05STakashi Sakamoto goto end; 75eb7b3a05STakashi Sakamoto 76eb7b3a05STakashi Sakamoto trials = 0; 77eb7b3a05STakashi Sakamoto do { 78eb7b3a05STakashi Sakamoto err = avc_general_get_sig_fmt(bebob->unit, &rx_rate, 79eb7b3a05STakashi Sakamoto AVC_GENERAL_PLUG_DIR_IN, 0); 80eb7b3a05STakashi Sakamoto } while (err == -EAGAIN && ++trials < 3); 81eb7b3a05STakashi Sakamoto if (err < 0) 82eb7b3a05STakashi Sakamoto goto end; 83eb7b3a05STakashi Sakamoto 84eb7b3a05STakashi Sakamoto *curr_rate = rx_rate; 85eb7b3a05STakashi Sakamoto if (rx_rate == tx_rate) 86eb7b3a05STakashi Sakamoto goto end; 87eb7b3a05STakashi Sakamoto 88eb7b3a05STakashi Sakamoto /* synchronize receive stream rate to transmit stream rate */ 89eb7b3a05STakashi Sakamoto err = avc_general_set_sig_fmt(bebob->unit, rx_rate, 90eb7b3a05STakashi Sakamoto AVC_GENERAL_PLUG_DIR_IN, 0); 91eb7b3a05STakashi Sakamoto end: 92eb7b3a05STakashi Sakamoto return err; 93eb7b3a05STakashi Sakamoto } 94eb7b3a05STakashi Sakamoto 95eb7b3a05STakashi Sakamoto int 96eb7b3a05STakashi Sakamoto snd_bebob_stream_set_rate(struct snd_bebob *bebob, unsigned int rate) 97eb7b3a05STakashi Sakamoto { 98eb7b3a05STakashi Sakamoto int err; 99eb7b3a05STakashi Sakamoto 100eb7b3a05STakashi Sakamoto err = avc_general_set_sig_fmt(bebob->unit, rate, 101eb7b3a05STakashi Sakamoto AVC_GENERAL_PLUG_DIR_OUT, 0); 102eb7b3a05STakashi Sakamoto if (err < 0) 103eb7b3a05STakashi Sakamoto goto end; 104eb7b3a05STakashi Sakamoto 105eb7b3a05STakashi Sakamoto err = avc_general_set_sig_fmt(bebob->unit, rate, 106eb7b3a05STakashi Sakamoto AVC_GENERAL_PLUG_DIR_IN, 0); 107eb7b3a05STakashi Sakamoto if (err < 0) 108eb7b3a05STakashi Sakamoto goto end; 109eb7b3a05STakashi Sakamoto 110eb7b3a05STakashi Sakamoto /* 111eb7b3a05STakashi Sakamoto * Some devices need a bit time for transition. 112eb7b3a05STakashi Sakamoto * 300msec is got by some experiments. 113eb7b3a05STakashi Sakamoto */ 114eb7b3a05STakashi Sakamoto msleep(300); 115eb7b3a05STakashi Sakamoto end: 116eb7b3a05STakashi Sakamoto return err; 117eb7b3a05STakashi Sakamoto } 118eb7b3a05STakashi Sakamoto 1193e254b16STakashi Sakamoto int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob, 1203e254b16STakashi Sakamoto enum snd_bebob_clock_type *src) 121eb7b3a05STakashi Sakamoto { 1226b9866c8SJulia Lawall const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; 123eb7b3a05STakashi Sakamoto u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7]; 1241fc9522aSTakashi Sakamoto unsigned int id; 1255a668812STakashi Sakamoto enum avc_bridgeco_plug_type type; 126eb7b3a05STakashi Sakamoto int err = 0; 127eb7b3a05STakashi Sakamoto 1281fc9522aSTakashi Sakamoto /* 1.The device has its own operation to switch source of clock */ 1291fc9522aSTakashi Sakamoto if (clk_spec) { 1301fc9522aSTakashi Sakamoto err = clk_spec->get(bebob, &id); 131d1d0b6b6SChristian Vogel if (err < 0) { 1321fc9522aSTakashi Sakamoto dev_err(&bebob->unit->device, 1331fc9522aSTakashi Sakamoto "fail to get clock source: %d\n", err); 134d1d0b6b6SChristian Vogel goto end; 135d1d0b6b6SChristian Vogel } 136d1d0b6b6SChristian Vogel 137d1d0b6b6SChristian Vogel if (id >= clk_spec->num) { 138d1d0b6b6SChristian Vogel dev_err(&bebob->unit->device, 139d1d0b6b6SChristian Vogel "clock source %d out of range 0..%d\n", 140d1d0b6b6SChristian Vogel id, clk_spec->num - 1); 141d1d0b6b6SChristian Vogel err = -EIO; 142d1d0b6b6SChristian Vogel goto end; 143d1d0b6b6SChristian Vogel } 144d1d0b6b6SChristian Vogel 1453e254b16STakashi Sakamoto *src = clk_spec->types[id]; 1461fc9522aSTakashi Sakamoto goto end; 1471fc9522aSTakashi Sakamoto } 1481fc9522aSTakashi Sakamoto 149eb7b3a05STakashi Sakamoto /* 1501fc9522aSTakashi Sakamoto * 2.The device don't support to switch source of clock then assumed 151eb7b3a05STakashi Sakamoto * to use internal clock always 152eb7b3a05STakashi Sakamoto */ 153eb7b3a05STakashi Sakamoto if (bebob->sync_input_plug < 0) { 1543e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_INTERNAL; 155eb7b3a05STakashi Sakamoto goto end; 156eb7b3a05STakashi Sakamoto } 157eb7b3a05STakashi Sakamoto 158eb7b3a05STakashi Sakamoto /* 1591fc9522aSTakashi Sakamoto * 3.The device supports to switch source of clock by an usual way. 160eb7b3a05STakashi Sakamoto * Let's check input for 'Music Sub Unit Sync Input' plug. 161eb7b3a05STakashi Sakamoto */ 162eb7b3a05STakashi Sakamoto avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, 163eb7b3a05STakashi Sakamoto bebob->sync_input_plug); 164eb7b3a05STakashi Sakamoto err = avc_bridgeco_get_plug_input(bebob->unit, addr, input); 165eb7b3a05STakashi Sakamoto if (err < 0) { 166eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 167eb7b3a05STakashi Sakamoto "fail to get an input for MSU in plug %d: %d\n", 168eb7b3a05STakashi Sakamoto bebob->sync_input_plug, err); 169eb7b3a05STakashi Sakamoto goto end; 170eb7b3a05STakashi Sakamoto } 171eb7b3a05STakashi Sakamoto 172eb7b3a05STakashi Sakamoto /* 173eb7b3a05STakashi Sakamoto * If there are no input plugs, all of fields are 0xff. 174eb7b3a05STakashi Sakamoto * Here check the first field. This field is used for direction. 175eb7b3a05STakashi Sakamoto */ 176eb7b3a05STakashi Sakamoto if (input[0] == 0xff) { 1773e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_INTERNAL; 178eb7b3a05STakashi Sakamoto goto end; 179eb7b3a05STakashi Sakamoto } 180eb7b3a05STakashi Sakamoto 1815a668812STakashi Sakamoto /* The source from any output plugs is for one purpose only. */ 1825a668812STakashi Sakamoto if (input[0] == AVC_BRIDGECO_PLUG_DIR_OUT) { 183eb7b3a05STakashi Sakamoto /* 1845a668812STakashi Sakamoto * In BeBoB architecture, the source from music subunit may 1855a668812STakashi Sakamoto * bypass from oPCR[0]. This means that this source gives 1865a668812STakashi Sakamoto * synchronization to IEEE 1394 cycle start packet. 187eb7b3a05STakashi Sakamoto */ 1885a668812STakashi Sakamoto if (input[1] == AVC_BRIDGECO_PLUG_MODE_SUBUNIT && 1895a668812STakashi Sakamoto input[2] == 0x0c) { 1903e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_INTERNAL; 1915a668812STakashi Sakamoto goto end; 1925a668812STakashi Sakamoto } 1935a668812STakashi Sakamoto /* The source from any input units is for several purposes. */ 1945a668812STakashi Sakamoto } else if (input[1] == AVC_BRIDGECO_PLUG_MODE_UNIT) { 1955a668812STakashi Sakamoto if (input[2] == AVC_BRIDGECO_PLUG_UNIT_ISOC) { 1965a668812STakashi Sakamoto if (input[3] == 0x00) { 1975a668812STakashi Sakamoto /* 1985a668812STakashi Sakamoto * This source comes from iPCR[0]. This means 1995a668812STakashi Sakamoto * that presentation timestamp calculated by 2005a668812STakashi Sakamoto * SYT series of the received packets. In 2015a668812STakashi Sakamoto * short, this driver is the master of 2025a668812STakashi Sakamoto * synchronization. 2035a668812STakashi Sakamoto */ 2043e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_SYT; 2055a668812STakashi Sakamoto goto end; 2065a668812STakashi Sakamoto } else { 2075a668812STakashi Sakamoto /* 2085a668812STakashi Sakamoto * This source comes from iPCR[1-29]. This 2095a668812STakashi Sakamoto * means that the synchronization stream is not 2105a668812STakashi Sakamoto * the Audio/MIDI compound stream. 2115a668812STakashi Sakamoto */ 2123e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL; 2135a668812STakashi Sakamoto goto end; 2145a668812STakashi Sakamoto } 2155a668812STakashi Sakamoto } else if (input[2] == AVC_BRIDGECO_PLUG_UNIT_EXT) { 2165a668812STakashi Sakamoto /* Check type of this plug. */ 2175a668812STakashi Sakamoto avc_bridgeco_fill_unit_addr(addr, 2185a668812STakashi Sakamoto AVC_BRIDGECO_PLUG_DIR_IN, 2195a668812STakashi Sakamoto AVC_BRIDGECO_PLUG_UNIT_EXT, 2205a668812STakashi Sakamoto input[3]); 2215a668812STakashi Sakamoto err = avc_bridgeco_get_plug_type(bebob->unit, addr, 2225a668812STakashi Sakamoto &type); 2235a668812STakashi Sakamoto if (err < 0) 2245a668812STakashi Sakamoto goto end; 2255a668812STakashi Sakamoto 2265a668812STakashi Sakamoto if (type == AVC_BRIDGECO_PLUG_TYPE_DIG) { 2275a668812STakashi Sakamoto /* 2285a668812STakashi Sakamoto * SPDIF/ADAT or sometimes (not always) word 2295a668812STakashi Sakamoto * clock. 2305a668812STakashi Sakamoto */ 2313e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL; 2325a668812STakashi Sakamoto goto end; 2335a668812STakashi Sakamoto } else if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) { 2345a668812STakashi Sakamoto /* Often word clock. */ 2353e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_EXTERNAL; 2365a668812STakashi Sakamoto goto end; 2375a668812STakashi Sakamoto } else if (type == AVC_BRIDGECO_PLUG_TYPE_ADDITION) { 2385a668812STakashi Sakamoto /* 2395a668812STakashi Sakamoto * Not standard. 2405a668812STakashi Sakamoto * Mostly, additional internal clock. 2415a668812STakashi Sakamoto */ 2423e254b16STakashi Sakamoto *src = SND_BEBOB_CLOCK_TYPE_INTERNAL; 2435a668812STakashi Sakamoto goto end; 2445a668812STakashi Sakamoto } 2455a668812STakashi Sakamoto } 2465a668812STakashi Sakamoto } 2475a668812STakashi Sakamoto 2485a668812STakashi Sakamoto /* Not supported. */ 2495a668812STakashi Sakamoto err = -EIO; 250eb7b3a05STakashi Sakamoto end: 251eb7b3a05STakashi Sakamoto return err; 252eb7b3a05STakashi Sakamoto } 253eb7b3a05STakashi Sakamoto 254f2bbdbcbSTakashi Sakamoto static int map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s) 255eb7b3a05STakashi Sakamoto { 256eb7b3a05STakashi Sakamoto unsigned int sec, sections, ch, channels; 257eb7b3a05STakashi Sakamoto unsigned int pcm, midi, location; 258eb7b3a05STakashi Sakamoto unsigned int stm_pos, sec_loc, pos; 259eb7b3a05STakashi Sakamoto u8 *buf, addr[AVC_BRIDGECO_ADDR_BYTES], type; 260eb7b3a05STakashi Sakamoto enum avc_bridgeco_plug_dir dir; 261eb7b3a05STakashi Sakamoto int err; 262eb7b3a05STakashi Sakamoto 263eb7b3a05STakashi Sakamoto /* 264eb7b3a05STakashi Sakamoto * The length of return value of this command cannot be expected. Here 265eb7b3a05STakashi Sakamoto * use the maximum length of FCP. 266eb7b3a05STakashi Sakamoto */ 267eb7b3a05STakashi Sakamoto buf = kzalloc(256, GFP_KERNEL); 268eb7b3a05STakashi Sakamoto if (buf == NULL) 269eb7b3a05STakashi Sakamoto return -ENOMEM; 270eb7b3a05STakashi Sakamoto 271eb7b3a05STakashi Sakamoto if (s == &bebob->tx_stream) 272eb7b3a05STakashi Sakamoto dir = AVC_BRIDGECO_PLUG_DIR_OUT; 273eb7b3a05STakashi Sakamoto else 274eb7b3a05STakashi Sakamoto dir = AVC_BRIDGECO_PLUG_DIR_IN; 275eb7b3a05STakashi Sakamoto 276eb7b3a05STakashi Sakamoto avc_bridgeco_fill_unit_addr(addr, dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, 0); 277eb7b3a05STakashi Sakamoto err = avc_bridgeco_get_plug_ch_pos(bebob->unit, addr, buf, 256); 278eb7b3a05STakashi Sakamoto if (err < 0) { 279eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 280eb7b3a05STakashi Sakamoto "fail to get channel position for isoc %s plug 0: %d\n", 281eb7b3a05STakashi Sakamoto (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : "out", 282eb7b3a05STakashi Sakamoto err); 283eb7b3a05STakashi Sakamoto goto end; 284eb7b3a05STakashi Sakamoto } 285eb7b3a05STakashi Sakamoto pos = 0; 286eb7b3a05STakashi Sakamoto 287eb7b3a05STakashi Sakamoto /* positions in I/O buffer */ 288eb7b3a05STakashi Sakamoto pcm = 0; 289eb7b3a05STakashi Sakamoto midi = 0; 290eb7b3a05STakashi Sakamoto 291eb7b3a05STakashi Sakamoto /* the number of sections in AMDTP packet */ 292eb7b3a05STakashi Sakamoto sections = buf[pos++]; 293eb7b3a05STakashi Sakamoto 294eb7b3a05STakashi Sakamoto for (sec = 0; sec < sections; sec++) { 295eb7b3a05STakashi Sakamoto /* type of this section */ 296eb7b3a05STakashi Sakamoto avc_bridgeco_fill_unit_addr(addr, dir, 297eb7b3a05STakashi Sakamoto AVC_BRIDGECO_PLUG_UNIT_ISOC, 0); 298eb7b3a05STakashi Sakamoto err = avc_bridgeco_get_plug_section_type(bebob->unit, addr, 299eb7b3a05STakashi Sakamoto sec, &type); 300eb7b3a05STakashi Sakamoto if (err < 0) { 301eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 302eb7b3a05STakashi Sakamoto "fail to get section type for isoc %s plug 0: %d\n", 303eb7b3a05STakashi Sakamoto (dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" : 304eb7b3a05STakashi Sakamoto "out", 305eb7b3a05STakashi Sakamoto err); 306eb7b3a05STakashi Sakamoto goto end; 307eb7b3a05STakashi Sakamoto } 308eb7b3a05STakashi Sakamoto /* NoType */ 309eb7b3a05STakashi Sakamoto if (type == 0xff) { 310eb7b3a05STakashi Sakamoto err = -ENOSYS; 311eb7b3a05STakashi Sakamoto goto end; 312eb7b3a05STakashi Sakamoto } 313eb7b3a05STakashi Sakamoto 314eb7b3a05STakashi Sakamoto /* the number of channels in this section */ 315eb7b3a05STakashi Sakamoto channels = buf[pos++]; 316eb7b3a05STakashi Sakamoto 317eb7b3a05STakashi Sakamoto for (ch = 0; ch < channels; ch++) { 318eb7b3a05STakashi Sakamoto /* position of this channel in AMDTP packet */ 319eb7b3a05STakashi Sakamoto stm_pos = buf[pos++] - 1; 320eb7b3a05STakashi Sakamoto /* location of this channel in this section */ 321eb7b3a05STakashi Sakamoto sec_loc = buf[pos++] - 1; 322eb7b3a05STakashi Sakamoto 3239076c22dSTakashi Sakamoto /* 3249076c22dSTakashi Sakamoto * Basically the number of location is within the 3259076c22dSTakashi Sakamoto * number of channels in this section. But some models 3269076c22dSTakashi Sakamoto * of M-Audio don't follow this. Its location for MIDI 3279076c22dSTakashi Sakamoto * is the position of MIDI channels in AMDTP packet. 3289076c22dSTakashi Sakamoto */ 3299076c22dSTakashi Sakamoto if (sec_loc >= channels) 3309076c22dSTakashi Sakamoto sec_loc = ch; 3319076c22dSTakashi Sakamoto 332eb7b3a05STakashi Sakamoto switch (type) { 333eb7b3a05STakashi Sakamoto /* for MIDI conformant data channel */ 334eb7b3a05STakashi Sakamoto case 0x0a: 335eb7b3a05STakashi Sakamoto /* AMDTP_MAX_CHANNELS_FOR_MIDI is 1. */ 336eb7b3a05STakashi Sakamoto if ((midi > 0) && (stm_pos != midi)) { 337eb7b3a05STakashi Sakamoto err = -ENOSYS; 338eb7b3a05STakashi Sakamoto goto end; 339eb7b3a05STakashi Sakamoto } 340f65be911STakashi Sakamoto amdtp_am824_set_midi_position(s, stm_pos); 341eb7b3a05STakashi Sakamoto midi = stm_pos; 342eb7b3a05STakashi Sakamoto break; 343eb7b3a05STakashi Sakamoto /* for PCM data channel */ 344eb7b3a05STakashi Sakamoto case 0x01: /* Headphone */ 345eb7b3a05STakashi Sakamoto case 0x02: /* Microphone */ 346eb7b3a05STakashi Sakamoto case 0x03: /* Line */ 347eb7b3a05STakashi Sakamoto case 0x04: /* SPDIF */ 348eb7b3a05STakashi Sakamoto case 0x05: /* ADAT */ 349eb7b3a05STakashi Sakamoto case 0x06: /* TDIF */ 350eb7b3a05STakashi Sakamoto case 0x07: /* MADI */ 351eb7b3a05STakashi Sakamoto /* for undefined/changeable signal */ 352eb7b3a05STakashi Sakamoto case 0x08: /* Analog */ 353eb7b3a05STakashi Sakamoto case 0x09: /* Digital */ 354eb7b3a05STakashi Sakamoto default: 355eb7b3a05STakashi Sakamoto location = pcm + sec_loc; 35649c7b3fcSTakashi Sakamoto if (location >= AM824_MAX_CHANNELS_FOR_PCM) { 357eb7b3a05STakashi Sakamoto err = -ENOSYS; 358eb7b3a05STakashi Sakamoto goto end; 359eb7b3a05STakashi Sakamoto } 360f65be911STakashi Sakamoto amdtp_am824_set_pcm_position(s, location, 361f65be911STakashi Sakamoto stm_pos); 362eb7b3a05STakashi Sakamoto break; 363eb7b3a05STakashi Sakamoto } 364eb7b3a05STakashi Sakamoto } 365eb7b3a05STakashi Sakamoto 366eb7b3a05STakashi Sakamoto if (type != 0x0a) 367eb7b3a05STakashi Sakamoto pcm += channels; 368eb7b3a05STakashi Sakamoto else 369eb7b3a05STakashi Sakamoto midi += channels; 370eb7b3a05STakashi Sakamoto } 371eb7b3a05STakashi Sakamoto end: 372eb7b3a05STakashi Sakamoto kfree(buf); 373eb7b3a05STakashi Sakamoto return err; 374eb7b3a05STakashi Sakamoto } 375eb7b3a05STakashi Sakamoto 376eb7b3a05STakashi Sakamoto static int 377eb7b3a05STakashi Sakamoto check_connection_used_by_others(struct snd_bebob *bebob, struct amdtp_stream *s) 378eb7b3a05STakashi Sakamoto { 379eb7b3a05STakashi Sakamoto struct cmp_connection *conn; 380eb7b3a05STakashi Sakamoto bool used; 381eb7b3a05STakashi Sakamoto int err; 382eb7b3a05STakashi Sakamoto 383eb7b3a05STakashi Sakamoto if (s == &bebob->tx_stream) 384eb7b3a05STakashi Sakamoto conn = &bebob->out_conn; 385eb7b3a05STakashi Sakamoto else 386eb7b3a05STakashi Sakamoto conn = &bebob->in_conn; 387eb7b3a05STakashi Sakamoto 388eb7b3a05STakashi Sakamoto err = cmp_connection_check_used(conn, &used); 389eb7b3a05STakashi Sakamoto if ((err >= 0) && used && !amdtp_stream_running(s)) { 390eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 391eb7b3a05STakashi Sakamoto "Connection established by others: %cPCR[%d]\n", 392eb7b3a05STakashi Sakamoto (conn->direction == CMP_OUTPUT) ? 'o' : 'i', 393eb7b3a05STakashi Sakamoto conn->pcr_index); 394eb7b3a05STakashi Sakamoto err = -EBUSY; 395eb7b3a05STakashi Sakamoto } 396eb7b3a05STakashi Sakamoto 397eb7b3a05STakashi Sakamoto return err; 398eb7b3a05STakashi Sakamoto } 399eb7b3a05STakashi Sakamoto 400d3eabe93STakashi Sakamoto static void break_both_connections(struct snd_bebob *bebob) 401eb7b3a05STakashi Sakamoto { 402eb7b3a05STakashi Sakamoto cmp_connection_break(&bebob->in_conn); 403eb7b3a05STakashi Sakamoto cmp_connection_break(&bebob->out_conn); 404b6bc8123STakashi Sakamoto 405d3eabe93STakashi Sakamoto // These models seem to be in transition state for a longer time. When 406d3eabe93STakashi Sakamoto // accessing in the state, any transactions is corrupted. In the worst 407d3eabe93STakashi Sakamoto // case, the device is going to reboot. 408d3eabe93STakashi Sakamoto if (bebob->version < 2) 409d3eabe93STakashi Sakamoto msleep(600); 410eb7b3a05STakashi Sakamoto } 411eb7b3a05STakashi Sakamoto 4126c94f380STakashi Sakamoto static int start_stream(struct snd_bebob *bebob, struct amdtp_stream *stream) 413eb7b3a05STakashi Sakamoto { 414eb7b3a05STakashi Sakamoto struct cmp_connection *conn; 415eb7b3a05STakashi Sakamoto int err = 0; 416eb7b3a05STakashi Sakamoto 417eb7b3a05STakashi Sakamoto if (stream == &bebob->rx_stream) 418eb7b3a05STakashi Sakamoto conn = &bebob->in_conn; 419eb7b3a05STakashi Sakamoto else 420eb7b3a05STakashi Sakamoto conn = &bebob->out_conn; 421eb7b3a05STakashi Sakamoto 4226c94f380STakashi Sakamoto // channel mapping. 4233149ac48STakashi Sakamoto if (bebob->maudio_special_quirk == NULL) { 424eb7b3a05STakashi Sakamoto err = map_data_channels(bebob, stream); 425eb7b3a05STakashi Sakamoto if (err < 0) 4266c94f380STakashi Sakamoto return err; 4273149ac48STakashi Sakamoto } 428eb7b3a05STakashi Sakamoto 4296c94f380STakashi Sakamoto err = cmp_connection_establish(conn); 4306c94f380STakashi Sakamoto if (err < 0) 431eb7b3a05STakashi Sakamoto return err; 4326c94f380STakashi Sakamoto 4336c94f380STakashi Sakamoto return amdtp_domain_add_stream(&bebob->domain, stream, 4346c94f380STakashi Sakamoto conn->resources.channel, conn->speed); 435eb7b3a05STakashi Sakamoto } 436eb7b3a05STakashi Sakamoto 43733e41a5cSTakashi Sakamoto static int init_stream(struct snd_bebob *bebob, struct amdtp_stream *stream) 438eb7b3a05STakashi Sakamoto { 43933e41a5cSTakashi Sakamoto enum amdtp_stream_direction dir_stream; 44033e41a5cSTakashi Sakamoto struct cmp_connection *conn; 44133e41a5cSTakashi Sakamoto enum cmp_direction dir_conn; 442eb7b3a05STakashi Sakamoto int err; 443eb7b3a05STakashi Sakamoto 44433e41a5cSTakashi Sakamoto if (stream == &bebob->tx_stream) { 44533e41a5cSTakashi Sakamoto dir_stream = AMDTP_IN_STREAM; 44633e41a5cSTakashi Sakamoto conn = &bebob->out_conn; 44733e41a5cSTakashi Sakamoto dir_conn = CMP_OUTPUT; 44833e41a5cSTakashi Sakamoto } else { 44933e41a5cSTakashi Sakamoto dir_stream = AMDTP_OUT_STREAM; 45033e41a5cSTakashi Sakamoto conn = &bebob->in_conn; 45133e41a5cSTakashi Sakamoto dir_conn = CMP_INPUT; 452eb7b3a05STakashi Sakamoto } 45314a37ac1STakashi Sakamoto 45433e41a5cSTakashi Sakamoto err = cmp_connection_init(conn, bebob->unit, dir_conn, 0); 45533e41a5cSTakashi Sakamoto if (err < 0) 45633e41a5cSTakashi Sakamoto return err; 45733e41a5cSTakashi Sakamoto 45833e41a5cSTakashi Sakamoto err = amdtp_am824_init(stream, bebob->unit, dir_stream, CIP_BLOCKING); 45933e41a5cSTakashi Sakamoto if (err < 0) { 46033e41a5cSTakashi Sakamoto cmp_connection_destroy(conn); 46133e41a5cSTakashi Sakamoto return err; 46233e41a5cSTakashi Sakamoto } 46333e41a5cSTakashi Sakamoto 46433e41a5cSTakashi Sakamoto if (stream == &bebob->tx_stream) { 46533e41a5cSTakashi Sakamoto // BeBoB v3 transfers packets with these qurks: 46633e41a5cSTakashi Sakamoto // - In the beginning of streaming, the value of dbc is 46733e41a5cSTakashi Sakamoto // incremented even if no data blocks are transferred. 46833e41a5cSTakashi Sakamoto // - The value of dbc is reset suddenly. 469c4d860a0STakashi Sakamoto if (bebob->version > 2) 470c4d860a0STakashi Sakamoto bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC | 471c4d860a0STakashi Sakamoto CIP_SKIP_DBC_ZERO_CHECK; 472c4d860a0STakashi Sakamoto 47333e41a5cSTakashi Sakamoto // At high sampling rate, M-Audio special firmware transmits 47433e41a5cSTakashi Sakamoto // empty packet with the value of dbc incremented by 8 but the 47533e41a5cSTakashi Sakamoto // others are valid to IEC 61883-1. 4769d59124cSTakashi Sakamoto if (bebob->maudio_special_quirk) 4779d59124cSTakashi Sakamoto bebob->tx_stream.flags |= CIP_EMPTY_HAS_WRONG_DBC; 478eb7b3a05STakashi Sakamoto } 47933e41a5cSTakashi Sakamoto 48033e41a5cSTakashi Sakamoto return 0; 48133e41a5cSTakashi Sakamoto } 48233e41a5cSTakashi Sakamoto 48333e41a5cSTakashi Sakamoto static void destroy_stream(struct snd_bebob *bebob, struct amdtp_stream *stream) 48433e41a5cSTakashi Sakamoto { 48533e41a5cSTakashi Sakamoto amdtp_stream_destroy(stream); 48633e41a5cSTakashi Sakamoto 48733e41a5cSTakashi Sakamoto if (stream == &bebob->tx_stream) 48833e41a5cSTakashi Sakamoto cmp_connection_destroy(&bebob->out_conn); 48933e41a5cSTakashi Sakamoto else 49033e41a5cSTakashi Sakamoto cmp_connection_destroy(&bebob->in_conn); 49133e41a5cSTakashi Sakamoto } 49233e41a5cSTakashi Sakamoto 49333e41a5cSTakashi Sakamoto int snd_bebob_stream_init_duplex(struct snd_bebob *bebob) 49433e41a5cSTakashi Sakamoto { 49533e41a5cSTakashi Sakamoto int err; 49633e41a5cSTakashi Sakamoto 49733e41a5cSTakashi Sakamoto err = init_stream(bebob, &bebob->tx_stream); 49833e41a5cSTakashi Sakamoto if (err < 0) 499eb7b3a05STakashi Sakamoto return err; 50033e41a5cSTakashi Sakamoto 50133e41a5cSTakashi Sakamoto err = init_stream(bebob, &bebob->rx_stream); 50233e41a5cSTakashi Sakamoto if (err < 0) { 50333e41a5cSTakashi Sakamoto destroy_stream(bebob, &bebob->tx_stream); 50433e41a5cSTakashi Sakamoto return err; 50533e41a5cSTakashi Sakamoto } 50633e41a5cSTakashi Sakamoto 507b0db4d51STakashi Sakamoto err = amdtp_domain_init(&bebob->domain); 508b0db4d51STakashi Sakamoto if (err < 0) { 509b0db4d51STakashi Sakamoto destroy_stream(bebob, &bebob->tx_stream); 510b0db4d51STakashi Sakamoto destroy_stream(bebob, &bebob->rx_stream); 511b0db4d51STakashi Sakamoto } 512b0db4d51STakashi Sakamoto 513b0db4d51STakashi Sakamoto return err; 514eb7b3a05STakashi Sakamoto } 515eb7b3a05STakashi Sakamoto 516ac2888b9STakashi Sakamoto static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream, 517ac2888b9STakashi Sakamoto unsigned int rate, unsigned int index) 518eb7b3a05STakashi Sakamoto { 519d2b6f15bSTakashi Sakamoto unsigned int pcm_channels; 520d2b6f15bSTakashi Sakamoto unsigned int midi_ports; 5217bc93821STakashi Sakamoto struct cmp_connection *conn; 5227bc93821STakashi Sakamoto int err; 523ac2888b9STakashi Sakamoto 5247bc93821STakashi Sakamoto if (stream == &bebob->tx_stream) { 525d2b6f15bSTakashi Sakamoto pcm_channels = bebob->tx_stream_formations[index].pcm; 526d2b6f15bSTakashi Sakamoto midi_ports = bebob->midi_input_ports; 5277bc93821STakashi Sakamoto conn = &bebob->out_conn; 5287bc93821STakashi Sakamoto } else { 529d2b6f15bSTakashi Sakamoto pcm_channels = bebob->rx_stream_formations[index].pcm; 530d2b6f15bSTakashi Sakamoto midi_ports = bebob->midi_output_ports; 5317bc93821STakashi Sakamoto conn = &bebob->in_conn; 5327bc93821STakashi Sakamoto } 533ac2888b9STakashi Sakamoto 534d2b6f15bSTakashi Sakamoto err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, false); 5357bc93821STakashi Sakamoto if (err < 0) 5367bc93821STakashi Sakamoto return err; 5377bc93821STakashi Sakamoto 5387bc93821STakashi Sakamoto return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream)); 539ac2888b9STakashi Sakamoto } 540ac2888b9STakashi Sakamoto 5418737209fSTakashi Sakamoto int snd_bebob_stream_reserve_duplex(struct snd_bebob *bebob, unsigned int rate, 5421fde7a44STakashi Sakamoto unsigned int frames_per_period, 5431fde7a44STakashi Sakamoto unsigned int frames_per_buffer) 544ac2888b9STakashi Sakamoto { 545eb7b3a05STakashi Sakamoto unsigned int curr_rate; 546ac2888b9STakashi Sakamoto int err; 547eb7b3a05STakashi Sakamoto 548ac2888b9STakashi Sakamoto // Considering JACK/FFADO streaming: 549ac2888b9STakashi Sakamoto // TODO: This can be removed hwdep functionality becomes popular. 550c71283cbSTakashi Sakamoto err = check_connection_used_by_others(bebob, &bebob->rx_stream); 551eb7b3a05STakashi Sakamoto if (err < 0) 552ac2888b9STakashi Sakamoto return err; 553eb7b3a05STakashi Sakamoto 554ac2888b9STakashi Sakamoto err = bebob->spec->rate->get(bebob, &curr_rate); 555ac2888b9STakashi Sakamoto if (err < 0) 556ac2888b9STakashi Sakamoto return err; 557eb7b3a05STakashi Sakamoto if (rate == 0) 558eb7b3a05STakashi Sakamoto rate = curr_rate; 559ac2888b9STakashi Sakamoto if (curr_rate != rate) { 560b0db4d51STakashi Sakamoto amdtp_domain_stop(&bebob->domain); 561eb7b3a05STakashi Sakamoto break_both_connections(bebob); 5627599e279STakashi Sakamoto 5637599e279STakashi Sakamoto cmp_connection_release(&bebob->out_conn); 5647599e279STakashi Sakamoto cmp_connection_release(&bebob->in_conn); 565eb7b3a05STakashi Sakamoto } 566eb7b3a05STakashi Sakamoto 567ac2888b9STakashi Sakamoto if (bebob->substreams_counter == 0 || curr_rate != rate) { 568ac2888b9STakashi Sakamoto unsigned int index; 569ac2888b9STakashi Sakamoto 570ac2888b9STakashi Sakamoto // NOTE: 571ac2888b9STakashi Sakamoto // If establishing connections at first, Yamaha GO46 572ac2888b9STakashi Sakamoto // (and maybe Terratec X24) don't generate sound. 573ac2888b9STakashi Sakamoto // 574ac2888b9STakashi Sakamoto // For firmware customized by M-Audio, refer to next NOTE. 575ac2888b9STakashi Sakamoto err = bebob->spec->rate->set(bebob, rate); 576eb7b3a05STakashi Sakamoto if (err < 0) { 577eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 578eb7b3a05STakashi Sakamoto "fail to set sampling rate: %d\n", 579eb7b3a05STakashi Sakamoto err); 580ac2888b9STakashi Sakamoto return err; 5813149ac48STakashi Sakamoto } 582eb7b3a05STakashi Sakamoto 583ac2888b9STakashi Sakamoto err = get_formation_index(rate, &index); 584eb7b3a05STakashi Sakamoto if (err < 0) 585ac2888b9STakashi Sakamoto return err; 586eb7b3a05STakashi Sakamoto 587ac2888b9STakashi Sakamoto err = keep_resources(bebob, &bebob->tx_stream, rate, index); 588ac2888b9STakashi Sakamoto if (err < 0) 589ac2888b9STakashi Sakamoto return err; 590ac2888b9STakashi Sakamoto 591ac2888b9STakashi Sakamoto err = keep_resources(bebob, &bebob->rx_stream, rate, index); 5927bc93821STakashi Sakamoto if (err < 0) { 5937bc93821STakashi Sakamoto cmp_connection_release(&bebob->out_conn); 594ac2888b9STakashi Sakamoto return err; 595ac2888b9STakashi Sakamoto } 5968737209fSTakashi Sakamoto 5978737209fSTakashi Sakamoto err = amdtp_domain_set_events_per_period(&bebob->domain, 5981fde7a44STakashi Sakamoto frames_per_period, frames_per_buffer); 5998737209fSTakashi Sakamoto if (err < 0) { 6008737209fSTakashi Sakamoto cmp_connection_release(&bebob->out_conn); 6018737209fSTakashi Sakamoto cmp_connection_release(&bebob->in_conn); 6028737209fSTakashi Sakamoto return err; 6038737209fSTakashi Sakamoto } 6047bc93821STakashi Sakamoto } 605ac2888b9STakashi Sakamoto 606ac2888b9STakashi Sakamoto return 0; 607ac2888b9STakashi Sakamoto } 608ac2888b9STakashi Sakamoto 609ac2888b9STakashi Sakamoto int snd_bebob_stream_start_duplex(struct snd_bebob *bebob) 610ac2888b9STakashi Sakamoto { 611ac2888b9STakashi Sakamoto int err; 612ac2888b9STakashi Sakamoto 613ac2888b9STakashi Sakamoto // Need no substreams. 614ac2888b9STakashi Sakamoto if (bebob->substreams_counter == 0) 615ac2888b9STakashi Sakamoto return -EIO; 616ac2888b9STakashi Sakamoto 617ac2888b9STakashi Sakamoto // packet queueing error or detecting discontinuity 618ac2888b9STakashi Sakamoto if (amdtp_streaming_error(&bebob->rx_stream) || 619ac2888b9STakashi Sakamoto amdtp_streaming_error(&bebob->tx_stream)) { 620b0db4d51STakashi Sakamoto amdtp_domain_stop(&bebob->domain); 621ac2888b9STakashi Sakamoto break_both_connections(bebob); 622ac2888b9STakashi Sakamoto } 623ac2888b9STakashi Sakamoto 624ac2888b9STakashi Sakamoto if (!amdtp_stream_running(&bebob->rx_stream)) { 6256c94f380STakashi Sakamoto enum snd_bebob_clock_type src; 626ac2888b9STakashi Sakamoto unsigned int curr_rate; 62726541cb1STakashi Sakamoto unsigned int tx_init_skip_cycles; 628ac2888b9STakashi Sakamoto 629ac2888b9STakashi Sakamoto if (bebob->maudio_special_quirk) { 630ac2888b9STakashi Sakamoto err = bebob->spec->rate->get(bebob, &curr_rate); 631ac2888b9STakashi Sakamoto if (err < 0) 632ac2888b9STakashi Sakamoto return err; 633ac2888b9STakashi Sakamoto } 634ac2888b9STakashi Sakamoto 6356c94f380STakashi Sakamoto err = snd_bebob_stream_get_clock_src(bebob, &src); 636ac2888b9STakashi Sakamoto if (err < 0) 637ac2888b9STakashi Sakamoto return err; 638ac2888b9STakashi Sakamoto 639266807f9STakashi Sakamoto err = start_stream(bebob, &bebob->rx_stream); 640b0db4d51STakashi Sakamoto if (err < 0) 641ac2888b9STakashi Sakamoto goto error; 642b0db4d51STakashi Sakamoto 643266807f9STakashi Sakamoto err = start_stream(bebob, &bebob->tx_stream); 644b0db4d51STakashi Sakamoto if (err < 0) 645b0db4d51STakashi Sakamoto goto error; 646b0db4d51STakashi Sakamoto 6475ec85c19STakashi Sakamoto if (!bebob->discontinuity_quirk) 6485ec85c19STakashi Sakamoto tx_init_skip_cycles = 0; 649da5e8337STakashi Sakamoto else 65026541cb1STakashi Sakamoto tx_init_skip_cycles = 16000; 6515ec85c19STakashi Sakamoto 652*1bd1b3beSTakashi Sakamoto // MEMO: Some devices start packet transmission long enough after establishment of 653*1bd1b3beSTakashi Sakamoto // CMP connection. In the early stage of packet streaming, any device transfers 654*1bd1b3beSTakashi Sakamoto // NODATA packets. After several hundred cycles, it begins to multiplex event into 655*1bd1b3beSTakashi Sakamoto // the packet with adequate value of syt field in CIP header. Some devices are 656*1bd1b3beSTakashi Sakamoto // strictly to generate any discontinuity in the sequence of tx packet when they 657*1bd1b3beSTakashi Sakamoto // receives inadequate sequence of value in syt field of CIP header. In the case, 658*1bd1b3beSTakashi Sakamoto // the request to break CMP connection is often corrupted, then any transaction 659*1bd1b3beSTakashi Sakamoto // results in unrecoverable error, sometimes generate bus-reset. 660*1bd1b3beSTakashi Sakamoto err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles, true, false); 661b0db4d51STakashi Sakamoto if (err < 0) 662b0db4d51STakashi Sakamoto goto error; 663eb7b3a05STakashi Sakamoto 664ac2888b9STakashi Sakamoto // NOTE: 665ac2888b9STakashi Sakamoto // The firmware customized by M-Audio uses these commands to 666ac2888b9STakashi Sakamoto // start transmitting stream. This is not usual way. 667ac2888b9STakashi Sakamoto if (bebob->maudio_special_quirk) { 668ac2888b9STakashi Sakamoto err = bebob->spec->rate->set(bebob, curr_rate); 6693149ac48STakashi Sakamoto if (err < 0) { 6703149ac48STakashi Sakamoto dev_err(&bebob->unit->device, 6713149ac48STakashi Sakamoto "fail to ensure sampling rate: %d\n", 6723149ac48STakashi Sakamoto err); 673ac2888b9STakashi Sakamoto goto error; 6743149ac48STakashi Sakamoto } 6753149ac48STakashi Sakamoto } 6763149ac48STakashi Sakamoto 67726541cb1STakashi Sakamoto // Some devices postpone start of transmission mostly for 1 sec after receives 67826541cb1STakashi Sakamoto // packets firstly. 679bdaedca7STakashi Sakamoto if (!amdtp_domain_wait_ready(&bebob->domain, READY_TIMEOUT_MS)) { 680ac2888b9STakashi Sakamoto err = -ETIMEDOUT; 681ac2888b9STakashi Sakamoto goto error; 682ac2888b9STakashi Sakamoto } 683ac2888b9STakashi Sakamoto } 684ac2888b9STakashi Sakamoto 685ac2888b9STakashi Sakamoto return 0; 686ac2888b9STakashi Sakamoto error: 687b0db4d51STakashi Sakamoto amdtp_domain_stop(&bebob->domain); 688eb7b3a05STakashi Sakamoto break_both_connections(bebob); 689eb7b3a05STakashi Sakamoto return err; 690eb7b3a05STakashi Sakamoto } 691eb7b3a05STakashi Sakamoto 692eb7b3a05STakashi Sakamoto void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob) 693eb7b3a05STakashi Sakamoto { 6944fd6c6c7STakashi Sakamoto if (bebob->substreams_counter == 0) { 695b0db4d51STakashi Sakamoto amdtp_domain_stop(&bebob->domain); 696eb7b3a05STakashi Sakamoto break_both_connections(bebob); 6977bc93821STakashi Sakamoto 6987bc93821STakashi Sakamoto cmp_connection_release(&bebob->out_conn); 6997bc93821STakashi Sakamoto cmp_connection_release(&bebob->in_conn); 700eb7b3a05STakashi Sakamoto } 701eb7b3a05STakashi Sakamoto } 702eb7b3a05STakashi Sakamoto 703d23c2cc4STakashi Sakamoto /* 704d23c2cc4STakashi Sakamoto * This function should be called before starting streams or after stopping 705d23c2cc4STakashi Sakamoto * streams. 706d23c2cc4STakashi Sakamoto */ 707eb7b3a05STakashi Sakamoto void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob) 708eb7b3a05STakashi Sakamoto { 709b0db4d51STakashi Sakamoto amdtp_domain_destroy(&bebob->domain); 710b0db4d51STakashi Sakamoto 71133e41a5cSTakashi Sakamoto destroy_stream(bebob, &bebob->tx_stream); 71233e41a5cSTakashi Sakamoto destroy_stream(bebob, &bebob->rx_stream); 713eb7b3a05STakashi Sakamoto } 714eb7b3a05STakashi Sakamoto 715eb7b3a05STakashi Sakamoto /* 716eb7b3a05STakashi Sakamoto * See: Table 50: Extended Stream Format Info Format Hierarchy Level 2’ 717eb7b3a05STakashi Sakamoto * in Additional AVC commands (Nov 2003, BridgeCo) 718eb7b3a05STakashi Sakamoto * Also 'Clause 12 AM824 sequence adaption layers' in IEC 61883-6:2005 719eb7b3a05STakashi Sakamoto */ 720eb7b3a05STakashi Sakamoto static int 721eb7b3a05STakashi Sakamoto parse_stream_formation(u8 *buf, unsigned int len, 722eb7b3a05STakashi Sakamoto struct snd_bebob_stream_formation *formation) 723eb7b3a05STakashi Sakamoto { 724eb7b3a05STakashi Sakamoto unsigned int i, e, channels, format; 725eb7b3a05STakashi Sakamoto 726eb7b3a05STakashi Sakamoto /* 727eb7b3a05STakashi Sakamoto * this module can support a hierarchy combination that: 728eb7b3a05STakashi Sakamoto * Root: Audio and Music (0x90) 729eb7b3a05STakashi Sakamoto * Level 1: AM824 Compound (0x40) 730eb7b3a05STakashi Sakamoto */ 731eb7b3a05STakashi Sakamoto if ((buf[0] != 0x90) || (buf[1] != 0x40)) 732eb7b3a05STakashi Sakamoto return -ENOSYS; 733eb7b3a05STakashi Sakamoto 734eb7b3a05STakashi Sakamoto /* check sampling rate */ 735eb7b3a05STakashi Sakamoto for (i = 0; i < ARRAY_SIZE(bridgeco_freq_table); i++) { 736eb7b3a05STakashi Sakamoto if (buf[2] == bridgeco_freq_table[i]) 737eb7b3a05STakashi Sakamoto break; 738eb7b3a05STakashi Sakamoto } 73933a5f989SDan Carpenter if (i == ARRAY_SIZE(bridgeco_freq_table)) 740eb7b3a05STakashi Sakamoto return -ENOSYS; 741eb7b3a05STakashi Sakamoto 742eb7b3a05STakashi Sakamoto /* Avoid double count by different entries for the same rate. */ 743eb7b3a05STakashi Sakamoto memset(&formation[i], 0, sizeof(struct snd_bebob_stream_formation)); 744eb7b3a05STakashi Sakamoto 745eb7b3a05STakashi Sakamoto for (e = 0; e < buf[4]; e++) { 746eb7b3a05STakashi Sakamoto channels = buf[5 + e * 2]; 747eb7b3a05STakashi Sakamoto format = buf[6 + e * 2]; 748eb7b3a05STakashi Sakamoto 749eb7b3a05STakashi Sakamoto switch (format) { 75051fa31d4STakashi Sakamoto /* IEC 60958 Conformant, currently handled as MBLA */ 751eb7b3a05STakashi Sakamoto case 0x00: 752eb7b3a05STakashi Sakamoto /* Multi bit linear audio */ 753eb7b3a05STakashi Sakamoto case 0x06: /* Raw */ 754eb7b3a05STakashi Sakamoto formation[i].pcm += channels; 755eb7b3a05STakashi Sakamoto break; 756eb7b3a05STakashi Sakamoto /* MIDI Conformant */ 757eb7b3a05STakashi Sakamoto case 0x0d: 758eb7b3a05STakashi Sakamoto formation[i].midi += channels; 759eb7b3a05STakashi Sakamoto break; 760eb7b3a05STakashi Sakamoto /* IEC 61937-3 to 7 */ 761eb7b3a05STakashi Sakamoto case 0x01: 762eb7b3a05STakashi Sakamoto case 0x02: 763eb7b3a05STakashi Sakamoto case 0x03: 764eb7b3a05STakashi Sakamoto case 0x04: 765eb7b3a05STakashi Sakamoto case 0x05: 766eb7b3a05STakashi Sakamoto /* Multi bit linear audio */ 767eb7b3a05STakashi Sakamoto case 0x07: /* DVD-Audio */ 768eb7b3a05STakashi Sakamoto case 0x0c: /* High Precision */ 769eb7b3a05STakashi Sakamoto /* One Bit Audio */ 770eb7b3a05STakashi Sakamoto case 0x08: /* (Plain) Raw */ 771eb7b3a05STakashi Sakamoto case 0x09: /* (Plain) SACD */ 772eb7b3a05STakashi Sakamoto case 0x0a: /* (Encoded) Raw */ 773eb7b3a05STakashi Sakamoto case 0x0b: /* (Encoded) SACD */ 774eb7b3a05STakashi Sakamoto /* Synchronization Stream (Stereo Raw audio) */ 775eb7b3a05STakashi Sakamoto case 0x40: 776eb7b3a05STakashi Sakamoto /* Don't care */ 777eb7b3a05STakashi Sakamoto case 0xff: 778eb7b3a05STakashi Sakamoto default: 779eb7b3a05STakashi Sakamoto return -ENOSYS; /* not supported */ 780eb7b3a05STakashi Sakamoto } 781eb7b3a05STakashi Sakamoto } 782eb7b3a05STakashi Sakamoto 78349c7b3fcSTakashi Sakamoto if (formation[i].pcm > AM824_MAX_CHANNELS_FOR_PCM || 78449c7b3fcSTakashi Sakamoto formation[i].midi > AM824_MAX_CHANNELS_FOR_MIDI) 785eb7b3a05STakashi Sakamoto return -ENOSYS; 786eb7b3a05STakashi Sakamoto 787eb7b3a05STakashi Sakamoto return 0; 788eb7b3a05STakashi Sakamoto } 789eb7b3a05STakashi Sakamoto 790caa27151STakashi Sakamoto static int fill_stream_formations(struct snd_bebob *bebob, u8 addr[AVC_BRIDGECO_ADDR_BYTES], 791caa27151STakashi Sakamoto enum avc_bridgeco_plug_dir plug_dir, unsigned int plug_id, 792caa27151STakashi Sakamoto struct snd_bebob_stream_formation *formations) 793eb7b3a05STakashi Sakamoto { 794caa27151STakashi Sakamoto enum avc_bridgeco_plug_type plug_type; 795eb7b3a05STakashi Sakamoto u8 *buf; 796eb7b3a05STakashi Sakamoto unsigned int len, eid; 797eb7b3a05STakashi Sakamoto int err; 798eb7b3a05STakashi Sakamoto 799caa27151STakashi Sakamoto avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id); 800caa27151STakashi Sakamoto 801caa27151STakashi Sakamoto err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type); 802caa27151STakashi Sakamoto if (err < 0) { 803caa27151STakashi Sakamoto dev_err(&bebob->unit->device, 804caa27151STakashi Sakamoto "Fail to get type for isoc %d plug 0: %d\n", plug_dir, err); 805caa27151STakashi Sakamoto return err; 806caa27151STakashi Sakamoto } else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_ISOC) 807caa27151STakashi Sakamoto return -ENXIO; 808caa27151STakashi Sakamoto 809eb7b3a05STakashi Sakamoto buf = kmalloc(FORMAT_MAXIMUM_LENGTH, GFP_KERNEL); 810eb7b3a05STakashi Sakamoto if (buf == NULL) 811eb7b3a05STakashi Sakamoto return -ENOMEM; 812eb7b3a05STakashi Sakamoto 813caa27151STakashi Sakamoto for (eid = 0; eid < SND_BEBOB_STRM_FMT_ENTRIES; ++eid) { 814caa27151STakashi Sakamoto avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id); 815eb7b3a05STakashi Sakamoto 816eb7b3a05STakashi Sakamoto len = FORMAT_MAXIMUM_LENGTH; 817caa27151STakashi Sakamoto err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf, &len, eid); 818caa27151STakashi Sakamoto // No entries remained. 819eb7b3a05STakashi Sakamoto if (err == -EINVAL && eid > 0) { 820eb7b3a05STakashi Sakamoto err = 0; 821eb7b3a05STakashi Sakamoto break; 822eb7b3a05STakashi Sakamoto } else if (err < 0) { 823eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 824caa27151STakashi Sakamoto "fail to get stream format %d for isoc %d plug %d:%d\n", 825caa27151STakashi Sakamoto eid, plug_dir, plug_id, err); 826eb7b3a05STakashi Sakamoto break; 827eb7b3a05STakashi Sakamoto } 828eb7b3a05STakashi Sakamoto 829eb7b3a05STakashi Sakamoto err = parse_stream_formation(buf, len, formations); 830eb7b3a05STakashi Sakamoto if (err < 0) 831eb7b3a05STakashi Sakamoto break; 832eb7b3a05STakashi Sakamoto } 833eb7b3a05STakashi Sakamoto 834eb7b3a05STakashi Sakamoto kfree(buf); 835eb7b3a05STakashi Sakamoto return err; 836eb7b3a05STakashi Sakamoto } 837eb7b3a05STakashi Sakamoto 8385c6ea94fSTakashi Sakamoto static int detect_midi_ports(struct snd_bebob *bebob, 8395c6ea94fSTakashi Sakamoto const struct snd_bebob_stream_formation *formats, 8405c6ea94fSTakashi Sakamoto u8 addr[AVC_BRIDGECO_ADDR_BYTES], enum avc_bridgeco_plug_dir plug_dir, 8415c6ea94fSTakashi Sakamoto unsigned int plug_count, unsigned int *midi_ports) 8425c6ea94fSTakashi Sakamoto { 8435c6ea94fSTakashi Sakamoto int i; 8445c6ea94fSTakashi Sakamoto int err = 0; 8455c6ea94fSTakashi Sakamoto 8465c6ea94fSTakashi Sakamoto *midi_ports = 0; 8475c6ea94fSTakashi Sakamoto 8485c6ea94fSTakashi Sakamoto /// Detect the number of available MIDI ports when packet has MIDI conformant data channel. 8495c6ea94fSTakashi Sakamoto for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; ++i) { 8505c6ea94fSTakashi Sakamoto if (formats[i].midi > 0) 8515c6ea94fSTakashi Sakamoto break; 8525c6ea94fSTakashi Sakamoto } 8535c6ea94fSTakashi Sakamoto if (i >= SND_BEBOB_STRM_FMT_ENTRIES) 8545c6ea94fSTakashi Sakamoto return 0; 8555c6ea94fSTakashi Sakamoto 8565c6ea94fSTakashi Sakamoto for (i = 0; i < plug_count; ++i) { 8575c6ea94fSTakashi Sakamoto enum avc_bridgeco_plug_type plug_type; 8585c6ea94fSTakashi Sakamoto unsigned int ch_count; 8595c6ea94fSTakashi Sakamoto 8605c6ea94fSTakashi Sakamoto avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_EXT, i); 8615c6ea94fSTakashi Sakamoto 8625c6ea94fSTakashi Sakamoto err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type); 8635c6ea94fSTakashi Sakamoto if (err < 0) { 8645c6ea94fSTakashi Sakamoto dev_err(&bebob->unit->device, 8655c6ea94fSTakashi Sakamoto "fail to get type for external %d plug %d: %d\n", 8665c6ea94fSTakashi Sakamoto plug_dir, i, err); 8675c6ea94fSTakashi Sakamoto break; 8685c6ea94fSTakashi Sakamoto } else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_MIDI) { 8695c6ea94fSTakashi Sakamoto continue; 8705c6ea94fSTakashi Sakamoto } 8715c6ea94fSTakashi Sakamoto 8725c6ea94fSTakashi Sakamoto err = avc_bridgeco_get_plug_ch_count(bebob->unit, addr, &ch_count); 8735c6ea94fSTakashi Sakamoto if (err < 0) 8745c6ea94fSTakashi Sakamoto break; 8755c6ea94fSTakashi Sakamoto *midi_ports += ch_count; 8765c6ea94fSTakashi Sakamoto } 8775c6ea94fSTakashi Sakamoto 8785c6ea94fSTakashi Sakamoto return err; 8795c6ea94fSTakashi Sakamoto } 8805c6ea94fSTakashi Sakamoto 881eb7b3a05STakashi Sakamoto static int 882eb7b3a05STakashi Sakamoto seek_msu_sync_input_plug(struct snd_bebob *bebob) 883eb7b3a05STakashi Sakamoto { 884eb7b3a05STakashi Sakamoto u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES]; 885a6b598bfSTakashi Sakamoto unsigned int i; 886a6b598bfSTakashi Sakamoto enum avc_bridgeco_plug_type type; 887eb7b3a05STakashi Sakamoto int err; 888eb7b3a05STakashi Sakamoto 889eb7b3a05STakashi Sakamoto /* Get the number of Music Sub Unit for both direction. */ 890eb7b3a05STakashi Sakamoto err = avc_general_get_plug_info(bebob->unit, 0x0c, 0x00, 0x00, plugs); 891eb7b3a05STakashi Sakamoto if (err < 0) { 892eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 893eb7b3a05STakashi Sakamoto "fail to get info for MSU in/out plugs: %d\n", 894eb7b3a05STakashi Sakamoto err); 895eb7b3a05STakashi Sakamoto goto end; 896eb7b3a05STakashi Sakamoto } 897eb7b3a05STakashi Sakamoto 898eb7b3a05STakashi Sakamoto /* seek destination plugs for 'MSU sync input' */ 899eb7b3a05STakashi Sakamoto bebob->sync_input_plug = -1; 900eb7b3a05STakashi Sakamoto for (i = 0; i < plugs[0]; i++) { 901eb7b3a05STakashi Sakamoto avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, i); 902eb7b3a05STakashi Sakamoto err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type); 903eb7b3a05STakashi Sakamoto if (err < 0) { 904eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 905eb7b3a05STakashi Sakamoto "fail to get type for MSU in plug %d: %d\n", 906eb7b3a05STakashi Sakamoto i, err); 907eb7b3a05STakashi Sakamoto goto end; 908eb7b3a05STakashi Sakamoto } 909eb7b3a05STakashi Sakamoto 910eb7b3a05STakashi Sakamoto if (type == AVC_BRIDGECO_PLUG_TYPE_SYNC) { 911eb7b3a05STakashi Sakamoto bebob->sync_input_plug = i; 912eb7b3a05STakashi Sakamoto break; 913eb7b3a05STakashi Sakamoto } 914eb7b3a05STakashi Sakamoto } 915eb7b3a05STakashi Sakamoto end: 916eb7b3a05STakashi Sakamoto return err; 917eb7b3a05STakashi Sakamoto } 918eb7b3a05STakashi Sakamoto 919eb7b3a05STakashi Sakamoto int snd_bebob_stream_discover(struct snd_bebob *bebob) 920eb7b3a05STakashi Sakamoto { 9216b9866c8SJulia Lawall const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock; 922eb7b3a05STakashi Sakamoto u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES]; 923eb7b3a05STakashi Sakamoto int err; 924eb7b3a05STakashi Sakamoto 925eb7b3a05STakashi Sakamoto /* the number of plugs for isoc in/out, ext in/out */ 926eb7b3a05STakashi Sakamoto err = avc_general_get_plug_info(bebob->unit, 0x1f, 0x07, 0x00, plugs); 927eb7b3a05STakashi Sakamoto if (err < 0) { 928eb7b3a05STakashi Sakamoto dev_err(&bebob->unit->device, 929eb7b3a05STakashi Sakamoto "fail to get info for isoc/external in/out plugs: %d\n", 930eb7b3a05STakashi Sakamoto err); 931eb7b3a05STakashi Sakamoto goto end; 932eb7b3a05STakashi Sakamoto } 933eb7b3a05STakashi Sakamoto 934eb7b3a05STakashi Sakamoto /* 935eb7b3a05STakashi Sakamoto * This module supports at least one isoc input plug and one isoc 936eb7b3a05STakashi Sakamoto * output plug. 937eb7b3a05STakashi Sakamoto */ 938eb7b3a05STakashi Sakamoto if ((plugs[0] == 0) || (plugs[1] == 0)) { 939eb7b3a05STakashi Sakamoto err = -ENOSYS; 940eb7b3a05STakashi Sakamoto goto end; 941eb7b3a05STakashi Sakamoto } 942eb7b3a05STakashi Sakamoto 943caa27151STakashi Sakamoto err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_IN, 0, 944caa27151STakashi Sakamoto bebob->rx_stream_formations); 945eb7b3a05STakashi Sakamoto if (err < 0) 946eb7b3a05STakashi Sakamoto goto end; 947eb7b3a05STakashi Sakamoto 948caa27151STakashi Sakamoto err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_OUT, 0, 949caa27151STakashi Sakamoto bebob->tx_stream_formations); 950eb7b3a05STakashi Sakamoto if (err < 0) 951eb7b3a05STakashi Sakamoto goto end; 952eb7b3a05STakashi Sakamoto 9535c6ea94fSTakashi Sakamoto err = detect_midi_ports(bebob, bebob->rx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_IN, 9545c6ea94fSTakashi Sakamoto plugs[2], &bebob->midi_input_ports); 9555c6ea94fSTakashi Sakamoto if (err < 0) 956eb7b3a05STakashi Sakamoto goto end; 957eb7b3a05STakashi Sakamoto 9585c6ea94fSTakashi Sakamoto err = detect_midi_ports(bebob, bebob->tx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_OUT, 9595c6ea94fSTakashi Sakamoto plugs[3], &bebob->midi_output_ports); 9605c6ea94fSTakashi Sakamoto if (err < 0) 961eb7b3a05STakashi Sakamoto goto end; 962eb7b3a05STakashi Sakamoto 963eb7b3a05STakashi Sakamoto /* for check source of clock later */ 9641fc9522aSTakashi Sakamoto if (!clk_spec) 965eb7b3a05STakashi Sakamoto err = seek_msu_sync_input_plug(bebob); 966eb7b3a05STakashi Sakamoto end: 967eb7b3a05STakashi Sakamoto return err; 968eb7b3a05STakashi Sakamoto } 969618eabeaSTakashi Sakamoto 970618eabeaSTakashi Sakamoto void snd_bebob_stream_lock_changed(struct snd_bebob *bebob) 971618eabeaSTakashi Sakamoto { 972618eabeaSTakashi Sakamoto bebob->dev_lock_changed = true; 973618eabeaSTakashi Sakamoto wake_up(&bebob->hwdep_wait); 974618eabeaSTakashi Sakamoto } 975618eabeaSTakashi Sakamoto 976618eabeaSTakashi Sakamoto int snd_bebob_stream_lock_try(struct snd_bebob *bebob) 977618eabeaSTakashi Sakamoto { 978618eabeaSTakashi Sakamoto int err; 979618eabeaSTakashi Sakamoto 980618eabeaSTakashi Sakamoto spin_lock_irq(&bebob->lock); 981618eabeaSTakashi Sakamoto 982618eabeaSTakashi Sakamoto /* user land lock this */ 983618eabeaSTakashi Sakamoto if (bebob->dev_lock_count < 0) { 984618eabeaSTakashi Sakamoto err = -EBUSY; 985618eabeaSTakashi Sakamoto goto end; 986618eabeaSTakashi Sakamoto } 987618eabeaSTakashi Sakamoto 988618eabeaSTakashi Sakamoto /* this is the first time */ 989618eabeaSTakashi Sakamoto if (bebob->dev_lock_count++ == 0) 990618eabeaSTakashi Sakamoto snd_bebob_stream_lock_changed(bebob); 991618eabeaSTakashi Sakamoto err = 0; 992618eabeaSTakashi Sakamoto end: 993618eabeaSTakashi Sakamoto spin_unlock_irq(&bebob->lock); 994618eabeaSTakashi Sakamoto return err; 995618eabeaSTakashi Sakamoto } 996618eabeaSTakashi Sakamoto 997618eabeaSTakashi Sakamoto void snd_bebob_stream_lock_release(struct snd_bebob *bebob) 998618eabeaSTakashi Sakamoto { 999618eabeaSTakashi Sakamoto spin_lock_irq(&bebob->lock); 1000618eabeaSTakashi Sakamoto 1001618eabeaSTakashi Sakamoto if (WARN_ON(bebob->dev_lock_count <= 0)) 1002618eabeaSTakashi Sakamoto goto end; 1003618eabeaSTakashi Sakamoto if (--bebob->dev_lock_count == 0) 1004618eabeaSTakashi Sakamoto snd_bebob_stream_lock_changed(bebob); 1005618eabeaSTakashi Sakamoto end: 1006618eabeaSTakashi Sakamoto spin_unlock_irq(&bebob->lock); 1007618eabeaSTakashi Sakamoto } 1008