xref: /linux/sound/pci/echoaudio/mona_dsp.c (revision 353b7a55dcaf5fb8758e09ebe2ddf5f3adbac7c5)
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 static int write_control_reg(struct echoaudio *chip, u32 value, char force);
33dd7b254dSGiuliano Pochini static int set_input_clock(struct echoaudio *chip, u16 clock);
34dd7b254dSGiuliano Pochini static int set_professional_spdif(struct echoaudio *chip, char prof);
35dd7b254dSGiuliano Pochini static int set_digital_mode(struct echoaudio *chip, u8 mode);
3619b50063SGiuliano Pochini static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
37dd7b254dSGiuliano Pochini static int check_asic_status(struct echoaudio *chip);
38dd7b254dSGiuliano Pochini 
39dd7b254dSGiuliano Pochini 
40dd7b254dSGiuliano Pochini static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
41dd7b254dSGiuliano Pochini {
42dd7b254dSGiuliano Pochini 	int err;
43dd7b254dSGiuliano Pochini 
44da3cec35STakashi Iwai 	if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA))
45da3cec35STakashi Iwai 		return -ENODEV;
46dd7b254dSGiuliano Pochini 
47*549717fcSTakashi Iwai 	err = init_dsp_comm_page(chip);
48*549717fcSTakashi Iwai 	if (err) {
49b5b4a41bSSudip Mukherjee 		dev_err(chip->card->dev,
50b5b4a41bSSudip Mukherjee 			"init_hw - could not initialize DSP comm page\n");
51dd7b254dSGiuliano Pochini 		return err;
52dd7b254dSGiuliano Pochini 	}
53dd7b254dSGiuliano Pochini 
54dd7b254dSGiuliano Pochini 	chip->device_id = device_id;
55dd7b254dSGiuliano Pochini 	chip->subdevice_id = subdevice_id;
563f6175ecSMark Brown 	chip->bad_board = true;
57dd7b254dSGiuliano Pochini 	chip->input_clock_types =
58dd7b254dSGiuliano Pochini 		ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
59dd7b254dSGiuliano Pochini 		ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
60dd7b254dSGiuliano Pochini 	chip->digital_modes =
61dd7b254dSGiuliano Pochini 		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
62dd7b254dSGiuliano Pochini 		ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
63dd7b254dSGiuliano Pochini 		ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
64dd7b254dSGiuliano Pochini 
65dd7b254dSGiuliano Pochini 	/* Mona comes in both '301 and '361 flavors */
66dd7b254dSGiuliano Pochini 	if (chip->device_id == DEVICE_ID_56361)
6719b50063SGiuliano Pochini 		chip->dsp_code_to_load = FW_MONA_361_DSP;
68dd7b254dSGiuliano Pochini 	else
6919b50063SGiuliano Pochini 		chip->dsp_code_to_load = FW_MONA_301_DSP;
70dd7b254dSGiuliano Pochini 
71*549717fcSTakashi Iwai 	err = load_firmware(chip);
72*549717fcSTakashi Iwai 	if (err < 0)
73dd7b254dSGiuliano Pochini 		return err;
743f6175ecSMark Brown 	chip->bad_board = false;
75dd7b254dSGiuliano Pochini 
76dd7b254dSGiuliano Pochini 	return err;
77dd7b254dSGiuliano Pochini }
78dd7b254dSGiuliano Pochini 
79dd7b254dSGiuliano Pochini 
80dd7b254dSGiuliano Pochini 
81ad3499f4SGiuliano Pochini static int set_mixer_defaults(struct echoaudio *chip)
82ad3499f4SGiuliano Pochini {
83ad3499f4SGiuliano Pochini 	chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
843f6175ecSMark Brown 	chip->professional_spdif = false;
853f6175ecSMark Brown 	chip->digital_in_automute = true;
86ad3499f4SGiuliano Pochini 	return init_line_levels(chip);
87ad3499f4SGiuliano Pochini }
88ad3499f4SGiuliano Pochini 
89ad3499f4SGiuliano Pochini 
90ad3499f4SGiuliano Pochini 
91dd7b254dSGiuliano Pochini static u32 detect_input_clocks(const struct echoaudio *chip)
92dd7b254dSGiuliano Pochini {
93dd7b254dSGiuliano Pochini 	u32 clocks_from_dsp, clock_bits;
94dd7b254dSGiuliano Pochini 
95dd7b254dSGiuliano Pochini 	/* Map the DSP clock detect bits to the generic driver clock
96dd7b254dSGiuliano Pochini 	   detect bits */
97dd7b254dSGiuliano Pochini 	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
98dd7b254dSGiuliano Pochini 
99dd7b254dSGiuliano Pochini 	clock_bits = ECHO_CLOCK_BIT_INTERNAL;
100dd7b254dSGiuliano Pochini 
101dd7b254dSGiuliano Pochini 	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF)
102dd7b254dSGiuliano Pochini 		clock_bits |= ECHO_CLOCK_BIT_SPDIF;
103dd7b254dSGiuliano Pochini 
104dd7b254dSGiuliano Pochini 	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT)
105dd7b254dSGiuliano Pochini 		clock_bits |= ECHO_CLOCK_BIT_ADAT;
106dd7b254dSGiuliano Pochini 
107dd7b254dSGiuliano Pochini 	if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD)
108dd7b254dSGiuliano Pochini 		clock_bits |= ECHO_CLOCK_BIT_WORD;
109dd7b254dSGiuliano Pochini 
110dd7b254dSGiuliano Pochini 	return clock_bits;
111dd7b254dSGiuliano Pochini }
112dd7b254dSGiuliano Pochini 
113dd7b254dSGiuliano Pochini 
114dd7b254dSGiuliano Pochini 
115dd7b254dSGiuliano Pochini /* Mona has an ASIC on the PCI card and another ASIC in the external box;
116dd7b254dSGiuliano Pochini both need to be loaded. */
117dd7b254dSGiuliano Pochini static int load_asic(struct echoaudio *chip)
118dd7b254dSGiuliano Pochini {
119dd7b254dSGiuliano Pochini 	u32 control_reg;
120dd7b254dSGiuliano Pochini 	int err;
12119b50063SGiuliano Pochini 	short asic;
122dd7b254dSGiuliano Pochini 
123dd7b254dSGiuliano Pochini 	if (chip->asic_loaded)
124dd7b254dSGiuliano Pochini 		return 0;
125dd7b254dSGiuliano Pochini 
126dd7b254dSGiuliano Pochini 	mdelay(10);
127dd7b254dSGiuliano Pochini 
128dd7b254dSGiuliano Pochini 	if (chip->device_id == DEVICE_ID_56361)
12919b50063SGiuliano Pochini 		asic = FW_MONA_361_1_ASIC48;
130dd7b254dSGiuliano Pochini 	else
13119b50063SGiuliano Pochini 		asic = FW_MONA_301_1_ASIC48;
132dd7b254dSGiuliano Pochini 
133dd7b254dSGiuliano Pochini 	err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
134dd7b254dSGiuliano Pochini 	if (err < 0)
135dd7b254dSGiuliano Pochini 		return err;
136dd7b254dSGiuliano Pochini 
137dd7b254dSGiuliano Pochini 	chip->asic_code = asic;
138dd7b254dSGiuliano Pochini 	mdelay(10);
139dd7b254dSGiuliano Pochini 
140dd7b254dSGiuliano Pochini 	/* Do the external one */
141dd7b254dSGiuliano Pochini 	err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
14219b50063SGiuliano Pochini 				FW_MONA_2_ASIC);
143dd7b254dSGiuliano Pochini 	if (err < 0)
144dd7b254dSGiuliano Pochini 		return err;
145dd7b254dSGiuliano Pochini 
146dd7b254dSGiuliano Pochini 	mdelay(10);
147dd7b254dSGiuliano Pochini 	err = check_asic_status(chip);
148dd7b254dSGiuliano Pochini 
149dd7b254dSGiuliano Pochini 	/* Set up the control register if the load succeeded -
150dd7b254dSGiuliano Pochini 	   48 kHz, internal clock, S/PDIF RCA mode */
151dd7b254dSGiuliano Pochini 	if (!err) {
152dd7b254dSGiuliano Pochini 		control_reg = GML_CONVERTER_ENABLE | GML_48KHZ;
1533f6175ecSMark Brown 		err = write_control_reg(chip, control_reg, true);
154dd7b254dSGiuliano Pochini 	}
155dd7b254dSGiuliano Pochini 
156dd7b254dSGiuliano Pochini 	return err;
157dd7b254dSGiuliano Pochini }
158dd7b254dSGiuliano Pochini 
159dd7b254dSGiuliano Pochini 
160dd7b254dSGiuliano Pochini 
161dd7b254dSGiuliano Pochini /* Depending on what digital mode you want, Mona needs different ASICs
162dd7b254dSGiuliano Pochini loaded.  This function checks the ASIC needed for the new mode and sees
163dd7b254dSGiuliano Pochini if it matches the one already loaded. */
164dd7b254dSGiuliano Pochini static int switch_asic(struct echoaudio *chip, char double_speed)
165dd7b254dSGiuliano Pochini {
166dd7b254dSGiuliano Pochini 	int err;
16719b50063SGiuliano Pochini 	short asic;
168dd7b254dSGiuliano Pochini 
169dd7b254dSGiuliano Pochini 	/* Check the clock detect bits to see if this is
170dd7b254dSGiuliano Pochini 	a single-speed clock or a double-speed clock; load
171dd7b254dSGiuliano Pochini 	a new ASIC if necessary. */
172dd7b254dSGiuliano Pochini 	if (chip->device_id == DEVICE_ID_56361) {
173dd7b254dSGiuliano Pochini 		if (double_speed)
17419b50063SGiuliano Pochini 			asic = FW_MONA_361_1_ASIC96;
175dd7b254dSGiuliano Pochini 		else
17619b50063SGiuliano Pochini 			asic = FW_MONA_361_1_ASIC48;
177dd7b254dSGiuliano Pochini 	} else {
178dd7b254dSGiuliano Pochini 		if (double_speed)
17919b50063SGiuliano Pochini 			asic = FW_MONA_301_1_ASIC96;
180dd7b254dSGiuliano Pochini 		else
18119b50063SGiuliano Pochini 			asic = FW_MONA_301_1_ASIC48;
182dd7b254dSGiuliano Pochini 	}
183dd7b254dSGiuliano Pochini 
184dd7b254dSGiuliano Pochini 	if (asic != chip->asic_code) {
185dd7b254dSGiuliano Pochini 		/* Load the desired ASIC */
186dd7b254dSGiuliano Pochini 		err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
187dd7b254dSGiuliano Pochini 					asic);
188dd7b254dSGiuliano Pochini 		if (err < 0)
189dd7b254dSGiuliano Pochini 			return err;
190dd7b254dSGiuliano Pochini 		chip->asic_code = asic;
191dd7b254dSGiuliano Pochini 	}
192dd7b254dSGiuliano Pochini 
193dd7b254dSGiuliano Pochini 	return 0;
194dd7b254dSGiuliano Pochini }
195dd7b254dSGiuliano Pochini 
196dd7b254dSGiuliano Pochini 
197dd7b254dSGiuliano Pochini 
198dd7b254dSGiuliano Pochini static int set_sample_rate(struct echoaudio *chip, u32 rate)
199dd7b254dSGiuliano Pochini {
200dd7b254dSGiuliano Pochini 	u32 control_reg, clock;
20119b50063SGiuliano Pochini 	short asic;
202dd7b254dSGiuliano Pochini 	char force_write;
203dd7b254dSGiuliano Pochini 
204dd7b254dSGiuliano Pochini 	/* Only set the clock for internal mode. */
205dd7b254dSGiuliano Pochini 	if (chip->input_clock != ECHO_CLOCK_INTERNAL) {
206b5b4a41bSSudip Mukherjee 		dev_dbg(chip->card->dev,
207b5b4a41bSSudip Mukherjee 			"Cannot set sample rate - clock not set to CLK_CLOCKININTERNAL\n");
208dd7b254dSGiuliano Pochini 		/* Save the rate anyhow */
209dd7b254dSGiuliano Pochini 		chip->comm_page->sample_rate = cpu_to_le32(rate);
210dd7b254dSGiuliano Pochini 		chip->sample_rate = rate;
211dd7b254dSGiuliano Pochini 		return 0;
212dd7b254dSGiuliano Pochini 	}
213dd7b254dSGiuliano Pochini 
214dd7b254dSGiuliano Pochini 	/* Now, check to see if the required ASIC is loaded */
215dd7b254dSGiuliano Pochini 	if (rate >= 88200) {
216dd7b254dSGiuliano Pochini 		if (chip->digital_mode == DIGITAL_MODE_ADAT)
217dd7b254dSGiuliano Pochini 			return -EINVAL;
218dd7b254dSGiuliano Pochini 		if (chip->device_id == DEVICE_ID_56361)
21919b50063SGiuliano Pochini 			asic = FW_MONA_361_1_ASIC96;
220dd7b254dSGiuliano Pochini 		else
22119b50063SGiuliano Pochini 			asic = FW_MONA_301_1_ASIC96;
222dd7b254dSGiuliano Pochini 	} else {
223dd7b254dSGiuliano Pochini 		if (chip->device_id == DEVICE_ID_56361)
22419b50063SGiuliano Pochini 			asic = FW_MONA_361_1_ASIC48;
225dd7b254dSGiuliano Pochini 		else
22619b50063SGiuliano Pochini 			asic = FW_MONA_301_1_ASIC48;
227dd7b254dSGiuliano Pochini 	}
228dd7b254dSGiuliano Pochini 
229dd7b254dSGiuliano Pochini 	force_write = 0;
230dd7b254dSGiuliano Pochini 	if (asic != chip->asic_code) {
231dd7b254dSGiuliano Pochini 		int err;
232dd7b254dSGiuliano Pochini 		/* Load the desired ASIC (load_asic_generic() can sleep) */
233dd7b254dSGiuliano Pochini 		spin_unlock_irq(&chip->lock);
234dd7b254dSGiuliano Pochini 		err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC,
235dd7b254dSGiuliano Pochini 					asic);
236dd7b254dSGiuliano Pochini 		spin_lock_irq(&chip->lock);
237dd7b254dSGiuliano Pochini 
238dd7b254dSGiuliano Pochini 		if (err < 0)
239dd7b254dSGiuliano Pochini 			return err;
240dd7b254dSGiuliano Pochini 		chip->asic_code = asic;
241dd7b254dSGiuliano Pochini 		force_write = 1;
242dd7b254dSGiuliano Pochini 	}
243dd7b254dSGiuliano Pochini 
244dd7b254dSGiuliano Pochini 	/* Compute the new control register value */
245dd7b254dSGiuliano Pochini 	clock = 0;
246dd7b254dSGiuliano Pochini 	control_reg = le32_to_cpu(chip->comm_page->control_register);
247dd7b254dSGiuliano Pochini 	control_reg &= GML_CLOCK_CLEAR_MASK;
248dd7b254dSGiuliano Pochini 	control_reg &= GML_SPDIF_RATE_CLEAR_MASK;
249dd7b254dSGiuliano Pochini 
250dd7b254dSGiuliano Pochini 	switch (rate) {
251dd7b254dSGiuliano Pochini 	case 96000:
252dd7b254dSGiuliano Pochini 		clock = GML_96KHZ;
253dd7b254dSGiuliano Pochini 		break;
254dd7b254dSGiuliano Pochini 	case 88200:
255dd7b254dSGiuliano Pochini 		clock = GML_88KHZ;
256dd7b254dSGiuliano Pochini 		break;
257dd7b254dSGiuliano Pochini 	case 48000:
258dd7b254dSGiuliano Pochini 		clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1;
259dd7b254dSGiuliano Pochini 		break;
260dd7b254dSGiuliano Pochini 	case 44100:
261dd7b254dSGiuliano Pochini 		clock = GML_44KHZ;
262dd7b254dSGiuliano Pochini 		/* Professional mode */
263dd7b254dSGiuliano Pochini 		if (control_reg & GML_SPDIF_PRO_MODE)
264dd7b254dSGiuliano Pochini 			clock |= GML_SPDIF_SAMPLE_RATE0;
265dd7b254dSGiuliano Pochini 		break;
266dd7b254dSGiuliano Pochini 	case 32000:
267dd7b254dSGiuliano Pochini 		clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 |
268dd7b254dSGiuliano Pochini 			GML_SPDIF_SAMPLE_RATE1;
269dd7b254dSGiuliano Pochini 		break;
270dd7b254dSGiuliano Pochini 	case 22050:
271dd7b254dSGiuliano Pochini 		clock = GML_22KHZ;
272dd7b254dSGiuliano Pochini 		break;
273dd7b254dSGiuliano Pochini 	case 16000:
274dd7b254dSGiuliano Pochini 		clock = GML_16KHZ;
275dd7b254dSGiuliano Pochini 		break;
276dd7b254dSGiuliano Pochini 	case 11025:
277dd7b254dSGiuliano Pochini 		clock = GML_11KHZ;
278dd7b254dSGiuliano Pochini 		break;
279dd7b254dSGiuliano Pochini 	case 8000:
280dd7b254dSGiuliano Pochini 		clock = GML_8KHZ;
281dd7b254dSGiuliano Pochini 		break;
282dd7b254dSGiuliano Pochini 	default:
283b5b4a41bSSudip Mukherjee 		dev_err(chip->card->dev,
284b5b4a41bSSudip Mukherjee 			"set_sample_rate: %d invalid!\n", rate);
285dd7b254dSGiuliano Pochini 		return -EINVAL;
286dd7b254dSGiuliano Pochini 	}
287dd7b254dSGiuliano Pochini 
288dd7b254dSGiuliano Pochini 	control_reg |= clock;
289dd7b254dSGiuliano Pochini 
290dd7b254dSGiuliano Pochini 	chip->comm_page->sample_rate = cpu_to_le32(rate);	/* ignored by the DSP */
291dd7b254dSGiuliano Pochini 	chip->sample_rate = rate;
292b5b4a41bSSudip Mukherjee 	dev_dbg(chip->card->dev,
293b5b4a41bSSudip Mukherjee 		"set_sample_rate: %d clock %d\n", rate, clock);
294dd7b254dSGiuliano Pochini 
295dd7b254dSGiuliano Pochini 	return write_control_reg(chip, control_reg, force_write);
296dd7b254dSGiuliano Pochini }
297dd7b254dSGiuliano Pochini 
298dd7b254dSGiuliano Pochini 
299dd7b254dSGiuliano Pochini 
300dd7b254dSGiuliano Pochini static int set_input_clock(struct echoaudio *chip, u16 clock)
301dd7b254dSGiuliano Pochini {
302dd7b254dSGiuliano Pochini 	u32 control_reg, clocks_from_dsp;
303dd7b254dSGiuliano Pochini 	int err;
304dd7b254dSGiuliano Pochini 
305dd7b254dSGiuliano Pochini 	/* Mask off the clock select bits */
306dd7b254dSGiuliano Pochini 	control_reg = le32_to_cpu(chip->comm_page->control_register) &
307dd7b254dSGiuliano Pochini 		GML_CLOCK_CLEAR_MASK;
308dd7b254dSGiuliano Pochini 	clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
309dd7b254dSGiuliano Pochini 
310dd7b254dSGiuliano Pochini 	switch (clock) {
311dd7b254dSGiuliano Pochini 	case ECHO_CLOCK_INTERNAL:
312dd7b254dSGiuliano Pochini 		chip->input_clock = ECHO_CLOCK_INTERNAL;
313dd7b254dSGiuliano Pochini 		return set_sample_rate(chip, chip->sample_rate);
314dd7b254dSGiuliano Pochini 	case ECHO_CLOCK_SPDIF:
315dd7b254dSGiuliano Pochini 		if (chip->digital_mode == DIGITAL_MODE_ADAT)
316dd7b254dSGiuliano Pochini 			return -EAGAIN;
317dd7b254dSGiuliano Pochini 		spin_unlock_irq(&chip->lock);
318dd7b254dSGiuliano Pochini 		err = switch_asic(chip, clocks_from_dsp &
319dd7b254dSGiuliano Pochini 				  GML_CLOCK_DETECT_BIT_SPDIF96);
320dd7b254dSGiuliano Pochini 		spin_lock_irq(&chip->lock);
321dd7b254dSGiuliano Pochini 		if (err < 0)
322dd7b254dSGiuliano Pochini 			return err;
323dd7b254dSGiuliano Pochini 		control_reg |= GML_SPDIF_CLOCK;
324dd7b254dSGiuliano Pochini 		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96)
325dd7b254dSGiuliano Pochini 			control_reg |= GML_DOUBLE_SPEED_MODE;
326dd7b254dSGiuliano Pochini 		else
327dd7b254dSGiuliano Pochini 			control_reg &= ~GML_DOUBLE_SPEED_MODE;
328dd7b254dSGiuliano Pochini 		break;
329dd7b254dSGiuliano Pochini 	case ECHO_CLOCK_WORD:
330dd7b254dSGiuliano Pochini 		spin_unlock_irq(&chip->lock);
331dd7b254dSGiuliano Pochini 		err = switch_asic(chip, clocks_from_dsp &
332dd7b254dSGiuliano Pochini 				  GML_CLOCK_DETECT_BIT_WORD96);
333dd7b254dSGiuliano Pochini 		spin_lock_irq(&chip->lock);
334dd7b254dSGiuliano Pochini 		if (err < 0)
335dd7b254dSGiuliano Pochini 			return err;
336dd7b254dSGiuliano Pochini 		control_reg |= GML_WORD_CLOCK;
337dd7b254dSGiuliano Pochini 		if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96)
338dd7b254dSGiuliano Pochini 			control_reg |= GML_DOUBLE_SPEED_MODE;
339dd7b254dSGiuliano Pochini 		else
340dd7b254dSGiuliano Pochini 			control_reg &= ~GML_DOUBLE_SPEED_MODE;
341dd7b254dSGiuliano Pochini 		break;
342dd7b254dSGiuliano Pochini 	case ECHO_CLOCK_ADAT:
343b5b4a41bSSudip Mukherjee 		dev_dbg(chip->card->dev, "Set Mona clock to ADAT\n");
344dd7b254dSGiuliano Pochini 		if (chip->digital_mode != DIGITAL_MODE_ADAT)
345dd7b254dSGiuliano Pochini 			return -EAGAIN;
346dd7b254dSGiuliano Pochini 		control_reg |= GML_ADAT_CLOCK;
347dd7b254dSGiuliano Pochini 		control_reg &= ~GML_DOUBLE_SPEED_MODE;
348dd7b254dSGiuliano Pochini 		break;
349dd7b254dSGiuliano Pochini 	default:
350b5b4a41bSSudip Mukherjee 		dev_err(chip->card->dev,
351b5b4a41bSSudip Mukherjee 			"Input clock 0x%x not supported for Mona\n", clock);
352dd7b254dSGiuliano Pochini 		return -EINVAL;
353dd7b254dSGiuliano Pochini 	}
354dd7b254dSGiuliano Pochini 
355dd7b254dSGiuliano Pochini 	chip->input_clock = clock;
3563f6175ecSMark Brown 	return write_control_reg(chip, control_reg, true);
357dd7b254dSGiuliano Pochini }
358dd7b254dSGiuliano Pochini 
359dd7b254dSGiuliano Pochini 
360dd7b254dSGiuliano Pochini 
361dd7b254dSGiuliano Pochini static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
362dd7b254dSGiuliano Pochini {
363dd7b254dSGiuliano Pochini 	u32 control_reg;
364dd7b254dSGiuliano Pochini 	int err, incompatible_clock;
365dd7b254dSGiuliano Pochini 
366dd7b254dSGiuliano Pochini 	/* Set clock to "internal" if it's not compatible with the new mode */
3673f6175ecSMark Brown 	incompatible_clock = false;
368dd7b254dSGiuliano Pochini 	switch (mode) {
369dd7b254dSGiuliano Pochini 	case DIGITAL_MODE_SPDIF_OPTICAL:
370dd7b254dSGiuliano Pochini 	case DIGITAL_MODE_SPDIF_RCA:
371dd7b254dSGiuliano Pochini 		if (chip->input_clock == ECHO_CLOCK_ADAT)
3723f6175ecSMark Brown 			incompatible_clock = true;
373dd7b254dSGiuliano Pochini 		break;
374dd7b254dSGiuliano Pochini 	case DIGITAL_MODE_ADAT:
375dd7b254dSGiuliano Pochini 		if (chip->input_clock == ECHO_CLOCK_SPDIF)
3763f6175ecSMark Brown 			incompatible_clock = true;
377dd7b254dSGiuliano Pochini 		break;
378dd7b254dSGiuliano Pochini 	default:
379b5b4a41bSSudip Mukherjee 		dev_err(chip->card->dev,
380b5b4a41bSSudip Mukherjee 			"Digital mode not supported: %d\n", mode);
381dd7b254dSGiuliano Pochini 		return -EINVAL;
382dd7b254dSGiuliano Pochini 	}
383dd7b254dSGiuliano Pochini 
384dd7b254dSGiuliano Pochini 	spin_lock_irq(&chip->lock);
385dd7b254dSGiuliano Pochini 
386dd7b254dSGiuliano Pochini 	if (incompatible_clock) {	/* Switch to 48KHz, internal */
387dd7b254dSGiuliano Pochini 		chip->sample_rate = 48000;
388dd7b254dSGiuliano Pochini 		set_input_clock(chip, ECHO_CLOCK_INTERNAL);
389dd7b254dSGiuliano Pochini 	}
390dd7b254dSGiuliano Pochini 
391dd7b254dSGiuliano Pochini 	/* Clear the current digital mode */
392dd7b254dSGiuliano Pochini 	control_reg = le32_to_cpu(chip->comm_page->control_register);
393dd7b254dSGiuliano Pochini 	control_reg &= GML_DIGITAL_MODE_CLEAR_MASK;
394dd7b254dSGiuliano Pochini 
395dd7b254dSGiuliano Pochini 	/* Tweak the control reg */
396dd7b254dSGiuliano Pochini 	switch (mode) {
397dd7b254dSGiuliano Pochini 	case DIGITAL_MODE_SPDIF_OPTICAL:
398dd7b254dSGiuliano Pochini 		control_reg |= GML_SPDIF_OPTICAL_MODE;
399dd7b254dSGiuliano Pochini 		break;
400dd7b254dSGiuliano Pochini 	case DIGITAL_MODE_SPDIF_RCA:
401dd7b254dSGiuliano Pochini 		/* GML_SPDIF_OPTICAL_MODE bit cleared */
402dd7b254dSGiuliano Pochini 		break;
403dd7b254dSGiuliano Pochini 	case DIGITAL_MODE_ADAT:
404dd7b254dSGiuliano Pochini 		/* If the current ASIC is the 96KHz ASIC, switch the ASIC
405dd7b254dSGiuliano Pochini 		   and set to 48 KHz */
40619b50063SGiuliano Pochini 		if (chip->asic_code == FW_MONA_361_1_ASIC96 ||
40719b50063SGiuliano Pochini 		    chip->asic_code == FW_MONA_301_1_ASIC96) {
408dd7b254dSGiuliano Pochini 			set_sample_rate(chip, 48000);
409dd7b254dSGiuliano Pochini 		}
410dd7b254dSGiuliano Pochini 		control_reg |= GML_ADAT_MODE;
411dd7b254dSGiuliano Pochini 		control_reg &= ~GML_DOUBLE_SPEED_MODE;
412dd7b254dSGiuliano Pochini 		break;
413dd7b254dSGiuliano Pochini 	}
414dd7b254dSGiuliano Pochini 
4153f6175ecSMark Brown 	err = write_control_reg(chip, control_reg, false);
416dd7b254dSGiuliano Pochini 	spin_unlock_irq(&chip->lock);
417dd7b254dSGiuliano Pochini 	if (err < 0)
418dd7b254dSGiuliano Pochini 		return err;
419dd7b254dSGiuliano Pochini 	chip->digital_mode = mode;
420dd7b254dSGiuliano Pochini 
421b5b4a41bSSudip Mukherjee 	dev_dbg(chip->card->dev, "set_digital_mode to %d\n", mode);
422dd7b254dSGiuliano Pochini 	return incompatible_clock;
423dd7b254dSGiuliano Pochini }
424