xref: /linux/sound/pci/echoaudio/echo3g_dsp.c (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
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 static int load_asic(struct echoaudio *chip);
32dd7b254dSGiuliano Pochini static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode);
33dd7b254dSGiuliano Pochini static int set_digital_mode(struct echoaudio *chip, u8 mode);
34dd7b254dSGiuliano Pochini static int check_asic_status(struct echoaudio *chip);
35dd7b254dSGiuliano Pochini static int set_sample_rate(struct echoaudio *chip, u32 rate);
36dd7b254dSGiuliano Pochini static int set_input_clock(struct echoaudio *chip, u16 clock);
37dd7b254dSGiuliano Pochini static int set_professional_spdif(struct echoaudio *chip, char prof);
38dd7b254dSGiuliano Pochini static int set_phantom_power(struct echoaudio *chip, char on);
39dd7b254dSGiuliano Pochini static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
40dd7b254dSGiuliano Pochini 			     char force);
41dd7b254dSGiuliano Pochini 
42579c84a9SAdrian Bunk #include <linux/interrupt.h>
43dd7b254dSGiuliano Pochini 
44dd7b254dSGiuliano Pochini static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
45dd7b254dSGiuliano Pochini {
46dd7b254dSGiuliano Pochini 	int err;
47dd7b254dSGiuliano Pochini 
48dd7b254dSGiuliano Pochini 	local_irq_enable();
49da3cec35STakashi Iwai 	if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G))
50da3cec35STakashi Iwai 		return -ENODEV;
51dd7b254dSGiuliano Pochini 
52dd7b254dSGiuliano Pochini 	if ((err = init_dsp_comm_page(chip))) {
53b5b4a41bSSudip Mukherjee 		dev_err(chip->card->dev,
54b5b4a41bSSudip Mukherjee 			"init_hw - could not initialize DSP comm page\n");
55dd7b254dSGiuliano Pochini 		return err;
56dd7b254dSGiuliano Pochini 	}
57dd7b254dSGiuliano Pochini 
58dd7b254dSGiuliano Pochini 	chip->comm_page->e3g_frq_register =
59e930e995SHarvey Harrison 		cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2);
60dd7b254dSGiuliano Pochini 	chip->device_id = device_id;
61dd7b254dSGiuliano Pochini 	chip->subdevice_id = subdevice_id;
62*3f6175ecSMark Brown 	chip->bad_board = true;
63*3f6175ecSMark Brown 	chip->has_midi = true;
6419b50063SGiuliano Pochini 	chip->dsp_code_to_load = FW_ECHO3G_DSP;
65dd7b254dSGiuliano Pochini 
66dd7b254dSGiuliano Pochini 	/* Load the DSP code and the ASIC on the PCI card and get
67dd7b254dSGiuliano Pochini 	what type of external box is attached */
68dd7b254dSGiuliano Pochini 	err = load_firmware(chip);
69dd7b254dSGiuliano Pochini 
70dd7b254dSGiuliano Pochini 	if (err < 0) {
71dd7b254dSGiuliano Pochini 		return err;
72dd7b254dSGiuliano Pochini 	} else if (err == E3G_GINA3G_BOX_TYPE) {
73dd7b254dSGiuliano Pochini 		chip->input_clock_types =	ECHO_CLOCK_BIT_INTERNAL |
74dd7b254dSGiuliano Pochini 						ECHO_CLOCK_BIT_SPDIF |
75dd7b254dSGiuliano Pochini 						ECHO_CLOCK_BIT_ADAT;
76dd7b254dSGiuliano Pochini 		chip->card_name = "Gina3G";
77dd7b254dSGiuliano Pochini 		chip->px_digital_out = chip->bx_digital_out = 6;
78dd7b254dSGiuliano Pochini 		chip->px_analog_in = chip->bx_analog_in = 14;
79dd7b254dSGiuliano Pochini 		chip->px_digital_in = chip->bx_digital_in = 16;
80dd7b254dSGiuliano Pochini 		chip->px_num = chip->bx_num = 24;
81*3f6175ecSMark Brown 		chip->has_phantom_power = true;
82*3f6175ecSMark Brown 		chip->hasnt_input_nominal_level = true;
83dd7b254dSGiuliano Pochini 	} else if (err == E3G_LAYLA3G_BOX_TYPE) {
84dd7b254dSGiuliano Pochini 		chip->input_clock_types =	ECHO_CLOCK_BIT_INTERNAL |
85dd7b254dSGiuliano Pochini 						ECHO_CLOCK_BIT_SPDIF |
86dd7b254dSGiuliano Pochini 						ECHO_CLOCK_BIT_ADAT |
87dd7b254dSGiuliano Pochini 						ECHO_CLOCK_BIT_WORD;
88dd7b254dSGiuliano Pochini 		chip->card_name = "Layla3G";
89dd7b254dSGiuliano Pochini 		chip->px_digital_out = chip->bx_digital_out = 8;
90dd7b254dSGiuliano Pochini 		chip->px_analog_in = chip->bx_analog_in = 16;
91dd7b254dSGiuliano Pochini 		chip->px_digital_in = chip->bx_digital_in = 24;
92dd7b254dSGiuliano Pochini 		chip->px_num = chip->bx_num = 32;
93dd7b254dSGiuliano Pochini 	} else {
94dd7b254dSGiuliano Pochini 		return -ENODEV;
95dd7b254dSGiuliano Pochini 	}
96dd7b254dSGiuliano Pochini 
97dd7b254dSGiuliano Pochini 	chip->digital_modes =	ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
98dd7b254dSGiuliano Pochini 				ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
99dd7b254dSGiuliano Pochini 				ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
100ad3499f4SGiuliano Pochini 
101ad3499f4SGiuliano Pochini 	return err;
102ad3499f4SGiuliano Pochini }
103ad3499f4SGiuliano Pochini 
104ad3499f4SGiuliano Pochini 
105ad3499f4SGiuliano Pochini 
106ad3499f4SGiuliano Pochini static int set_mixer_defaults(struct echoaudio *chip)
107ad3499f4SGiuliano Pochini {
108dd7b254dSGiuliano Pochini 	chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
109*3f6175ecSMark Brown 	chip->professional_spdif = false;
110*3f6175ecSMark Brown 	chip->non_audio_spdif = false;
111*3f6175ecSMark Brown 	chip->bad_board = false;
112*3f6175ecSMark Brown 	chip->phantom_power = false;
113ad3499f4SGiuliano Pochini 	return init_line_levels(chip);
114dd7b254dSGiuliano Pochini }
115dd7b254dSGiuliano Pochini 
116dd7b254dSGiuliano Pochini 
117dd7b254dSGiuliano Pochini 
118dd7b254dSGiuliano Pochini static int set_phantom_power(struct echoaudio *chip, char on)
119dd7b254dSGiuliano Pochini {
120dd7b254dSGiuliano Pochini 	u32 control_reg = le32_to_cpu(chip->comm_page->control_register);
121dd7b254dSGiuliano Pochini 
122dd7b254dSGiuliano Pochini 	if (on)
123dd7b254dSGiuliano Pochini 		control_reg |= E3G_PHANTOM_POWER;
124dd7b254dSGiuliano Pochini 	else
125dd7b254dSGiuliano Pochini 		control_reg &= ~E3G_PHANTOM_POWER;
126dd7b254dSGiuliano Pochini 
127dd7b254dSGiuliano Pochini 	chip->phantom_power = on;
128dd7b254dSGiuliano Pochini 	return write_control_reg(chip, control_reg,
129dd7b254dSGiuliano Pochini 				 le32_to_cpu(chip->comm_page->e3g_frq_register),
130dd7b254dSGiuliano Pochini 				 0);
131dd7b254dSGiuliano Pochini }
132