blob: eea6fe530ab4b000cea7d00afedc538115a71b5d [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) {
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +053049 dev_err(chip->card->dev,
50 "check_asic_status: failed on read_dsp\n");
Mark Brown3f6175e2015-08-10 13:02:53 +010051 chip->asic_loaded = false;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020052 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
62the control register. write_control_reg sends the new control register
63value to the DSP. */
64static int write_control_reg(struct echoaudio *chip, u32 value, char force)
65{
Takashi Iwai2a833a02018-07-25 23:24:10 +020066 __le32 reg_value;
67
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020068 /* 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
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +053074 dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020075
76 /* Write the control register */
Takashi Iwai2a833a02018-07-25 23:24:10 +020077 reg_value = cpu_to_le32(value);
78 if (reg_value != chip->comm_page->control_register || force) {
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020079 if (wait_handshake(chip))
80 return -EIO;
Takashi Iwai2a833a02018-07-25 23:24:10 +020081 chip->comm_page->control_register = reg_value;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020082 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
91input auto-mute is enabled, the DSP will only enable the digital inputs if
92the card is syncing to a valid clock on the ADAT or S/PDIF inputs.
93If the auto-mute is disabled, the digital inputs are enabled regardless of
94what the input clock is set or what is connected. */
95static int set_input_auto_mute(struct echoaudio *chip, int automute)
96{
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +053097 dev_dbg(chip->card->dev, "set_input_auto_mute %d\n", automute);
Giuliano Pochinidd7b2542006-06-28 13:53:41 +020098
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 */
109static 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 */
Takashi Iwaida3cec32008-08-08 17:12:14 +0200118 if (snd_BUG_ON(chip->pipe_alloc_mask))
119 return -EAGAIN;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200120
Takashi Iwaida3cec32008-08-08 17:12:14 +0200121 if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
122 return -EINVAL;
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200123
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 */
156static 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
Mark Brown3f6175e2015-08-10 13:02:53 +0100197 if ((err = write_control_reg(chip, control_reg, false)))
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200198 return err;
199 chip->professional_spdif = prof;
Sudip Mukherjeeb5b4a412014-11-03 16:04:13 +0530200 dev_dbg(chip->card->dev, "set_professional_spdif to %s\n",
201 prof ? "Professional" : "Consumer");
Giuliano Pochinidd7b2542006-06-28 13:53:41 +0200202 return 0;
203}