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/* 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		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
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{
66	/* Handle the digital input auto-mute */
67	if (chip->digital_in_automute)
68		value |= GML_DIGITAL_IN_AUTO_MUTE;
69	else
70		value &= ~GML_DIGITAL_IN_AUTO_MUTE;
71
72	dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value);
73
74	/* Write the control register */
75	value = cpu_to_le32(value);
76	if (value != chip->comm_page->control_register || force) {
77		if (wait_handshake(chip))
78			return -EIO;
79		chip->comm_page->control_register = value;
80		clear_handshake(chip);
81		return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
82	}
83	return 0;
84}
85
86
87
88/* Gina24, Layla24, and Mona support digital input auto-mute.  If the digital
89input auto-mute is enabled, the DSP will only enable the digital inputs if
90the card is syncing to a valid clock on the ADAT or S/PDIF inputs.
91If the auto-mute is disabled, the digital inputs are enabled regardless of
92what the input clock is set or what is connected. */
93static int set_input_auto_mute(struct echoaudio *chip, int automute)
94{
95	dev_dbg(chip->card->dev, "set_input_auto_mute %d\n", automute);
96
97	chip->digital_in_automute = automute;
98
99	/* Re-set the input clock to the current value - indirectly causes
100	the auto-mute flag to be sent to the DSP */
101	return set_input_clock(chip, chip->input_clock);
102}
103
104
105
106/* S/PDIF coax / S/PDIF optical / ADAT - switch */
107static int set_digital_mode(struct echoaudio *chip, u8 mode)
108{
109	u8 previous_mode;
110	int err, i, o;
111
112	if (chip->bad_board)
113		return -EIO;
114
115	/* All audio channels must be closed before changing the digital mode */
116	if (snd_BUG_ON(chip->pipe_alloc_mask))
117		return -EAGAIN;
118
119	if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
120		return -EINVAL;
121
122	previous_mode = chip->digital_mode;
123	err = dsp_set_digital_mode(chip, mode);
124
125	/* If we successfully changed the digital mode from or to ADAT,
126	   then make sure all output, input and monitor levels are
127	   updated by the DSP comm object. */
128	if (err >= 0 && previous_mode != mode &&
129	    (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
130		spin_lock_irq(&chip->lock);
131		for (o = 0; o < num_busses_out(chip); o++)
132			for (i = 0; i < num_busses_in(chip); i++)
133				set_monitor_gain(chip, o, i,
134						 chip->monitor_gain[o][i]);
135
136#ifdef ECHOCARD_HAS_INPUT_GAIN
137		for (i = 0; i < num_busses_in(chip); i++)
138			set_input_gain(chip, i, chip->input_gain[i]);
139		update_input_line_level(chip);
140#endif
141
142		for (o = 0; o < num_busses_out(chip); o++)
143			set_output_gain(chip, o, chip->output_gain[o]);
144		update_output_line_level(chip);
145		spin_unlock_irq(&chip->lock);
146	}
147
148	return err;
149}
150
151
152
153/* Set the S/PDIF output format */
154static int set_professional_spdif(struct echoaudio *chip, char prof)
155{
156	u32 control_reg;
157	int err;
158
159	/* Clear the current S/PDIF flags */
160	control_reg = le32_to_cpu(chip->comm_page->control_register);
161	control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK;
162
163	/* Set the new S/PDIF flags depending on the mode */
164	control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT |
165		GML_SPDIF_COPY_PERMIT;
166	if (prof) {
167		/* Professional mode */
168		control_reg |= GML_SPDIF_PRO_MODE;
169
170		switch (chip->sample_rate) {
171		case 32000:
172			control_reg |= GML_SPDIF_SAMPLE_RATE0 |
173				GML_SPDIF_SAMPLE_RATE1;
174			break;
175		case 44100:
176			control_reg |= GML_SPDIF_SAMPLE_RATE0;
177			break;
178		case 48000:
179			control_reg |= GML_SPDIF_SAMPLE_RATE1;
180			break;
181		}
182	} else {
183		/* Consumer mode */
184		switch (chip->sample_rate) {
185		case 32000:
186			control_reg |= GML_SPDIF_SAMPLE_RATE0 |
187				GML_SPDIF_SAMPLE_RATE1;
188			break;
189		case 48000:
190			control_reg |= GML_SPDIF_SAMPLE_RATE1;
191			break;
192		}
193	}
194
195	if ((err = write_control_reg(chip, control_reg, FALSE)))
196		return err;
197	chip->professional_spdif = prof;
198	dev_dbg(chip->card->dev, "set_professional_spdif to %s\n",
199		prof ? "Professional" : "Consumer");
200	return 0;
201}
202