1dd7b254dSGiuliano Pochini /****************************************************************************
2dd7b254dSGiuliano Pochini
3dd7b254dSGiuliano Pochini Copyright Echo Digital Audio Corporation (c) 1998 - 2004
4dd7b254dSGiuliano Pochini All rights reserved
5dd7b254dSGiuliano Pochini www.echoaudio.com
6dd7b254dSGiuliano Pochini
7dd7b254dSGiuliano Pochini This file is part of Echo Digital Audio's generic driver library.
8dd7b254dSGiuliano Pochini
9dd7b254dSGiuliano Pochini Echo Digital Audio's generic driver library is free software;
10dd7b254dSGiuliano Pochini you can redistribute it and/or modify it under the terms of
11dd7b254dSGiuliano Pochini the GNU General Public License as published by the Free Software
12dd7b254dSGiuliano Pochini Foundation.
13dd7b254dSGiuliano Pochini
14dd7b254dSGiuliano Pochini This program is distributed in the hope that it will be useful,
15dd7b254dSGiuliano Pochini but WITHOUT ANY WARRANTY; without even the implied warranty of
16dd7b254dSGiuliano Pochini MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17dd7b254dSGiuliano Pochini GNU General Public License for more details.
18dd7b254dSGiuliano Pochini
19dd7b254dSGiuliano Pochini You should have received a copy of the GNU General Public License
20dd7b254dSGiuliano Pochini along with this program; if not, write to the Free Software
21dd7b254dSGiuliano Pochini Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22dd7b254dSGiuliano Pochini MA 02111-1307, USA.
23dd7b254dSGiuliano Pochini
24dd7b254dSGiuliano Pochini *************************************************************************
25dd7b254dSGiuliano Pochini
26dd7b254dSGiuliano Pochini Translation from C++ and adaptation for use in ALSA-Driver
27dd7b254dSGiuliano Pochini were made by Giuliano Pochini <pochini@shiny.it>
28dd7b254dSGiuliano Pochini
29dd7b254dSGiuliano Pochini ****************************************************************************/
30dd7b254dSGiuliano Pochini
31dd7b254dSGiuliano Pochini
32dd7b254dSGiuliano Pochini
33dd7b254dSGiuliano Pochini /* These functions are common for all "3G" cards */
34dd7b254dSGiuliano Pochini
35dd7b254dSGiuliano Pochini
check_asic_status(struct echoaudio * chip)36dd7b254dSGiuliano Pochini static int check_asic_status(struct echoaudio *chip)
37dd7b254dSGiuliano Pochini {
38dd7b254dSGiuliano Pochini u32 box_status;
39dd7b254dSGiuliano Pochini
40dd7b254dSGiuliano Pochini if (wait_handshake(chip))
41dd7b254dSGiuliano Pochini return -EIO;
42dd7b254dSGiuliano Pochini
43e930e995SHarvey Harrison chip->comm_page->ext_box_status = cpu_to_le32(E3G_ASIC_NOT_LOADED);
443f6175ecSMark Brown chip->asic_loaded = false;
45dd7b254dSGiuliano Pochini clear_handshake(chip);
46dd7b254dSGiuliano Pochini send_vector(chip, DSP_VC_TEST_ASIC);
47dd7b254dSGiuliano Pochini
48dd7b254dSGiuliano Pochini if (wait_handshake(chip)) {
49dd7b254dSGiuliano Pochini chip->dsp_code = NULL;
50dd7b254dSGiuliano Pochini return -EIO;
51dd7b254dSGiuliano Pochini }
52dd7b254dSGiuliano Pochini
53dd7b254dSGiuliano Pochini box_status = le32_to_cpu(chip->comm_page->ext_box_status);
54b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev, "box_status=%x\n", box_status);
55dd7b254dSGiuliano Pochini if (box_status == E3G_ASIC_NOT_LOADED)
56dd7b254dSGiuliano Pochini return -ENODEV;
57dd7b254dSGiuliano Pochini
583f6175ecSMark Brown chip->asic_loaded = true;
59dd7b254dSGiuliano Pochini return box_status & E3G_BOX_TYPE_MASK;
60dd7b254dSGiuliano Pochini }
61dd7b254dSGiuliano Pochini
62dd7b254dSGiuliano Pochini
63dd7b254dSGiuliano Pochini
get_frq_reg(struct echoaudio * chip)64dd7b254dSGiuliano Pochini static inline u32 get_frq_reg(struct echoaudio *chip)
65dd7b254dSGiuliano Pochini {
66dd7b254dSGiuliano Pochini return le32_to_cpu(chip->comm_page->e3g_frq_register);
67dd7b254dSGiuliano Pochini }
68dd7b254dSGiuliano Pochini
69dd7b254dSGiuliano Pochini
70dd7b254dSGiuliano Pochini
71dd7b254dSGiuliano Pochini /* Most configuration of 3G cards is accomplished by writing the control
72dd7b254dSGiuliano Pochini register. write_control_reg sends the new control register value to the DSP. */
write_control_reg(struct echoaudio * chip,u32 ctl,u32 frq,char force)73dd7b254dSGiuliano Pochini static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
74dd7b254dSGiuliano Pochini char force)
75dd7b254dSGiuliano Pochini {
76*2a833a02STakashi Iwai __le32 ctl_reg, frq_reg;
77*2a833a02STakashi Iwai
78dd7b254dSGiuliano Pochini if (wait_handshake(chip))
79dd7b254dSGiuliano Pochini return -EIO;
80dd7b254dSGiuliano Pochini
81b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev,
82b5b4a41bSSudip Mukherjee "WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq);
83dd7b254dSGiuliano Pochini
84*2a833a02STakashi Iwai ctl_reg = cpu_to_le32(ctl);
85*2a833a02STakashi Iwai frq_reg = cpu_to_le32(frq);
86dd7b254dSGiuliano Pochini
87*2a833a02STakashi Iwai if (ctl_reg != chip->comm_page->control_register ||
88*2a833a02STakashi Iwai frq_reg != chip->comm_page->e3g_frq_register || force) {
89*2a833a02STakashi Iwai chip->comm_page->e3g_frq_register = frq_reg;
90*2a833a02STakashi Iwai chip->comm_page->control_register = ctl_reg;
91dd7b254dSGiuliano Pochini clear_handshake(chip);
92dd7b254dSGiuliano Pochini return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
93dd7b254dSGiuliano Pochini }
94dd7b254dSGiuliano Pochini
95b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev, "WriteControlReg: not written, no change\n");
96dd7b254dSGiuliano Pochini return 0;
97dd7b254dSGiuliano Pochini }
98dd7b254dSGiuliano Pochini
99dd7b254dSGiuliano Pochini
100dd7b254dSGiuliano Pochini
101dd7b254dSGiuliano Pochini /* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */
set_digital_mode(struct echoaudio * chip,u8 mode)102dd7b254dSGiuliano Pochini static int set_digital_mode(struct echoaudio *chip, u8 mode)
103dd7b254dSGiuliano Pochini {
104dd7b254dSGiuliano Pochini u8 previous_mode;
105dd7b254dSGiuliano Pochini int err, i, o;
106dd7b254dSGiuliano Pochini
107dd7b254dSGiuliano Pochini /* All audio channels must be closed before changing the digital mode */
108da3cec35STakashi Iwai if (snd_BUG_ON(chip->pipe_alloc_mask))
109da3cec35STakashi Iwai return -EAGAIN;
110dd7b254dSGiuliano Pochini
111da3cec35STakashi Iwai if (snd_BUG_ON(!(chip->digital_modes & (1 << mode))))
112da3cec35STakashi Iwai return -EINVAL;
113dd7b254dSGiuliano Pochini
114dd7b254dSGiuliano Pochini previous_mode = chip->digital_mode;
115dd7b254dSGiuliano Pochini err = dsp_set_digital_mode(chip, mode);
116dd7b254dSGiuliano Pochini
117dd7b254dSGiuliano Pochini /* If we successfully changed the digital mode from or to ADAT,
118dd7b254dSGiuliano Pochini * then make sure all output, input and monitor levels are
119dd7b254dSGiuliano Pochini * updated by the DSP comm object. */
120dd7b254dSGiuliano Pochini if (err >= 0 && previous_mode != mode &&
121dd7b254dSGiuliano Pochini (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) {
122dd7b254dSGiuliano Pochini spin_lock_irq(&chip->lock);
123dd7b254dSGiuliano Pochini for (o = 0; o < num_busses_out(chip); o++)
124dd7b254dSGiuliano Pochini for (i = 0; i < num_busses_in(chip); i++)
125dd7b254dSGiuliano Pochini set_monitor_gain(chip, o, i,
126dd7b254dSGiuliano Pochini chip->monitor_gain[o][i]);
127dd7b254dSGiuliano Pochini
128dd7b254dSGiuliano Pochini #ifdef ECHOCARD_HAS_INPUT_GAIN
129dd7b254dSGiuliano Pochini for (i = 0; i < num_busses_in(chip); i++)
130dd7b254dSGiuliano Pochini set_input_gain(chip, i, chip->input_gain[i]);
131dd7b254dSGiuliano Pochini update_input_line_level(chip);
132dd7b254dSGiuliano Pochini #endif
133dd7b254dSGiuliano Pochini
134dd7b254dSGiuliano Pochini for (o = 0; o < num_busses_out(chip); o++)
135dd7b254dSGiuliano Pochini set_output_gain(chip, o, chip->output_gain[o]);
136dd7b254dSGiuliano Pochini update_output_line_level(chip);
137dd7b254dSGiuliano Pochini spin_unlock_irq(&chip->lock);
138dd7b254dSGiuliano Pochini }
139dd7b254dSGiuliano Pochini
140dd7b254dSGiuliano Pochini return err;
141dd7b254dSGiuliano Pochini }
142dd7b254dSGiuliano Pochini
143dd7b254dSGiuliano Pochini
144dd7b254dSGiuliano Pochini
set_spdif_bits(struct echoaudio * chip,u32 control_reg,u32 rate)145dd7b254dSGiuliano Pochini static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate)
146dd7b254dSGiuliano Pochini {
147dd7b254dSGiuliano Pochini control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK;
148dd7b254dSGiuliano Pochini
149dd7b254dSGiuliano Pochini switch (rate) {
150dd7b254dSGiuliano Pochini case 32000 :
151dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1;
152dd7b254dSGiuliano Pochini break;
153dd7b254dSGiuliano Pochini case 44100 :
154dd7b254dSGiuliano Pochini if (chip->professional_spdif)
155dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_SAMPLE_RATE0;
156dd7b254dSGiuliano Pochini break;
157dd7b254dSGiuliano Pochini case 48000 :
158dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_SAMPLE_RATE1;
159dd7b254dSGiuliano Pochini break;
160dd7b254dSGiuliano Pochini }
161dd7b254dSGiuliano Pochini
162dd7b254dSGiuliano Pochini if (chip->professional_spdif)
163dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_PRO_MODE;
164dd7b254dSGiuliano Pochini
165dd7b254dSGiuliano Pochini if (chip->non_audio_spdif)
166dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_NOT_AUDIO;
167dd7b254dSGiuliano Pochini
168dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL |
169dd7b254dSGiuliano Pochini E3G_SPDIF_COPY_PERMIT;
170dd7b254dSGiuliano Pochini
171dd7b254dSGiuliano Pochini return control_reg;
172dd7b254dSGiuliano Pochini }
173dd7b254dSGiuliano Pochini
174dd7b254dSGiuliano Pochini
175dd7b254dSGiuliano Pochini
176dd7b254dSGiuliano Pochini /* Set the S/PDIF output format */
set_professional_spdif(struct echoaudio * chip,char prof)177dd7b254dSGiuliano Pochini static int set_professional_spdif(struct echoaudio *chip, char prof)
178dd7b254dSGiuliano Pochini {
179dd7b254dSGiuliano Pochini u32 control_reg;
180dd7b254dSGiuliano Pochini
181dd7b254dSGiuliano Pochini control_reg = le32_to_cpu(chip->comm_page->control_register);
182dd7b254dSGiuliano Pochini chip->professional_spdif = prof;
183dd7b254dSGiuliano Pochini control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate);
184dd7b254dSGiuliano Pochini return write_control_reg(chip, control_reg, get_frq_reg(chip), 0);
185dd7b254dSGiuliano Pochini }
186dd7b254dSGiuliano Pochini
187dd7b254dSGiuliano Pochini
188dd7b254dSGiuliano Pochini
189dd7b254dSGiuliano Pochini /* detect_input_clocks() returns a bitmask consisting of all the input clocks
190dd7b254dSGiuliano Pochini currently connected to the hardware; this changes as the user connects and
191dd7b254dSGiuliano Pochini disconnects clock inputs. You should use this information to determine which
192dd7b254dSGiuliano Pochini clocks the user is allowed to select. */
detect_input_clocks(const struct echoaudio * chip)193dd7b254dSGiuliano Pochini static u32 detect_input_clocks(const struct echoaudio *chip)
194dd7b254dSGiuliano Pochini {
195dd7b254dSGiuliano Pochini u32 clocks_from_dsp, clock_bits;
196dd7b254dSGiuliano Pochini
197dd7b254dSGiuliano Pochini /* Map the DSP clock detect bits to the generic driver clock
198dd7b254dSGiuliano Pochini * detect bits */
199dd7b254dSGiuliano Pochini clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
200dd7b254dSGiuliano Pochini
201dd7b254dSGiuliano Pochini clock_bits = ECHO_CLOCK_BIT_INTERNAL;
202dd7b254dSGiuliano Pochini
203dd7b254dSGiuliano Pochini if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD)
204dd7b254dSGiuliano Pochini clock_bits |= ECHO_CLOCK_BIT_WORD;
205dd7b254dSGiuliano Pochini
206dd7b254dSGiuliano Pochini switch(chip->digital_mode) {
207dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_RCA:
208dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_OPTICAL:
209dd7b254dSGiuliano Pochini if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF)
210dd7b254dSGiuliano Pochini clock_bits |= ECHO_CLOCK_BIT_SPDIF;
211dd7b254dSGiuliano Pochini break;
212dd7b254dSGiuliano Pochini case DIGITAL_MODE_ADAT:
213dd7b254dSGiuliano Pochini if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT)
214dd7b254dSGiuliano Pochini clock_bits |= ECHO_CLOCK_BIT_ADAT;
215dd7b254dSGiuliano Pochini break;
216dd7b254dSGiuliano Pochini }
217dd7b254dSGiuliano Pochini
218dd7b254dSGiuliano Pochini return clock_bits;
219dd7b254dSGiuliano Pochini }
220dd7b254dSGiuliano Pochini
221dd7b254dSGiuliano Pochini
222dd7b254dSGiuliano Pochini
load_asic(struct echoaudio * chip)223dd7b254dSGiuliano Pochini static int load_asic(struct echoaudio *chip)
224dd7b254dSGiuliano Pochini {
225dd7b254dSGiuliano Pochini int box_type, err;
226dd7b254dSGiuliano Pochini
227dd7b254dSGiuliano Pochini if (chip->asic_loaded)
228dd7b254dSGiuliano Pochini return 0;
229dd7b254dSGiuliano Pochini
230dd7b254dSGiuliano Pochini /* Give the DSP a few milliseconds to settle down */
231dd7b254dSGiuliano Pochini mdelay(2);
232dd7b254dSGiuliano Pochini
23319b50063SGiuliano Pochini err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC);
234dd7b254dSGiuliano Pochini if (err < 0)
235dd7b254dSGiuliano Pochini return err;
236dd7b254dSGiuliano Pochini
23719b50063SGiuliano Pochini chip->asic_code = FW_3G_ASIC;
238dd7b254dSGiuliano Pochini
23959ae9d05SGiuliano Pochini /* Now give the new ASIC some time to set up */
24059ae9d05SGiuliano Pochini msleep(1000);
241dd7b254dSGiuliano Pochini /* See if it worked */
242dd7b254dSGiuliano Pochini box_type = check_asic_status(chip);
243dd7b254dSGiuliano Pochini
244dd7b254dSGiuliano Pochini /* Set up the control register if the load succeeded -
245dd7b254dSGiuliano Pochini * 48 kHz, internal clock, S/PDIF RCA mode */
246dd7b254dSGiuliano Pochini if (box_type >= 0) {
247dd7b254dSGiuliano Pochini err = write_control_reg(chip, E3G_48KHZ,
2483f6175ecSMark Brown E3G_FREQ_REG_DEFAULT, true);
249dd7b254dSGiuliano Pochini if (err < 0)
250dd7b254dSGiuliano Pochini return err;
251dd7b254dSGiuliano Pochini }
252dd7b254dSGiuliano Pochini
253dd7b254dSGiuliano Pochini return box_type;
254dd7b254dSGiuliano Pochini }
255dd7b254dSGiuliano Pochini
256dd7b254dSGiuliano Pochini
257dd7b254dSGiuliano Pochini
set_sample_rate(struct echoaudio * chip,u32 rate)258dd7b254dSGiuliano Pochini static int set_sample_rate(struct echoaudio *chip, u32 rate)
259dd7b254dSGiuliano Pochini {
260dd7b254dSGiuliano Pochini u32 control_reg, clock, base_rate, frq_reg;
261dd7b254dSGiuliano Pochini
262dd7b254dSGiuliano Pochini /* Only set the clock for internal mode. */
263dd7b254dSGiuliano Pochini if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
264b5b4a41bSSudip Mukherjee dev_warn(chip->card->dev,
265b5b4a41bSSudip Mukherjee "Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
266dd7b254dSGiuliano Pochini /* Save the rate anyhow */
267dd7b254dSGiuliano Pochini chip->comm_page->sample_rate = cpu_to_le32(rate);
268dd7b254dSGiuliano Pochini chip->sample_rate = rate;
269dd7b254dSGiuliano Pochini set_input_clock(chip, chip->input_clock);
270dd7b254dSGiuliano Pochini return 0;
271dd7b254dSGiuliano Pochini }
272dd7b254dSGiuliano Pochini
273da3cec35STakashi Iwai if (snd_BUG_ON(rate >= 50000 &&
274da3cec35STakashi Iwai chip->digital_mode == DIGITAL_MODE_ADAT))
275da3cec35STakashi Iwai return -EINVAL;
276dd7b254dSGiuliano Pochini
277dd7b254dSGiuliano Pochini clock = 0;
278dd7b254dSGiuliano Pochini control_reg = le32_to_cpu(chip->comm_page->control_register);
279dd7b254dSGiuliano Pochini control_reg &= E3G_CLOCK_CLEAR_MASK;
280dd7b254dSGiuliano Pochini
281dd7b254dSGiuliano Pochini switch (rate) {
282dd7b254dSGiuliano Pochini case 96000:
283dd7b254dSGiuliano Pochini clock = E3G_96KHZ;
284dd7b254dSGiuliano Pochini break;
285dd7b254dSGiuliano Pochini case 88200:
286dd7b254dSGiuliano Pochini clock = E3G_88KHZ;
287dd7b254dSGiuliano Pochini break;
288dd7b254dSGiuliano Pochini case 48000:
289dd7b254dSGiuliano Pochini clock = E3G_48KHZ;
290dd7b254dSGiuliano Pochini break;
291dd7b254dSGiuliano Pochini case 44100:
292dd7b254dSGiuliano Pochini clock = E3G_44KHZ;
293dd7b254dSGiuliano Pochini break;
294dd7b254dSGiuliano Pochini case 32000:
295dd7b254dSGiuliano Pochini clock = E3G_32KHZ;
296dd7b254dSGiuliano Pochini break;
297dd7b254dSGiuliano Pochini default:
298dd7b254dSGiuliano Pochini clock = E3G_CONTINUOUS_CLOCK;
299dd7b254dSGiuliano Pochini if (rate > 50000)
300dd7b254dSGiuliano Pochini clock |= E3G_DOUBLE_SPEED_MODE;
301dd7b254dSGiuliano Pochini break;
302dd7b254dSGiuliano Pochini }
303dd7b254dSGiuliano Pochini
304dd7b254dSGiuliano Pochini control_reg |= clock;
305dd7b254dSGiuliano Pochini control_reg = set_spdif_bits(chip, control_reg, rate);
306dd7b254dSGiuliano Pochini
307dd7b254dSGiuliano Pochini base_rate = rate;
308dd7b254dSGiuliano Pochini if (base_rate > 50000)
309dd7b254dSGiuliano Pochini base_rate /= 2;
310dd7b254dSGiuliano Pochini if (base_rate < 32000)
311dd7b254dSGiuliano Pochini base_rate = 32000;
312dd7b254dSGiuliano Pochini
313dd7b254dSGiuliano Pochini frq_reg = E3G_MAGIC_NUMBER / base_rate - 2;
314dd7b254dSGiuliano Pochini if (frq_reg > E3G_FREQ_REG_MAX)
315dd7b254dSGiuliano Pochini frq_reg = E3G_FREQ_REG_MAX;
316dd7b254dSGiuliano Pochini
317dd7b254dSGiuliano Pochini chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */
318dd7b254dSGiuliano Pochini chip->sample_rate = rate;
319b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev,
320b5b4a41bSSudip Mukherjee "SetSampleRate: %d clock %x\n", rate, control_reg);
321dd7b254dSGiuliano Pochini
322dd7b254dSGiuliano Pochini /* Tell the DSP about it - DSP reads both control reg & freq reg */
323dd7b254dSGiuliano Pochini return write_control_reg(chip, control_reg, frq_reg, 0);
324dd7b254dSGiuliano Pochini }
325dd7b254dSGiuliano Pochini
326dd7b254dSGiuliano Pochini
327dd7b254dSGiuliano Pochini
328dd7b254dSGiuliano Pochini /* Set the sample clock source to internal, S/PDIF, ADAT */
set_input_clock(struct echoaudio * chip,u16 clock)329dd7b254dSGiuliano Pochini static int set_input_clock(struct echoaudio *chip, u16 clock)
330dd7b254dSGiuliano Pochini {
331dd7b254dSGiuliano Pochini u32 control_reg, clocks_from_dsp;
332dd7b254dSGiuliano Pochini
333dd7b254dSGiuliano Pochini
334dd7b254dSGiuliano Pochini /* Mask off the clock select bits */
335dd7b254dSGiuliano Pochini control_reg = le32_to_cpu(chip->comm_page->control_register) &
336dd7b254dSGiuliano Pochini E3G_CLOCK_CLEAR_MASK;
337dd7b254dSGiuliano Pochini clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
338dd7b254dSGiuliano Pochini
339dd7b254dSGiuliano Pochini switch (clock) {
340dd7b254dSGiuliano Pochini case ECHO_CLOCK_INTERNAL:
341dd7b254dSGiuliano Pochini chip->input_clock = ECHO_CLOCK_INTERNAL;
342dd7b254dSGiuliano Pochini return set_sample_rate(chip, chip->sample_rate);
343dd7b254dSGiuliano Pochini case ECHO_CLOCK_SPDIF:
344dd7b254dSGiuliano Pochini if (chip->digital_mode == DIGITAL_MODE_ADAT)
345dd7b254dSGiuliano Pochini return -EAGAIN;
346dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_CLOCK;
347dd7b254dSGiuliano Pochini if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96)
348dd7b254dSGiuliano Pochini control_reg |= E3G_DOUBLE_SPEED_MODE;
349dd7b254dSGiuliano Pochini else
350dd7b254dSGiuliano Pochini control_reg &= ~E3G_DOUBLE_SPEED_MODE;
351dd7b254dSGiuliano Pochini break;
352dd7b254dSGiuliano Pochini case ECHO_CLOCK_ADAT:
353dd7b254dSGiuliano Pochini if (chip->digital_mode != DIGITAL_MODE_ADAT)
354dd7b254dSGiuliano Pochini return -EAGAIN;
355dd7b254dSGiuliano Pochini control_reg |= E3G_ADAT_CLOCK;
356dd7b254dSGiuliano Pochini control_reg &= ~E3G_DOUBLE_SPEED_MODE;
357dd7b254dSGiuliano Pochini break;
358dd7b254dSGiuliano Pochini case ECHO_CLOCK_WORD:
359dd7b254dSGiuliano Pochini control_reg |= E3G_WORD_CLOCK;
360dd7b254dSGiuliano Pochini if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96)
361dd7b254dSGiuliano Pochini control_reg |= E3G_DOUBLE_SPEED_MODE;
362dd7b254dSGiuliano Pochini else
363dd7b254dSGiuliano Pochini control_reg &= ~E3G_DOUBLE_SPEED_MODE;
364dd7b254dSGiuliano Pochini break;
365dd7b254dSGiuliano Pochini default:
366b5b4a41bSSudip Mukherjee dev_err(chip->card->dev,
367b5b4a41bSSudip Mukherjee "Input clock 0x%x not supported for Echo3G\n", clock);
368dd7b254dSGiuliano Pochini return -EINVAL;
369dd7b254dSGiuliano Pochini }
370dd7b254dSGiuliano Pochini
371dd7b254dSGiuliano Pochini chip->input_clock = clock;
372dd7b254dSGiuliano Pochini return write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
373dd7b254dSGiuliano Pochini }
374dd7b254dSGiuliano Pochini
375dd7b254dSGiuliano Pochini
376dd7b254dSGiuliano Pochini
dsp_set_digital_mode(struct echoaudio * chip,u8 mode)377dd7b254dSGiuliano Pochini static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
378dd7b254dSGiuliano Pochini {
379dd7b254dSGiuliano Pochini u32 control_reg;
380dd7b254dSGiuliano Pochini int err, incompatible_clock;
381dd7b254dSGiuliano Pochini
382dd7b254dSGiuliano Pochini /* Set clock to "internal" if it's not compatible with the new mode */
3833f6175ecSMark Brown incompatible_clock = false;
384dd7b254dSGiuliano Pochini switch (mode) {
385dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_OPTICAL:
386dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_RCA:
387dd7b254dSGiuliano Pochini if (chip->input_clock == ECHO_CLOCK_ADAT)
3883f6175ecSMark Brown incompatible_clock = true;
389dd7b254dSGiuliano Pochini break;
390dd7b254dSGiuliano Pochini case DIGITAL_MODE_ADAT:
391dd7b254dSGiuliano Pochini if (chip->input_clock == ECHO_CLOCK_SPDIF)
3923f6175ecSMark Brown incompatible_clock = true;
393dd7b254dSGiuliano Pochini break;
394dd7b254dSGiuliano Pochini default:
395b5b4a41bSSudip Mukherjee dev_err(chip->card->dev,
396b5b4a41bSSudip Mukherjee "Digital mode not supported: %d\n", mode);
397dd7b254dSGiuliano Pochini return -EINVAL;
398dd7b254dSGiuliano Pochini }
399dd7b254dSGiuliano Pochini
400dd7b254dSGiuliano Pochini spin_lock_irq(&chip->lock);
401dd7b254dSGiuliano Pochini
402dd7b254dSGiuliano Pochini if (incompatible_clock) {
403dd7b254dSGiuliano Pochini chip->sample_rate = 48000;
404dd7b254dSGiuliano Pochini set_input_clock(chip, ECHO_CLOCK_INTERNAL);
405dd7b254dSGiuliano Pochini }
406dd7b254dSGiuliano Pochini
407dd7b254dSGiuliano Pochini /* Clear the current digital mode */
408dd7b254dSGiuliano Pochini control_reg = le32_to_cpu(chip->comm_page->control_register);
409dd7b254dSGiuliano Pochini control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK;
410dd7b254dSGiuliano Pochini
411dd7b254dSGiuliano Pochini /* Tweak the control reg */
412dd7b254dSGiuliano Pochini switch (mode) {
413dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_OPTICAL:
414dd7b254dSGiuliano Pochini control_reg |= E3G_SPDIF_OPTICAL_MODE;
415dd7b254dSGiuliano Pochini break;
416dd7b254dSGiuliano Pochini case DIGITAL_MODE_SPDIF_RCA:
417dd7b254dSGiuliano Pochini /* E3G_SPDIF_OPTICAL_MODE bit cleared */
418dd7b254dSGiuliano Pochini break;
419dd7b254dSGiuliano Pochini case DIGITAL_MODE_ADAT:
420dd7b254dSGiuliano Pochini control_reg |= E3G_ADAT_MODE;
421dd7b254dSGiuliano Pochini control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */
422dd7b254dSGiuliano Pochini break;
423dd7b254dSGiuliano Pochini }
424dd7b254dSGiuliano Pochini
425dd7b254dSGiuliano Pochini err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1);
426dd7b254dSGiuliano Pochini spin_unlock_irq(&chip->lock);
427dd7b254dSGiuliano Pochini if (err < 0)
428dd7b254dSGiuliano Pochini return err;
429dd7b254dSGiuliano Pochini chip->digital_mode = mode;
430dd7b254dSGiuliano Pochini
431b5b4a41bSSudip Mukherjee dev_dbg(chip->card->dev, "set_digital_mode(%d)\n", chip->digital_mode);
432dd7b254dSGiuliano Pochini return incompatible_clock;
433dd7b254dSGiuliano Pochini }
434