xref: /openbmc/linux/sound/pci/echoaudio/indigoio_dsp.c (revision 19b50063780953563e3c3a2867c39aad7b9e64cf)
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 set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
33dd7b254dSGiuliano Pochini 			   int gain);
34dd7b254dSGiuliano Pochini static int update_vmixer_level(struct echoaudio *chip);
35dd7b254dSGiuliano Pochini 
36dd7b254dSGiuliano Pochini 
37dd7b254dSGiuliano Pochini static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
38dd7b254dSGiuliano Pochini {
39dd7b254dSGiuliano Pochini 	int err;
40dd7b254dSGiuliano Pochini 
41dd7b254dSGiuliano Pochini 	DE_INIT(("init_hw() - Indigo IO\n"));
42da3cec35STakashi Iwai 	if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO))
43da3cec35STakashi Iwai 		return -ENODEV;
44dd7b254dSGiuliano Pochini 
45dd7b254dSGiuliano Pochini 	if ((err = init_dsp_comm_page(chip))) {
46dd7b254dSGiuliano Pochini 		DE_INIT(("init_hw - could not initialize DSP comm page\n"));
47dd7b254dSGiuliano Pochini 		return err;
48dd7b254dSGiuliano Pochini 	}
49dd7b254dSGiuliano Pochini 
50dd7b254dSGiuliano Pochini 	chip->device_id = device_id;
51dd7b254dSGiuliano Pochini 	chip->subdevice_id = subdevice_id;
52dd7b254dSGiuliano Pochini 	chip->bad_board = TRUE;
53*19b50063SGiuliano Pochini 	chip->dsp_code_to_load = FW_INDIGO_IO_DSP;
54dd7b254dSGiuliano Pochini 	/* Since this card has no ASIC, mark it as loaded so everything
55dd7b254dSGiuliano Pochini 	   works OK */
56dd7b254dSGiuliano Pochini 	chip->asic_loaded = TRUE;
57dd7b254dSGiuliano Pochini 	chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL;
58dd7b254dSGiuliano Pochini 
59dd7b254dSGiuliano Pochini 	if ((err = load_firmware(chip)) < 0)
60dd7b254dSGiuliano Pochini 		return err;
61dd7b254dSGiuliano Pochini 	chip->bad_board = FALSE;
62dd7b254dSGiuliano Pochini 
63dd7b254dSGiuliano Pochini 	if ((err = init_line_levels(chip)) < 0)
64dd7b254dSGiuliano Pochini 		return err;
65dd7b254dSGiuliano Pochini 
66dd7b254dSGiuliano Pochini 	DE_INIT(("init_hw done\n"));
67dd7b254dSGiuliano Pochini 	return err;
68dd7b254dSGiuliano Pochini }
69dd7b254dSGiuliano Pochini 
70dd7b254dSGiuliano Pochini 
71dd7b254dSGiuliano Pochini 
72dd7b254dSGiuliano Pochini static u32 detect_input_clocks(const struct echoaudio *chip)
73dd7b254dSGiuliano Pochini {
74dd7b254dSGiuliano Pochini 	return ECHO_CLOCK_BIT_INTERNAL;
75dd7b254dSGiuliano Pochini }
76dd7b254dSGiuliano Pochini 
77dd7b254dSGiuliano Pochini 
78dd7b254dSGiuliano Pochini 
79dd7b254dSGiuliano Pochini /* The IndigoIO has no ASIC. Just do nothing */
80dd7b254dSGiuliano Pochini static int load_asic(struct echoaudio *chip)
81dd7b254dSGiuliano Pochini {
82dd7b254dSGiuliano Pochini 	return 0;
83dd7b254dSGiuliano Pochini }
84dd7b254dSGiuliano Pochini 
85dd7b254dSGiuliano Pochini 
86dd7b254dSGiuliano Pochini 
87dd7b254dSGiuliano Pochini static int set_sample_rate(struct echoaudio *chip, u32 rate)
88dd7b254dSGiuliano Pochini {
89dd7b254dSGiuliano Pochini 	if (wait_handshake(chip))
90dd7b254dSGiuliano Pochini 		return -EIO;
91dd7b254dSGiuliano Pochini 
92dd7b254dSGiuliano Pochini 	chip->sample_rate = rate;
93dd7b254dSGiuliano Pochini 	chip->comm_page->sample_rate = cpu_to_le32(rate);
94dd7b254dSGiuliano Pochini 	clear_handshake(chip);
95dd7b254dSGiuliano Pochini 	return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
96dd7b254dSGiuliano Pochini }
97dd7b254dSGiuliano Pochini 
98dd7b254dSGiuliano Pochini 
99dd7b254dSGiuliano Pochini 
100dd7b254dSGiuliano Pochini /* This function routes the sound from a virtual channel to a real output */
101dd7b254dSGiuliano Pochini static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
102dd7b254dSGiuliano Pochini 			   int gain)
103dd7b254dSGiuliano Pochini {
104dd7b254dSGiuliano Pochini 	int index;
105dd7b254dSGiuliano Pochini 
106da3cec35STakashi Iwai 	if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
107da3cec35STakashi Iwai 		       output >= num_busses_out(chip)))
108da3cec35STakashi Iwai 		return -EINVAL;
109dd7b254dSGiuliano Pochini 
110dd7b254dSGiuliano Pochini 	if (wait_handshake(chip))
111dd7b254dSGiuliano Pochini 		return -EIO;
112dd7b254dSGiuliano Pochini 
113dd7b254dSGiuliano Pochini 	chip->vmixer_gain[output][pipe] = gain;
114dd7b254dSGiuliano Pochini 	index = output * num_pipes_out(chip) + pipe;
115dd7b254dSGiuliano Pochini 	chip->comm_page->vmixer[index] = gain;
116dd7b254dSGiuliano Pochini 
117dd7b254dSGiuliano Pochini 	DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
118dd7b254dSGiuliano Pochini 	return 0;
119dd7b254dSGiuliano Pochini }
120dd7b254dSGiuliano Pochini 
121dd7b254dSGiuliano Pochini 
122dd7b254dSGiuliano Pochini 
123dd7b254dSGiuliano Pochini /* Tell the DSP to read and update virtual mixer levels in comm page. */
124dd7b254dSGiuliano Pochini static int update_vmixer_level(struct echoaudio *chip)
125dd7b254dSGiuliano Pochini {
126dd7b254dSGiuliano Pochini 	if (wait_handshake(chip))
127dd7b254dSGiuliano Pochini 		return -EIO;
128dd7b254dSGiuliano Pochini 	clear_handshake(chip);
129dd7b254dSGiuliano Pochini 	return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
130dd7b254dSGiuliano Pochini }
131dd7b254dSGiuliano Pochini 
132