1*4882a593Smuzhiyun /****************************************************************************
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright Echo Digital Audio Corporation (c) 1998 - 2004
4*4882a593Smuzhiyun All rights reserved
5*4882a593Smuzhiyun www.echoaudio.com
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun This file is part of Echo Digital Audio's generic driver library.
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun Echo Digital Audio's generic driver library is free software;
10*4882a593Smuzhiyun you can redistribute it and/or modify it under the terms of
11*4882a593Smuzhiyun the GNU General Public License as published by the Free Software
12*4882a593Smuzhiyun Foundation.
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun This program is distributed in the hope that it will be useful,
15*4882a593Smuzhiyun but WITHOUT ANY WARRANTY; without even the implied warranty of
16*4882a593Smuzhiyun MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17*4882a593Smuzhiyun GNU General Public License for more details.
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun You should have received a copy of the GNU General Public License
20*4882a593Smuzhiyun along with this program; if not, write to the Free Software
21*4882a593Smuzhiyun Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22*4882a593Smuzhiyun MA 02111-1307, USA.
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun *************************************************************************
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun Translation from C++ and adaptation for use in ALSA-Driver
27*4882a593Smuzhiyun were made by Giuliano Pochini <pochini@shiny.it>
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun ****************************************************************************/
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #if PAGE_SIZE < 4096
32*4882a593Smuzhiyun #error PAGE_SIZE is < 4k
33*4882a593Smuzhiyun #endif
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun static int restore_dsp_rettings(struct echoaudio *chip);
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /* Some vector commands involve the DSP reading or writing data to and from the
39*4882a593Smuzhiyun comm page; if you send one of these commands to the DSP, it will complete the
40*4882a593Smuzhiyun command and then write a non-zero value to the Handshake field in the
41*4882a593Smuzhiyun comm page. This function waits for the handshake to show up. */
wait_handshake(struct echoaudio * chip)42*4882a593Smuzhiyun static int wait_handshake(struct echoaudio *chip)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun int i;
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /* Wait up to 20ms for the handshake from the DSP */
47*4882a593Smuzhiyun for (i = 0; i < HANDSHAKE_TIMEOUT; i++) {
48*4882a593Smuzhiyun /* Look for the handshake value */
49*4882a593Smuzhiyun barrier();
50*4882a593Smuzhiyun if (chip->comm_page->handshake) {
51*4882a593Smuzhiyun return 0;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun udelay(1);
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun dev_err(chip->card->dev, "wait_handshake(): Timeout waiting for DSP\n");
57*4882a593Smuzhiyun return -EBUSY;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* Much of the interaction between the DSP and the driver is done via vector
63*4882a593Smuzhiyun commands; send_vector writes a vector command to the DSP. Typically, this
64*4882a593Smuzhiyun causes the DSP to read or write fields in the comm page.
65*4882a593Smuzhiyun PCI posting is not required thanks to the handshake logic. */
send_vector(struct echoaudio * chip,u32 command)66*4882a593Smuzhiyun static int send_vector(struct echoaudio *chip, u32 command)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun int i;
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun wmb(); /* Flush all pending writes before sending the command */
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /* Wait up to 100ms for the "vector busy" bit to be off */
73*4882a593Smuzhiyun for (i = 0; i < VECTOR_BUSY_TIMEOUT; i++) {
74*4882a593Smuzhiyun if (!(get_dsp_register(chip, CHI32_VECTOR_REG) &
75*4882a593Smuzhiyun CHI32_VECTOR_BUSY)) {
76*4882a593Smuzhiyun set_dsp_register(chip, CHI32_VECTOR_REG, command);
77*4882a593Smuzhiyun /*if (i) DE_ACT(("send_vector time: %d\n", i));*/
78*4882a593Smuzhiyun return 0;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun udelay(1);
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun dev_err(chip->card->dev, "timeout on send_vector\n");
84*4882a593Smuzhiyun return -EBUSY;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /* write_dsp writes a 32-bit value to the DSP; this is used almost
90*4882a593Smuzhiyun exclusively for loading the DSP. */
write_dsp(struct echoaudio * chip,u32 data)91*4882a593Smuzhiyun static int write_dsp(struct echoaudio *chip, u32 data)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun u32 status, i;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun for (i = 0; i < 10000000; i++) { /* timeout = 10s */
96*4882a593Smuzhiyun status = get_dsp_register(chip, CHI32_STATUS_REG);
97*4882a593Smuzhiyun if ((status & CHI32_STATUS_HOST_WRITE_EMPTY) != 0) {
98*4882a593Smuzhiyun set_dsp_register(chip, CHI32_DATA_REG, data);
99*4882a593Smuzhiyun wmb(); /* write it immediately */
100*4882a593Smuzhiyun return 0;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun udelay(1);
103*4882a593Smuzhiyun cond_resched();
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun chip->bad_board = true; /* Set true until DSP re-loaded */
107*4882a593Smuzhiyun dev_dbg(chip->card->dev, "write_dsp: Set bad_board to true\n");
108*4882a593Smuzhiyun return -EIO;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /* read_dsp reads a 32-bit value from the DSP; this is used almost
114*4882a593Smuzhiyun exclusively for loading the DSP and checking the status of the ASIC. */
read_dsp(struct echoaudio * chip,u32 * data)115*4882a593Smuzhiyun static int read_dsp(struct echoaudio *chip, u32 *data)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun u32 status, i;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun for (i = 0; i < READ_DSP_TIMEOUT; i++) {
120*4882a593Smuzhiyun status = get_dsp_register(chip, CHI32_STATUS_REG);
121*4882a593Smuzhiyun if ((status & CHI32_STATUS_HOST_READ_FULL) != 0) {
122*4882a593Smuzhiyun *data = get_dsp_register(chip, CHI32_DATA_REG);
123*4882a593Smuzhiyun return 0;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun udelay(1);
126*4882a593Smuzhiyun cond_resched();
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun chip->bad_board = true; /* Set true until DSP re-loaded */
130*4882a593Smuzhiyun dev_err(chip->card->dev, "read_dsp: Set bad_board to true\n");
131*4882a593Smuzhiyun return -EIO;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun /****************************************************************************
137*4882a593Smuzhiyun Firmware loading functions
138*4882a593Smuzhiyun ****************************************************************************/
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun /* This function is used to read back the serial number from the DSP;
141*4882a593Smuzhiyun this is triggered by the SET_COMMPAGE_ADDR command.
142*4882a593Smuzhiyun Only some early Echogals products have serial numbers in the ROM;
143*4882a593Smuzhiyun the serial number is not used, but you still need to do this as
144*4882a593Smuzhiyun part of the DSP load process. */
read_sn(struct echoaudio * chip)145*4882a593Smuzhiyun static int read_sn(struct echoaudio *chip)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun int i;
148*4882a593Smuzhiyun u32 sn[6];
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun for (i = 0; i < 5; i++) {
151*4882a593Smuzhiyun if (read_dsp(chip, &sn[i])) {
152*4882a593Smuzhiyun dev_err(chip->card->dev,
153*4882a593Smuzhiyun "Failed to read serial number\n");
154*4882a593Smuzhiyun return -EIO;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun dev_dbg(chip->card->dev,
158*4882a593Smuzhiyun "Read serial number %08x %08x %08x %08x %08x\n",
159*4882a593Smuzhiyun sn[0], sn[1], sn[2], sn[3], sn[4]);
160*4882a593Smuzhiyun return 0;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun #ifndef ECHOCARD_HAS_ASIC
166*4882a593Smuzhiyun /* This card has no ASIC, just return ok */
check_asic_status(struct echoaudio * chip)167*4882a593Smuzhiyun static inline int check_asic_status(struct echoaudio *chip)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun chip->asic_loaded = true;
170*4882a593Smuzhiyun return 0;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun #endif /* !ECHOCARD_HAS_ASIC */
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_ASIC
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /* Load ASIC code - done after the DSP is loaded */
load_asic_generic(struct echoaudio * chip,u32 cmd,short asic)180*4882a593Smuzhiyun static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun const struct firmware *fw;
183*4882a593Smuzhiyun int err;
184*4882a593Smuzhiyun u32 i, size;
185*4882a593Smuzhiyun u8 *code;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun err = get_firmware(&fw, chip, asic);
188*4882a593Smuzhiyun if (err < 0) {
189*4882a593Smuzhiyun dev_warn(chip->card->dev, "Firmware not found !\n");
190*4882a593Smuzhiyun return err;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun code = (u8 *)fw->data;
194*4882a593Smuzhiyun size = fw->size;
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /* Send the "Here comes the ASIC" command */
197*4882a593Smuzhiyun if (write_dsp(chip, cmd) < 0)
198*4882a593Smuzhiyun goto la_error;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /* Write length of ASIC file in bytes */
201*4882a593Smuzhiyun if (write_dsp(chip, size) < 0)
202*4882a593Smuzhiyun goto la_error;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun for (i = 0; i < size; i++) {
205*4882a593Smuzhiyun if (write_dsp(chip, code[i]) < 0)
206*4882a593Smuzhiyun goto la_error;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun free_firmware(fw, chip);
210*4882a593Smuzhiyun return 0;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun la_error:
213*4882a593Smuzhiyun dev_err(chip->card->dev, "failed on write_dsp\n");
214*4882a593Smuzhiyun free_firmware(fw, chip);
215*4882a593Smuzhiyun return -EIO;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun #endif /* ECHOCARD_HAS_ASIC */
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun #ifdef DSP_56361
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun /* Install the resident loader for 56361 DSPs; The resident loader is on
225*4882a593Smuzhiyun the EPROM on the board for 56301 DSP. The resident loader is a tiny little
226*4882a593Smuzhiyun program that is used to load the real DSP code. */
install_resident_loader(struct echoaudio * chip)227*4882a593Smuzhiyun static int install_resident_loader(struct echoaudio *chip)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun u32 address;
230*4882a593Smuzhiyun int index, words, i;
231*4882a593Smuzhiyun u16 *code;
232*4882a593Smuzhiyun u32 status;
233*4882a593Smuzhiyun const struct firmware *fw;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /* 56361 cards only! This check is required by the old 56301-based
236*4882a593Smuzhiyun Mona and Gina24 */
237*4882a593Smuzhiyun if (chip->device_id != DEVICE_ID_56361)
238*4882a593Smuzhiyun return 0;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun /* Look to see if the resident loader is present. If the resident
241*4882a593Smuzhiyun loader is already installed, host flag 5 will be on. */
242*4882a593Smuzhiyun status = get_dsp_register(chip, CHI32_STATUS_REG);
243*4882a593Smuzhiyun if (status & CHI32_STATUS_REG_HF5) {
244*4882a593Smuzhiyun dev_dbg(chip->card->dev,
245*4882a593Smuzhiyun "Resident loader already installed; status is 0x%x\n",
246*4882a593Smuzhiyun status);
247*4882a593Smuzhiyun return 0;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun i = get_firmware(&fw, chip, FW_361_LOADER);
251*4882a593Smuzhiyun if (i < 0) {
252*4882a593Smuzhiyun dev_warn(chip->card->dev, "Firmware not found !\n");
253*4882a593Smuzhiyun return i;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun /* The DSP code is an array of 16 bit words. The array is divided up
257*4882a593Smuzhiyun into sections. The first word of each section is the size in words,
258*4882a593Smuzhiyun followed by the section type.
259*4882a593Smuzhiyun Since DSP addresses and data are 24 bits wide, they each take up two
260*4882a593Smuzhiyun 16 bit words in the array.
261*4882a593Smuzhiyun This is a lot like the other loader loop, but it's not a loop, you
262*4882a593Smuzhiyun don't write the memory type, and you don't write a zero at the end. */
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun /* Set DSP format bits for 24 bit mode */
265*4882a593Smuzhiyun set_dsp_register(chip, CHI32_CONTROL_REG,
266*4882a593Smuzhiyun get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun code = (u16 *)fw->data;
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun /* Skip the header section; the first word in the array is the size
271*4882a593Smuzhiyun of the first section, so the first real section of code is pointed
272*4882a593Smuzhiyun to by Code[0]. */
273*4882a593Smuzhiyun index = code[0];
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun /* Skip the section size, LRS block type, and DSP memory type */
276*4882a593Smuzhiyun index += 3;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun /* Get the number of DSP words to write */
279*4882a593Smuzhiyun words = code[index++];
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun /* Get the DSP address for this block; 24 bits, so build from two words */
282*4882a593Smuzhiyun address = ((u32)code[index] << 16) + code[index + 1];
283*4882a593Smuzhiyun index += 2;
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /* Write the count to the DSP */
286*4882a593Smuzhiyun if (write_dsp(chip, words)) {
287*4882a593Smuzhiyun dev_err(chip->card->dev,
288*4882a593Smuzhiyun "install_resident_loader: Failed to write word count!\n");
289*4882a593Smuzhiyun goto irl_error;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun /* Write the DSP address */
292*4882a593Smuzhiyun if (write_dsp(chip, address)) {
293*4882a593Smuzhiyun dev_err(chip->card->dev,
294*4882a593Smuzhiyun "install_resident_loader: Failed to write DSP address!\n");
295*4882a593Smuzhiyun goto irl_error;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun /* Write out this block of code to the DSP */
298*4882a593Smuzhiyun for (i = 0; i < words; i++) {
299*4882a593Smuzhiyun u32 data;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun data = ((u32)code[index] << 16) + code[index + 1];
302*4882a593Smuzhiyun if (write_dsp(chip, data)) {
303*4882a593Smuzhiyun dev_err(chip->card->dev,
304*4882a593Smuzhiyun "install_resident_loader: Failed to write DSP code\n");
305*4882a593Smuzhiyun goto irl_error;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun index += 2;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /* Wait for flag 5 to come up */
311*4882a593Smuzhiyun for (i = 0; i < 200; i++) { /* Timeout is 50us * 200 = 10ms */
312*4882a593Smuzhiyun udelay(50);
313*4882a593Smuzhiyun status = get_dsp_register(chip, CHI32_STATUS_REG);
314*4882a593Smuzhiyun if (status & CHI32_STATUS_REG_HF5)
315*4882a593Smuzhiyun break;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun if (i == 200) {
319*4882a593Smuzhiyun dev_err(chip->card->dev, "Resident loader failed to set HF5\n");
320*4882a593Smuzhiyun goto irl_error;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun dev_dbg(chip->card->dev, "Resident loader successfully installed\n");
324*4882a593Smuzhiyun free_firmware(fw, chip);
325*4882a593Smuzhiyun return 0;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun irl_error:
328*4882a593Smuzhiyun free_firmware(fw, chip);
329*4882a593Smuzhiyun return -EIO;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun #endif /* DSP_56361 */
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun
load_dsp(struct echoaudio * chip,u16 * code)335*4882a593Smuzhiyun static int load_dsp(struct echoaudio *chip, u16 *code)
336*4882a593Smuzhiyun {
337*4882a593Smuzhiyun u32 address, data;
338*4882a593Smuzhiyun int index, words, i;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun if (chip->dsp_code == code) {
341*4882a593Smuzhiyun dev_warn(chip->card->dev, "DSP is already loaded!\n");
342*4882a593Smuzhiyun return 0;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun chip->bad_board = true; /* Set true until DSP loaded */
345*4882a593Smuzhiyun chip->dsp_code = NULL; /* Current DSP code not loaded */
346*4882a593Smuzhiyun chip->asic_loaded = false; /* Loading the DSP code will reset the ASIC */
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun dev_dbg(chip->card->dev, "load_dsp: Set bad_board to true\n");
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun /* If this board requires a resident loader, install it. */
351*4882a593Smuzhiyun #ifdef DSP_56361
352*4882a593Smuzhiyun if ((i = install_resident_loader(chip)) < 0)
353*4882a593Smuzhiyun return i;
354*4882a593Smuzhiyun #endif
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /* Send software reset command */
357*4882a593Smuzhiyun if (send_vector(chip, DSP_VC_RESET) < 0) {
358*4882a593Smuzhiyun dev_err(chip->card->dev,
359*4882a593Smuzhiyun "LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n");
360*4882a593Smuzhiyun return -EIO;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun /* Delay 10us */
363*4882a593Smuzhiyun udelay(10);
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun /* Wait 10ms for HF3 to indicate that software reset is complete */
366*4882a593Smuzhiyun for (i = 0; i < 1000; i++) { /* Timeout is 10us * 1000 = 10ms */
367*4882a593Smuzhiyun if (get_dsp_register(chip, CHI32_STATUS_REG) &
368*4882a593Smuzhiyun CHI32_STATUS_REG_HF3)
369*4882a593Smuzhiyun break;
370*4882a593Smuzhiyun udelay(10);
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun if (i == 1000) {
374*4882a593Smuzhiyun dev_err(chip->card->dev,
375*4882a593Smuzhiyun "load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n");
376*4882a593Smuzhiyun return -EIO;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun /* Set DSP format bits for 24 bit mode now that soft reset is done */
380*4882a593Smuzhiyun set_dsp_register(chip, CHI32_CONTROL_REG,
381*4882a593Smuzhiyun get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900);
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun /* Main loader loop */
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun index = code[0];
386*4882a593Smuzhiyun for (;;) {
387*4882a593Smuzhiyun int block_type, mem_type;
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun /* Total Block Size */
390*4882a593Smuzhiyun index++;
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* Block Type */
393*4882a593Smuzhiyun block_type = code[index];
394*4882a593Smuzhiyun if (block_type == 4) /* We're finished */
395*4882a593Smuzhiyun break;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun index++;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun /* Memory Type P=0,X=1,Y=2 */
400*4882a593Smuzhiyun mem_type = code[index++];
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun /* Block Code Size */
403*4882a593Smuzhiyun words = code[index++];
404*4882a593Smuzhiyun if (words == 0) /* We're finished */
405*4882a593Smuzhiyun break;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun /* Start Address */
408*4882a593Smuzhiyun address = ((u32)code[index] << 16) + code[index + 1];
409*4882a593Smuzhiyun index += 2;
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun if (write_dsp(chip, words) < 0) {
412*4882a593Smuzhiyun dev_err(chip->card->dev,
413*4882a593Smuzhiyun "load_dsp: failed to write number of DSP words\n");
414*4882a593Smuzhiyun return -EIO;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun if (write_dsp(chip, address) < 0) {
417*4882a593Smuzhiyun dev_err(chip->card->dev,
418*4882a593Smuzhiyun "load_dsp: failed to write DSP address\n");
419*4882a593Smuzhiyun return -EIO;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun if (write_dsp(chip, mem_type) < 0) {
422*4882a593Smuzhiyun dev_err(chip->card->dev,
423*4882a593Smuzhiyun "load_dsp: failed to write DSP memory type\n");
424*4882a593Smuzhiyun return -EIO;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun /* Code */
427*4882a593Smuzhiyun for (i = 0; i < words; i++, index+=2) {
428*4882a593Smuzhiyun data = ((u32)code[index] << 16) + code[index + 1];
429*4882a593Smuzhiyun if (write_dsp(chip, data) < 0) {
430*4882a593Smuzhiyun dev_err(chip->card->dev,
431*4882a593Smuzhiyun "load_dsp: failed to write DSP data\n");
432*4882a593Smuzhiyun return -EIO;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun if (write_dsp(chip, 0) < 0) { /* We're done!!! */
438*4882a593Smuzhiyun dev_err(chip->card->dev,
439*4882a593Smuzhiyun "load_dsp: Failed to write final zero\n");
440*4882a593Smuzhiyun return -EIO;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun udelay(10);
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun for (i = 0; i < 5000; i++) { /* Timeout is 100us * 5000 = 500ms */
445*4882a593Smuzhiyun /* Wait for flag 4 - indicates that the DSP loaded OK */
446*4882a593Smuzhiyun if (get_dsp_register(chip, CHI32_STATUS_REG) &
447*4882a593Smuzhiyun CHI32_STATUS_REG_HF4) {
448*4882a593Smuzhiyun set_dsp_register(chip, CHI32_CONTROL_REG,
449*4882a593Smuzhiyun get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00);
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) {
452*4882a593Smuzhiyun dev_err(chip->card->dev,
453*4882a593Smuzhiyun "load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n");
454*4882a593Smuzhiyun return -EIO;
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun if (write_dsp(chip, chip->comm_page_phys) < 0) {
458*4882a593Smuzhiyun dev_err(chip->card->dev,
459*4882a593Smuzhiyun "load_dsp: Failed to write comm page address\n");
460*4882a593Smuzhiyun return -EIO;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun /* Get the serial number via slave mode.
464*4882a593Smuzhiyun This is triggered by the SET_COMMPAGE_ADDR command.
465*4882a593Smuzhiyun We don't actually use the serial number but we have to
466*4882a593Smuzhiyun get it as part of the DSP init voodoo. */
467*4882a593Smuzhiyun if (read_sn(chip) < 0) {
468*4882a593Smuzhiyun dev_err(chip->card->dev,
469*4882a593Smuzhiyun "load_dsp: Failed to read serial number\n");
470*4882a593Smuzhiyun return -EIO;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun chip->dsp_code = code; /* Show which DSP code loaded */
474*4882a593Smuzhiyun chip->bad_board = false; /* DSP OK */
475*4882a593Smuzhiyun return 0;
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun udelay(100);
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun dev_err(chip->card->dev,
481*4882a593Smuzhiyun "load_dsp: DSP load timed out waiting for HF4\n");
482*4882a593Smuzhiyun return -EIO;
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun /* load_firmware takes care of loading the DSP and any ASIC code. */
load_firmware(struct echoaudio * chip)488*4882a593Smuzhiyun static int load_firmware(struct echoaudio *chip)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun const struct firmware *fw;
491*4882a593Smuzhiyun int box_type, err;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if (snd_BUG_ON(!chip->comm_page))
494*4882a593Smuzhiyun return -EPERM;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun /* See if the ASIC is present and working - only if the DSP is already loaded */
497*4882a593Smuzhiyun if (chip->dsp_code) {
498*4882a593Smuzhiyun if ((box_type = check_asic_status(chip)) >= 0)
499*4882a593Smuzhiyun return box_type;
500*4882a593Smuzhiyun /* ASIC check failed; force the DSP to reload */
501*4882a593Smuzhiyun chip->dsp_code = NULL;
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun err = get_firmware(&fw, chip, chip->dsp_code_to_load);
505*4882a593Smuzhiyun if (err < 0)
506*4882a593Smuzhiyun return err;
507*4882a593Smuzhiyun err = load_dsp(chip, (u16 *)fw->data);
508*4882a593Smuzhiyun free_firmware(fw, chip);
509*4882a593Smuzhiyun if (err < 0)
510*4882a593Smuzhiyun return err;
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun if ((box_type = load_asic(chip)) < 0)
513*4882a593Smuzhiyun return box_type; /* error */
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun return box_type;
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun /****************************************************************************
521*4882a593Smuzhiyun Mixer functions
522*4882a593Smuzhiyun ****************************************************************************/
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun #if defined(ECHOCARD_HAS_INPUT_NOMINAL_LEVEL) || \
525*4882a593Smuzhiyun defined(ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL)
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun /* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */
set_nominal_level(struct echoaudio * chip,u16 index,char consumer)528*4882a593Smuzhiyun static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun if (snd_BUG_ON(index >= num_busses_out(chip) + num_busses_in(chip)))
531*4882a593Smuzhiyun return -EINVAL;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun /* Wait for the handshake (OK even if ASIC is not loaded) */
534*4882a593Smuzhiyun if (wait_handshake(chip))
535*4882a593Smuzhiyun return -EIO;
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun chip->nominal_level[index] = consumer;
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun if (consumer)
540*4882a593Smuzhiyun chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index);
541*4882a593Smuzhiyun else
542*4882a593Smuzhiyun chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index);
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun return 0;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun #endif /* ECHOCARD_HAS_*_NOMINAL_LEVEL */
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun /* Set the gain for a single physical output channel (dB). */
set_output_gain(struct echoaudio * chip,u16 channel,s8 gain)552*4882a593Smuzhiyun static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun if (snd_BUG_ON(channel >= num_busses_out(chip)))
555*4882a593Smuzhiyun return -EINVAL;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun if (wait_handshake(chip))
558*4882a593Smuzhiyun return -EIO;
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun /* Save the new value */
561*4882a593Smuzhiyun chip->output_gain[channel] = gain;
562*4882a593Smuzhiyun chip->comm_page->line_out_level[channel] = gain;
563*4882a593Smuzhiyun return 0;
564*4882a593Smuzhiyun }
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_MONITOR
569*4882a593Smuzhiyun /* Set the monitor level from an input bus to an output bus. */
set_monitor_gain(struct echoaudio * chip,u16 output,u16 input,s8 gain)570*4882a593Smuzhiyun static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input,
571*4882a593Smuzhiyun s8 gain)
572*4882a593Smuzhiyun {
573*4882a593Smuzhiyun if (snd_BUG_ON(output >= num_busses_out(chip) ||
574*4882a593Smuzhiyun input >= num_busses_in(chip)))
575*4882a593Smuzhiyun return -EINVAL;
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun if (wait_handshake(chip))
578*4882a593Smuzhiyun return -EIO;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun chip->monitor_gain[output][input] = gain;
581*4882a593Smuzhiyun chip->comm_page->monitors[monitor_index(chip, output, input)] = gain;
582*4882a593Smuzhiyun return 0;
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun #endif /* ECHOCARD_HAS_MONITOR */
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun /* Tell the DSP to read and update output, nominal & monitor levels in comm page. */
update_output_line_level(struct echoaudio * chip)588*4882a593Smuzhiyun static int update_output_line_level(struct echoaudio *chip)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun if (wait_handshake(chip))
591*4882a593Smuzhiyun return -EIO;
592*4882a593Smuzhiyun clear_handshake(chip);
593*4882a593Smuzhiyun return send_vector(chip, DSP_VC_UPDATE_OUTVOL);
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun /* Tell the DSP to read and update input levels in comm page */
update_input_line_level(struct echoaudio * chip)599*4882a593Smuzhiyun static int update_input_line_level(struct echoaudio *chip)
600*4882a593Smuzhiyun {
601*4882a593Smuzhiyun if (wait_handshake(chip))
602*4882a593Smuzhiyun return -EIO;
603*4882a593Smuzhiyun clear_handshake(chip);
604*4882a593Smuzhiyun return send_vector(chip, DSP_VC_UPDATE_INGAIN);
605*4882a593Smuzhiyun }
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun /* set_meters_on turns the meters on or off. If meters are turned on, the DSP
610*4882a593Smuzhiyun will write the meter and clock detect values to the comm page at about 30Hz */
set_meters_on(struct echoaudio * chip,char on)611*4882a593Smuzhiyun static void set_meters_on(struct echoaudio *chip, char on)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun if (on && !chip->meters_enabled) {
614*4882a593Smuzhiyun send_vector(chip, DSP_VC_METERS_ON);
615*4882a593Smuzhiyun chip->meters_enabled = 1;
616*4882a593Smuzhiyun } else if (!on && chip->meters_enabled) {
617*4882a593Smuzhiyun send_vector(chip, DSP_VC_METERS_OFF);
618*4882a593Smuzhiyun chip->meters_enabled = 0;
619*4882a593Smuzhiyun memset((s8 *)chip->comm_page->vu_meter, ECHOGAIN_MUTED,
620*4882a593Smuzhiyun DSP_MAXPIPES);
621*4882a593Smuzhiyun memset((s8 *)chip->comm_page->peak_meter, ECHOGAIN_MUTED,
622*4882a593Smuzhiyun DSP_MAXPIPES);
623*4882a593Smuzhiyun }
624*4882a593Smuzhiyun }
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun /* Fill out an the given array using the current values in the comm page.
629*4882a593Smuzhiyun Meters are written in the comm page by the DSP in this order:
630*4882a593Smuzhiyun Output busses
631*4882a593Smuzhiyun Input busses
632*4882a593Smuzhiyun Output pipes (vmixer cards only)
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun This function assumes there are no more than 16 in/out busses or pipes
635*4882a593Smuzhiyun Meters is an array [3][16][2] of long. */
get_audio_meters(struct echoaudio * chip,long * meters)636*4882a593Smuzhiyun static void get_audio_meters(struct echoaudio *chip, long *meters)
637*4882a593Smuzhiyun {
638*4882a593Smuzhiyun unsigned int i, m, n;
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun for (i = 0 ; i < 96; i++)
641*4882a593Smuzhiyun meters[i] = 0;
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun for (m = 0, n = 0, i = 0; i < num_busses_out(chip); i++, m++) {
644*4882a593Smuzhiyun meters[n++] = chip->comm_page->vu_meter[m];
645*4882a593Smuzhiyun meters[n++] = chip->comm_page->peak_meter[m];
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun #ifdef ECHOCARD_ECHO3G
649*4882a593Smuzhiyun m = E3G_MAX_OUTPUTS; /* Skip unused meters */
650*4882a593Smuzhiyun #endif
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun for (n = 32, i = 0; i < num_busses_in(chip); i++, m++) {
653*4882a593Smuzhiyun meters[n++] = chip->comm_page->vu_meter[m];
654*4882a593Smuzhiyun meters[n++] = chip->comm_page->peak_meter[m];
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_VMIXER
657*4882a593Smuzhiyun for (n = 64, i = 0; i < num_pipes_out(chip); i++, m++) {
658*4882a593Smuzhiyun meters[n++] = chip->comm_page->vu_meter[m];
659*4882a593Smuzhiyun meters[n++] = chip->comm_page->peak_meter[m];
660*4882a593Smuzhiyun }
661*4882a593Smuzhiyun #endif
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun
restore_dsp_rettings(struct echoaudio * chip)666*4882a593Smuzhiyun static int restore_dsp_rettings(struct echoaudio *chip)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun int i, o, err;
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun if ((err = check_asic_status(chip)) < 0)
671*4882a593Smuzhiyun return err;
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun /* Gina20/Darla20 only. Should be harmless for other cards. */
674*4882a593Smuzhiyun chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF;
675*4882a593Smuzhiyun chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF;
676*4882a593Smuzhiyun chip->comm_page->handshake = cpu_to_le32(0xffffffff);
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun /* Restore output busses */
679*4882a593Smuzhiyun for (i = 0; i < num_busses_out(chip); i++) {
680*4882a593Smuzhiyun err = set_output_gain(chip, i, chip->output_gain[i]);
681*4882a593Smuzhiyun if (err < 0)
682*4882a593Smuzhiyun return err;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_VMIXER
686*4882a593Smuzhiyun for (i = 0; i < num_pipes_out(chip); i++)
687*4882a593Smuzhiyun for (o = 0; o < num_busses_out(chip); o++) {
688*4882a593Smuzhiyun err = set_vmixer_gain(chip, o, i,
689*4882a593Smuzhiyun chip->vmixer_gain[o][i]);
690*4882a593Smuzhiyun if (err < 0)
691*4882a593Smuzhiyun return err;
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun if (update_vmixer_level(chip) < 0)
694*4882a593Smuzhiyun return -EIO;
695*4882a593Smuzhiyun #endif /* ECHOCARD_HAS_VMIXER */
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_MONITOR
698*4882a593Smuzhiyun for (o = 0; o < num_busses_out(chip); o++)
699*4882a593Smuzhiyun for (i = 0; i < num_busses_in(chip); i++) {
700*4882a593Smuzhiyun err = set_monitor_gain(chip, o, i,
701*4882a593Smuzhiyun chip->monitor_gain[o][i]);
702*4882a593Smuzhiyun if (err < 0)
703*4882a593Smuzhiyun return err;
704*4882a593Smuzhiyun }
705*4882a593Smuzhiyun #endif /* ECHOCARD_HAS_MONITOR */
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_INPUT_GAIN
708*4882a593Smuzhiyun for (i = 0; i < num_busses_in(chip); i++) {
709*4882a593Smuzhiyun err = set_input_gain(chip, i, chip->input_gain[i]);
710*4882a593Smuzhiyun if (err < 0)
711*4882a593Smuzhiyun return err;
712*4882a593Smuzhiyun }
713*4882a593Smuzhiyun #endif /* ECHOCARD_HAS_INPUT_GAIN */
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun err = update_output_line_level(chip);
716*4882a593Smuzhiyun if (err < 0)
717*4882a593Smuzhiyun return err;
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun err = update_input_line_level(chip);
720*4882a593Smuzhiyun if (err < 0)
721*4882a593Smuzhiyun return err;
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun err = set_sample_rate(chip, chip->sample_rate);
724*4882a593Smuzhiyun if (err < 0)
725*4882a593Smuzhiyun return err;
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun if (chip->meters_enabled) {
728*4882a593Smuzhiyun err = send_vector(chip, DSP_VC_METERS_ON);
729*4882a593Smuzhiyun if (err < 0)
730*4882a593Smuzhiyun return err;
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
734*4882a593Smuzhiyun if (set_digital_mode(chip, chip->digital_mode) < 0)
735*4882a593Smuzhiyun return -EIO;
736*4882a593Smuzhiyun #endif
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_DIGITAL_IO
739*4882a593Smuzhiyun if (set_professional_spdif(chip, chip->professional_spdif) < 0)
740*4882a593Smuzhiyun return -EIO;
741*4882a593Smuzhiyun #endif
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_PHANTOM_POWER
744*4882a593Smuzhiyun if (set_phantom_power(chip, chip->phantom_power) < 0)
745*4882a593Smuzhiyun return -EIO;
746*4882a593Smuzhiyun #endif
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
749*4882a593Smuzhiyun /* set_input_clock() also restores automute setting */
750*4882a593Smuzhiyun if (set_input_clock(chip, chip->input_clock) < 0)
751*4882a593Smuzhiyun return -EIO;
752*4882a593Smuzhiyun #endif
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH
755*4882a593Smuzhiyun if (set_output_clock(chip, chip->output_clock) < 0)
756*4882a593Smuzhiyun return -EIO;
757*4882a593Smuzhiyun #endif
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun if (wait_handshake(chip) < 0)
760*4882a593Smuzhiyun return -EIO;
761*4882a593Smuzhiyun clear_handshake(chip);
762*4882a593Smuzhiyun if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0)
763*4882a593Smuzhiyun return -EIO;
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun return 0;
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun /****************************************************************************
771*4882a593Smuzhiyun Transport functions
772*4882a593Smuzhiyun ****************************************************************************/
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun /* set_audio_format() sets the format of the audio data in host memory for
775*4882a593Smuzhiyun this pipe. Note that _MS_ (mono-to-stereo) playback modes are not used by ALSA
776*4882a593Smuzhiyun but they are here because they are just mono while capturing */
set_audio_format(struct echoaudio * chip,u16 pipe_index,const struct audioformat * format)777*4882a593Smuzhiyun static void set_audio_format(struct echoaudio *chip, u16 pipe_index,
778*4882a593Smuzhiyun const struct audioformat *format)
779*4882a593Smuzhiyun {
780*4882a593Smuzhiyun u16 dsp_format;
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SS_16LE;
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun /* Look for super-interleave (no big-endian and 8 bits) */
785*4882a593Smuzhiyun if (format->interleave > 2) {
786*4882a593Smuzhiyun switch (format->bits_per_sample) {
787*4882a593Smuzhiyun case 16:
788*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE;
789*4882a593Smuzhiyun break;
790*4882a593Smuzhiyun case 24:
791*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE;
792*4882a593Smuzhiyun break;
793*4882a593Smuzhiyun case 32:
794*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE;
795*4882a593Smuzhiyun break;
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun dsp_format |= format->interleave;
798*4882a593Smuzhiyun } else if (format->data_are_bigendian) {
799*4882a593Smuzhiyun /* For big-endian data, only 32 bit samples are supported */
800*4882a593Smuzhiyun switch (format->interleave) {
801*4882a593Smuzhiyun case 1:
802*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_MM_32BE;
803*4882a593Smuzhiyun break;
804*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32
805*4882a593Smuzhiyun case 2:
806*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SS_32BE;
807*4882a593Smuzhiyun break;
808*4882a593Smuzhiyun #endif
809*4882a593Smuzhiyun }
810*4882a593Smuzhiyun } else if (format->interleave == 1 &&
811*4882a593Smuzhiyun format->bits_per_sample == 32 && !format->mono_to_stereo) {
812*4882a593Smuzhiyun /* 32 bit little-endian mono->mono case */
813*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_MM_32LE;
814*4882a593Smuzhiyun } else {
815*4882a593Smuzhiyun /* Handle the other little-endian formats */
816*4882a593Smuzhiyun switch (format->bits_per_sample) {
817*4882a593Smuzhiyun case 8:
818*4882a593Smuzhiyun if (format->interleave == 2)
819*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SS_8;
820*4882a593Smuzhiyun else
821*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_MS_8;
822*4882a593Smuzhiyun break;
823*4882a593Smuzhiyun default:
824*4882a593Smuzhiyun case 16:
825*4882a593Smuzhiyun if (format->interleave == 2)
826*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SS_16LE;
827*4882a593Smuzhiyun else
828*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_MS_16LE;
829*4882a593Smuzhiyun break;
830*4882a593Smuzhiyun case 24:
831*4882a593Smuzhiyun if (format->interleave == 2)
832*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SS_24LE;
833*4882a593Smuzhiyun else
834*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_MS_24LE;
835*4882a593Smuzhiyun break;
836*4882a593Smuzhiyun case 32:
837*4882a593Smuzhiyun if (format->interleave == 2)
838*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_SS_32LE;
839*4882a593Smuzhiyun else
840*4882a593Smuzhiyun dsp_format = DSP_AUDIOFORM_MS_32LE;
841*4882a593Smuzhiyun break;
842*4882a593Smuzhiyun }
843*4882a593Smuzhiyun }
844*4882a593Smuzhiyun dev_dbg(chip->card->dev,
845*4882a593Smuzhiyun "set_audio_format[%d] = %x\n", pipe_index, dsp_format);
846*4882a593Smuzhiyun chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format);
847*4882a593Smuzhiyun }
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun /* start_transport starts transport for a set of pipes.
852*4882a593Smuzhiyun The bits 1 in channel_mask specify what pipes to start. Only the bit of the
853*4882a593Smuzhiyun first channel must be set, regardless its interleave.
854*4882a593Smuzhiyun Same thing for pause_ and stop_ -trasport below. */
start_transport(struct echoaudio * chip,u32 channel_mask,u32 cyclic_mask)855*4882a593Smuzhiyun static int start_transport(struct echoaudio *chip, u32 channel_mask,
856*4882a593Smuzhiyun u32 cyclic_mask)
857*4882a593Smuzhiyun {
858*4882a593Smuzhiyun
859*4882a593Smuzhiyun if (wait_handshake(chip))
860*4882a593Smuzhiyun return -EIO;
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun chip->comm_page->cmd_start |= cpu_to_le32(channel_mask);
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun if (chip->comm_page->cmd_start) {
865*4882a593Smuzhiyun clear_handshake(chip);
866*4882a593Smuzhiyun send_vector(chip, DSP_VC_START_TRANSFER);
867*4882a593Smuzhiyun if (wait_handshake(chip))
868*4882a593Smuzhiyun return -EIO;
869*4882a593Smuzhiyun /* Keep track of which pipes are transporting */
870*4882a593Smuzhiyun chip->active_mask |= channel_mask;
871*4882a593Smuzhiyun chip->comm_page->cmd_start = 0;
872*4882a593Smuzhiyun return 0;
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun dev_err(chip->card->dev, "start_transport: No pipes to start!\n");
876*4882a593Smuzhiyun return -EINVAL;
877*4882a593Smuzhiyun }
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun
880*4882a593Smuzhiyun
pause_transport(struct echoaudio * chip,u32 channel_mask)881*4882a593Smuzhiyun static int pause_transport(struct echoaudio *chip, u32 channel_mask)
882*4882a593Smuzhiyun {
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun if (wait_handshake(chip))
885*4882a593Smuzhiyun return -EIO;
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask);
888*4882a593Smuzhiyun chip->comm_page->cmd_reset = 0;
889*4882a593Smuzhiyun if (chip->comm_page->cmd_stop) {
890*4882a593Smuzhiyun clear_handshake(chip);
891*4882a593Smuzhiyun send_vector(chip, DSP_VC_STOP_TRANSFER);
892*4882a593Smuzhiyun if (wait_handshake(chip))
893*4882a593Smuzhiyun return -EIO;
894*4882a593Smuzhiyun /* Keep track of which pipes are transporting */
895*4882a593Smuzhiyun chip->active_mask &= ~channel_mask;
896*4882a593Smuzhiyun chip->comm_page->cmd_stop = 0;
897*4882a593Smuzhiyun chip->comm_page->cmd_reset = 0;
898*4882a593Smuzhiyun return 0;
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun dev_dbg(chip->card->dev, "pause_transport: No pipes to stop!\n");
902*4882a593Smuzhiyun return 0;
903*4882a593Smuzhiyun }
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun
stop_transport(struct echoaudio * chip,u32 channel_mask)907*4882a593Smuzhiyun static int stop_transport(struct echoaudio *chip, u32 channel_mask)
908*4882a593Smuzhiyun {
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun if (wait_handshake(chip))
911*4882a593Smuzhiyun return -EIO;
912*4882a593Smuzhiyun
913*4882a593Smuzhiyun chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask);
914*4882a593Smuzhiyun chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask);
915*4882a593Smuzhiyun if (chip->comm_page->cmd_reset) {
916*4882a593Smuzhiyun clear_handshake(chip);
917*4882a593Smuzhiyun send_vector(chip, DSP_VC_STOP_TRANSFER);
918*4882a593Smuzhiyun if (wait_handshake(chip))
919*4882a593Smuzhiyun return -EIO;
920*4882a593Smuzhiyun /* Keep track of which pipes are transporting */
921*4882a593Smuzhiyun chip->active_mask &= ~channel_mask;
922*4882a593Smuzhiyun chip->comm_page->cmd_stop = 0;
923*4882a593Smuzhiyun chip->comm_page->cmd_reset = 0;
924*4882a593Smuzhiyun return 0;
925*4882a593Smuzhiyun }
926*4882a593Smuzhiyun
927*4882a593Smuzhiyun dev_dbg(chip->card->dev, "stop_transport: No pipes to stop!\n");
928*4882a593Smuzhiyun return 0;
929*4882a593Smuzhiyun }
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun
is_pipe_allocated(struct echoaudio * chip,u16 pipe_index)933*4882a593Smuzhiyun static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index)
934*4882a593Smuzhiyun {
935*4882a593Smuzhiyun return (chip->pipe_alloc_mask & (1 << pipe_index));
936*4882a593Smuzhiyun }
937*4882a593Smuzhiyun
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun /* Stops everything and turns off the DSP. All pipes should be already
941*4882a593Smuzhiyun stopped and unallocated. */
rest_in_peace(struct echoaudio * chip)942*4882a593Smuzhiyun static int rest_in_peace(struct echoaudio *chip)
943*4882a593Smuzhiyun {
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun /* Stops all active pipes (just to be sure) */
946*4882a593Smuzhiyun stop_transport(chip, chip->active_mask);
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun set_meters_on(chip, false);
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_MIDI
951*4882a593Smuzhiyun enable_midi_input(chip, false);
952*4882a593Smuzhiyun #endif
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun /* Go to sleep */
955*4882a593Smuzhiyun if (chip->dsp_code) {
956*4882a593Smuzhiyun /* Make load_firmware do a complete reload */
957*4882a593Smuzhiyun chip->dsp_code = NULL;
958*4882a593Smuzhiyun /* Put the DSP to sleep */
959*4882a593Smuzhiyun return send_vector(chip, DSP_VC_GO_COMATOSE);
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun return 0;
962*4882a593Smuzhiyun }
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun
966*4882a593Smuzhiyun /* Fills the comm page with default values */
init_dsp_comm_page(struct echoaudio * chip)967*4882a593Smuzhiyun static int init_dsp_comm_page(struct echoaudio *chip)
968*4882a593Smuzhiyun {
969*4882a593Smuzhiyun /* Check if the compiler added extra padding inside the structure */
970*4882a593Smuzhiyun if (offsetof(struct comm_page, midi_output) != 0xbe0) {
971*4882a593Smuzhiyun dev_err(chip->card->dev,
972*4882a593Smuzhiyun "init_dsp_comm_page() - Invalid struct comm_page structure\n");
973*4882a593Smuzhiyun return -EPERM;
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun /* Init all the basic stuff */
977*4882a593Smuzhiyun chip->card_name = ECHOCARD_NAME;
978*4882a593Smuzhiyun chip->bad_board = true; /* Set true until DSP loaded */
979*4882a593Smuzhiyun chip->dsp_code = NULL; /* Current DSP code not loaded */
980*4882a593Smuzhiyun chip->asic_loaded = false;
981*4882a593Smuzhiyun memset(chip->comm_page, 0, sizeof(struct comm_page));
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun /* Init the comm page */
984*4882a593Smuzhiyun chip->comm_page->comm_size =
985*4882a593Smuzhiyun cpu_to_le32(sizeof(struct comm_page));
986*4882a593Smuzhiyun chip->comm_page->handshake = cpu_to_le32(0xffffffff);
987*4882a593Smuzhiyun chip->comm_page->midi_out_free_count =
988*4882a593Smuzhiyun cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE);
989*4882a593Smuzhiyun chip->comm_page->sample_rate = cpu_to_le32(44100);
990*4882a593Smuzhiyun
991*4882a593Smuzhiyun /* Set line levels so we don't blast any inputs on startup */
992*4882a593Smuzhiyun memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE);
993*4882a593Smuzhiyun memset(chip->comm_page->vmixer, ECHOGAIN_MUTED, VMIXER_ARRAY_SIZE);
994*4882a593Smuzhiyun
995*4882a593Smuzhiyun return 0;
996*4882a593Smuzhiyun }
997*4882a593Smuzhiyun
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun
1000*4882a593Smuzhiyun /* This function initializes the chip structure with default values, ie. all
1001*4882a593Smuzhiyun * muted and internal clock source. Then it copies the settings to the DSP.
1002*4882a593Smuzhiyun * This MUST be called after the DSP is up and running !
1003*4882a593Smuzhiyun */
init_line_levels(struct echoaudio * chip)1004*4882a593Smuzhiyun static int init_line_levels(struct echoaudio *chip)
1005*4882a593Smuzhiyun {
1006*4882a593Smuzhiyun memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain));
1007*4882a593Smuzhiyun memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain));
1008*4882a593Smuzhiyun memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain));
1009*4882a593Smuzhiyun memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain));
1010*4882a593Smuzhiyun chip->input_clock = ECHO_CLOCK_INTERNAL;
1011*4882a593Smuzhiyun chip->output_clock = ECHO_CLOCK_WORD;
1012*4882a593Smuzhiyun chip->sample_rate = 44100;
1013*4882a593Smuzhiyun return restore_dsp_rettings(chip);
1014*4882a593Smuzhiyun }
1015*4882a593Smuzhiyun
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun /* This is low level part of the interrupt handler.
1019*4882a593Smuzhiyun It returns -1 if the IRQ is not ours, or N>=0 if it is, where N is the number
1020*4882a593Smuzhiyun of midi data in the input queue. */
service_irq(struct echoaudio * chip)1021*4882a593Smuzhiyun static int service_irq(struct echoaudio *chip)
1022*4882a593Smuzhiyun {
1023*4882a593Smuzhiyun int st;
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun /* Read the DSP status register and see if this DSP generated this interrupt */
1026*4882a593Smuzhiyun if (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_IRQ) {
1027*4882a593Smuzhiyun st = 0;
1028*4882a593Smuzhiyun #ifdef ECHOCARD_HAS_MIDI
1029*4882a593Smuzhiyun /* Get and parse midi data if present */
1030*4882a593Smuzhiyun if (chip->comm_page->midi_input[0]) /* The count is at index 0 */
1031*4882a593Smuzhiyun st = midi_service_irq(chip); /* Returns how many midi bytes we received */
1032*4882a593Smuzhiyun #endif
1033*4882a593Smuzhiyun /* Clear the hardware interrupt */
1034*4882a593Smuzhiyun chip->comm_page->midi_input[0] = 0;
1035*4882a593Smuzhiyun send_vector(chip, DSP_VC_ACK_INT);
1036*4882a593Smuzhiyun return st;
1037*4882a593Smuzhiyun }
1038*4882a593Smuzhiyun return -1;
1039*4882a593Smuzhiyun }
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun
1044*4882a593Smuzhiyun /******************************************************************************
1045*4882a593Smuzhiyun Functions for opening and closing pipes
1046*4882a593Smuzhiyun ******************************************************************************/
1047*4882a593Smuzhiyun
1048*4882a593Smuzhiyun /* allocate_pipes is used to reserve audio pipes for your exclusive use.
1049*4882a593Smuzhiyun The call will fail if some pipes are already allocated. */
allocate_pipes(struct echoaudio * chip,struct audiopipe * pipe,int pipe_index,int interleave)1050*4882a593Smuzhiyun static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe,
1051*4882a593Smuzhiyun int pipe_index, int interleave)
1052*4882a593Smuzhiyun {
1053*4882a593Smuzhiyun int i;
1054*4882a593Smuzhiyun u32 channel_mask;
1055*4882a593Smuzhiyun
1056*4882a593Smuzhiyun dev_dbg(chip->card->dev,
1057*4882a593Smuzhiyun "allocate_pipes: ch=%d int=%d\n", pipe_index, interleave);
1058*4882a593Smuzhiyun
1059*4882a593Smuzhiyun if (chip->bad_board)
1060*4882a593Smuzhiyun return -EIO;
1061*4882a593Smuzhiyun
1062*4882a593Smuzhiyun for (channel_mask = i = 0; i < interleave; i++)
1063*4882a593Smuzhiyun channel_mask |= 1 << (pipe_index + i);
1064*4882a593Smuzhiyun if (chip->pipe_alloc_mask & channel_mask) {
1065*4882a593Smuzhiyun dev_err(chip->card->dev,
1066*4882a593Smuzhiyun "allocate_pipes: channel already open\n");
1067*4882a593Smuzhiyun return -EAGAIN;
1068*4882a593Smuzhiyun }
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun chip->comm_page->position[pipe_index] = 0;
1071*4882a593Smuzhiyun chip->pipe_alloc_mask |= channel_mask;
1072*4882a593Smuzhiyun /* This driver uses cyclic buffers only */
1073*4882a593Smuzhiyun chip->pipe_cyclic_mask |= channel_mask;
1074*4882a593Smuzhiyun pipe->index = pipe_index;
1075*4882a593Smuzhiyun pipe->interleave = interleave;
1076*4882a593Smuzhiyun pipe->state = PIPE_STATE_STOPPED;
1077*4882a593Smuzhiyun
1078*4882a593Smuzhiyun /* The counter register is where the DSP writes the 32 bit DMA
1079*4882a593Smuzhiyun position for a pipe. The DSP is constantly updating this value as
1080*4882a593Smuzhiyun it moves data. The DMA counter is in units of bytes, not samples. */
1081*4882a593Smuzhiyun pipe->dma_counter = (__le32 *)&chip->comm_page->position[pipe_index];
1082*4882a593Smuzhiyun *pipe->dma_counter = 0;
1083*4882a593Smuzhiyun return pipe_index;
1084*4882a593Smuzhiyun }
1085*4882a593Smuzhiyun
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun
free_pipes(struct echoaudio * chip,struct audiopipe * pipe)1088*4882a593Smuzhiyun static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe)
1089*4882a593Smuzhiyun {
1090*4882a593Smuzhiyun u32 channel_mask;
1091*4882a593Smuzhiyun int i;
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index)))
1094*4882a593Smuzhiyun return -EINVAL;
1095*4882a593Smuzhiyun if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED))
1096*4882a593Smuzhiyun return -EINVAL;
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun for (channel_mask = i = 0; i < pipe->interleave; i++)
1099*4882a593Smuzhiyun channel_mask |= 1 << (pipe->index + i);
1100*4882a593Smuzhiyun
1101*4882a593Smuzhiyun chip->pipe_alloc_mask &= ~channel_mask;
1102*4882a593Smuzhiyun chip->pipe_cyclic_mask &= ~channel_mask;
1103*4882a593Smuzhiyun return 0;
1104*4882a593Smuzhiyun }
1105*4882a593Smuzhiyun
1106*4882a593Smuzhiyun
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun /******************************************************************************
1109*4882a593Smuzhiyun Functions for managing the scatter-gather list
1110*4882a593Smuzhiyun ******************************************************************************/
1111*4882a593Smuzhiyun
sglist_init(struct echoaudio * chip,struct audiopipe * pipe)1112*4882a593Smuzhiyun static int sglist_init(struct echoaudio *chip, struct audiopipe *pipe)
1113*4882a593Smuzhiyun {
1114*4882a593Smuzhiyun pipe->sglist_head = 0;
1115*4882a593Smuzhiyun memset(pipe->sgpage.area, 0, PAGE_SIZE);
1116*4882a593Smuzhiyun chip->comm_page->sglist_addr[pipe->index].addr =
1117*4882a593Smuzhiyun cpu_to_le32(pipe->sgpage.addr);
1118*4882a593Smuzhiyun return 0;
1119*4882a593Smuzhiyun }
1120*4882a593Smuzhiyun
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun
sglist_add_mapping(struct echoaudio * chip,struct audiopipe * pipe,dma_addr_t address,size_t length)1123*4882a593Smuzhiyun static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe,
1124*4882a593Smuzhiyun dma_addr_t address, size_t length)
1125*4882a593Smuzhiyun {
1126*4882a593Smuzhiyun int head = pipe->sglist_head;
1127*4882a593Smuzhiyun struct sg_entry *list = (struct sg_entry *)pipe->sgpage.area;
1128*4882a593Smuzhiyun
1129*4882a593Smuzhiyun if (head < MAX_SGLIST_ENTRIES - 1) {
1130*4882a593Smuzhiyun list[head].addr = cpu_to_le32(address);
1131*4882a593Smuzhiyun list[head].size = cpu_to_le32(length);
1132*4882a593Smuzhiyun pipe->sglist_head++;
1133*4882a593Smuzhiyun } else {
1134*4882a593Smuzhiyun dev_err(chip->card->dev, "SGlist: too many fragments\n");
1135*4882a593Smuzhiyun return -ENOMEM;
1136*4882a593Smuzhiyun }
1137*4882a593Smuzhiyun return 0;
1138*4882a593Smuzhiyun }
1139*4882a593Smuzhiyun
1140*4882a593Smuzhiyun
1141*4882a593Smuzhiyun
sglist_add_irq(struct echoaudio * chip,struct audiopipe * pipe)1142*4882a593Smuzhiyun static inline int sglist_add_irq(struct echoaudio *chip, struct audiopipe *pipe)
1143*4882a593Smuzhiyun {
1144*4882a593Smuzhiyun return sglist_add_mapping(chip, pipe, 0, 0);
1145*4882a593Smuzhiyun }
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun
1148*4882a593Smuzhiyun
sglist_wrap(struct echoaudio * chip,struct audiopipe * pipe)1149*4882a593Smuzhiyun static inline int sglist_wrap(struct echoaudio *chip, struct audiopipe *pipe)
1150*4882a593Smuzhiyun {
1151*4882a593Smuzhiyun return sglist_add_mapping(chip, pipe, pipe->sgpage.addr, 0);
1152*4882a593Smuzhiyun }
1153