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