~ubuntu-branches/ubuntu/maverick/linux-backports-modules-2.6.32/maverick

« back to all changes in this revision

Viewing changes to updates/alsa-driver/alsa-kernel/pci/echoaudio/layla20_dsp.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft, Andy Whitcroft
  • Date: 2010-02-04 23:15:51 UTC
  • Revision ID: james.westby@ubuntu.com-20100204231551-vjz5pkvxclukjxm1
Tags: 2.6.32-12.1
[ Andy Whitcroft ]

* initial LBM for lucid
* drop generated files
* printchanges -- rebase tree does not have stable tags use changelog
* printenv -- add revisions to printenv output
* formally rename compat-wireless to linux-backports-modules-wireless
* Update to compat-wireless-2.6.33-rc5
* update nouveau to mainline 2.6.33-rc4
* add new LBM package for nouveau
* nouveau -- fix major numbers and proc entry names
* fix up firmware installs for -wireless
* clean up UPDATE-NOVEAU
* update Nouveau to v2.6.33-rc6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
static int read_dsp(struct echoaudio *chip, u32 *data);
 
33
static int set_professional_spdif(struct echoaudio *chip, char prof);
 
34
static int load_asic_generic(struct echoaudio *chip, u32 cmd,
 
35
                             const struct firmware *asic);
 
36
static int check_asic_status(struct echoaudio *chip);
 
37
static int update_flags(struct echoaudio *chip);
 
38
 
 
39
 
 
40
static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
 
41
{
 
42
        int err;
 
43
 
 
44
        DE_INIT(("init_hw() - Layla20\n"));
 
45
        if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20))
 
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->has_midi = TRUE;
 
57
        chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP];
 
58
        chip->input_clock_types =
 
59
                ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
 
60
                ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
 
61
        chip->output_clock_types =
 
62
                ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
 
63
 
 
64
        if ((err = load_firmware(chip)) < 0)
 
65
                return err;
 
66
        chip->bad_board = FALSE;
 
67
 
 
68
        if ((err = init_line_levels(chip)) < 0)
 
69
                return err;
 
70
 
 
71
        err = set_professional_spdif(chip, TRUE);
 
72
 
 
73
        DE_INIT(("init_hw done\n"));
 
74
        return err;
 
75
}
 
76
 
 
77
 
 
78
 
 
79
static u32 detect_input_clocks(const struct echoaudio *chip)
 
80
{
 
81
        u32 clocks_from_dsp, clock_bits;
 
82
 
 
83
        /* Map the DSP clock detect bits to the generic driver clock detect bits */
 
84
        clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
 
85
 
 
86
        clock_bits = ECHO_CLOCK_BIT_INTERNAL;
 
87
 
 
88
        if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
 
89
                clock_bits |= ECHO_CLOCK_BIT_SPDIF;
 
90
 
 
91
        if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) {
 
92
                if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER)
 
93
                        clock_bits |= ECHO_CLOCK_BIT_SUPER;
 
94
                else
 
95
                        clock_bits |= ECHO_CLOCK_BIT_WORD;
 
96
        }
 
97
 
 
98
        return clock_bits;
 
99
}
 
100
 
 
101
 
 
102
 
 
103
/* ASIC status check - some cards have one or two ASICs that need to be
 
104
loaded.  Once that load is complete, this function is called to see if
 
105
the load was successful.
 
106
If this load fails, it does not necessarily mean that the hardware is
 
107
defective - the external box may be disconnected or turned off.
 
108
This routine sometimes fails for Layla20; for Layla20, the loop runs
 
109
5 times and succeeds if it wins on three of the loops. */
 
110
static int check_asic_status(struct echoaudio *chip)
 
111
{
 
112
        u32 asic_status;
 
113
        int goodcnt, i;
 
114
 
 
115
        chip->asic_loaded = FALSE;
 
116
        for (i = goodcnt = 0; i < 5; i++) {
 
117
                send_vector(chip, DSP_VC_TEST_ASIC);
 
118
 
 
119
                /* The DSP will return a value to indicate whether or not
 
120
                   the ASIC is currently loaded */
 
121
                if (read_dsp(chip, &asic_status) < 0) {
 
122
                        DE_ACT(("check_asic_status: failed on read_dsp\n"));
 
123
                        return -EIO;
 
124
                }
 
125
 
 
126
                if (asic_status == ASIC_ALREADY_LOADED) {
 
127
                        if (++goodcnt == 3) {
 
128
                                chip->asic_loaded = TRUE;
 
129
                                return 0;
 
130
                        }
 
131
                }
 
132
        }
 
133
        return -EIO;
 
134
}
 
135
 
 
136
 
 
137
 
 
138
/* Layla20 has an ASIC in the external box */
 
139
static int load_asic(struct echoaudio *chip)
 
140
{
 
141
        int err;
 
142
 
 
143
        if (chip->asic_loaded)
 
144
                return 0;
 
145
 
 
146
        err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
 
147
                                &card_fw[FW_LAYLA20_ASIC]);
 
148
        if (err < 0)
 
149
                return err;
 
150
 
 
151
        /* Check if ASIC is alive and well. */
 
152
        return check_asic_status(chip);
 
153
}
 
154
 
 
155
 
 
156
 
 
157
static int set_sample_rate(struct echoaudio *chip, u32 rate)
 
158
{
 
159
        if (snd_BUG_ON(rate < 8000 || rate > 50000))
 
160
                return -EINVAL;
 
161
 
 
162
        /* Only set the clock for internal mode. Do not return failure,
 
163
           simply treat it as a non-event. */
 
164
        if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
 
165
                DE_ACT(("set_sample_rate: Cannot set sample rate - "
 
166
                        "clock not set to CLK_CLOCKININTERNAL\n"));
 
167
                chip->comm_page->sample_rate = cpu_to_le32(rate);
 
168
                chip->sample_rate = rate;
 
169
                return 0;
 
170
        }
 
171
 
 
172
        if (wait_handshake(chip))
 
173
                return -EIO;
 
174
 
 
175
        DE_ACT(("set_sample_rate(%d)\n", rate));
 
176
        chip->sample_rate = rate;
 
177
        chip->comm_page->sample_rate = cpu_to_le32(rate);
 
178
        clear_handshake(chip);
 
179
        return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE);
 
180
}
 
181
 
 
182
 
 
183
 
 
184
static int set_input_clock(struct echoaudio *chip, u16 clock_source)
 
185
{
 
186
        u16 clock;
 
187
        u32 rate;
 
188
 
 
189
        DE_ACT(("set_input_clock:\n"));
 
190
        rate = 0;
 
191
        switch (clock_source) {
 
192
        case ECHO_CLOCK_INTERNAL:
 
193
                DE_ACT(("Set Layla20 clock to INTERNAL\n"));
 
194
                rate = chip->sample_rate;
 
195
                clock = LAYLA20_CLOCK_INTERNAL;
 
196
                break;
 
197
        case ECHO_CLOCK_SPDIF:
 
198
                DE_ACT(("Set Layla20 clock to SPDIF\n"));
 
199
                clock = LAYLA20_CLOCK_SPDIF;
 
200
                break;
 
201
        case ECHO_CLOCK_WORD:
 
202
                DE_ACT(("Set Layla20 clock to WORD\n"));
 
203
                clock = LAYLA20_CLOCK_WORD;
 
204
                break;
 
205
        case ECHO_CLOCK_SUPER:
 
206
                DE_ACT(("Set Layla20 clock to SUPER\n"));
 
207
                clock = LAYLA20_CLOCK_SUPER;
 
208
                break;
 
209
        default:
 
210
                DE_ACT(("Input clock 0x%x not supported for Layla24\n",
 
211
                        clock_source));
 
212
                return -EINVAL;
 
213
        }
 
214
        chip->input_clock = clock_source;
 
215
 
 
216
        chip->comm_page->input_clock = cpu_to_le16(clock);
 
217
        clear_handshake(chip);
 
218
        send_vector(chip, DSP_VC_UPDATE_CLOCKS);
 
219
 
 
220
        if (rate)
 
221
                set_sample_rate(chip, rate);
 
222
 
 
223
        return 0;
 
224
}
 
225
 
 
226
 
 
227
 
 
228
static int set_output_clock(struct echoaudio *chip, u16 clock)
 
229
{
 
230
        DE_ACT(("set_output_clock: %d\n", clock));
 
231
        switch (clock) {
 
232
        case ECHO_CLOCK_SUPER:
 
233
                clock = LAYLA20_OUTPUT_CLOCK_SUPER;
 
234
                break;
 
235
        case ECHO_CLOCK_WORD:
 
236
                clock = LAYLA20_OUTPUT_CLOCK_WORD;
 
237
                break;
 
238
        default:
 
239
                DE_ACT(("set_output_clock wrong clock\n"));
 
240
                return -EINVAL;
 
241
        }
 
242
 
 
243
        if (wait_handshake(chip))
 
244
                return -EIO;
 
245
 
 
246
        chip->comm_page->output_clock = cpu_to_le16(clock);
 
247
        chip->output_clock = clock;
 
248
        clear_handshake(chip);
 
249
        return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
 
250
}
 
251
 
 
252
 
 
253
 
 
254
/* Set input bus gain (one unit is 0.5dB !) */
 
255
static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
 
256
{
 
257
        if (snd_BUG_ON(input >= num_busses_in(chip)))
 
258
                return -EINVAL;
 
259
 
 
260
        if (wait_handshake(chip))
 
261
                return -EIO;
 
262
 
 
263
        chip->input_gain[input] = gain;
 
264
        gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
 
265
        chip->comm_page->line_in_level[input] = gain;
 
266
        return 0;
 
267
}
 
268
 
 
269
 
 
270
 
 
271
/* Tell the DSP to reread the flags from the comm page */
 
272
static int update_flags(struct echoaudio *chip)
 
273
{
 
274
        if (wait_handshake(chip))
 
275
                return -EIO;
 
276
        clear_handshake(chip);
 
277
        return send_vector(chip, DSP_VC_UPDATE_FLAGS);
 
278
}
 
279
 
 
280
 
 
281
 
 
282
static int set_professional_spdif(struct echoaudio *chip, char prof)
 
283
{
 
284
        DE_ACT(("set_professional_spdif %d\n", prof));
 
285
        if (prof)
 
286
                chip->comm_page->flags |=
 
287
                        cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
 
288
        else
 
289
                chip->comm_page->flags &=
 
290
                        ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
 
291
        chip->professional_spdif = prof;
 
292
        return update_flags(chip);
 
293
}