1 /**************************************************************************** 2 3 Copyright Echo Digital Audio Corporation (c) 1998 - 2004 4 All rights reserved 5 www.echoaudio.com 6 7 This file is part of Echo Digital Audio's generic driver library. 8 9 Echo Digital Audio's generic driver library is free software; 10 you can redistribute it and/or modify it under the terms of 11 the GNU General Public License as published by the Free Software 12 Foundation. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, 22 MA 02111-1307, USA. 23 24 ************************************************************************* 25 26 Translation from C++ and adaptation for use in ALSA-Driver 27 were made by Giuliano Pochini <pochini@shiny.it> 28 29 ****************************************************************************/ 30 31 32 /* These functions are common for Gina24, Layla24 and Mona cards */ 33 34 35 /* ASIC status check - some cards have one or two ASICs that need to be 36 loaded. Once that load is complete, this function is called to see if 37 the load was successful. 38 If this load fails, it does not necessarily mean that the hardware is 39 defective - the external box may be disconnected or turned off. */ 40 static int check_asic_status(struct echoaudio *chip) 41 { 42 u32 asic_status; 43 44 send_vector(chip, DSP_VC_TEST_ASIC); 45 46 /* The DSP will return a value to indicate whether or not the 47 ASIC is currently loaded */ 48 if (read_dsp(chip, &asic_status) < 0) { 49 DE_INIT(("check_asic_status: failed on read_dsp\n")); 50 chip->asic_loaded = FALSE; 51 return -EIO; 52 } 53 54 chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED); 55 return chip->asic_loaded ? 0 : -EIO; 56 } 57 58 59 60 /* Most configuration of Gina24, Layla24, or Mona is accomplished by writing 61 the control register. write_control_reg sends the new control register 62 value to the DSP. */ 63 static int write_control_reg(struct echoaudio *chip, u32 value, char force) 64 { 65 /* Handle the digital input auto-mute */ 66 if (chip->digital_in_automute) 67 value |= GML_DIGITAL_IN_AUTO_MUTE; 68 else 69 value &= ~GML_DIGITAL_IN_AUTO_MUTE; 70 71 DE_ACT(("write_control_reg: 0x%x\n", value)); 72 73 /* Write the control register */ 74 value = cpu_to_le32(value); 75 if (value != chip->comm_page->control_register || force) { 76 if (wait_handshake(chip)) 77 return -EIO; 78 chip->comm_page->control_register = value; 79 clear_handshake(chip); 80 return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); 81 } 82 return 0; 83 } 84 85 86 87 /* Gina24, Layla24, and Mona support digital input auto-mute. If the digital 88 input auto-mute is enabled, the DSP will only enable the digital inputs if 89 the card is syncing to a valid clock on the ADAT or S/PDIF inputs. 90 If the auto-mute is disabled, the digital inputs are enabled regardless of 91 what the input clock is set or what is connected. */ 92 static int set_input_auto_mute(struct echoaudio *chip, int automute) 93 { 94 DE_ACT(("set_input_auto_mute %d\n", automute)); 95 96 chip->digital_in_automute = automute; 97 98 /* Re-set the input clock to the current value - indirectly causes 99 the auto-mute flag to be sent to the DSP */ 100 return set_input_clock(chip, chip->input_clock); 101 } 102 103 104 105 /* S/PDIF coax / S/PDIF optical / ADAT - switch */ 106 static int set_digital_mode(struct echoaudio *chip, u8 mode) 107 { 108 u8 previous_mode; 109 int err, i, o; 110 111 if (chip->bad_board) 112 return -EIO; 113 114 /* All audio channels must be closed before changing the digital mode */ 115 snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); 116 117 snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); 118 119 previous_mode = chip->digital_mode; 120 err = dsp_set_digital_mode(chip, mode); 121 122 /* If we successfully changed the digital mode from or to ADAT, 123 then make sure all output, input and monitor levels are 124 updated by the DSP comm object. */ 125 if (err >= 0 && previous_mode != mode && 126 (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { 127 spin_lock_irq(&chip->lock); 128 for (o = 0; o < num_busses_out(chip); o++) 129 for (i = 0; i < num_busses_in(chip); i++) 130 set_monitor_gain(chip, o, i, 131 chip->monitor_gain[o][i]); 132 133 #ifdef ECHOCARD_HAS_INPUT_GAIN 134 for (i = 0; i < num_busses_in(chip); i++) 135 set_input_gain(chip, i, chip->input_gain[i]); 136 update_input_line_level(chip); 137 #endif 138 139 for (o = 0; o < num_busses_out(chip); o++) 140 set_output_gain(chip, o, chip->output_gain[o]); 141 update_output_line_level(chip); 142 spin_unlock_irq(&chip->lock); 143 } 144 145 return err; 146 } 147 148 149 150 /* Set the S/PDIF output format */ 151 static int set_professional_spdif(struct echoaudio *chip, char prof) 152 { 153 u32 control_reg; 154 int err; 155 156 /* Clear the current S/PDIF flags */ 157 control_reg = le32_to_cpu(chip->comm_page->control_register); 158 control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK; 159 160 /* Set the new S/PDIF flags depending on the mode */ 161 control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT | 162 GML_SPDIF_COPY_PERMIT; 163 if (prof) { 164 /* Professional mode */ 165 control_reg |= GML_SPDIF_PRO_MODE; 166 167 switch (chip->sample_rate) { 168 case 32000: 169 control_reg |= GML_SPDIF_SAMPLE_RATE0 | 170 GML_SPDIF_SAMPLE_RATE1; 171 break; 172 case 44100: 173 control_reg |= GML_SPDIF_SAMPLE_RATE0; 174 break; 175 case 48000: 176 control_reg |= GML_SPDIF_SAMPLE_RATE1; 177 break; 178 } 179 } else { 180 /* Consumer mode */ 181 switch (chip->sample_rate) { 182 case 32000: 183 control_reg |= GML_SPDIF_SAMPLE_RATE0 | 184 GML_SPDIF_SAMPLE_RATE1; 185 break; 186 case 48000: 187 control_reg |= GML_SPDIF_SAMPLE_RATE1; 188 break; 189 } 190 } 191 192 if ((err = write_control_reg(chip, control_reg, FALSE))) 193 return err; 194 chip->professional_spdif = prof; 195 DE_ACT(("set_professional_spdif to %s\n", 196 prof ? "Professional" : "Consumer")); 197 return 0; 198 } 199