linux/sound/pci/echoaudio/mia_dsp.c
<<
>>
Prefs
   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
  32static int set_input_clock(struct echoaudio *chip, u16 clock);
  33static int set_professional_spdif(struct echoaudio *chip, char prof);
  34static int update_flags(struct echoaudio *chip);
  35static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
  36                           int gain);
  37static int update_vmixer_level(struct echoaudio *chip);
  38
  39
  40static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
  41{
  42        int err;
  43
  44        DE_INIT(("init_hw() - Mia\n"));
  45        if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
  46                return -ENODEV;
  47
  48        if ((err = init_dsp_comm_page(chip))) {
  49                DE_INIT(("init_hw - could not initialize DSP comm page\n"));
  50                return err;
  51        }
  52
  53        chip->device_id = device_id;
  54        chip->subdevice_id = subdevice_id;
  55        chip->bad_board = TRUE;
  56        chip->dsp_code_to_load = FW_MIA_DSP;
  57        /* Since this card has no ASIC, mark it as loaded so everything
  58           works OK */
  59        chip->asic_loaded = TRUE;
  60        if ((subdevice_id & 0x0000f) == MIA_MIDI_REV)
  61                chip->has_midi = TRUE;
  62        chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
  63                ECHO_CLOCK_BIT_SPDIF;
  64
  65        if ((err = load_firmware(chip)) < 0)
  66                return err;
  67        chip->bad_board = FALSE;
  68
  69        DE_INIT(("init_hw done\n"));
  70        return err;
  71}
  72
  73
  74
  75static int set_mixer_defaults(struct echoaudio *chip)
  76{
  77        return init_line_levels(chip);
  78}
  79
  80
  81
  82static u32 detect_input_clocks(const struct echoaudio *chip)
  83{
  84        u32 clocks_from_dsp, clock_bits;
  85
  86        /* Map the DSP clock detect bits to the generic driver clock
  87           detect bits */
  88        clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
  89
  90        clock_bits = ECHO_CLOCK_BIT_INTERNAL;
  91
  92        if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
  93                clock_bits |= ECHO_CLOCK_BIT_SPDIF;
  94
  95        return clock_bits;
  96}
  97
  98
  99
 100/* The Mia has no ASIC. Just do nothing */
 101static int load_asic(struct echoaudio *chip)
 102{
 103        return 0;
 104}
 105
 106
 107
 108static int set_sample_rate(struct echoaudio *chip, u32 rate)
 109{
 110        u32 control_reg;
 111
 112        switch (rate) {
 113        case 96000:
 114                control_reg = MIA_96000;
 115                break;
 116        case 88200:
 117                control_reg = MIA_88200;
 118                break;
 119        case 48000:
 120                control_reg = MIA_48000;
 121                break;
 122        case 44100:
 123                control_reg = MIA_44100;
 124                break;
 125        case 32000:
 126                control_reg = MIA_32000;
 127                break;
 128        default:
 129                DE_ACT(("set_sample_rate: %d invalid!\n", rate));
 130                return -EINVAL;
 131        }
 132
 133        /* Override the clock setting if this Mia is set to S/PDIF clock */
 134        if (chip->input_clock == ECHO_CLOCK_SPDIF)
 135                control_reg |= MIA_SPDIF;
 136
 137        /* Set the control register if it has changed */
 138        if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
 139                if (wait_handshake(chip))
 140                        return -EIO;
 141
 142                chip->comm_page->sample_rate = cpu_to_le32(rate);       /* ignored by the DSP */
 143                chip->comm_page->control_register = cpu_to_le32(control_reg);
 144                chip->sample_rate = rate;
 145
 146                clear_handshake(chip);
 147                return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
 148        }
 149        return 0;
 150}
 151
 152
 153
 154static int set_input_clock(struct echoaudio *chip, u16 clock)
 155{
 156        DE_ACT(("set_input_clock(%d)\n", clock));
 157        if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
 158                       clock != ECHO_CLOCK_SPDIF))
 159                return -EINVAL;
 160
 161        chip->input_clock = clock;
 162        return set_sample_rate(chip, chip->sample_rate);
 163}
 164
 165
 166
 167/* This function routes the sound from a virtual channel to a real output */
 168static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
 169                           int gain)
 170{
 171        int index;
 172
 173        if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
 174                       output >= num_busses_out(chip)))
 175                return -EINVAL;
 176
 177        if (wait_handshake(chip))
 178                return -EIO;
 179
 180        chip->vmixer_gain[output][pipe] = gain;
 181        index = output * num_pipes_out(chip) + pipe;
 182        chip->comm_page->vmixer[index] = gain;
 183
 184        DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
 185        return 0;
 186}
 187
 188
 189
 190/* Tell the DSP to read and update virtual mixer levels in comm page. */
 191static int update_vmixer_level(struct echoaudio *chip)
 192{
 193        if (wait_handshake(chip))
 194                return -EIO;
 195        clear_handshake(chip);
 196        return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
 197}
 198
 199
 200
 201/* Tell the DSP to reread the flags from the comm page */
 202static int update_flags(struct echoaudio *chip)
 203{
 204        if (wait_handshake(chip))
 205                return -EIO;
 206        clear_handshake(chip);
 207        return send_vector(chip, DSP_VC_UPDATE_FLAGS);
 208}
 209
 210
 211
 212static int set_professional_spdif(struct echoaudio *chip, char prof)
 213{
 214        DE_ACT(("set_professional_spdif %d\n", prof));
 215        if (prof)
 216                chip->comm_page->flags |=
 217                        cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
 218        else
 219                chip->comm_page->flags &=
 220                        ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
 221        chip->professional_spdif = prof;
 222        return update_flags(chip);
 223}
 224
 225