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