xref: /openbmc/linux/sound/pci/echoaudio/echoaudio_3g.c (revision 3eb66e91a25497065c5322b1268cbc3953642227)
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