root/sound/pci/echoaudio/echoaudio_gml.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_asic_status
  2. write_control_reg
  3. set_input_auto_mute
  4. set_digital_mode
  5. set_professional_spdif

   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                 dev_err(chip->card->dev,
  50                         "check_asic_status: failed on read_dsp\n");
  51                 chip->asic_loaded = false;
  52                 return -EIO;
  53         }
  54 
  55         chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED);
  56         return chip->asic_loaded ? 0 : -EIO;
  57 }
  58 
  59 
  60 
  61 /* Most configuration of Gina24, Layla24, or Mona is accomplished by writing
  62 the control register.  write_control_reg sends the new control register
  63 value to the DSP. */
  64 static int write_control_reg(struct echoaudio *chip, u32 value, char force)
  65 {
  66         __le32 reg_value;
  67 
  68         /* Handle the digital input auto-mute */
  69         if (chip->digital_in_automute)
  70                 value |= GML_DIGITAL_IN_AUTO_MUTE;
  71         else
  72                 value &= ~GML_DIGITAL_IN_AUTO_MUTE;
  73 
  74         dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value);
  75 
  76         /* Write the control register */
  77         reg_value = cpu_to_le32(value);
  78         if (reg_value != chip->comm_page->control_register || force) {
  79                 if (wait_handshake(chip))
  80                         return -EIO;
  81                 chip->comm_page->control_register = reg_value;
  82                 clear_handshake(chip);
  83                 return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
  84         }
  85         return 0;
  86 }
  87 
  88 
  89 
  90 /* Gina24, Layla24, and Mona support digital input auto-mute.  If the digital
  91 input auto-mute is enabled, the DSP will only enable the digital inputs if
  92 the card is syncing to a valid clock on the ADAT or S/PDIF inputs.
  93 If the auto-mute is disabled, the digital inputs are enabled regardless of
  94 what the input clock is set or what is connected. */
  95 static int set_input_auto_mute(struct echoaudio *chip, int automute)
  96 {
  97         dev_dbg(chip->card->dev, "set_input_auto_mute %d\n", automute);
  98 
  99         chip->digital_in_automute = automute;
 100 
 101         /* Re-set the input clock to the current value - indirectly causes
 102         the auto-mute flag to be sent to the DSP */
 103         return set_input_clock(chip, chip->input_clock);
 104 }
 105 
 106 
 107 
 108 /* S/PDIF coax / S/PDIF optical / ADAT - switch */
 109 static int set_digital_mode(struct echoaudio *chip, u8 mode)
 110 {
 111         u8 previous_mode;
 112         int err, i, o;
 113 
 114         if (chip->bad_board)
 115                 return -EIO;
 116 
 117         /* All audio channels must be closed before changing the digital mode */
 118         if (snd_BUG_ON(chip->pipe_alloc_mask))
 119                 return -EAGAIN;
 120 
 121         if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
 122                 return -EINVAL;
 123 
 124         previous_mode = chip->digital_mode;
 125         err = dsp_set_digital_mode(chip, mode);
 126 
 127         /* If we successfully changed the digital mode from or to ADAT,
 128            then make sure all output, input and monitor levels are
 129            updated by the DSP comm object. */
 130         if (err >= 0 && previous_mode != mode &&
 131             (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
 132                 spin_lock_irq(&chip->lock);
 133                 for (o = 0; o < num_busses_out(chip); o++)
 134                         for (i = 0; i < num_busses_in(chip); i++)
 135                                 set_monitor_gain(chip, o, i,
 136                                                  chip->monitor_gain[o][i]);
 137 
 138 #ifdef ECHOCARD_HAS_INPUT_GAIN
 139                 for (i = 0; i < num_busses_in(chip); i++)
 140                         set_input_gain(chip, i, chip->input_gain[i]);
 141                 update_input_line_level(chip);
 142 #endif
 143 
 144                 for (o = 0; o < num_busses_out(chip); o++)
 145                         set_output_gain(chip, o, chip->output_gain[o]);
 146                 update_output_line_level(chip);
 147                 spin_unlock_irq(&chip->lock);
 148         }
 149 
 150         return err;
 151 }
 152 
 153 
 154 
 155 /* Set the S/PDIF output format */
 156 static int set_professional_spdif(struct echoaudio *chip, char prof)
 157 {
 158         u32 control_reg;
 159         int err;
 160 
 161         /* Clear the current S/PDIF flags */
 162         control_reg = le32_to_cpu(chip->comm_page->control_register);
 163         control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK;
 164 
 165         /* Set the new S/PDIF flags depending on the mode */
 166         control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT |
 167                 GML_SPDIF_COPY_PERMIT;
 168         if (prof) {
 169                 /* Professional mode */
 170                 control_reg |= GML_SPDIF_PRO_MODE;
 171 
 172                 switch (chip->sample_rate) {
 173                 case 32000:
 174                         control_reg |= GML_SPDIF_SAMPLE_RATE0 |
 175                                 GML_SPDIF_SAMPLE_RATE1;
 176                         break;
 177                 case 44100:
 178                         control_reg |= GML_SPDIF_SAMPLE_RATE0;
 179                         break;
 180                 case 48000:
 181                         control_reg |= GML_SPDIF_SAMPLE_RATE1;
 182                         break;
 183                 }
 184         } else {
 185                 /* Consumer mode */
 186                 switch (chip->sample_rate) {
 187                 case 32000:
 188                         control_reg |= GML_SPDIF_SAMPLE_RATE0 |
 189                                 GML_SPDIF_SAMPLE_RATE1;
 190                         break;
 191                 case 48000:
 192                         control_reg |= GML_SPDIF_SAMPLE_RATE1;
 193                         break;
 194                 }
 195         }
 196 
 197         if ((err = write_control_reg(chip, control_reg, false)))
 198                 return err;
 199         chip->professional_spdif = prof;
 200         dev_dbg(chip->card->dev, "set_professional_spdif to %s\n",
 201                 prof ? "Professional" : "Consumer");
 202         return 0;
 203 }

/* [<][>][^][v][top][bottom][index][help] */