diff options
author | Giuliano Pochini <pochini@shiny.it> | 2006-06-28 07:53:41 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-06-28 13:31:20 -0400 |
commit | dd7b254d8dd3a9528f423ac3bf875e6f0c8da561 (patch) | |
tree | 923ac13451c796b730f21c7260beba9f74acff63 /sound/pci/echoaudio/echoaudio_gml.c | |
parent | cb9d24e4349013628259b5fee97e692173731b07 (diff) |
[ALSA] Add echoaudio sound drivers
From: Giuliano Pochini <pochini@shiny.it>Add echoaudio sound drivers (darla20, darla24, echo3g, gina20, gina24,
indigo, indigodj, indigoio, layla20, lala24, mia, mona)
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/echoaudio/echoaudio_gml.c')
-rw-r--r-- | sound/pci/echoaudio/echoaudio_gml.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c new file mode 100644 index 000000000000..3aa37e76ebab --- /dev/null +++ b/sound/pci/echoaudio/echoaudio_gml.c | |||
@@ -0,0 +1,198 @@ | |||
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 | ||
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 | 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 | ||
61 | the control register. write_control_reg sends the new control register | ||
62 | value to the DSP. */ | ||
63 | static 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 | ||
88 | input auto-mute is enabled, the DSP will only enable the digital inputs if | ||
89 | the card is syncing to a valid clock on the ADAT or S/PDIF inputs. | ||
90 | If the auto-mute is disabled, the digital inputs are enabled regardless of | ||
91 | what the input clock is set or what is connected. */ | ||
92 | static 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 */ | ||
106 | static 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 */ | ||
115 | snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); | ||
116 | |||
117 | snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); | ||
118 | |||
119 | previous_mode = chip->digital_mode; | ||
120 | err = dsp_set_digital_mode(chip, mode); | ||
121 | |||
122 | /* If we successfully changed the digital mode from or to ADAT, | ||
123 | then make sure all output, input and monitor levels are | ||
124 | updated by the DSP comm object. */ | ||
125 | if (err >= 0 && previous_mode != mode && | ||
126 | (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { | ||
127 | spin_lock_irq(&chip->lock); | ||
128 | for (o = 0; o < num_busses_out(chip); o++) | ||
129 | for (i = 0; i < num_busses_in(chip); i++) | ||
130 | set_monitor_gain(chip, o, i, | ||
131 | chip->monitor_gain[o][i]); | ||
132 | |||
133 | #ifdef ECHOCARD_HAS_INPUT_GAIN | ||
134 | for (i = 0; i < num_busses_in(chip); i++) | ||
135 | set_input_gain(chip, i, chip->input_gain[i]); | ||
136 | update_input_line_level(chip); | ||
137 | #endif | ||
138 | |||
139 | for (o = 0; o < num_busses_out(chip); o++) | ||
140 | set_output_gain(chip, o, chip->output_gain[o]); | ||
141 | update_output_line_level(chip); | ||
142 | spin_unlock_irq(&chip->lock); | ||
143 | } | ||
144 | |||
145 | return err; | ||
146 | } | ||
147 | |||
148 | |||
149 | |||
150 | /* Set the S/PDIF output format */ | ||
151 | static int set_professional_spdif(struct echoaudio *chip, char prof) | ||
152 | { | ||
153 | u32 control_reg; | ||
154 | int err; | ||
155 | |||
156 | /* Clear the current S/PDIF flags */ | ||
157 | control_reg = le32_to_cpu(chip->comm_page->control_register); | ||
158 | control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK; | ||
159 | |||
160 | /* Set the new S/PDIF flags depending on the mode */ | ||
161 | control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT | | ||
162 | GML_SPDIF_COPY_PERMIT; | ||
163 | if (prof) { | ||
164 | /* Professional mode */ | ||
165 | control_reg |= GML_SPDIF_PRO_MODE; | ||
166 | |||
167 | switch (chip->sample_rate) { | ||
168 | case 32000: | ||
169 | control_reg |= GML_SPDIF_SAMPLE_RATE0 | | ||
170 | GML_SPDIF_SAMPLE_RATE1; | ||
171 | break; | ||
172 | case 44100: | ||
173 | control_reg |= GML_SPDIF_SAMPLE_RATE0; | ||
174 | break; | ||
175 | case 48000: | ||
176 | control_reg |= GML_SPDIF_SAMPLE_RATE1; | ||
177 | break; | ||
178 | } | ||
179 | } else { | ||
180 | /* Consumer mode */ | ||
181 | switch (chip->sample_rate) { | ||
182 | case 32000: | ||
183 | control_reg |= GML_SPDIF_SAMPLE_RATE0 | | ||
184 | GML_SPDIF_SAMPLE_RATE1; | ||
185 | break; | ||
186 | case 48000: | ||
187 | control_reg |= GML_SPDIF_SAMPLE_RATE1; | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | if ((err = write_control_reg(chip, control_reg, FALSE))) | ||
193 | return err; | ||
194 | chip->professional_spdif = prof; | ||
195 | DE_ACT(("set_professional_spdif to %s\n", | ||
196 | prof ? "Professional" : "Consumer")); | ||
197 | return 0; | ||
198 | } | ||