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