ALSA: hda - move 8086:fb30 quirk (stac9205) to the proper section
[linux-2.6] / sound / pci / echoaudio / mia_dsp.c
1 /****************************************************************************
2
3    Copyright Echo Digital Audio Corporation (c) 1998 - 2004
4    All rights reserved
5    www.echoaudio.com
6
7    This file is part of Echo Digital Audio's generic driver library.
8
9    Echo Digital Audio's generic driver library is free software;
10    you can redistribute it and/or modify it under the terms of
11    the GNU General Public License as published by the Free Software
12    Foundation.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22    MA  02111-1307, USA.
23
24    *************************************************************************
25
26  Translation from C++ and adaptation for use in ALSA-Driver
27  were made by Giuliano Pochini <pochini@shiny.it>
28
29 ****************************************************************************/
30
31
32 static int set_input_clock(struct echoaudio *chip, u16 clock);
33 static int set_professional_spdif(struct echoaudio *chip, char prof);
34 static int update_flags(struct echoaudio *chip);
35 static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
36                            int gain);
37 static int update_vmixer_level(struct echoaudio *chip);
38
39
40 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
41 {
42         int err;
43
44         DE_INIT(("init_hw() - Mia\n"));
45         if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA))
46                 return -ENODEV;
47
48         if ((err = init_dsp_comm_page(chip))) {
49                 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
50                 return err;
51         }
52
53         chip->device_id = device_id;
54         chip->subdevice_id = subdevice_id;
55         chip->bad_board = TRUE;
56         chip->dsp_code_to_load = &card_fw[FW_MIA_DSP];
57         /* Since this card has no ASIC, mark it as loaded so everything
58            works OK */
59         chip->asic_loaded = TRUE;
60         if ((subdevice_id & 0x0000f) == MIA_MIDI_REV)
61                 chip->has_midi = TRUE;
62         chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
63                 ECHO_CLOCK_BIT_SPDIF;
64
65         if ((err = load_firmware(chip)) < 0)
66                 return err;
67         chip->bad_board = FALSE;
68
69         if ((err = init_line_levels(chip)))
70                 return err;
71
72         DE_INIT(("init_hw done\n"));
73         return err;
74 }
75
76
77
78 static u32 detect_input_clocks(const struct echoaudio *chip)
79 {
80         u32 clocks_from_dsp, clock_bits;
81
82         /* Map the DSP clock detect bits to the generic driver clock
83            detect bits */
84         clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
85
86         clock_bits = ECHO_CLOCK_BIT_INTERNAL;
87
88         if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
89                 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
90
91         return clock_bits;
92 }
93
94
95
96 /* The Mia has no ASIC. Just do nothing */
97 static int load_asic(struct echoaudio *chip)
98 {
99         return 0;
100 }
101
102
103
104 static int set_sample_rate(struct echoaudio *chip, u32 rate)
105 {
106         u32 control_reg;
107
108         switch (rate) {
109         case 96000:
110                 control_reg = MIA_96000;
111                 break;
112         case 88200:
113                 control_reg = MIA_88200;
114                 break;
115         case 48000:
116                 control_reg = MIA_48000;
117                 break;
118         case 44100:
119                 control_reg = MIA_44100;
120                 break;
121         case 32000:
122                 control_reg = MIA_32000;
123                 break;
124         default:
125                 DE_ACT(("set_sample_rate: %d invalid!\n", rate));
126                 return -EINVAL;
127         }
128
129         /* Override the clock setting if this Mia is set to S/PDIF clock */
130         if (chip->input_clock == ECHO_CLOCK_SPDIF)
131                 control_reg |= MIA_SPDIF;
132
133         /* Set the control register if it has changed */
134         if (control_reg != le32_to_cpu(chip->comm_page->control_register)) {
135                 if (wait_handshake(chip))
136                         return -EIO;
137
138                 chip->comm_page->sample_rate = cpu_to_le32(rate);       /* ignored by the DSP */
139                 chip->comm_page->control_register = cpu_to_le32(control_reg);
140                 chip->sample_rate = rate;
141
142                 clear_handshake(chip);
143                 return send_vector(chip, DSP_VC_UPDATE_CLOCKS);
144         }
145         return 0;
146 }
147
148
149
150 static int set_input_clock(struct echoaudio *chip, u16 clock)
151 {
152         DE_ACT(("set_input_clock(%d)\n", clock));
153         if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL &&
154                        clock != ECHO_CLOCK_SPDIF))
155                 return -EINVAL;
156
157         chip->input_clock = clock;
158         return set_sample_rate(chip, chip->sample_rate);
159 }
160
161
162
163 /* This function routes the sound from a virtual channel to a real output */
164 static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe,
165                            int gain)
166 {
167         int index;
168
169         if (snd_BUG_ON(pipe >= num_pipes_out(chip) ||
170                        output >= num_busses_out(chip)))
171                 return -EINVAL;
172
173         if (wait_handshake(chip))
174                 return -EIO;
175
176         chip->vmixer_gain[output][pipe] = gain;
177         index = output * num_pipes_out(chip) + pipe;
178         chip->comm_page->vmixer[index] = gain;
179
180         DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain));
181         return 0;
182 }
183
184
185
186 /* Tell the DSP to read and update virtual mixer levels in comm page. */
187 static int update_vmixer_level(struct echoaudio *chip)
188 {
189         if (wait_handshake(chip))
190                 return -EIO;
191         clear_handshake(chip);
192         return send_vector(chip, DSP_VC_SET_VMIXER_GAIN);
193 }
194
195
196
197 /* Tell the DSP to reread the flags from the comm page */
198 static int update_flags(struct echoaudio *chip)
199 {
200         if (wait_handshake(chip))
201                 return -EIO;
202         clear_handshake(chip);
203         return send_vector(chip, DSP_VC_UPDATE_FLAGS);
204 }
205
206
207
208 static int set_professional_spdif(struct echoaudio *chip, char prof)
209 {
210         DE_ACT(("set_professional_spdif %d\n", prof));
211         if (prof)
212                 chip->comm_page->flags |=
213                         cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
214         else
215                 chip->comm_page->flags &=
216                         ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
217         chip->professional_spdif = prof;
218         return update_flags(chip);
219 }
220