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        if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
  45                return -ENODEV;
  46
  47        if ((err = init_dsp_comm_page(chip))) {
  48                dev_err(chip->card->dev,
  49                        "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        return err;
  70}
  71
  72
  73
  74static int set_mixer_defaults(struct echoaudio *chip)
  75{
  76        return init_line_levels(chip);
  77}
  78
  79
  80
  81static u32 detect_input_clocks(const struct echoaudio *chip)
  82{
  83        u32 clocks_from_dsp, clock_bits;
  84
  85        /* Map the DSP clock detect bits to the generic driver clock
  86           detect bits */
  87        clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
  88
  89        clock_bits = ECHO_CLOCK_BIT_INTERNAL;
  90
  91        if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
  92                clock_bits |= ECHO_CLOCK_BIT_SPDIF;
  93
  94        return clock_bits;
  95}
  96
  97
  98
  99/* The Mia has no ASIC. Just do nothing */
 100static int load_asic(struct echoaudio *chip)
 101{
 102        return 0;
 103}
 104
 105
 106
 107static int set_sample_rate(struct echoaudio *chip, u32 rate)
 108{
 109        u32 control_reg;
 110
 111        switch (rate) {
 112        case 96000:
 113                control_reg = MIA_96000;
 114                break;
 115        case 88200:
 116                control_reg = MIA_88200;
 117                break;
 118        case 48000:
 119                control_reg = MIA_48000;
 120                break;
 121        case 44100:
 122                control_reg = MIA_44100;
 123                break;
 124        case 32000:
 125                control_reg = MIA_32000;
 126                break;
 127        default:
 128                dev_err(chip->card->dev,
 129                        "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        dev_dbg(chip->card->dev, "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        dev_dbg(chip->card->dev,
 185                "set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain);
 186        return 0;
 187}
 188
 189
 190
 191/* Tell the DSP to read and update virtual mixer levels in comm page. */
 192static int update_vmixer_level(struct echoaudio *chip)
 193{
 194        if (wait_handshake(chip))
 195                return -EIO;
 196        clear_handshake(chip);
 197        return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
 198}
 199
 200
 201
 202/* Tell the DSP to reread the flags from the comm page */
 203static int update_flags(struct echoaudio *chip)
 204{
 205        if (wait_handshake(chip))
 206                return -EIO;
 207        clear_handshake(chip);
 208        return send_vector(chip, DSP_VC_UPDATE_FLAGS);
 209}
 210
 211
 212
 213static int set_professional_spdif(struct echoaudio *chip, char prof)
 214{
 215        dev_dbg(chip->card->dev, "set_professional_spdif %d\n", prof);
 216        if (prof)
 217                chip->comm_page->flags |=
 218                        cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
 219        else
 220                chip->comm_page->flags &=
 221                        ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
 222        chip->professional_spdif = prof;
 223        return update_flags(chip);
 224}
 225
 226