Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/echoaudio/echoaudio_gml.c
26424 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
/* These functions are common for Gina24, Layla24 and Mona cards */
33
34
35
/* ASIC status check - some cards have one or two ASICs that need to be
36
loaded. Once that load is complete, this function is called to see if
37
the load was successful.
38
If this load fails, it does not necessarily mean that the hardware is
39
defective - the external box may be disconnected or turned off. */
40
static int check_asic_status(struct echoaudio *chip)
41
{
42
u32 asic_status;
43
44
send_vector(chip, DSP_VC_TEST_ASIC);
45
46
/* The DSP will return a value to indicate whether or not the
47
ASIC is currently loaded */
48
if (read_dsp(chip, &asic_status) < 0) {
49
dev_err(chip->card->dev,
50
"check_asic_status: failed on read_dsp\n");
51
chip->asic_loaded = false;
52
return -EIO;
53
}
54
55
chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED);
56
return chip->asic_loaded ? 0 : -EIO;
57
}
58
59
60
61
/* Most configuration of Gina24, Layla24, or Mona is accomplished by writing
62
the control register. write_control_reg sends the new control register
63
value to the DSP. */
64
static int write_control_reg(struct echoaudio *chip, u32 value, char force)
65
{
66
__le32 reg_value;
67
68
/* Handle the digital input auto-mute */
69
if (chip->digital_in_automute)
70
value |= GML_DIGITAL_IN_AUTO_MUTE;
71
else
72
value &= ~GML_DIGITAL_IN_AUTO_MUTE;
73
74
dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value);
75
76
/* Write the control register */
77
reg_value = cpu_to_le32(value);
78
if (reg_value != chip->comm_page->control_register || force) {
79
if (wait_handshake(chip))
80
return -EIO;
81
chip->comm_page->control_register = reg_value;
82
clear_handshake(chip);
83
return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
84
}
85
return 0;
86
}
87
88
89
90
/* Gina24, Layla24, and Mona support digital input auto-mute. If the digital
91
input auto-mute is enabled, the DSP will only enable the digital inputs if
92
the card is syncing to a valid clock on the ADAT or S/PDIF inputs.
93
If the auto-mute is disabled, the digital inputs are enabled regardless of
94
what the input clock is set or what is connected. */
95
static int set_input_auto_mute(struct echoaudio *chip, int automute)
96
{
97
dev_dbg(chip->card->dev, "set_input_auto_mute %d\n", automute);
98
99
chip->digital_in_automute = automute;
100
101
/* Re-set the input clock to the current value - indirectly causes
102
the auto-mute flag to be sent to the DSP */
103
return set_input_clock(chip, chip->input_clock);
104
}
105
106
107
108
/* S/PDIF coax / S/PDIF optical / ADAT - switch */
109
static int set_digital_mode(struct echoaudio *chip, u8 mode)
110
{
111
u8 previous_mode;
112
int err, i, o;
113
114
if (chip->bad_board)
115
return -EIO;
116
117
/* All audio channels must be closed before changing the digital mode */
118
if (snd_BUG_ON(chip->pipe_alloc_mask))
119
return -EAGAIN;
120
121
if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
122
return -EINVAL;
123
124
previous_mode = chip->digital_mode;
125
err = dsp_set_digital_mode(chip, mode);
126
127
/* If we successfully changed the digital mode from or to ADAT,
128
then make sure all output, input and monitor levels are
129
updated by the DSP comm object. */
130
if (err >= 0 && previous_mode != mode &&
131
(previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
132
spin_lock_irq(&chip->lock);
133
for (o = 0; o < num_busses_out(chip); o++)
134
for (i = 0; i < num_busses_in(chip); i++)
135
set_monitor_gain(chip, o, i,
136
chip->monitor_gain[o][i]);
137
138
#ifdef ECHOCARD_HAS_INPUT_GAIN
139
for (i = 0; i < num_busses_in(chip); i++)
140
set_input_gain(chip, i, chip->input_gain[i]);
141
update_input_line_level(chip);
142
#endif
143
144
for (o = 0; o < num_busses_out(chip); o++)
145
set_output_gain(chip, o, chip->output_gain[o]);
146
update_output_line_level(chip);
147
spin_unlock_irq(&chip->lock);
148
}
149
150
return err;
151
}
152
153
154
155
/* Set the S/PDIF output format */
156
static int set_professional_spdif(struct echoaudio *chip, char prof)
157
{
158
u32 control_reg;
159
int err;
160
161
/* Clear the current S/PDIF flags */
162
control_reg = le32_to_cpu(chip->comm_page->control_register);
163
control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK;
164
165
/* Set the new S/PDIF flags depending on the mode */
166
control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT |
167
GML_SPDIF_COPY_PERMIT;
168
if (prof) {
169
/* Professional mode */
170
control_reg |= GML_SPDIF_PRO_MODE;
171
172
switch (chip->sample_rate) {
173
case 32000:
174
control_reg |= GML_SPDIF_SAMPLE_RATE0 |
175
GML_SPDIF_SAMPLE_RATE1;
176
break;
177
case 44100:
178
control_reg |= GML_SPDIF_SAMPLE_RATE0;
179
break;
180
case 48000:
181
control_reg |= GML_SPDIF_SAMPLE_RATE1;
182
break;
183
}
184
} else {
185
/* Consumer mode */
186
switch (chip->sample_rate) {
187
case 32000:
188
control_reg |= GML_SPDIF_SAMPLE_RATE0 |
189
GML_SPDIF_SAMPLE_RATE1;
190
break;
191
case 48000:
192
control_reg |= GML_SPDIF_SAMPLE_RATE1;
193
break;
194
}
195
}
196
197
err = write_control_reg(chip, control_reg, false);
198
if (err)
199
return err;
200
chip->professional_spdif = prof;
201
dev_dbg(chip->card->dev, "set_professional_spdif to %s\n",
202
prof ? "Professional" : "Consumer");
203
return 0;
204
}
205
206