/* S/PDIF coax / S/PDIF optical / ADAT - switch */ static int set_digital_mode(struct echoaudio *chip, u8 mode) { u8 previous_mode; int err, i, o; if (chip->bad_board) return -EIO; /* All audio channels must be closed before changing the digital mode */ if (snd_BUG_ON(chip->pipe_alloc_mask)) return -EAGAIN; if (snd_BUG_ON(!(chip->digital_modes & (1 << mode)))) return -EINVAL; previous_mode = chip->digital_mode; err = dsp_set_digital_mode(chip, mode); /* If we successfully changed the digital mode from or to ADAT, then make sure all output, input and monitor levels are updated by the DSP comm object. */ if (err >= 0 && previous_mode != mode && (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { spin_lock_irq(&chip->lock); for (o = 0; o < num_busses_out(chip); o++) for (i = 0; i < num_busses_in(chip); i++) set_monitor_gain(chip, o, i, chip->monitor_gain[o][i]); #ifdef ECHOCARD_HAS_INPUT_GAIN for (i = 0; i < num_busses_in(chip); i++) set_input_gain(chip, i, chip->input_gain[i]); update_input_line_level(chip); #endif for (o = 0; o < num_busses_out(chip); o++) set_output_gain(chip, o, chip->output_gain[o]); update_output_line_level(chip); spin_unlock_irq(&chip->lock); } return err; }
static int set_digital_mode(struct echoaudio *chip, u8 mode) { u8 previous_mode; int err, i, o; if (chip->bad_board) return -EIO; if (snd_BUG_ON(chip->pipe_alloc_mask)) return -EAGAIN; if (snd_BUG_ON(!(chip->digital_modes & (1 << mode)))) return -EINVAL; previous_mode = chip->digital_mode; err = dsp_set_digital_mode(chip, mode); if (err >= 0 && previous_mode != mode && (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { spin_lock_irq(&chip->lock); for (o = 0; o < num_busses_out(chip); o++) for (i = 0; i < num_busses_in(chip); i++) set_monitor_gain(chip, o, i, chip->monitor_gain[o][i]); #ifdef ECHOCARD_HAS_INPUT_GAIN for (i = 0; i < num_busses_in(chip); i++) set_input_gain(chip, i, chip->input_gain[i]); update_input_line_level(chip); #endif for (o = 0; o < num_busses_out(chip); o++) set_output_gain(chip, o, chip->output_gain[o]); update_output_line_level(chip); spin_unlock_irq(&chip->lock); } return err; }