Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/echoaudio/gina20_dsp.c
26451 views
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 <[email protected]>
28
29
****************************************************************************/
30
31
32
static int set_professional_spdif(struct echoaudio *chip, char prof);
33
static int update_flags(struct echoaudio *chip);
34
35
36
static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
37
{
38
int err;
39
40
if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20))
41
return -ENODEV;
42
43
err = init_dsp_comm_page(chip);
44
if (err) {
45
dev_err(chip->card->dev,
46
"init_hw - could not initialize DSP comm page\n");
47
return err;
48
}
49
50
chip->device_id = device_id;
51
chip->subdevice_id = subdevice_id;
52
chip->bad_board = true;
53
chip->dsp_code_to_load = FW_GINA20_DSP;
54
chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
55
chip->clock_state = GD_CLOCK_UNDEF;
56
/* Since this card has no ASIC, mark it as loaded so everything
57
works OK */
58
chip->asic_loaded = true;
59
chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
60
ECHO_CLOCK_BIT_SPDIF;
61
62
err = load_firmware(chip);
63
if (err < 0)
64
return err;
65
chip->bad_board = false;
66
67
return err;
68
}
69
70
71
72
static int set_mixer_defaults(struct echoaudio *chip)
73
{
74
chip->professional_spdif = false;
75
return init_line_levels(chip);
76
}
77
78
79
80
static u32 detect_input_clocks(const struct echoaudio *chip)
81
{
82
u32 clocks_from_dsp, clock_bits;
83
84
/* Map the DSP clock detect bits to the generic driver clock
85
detect bits */
86
clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
87
88
clock_bits = ECHO_CLOCK_BIT_INTERNAL;
89
90
if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
91
clock_bits |= ECHO_CLOCK_BIT_SPDIF;
92
93
return clock_bits;
94
}
95
96
97
98
/* The Gina20 has no ASIC. Just do nothing */
99
static int load_asic(struct echoaudio *chip)
100
{
101
return 0;
102
}
103
104
105
106
static int set_sample_rate(struct echoaudio *chip, u32 rate)
107
{
108
u8 clock_state, spdif_status;
109
110
if (wait_handshake(chip))
111
return -EIO;
112
113
switch (rate) {
114
case 44100:
115
clock_state = GD_CLOCK_44;
116
spdif_status = GD_SPDIF_STATUS_44;
117
break;
118
case 48000:
119
clock_state = GD_CLOCK_48;
120
spdif_status = GD_SPDIF_STATUS_48;
121
break;
122
default:
123
clock_state = GD_CLOCK_NOCHANGE;
124
spdif_status = GD_SPDIF_STATUS_NOCHANGE;
125
break;
126
}
127
128
if (chip->clock_state == clock_state)
129
clock_state = GD_CLOCK_NOCHANGE;
130
if (spdif_status == chip->spdif_status)
131
spdif_status = GD_SPDIF_STATUS_NOCHANGE;
132
133
chip->comm_page->sample_rate = cpu_to_le32(rate);
134
chip->comm_page->gd_clock_state = clock_state;
135
chip->comm_page->gd_spdif_status = spdif_status;
136
chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */
137
138
/* Save the new audio state if it changed */
139
if (clock_state != GD_CLOCK_NOCHANGE)
140
chip->clock_state = clock_state;
141
if (spdif_status != GD_SPDIF_STATUS_NOCHANGE)
142
chip->spdif_status = spdif_status;
143
chip->sample_rate = rate;
144
145
clear_handshake(chip);
146
return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
147
}
148
149
150
151
static int set_input_clock(struct echoaudio *chip, u16 clock)
152
{
153
154
switch (clock) {
155
case ECHO_CLOCK_INTERNAL:
156
/* Reset the audio state to unknown (just in case) */
157
chip->clock_state = GD_CLOCK_UNDEF;
158
chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
159
set_sample_rate(chip, chip->sample_rate);
160
chip->input_clock = clock;
161
break;
162
case ECHO_CLOCK_SPDIF:
163
chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN;
164
chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE;
165
clear_handshake(chip);
166
send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
167
chip->clock_state = GD_CLOCK_SPDIFIN;
168
chip->input_clock = clock;
169
break;
170
default:
171
return -EINVAL;
172
}
173
174
return 0;
175
}
176
177
178
179
/* Set input bus gain (one unit is 0.5dB !) */
180
static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
181
{
182
if (snd_BUG_ON(input >= num_busses_in(chip)))
183
return -EINVAL;
184
185
if (wait_handshake(chip))
186
return -EIO;
187
188
chip->input_gain[input] = gain;
189
gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
190
chip->comm_page->line_in_level[input] = gain;
191
return 0;
192
}
193
194
195
196
/* Tell the DSP to reread the flags from the comm page */
197
static int update_flags(struct echoaudio *chip)
198
{
199
if (wait_handshake(chip))
200
return -EIO;
201
clear_handshake(chip);
202
return send_vector(chip, DSP_VC_UPDATE_FLAGS);
203
}
204
205
206
207
static int set_professional_spdif(struct echoaudio *chip, char prof)
208
{
209
if (prof)
210
chip->comm_page->flags |=
211
cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
212
else
213
chip->comm_page->flags &=
214
~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
215
chip->professional_spdif = prof;
216
return update_flags(chip);
217
}
218
219