linux/sound/pci/echoaudio/gina24_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 write_control_reg(struct echoaudio *chip, u32 value, char force);
  33static int set_input_clock(struct echoaudio *chip, u16 clock);
  34static int set_professional_spdif(struct echoaudio *chip, char prof);
  35static int set_digital_mode(struct echoaudio *chip, u8 mode);
  36static int load_asic_generic(struct echoaudio *chip, u32 cmd,
  37                             const struct firmware *asic);
  38static int check_asic_status(struct echoaudio *chip);
  39
  40
  41static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
  42{
  43        int err;
  44
  45        DE_INIT(("init_hw() - Gina24\n"));
  46        snd_assert((subdevice_id & 0xfff0) == GINA24, 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->input_clock_types =
  57                ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
  58                ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
  59                ECHO_CLOCK_BIT_ADAT;
  60        chip->professional_spdif = FALSE;
  61        chip->digital_in_automute = TRUE;
  62        chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
  63
  64        /* Gina24 comes in both '301 and '361 flavors */
  65        if (chip->device_id == DEVICE_ID_56361) {
  66                chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP];
  67                chip->digital_modes =
  68                        ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
  69                        ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
  70                        ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
  71        } else {
  72                chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP];
  73                chip->digital_modes =
  74                        ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
  75                        ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
  76                        ECHOCAPS_HAS_DIGITAL_MODE_ADAT |
  77                        ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM;
  78        }
  79
  80        if ((err = load_firmware(chip)) < 0)
  81                return err;
  82        chip->bad_board = FALSE;
  83
  84        if ((err = init_line_levels(chip)) < 0)
  85                return err;
  86        err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
  87        snd_assert(err >= 0, return err);
  88        err = set_professional_spdif(chip, TRUE);
  89
  90        DE_INIT(("init_hw done\n"));
  91        return err;
  92}
  93
  94
  95
  96static u32 detect_input_clocks(const struct echoaudio *chip)
  97{
  98        u32 clocks_from_dsp, clock_bits;
  99
 100        /* Map the DSP clock detect bits to the generic driver clock
 101           detect bits */
 102        clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
 103
 104        clock_bits = ECHO_CLOCK_BIT_INTERNAL;
 105
 106        if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
 107                clock_bits |= ECHO_CLOCK_BIT_SPDIF;
 108
 109        if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
 110                clock_bits |= ECHO_CLOCK_BIT_ADAT;
 111
 112        if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC)
 113                clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96;
 114
 115        return clock_bits;
 116}
 117
 118
 119
 120/* Gina24 has an ASIC on the PCI card which must be loaded for anything
 121interesting to happen. */
 122static int load_asic(struct echoaudio *chip)
 123{
 124        u32 control_reg;
 125        int err;
 126        const struct firmware *fw;
 127
 128        if (chip->asic_loaded)
 129                return 1;
 130
 131        /* Give the DSP a few milliseconds to settle down */
 132        mdelay(10);
 133
 134        /* Pick the correct ASIC for '301 or '361 Gina24 */
 135        if (chip->device_id == DEVICE_ID_56361)
 136                fw = &card_fw[FW_GINA24_361_ASIC];
 137        else
 138                fw = &card_fw[FW_GINA24_301_ASIC];
 139
 140        if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0)
 141                return err;
 142
 143        chip->asic_code = fw;
 144
 145        /* Now give the new ASIC a little time to set up */
 146        mdelay(10);
 147        /* See if it worked */
 148        err = check_asic_status(chip);
 149
 150        /* Set up the control register if the load succeeded -
 151           48 kHz, internal clock, S/PDIF RCA mode */
 152        if (!err) {
 153                control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
 154                err = write_control_reg(chip, control_reg, TRUE);
 155        }
 156        DE_INIT(("load_asic() done\n"));
 157        return err;
 158}
 159
 160
 161
 162static int set_sample_rate(struct echoaudio *chip, u32 rate)
 163{
 164        u32 control_reg, clock;
 165
 166        snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT,
 167                   return -EINVAL);
 168
 169        /* Only set the clock for internal mode. */
 170        if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
 171                DE_ACT(("set_sample_rate: Cannot set sample rate - "
 172                        "clock not set to CLK_CLOCKININTERNAL\n"));
 173                /* Save the rate anyhow */
 174                chip->comm_page->sample_rate = cpu_to_le32(rate);
 175                chip->sample_rate = rate;
 176                return 0;
 177        }
 178
 179        clock = 0;
 180
 181        control_reg = le32_to_cpu(chip->comm_page->control_register);
 182        control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK;
 183
 184        switch (rate) {
 185        case 96000:
 186                clock = GML_96KHZ;
 187                break;
 188        case 88200:
 189                clock = GML_88KHZ;
 190                break;
 191        case 48000:
 192                clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
 193                break;
 194        case 44100:
 195                clock = GML_44KHZ;
 196                /* Professional mode ? */
 197                if (control_reg & GML_SPDIF_PRO_MODE)
 198                        clock |= GML_SPDIF_SAMPLE_RATE0;
 199                break;
 200        case 32000:
 201                clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
 202                        GML_SPDIF_SAMPLE_RATE1;
 203                break;
 204        case 22050:
 205                clock = GML_22KHZ;
 206                break;
 207        case 16000:
 208                clock = GML_16KHZ;
 209                break;
 210        case 11025:
 211                clock = GML_11KHZ;
 212                break;
 213        case 8000:
 214                clock = GML_8KHZ;
 215                break;
 216        default:
 217                DE_ACT(("set_sample_rate: %d invalid!\n", rate));
 218                return -EINVAL;
 219        }
 220
 221        control_reg |= clock;
 222
 223        chip->comm_page->sample_rate = cpu_to_le32(rate);       /* ignored by the DSP */
 224        chip->sample_rate = rate;
 225        DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
 226
 227        return write_control_reg(chip, control_reg, FALSE);
 228}
 229
 230
 231
 232static int set_input_clock(struct echoaudio *chip, u16 clock)
 233{
 234        u32 control_reg, clocks_from_dsp;
 235
 236        DE_ACT(("set_input_clock:\n"));
 237
 238        /* Mask off the clock select bits */
 239        control_reg = le32_to_cpu(chip->comm_page->control_register) &
 240                GML_CLOCK_CLEAR_MASK;
 241        clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
 242
 243        switch (clock) {
 244        case ECHO_CLOCK_INTERNAL:
 245                DE_ACT(("Set Gina24 clock to INTERNAL\n"));
 246                chip->input_clock = ECHO_CLOCK_INTERNAL;
 247                return set_sample_rate(chip, chip->sample_rate);
 248        case ECHO_CLOCK_SPDIF:
 249                if (chip->digital_mode == DIGITAL_MODE_ADAT)
 250                        return -EAGAIN;
 251                DE_ACT(("Set Gina24 clock to SPDIF\n"));
 252                control_reg |= GML_SPDIF_CLOCK;
 253                if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
 254                        control_reg |= GML_DOUBLE_SPEED_MODE;
 255                else
 256                        control_reg &= ~GML_DOUBLE_SPEED_MODE;
 257                break;
 258        case ECHO_CLOCK_ADAT:
 259                if (chip->digital_mode != DIGITAL_MODE_ADAT)
 260                        return -EAGAIN;
 261                DE_ACT(("Set Gina24 clock to ADAT\n"));
 262                control_reg |= GML_ADAT_CLOCK;
 263                control_reg &= ~GML_DOUBLE_SPEED_MODE;
 264                break;
 265        case ECHO_CLOCK_ESYNC:
 266                DE_ACT(("Set Gina24 clock to ESYNC\n"));
 267                control_reg |= GML_ESYNC_CLOCK;
 268                control_reg &= ~GML_DOUBLE_SPEED_MODE;
 269                break;
 270        case ECHO_CLOCK_ESYNC96:
 271                DE_ACT(("Set Gina24 clock to ESYNC96\n"));
 272                control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE;
 273                break;
 274        default:
 275                DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock));
 276                return -EINVAL;
 277        }
 278
 279        chip->input_clock = clock;
 280        return write_control_reg(chip, control_reg, TRUE);
 281}
 282
 283
 284
 285static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
 286{
 287        u32 control_reg;
 288        int err, incompatible_clock;
 289
 290        /* Set clock to "internal" if it's not compatible with the new mode */
 291        incompatible_clock = FALSE;
 292        switch (mode) {
 293        case DIGITAL_MODE_SPDIF_OPTICAL:
 294        case DIGITAL_MODE_SPDIF_CDROM:
 295        case DIGITAL_MODE_SPDIF_RCA:
 296                if (chip->input_clock == ECHO_CLOCK_ADAT)
 297                        incompatible_clock = TRUE;
 298                break;
 299        case DIGITAL_MODE_ADAT:
 300                if (chip->input_clock == ECHO_CLOCK_SPDIF)
 301                        incompatible_clock = TRUE;
 302                break;
 303        default:
 304                DE_ACT(("Digital mode not supported: %d\n", mode));
 305                return -EINVAL;
 306        }
 307
 308        spin_lock_irq(&chip->lock);
 309
 310        if (incompatible_clock) {       /* Switch to 48KHz, internal */
 311                chip->sample_rate = 48000;
 312                set_input_clock(chip, ECHO_CLOCK_INTERNAL);
 313        }
 314
 315        /* Clear the current digital mode */
 316        control_reg = le32_to_cpu(chip->comm_page->control_register);
 317        control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
 318
 319        /* Tweak the control reg */
 320        switch (mode) {
 321        case DIGITAL_MODE_SPDIF_OPTICAL:
 322                control_reg |= GML_SPDIF_OPTICAL_MODE;
 323                break;
 324        case DIGITAL_MODE_SPDIF_CDROM:
 325                /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */
 326                if (chip->device_id == DEVICE_ID_56301)
 327                        control_reg |= GML_SPDIF_CDROM_MODE;
 328                break;
 329        case DIGITAL_MODE_SPDIF_RCA:
 330                /* GML_SPDIF_OPTICAL_MODE bit cleared */
 331                break;
 332        case DIGITAL_MODE_ADAT:
 333                control_reg |= GML_ADAT_MODE;
 334                control_reg &= ~GML_DOUBLE_SPEED_MODE;
 335                break;
 336        }
 337
 338        err = write_control_reg(chip, control_reg, TRUE);
 339        spin_unlock_irq(&chip->lock);
 340        if (err < 0)
 341                return err;
 342        chip->digital_mode = mode;
 343
 344        DE_ACT(("set_digital_mode to %d\n", chip->digital_mode));
 345        return incompatible_clock;
 346}
 347
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.