1da607e19SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 26eb6c81eSTakashi Sakamoto /* 36eb6c81eSTakashi Sakamoto * dice_stream.c - a part of driver for DICE based devices 46eb6c81eSTakashi Sakamoto * 56eb6c81eSTakashi Sakamoto * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 66eb6c81eSTakashi Sakamoto * Copyright (c) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp> 76eb6c81eSTakashi Sakamoto */ 86eb6c81eSTakashi Sakamoto 96eb6c81eSTakashi Sakamoto #include "dice.h" 106eb6c81eSTakashi Sakamoto 11288a8d0cSTakashi Sakamoto #define CALLBACK_TIMEOUT 200 12dfabc0eeSTakashi Sakamoto #define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC) 13288a8d0cSTakashi Sakamoto 148cc1a8abSTakashi Sakamoto struct reg_params { 158cc1a8abSTakashi Sakamoto unsigned int count; 168cc1a8abSTakashi Sakamoto unsigned int size; 178cc1a8abSTakashi Sakamoto }; 188cc1a8abSTakashi Sakamoto 196eb6c81eSTakashi Sakamoto const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = { 206eb6c81eSTakashi Sakamoto /* mode 0 */ 216eb6c81eSTakashi Sakamoto [0] = 32000, 226eb6c81eSTakashi Sakamoto [1] = 44100, 236eb6c81eSTakashi Sakamoto [2] = 48000, 246eb6c81eSTakashi Sakamoto /* mode 1 */ 256eb6c81eSTakashi Sakamoto [3] = 88200, 266eb6c81eSTakashi Sakamoto [4] = 96000, 276eb6c81eSTakashi Sakamoto /* mode 2 */ 286eb6c81eSTakashi Sakamoto [5] = 176400, 296eb6c81eSTakashi Sakamoto [6] = 192000, 306eb6c81eSTakashi Sakamoto }; 316eb6c81eSTakashi Sakamoto 32b60152f7STakashi Sakamoto int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate, 33b60152f7STakashi Sakamoto enum snd_dice_rate_mode *mode) 34b60152f7STakashi Sakamoto { 35b60152f7STakashi Sakamoto /* Corresponding to each entry in snd_dice_rates. */ 36b60152f7STakashi Sakamoto static const enum snd_dice_rate_mode modes[] = { 37b60152f7STakashi Sakamoto [0] = SND_DICE_RATE_MODE_LOW, 38b60152f7STakashi Sakamoto [1] = SND_DICE_RATE_MODE_LOW, 39b60152f7STakashi Sakamoto [2] = SND_DICE_RATE_MODE_LOW, 40b60152f7STakashi Sakamoto [3] = SND_DICE_RATE_MODE_MIDDLE, 41b60152f7STakashi Sakamoto [4] = SND_DICE_RATE_MODE_MIDDLE, 42b60152f7STakashi Sakamoto [5] = SND_DICE_RATE_MODE_HIGH, 43b60152f7STakashi Sakamoto [6] = SND_DICE_RATE_MODE_HIGH, 44b60152f7STakashi Sakamoto }; 45b60152f7STakashi Sakamoto int i; 46b60152f7STakashi Sakamoto 47b60152f7STakashi Sakamoto for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) { 48b60152f7STakashi Sakamoto if (!(dice->clock_caps & BIT(i))) 49b60152f7STakashi Sakamoto continue; 50b60152f7STakashi Sakamoto if (snd_dice_rates[i] != rate) 51b60152f7STakashi Sakamoto continue; 52b60152f7STakashi Sakamoto 53b60152f7STakashi Sakamoto *mode = modes[i]; 54b60152f7STakashi Sakamoto return 0; 55b60152f7STakashi Sakamoto } 56b60152f7STakashi Sakamoto 57b60152f7STakashi Sakamoto return -EINVAL; 58b60152f7STakashi Sakamoto } 59b60152f7STakashi Sakamoto 60dfabc0eeSTakashi Sakamoto /* 61dfabc0eeSTakashi Sakamoto * This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE 62dfabc0eeSTakashi Sakamoto * to GLOBAL_STATUS. Especially, just after powering on, these are different. 63dfabc0eeSTakashi Sakamoto */ 64afa617f2STakashi Sakamoto static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate) 65dfabc0eeSTakashi Sakamoto { 66fbeac84dSTakashi Sakamoto __be32 reg, nominal; 67afa617f2STakashi Sakamoto u32 data; 68afa617f2STakashi Sakamoto int i; 69dfabc0eeSTakashi Sakamoto int err; 70dfabc0eeSTakashi Sakamoto 71dfabc0eeSTakashi Sakamoto err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT, 72dfabc0eeSTakashi Sakamoto ®, sizeof(reg)); 73dfabc0eeSTakashi Sakamoto if (err < 0) 74dfabc0eeSTakashi Sakamoto return err; 75dfabc0eeSTakashi Sakamoto 76afa617f2STakashi Sakamoto data = be32_to_cpu(reg); 77afa617f2STakashi Sakamoto 78afa617f2STakashi Sakamoto data &= ~CLOCK_RATE_MASK; 79afa617f2STakashi Sakamoto for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { 80afa617f2STakashi Sakamoto if (snd_dice_rates[i] == rate) 81afa617f2STakashi Sakamoto break; 82afa617f2STakashi Sakamoto } 83afa617f2STakashi Sakamoto if (i == ARRAY_SIZE(snd_dice_rates)) 84afa617f2STakashi Sakamoto return -EINVAL; 85afa617f2STakashi Sakamoto data |= i << CLOCK_RATE_SHIFT; 86afa617f2STakashi Sakamoto 87dfabc0eeSTakashi Sakamoto if (completion_done(&dice->clock_accepted)) 88dfabc0eeSTakashi Sakamoto reinit_completion(&dice->clock_accepted); 89dfabc0eeSTakashi Sakamoto 90afa617f2STakashi Sakamoto reg = cpu_to_be32(data); 91dfabc0eeSTakashi Sakamoto err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT, 92dfabc0eeSTakashi Sakamoto ®, sizeof(reg)); 93dfabc0eeSTakashi Sakamoto if (err < 0) 94dfabc0eeSTakashi Sakamoto return err; 95dfabc0eeSTakashi Sakamoto 96dfabc0eeSTakashi Sakamoto if (wait_for_completion_timeout(&dice->clock_accepted, 97fbeac84dSTakashi Sakamoto msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) { 98fbeac84dSTakashi Sakamoto /* 99fbeac84dSTakashi Sakamoto * Old versions of Dice firmware transfer no notification when 100fbeac84dSTakashi Sakamoto * the same clock status as current one is set. In this case, 101fbeac84dSTakashi Sakamoto * just check current clock status. 102fbeac84dSTakashi Sakamoto */ 103fbeac84dSTakashi Sakamoto err = snd_dice_transaction_read_global(dice, GLOBAL_STATUS, 104fbeac84dSTakashi Sakamoto &nominal, sizeof(nominal)); 105fbeac84dSTakashi Sakamoto if (err < 0) 106fbeac84dSTakashi Sakamoto return err; 107fbeac84dSTakashi Sakamoto if (!(be32_to_cpu(nominal) & STATUS_SOURCE_LOCKED)) 108dfabc0eeSTakashi Sakamoto return -ETIMEDOUT; 109fbeac84dSTakashi Sakamoto } 110dfabc0eeSTakashi Sakamoto 111dfabc0eeSTakashi Sakamoto return 0; 112dfabc0eeSTakashi Sakamoto } 113dfabc0eeSTakashi Sakamoto 1148cc1a8abSTakashi Sakamoto static int get_register_params(struct snd_dice *dice, 1158cc1a8abSTakashi Sakamoto struct reg_params *tx_params, 1168cc1a8abSTakashi Sakamoto struct reg_params *rx_params) 1176eb6c81eSTakashi Sakamoto { 118436b5abeSTakashi Sakamoto __be32 reg[2]; 119436b5abeSTakashi Sakamoto int err; 1206eb6c81eSTakashi Sakamoto 121436b5abeSTakashi Sakamoto err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg, sizeof(reg)); 122436b5abeSTakashi Sakamoto if (err < 0) 123436b5abeSTakashi Sakamoto return err; 1248cc1a8abSTakashi Sakamoto tx_params->count = 1258cc1a8abSTakashi Sakamoto min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS); 1268cc1a8abSTakashi Sakamoto tx_params->size = be32_to_cpu(reg[1]) * 4; 127288a8d0cSTakashi Sakamoto 128436b5abeSTakashi Sakamoto err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg, sizeof(reg)); 129436b5abeSTakashi Sakamoto if (err < 0) 130436b5abeSTakashi Sakamoto return err; 1318cc1a8abSTakashi Sakamoto rx_params->count = 1328cc1a8abSTakashi Sakamoto min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS); 1338cc1a8abSTakashi Sakamoto rx_params->size = be32_to_cpu(reg[1]) * 4; 134436b5abeSTakashi Sakamoto 135436b5abeSTakashi Sakamoto return 0; 136436b5abeSTakashi Sakamoto } 137436b5abeSTakashi Sakamoto 138436b5abeSTakashi Sakamoto static void release_resources(struct snd_dice *dice) 139436b5abeSTakashi Sakamoto { 140436b5abeSTakashi Sakamoto unsigned int i; 141436b5abeSTakashi Sakamoto 142436b5abeSTakashi Sakamoto for (i = 0; i < MAX_STREAMS; i++) { 143436b5abeSTakashi Sakamoto if (amdtp_stream_running(&dice->tx_stream[i])) { 144436b5abeSTakashi Sakamoto amdtp_stream_pcm_abort(&dice->tx_stream[i]); 145436b5abeSTakashi Sakamoto amdtp_stream_stop(&dice->tx_stream[i]); 146436b5abeSTakashi Sakamoto } 147436b5abeSTakashi Sakamoto if (amdtp_stream_running(&dice->rx_stream[i])) { 148436b5abeSTakashi Sakamoto amdtp_stream_pcm_abort(&dice->rx_stream[i]); 149436b5abeSTakashi Sakamoto amdtp_stream_stop(&dice->rx_stream[i]); 150436b5abeSTakashi Sakamoto } 151436b5abeSTakashi Sakamoto 152436b5abeSTakashi Sakamoto fw_iso_resources_free(&dice->tx_resources[i]); 153436b5abeSTakashi Sakamoto fw_iso_resources_free(&dice->rx_resources[i]); 154436b5abeSTakashi Sakamoto } 155436b5abeSTakashi Sakamoto } 156436b5abeSTakashi Sakamoto 157436b5abeSTakashi Sakamoto static void stop_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, 1588cc1a8abSTakashi Sakamoto struct reg_params *params) 159436b5abeSTakashi Sakamoto { 160436b5abeSTakashi Sakamoto __be32 reg; 161436b5abeSTakashi Sakamoto unsigned int i; 162436b5abeSTakashi Sakamoto 1638cc1a8abSTakashi Sakamoto for (i = 0; i < params->count; i++) { 164436b5abeSTakashi Sakamoto reg = cpu_to_be32((u32)-1); 165436b5abeSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 166436b5abeSTakashi Sakamoto snd_dice_transaction_write_tx(dice, 1678cc1a8abSTakashi Sakamoto params->size * i + TX_ISOCHRONOUS, 168436b5abeSTakashi Sakamoto ®, sizeof(reg)); 169436b5abeSTakashi Sakamoto } else { 170436b5abeSTakashi Sakamoto snd_dice_transaction_write_rx(dice, 1718cc1a8abSTakashi Sakamoto params->size * i + RX_ISOCHRONOUS, 172436b5abeSTakashi Sakamoto ®, sizeof(reg)); 173436b5abeSTakashi Sakamoto } 174436b5abeSTakashi Sakamoto } 175288a8d0cSTakashi Sakamoto } 176288a8d0cSTakashi Sakamoto 1779a02843cSTakashi Sakamoto static int keep_resources(struct snd_dice *dice, 178436b5abeSTakashi Sakamoto enum amdtp_stream_direction dir, unsigned int index, 179436b5abeSTakashi Sakamoto unsigned int rate, unsigned int pcm_chs, 180436b5abeSTakashi Sakamoto unsigned int midi_ports) 181288a8d0cSTakashi Sakamoto { 182436b5abeSTakashi Sakamoto struct amdtp_stream *stream; 1839a02843cSTakashi Sakamoto struct fw_iso_resources *resources; 18427ec83b5STakashi Sakamoto bool double_pcm_frames; 185436b5abeSTakashi Sakamoto unsigned int i; 186288a8d0cSTakashi Sakamoto int err; 187288a8d0cSTakashi Sakamoto 188436b5abeSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 189436b5abeSTakashi Sakamoto stream = &dice->tx_stream[index]; 190436b5abeSTakashi Sakamoto resources = &dice->tx_resources[index]; 1919a02843cSTakashi Sakamoto } else { 192436b5abeSTakashi Sakamoto stream = &dice->rx_stream[index]; 193436b5abeSTakashi Sakamoto resources = &dice->rx_resources[index]; 1949a02843cSTakashi Sakamoto } 195288a8d0cSTakashi Sakamoto 196288a8d0cSTakashi Sakamoto /* 197288a8d0cSTakashi Sakamoto * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in 198288a8d0cSTakashi Sakamoto * one data block of AMDTP packet. Thus sampling transfer frequency is 199288a8d0cSTakashi Sakamoto * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are 200288a8d0cSTakashi Sakamoto * transferred on AMDTP packets at 96 kHz. Two successive samples of a 201288a8d0cSTakashi Sakamoto * channel are stored consecutively in the packet. This quirk is called 202288a8d0cSTakashi Sakamoto * as 'Dual Wire'. 203288a8d0cSTakashi Sakamoto * For this quirk, blocking mode is required and PCM buffer size should 204288a8d0cSTakashi Sakamoto * be aligned to SYT_INTERVAL. 205288a8d0cSTakashi Sakamoto */ 2066f688268STakashi Sakamoto double_pcm_frames = rate > 96000; 20727ec83b5STakashi Sakamoto if (double_pcm_frames) { 208288a8d0cSTakashi Sakamoto rate /= 2; 209288a8d0cSTakashi Sakamoto pcm_chs *= 2; 210288a8d0cSTakashi Sakamoto } 211288a8d0cSTakashi Sakamoto 21251c29fd2STakashi Sakamoto err = amdtp_am824_set_parameters(stream, rate, pcm_chs, midi_ports, 21351c29fd2STakashi Sakamoto double_pcm_frames); 214547e631cSTakashi Sakamoto if (err < 0) 215436b5abeSTakashi Sakamoto return err; 216547e631cSTakashi Sakamoto 21727ec83b5STakashi Sakamoto if (double_pcm_frames) { 218288a8d0cSTakashi Sakamoto pcm_chs /= 2; 219288a8d0cSTakashi Sakamoto 220288a8d0cSTakashi Sakamoto for (i = 0; i < pcm_chs; i++) { 221f65be911STakashi Sakamoto amdtp_am824_set_pcm_position(stream, i, i * 2); 222f65be911STakashi Sakamoto amdtp_am824_set_pcm_position(stream, i + pcm_chs, 223f65be911STakashi Sakamoto i * 2 + 1); 224288a8d0cSTakashi Sakamoto } 225288a8d0cSTakashi Sakamoto } 226288a8d0cSTakashi Sakamoto 227436b5abeSTakashi Sakamoto return fw_iso_resources_allocate(resources, 228436b5abeSTakashi Sakamoto amdtp_stream_get_max_payload(stream), 229436b5abeSTakashi Sakamoto fw_parent_device(dice->unit)->max_speed); 230288a8d0cSTakashi Sakamoto } 231288a8d0cSTakashi Sakamoto 232436b5abeSTakashi Sakamoto static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, 2338cc1a8abSTakashi Sakamoto unsigned int rate, struct reg_params *params) 234436b5abeSTakashi Sakamoto { 235436b5abeSTakashi Sakamoto __be32 reg[2]; 236afa617f2STakashi Sakamoto enum snd_dice_rate_mode mode; 237436b5abeSTakashi Sakamoto unsigned int i, pcm_chs, midi_ports; 238436b5abeSTakashi Sakamoto struct amdtp_stream *streams; 239436b5abeSTakashi Sakamoto struct fw_iso_resources *resources; 240b0e159feSTakashi Sakamoto struct fw_device *fw_dev = fw_parent_device(dice->unit); 241436b5abeSTakashi Sakamoto int err = 0; 242436b5abeSTakashi Sakamoto 243436b5abeSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 244436b5abeSTakashi Sakamoto streams = dice->tx_stream; 245436b5abeSTakashi Sakamoto resources = dice->tx_resources; 246436b5abeSTakashi Sakamoto } else { 247436b5abeSTakashi Sakamoto streams = dice->rx_stream; 248436b5abeSTakashi Sakamoto resources = dice->rx_resources; 249436b5abeSTakashi Sakamoto } 250436b5abeSTakashi Sakamoto 251afa617f2STakashi Sakamoto err = snd_dice_stream_get_rate_mode(dice, rate, &mode); 252afa617f2STakashi Sakamoto if (err < 0) 253afa617f2STakashi Sakamoto return err; 254afa617f2STakashi Sakamoto 2558cc1a8abSTakashi Sakamoto for (i = 0; i < params->count; i++) { 256afa617f2STakashi Sakamoto unsigned int pcm_cache; 257afa617f2STakashi Sakamoto unsigned int midi_cache; 258afa617f2STakashi Sakamoto 259436b5abeSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 260afa617f2STakashi Sakamoto pcm_cache = dice->tx_pcm_chs[i][mode]; 261afa617f2STakashi Sakamoto midi_cache = dice->tx_midi_ports[i]; 262436b5abeSTakashi Sakamoto err = snd_dice_transaction_read_tx(dice, 2638cc1a8abSTakashi Sakamoto params->size * i + TX_NUMBER_AUDIO, 264436b5abeSTakashi Sakamoto reg, sizeof(reg)); 265436b5abeSTakashi Sakamoto } else { 266afa617f2STakashi Sakamoto pcm_cache = dice->rx_pcm_chs[i][mode]; 267afa617f2STakashi Sakamoto midi_cache = dice->rx_midi_ports[i]; 268436b5abeSTakashi Sakamoto err = snd_dice_transaction_read_rx(dice, 2698cc1a8abSTakashi Sakamoto params->size * i + RX_NUMBER_AUDIO, 270436b5abeSTakashi Sakamoto reg, sizeof(reg)); 271436b5abeSTakashi Sakamoto } 272436b5abeSTakashi Sakamoto if (err < 0) 273436b5abeSTakashi Sakamoto return err; 274436b5abeSTakashi Sakamoto pcm_chs = be32_to_cpu(reg[0]); 275436b5abeSTakashi Sakamoto midi_ports = be32_to_cpu(reg[1]); 276436b5abeSTakashi Sakamoto 277afa617f2STakashi Sakamoto /* These are important for developer of this driver. */ 278afa617f2STakashi Sakamoto if (pcm_chs != pcm_cache || midi_ports != midi_cache) { 279afa617f2STakashi Sakamoto dev_info(&dice->unit->device, 280afa617f2STakashi Sakamoto "cache mismatch: pcm: %u:%u, midi: %u:%u\n", 281afa617f2STakashi Sakamoto pcm_chs, pcm_cache, midi_ports, midi_cache); 282afa617f2STakashi Sakamoto return -EPROTO; 283afa617f2STakashi Sakamoto } 284afa617f2STakashi Sakamoto 285436b5abeSTakashi Sakamoto err = keep_resources(dice, dir, i, rate, pcm_chs, midi_ports); 286436b5abeSTakashi Sakamoto if (err < 0) 287436b5abeSTakashi Sakamoto return err; 288436b5abeSTakashi Sakamoto 289436b5abeSTakashi Sakamoto reg[0] = cpu_to_be32(resources[i].channel); 290436b5abeSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 291436b5abeSTakashi Sakamoto err = snd_dice_transaction_write_tx(dice, 2928cc1a8abSTakashi Sakamoto params->size * i + TX_ISOCHRONOUS, 293436b5abeSTakashi Sakamoto reg, sizeof(reg[0])); 294436b5abeSTakashi Sakamoto } else { 295436b5abeSTakashi Sakamoto err = snd_dice_transaction_write_rx(dice, 2968cc1a8abSTakashi Sakamoto params->size * i + RX_ISOCHRONOUS, 297436b5abeSTakashi Sakamoto reg, sizeof(reg[0])); 298436b5abeSTakashi Sakamoto } 299436b5abeSTakashi Sakamoto if (err < 0) 300436b5abeSTakashi Sakamoto return err; 301436b5abeSTakashi Sakamoto 302b0e159feSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 303b0e159feSTakashi Sakamoto reg[0] = cpu_to_be32(fw_dev->max_speed); 304b0e159feSTakashi Sakamoto err = snd_dice_transaction_write_tx(dice, 305b0e159feSTakashi Sakamoto params->size * i + TX_SPEED, 306b0e159feSTakashi Sakamoto reg, sizeof(reg[0])); 307b0e159feSTakashi Sakamoto if (err < 0) 308b0e159feSTakashi Sakamoto return err; 309b0e159feSTakashi Sakamoto } 310b0e159feSTakashi Sakamoto 311436b5abeSTakashi Sakamoto err = amdtp_stream_start(&streams[i], resources[i].channel, 312b0e159feSTakashi Sakamoto fw_dev->max_speed); 313288a8d0cSTakashi Sakamoto if (err < 0) 314288a8d0cSTakashi Sakamoto return err; 315288a8d0cSTakashi Sakamoto } 316288a8d0cSTakashi Sakamoto 317436b5abeSTakashi Sakamoto return err; 318436b5abeSTakashi Sakamoto } 319436b5abeSTakashi Sakamoto 32020b94544STakashi Sakamoto static int start_duplex_streams(struct snd_dice *dice, unsigned int rate) 32120b94544STakashi Sakamoto { 32220b94544STakashi Sakamoto struct reg_params tx_params, rx_params; 32320b94544STakashi Sakamoto int i; 32420b94544STakashi Sakamoto int err; 32520b94544STakashi Sakamoto 32620b94544STakashi Sakamoto err = get_register_params(dice, &tx_params, &rx_params); 32720b94544STakashi Sakamoto if (err < 0) 32820b94544STakashi Sakamoto return err; 32920b94544STakashi Sakamoto 33020b94544STakashi Sakamoto /* Stop transmission. */ 33120b94544STakashi Sakamoto stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 33220b94544STakashi Sakamoto stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 33320b94544STakashi Sakamoto snd_dice_transaction_clear_enable(dice); 33420b94544STakashi Sakamoto release_resources(dice); 33520b94544STakashi Sakamoto 336afa617f2STakashi Sakamoto err = ensure_phase_lock(dice, rate); 33720b94544STakashi Sakamoto if (err < 0) { 33820b94544STakashi Sakamoto dev_err(&dice->unit->device, "fail to ensure phase lock\n"); 33920b94544STakashi Sakamoto return err; 34020b94544STakashi Sakamoto } 34120b94544STakashi Sakamoto 342afa617f2STakashi Sakamoto /* Likely to have changed stream formats. */ 343afa617f2STakashi Sakamoto err = get_register_params(dice, &tx_params, &rx_params); 344afa617f2STakashi Sakamoto if (err < 0) 345afa617f2STakashi Sakamoto return err; 346afa617f2STakashi Sakamoto 34720b94544STakashi Sakamoto /* Start both streams. */ 34820b94544STakashi Sakamoto err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params); 34920b94544STakashi Sakamoto if (err < 0) 35020b94544STakashi Sakamoto goto error; 35120b94544STakashi Sakamoto err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params); 35220b94544STakashi Sakamoto if (err < 0) 35320b94544STakashi Sakamoto goto error; 35420b94544STakashi Sakamoto 35520b94544STakashi Sakamoto err = snd_dice_transaction_set_enable(dice); 35620b94544STakashi Sakamoto if (err < 0) { 35720b94544STakashi Sakamoto dev_err(&dice->unit->device, "fail to enable interface\n"); 35820b94544STakashi Sakamoto goto error; 35920b94544STakashi Sakamoto } 36020b94544STakashi Sakamoto 36120b94544STakashi Sakamoto for (i = 0; i < MAX_STREAMS; i++) { 36220b94544STakashi Sakamoto if ((i < tx_params.count && 36320b94544STakashi Sakamoto !amdtp_stream_wait_callback(&dice->tx_stream[i], 36420b94544STakashi Sakamoto CALLBACK_TIMEOUT)) || 36520b94544STakashi Sakamoto (i < rx_params.count && 36620b94544STakashi Sakamoto !amdtp_stream_wait_callback(&dice->rx_stream[i], 36720b94544STakashi Sakamoto CALLBACK_TIMEOUT))) { 36820b94544STakashi Sakamoto err = -ETIMEDOUT; 36920b94544STakashi Sakamoto goto error; 37020b94544STakashi Sakamoto } 37120b94544STakashi Sakamoto } 37220b94544STakashi Sakamoto 37320b94544STakashi Sakamoto return 0; 37420b94544STakashi Sakamoto error: 37520b94544STakashi Sakamoto stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 37620b94544STakashi Sakamoto stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 37720b94544STakashi Sakamoto snd_dice_transaction_clear_enable(dice); 37820b94544STakashi Sakamoto release_resources(dice); 37920b94544STakashi Sakamoto return err; 38020b94544STakashi Sakamoto } 38120b94544STakashi Sakamoto 382436b5abeSTakashi Sakamoto /* 383436b5abeSTakashi Sakamoto * MEMO: After this function, there're two states of streams: 384436b5abeSTakashi Sakamoto * - None streams are running. 385436b5abeSTakashi Sakamoto * - All streams are running. 386436b5abeSTakashi Sakamoto */ 3879a02843cSTakashi Sakamoto int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate) 3889a02843cSTakashi Sakamoto { 389288a8d0cSTakashi Sakamoto unsigned int curr_rate; 390436b5abeSTakashi Sakamoto unsigned int i; 391ec592fd3STakashi Sakamoto enum snd_dice_rate_mode mode; 392436b5abeSTakashi Sakamoto int err; 3939a02843cSTakashi Sakamoto 3949a02843cSTakashi Sakamoto if (dice->substreams_counter == 0) 395436b5abeSTakashi Sakamoto return -EIO; 3969a02843cSTakashi Sakamoto 397ec592fd3STakashi Sakamoto /* Check sampling transmission frequency. */ 398288a8d0cSTakashi Sakamoto err = snd_dice_transaction_get_rate(dice, &curr_rate); 399288a8d0cSTakashi Sakamoto if (err < 0) { 400288a8d0cSTakashi Sakamoto dev_err(&dice->unit->device, 401288a8d0cSTakashi Sakamoto "fail to get sampling rate\n"); 402436b5abeSTakashi Sakamoto return err; 403288a8d0cSTakashi Sakamoto } 404a113ff88STakashi Sakamoto if (rate == 0) 405a113ff88STakashi Sakamoto rate = curr_rate; 406436b5abeSTakashi Sakamoto if (rate != curr_rate) 407afa617f2STakashi Sakamoto goto restart; 408288a8d0cSTakashi Sakamoto 409ec592fd3STakashi Sakamoto /* Check error of packet streaming. */ 410ec592fd3STakashi Sakamoto for (i = 0; i < MAX_STREAMS; ++i) { 411ec592fd3STakashi Sakamoto if (amdtp_streaming_error(&dice->tx_stream[i])) 412ec592fd3STakashi Sakamoto break; 413ec592fd3STakashi Sakamoto if (amdtp_streaming_error(&dice->rx_stream[i])) 414436b5abeSTakashi Sakamoto break; 415436b5abeSTakashi Sakamoto } 416ec592fd3STakashi Sakamoto if (i < MAX_STREAMS) 41720b94544STakashi Sakamoto goto restart; 418ec592fd3STakashi Sakamoto 419ec592fd3STakashi Sakamoto /* Check required streams are running or not. */ 420ec592fd3STakashi Sakamoto err = snd_dice_stream_get_rate_mode(dice, rate, &mode); 421ec592fd3STakashi Sakamoto if (err < 0) 422ec592fd3STakashi Sakamoto return err; 423ec592fd3STakashi Sakamoto for (i = 0; i < MAX_STREAMS; ++i) { 424ec592fd3STakashi Sakamoto if (dice->tx_pcm_chs[i][mode] > 0 && 425ec592fd3STakashi Sakamoto !amdtp_stream_running(&dice->tx_stream[i])) 426ec592fd3STakashi Sakamoto break; 427ec592fd3STakashi Sakamoto if (dice->rx_pcm_chs[i][mode] > 0 && 428436b5abeSTakashi Sakamoto !amdtp_stream_running(&dice->rx_stream[i])) 429436b5abeSTakashi Sakamoto break; 430436b5abeSTakashi Sakamoto } 431ec592fd3STakashi Sakamoto if (i < MAX_STREAMS) 43220b94544STakashi Sakamoto goto restart; 433436b5abeSTakashi Sakamoto 43420b94544STakashi Sakamoto return 0; 43520b94544STakashi Sakamoto restart: 43620b94544STakashi Sakamoto return start_duplex_streams(dice, rate); 4376eb6c81eSTakashi Sakamoto } 4386eb6c81eSTakashi Sakamoto 439436b5abeSTakashi Sakamoto /* 440436b5abeSTakashi Sakamoto * MEMO: After this function, there're two states of streams: 441436b5abeSTakashi Sakamoto * - None streams are running. 442436b5abeSTakashi Sakamoto * - All streams are running. 443436b5abeSTakashi Sakamoto */ 4449a02843cSTakashi Sakamoto void snd_dice_stream_stop_duplex(struct snd_dice *dice) 4456eb6c81eSTakashi Sakamoto { 4468cc1a8abSTakashi Sakamoto struct reg_params tx_params, rx_params; 447436b5abeSTakashi Sakamoto 4489a02843cSTakashi Sakamoto if (dice->substreams_counter > 0) 4499a02843cSTakashi Sakamoto return; 4509a02843cSTakashi Sakamoto 451288a8d0cSTakashi Sakamoto snd_dice_transaction_clear_enable(dice); 4529a02843cSTakashi Sakamoto 4538cc1a8abSTakashi Sakamoto if (get_register_params(dice, &tx_params, &rx_params) == 0) { 4548cc1a8abSTakashi Sakamoto stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 4558cc1a8abSTakashi Sakamoto stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 4566eb6c81eSTakashi Sakamoto } 4576eb6c81eSTakashi Sakamoto 458436b5abeSTakashi Sakamoto release_resources(dice); 459436b5abeSTakashi Sakamoto } 4609a02843cSTakashi Sakamoto 461436b5abeSTakashi Sakamoto static int init_stream(struct snd_dice *dice, enum amdtp_stream_direction dir, 462436b5abeSTakashi Sakamoto unsigned int index) 463436b5abeSTakashi Sakamoto { 464436b5abeSTakashi Sakamoto struct amdtp_stream *stream; 465436b5abeSTakashi Sakamoto struct fw_iso_resources *resources; 466436b5abeSTakashi Sakamoto int err; 467436b5abeSTakashi Sakamoto 468436b5abeSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 469436b5abeSTakashi Sakamoto stream = &dice->tx_stream[index]; 470436b5abeSTakashi Sakamoto resources = &dice->tx_resources[index]; 4719a02843cSTakashi Sakamoto } else { 472436b5abeSTakashi Sakamoto stream = &dice->rx_stream[index]; 473436b5abeSTakashi Sakamoto resources = &dice->rx_resources[index]; 4749a02843cSTakashi Sakamoto } 4759a02843cSTakashi Sakamoto 4769a02843cSTakashi Sakamoto err = fw_iso_resources_init(resources, dice->unit); 4779a02843cSTakashi Sakamoto if (err < 0) 4789a02843cSTakashi Sakamoto goto end; 4799a02843cSTakashi Sakamoto resources->channels_mask = 0x00000000ffffffffuLL; 4809a02843cSTakashi Sakamoto 4815955815eSTakashi Sakamoto err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING); 4829a02843cSTakashi Sakamoto if (err < 0) { 4839a02843cSTakashi Sakamoto amdtp_stream_destroy(stream); 4849a02843cSTakashi Sakamoto fw_iso_resources_destroy(resources); 4859a02843cSTakashi Sakamoto } 4869a02843cSTakashi Sakamoto end: 4879a02843cSTakashi Sakamoto return err; 4889a02843cSTakashi Sakamoto } 4899a02843cSTakashi Sakamoto 490d23c2cc4STakashi Sakamoto /* 491d23c2cc4STakashi Sakamoto * This function should be called before starting streams or after stopping 492d23c2cc4STakashi Sakamoto * streams. 493d23c2cc4STakashi Sakamoto */ 494436b5abeSTakashi Sakamoto static void destroy_stream(struct snd_dice *dice, 495436b5abeSTakashi Sakamoto enum amdtp_stream_direction dir, 496436b5abeSTakashi Sakamoto unsigned int index) 4979a02843cSTakashi Sakamoto { 498436b5abeSTakashi Sakamoto struct amdtp_stream *stream; 499d23c2cc4STakashi Sakamoto struct fw_iso_resources *resources; 5009a02843cSTakashi Sakamoto 501436b5abeSTakashi Sakamoto if (dir == AMDTP_IN_STREAM) { 502436b5abeSTakashi Sakamoto stream = &dice->tx_stream[index]; 503436b5abeSTakashi Sakamoto resources = &dice->tx_resources[index]; 504436b5abeSTakashi Sakamoto } else { 505436b5abeSTakashi Sakamoto stream = &dice->rx_stream[index]; 506436b5abeSTakashi Sakamoto resources = &dice->rx_resources[index]; 507436b5abeSTakashi Sakamoto } 508d23c2cc4STakashi Sakamoto 509d23c2cc4STakashi Sakamoto amdtp_stream_destroy(stream); 510d23c2cc4STakashi Sakamoto fw_iso_resources_destroy(resources); 5119a02843cSTakashi Sakamoto } 5129a02843cSTakashi Sakamoto 5139a02843cSTakashi Sakamoto int snd_dice_stream_init_duplex(struct snd_dice *dice) 5146eb6c81eSTakashi Sakamoto { 515436b5abeSTakashi Sakamoto int i, err; 5166eb6c81eSTakashi Sakamoto 517436b5abeSTakashi Sakamoto for (i = 0; i < MAX_STREAMS; i++) { 518436b5abeSTakashi Sakamoto err = init_stream(dice, AMDTP_IN_STREAM, i); 519436b5abeSTakashi Sakamoto if (err < 0) { 520436b5abeSTakashi Sakamoto for (; i >= 0; i--) 5210f925660STakashi Sakamoto destroy_stream(dice, AMDTP_IN_STREAM, i); 5226eb6c81eSTakashi Sakamoto goto end; 523436b5abeSTakashi Sakamoto } 524436b5abeSTakashi Sakamoto } 5256eb6c81eSTakashi Sakamoto 526436b5abeSTakashi Sakamoto for (i = 0; i < MAX_STREAMS; i++) { 527436b5abeSTakashi Sakamoto err = init_stream(dice, AMDTP_OUT_STREAM, i); 528436b5abeSTakashi Sakamoto if (err < 0) { 529436b5abeSTakashi Sakamoto for (; i >= 0; i--) 530436b5abeSTakashi Sakamoto destroy_stream(dice, AMDTP_OUT_STREAM, i); 531436b5abeSTakashi Sakamoto for (i = 0; i < MAX_STREAMS; i++) 532436b5abeSTakashi Sakamoto destroy_stream(dice, AMDTP_IN_STREAM, i); 533436b5abeSTakashi Sakamoto break; 534436b5abeSTakashi Sakamoto } 535436b5abeSTakashi Sakamoto } 5366eb6c81eSTakashi Sakamoto end: 5376eb6c81eSTakashi Sakamoto return err; 5386eb6c81eSTakashi Sakamoto } 5396eb6c81eSTakashi Sakamoto 5409a02843cSTakashi Sakamoto void snd_dice_stream_destroy_duplex(struct snd_dice *dice) 5416eb6c81eSTakashi Sakamoto { 5426b94fb14STakashi Sakamoto unsigned int i; 543436b5abeSTakashi Sakamoto 5446b94fb14STakashi Sakamoto for (i = 0; i < MAX_STREAMS; i++) { 5456b94fb14STakashi Sakamoto destroy_stream(dice, AMDTP_IN_STREAM, i); 5466b94fb14STakashi Sakamoto destroy_stream(dice, AMDTP_OUT_STREAM, i); 547436b5abeSTakashi Sakamoto } 5486eb6c81eSTakashi Sakamoto } 5496eb6c81eSTakashi Sakamoto 5509a02843cSTakashi Sakamoto void snd_dice_stream_update_duplex(struct snd_dice *dice) 5516eb6c81eSTakashi Sakamoto { 5528cc1a8abSTakashi Sakamoto struct reg_params tx_params, rx_params; 553436b5abeSTakashi Sakamoto 5546eb6c81eSTakashi Sakamoto /* 5556eb6c81eSTakashi Sakamoto * On a bus reset, the DICE firmware disables streaming and then goes 5566eb6c81eSTakashi Sakamoto * off contemplating its own navel for hundreds of milliseconds before 5576eb6c81eSTakashi Sakamoto * it can react to any of our attempts to reenable streaming. This 5586eb6c81eSTakashi Sakamoto * means that we lose synchronization anyway, so we force our streams 5596eb6c81eSTakashi Sakamoto * to stop so that the application can restart them in an orderly 5606eb6c81eSTakashi Sakamoto * manner. 5616eb6c81eSTakashi Sakamoto */ 5626eb6c81eSTakashi Sakamoto dice->global_enabled = false; 5636eb6c81eSTakashi Sakamoto 5648cc1a8abSTakashi Sakamoto if (get_register_params(dice, &tx_params, &rx_params) == 0) { 5658cc1a8abSTakashi Sakamoto stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 5668cc1a8abSTakashi Sakamoto stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 567436b5abeSTakashi Sakamoto } 5686eb6c81eSTakashi Sakamoto } 5696eb6c81eSTakashi Sakamoto 570b60152f7STakashi Sakamoto int snd_dice_stream_detect_current_formats(struct snd_dice *dice) 571b60152f7STakashi Sakamoto { 572b60152f7STakashi Sakamoto unsigned int rate; 573b60152f7STakashi Sakamoto enum snd_dice_rate_mode mode; 574b60152f7STakashi Sakamoto __be32 reg[2]; 575b60152f7STakashi Sakamoto struct reg_params tx_params, rx_params; 576b60152f7STakashi Sakamoto int i; 577b60152f7STakashi Sakamoto int err; 578b60152f7STakashi Sakamoto 57958579c05STakashi Sakamoto /* If extended protocol is available, detect detail spec. */ 58058579c05STakashi Sakamoto err = snd_dice_detect_extension_formats(dice); 58158579c05STakashi Sakamoto if (err >= 0) 58258579c05STakashi Sakamoto return err; 58358579c05STakashi Sakamoto 584b60152f7STakashi Sakamoto /* 585b60152f7STakashi Sakamoto * Available stream format is restricted at current mode of sampling 586b60152f7STakashi Sakamoto * clock. 587b60152f7STakashi Sakamoto */ 588b60152f7STakashi Sakamoto err = snd_dice_transaction_get_rate(dice, &rate); 589b60152f7STakashi Sakamoto if (err < 0) 590b60152f7STakashi Sakamoto return err; 591b60152f7STakashi Sakamoto 592b60152f7STakashi Sakamoto err = snd_dice_stream_get_rate_mode(dice, rate, &mode); 593b60152f7STakashi Sakamoto if (err < 0) 594b60152f7STakashi Sakamoto return err; 595b60152f7STakashi Sakamoto 596b60152f7STakashi Sakamoto /* 597b60152f7STakashi Sakamoto * Just after owning the unit (GLOBAL_OWNER), the unit can return 598b60152f7STakashi Sakamoto * invalid stream formats. Selecting clock parameters have an effect 599b60152f7STakashi Sakamoto * for the unit to refine it. 600b60152f7STakashi Sakamoto */ 601afa617f2STakashi Sakamoto err = ensure_phase_lock(dice, rate); 602b60152f7STakashi Sakamoto if (err < 0) 603b60152f7STakashi Sakamoto return err; 604b60152f7STakashi Sakamoto 605b60152f7STakashi Sakamoto err = get_register_params(dice, &tx_params, &rx_params); 606b60152f7STakashi Sakamoto if (err < 0) 607b60152f7STakashi Sakamoto return err; 608b60152f7STakashi Sakamoto 609b60152f7STakashi Sakamoto for (i = 0; i < tx_params.count; ++i) { 610b60152f7STakashi Sakamoto err = snd_dice_transaction_read_tx(dice, 611b60152f7STakashi Sakamoto tx_params.size * i + TX_NUMBER_AUDIO, 612b60152f7STakashi Sakamoto reg, sizeof(reg)); 613b60152f7STakashi Sakamoto if (err < 0) 614b60152f7STakashi Sakamoto return err; 615b60152f7STakashi Sakamoto dice->tx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); 616b60152f7STakashi Sakamoto dice->tx_midi_ports[i] = max_t(unsigned int, 617b60152f7STakashi Sakamoto be32_to_cpu(reg[1]), dice->tx_midi_ports[i]); 618b60152f7STakashi Sakamoto } 619b60152f7STakashi Sakamoto for (i = 0; i < rx_params.count; ++i) { 620b60152f7STakashi Sakamoto err = snd_dice_transaction_read_rx(dice, 621b60152f7STakashi Sakamoto rx_params.size * i + RX_NUMBER_AUDIO, 622b60152f7STakashi Sakamoto reg, sizeof(reg)); 623b60152f7STakashi Sakamoto if (err < 0) 624b60152f7STakashi Sakamoto return err; 625b60152f7STakashi Sakamoto dice->rx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); 626b60152f7STakashi Sakamoto dice->rx_midi_ports[i] = max_t(unsigned int, 627b60152f7STakashi Sakamoto be32_to_cpu(reg[1]), dice->rx_midi_ports[i]); 628b60152f7STakashi Sakamoto } 629b60152f7STakashi Sakamoto 630b60152f7STakashi Sakamoto return 0; 631b60152f7STakashi Sakamoto } 632b60152f7STakashi Sakamoto 6336eb6c81eSTakashi Sakamoto static void dice_lock_changed(struct snd_dice *dice) 6346eb6c81eSTakashi Sakamoto { 6356eb6c81eSTakashi Sakamoto dice->dev_lock_changed = true; 6366eb6c81eSTakashi Sakamoto wake_up(&dice->hwdep_wait); 6376eb6c81eSTakashi Sakamoto } 6386eb6c81eSTakashi Sakamoto 6396eb6c81eSTakashi Sakamoto int snd_dice_stream_lock_try(struct snd_dice *dice) 6406eb6c81eSTakashi Sakamoto { 6416eb6c81eSTakashi Sakamoto int err; 6426eb6c81eSTakashi Sakamoto 6436eb6c81eSTakashi Sakamoto spin_lock_irq(&dice->lock); 6446eb6c81eSTakashi Sakamoto 6456eb6c81eSTakashi Sakamoto if (dice->dev_lock_count < 0) { 6466eb6c81eSTakashi Sakamoto err = -EBUSY; 6476eb6c81eSTakashi Sakamoto goto out; 6486eb6c81eSTakashi Sakamoto } 6496eb6c81eSTakashi Sakamoto 6506eb6c81eSTakashi Sakamoto if (dice->dev_lock_count++ == 0) 6516eb6c81eSTakashi Sakamoto dice_lock_changed(dice); 6526eb6c81eSTakashi Sakamoto err = 0; 6536eb6c81eSTakashi Sakamoto out: 6546eb6c81eSTakashi Sakamoto spin_unlock_irq(&dice->lock); 6556eb6c81eSTakashi Sakamoto return err; 6566eb6c81eSTakashi Sakamoto } 6576eb6c81eSTakashi Sakamoto 6586eb6c81eSTakashi Sakamoto void snd_dice_stream_lock_release(struct snd_dice *dice) 6596eb6c81eSTakashi Sakamoto { 6606eb6c81eSTakashi Sakamoto spin_lock_irq(&dice->lock); 6616eb6c81eSTakashi Sakamoto 6626eb6c81eSTakashi Sakamoto if (WARN_ON(dice->dev_lock_count <= 0)) 6636eb6c81eSTakashi Sakamoto goto out; 6646eb6c81eSTakashi Sakamoto 6656eb6c81eSTakashi Sakamoto if (--dice->dev_lock_count == 0) 6666eb6c81eSTakashi Sakamoto dice_lock_changed(dice); 6676eb6c81eSTakashi Sakamoto out: 6686eb6c81eSTakashi Sakamoto spin_unlock_irq(&dice->lock); 6696eb6c81eSTakashi Sakamoto } 670