/****************************************************************************
Copyright Echo Digital Audio Corporation (c) 1998 - 2004
All rights reserved
www.echoaudio.com
This file is part of Echo Digital Audio's generic driver library.
Echo Digital Audio's generic driver library is free software;
you can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software
Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
*************************************************************************
Translation from C++ and adaptation for use in ALSA-Driver
were made by Giuliano Pochini <pochini@shiny.it>
****************************************************************************/
#if PAGE_SIZE < 4096
#error PAGE_SIZE is < 4k
#endif
static int restore_dsp_rettings(struct echoaudio *chip);
/* Some vector commands involve the DSP reading or writing data to and from the
comm page; if you send one of these commands to the DSP, it will complete the
command and then write a non-zero value to the Handshake field in the
comm page. This function waits for the handshake to show up. */
static int wait_handshake(struct echoaudio *chip)
{
int i;
/* Wait up to 10ms for the handshake from the DSP */
for (i = 0; i < HANDSHAKE_TIMEOUT; i++) {
/* Look for the handshake value */
if (chip->comm_page->handshake) {
/*if (i) DE_ACT(("Handshake time: %d\n", i));*/
return 0;
}
udelay(1);
}
snd_printk(KERN_ERR "wait_handshake(): Timeout waiting for DSP\n");
return -EBUSY;
}
/* Much of the interaction between the DSP and the driver is done via vector
commands; send_vector writes a vector command to the DSP. Typically, this
causes the DSP to read or write fields in the comm page.
PCI posting is not required thanks to the handshake logic. */
static int send_vector(struct echoaudio *chip, u32 command)
{
int i;
wmb(); /* Flush all pending writes before sending the command */
/* Wait up to 100ms for the "vector busy" bit to be off */
for (i = 0; i < VECTOR_BUSY_TIMEOUT; i++) {
if (!(get_dsp_register(chip, CHI32_VECTOR_REG) &
CHI32_VECTOR_BUSY)) {
set_dsp_register(chip, CHI32_VECTOR_REG, command);
/*if (i) DE_ACT(("send_vector time: %d\n", i));*/
return 0;
}
udelay(1);
}
DE_ACT((KERN_ERR "timeout on send_vector\n"));
return -EBUSY;
}
/* write_dsp writes a 32-bit value to the DSP; this is used almost
exclusively for loading the DSP. */
static int write_dsp(struct echoaudio *chip, u32 data)
{
u32 status, i;
for (i = 0; i < 10000000; i++) { /* timeout = 10s */
status = get_dsp_register(chip, CHI32_STATUS_REG);
if ((status & CHI32_STATUS_HOST_WRITE_EMPTY) != 0) {
set_dsp_register(chip, CHI32_DATA_REG, data);
wmb(); /* write it immediately */
return 0;
}
udelay(1);
cond_resched();
}
chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */
DE_ACT((KERN_ERR "write_dsp: Set bad_board to TRUE\n"));
return -EIO;
}
/* read_dsp reads a 32-bit value from the DSP; this is used almost
exclusively for loading the DSP and checking the status of the ASIC. */
static int read_dsp(struct echoaudio *chip, u32 *data)
{
u32 status, i;
for (i = 0; i < READ_DSP_TIMEOUT; i++) {
status = get_dsp_register(chip, CHI32_STATUS_REG);
if ((status & CHI32_STATUS_HOST_READ_FULL) != 0) {
*data = get_dsp_register(chip, CHI32_DATA_REG);
return 0;
}
udelay(1);
cond_resched();
}
chip->bad_board = TRUE; /* Set TRUE until DSP re-loaded */
DE_INIT((KERN_ERR "read_dsp: Set bad_board to TRUE\n"));
return -EIO;
}
/****************************************************************************
Firmware loading functions
****************************************************************************/
/* This function is used to read back the serial number from the DSP;
this is triggered by the SET_COMMPAGE_ADDR command.
Only some early Echogals products have serial numbers in the ROM;
the serial number is not used, but you still need to do this as
part of the DSP load process. */
static int read_sn(struct echoaudio *chip)
{
int i;
u32 sn[6];
for (i = 0; i <