diff options
Diffstat (limited to 'ANDROID_3.4.5/sound/pci/echoaudio')
37 files changed, 0 insertions, 10472 deletions
diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/Makefile b/ANDROID_3.4.5/sound/pci/echoaudio/Makefile deleted file mode 100644 index 1361de77..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# -# Makefile for ALSA Echoaudio soundcard drivers -# Copyright (c) 2003 by Giuliano Pochini <pochini@shiny.it> -# - -snd-darla20-objs := darla20.o -snd-gina20-objs := gina20.o -snd-layla20-objs := layla20.o -snd-darla24-objs := darla24.o -snd-gina24-objs := gina24.o -snd-layla24-objs := layla24.o -snd-mona-objs := mona.o -snd-mia-objs := mia.o -snd-echo3g-objs := echo3g.o -snd-indigo-objs := indigo.o -snd-indigoio-objs := indigoio.o -snd-indigodj-objs := indigodj.o -snd-indigoiox-objs := indigoiox.o -snd-indigodjx-objs := indigodjx.o - -obj-$(CONFIG_SND_DARLA20) += snd-darla20.o -obj-$(CONFIG_SND_GINA20) += snd-gina20.o -obj-$(CONFIG_SND_LAYLA20) += snd-layla20.o -obj-$(CONFIG_SND_DARLA24) += snd-darla24.o -obj-$(CONFIG_SND_GINA24) += snd-gina24.o -obj-$(CONFIG_SND_LAYLA24) += snd-layla24.o -obj-$(CONFIG_SND_MONA) += snd-mona.o -obj-$(CONFIG_SND_MIA) += snd-mia.o -obj-$(CONFIG_SND_ECHO3G) += snd-echo3g.o -obj-$(CONFIG_SND_INDIGO) += snd-indigo.o -obj-$(CONFIG_SND_INDIGOIO) += snd-indigoio.o -obj-$(CONFIG_SND_INDIGODJ) += snd-indigodj.o -obj-$(CONFIG_SND_INDIGOIOX) += snd-indigoiox.o -obj-$(CONFIG_SND_INDIGODJX) += snd-indigodjx.o diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla20.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla20.c deleted file mode 100644 index d47e72ae..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/darla20.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHOGALS_FAMILY -#define ECHOCARD_DARLA20 -#define ECHOCARD_NAME "Darla20" -#define ECHOCARD_HAS_MONITOR - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 2 */ -#define PX_DIGITAL_IN 10 /* 0 */ -#define PX_NUM 10 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 8 */ -#define BX_DIGITAL_OUT 8 /* 0 */ -#define BX_ANALOG_IN 8 /* 2 */ -#define BX_DIGITAL_IN 10 /* 0 */ -#define BX_NUM 10 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/darla20_dsp.fw"); - -#define FW_DARLA20_DSP 0 - -static const struct firmware card_fw[] = { - {0, "darla20_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, - .rate_min = 44100, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. */ -}; - - -#include "darla20_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla20_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla20_dsp.c deleted file mode 100644 index 20c7cbc8..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/darla20_dsp.c +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - - 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> - -****************************************************************************/ - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Darla20\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_DARLA20_DSP; - chip->spdif_status = GD_SPDIF_STATUS_UNDEF; - chip->clock_state = GD_CLOCK_UNDEF; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} - - - -/* The Darla20 has no external clock sources */ -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - return ECHO_CLOCK_BIT_INTERNAL; -} - - - -/* The Darla20 has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u8 clock_state, spdif_status; - - if (wait_handshake(chip)) - return -EIO; - - switch (rate) { - case 44100: - clock_state = GD_CLOCK_44; - spdif_status = GD_SPDIF_STATUS_44; - break; - case 48000: - clock_state = GD_CLOCK_48; - spdif_status = GD_SPDIF_STATUS_48; - break; - default: - clock_state = GD_CLOCK_NOCHANGE; - spdif_status = GD_SPDIF_STATUS_NOCHANGE; - break; - } - - if (chip->clock_state == clock_state) - clock_state = GD_CLOCK_NOCHANGE; - if (spdif_status == chip->spdif_status) - spdif_status = GD_SPDIF_STATUS_NOCHANGE; - - chip->comm_page->sample_rate = cpu_to_le32(rate); - chip->comm_page->gd_clock_state = clock_state; - chip->comm_page->gd_spdif_status = spdif_status; - chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ - - /* Save the new audio state if it changed */ - if (clock_state != GD_CLOCK_NOCHANGE) - chip->clock_state = clock_state; - if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) - chip->spdif_status = spdif_status; - chip->sample_rate = rate; - - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla24.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla24.c deleted file mode 100644 index 413acf70..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/darla24.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHOGALS_FAMILY -#define ECHOCARD_DARLA24 -#define ECHOCARD_NAME "Darla24" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_SUPER_INTERLEAVE - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 2 */ -#define PX_DIGITAL_IN 10 /* 0 */ -#define PX_NUM 10 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 8 */ -#define BX_DIGITAL_OUT 8 /* 0 */ -#define BX_ANALOG_IN 8 /* 2 */ -#define BX_DIGITAL_IN 10 /* 0 */ -#define BX_NUM 10 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/darla24_dsp.fw"); - -#define FW_DARLA24_DSP 0 - -static const struct firmware card_fw[] = { - {0, "darla24_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */ - {0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_8000_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 8000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. */ -}; - - -#include "darla24_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/darla24_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/darla24_dsp.c deleted file mode 100644 index 6da6663e..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/darla24_dsp.c +++ /dev/null @@ -1,162 +0,0 @@ -/*************************************************************************** - - 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> - -****************************************************************************/ - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Darla24\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_DARLA24_DSP; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | - ECHO_CLOCK_BIT_ESYNC; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock - detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_ESYNC) - clock_bits |= ECHO_CLOCK_BIT_ESYNC; - - return clock_bits; -} - - - -/* The Darla24 has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u8 clock; - - switch (rate) { - case 96000: - clock = GD24_96000; - break; - case 88200: - clock = GD24_88200; - break; - case 48000: - clock = GD24_48000; - break; - case 44100: - clock = GD24_44100; - break; - case 32000: - clock = GD24_32000; - break; - case 22050: - clock = GD24_22050; - break; - case 16000: - clock = GD24_16000; - break; - case 11025: - clock = GD24_11025; - break; - case 8000: - clock = GD24_8000; - break; - default: - DE_ACT(("set_sample_rate: Error, invalid sample rate %d\n", - rate)); - return -EINVAL; - } - - if (wait_handshake(chip)) - return -EIO; - - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); - chip->sample_rate = rate; - - /* Override the sample rate if this card is set to Echo sync. */ - if (chip->input_clock == ECHO_CLOCK_ESYNC) - clock = GD24_EXT_SYNC; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ - chip->comm_page->gd_clock_state = clock; - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); -} - - - -static int set_input_clock(struct echoaudio *chip, u16 clock) -{ - if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL && - clock != ECHO_CLOCK_ESYNC)) - return -EINVAL; - chip->input_clock = clock; - return set_sample_rate(chip, chip->sample_rate); -} - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g.c b/ANDROID_3.4.5/sound/pci/echoaudio/echo3g.c deleted file mode 100644 index 1ec4edca..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHO3G_FAMILY -#define ECHOCARD_ECHO3G -#define ECHOCARD_NAME "Echo3G" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_ASIC -#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_DIGITAL_IO -#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH -#define ECHOCARD_HAS_ADAT 6 -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 -#define ECHOCARD_HAS_MIDI -#define ECHOCARD_HAS_PHANTOM_POWER - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 -#define PX_DIGITAL_OUT chip->px_digital_out -#define PX_ANALOG_IN chip->px_analog_in -#define PX_DIGITAL_IN chip->px_digital_in -#define PX_NUM chip->px_num - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 -#define BX_DIGITAL_OUT chip->bx_digital_out -#define BX_ANALOG_IN chip->bx_analog_in -#define BX_DIGITAL_IN chip->bx_digital_in -#define BX_NUM chip->bx_num - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <sound/rawmidi.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/echo3g_dsp.fw"); -MODULE_FIRMWARE("ea/3g_asic.fw"); - -#define FW_361_LOADER 0 -#define FW_ECHO3G_DSP 1 -#define FW_3G_ASIC 2 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "echo3g_dsp.fw"}, - {0, "3g_asic.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_CONTINUOUS, - .rate_min = 32000, - .rate_max = 100000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, -}; - -#include "echo3g_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio_3g.c" -#include "echoaudio.c" -#include "midi.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/echo3g_dsp.c deleted file mode 100644 index 3cdc2ee2..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echo3g_dsp.c +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - -static int load_asic(struct echoaudio *chip); -static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode); -static int set_digital_mode(struct echoaudio *chip, u8 mode); -static int check_asic_status(struct echoaudio *chip); -static int set_sample_rate(struct echoaudio *chip, u32 rate); -static int set_input_clock(struct echoaudio *chip, u16 clock); -static int set_professional_spdif(struct echoaudio *chip, char prof); -static int set_phantom_power(struct echoaudio *chip, char on); -static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, - char force); - -#include <linux/interrupt.h> - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - local_irq_enable(); - DE_INIT(("init_hw() - Echo3G\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->comm_page->e3g_frq_register = - cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2); - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->has_midi = TRUE; - chip->dsp_code_to_load = FW_ECHO3G_DSP; - - /* Load the DSP code and the ASIC on the PCI card and get - what type of external box is attached */ - err = load_firmware(chip); - - if (err < 0) { - return err; - } else if (err == E3G_GINA3G_BOX_TYPE) { - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | - ECHO_CLOCK_BIT_SPDIF | - ECHO_CLOCK_BIT_ADAT; - chip->card_name = "Gina3G"; - chip->px_digital_out = chip->bx_digital_out = 6; - chip->px_analog_in = chip->bx_analog_in = 14; - chip->px_digital_in = chip->bx_digital_in = 16; - chip->px_num = chip->bx_num = 24; - chip->has_phantom_power = TRUE; - chip->hasnt_input_nominal_level = TRUE; - } else if (err == E3G_LAYLA3G_BOX_TYPE) { - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | - ECHO_CLOCK_BIT_SPDIF | - ECHO_CLOCK_BIT_ADAT | - ECHO_CLOCK_BIT_WORD; - chip->card_name = "Layla3G"; - chip->px_digital_out = chip->bx_digital_out = 8; - chip->px_analog_in = chip->bx_analog_in = 16; - chip->px_digital_in = chip->bx_digital_in = 24; - chip->px_num = chip->bx_num = 32; - } else { - return -ENODEV; - } - - chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | - ECHOCAPS_HAS_DIGITAL_MODE_ADAT; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; - chip->professional_spdif = FALSE; - chip->non_audio_spdif = FALSE; - chip->bad_board = FALSE; - chip->phantom_power = FALSE; - return init_line_levels(chip); -} - - - -static int set_phantom_power(struct echoaudio *chip, char on) -{ - u32 control_reg = le32_to_cpu(chip->comm_page->control_register); - - if (on) - control_reg |= E3G_PHANTOM_POWER; - else - control_reg &= ~E3G_PHANTOM_POWER; - - chip->phantom_power = on; - return write_control_reg(chip, control_reg, - le32_to_cpu(chip->comm_page->e3g_frq_register), - 0); -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.c deleted file mode 100644 index 595c11f9..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.c +++ /dev/null @@ -1,2360 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#include <linux/module.h> - -MODULE_AUTHOR("Giuliano Pochini <pochini@shiny.it>"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Echoaudio " ECHOCARD_NAME " soundcards driver"); -MODULE_SUPPORTED_DEVICE("{{Echoaudio," ECHOCARD_NAME "}}"); -MODULE_DEVICE_TABLE(pci, snd_echo_ids); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for " ECHOCARD_NAME " soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); - -static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; -static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); - - - -static int get_firmware(const struct firmware **fw_entry, - struct echoaudio *chip, const short fw_index) -{ - int err; - char name[30]; - -#ifdef CONFIG_PM - if (chip->fw_cache[fw_index]) { - DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data)); - *fw_entry = chip->fw_cache[fw_index]; - return 0; - } -#endif - - DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data)); - snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); - err = request_firmware(fw_entry, name, pci_device(chip)); - if (err < 0) - snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err); -#ifdef CONFIG_PM - else - chip->fw_cache[fw_index] = *fw_entry; -#endif - return err; -} - - - -static void free_firmware(const struct firmware *fw_entry) -{ -#ifdef CONFIG_PM - DE_ACT(("firmware not released (kept in cache)\n")); -#else - release_firmware(fw_entry); - DE_ACT(("firmware released\n")); -#endif -} - - - -static void free_firmware_cache(struct echoaudio *chip) -{ -#ifdef CONFIG_PM - int i; - - for (i = 0; i < 8 ; i++) - if (chip->fw_cache[i]) { - release_firmware(chip->fw_cache[i]); - DE_ACT(("release_firmware(%d)\n", i)); - } - - DE_ACT(("firmware_cache released\n")); -#endif -} - - - -/****************************************************************************** - PCM interface -******************************************************************************/ - -static void audiopipe_free(struct snd_pcm_runtime *runtime) -{ - struct audiopipe *pipe = runtime->private_data; - - if (pipe->sgpage.area) - snd_dma_free_pages(&pipe->sgpage); - kfree(pipe); -} - - - -static int hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval *c = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_mask fmt; - - snd_mask_any(&fmt); - -#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - /* >=2 channels cannot be S32_BE */ - if (c->min == 2) { - fmt.bits[0] &= ~SNDRV_PCM_FMTBIT_S32_BE; - return snd_mask_refine(f, &fmt); - } -#endif - /* > 2 channels cannot be U8 and S32_BE */ - if (c->min > 2) { - fmt.bits[0] &= ~(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_BE); - return snd_mask_refine(f, &fmt); - } - /* Mono is ok with any format */ - return 0; -} - - - -static int hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval *c = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_interval ch; - - snd_interval_any(&ch); - - /* S32_BE is mono (and stereo) only */ - if (f->bits[0] == SNDRV_PCM_FMTBIT_S32_BE) { - ch.min = 1; -#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - ch.max = 2; -#else - ch.max = 1; -#endif - ch.integer = 1; - return snd_interval_refine(c, &ch); - } - /* U8 can be only mono or stereo */ - if (f->bits[0] == SNDRV_PCM_FMTBIT_U8) { - ch.min = 1; - ch.max = 2; - ch.integer = 1; - return snd_interval_refine(c, &ch); - } - /* S16_LE, S24_3LE and S32_LE support any number of channels. */ - return 0; -} - - - -static int hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval *c = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_mask fmt; - u64 fmask; - snd_mask_any(&fmt); - - fmask = fmt.bits[0] + ((u64)fmt.bits[1] << 32); - - /* >2 channels must be S16_LE, S24_3LE or S32_LE */ - if (c->min > 2) { - fmask &= SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE; - /* 1 channel must be S32_BE or S32_LE */ - } else if (c->max == 1) - fmask &= SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE; -#ifndef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - /* 2 channels cannot be S32_BE */ - else if (c->min == 2 && c->max == 2) - fmask &= ~SNDRV_PCM_FMTBIT_S32_BE; -#endif - else - return 0; - - fmt.bits[0] &= (u32)fmask; - fmt.bits[1] &= (u32)(fmask >> 32); - return snd_mask_refine(f, &fmt); -} - - - -static int hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval *c = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); - struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - struct snd_interval ch; - u64 fmask; - - snd_interval_any(&ch); - ch.integer = 1; - fmask = f->bits[0] + ((u64)f->bits[1] << 32); - - /* S32_BE is mono (and stereo) only */ - if (fmask == SNDRV_PCM_FMTBIT_S32_BE) { - ch.min = 1; -#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - ch.max = 2; -#else - ch.max = 1; -#endif - /* U8 is stereo only */ - } else if (fmask == SNDRV_PCM_FMTBIT_U8) - ch.min = ch.max = 2; - /* S16_LE and S24_3LE must be at least stereo */ - else if (!(fmask & ~(SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE))) - ch.min = 2; - else - return 0; - - return snd_interval_refine(c, &ch); -} - - - -/* Since the sample rate is a global setting, do allow the user to change the -sample rate only if there is only one pcm device open. */ -static int hw_rule_sample_rate(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct echoaudio *chip = rule->private; - struct snd_interval fixed; - - if (!chip->can_set_rate) { - snd_interval_any(&fixed); - fixed.min = fixed.max = chip->sample_rate; - return snd_interval_refine(rate, &fixed); - } - return 0; -} - - -static int pcm_open(struct snd_pcm_substream *substream, - signed char max_channels) -{ - struct echoaudio *chip; - struct snd_pcm_runtime *runtime; - struct audiopipe *pipe; - int err, i; - - if (max_channels <= 0) - return -EAGAIN; - - chip = snd_pcm_substream_chip(substream); - runtime = substream->runtime; - - pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL); - if (!pipe) - return -ENOMEM; - pipe->index = -1; /* Not configured yet */ - - /* Set up hw capabilities and contraints */ - memcpy(&pipe->hw, &pcm_hardware_skel, sizeof(struct snd_pcm_hardware)); - DE_HWP(("max_channels=%d\n", max_channels)); - pipe->constr.list = channels_list; - pipe->constr.mask = 0; - for (i = 0; channels_list[i] <= max_channels; i++); - pipe->constr.count = i; - if (pipe->hw.channels_max > max_channels) - pipe->hw.channels_max = max_channels; - if (chip->digital_mode == DIGITAL_MODE_ADAT) { - pipe->hw.rate_max = 48000; - pipe->hw.rates &= SNDRV_PCM_RATE_8000_48000; - } - - runtime->hw = pipe->hw; - runtime->private_data = pipe; - runtime->private_free = audiopipe_free; - snd_pcm_set_sync(substream); - - /* Only mono and any even number of channels are allowed */ - if ((err = snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - &pipe->constr)) < 0) - return err; - - /* All periods should have the same size */ - if ((err = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS)) < 0) - return err; - - /* The hw accesses memory in chunks 32 frames long and they should be - 32-bytes-aligned. It's not a requirement, but it seems that IRQs are - generated with a resolution of 32 frames. Thus we need the following */ - if ((err = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_PERIOD_SIZE, - 32)) < 0) - return err; - if ((err = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_BUFFER_SIZE, - 32)) < 0) - return err; - - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - hw_rule_sample_rate, chip, - SNDRV_PCM_HW_PARAM_RATE, -1)) < 0) - return err; - - /* Finally allocate a page for the scatter-gather list */ - if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - PAGE_SIZE, &pipe->sgpage)) < 0) { - DE_HWP(("s-g list allocation failed\n")); - return err; - } - - return 0; -} - - - -static int pcm_analog_in_open(struct snd_pcm_substream *substream) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - int err; - - DE_ACT(("pcm_analog_in_open\n")); - if ((err = pcm_open(substream, num_analog_busses_in(chip) - - substream->number)) < 0) - return err; - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - hw_rule_capture_channels_by_format, NULL, - SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) - return err; - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_FORMAT, - hw_rule_capture_format_by_channels, NULL, - SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) - return err; - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; - DE_HWP(("pcm_analog_in_open cs=%d oc=%d r=%d\n", - chip->can_set_rate, atomic_read(&chip->opencount), - chip->sample_rate)); - return 0; -} - - - -static int pcm_analog_out_open(struct snd_pcm_substream *substream) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - int max_channels, err; - -#ifdef ECHOCARD_HAS_VMIXER - max_channels = num_pipes_out(chip); -#else - max_channels = num_analog_busses_out(chip); -#endif - DE_ACT(("pcm_analog_out_open\n")); - if ((err = pcm_open(substream, max_channels - substream->number)) < 0) - return err; - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - hw_rule_playback_channels_by_format, - NULL, - SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) - return err; - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_FORMAT, - hw_rule_playback_format_by_channels, - NULL, - SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) - return err; - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; - DE_HWP(("pcm_analog_out_open cs=%d oc=%d r=%d\n", - chip->can_set_rate, atomic_read(&chip->opencount), - chip->sample_rate)); - return 0; -} - - - -#ifdef ECHOCARD_HAS_DIGITAL_IO - -static int pcm_digital_in_open(struct snd_pcm_substream *substream) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - int err, max_channels; - - DE_ACT(("pcm_digital_in_open\n")); - max_channels = num_digital_busses_in(chip) - substream->number; - mutex_lock(&chip->mode_mutex); - if (chip->digital_mode == DIGITAL_MODE_ADAT) - err = pcm_open(substream, max_channels); - else /* If the card has ADAT, subtract the 6 channels - * that S/PDIF doesn't have - */ - err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); - - if (err < 0) - goto din_exit; - - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - hw_rule_capture_channels_by_format, NULL, - SNDRV_PCM_HW_PARAM_FORMAT, -1)) < 0) - goto din_exit; - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_FORMAT, - hw_rule_capture_format_by_channels, NULL, - SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) - goto din_exit; - - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; - -din_exit: - mutex_unlock(&chip->mode_mutex); - return err; -} - - - -#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ - -static int pcm_digital_out_open(struct snd_pcm_substream *substream) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - int err, max_channels; - - DE_ACT(("pcm_digital_out_open\n")); - max_channels = num_digital_busses_out(chip) - substream->number; - mutex_lock(&chip->mode_mutex); - if (chip->digital_mode == DIGITAL_MODE_ADAT) - err = pcm_open(substream, max_channels); - else /* If the card has ADAT, subtract the 6 channels - * that S/PDIF doesn't have - */ - err = pcm_open(substream, max_channels - ECHOCARD_HAS_ADAT); - - if (err < 0) - goto dout_exit; - - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - hw_rule_playback_channels_by_format, - NULL, SNDRV_PCM_HW_PARAM_FORMAT, - -1)) < 0) - goto dout_exit; - if ((err = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_FORMAT, - hw_rule_playback_format_by_channels, - NULL, SNDRV_PCM_HW_PARAM_CHANNELS, - -1)) < 0) - goto dout_exit; - atomic_inc(&chip->opencount); - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) - chip->can_set_rate=0; -dout_exit: - mutex_unlock(&chip->mode_mutex); - return err; -} - -#endif /* !ECHOCARD_HAS_VMIXER */ - -#endif /* ECHOCARD_HAS_DIGITAL_IO */ - - - -static int pcm_close(struct snd_pcm_substream *substream) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - int oc; - - /* Nothing to do here. Audio is already off and pipe will be - * freed by its callback - */ - DE_ACT(("pcm_close\n")); - - atomic_dec(&chip->opencount); - oc = atomic_read(&chip->opencount); - DE_ACT(("pcm_close oc=%d cs=%d rs=%d\n", oc, - chip->can_set_rate, chip->rate_set)); - if (oc < 2) - chip->can_set_rate = 1; - if (oc == 0) - chip->rate_set = 0; - DE_ACT(("pcm_close2 oc=%d cs=%d rs=%d\n", oc, - chip->can_set_rate,chip->rate_set)); - - return 0; -} - - - -/* Channel allocation and scatter-gather list setup */ -static int init_engine(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params, - int pipe_index, int interleave) -{ - struct echoaudio *chip; - int err, per, rest, page, edge, offs; - struct audiopipe *pipe; - - chip = snd_pcm_substream_chip(substream); - pipe = (struct audiopipe *) substream->runtime->private_data; - - /* Sets up che hardware. If it's already initialized, reset and - * redo with the new parameters - */ - spin_lock_irq(&chip->lock); - if (pipe->index >= 0) { - DE_HWP(("hwp_ie free(%d)\n", pipe->index)); - err = free_pipes(chip, pipe); - snd_BUG_ON(err); - chip->substream[pipe->index] = NULL; - } - - err = allocate_pipes(chip, pipe, pipe_index, interleave); - if (err < 0) { - spin_unlock_irq(&chip->lock); - DE_ACT((KERN_NOTICE "allocate_pipes(%d) err=%d\n", - pipe_index, err)); - return err; - } - spin_unlock_irq(&chip->lock); - DE_ACT((KERN_NOTICE "allocate_pipes()=%d\n", pipe_index)); - - DE_HWP(("pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", - params_buffer_bytes(hw_params), params_periods(hw_params), - params_period_bytes(hw_params))); - err = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (err < 0) { - snd_printk(KERN_ERR "malloc_pages err=%d\n", err); - spin_lock_irq(&chip->lock); - free_pipes(chip, pipe); - spin_unlock_irq(&chip->lock); - pipe->index = -1; - return err; - } - - sglist_init(chip, pipe); - edge = PAGE_SIZE; - for (offs = page = per = 0; offs < params_buffer_bytes(hw_params); - per++) { - rest = params_period_bytes(hw_params); - if (offs + rest > params_buffer_bytes(hw_params)) - rest = params_buffer_bytes(hw_params) - offs; - while (rest) { - dma_addr_t addr; - addr = snd_pcm_sgbuf_get_addr(substream, offs); - if (rest <= edge - offs) { - sglist_add_mapping(chip, pipe, addr, rest); - sglist_add_irq(chip, pipe); - offs += rest; - rest = 0; - } else { - sglist_add_mapping(chip, pipe, addr, - edge - offs); - rest -= edge - offs; - offs = edge; - } - if (offs == edge) { - edge += PAGE_SIZE; - page++; - } - } - } - - /* Close the ring buffer */ - sglist_wrap(chip, pipe); - - /* This stuff is used by the irq handler, so it must be - * initialized before chip->substream - */ - chip->last_period[pipe_index] = 0; - pipe->last_counter = 0; - pipe->position = 0; - smp_wmb(); - chip->substream[pipe_index] = substream; - chip->rate_set = 1; - spin_lock_irq(&chip->lock); - set_sample_rate(chip, hw_params->rate_num / hw_params->rate_den); - spin_unlock_irq(&chip->lock); - DE_HWP(("pcm_hw_params ok\n")); - return 0; -} - - - -static int pcm_analog_in_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - - return init_engine(substream, hw_params, px_analog_in(chip) + - substream->number, params_channels(hw_params)); -} - - - -static int pcm_analog_out_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - return init_engine(substream, hw_params, substream->number, - params_channels(hw_params)); -} - - - -#ifdef ECHOCARD_HAS_DIGITAL_IO - -static int pcm_digital_in_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - - return init_engine(substream, hw_params, px_digital_in(chip) + - substream->number, params_channels(hw_params)); -} - - - -#ifndef ECHOCARD_HAS_VMIXER /* See the note in snd_echo_new_pcm() */ -static int pcm_digital_out_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - - return init_engine(substream, hw_params, px_digital_out(chip) + - substream->number, params_channels(hw_params)); -} -#endif /* !ECHOCARD_HAS_VMIXER */ - -#endif /* ECHOCARD_HAS_DIGITAL_IO */ - - - -static int pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct echoaudio *chip; - struct audiopipe *pipe; - - chip = snd_pcm_substream_chip(substream); - pipe = (struct audiopipe *) substream->runtime->private_data; - - spin_lock_irq(&chip->lock); - if (pipe->index >= 0) { - DE_HWP(("pcm_hw_free(%d)\n", pipe->index)); - free_pipes(chip, pipe); - chip->substream[pipe->index] = NULL; - pipe->index = -1; - } - spin_unlock_irq(&chip->lock); - - DE_HWP(("pcm_hw_freed\n")); - snd_pcm_lib_free_pages(substream); - return 0; -} - - - -static int pcm_prepare(struct snd_pcm_substream *substream) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct audioformat format; - int pipe_index = ((struct audiopipe *)runtime->private_data)->index; - - DE_HWP(("Prepare rate=%d format=%d channels=%d\n", - runtime->rate, runtime->format, runtime->channels)); - format.interleave = runtime->channels; - format.data_are_bigendian = 0; - format.mono_to_stereo = 0; - switch (runtime->format) { - case SNDRV_PCM_FORMAT_U8: - format.bits_per_sample = 8; - break; - case SNDRV_PCM_FORMAT_S16_LE: - format.bits_per_sample = 16; - break; - case SNDRV_PCM_FORMAT_S24_3LE: - format.bits_per_sample = 24; - break; - case SNDRV_PCM_FORMAT_S32_BE: - format.data_are_bigendian = 1; - case SNDRV_PCM_FORMAT_S32_LE: - format.bits_per_sample = 32; - break; - default: - DE_HWP(("Prepare error: unsupported format %d\n", - runtime->format)); - return -EINVAL; - } - - if (snd_BUG_ON(pipe_index >= px_num(chip))) - return -EINVAL; - if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) - return -EINVAL; - set_audio_format(chip, pipe_index, &format); - return 0; -} - - - -static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct echoaudio *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct audiopipe *pipe = runtime->private_data; - int i, err; - u32 channelmask = 0; - struct snd_pcm_substream *s; - - snd_pcm_group_for_each_entry(s, substream) { - for (i = 0; i < DSP_MAXPIPES; i++) { - if (s == chip->substream[i]) { - channelmask |= 1 << i; - snd_pcm_trigger_done(s, substream); - } - } - } - - spin_lock(&chip->lock); - switch (cmd) { - case SNDRV_PCM_TRIGGER_RESUME: - DE_ACT(("pcm_trigger resume\n")); - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - DE_ACT(("pcm_trigger start\n")); - for (i = 0; i < DSP_MAXPIPES; i++) { - if (channelmask & (1 << i)) { - pipe = chip->substream[i]->runtime->private_data; - switch (pipe->state) { - case PIPE_STATE_STOPPED: - chip->last_period[i] = 0; - pipe->last_counter = 0; - pipe->position = 0; - *pipe->dma_counter = 0; - case PIPE_STATE_PAUSED: - pipe->state = PIPE_STATE_STARTED; - break; - case PIPE_STATE_STARTED: - break; - } - } - } - err = start_transport(chip, channelmask, - chip->pipe_cyclic_mask); - break; - case SNDRV_PCM_TRIGGER_SUSPEND: - DE_ACT(("pcm_trigger suspend\n")); - case SNDRV_PCM_TRIGGER_STOP: - DE_ACT(("pcm_trigger stop\n")); - for (i = 0; i < DSP_MAXPIPES; i++) { - if (channelmask & (1 << i)) { - pipe = chip->substream[i]->runtime->private_data; - pipe->state = PIPE_STATE_STOPPED; - } - } - err = stop_transport(chip, channelmask); - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - DE_ACT(("pcm_trigger pause\n")); - for (i = 0; i < DSP_MAXPIPES; i++) { - if (channelmask & (1 << i)) { - pipe = chip->substream[i]->runtime->private_data; - pipe->state = PIPE_STATE_PAUSED; - } - } - err = pause_transport(chip, channelmask); - break; - default: - err = -EINVAL; - } - spin_unlock(&chip->lock); - return err; -} - - - -static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct audiopipe *pipe = runtime->private_data; - size_t cnt, bufsize, pos; - - cnt = le32_to_cpu(*pipe->dma_counter); - pipe->position += cnt - pipe->last_counter; - pipe->last_counter = cnt; - bufsize = substream->runtime->buffer_size; - pos = bytes_to_frames(substream->runtime, pipe->position); - - while (pos >= bufsize) { - pipe->position -= frames_to_bytes(substream->runtime, bufsize); - pos -= bufsize; - } - return pos; -} - - - -/* pcm *_ops structures */ -static struct snd_pcm_ops analog_playback_ops = { - .open = pcm_analog_out_open, - .close = pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = pcm_analog_out_hw_params, - .hw_free = pcm_hw_free, - .prepare = pcm_prepare, - .trigger = pcm_trigger, - .pointer = pcm_pointer, - .page = snd_pcm_sgbuf_ops_page, -}; -static struct snd_pcm_ops analog_capture_ops = { - .open = pcm_analog_in_open, - .close = pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = pcm_analog_in_hw_params, - .hw_free = pcm_hw_free, - .prepare = pcm_prepare, - .trigger = pcm_trigger, - .pointer = pcm_pointer, - .page = snd_pcm_sgbuf_ops_page, -}; -#ifdef ECHOCARD_HAS_DIGITAL_IO -#ifndef ECHOCARD_HAS_VMIXER -static struct snd_pcm_ops digital_playback_ops = { - .open = pcm_digital_out_open, - .close = pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = pcm_digital_out_hw_params, - .hw_free = pcm_hw_free, - .prepare = pcm_prepare, - .trigger = pcm_trigger, - .pointer = pcm_pointer, - .page = snd_pcm_sgbuf_ops_page, -}; -#endif /* !ECHOCARD_HAS_VMIXER */ -static struct snd_pcm_ops digital_capture_ops = { - .open = pcm_digital_in_open, - .close = pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = pcm_digital_in_hw_params, - .hw_free = pcm_hw_free, - .prepare = pcm_prepare, - .trigger = pcm_trigger, - .pointer = pcm_pointer, - .page = snd_pcm_sgbuf_ops_page, -}; -#endif /* ECHOCARD_HAS_DIGITAL_IO */ - - - -/* Preallocate memory only for the first substream because it's the most - * used one - */ -static int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev) -{ - struct snd_pcm_substream *ss; - int stream, err; - - for (stream = 0; stream < 2; stream++) - for (ss = pcm->streams[stream].substream; ss; ss = ss->next) { - err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG, - dev, - ss->number ? 0 : 128<<10, - 256<<10); - if (err < 0) - return err; - } - return 0; -} - - - -/*<--snd_echo_probe() */ -static int __devinit snd_echo_new_pcm(struct echoaudio *chip) -{ - struct snd_pcm *pcm; - int err; - -#ifdef ECHOCARD_HAS_VMIXER - /* This card has a Vmixer, that is there is no direct mapping from PCM - streams to physical outputs. The user can mix the streams as he wishes - via control interface and it's possible to send any stream to any - output, thus it makes no sense to keep analog and digital outputs - separated */ - - /* PCM#0 Virtual outputs and analog inputs */ - if ((err = snd_pcm_new(chip->card, "PCM", 0, num_pipes_out(chip), - num_analog_busses_in(chip), &pcm)) < 0) - return err; - pcm->private_data = chip; - chip->analog_pcm = pcm; - strcpy(pcm->name, chip->card->shortname); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) - return err; - DE_INIT(("Analog PCM ok\n")); - -#ifdef ECHOCARD_HAS_DIGITAL_IO - /* PCM#1 Digital inputs, no outputs */ - if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, 0, - num_digital_busses_in(chip), &pcm)) < 0) - return err; - pcm->private_data = chip; - chip->digital_pcm = pcm; - strcpy(pcm->name, chip->card->shortname); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) - return err; - DE_INIT(("Digital PCM ok\n")); -#endif /* ECHOCARD_HAS_DIGITAL_IO */ - -#else /* ECHOCARD_HAS_VMIXER */ - - /* The card can manage substreams formed by analog and digital channels - at the same time, but I prefer to keep analog and digital channels - separated, because that mixed thing is confusing and useless. So we - register two PCM devices: */ - - /* PCM#0 Analog i/o */ - if ((err = snd_pcm_new(chip->card, "Analog PCM", 0, - num_analog_busses_out(chip), - num_analog_busses_in(chip), &pcm)) < 0) - return err; - pcm->private_data = chip; - chip->analog_pcm = pcm; - strcpy(pcm->name, chip->card->shortname); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) - return err; - DE_INIT(("Analog PCM ok\n")); - -#ifdef ECHOCARD_HAS_DIGITAL_IO - /* PCM#1 Digital i/o */ - if ((err = snd_pcm_new(chip->card, "Digital PCM", 1, - num_digital_busses_out(chip), - num_digital_busses_in(chip), &pcm)) < 0) - return err; - pcm->private_data = chip; - chip->digital_pcm = pcm; - strcpy(pcm->name, chip->card->shortname); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) - return err; - DE_INIT(("Digital PCM ok\n")); -#endif /* ECHOCARD_HAS_DIGITAL_IO */ - -#endif /* ECHOCARD_HAS_VMIXER */ - - return 0; -} - - - - -/****************************************************************************** - Control interface -******************************************************************************/ - -#if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN) - -/******************* PCM output volume *******************/ -static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = num_busses_out(chip); - uinfo->value.integer.min = ECHOGAIN_MINOUT; - uinfo->value.integer.max = ECHOGAIN_MAXOUT; - return 0; -} - -static int snd_echo_output_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c; - - chip = snd_kcontrol_chip(kcontrol); - for (c = 0; c < num_busses_out(chip); c++) - ucontrol->value.integer.value[c] = chip->output_gain[c]; - return 0; -} - -static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c, changed, gain; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&chip->lock); - for (c = 0; c < num_busses_out(chip); c++) { - gain = ucontrol->value.integer.value[c]; - /* Ignore out of range values */ - if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) - continue; - if (chip->output_gain[c] != gain) { - set_output_gain(chip, c, gain); - changed = 1; - } - } - if (changed) - update_output_line_level(chip); - spin_unlock_irq(&chip->lock); - return changed; -} - -#ifdef ECHOCARD_HAS_LINE_OUT_GAIN -/* On the Mia this one controls the line-out volume */ -static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { - .name = "Line Playback Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = snd_echo_output_gain_info, - .get = snd_echo_output_gain_get, - .put = snd_echo_output_gain_put, - .tlv = {.p = db_scale_output_gain}, -}; -#else -static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { - .name = "PCM Playback Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = snd_echo_output_gain_info, - .get = snd_echo_output_gain_get, - .put = snd_echo_output_gain_put, - .tlv = {.p = db_scale_output_gain}, -}; -#endif - -#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */ - - - -#ifdef ECHOCARD_HAS_INPUT_GAIN - -/******************* Analog input volume *******************/ -static int snd_echo_input_gain_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = num_analog_busses_in(chip); - uinfo->value.integer.min = ECHOGAIN_MININP; - uinfo->value.integer.max = ECHOGAIN_MAXINP; - return 0; -} - -static int snd_echo_input_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c; - - chip = snd_kcontrol_chip(kcontrol); - for (c = 0; c < num_analog_busses_in(chip); c++) - ucontrol->value.integer.value[c] = chip->input_gain[c]; - return 0; -} - -static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c, gain, changed; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&chip->lock); - for (c = 0; c < num_analog_busses_in(chip); c++) { - gain = ucontrol->value.integer.value[c]; - /* Ignore out of range values */ - if (gain < ECHOGAIN_MININP || gain > ECHOGAIN_MAXINP) - continue; - if (chip->input_gain[c] != gain) { - set_input_gain(chip, c, gain); - changed = 1; - } - } - if (changed) - update_input_line_level(chip); - spin_unlock_irq(&chip->lock); - return changed; -} - -static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); - -static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { - .name = "Line Capture Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = snd_echo_input_gain_info, - .get = snd_echo_input_gain_get, - .put = snd_echo_input_gain_put, - .tlv = {.p = db_scale_input_gain}, -}; - -#endif /* ECHOCARD_HAS_INPUT_GAIN */ - - - -#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL - -/************ Analog output nominal level (+4dBu / -10dBV) ***************/ -static int snd_echo_output_nominal_info (struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = num_analog_busses_out(chip); - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int snd_echo_output_nominal_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c; - - chip = snd_kcontrol_chip(kcontrol); - for (c = 0; c < num_analog_busses_out(chip); c++) - ucontrol->value.integer.value[c] = chip->nominal_level[c]; - return 0; -} - -static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c, changed; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&chip->lock); - for (c = 0; c < num_analog_busses_out(chip); c++) { - if (chip->nominal_level[c] != ucontrol->value.integer.value[c]) { - set_nominal_level(chip, c, - ucontrol->value.integer.value[c]); - changed = 1; - } - } - if (changed) - update_output_line_level(chip); - spin_unlock_irq(&chip->lock); - return changed; -} - -static struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = { - .name = "Line Playback Switch (-10dBV)", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_echo_output_nominal_info, - .get = snd_echo_output_nominal_get, - .put = snd_echo_output_nominal_put, -}; - -#endif /* ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL */ - - - -#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL - -/*************** Analog input nominal level (+4dBu / -10dBV) ***************/ -static int snd_echo_input_nominal_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = num_analog_busses_in(chip); - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int snd_echo_input_nominal_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c; - - chip = snd_kcontrol_chip(kcontrol); - for (c = 0; c < num_analog_busses_in(chip); c++) - ucontrol->value.integer.value[c] = - chip->nominal_level[bx_analog_in(chip) + c]; - return 0; -} - -static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int c, changed; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&chip->lock); - for (c = 0; c < num_analog_busses_in(chip); c++) { - if (chip->nominal_level[bx_analog_in(chip) + c] != - ucontrol->value.integer.value[c]) { - set_nominal_level(chip, bx_analog_in(chip) + c, - ucontrol->value.integer.value[c]); - changed = 1; - } - } - if (changed) - update_output_line_level(chip); /* "Output" is not a mistake - * here. - */ - spin_unlock_irq(&chip->lock); - return changed; -} - -static struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = { - .name = "Line Capture Switch (-10dBV)", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_echo_input_nominal_info, - .get = snd_echo_input_nominal_get, - .put = snd_echo_input_nominal_put, -}; - -#endif /* ECHOCARD_HAS_INPUT_NOMINAL_LEVEL */ - - - -#ifdef ECHOCARD_HAS_MONITOR - -/******************* Monitor mixer *******************/ -static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = ECHOGAIN_MINOUT; - uinfo->value.integer.max = ECHOGAIN_MAXOUT; - uinfo->dimen.d[0] = num_busses_out(chip); - uinfo->dimen.d[1] = num_busses_in(chip); - return 0; -} - -static int snd_echo_mixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = - chip->monitor_gain[ucontrol->id.index / num_busses_in(chip)] - [ucontrol->id.index % num_busses_in(chip)]; - return 0; -} - -static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int changed, gain; - short out, in; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - out = ucontrol->id.index / num_busses_in(chip); - in = ucontrol->id.index % num_busses_in(chip); - gain = ucontrol->value.integer.value[0]; - if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) - return -EINVAL; - if (chip->monitor_gain[out][in] != gain) { - spin_lock_irq(&chip->lock); - set_monitor_gain(chip, out, in, gain); - update_output_line_level(chip); - spin_unlock_irq(&chip->lock); - changed = 1; - } - return changed; -} - -static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { - .name = "Monitor Mixer Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = snd_echo_mixer_info, - .get = snd_echo_mixer_get, - .put = snd_echo_mixer_put, - .tlv = {.p = db_scale_output_gain}, -}; - -#endif /* ECHOCARD_HAS_MONITOR */ - - - -#ifdef ECHOCARD_HAS_VMIXER - -/******************* Vmixer *******************/ -static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = ECHOGAIN_MINOUT; - uinfo->value.integer.max = ECHOGAIN_MAXOUT; - uinfo->dimen.d[0] = num_busses_out(chip); - uinfo->dimen.d[1] = num_pipes_out(chip); - return 0; -} - -static int snd_echo_vmixer_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = - chip->vmixer_gain[ucontrol->id.index / num_pipes_out(chip)] - [ucontrol->id.index % num_pipes_out(chip)]; - return 0; -} - -static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int gain, changed; - short vch, out; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - out = ucontrol->id.index / num_pipes_out(chip); - vch = ucontrol->id.index % num_pipes_out(chip); - gain = ucontrol->value.integer.value[0]; - if (gain < ECHOGAIN_MINOUT || gain > ECHOGAIN_MAXOUT) - return -EINVAL; - if (chip->vmixer_gain[out][vch] != ucontrol->value.integer.value[0]) { - spin_lock_irq(&chip->lock); - set_vmixer_gain(chip, out, vch, ucontrol->value.integer.value[0]); - update_vmixer_level(chip); - spin_unlock_irq(&chip->lock); - changed = 1; - } - return changed; -} - -static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { - .name = "VMixer Volume", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = snd_echo_vmixer_info, - .get = snd_echo_vmixer_get, - .put = snd_echo_vmixer_put, - .tlv = {.p = db_scale_output_gain}, -}; - -#endif /* ECHOCARD_HAS_VMIXER */ - - - -#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH - -/******************* Digital mode switch *******************/ -static int snd_echo_digital_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *names[4] = { - "S/PDIF Coaxial", "S/PDIF Optical", "ADAT Optical", - "S/PDIF Cdrom" - }; - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->value.enumerated.items = chip->num_digital_modes; - uinfo->count = 1; - if (uinfo->value.enumerated.item >= chip->num_digital_modes) - uinfo->value.enumerated.item = chip->num_digital_modes - 1; - strcpy(uinfo->value.enumerated.name, names[ - chip->digital_mode_list[uinfo->value.enumerated.item]]); - return 0; -} - -static int snd_echo_digital_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int i, mode; - - chip = snd_kcontrol_chip(kcontrol); - mode = chip->digital_mode; - for (i = chip->num_digital_modes - 1; i >= 0; i--) - if (mode == chip->digital_mode_list[i]) { - ucontrol->value.enumerated.item[0] = i; - break; - } - return 0; -} - -static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int changed; - unsigned short emode, dmode; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - - emode = ucontrol->value.enumerated.item[0]; - if (emode >= chip->num_digital_modes) - return -EINVAL; - dmode = chip->digital_mode_list[emode]; - - if (dmode != chip->digital_mode) { - /* mode_mutex is required to make this operation atomic wrt - pcm_digital_*_open() and set_input_clock() functions. */ - mutex_lock(&chip->mode_mutex); - - /* Do not allow the user to change the digital mode when a pcm - device is open because it also changes the number of channels - and the allowed sample rates */ - if (atomic_read(&chip->opencount)) { - changed = -EAGAIN; - } else { - changed = set_digital_mode(chip, dmode); - /* If we had to change the clock source, report it */ - if (changed > 0 && chip->clock_src_ctl) { - snd_ctl_notify(chip->card, - SNDRV_CTL_EVENT_MASK_VALUE, - &chip->clock_src_ctl->id); - DE_ACT(("SDM() =%d\n", changed)); - } - if (changed >= 0) - changed = 1; /* No errors */ - } - mutex_unlock(&chip->mode_mutex); - } - return changed; -} - -static struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = { - .name = "Digital mode Switch", - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .info = snd_echo_digital_mode_info, - .get = snd_echo_digital_mode_get, - .put = snd_echo_digital_mode_put, -}; - -#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ - - - -#ifdef ECHOCARD_HAS_DIGITAL_IO - -/******************* S/PDIF mode switch *******************/ -static int snd_echo_spdif_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *names[2] = {"Consumer", "Professional"}; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->value.enumerated.items = 2; - uinfo->count = 1; - if (uinfo->value.enumerated.item) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, - names[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_echo_spdif_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = !!chip->professional_spdif; - return 0; -} - -static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int mode; - - chip = snd_kcontrol_chip(kcontrol); - mode = !!ucontrol->value.enumerated.item[0]; - if (mode != chip->professional_spdif) { - spin_lock_irq(&chip->lock); - set_professional_spdif(chip, mode); - spin_unlock_irq(&chip->lock); - return 1; - } - return 0; -} - -static struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = { - .name = "S/PDIF mode Switch", - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .info = snd_echo_spdif_mode_info, - .get = snd_echo_spdif_mode_get, - .put = snd_echo_spdif_mode_put, -}; - -#endif /* ECHOCARD_HAS_DIGITAL_IO */ - - - -#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK - -/******************* Select input clock source *******************/ -static int snd_echo_clock_source_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *names[8] = { - "Internal", "Word", "Super", "S/PDIF", "ADAT", "ESync", - "ESync96", "MTC" - }; - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->value.enumerated.items = chip->num_clock_sources; - uinfo->count = 1; - if (uinfo->value.enumerated.item >= chip->num_clock_sources) - uinfo->value.enumerated.item = chip->num_clock_sources - 1; - strcpy(uinfo->value.enumerated.name, names[ - chip->clock_source_list[uinfo->value.enumerated.item]]); - return 0; -} - -static int snd_echo_clock_source_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int i, clock; - - chip = snd_kcontrol_chip(kcontrol); - clock = chip->input_clock; - - for (i = 0; i < chip->num_clock_sources; i++) - if (clock == chip->clock_source_list[i]) - ucontrol->value.enumerated.item[0] = i; - - return 0; -} - -static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int changed; - unsigned int eclock, dclock; - - changed = 0; - chip = snd_kcontrol_chip(kcontrol); - eclock = ucontrol->value.enumerated.item[0]; - if (eclock >= chip->input_clock_types) - return -EINVAL; - dclock = chip->clock_source_list[eclock]; - if (chip->input_clock != dclock) { - mutex_lock(&chip->mode_mutex); - spin_lock_irq(&chip->lock); - if ((changed = set_input_clock(chip, dclock)) == 0) - changed = 1; /* no errors */ - spin_unlock_irq(&chip->lock); - mutex_unlock(&chip->mode_mutex); - } - - if (changed < 0) - DE_ACT(("seticlk val%d err 0x%x\n", dclock, changed)); - - return changed; -} - -static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = { - .name = "Sample Clock Source", - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .info = snd_echo_clock_source_info, - .get = snd_echo_clock_source_get, - .put = snd_echo_clock_source_put, -}; - -#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ - - - -#ifdef ECHOCARD_HAS_PHANTOM_POWER - -/******************* Phantom power switch *******************/ -#define snd_echo_phantom_power_info snd_ctl_boolean_mono_info - -static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = chip->phantom_power; - return 0; -} - -static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip = snd_kcontrol_chip(kcontrol); - int power, changed = 0; - - power = !!ucontrol->value.integer.value[0]; - if (chip->phantom_power != power) { - spin_lock_irq(&chip->lock); - changed = set_phantom_power(chip, power); - spin_unlock_irq(&chip->lock); - if (changed == 0) - changed = 1; /* no errors */ - } - return changed; -} - -static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = { - .name = "Phantom power Switch", - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .info = snd_echo_phantom_power_info, - .get = snd_echo_phantom_power_get, - .put = snd_echo_phantom_power_put, -}; - -#endif /* ECHOCARD_HAS_PHANTOM_POWER */ - - - -#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE - -/******************* Digital input automute switch *******************/ -#define snd_echo_automute_info snd_ctl_boolean_mono_info - -static int snd_echo_automute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = chip->digital_in_automute; - return 0; -} - -static int snd_echo_automute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip = snd_kcontrol_chip(kcontrol); - int automute, changed = 0; - - automute = !!ucontrol->value.integer.value[0]; - if (chip->digital_in_automute != automute) { - spin_lock_irq(&chip->lock); - changed = set_input_auto_mute(chip, automute); - spin_unlock_irq(&chip->lock); - if (changed == 0) - changed = 1; /* no errors */ - } - return changed; -} - -static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = { - .name = "Digital Capture Switch (automute)", - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .info = snd_echo_automute_info, - .get = snd_echo_automute_get, - .put = snd_echo_automute_put, -}; - -#endif /* ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE */ - - - -/******************* VU-meters switch *******************/ -#define snd_echo_vumeters_switch_info snd_ctl_boolean_mono_info - -static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&chip->lock); - set_meters_on(chip, ucontrol->value.integer.value[0]); - spin_unlock_irq(&chip->lock); - return 1; -} - -static struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = { - .name = "VU-meters Switch", - .iface = SNDRV_CTL_ELEM_IFACE_CARD, - .access = SNDRV_CTL_ELEM_ACCESS_WRITE, - .info = snd_echo_vumeters_switch_info, - .put = snd_echo_vumeters_switch_put, -}; - - - -/***** Read VU-meters (input, output, analog and digital together) *****/ -static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 96; - uinfo->value.integer.min = ECHOGAIN_MINOUT; - uinfo->value.integer.max = 0; -#ifdef ECHOCARD_HAS_VMIXER - uinfo->dimen.d[0] = 3; /* Out, In, Virt */ -#else - uinfo->dimen.d[0] = 2; /* Out, In */ -#endif - uinfo->dimen.d[1] = 16; /* 16 channels */ - uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ - return 0; -} - -static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - get_audio_meters(chip, ucontrol->value.integer.value); - return 0; -} - -static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { - .name = "VU-meters", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .access = SNDRV_CTL_ELEM_ACCESS_READ | - SNDRV_CTL_ELEM_ACCESS_VOLATILE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .info = snd_echo_vumeters_info, - .get = snd_echo_vumeters_get, - .tlv = {.p = db_scale_output_gain}, -}; - - - -/*** Channels info - it exports informations about the number of channels ***/ -static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct echoaudio *chip; - - chip = snd_kcontrol_chip(kcontrol); - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 6; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1 << ECHO_CLOCK_NUMBER; - return 0; -} - -static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct echoaudio *chip; - int detected, clocks, bit, src; - - chip = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = num_busses_in(chip); - ucontrol->value.integer.value[1] = num_analog_busses_in(chip); - ucontrol->value.integer.value[2] = num_busses_out(chip); - ucontrol->value.integer.value[3] = num_analog_busses_out(chip); - ucontrol->value.integer.value[4] = num_pipes_out(chip); - - /* Compute the bitmask of the currently valid input clocks */ - detected = detect_input_clocks(chip); - clocks = 0; - src = chip->num_clock_sources - 1; - for (bit = ECHO_CLOCK_NUMBER - 1; bit >= 0; bit--) - if (detected & (1 << bit)) - for (; src >= 0; src--) - if (bit == chip->clock_source_list[src]) { - clocks |= 1 << src; - break; - } - ucontrol->value.integer.value[5] = clocks; - - return 0; -} - -static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = { - .name = "Channels info", - .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = snd_echo_channels_info_info, - .get = snd_echo_channels_info_get, -}; - - - - -/****************************************************************************** - IRQ Handler -******************************************************************************/ - -static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) -{ - struct echoaudio *chip = dev_id; - struct snd_pcm_substream *substream; - int period, ss, st; - - spin_lock(&chip->lock); - st = service_irq(chip); - if (st < 0) { - spin_unlock(&chip->lock); - return IRQ_NONE; - } - /* The hardware doesn't tell us which substream caused the irq, - thus we have to check all running substreams. */ - for (ss = 0; ss < DSP_MAXPIPES; ss++) { - substream = chip->substream[ss]; - if (substream && ((struct audiopipe *)substream->runtime-> - private_data)->state == PIPE_STATE_STARTED) { - period = pcm_pointer(substream) / - substream->runtime->period_size; - if (period != chip->last_period[ss]) { - chip->last_period[ss] = period; - spin_unlock(&chip->lock); - snd_pcm_period_elapsed(substream); - spin_lock(&chip->lock); - } - } - } - spin_unlock(&chip->lock); - -#ifdef ECHOCARD_HAS_MIDI - if (st > 0 && chip->midi_in) { - snd_rawmidi_receive(chip->midi_in, chip->midi_buffer, st); - DE_MID(("rawmidi_iread=%d\n", st)); - } -#endif - return IRQ_HANDLED; -} - - - - -/****************************************************************************** - Module construction / destruction -******************************************************************************/ - -static int snd_echo_free(struct echoaudio *chip) -{ - DE_INIT(("Stop DSP...\n")); - if (chip->comm_page) - rest_in_peace(chip); - DE_INIT(("Stopped.\n")); - - if (chip->irq >= 0) - free_irq(chip->irq, chip); - - if (chip->comm_page) - snd_dma_free_pages(&chip->commpage_dma_buf); - - if (chip->dsp_registers) - iounmap(chip->dsp_registers); - - if (chip->iores) - release_and_free_resource(chip->iores); - - DE_INIT(("MMIO freed.\n")); - - pci_disable_device(chip->pci); - - /* release chip data */ - free_firmware_cache(chip); - kfree(chip); - DE_INIT(("Chip freed.\n")); - return 0; -} - - - -static int snd_echo_dev_free(struct snd_device *device) -{ - struct echoaudio *chip = device->device_data; - - DE_INIT(("snd_echo_dev_free()...\n")); - return snd_echo_free(chip); -} - - - -/* <--snd_echo_probe() */ -static __devinit int snd_echo_create(struct snd_card *card, - struct pci_dev *pci, - struct echoaudio **rchip) -{ - struct echoaudio *chip; - int err; - size_t sz; - static struct snd_device_ops ops = { - .dev_free = snd_echo_dev_free, - }; - - *rchip = NULL; - - pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0xC0); - - if ((err = pci_enable_device(pci)) < 0) - return err; - pci_set_master(pci); - - /* Allocate chip if needed */ - if (!*rchip) { - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) { - pci_disable_device(pci); - return -ENOMEM; - } - DE_INIT(("chip=%p\n", chip)); - spin_lock_init(&chip->lock); - chip->card = card; - chip->pci = pci; - chip->irq = -1; - atomic_set(&chip->opencount, 0); - mutex_init(&chip->mode_mutex); - chip->can_set_rate = 1; - } else { - /* If this was called from the resume function, chip is - * already allocated and it contains current card settings. - */ - chip = *rchip; - } - - /* PCI resource allocation */ - chip->dsp_registers_phys = pci_resource_start(pci, 0); - sz = pci_resource_len(pci, 0); - if (sz > PAGE_SIZE) - sz = PAGE_SIZE; /* We map only the required part */ - - if ((chip->iores = request_mem_region(chip->dsp_registers_phys, sz, - ECHOCARD_NAME)) == NULL) { - snd_echo_free(chip); - snd_printk(KERN_ERR "cannot get memory region\n"); - return -EBUSY; - } - chip->dsp_registers = (volatile u32 __iomem *) - ioremap_nocache(chip->dsp_registers_phys, sz); - - if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, - KBUILD_MODNAME, chip)) { - snd_echo_free(chip); - snd_printk(KERN_ERR "cannot grab irq\n"); - return -EBUSY; - } - chip->irq = pci->irq; - DE_INIT(("pci=%p irq=%d subdev=%04x Init hardware...\n", - chip->pci, chip->irq, chip->pci->subsystem_device)); - - /* Create the DSP comm page - this is the area of memory used for most - of the communication with the DSP, which accesses it via bus mastering */ - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - sizeof(struct comm_page), - &chip->commpage_dma_buf) < 0) { - snd_echo_free(chip); - snd_printk(KERN_ERR "cannot allocate the comm page\n"); - return -ENOMEM; - } - chip->comm_page_phys = chip->commpage_dma_buf.addr; - chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area; - - err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); - if (err >= 0) - err = set_mixer_defaults(chip); - if (err < 0) { - DE_INIT(("init_hw err=%d\n", err)); - snd_echo_free(chip); - return err; - } - DE_INIT(("Card init OK\n")); - - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_echo_free(chip); - return err; - } - *rchip = chip; - /* Init done ! */ - return 0; -} - - - -/* constructor */ -static int __devinit snd_echo_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct echoaudio *chip; - char *dsp; - int i, err; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - DE_INIT(("Echoaudio driver starting...\n")); - i = 0; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); - if (err < 0) - return err; - - snd_card_set_dev(card, &pci->dev); - - chip = NULL; /* Tells snd_echo_create to allocate chip */ - if ((err = snd_echo_create(card, pci, &chip)) < 0) { - snd_card_free(card); - return err; - } - - strcpy(card->driver, "Echo_" ECHOCARD_NAME); - strcpy(card->shortname, chip->card_name); - - dsp = "56301"; - if (pci_id->device == 0x3410) - dsp = "56361"; - - sprintf(card->longname, "%s rev.%d (DSP%s) at 0x%lx irq %i", - card->shortname, pci_id->subdevice & 0x000f, dsp, - chip->dsp_registers_phys, chip->irq); - - if ((err = snd_echo_new_pcm(chip)) < 0) { - snd_printk(KERN_ERR "new pcm error %d\n", err); - snd_card_free(card); - return err; - } - -#ifdef ECHOCARD_HAS_MIDI - if (chip->has_midi) { /* Some Mia's do not have midi */ - if ((err = snd_echo_midi_create(card, chip)) < 0) { - snd_printk(KERN_ERR "new midi error %d\n", err); - snd_card_free(card); - return err; - } - } -#endif - -#ifdef ECHOCARD_HAS_VMIXER - snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) - goto ctl_error; -#ifdef ECHOCARD_HAS_LINE_OUT_GAIN - err = snd_ctl_add(chip->card, - snd_ctl_new1(&snd_echo_line_output_gain, chip)); - if (err < 0) - goto ctl_error; -#endif -#else /* ECHOCARD_HAS_VMIXER */ - err = snd_ctl_add(chip->card, - snd_ctl_new1(&snd_echo_pcm_output_gain, chip)); - if (err < 0) - goto ctl_error; -#endif /* ECHOCARD_HAS_VMIXER */ - -#ifdef ECHOCARD_HAS_INPUT_GAIN - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) - goto ctl_error; -#endif - -#ifdef ECHOCARD_HAS_INPUT_NOMINAL_LEVEL - if (!chip->hasnt_input_nominal_level) - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_intput_nominal_level, chip))) < 0) - goto ctl_error; -#endif - -#ifdef ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_output_nominal_level, chip))) < 0) - goto ctl_error; -#endif - - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters_switch, chip))) < 0) - goto ctl_error; - - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vumeters, chip))) < 0) - goto ctl_error; - -#ifdef ECHOCARD_HAS_MONITOR - snd_echo_monitor_mixer.count = num_busses_in(chip) * num_busses_out(chip); - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_monitor_mixer, chip))) < 0) - goto ctl_error; -#endif - -#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_automute_switch, chip))) < 0) - goto ctl_error; -#endif - - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_channels_info, chip))) < 0) - goto ctl_error; - -#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH - /* Creates a list of available digital modes */ - chip->num_digital_modes = 0; - for (i = 0; i < 6; i++) - if (chip->digital_modes & (1 << i)) - chip->digital_mode_list[chip->num_digital_modes++] = i; - - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_digital_mode_switch, chip))) < 0) - goto ctl_error; -#endif /* ECHOCARD_HAS_DIGITAL_MODE_SWITCH */ - -#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK - /* Creates a list of available clock sources */ - chip->num_clock_sources = 0; - for (i = 0; i < 10; i++) - if (chip->input_clock_types & (1 << i)) - chip->clock_source_list[chip->num_clock_sources++] = i; - - if (chip->num_clock_sources > 1) { - chip->clock_src_ctl = snd_ctl_new1(&snd_echo_clock_source_switch, chip); - if ((err = snd_ctl_add(chip->card, chip->clock_src_ctl)) < 0) - goto ctl_error; - } -#endif /* ECHOCARD_HAS_EXTERNAL_CLOCK */ - -#ifdef ECHOCARD_HAS_DIGITAL_IO - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_spdif_mode_switch, chip))) < 0) - goto ctl_error; -#endif - -#ifdef ECHOCARD_HAS_PHANTOM_POWER - if (chip->has_phantom_power) - if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_phantom_power_switch, chip))) < 0) - goto ctl_error; -#endif - - err = snd_card_register(card); - if (err < 0) - goto ctl_error; - snd_printk(KERN_INFO "Card registered: %s\n", card->longname); - - pci_set_drvdata(pci, chip); - dev++; - return 0; - -ctl_error: - snd_printk(KERN_ERR "new control error %d\n", err); - snd_card_free(card); - return err; -} - - - -#if defined(CONFIG_PM) - -static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state) -{ - struct echoaudio *chip = pci_get_drvdata(pci); - - DE_INIT(("suspend start\n")); - snd_pcm_suspend_all(chip->analog_pcm); - snd_pcm_suspend_all(chip->digital_pcm); - -#ifdef ECHOCARD_HAS_MIDI - /* This call can sleep */ - if (chip->midi_out) - snd_echo_midi_output_trigger(chip->midi_out, 0); -#endif - spin_lock_irq(&chip->lock); - if (wait_handshake(chip)) { - spin_unlock_irq(&chip->lock); - return -EIO; - } - clear_handshake(chip); - if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) { - spin_unlock_irq(&chip->lock); - return -EIO; - } - spin_unlock_irq(&chip->lock); - - chip->dsp_code = NULL; - free_irq(chip->irq, chip); - chip->irq = -1; - pci_save_state(pci); - pci_disable_device(pci); - - DE_INIT(("suspend done\n")); - return 0; -} - - - -static int snd_echo_resume(struct pci_dev *pci) -{ - struct echoaudio *chip = pci_get_drvdata(pci); - struct comm_page *commpage, *commpage_bak; - u32 pipe_alloc_mask; - int err; - - DE_INIT(("resume start\n")); - pci_restore_state(pci); - commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL); - if (commpage_bak == NULL) - return -ENOMEM; - commpage = chip->comm_page; - memcpy(commpage_bak, commpage, sizeof(struct comm_page)); - - err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); - if (err < 0) { - kfree(commpage_bak); - DE_INIT(("resume init_hw err=%d\n", err)); - snd_echo_free(chip); - return err; - } - DE_INIT(("resume init OK\n")); - - /* Temporarily set chip->pipe_alloc_mask=0 otherwise - * restore_dsp_settings() fails. - */ - pipe_alloc_mask = chip->pipe_alloc_mask; - chip->pipe_alloc_mask = 0; - err = restore_dsp_rettings(chip); - chip->pipe_alloc_mask = pipe_alloc_mask; - if (err < 0) { - kfree(commpage_bak); - return err; - } - DE_INIT(("resume restore OK\n")); - - memcpy(&commpage->audio_format, &commpage_bak->audio_format, - sizeof(commpage->audio_format)); - memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr, - sizeof(commpage->sglist_addr)); - memcpy(&commpage->midi_output, &commpage_bak->midi_output, - sizeof(commpage->midi_output)); - kfree(commpage_bak); - - if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, - KBUILD_MODNAME, chip)) { - snd_echo_free(chip); - snd_printk(KERN_ERR "cannot grab irq\n"); - return -EBUSY; - } - chip->irq = pci->irq; - DE_INIT(("resume irq=%d\n", chip->irq)); - -#ifdef ECHOCARD_HAS_MIDI - if (chip->midi_input_enabled) - enable_midi_input(chip, TRUE); - if (chip->midi_out) - snd_echo_midi_output_trigger(chip->midi_out, 1); -#endif - - DE_INIT(("resume done\n")); - return 0; -} - -#endif /* CONFIG_PM */ - - - -static void __devexit snd_echo_remove(struct pci_dev *pci) -{ - struct echoaudio *chip; - - chip = pci_get_drvdata(pci); - if (chip) - snd_card_free(chip->card); - pci_set_drvdata(pci, NULL); -} - - - -/****************************************************************************** - Everything starts and ends here -******************************************************************************/ - -/* pci_driver definition */ -static struct pci_driver driver = { - .name = KBUILD_MODNAME, - .id_table = snd_echo_ids, - .probe = snd_echo_probe, - .remove = __devexit_p(snd_echo_remove), -#ifdef CONFIG_PM - .suspend = snd_echo_suspend, - .resume = snd_echo_resume, -#endif /* CONFIG_PM */ -}; - - - -/* initialization of the module */ -static int __init alsa_card_echo_init(void) -{ - return pci_register_driver(&driver); -} - - - -/* clean up the module */ -static void __exit alsa_card_echo_exit(void) -{ - pci_unregister_driver(&driver); -} - - -module_init(alsa_card_echo_init) -module_exit(alsa_card_echo_exit) diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.h b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.h deleted file mode 100644 index 1df974dc..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio.h +++ /dev/null @@ -1,598 +0,0 @@ -/**************************************************************************** - - 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> - - **************************************************************************** - - - Here's a block diagram of how most of the cards work: - - +-----------+ - record | |<-------------------- Inputs - <-------| | | - PCI | Transport | | - bus | engine | \|/ - ------->| | +-------+ - play | |--->|monitor|-------> Outputs - +-----------+ | mixer | - +-------+ - - The lines going to and from the PCI bus represent "pipes". A pipe performs - audio transport - moving audio data to and from buffers on the host via - bus mastering. - - The inputs and outputs on the right represent input and output "busses." - A bus is a physical, real connection to the outside world. An example - of a bus would be the 1/4" analog connectors on the back of Layla or - an RCA S/PDIF connector. - - For most cards, there is a one-to-one correspondence between outputs - and busses; that is, each individual pipe is hard-wired to a single bus. - - Cards that work this way are Darla20, Gina20, Layla20, Darla24, Gina24, - Layla24, Mona, and Indigo. - - - Mia has a feature called "virtual outputs." - - - +-----------+ - record | |<----------------------------- Inputs - <-------| | | - PCI | Transport | | - bus | engine | \|/ - ------->| | +------+ +-------+ - play | |-->|vmixer|-->|monitor|-------> Outputs - +-----------+ +------+ | mixer | - +-------+ - - - Obviously, the difference here is the box labeled "vmixer." Vmixer is - short for "virtual output mixer." For Mia, pipes are *not* hard-wired - to a single bus; the vmixer lets you mix any pipe to any bus in any - combination. - - Note, however, that the left-hand side of the diagram is unchanged. - Transport works exactly the same way - the difference is in the mixer stage. - - - Pipes and busses are numbered starting at zero. - - - - Pipe index - ========== - - A number of calls in CEchoGals refer to a "pipe index". A pipe index is - a unique number for a pipe that unambiguously refers to a playback or record - pipe. Pipe indices are numbered starting with analog outputs, followed by - digital outputs, then analog inputs, then digital inputs. - - Take Gina24 as an example: - - Pipe index - - 0-7 Analog outputs (0 .. FirstDigitalBusOut-1) - 8-15 Digital outputs (FirstDigitalBusOut .. NumBussesOut-1) - 16-17 Analog inputs - 18-25 Digital inputs - - - You get the pipe index by calling CEchoGals::OpenAudio; the other transport - functions take the pipe index as a parameter. If you need a pipe index for - some other reason, use the handy Makepipe_index method. - - - Some calls take a CChannelMask parameter; CChannelMask is a handy way to - group pipe indices. - - - - Digital mode switch - =================== - - Some cards (right now, Gina24, Layla24, and Mona) have a Digital Mode Switch - or DMS. Cards with a DMS can be set to one of three mutually exclusive - digital modes: S/PDIF RCA, S/PDIF optical, or ADAT optical. - - This may create some confusion since ADAT optical is 8 channels wide and - S/PDIF is only two channels wide. Gina24, Layla24, and Mona handle this - by acting as if they always have 8 digital outs and ins. If you are in - either S/PDIF mode, the last 6 channels don't do anything - data sent - out these channels is thrown away and you will always record zeros. - - Note that with Gina24, Layla24, and Mona, sample rates above 50 kHz are - only available if you have the card configured for S/PDIF optical or S/PDIF - RCA. - - - - Double speed mode - ================= - - Some of the cards support 88.2 kHz and 96 kHz sampling (Darla24, Gina24, - Layla24, Mona, Mia, and Indigo). For these cards, the driver sometimes has - to worry about "double speed mode"; double speed mode applies whenever the - sampling rate is above 50 kHz. - - For instance, Mona and Layla24 support word clock sync. However, they - actually support two different word clock modes - single speed (below - 50 kHz) and double speed (above 50 kHz). The hardware detects if a single - or double speed word clock signal is present; the generic code uses that - information to determine which mode to use. - - The generic code takes care of all this for you. -*/ - - -#ifndef _ECHOAUDIO_H_ -#define _ECHOAUDIO_H_ - - -#define TRUE 1 -#define FALSE 0 - -#include "echoaudio_dsp.h" - - - -/*********************************************************************** - - PCI configuration space - -***********************************************************************/ - -/* - * PCI vendor ID and device IDs for the hardware - */ -#define VENDOR_ID 0x1057 -#define DEVICE_ID_56301 0x1801 -#define DEVICE_ID_56361 0x3410 -#define SUBVENDOR_ID 0xECC0 - - -/* - * Valid Echo PCI subsystem card IDs - */ -#define DARLA20 0x0010 -#define GINA20 0x0020 -#define LAYLA20 0x0030 -#define DARLA24 0x0040 -#define GINA24 0x0050 -#define LAYLA24 0x0060 -#define MONA 0x0070 -#define MIA 0x0080 -#define INDIGO 0x0090 -#define INDIGO_IO 0x00a0 -#define INDIGO_DJ 0x00b0 -#define DC8 0x00c0 -#define INDIGO_IOX 0x00d0 -#define INDIGO_DJX 0x00e0 -#define ECHO3G 0x0100 - - -/************************************************************************ - - Array sizes and so forth - -***********************************************************************/ - -/* - * Sizes - */ -#define ECHO_MAXAUDIOINPUTS 32 /* Max audio input channels */ -#define ECHO_MAXAUDIOOUTPUTS 32 /* Max audio output channels */ -#define ECHO_MAXAUDIOPIPES 32 /* Max number of input and output - * pipes */ -#define E3G_MAX_OUTPUTS 16 -#define ECHO_MAXMIDIJACKS 1 /* Max MIDI ports */ -#define ECHO_MIDI_QUEUE_SZ 512 /* Max MIDI input queue entries */ -#define ECHO_MTC_QUEUE_SZ 32 /* Max MIDI time code input queue - * entries */ - -/* - * MIDI activity indicator timeout - */ -#define MIDI_ACTIVITY_TIMEOUT_USEC 200000 - - -/**************************************************************************** - - Clocks - -*****************************************************************************/ - -/* - * Clock numbers - */ -#define ECHO_CLOCK_INTERNAL 0 -#define ECHO_CLOCK_WORD 1 -#define ECHO_CLOCK_SUPER 2 -#define ECHO_CLOCK_SPDIF 3 -#define ECHO_CLOCK_ADAT 4 -#define ECHO_CLOCK_ESYNC 5 -#define ECHO_CLOCK_ESYNC96 6 -#define ECHO_CLOCK_MTC 7 -#define ECHO_CLOCK_NUMBER 8 -#define ECHO_CLOCKS 0xffff - -/* - * Clock bit numbers - used to report capabilities and whatever clocks - * are being detected dynamically. - */ -#define ECHO_CLOCK_BIT_INTERNAL (1 << ECHO_CLOCK_INTERNAL) -#define ECHO_CLOCK_BIT_WORD (1 << ECHO_CLOCK_WORD) -#define ECHO_CLOCK_BIT_SUPER (1 << ECHO_CLOCK_SUPER) -#define ECHO_CLOCK_BIT_SPDIF (1 << ECHO_CLOCK_SPDIF) -#define ECHO_CLOCK_BIT_ADAT (1 << ECHO_CLOCK_ADAT) -#define ECHO_CLOCK_BIT_ESYNC (1 << ECHO_CLOCK_ESYNC) -#define ECHO_CLOCK_BIT_ESYNC96 (1 << ECHO_CLOCK_ESYNC96) -#define ECHO_CLOCK_BIT_MTC (1<<ECHO_CLOCK_MTC) - - -/*************************************************************************** - - Digital modes - -****************************************************************************/ - -/* - * Digital modes for Mona, Layla24, and Gina24 - */ -#define DIGITAL_MODE_NONE 0xFF -#define DIGITAL_MODE_SPDIF_RCA 0 -#define DIGITAL_MODE_SPDIF_OPTICAL 1 -#define DIGITAL_MODE_ADAT 2 -#define DIGITAL_MODE_SPDIF_CDROM 3 -#define DIGITAL_MODES 4 - -/* - * Digital mode capability masks - */ -#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA (1 << DIGITAL_MODE_SPDIF_RCA) -#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL (1 << DIGITAL_MODE_SPDIF_OPTICAL) -#define ECHOCAPS_HAS_DIGITAL_MODE_ADAT (1 << DIGITAL_MODE_ADAT) -#define ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM (1 << DIGITAL_MODE_SPDIF_CDROM) - - -#define EXT_3GBOX_NC 0x01 /* 3G box not connected */ -#define EXT_3GBOX_NOT_SET 0x02 /* 3G box not detected yet */ - - -#define ECHOGAIN_MUTED (-128) /* Minimum possible gain */ -#define ECHOGAIN_MINOUT (-128) /* Min output gain (dB) */ -#define ECHOGAIN_MAXOUT (6) /* Max output gain (dB) */ -#define ECHOGAIN_MININP (-50) /* Min input gain (0.5 dB) */ -#define ECHOGAIN_MAXINP (50) /* Max input gain (0.5 dB) */ - -#define PIPE_STATE_STOPPED 0 /* Pipe has been reset */ -#define PIPE_STATE_PAUSED 1 /* Pipe has been stopped */ -#define PIPE_STATE_STARTED 2 /* Pipe has been started */ -#define PIPE_STATE_PENDING 3 /* Pipe has pending start */ - - -/* Debug initialization */ -#ifdef CONFIG_SND_DEBUG -#define DE_INIT(x) snd_printk x -#else -#define DE_INIT(x) -#endif - -/* Debug hw_params callbacks */ -#ifdef CONFIG_SND_DEBUG -#define DE_HWP(x) snd_printk x -#else -#define DE_HWP(x) -#endif - -/* Debug normal activity (open, start, stop...) */ -#ifdef CONFIG_SND_DEBUG -#define DE_ACT(x) snd_printk x -#else -#define DE_ACT(x) -#endif - -/* Debug midi activity */ -#ifdef CONFIG_SND_DEBUG -#define DE_MID(x) snd_printk x -#else -#define DE_MID(x) -#endif - - -struct audiopipe { - volatile u32 *dma_counter; /* Commpage register that contains - * the current dma position - * (lower 32 bits only) - */ - u32 last_counter; /* The last position, which is used - * to compute... - */ - u32 position; /* ...the number of bytes tranferred - * by the DMA engine, modulo the - * buffer size - */ - short index; /* Index of the first channel or <0 - * if hw is not configured yet - */ - short interleave; - struct snd_dma_buffer sgpage; /* Room for the scatter-gather list */ - struct snd_pcm_hardware hw; - struct snd_pcm_hw_constraint_list constr; - short sglist_head; - char state; /* pipe state */ -}; - - -struct audioformat { - u8 interleave; /* How the data is arranged in memory: - * mono = 1, stereo = 2, ... - */ - u8 bits_per_sample; /* 8, 16, 24, 32 (24 bits left aligned) */ - char mono_to_stereo; /* Only used if interleave is 1 and - * if this is an output pipe. - */ - char data_are_bigendian; /* 1 = big endian, 0 = little endian */ -}; - - -struct echoaudio { - spinlock_t lock; - struct snd_pcm_substream *substream[DSP_MAXPIPES]; - int last_period[DSP_MAXPIPES]; - struct mutex mode_mutex; - u16 num_digital_modes, digital_mode_list[6]; - u16 num_clock_sources, clock_source_list[10]; - atomic_t opencount; - struct snd_kcontrol *clock_src_ctl; - struct snd_pcm *analog_pcm, *digital_pcm; - struct snd_card *card; - const char *card_name; - struct pci_dev *pci; - unsigned long dsp_registers_phys; - struct resource *iores; - struct snd_dma_buffer commpage_dma_buf; - int irq; -#ifdef ECHOCARD_HAS_MIDI - struct snd_rawmidi *rmidi; - struct snd_rawmidi_substream *midi_in, *midi_out; -#endif - struct timer_list timer; - char tinuse; /* Timer in use */ - char midi_full; /* MIDI output buffer is full */ - char can_set_rate; - char rate_set; - - /* This stuff is used mainly by the lowlevel code */ - struct comm_page *comm_page; /* Virtual address of the memory - * seen by DSP - */ - u32 pipe_alloc_mask; /* Bitmask of allocated pipes */ - u32 pipe_cyclic_mask; /* Bitmask of pipes with cyclic - * buffers - */ - u32 sample_rate; /* Card sample rate in Hz */ - u8 digital_mode; /* Current digital mode - * (see DIGITAL_MODE_*) - */ - u8 spdif_status; /* Gina20, Darla20, Darla24 - only */ - u8 clock_state; /* Gina20, Darla20, Darla24 - only */ - u8 input_clock; /* Currently selected sample clock - * source - */ - u8 output_clock; /* Layla20 only */ - char meters_enabled; /* VU-meters status */ - char asic_loaded; /* Set TRUE when ASIC loaded */ - char bad_board; /* Set TRUE if DSP won't load */ - char professional_spdif; /* 0 = consumer; 1 = professional */ - char non_audio_spdif; /* 3G - only */ - char digital_in_automute; /* Gina24, Layla24, Mona - only */ - char has_phantom_power; - char hasnt_input_nominal_level; /* Gina3G */ - char phantom_power; /* Gina3G - only */ - char has_midi; - char midi_input_enabled; - -#ifdef ECHOCARD_ECHO3G - /* External module -dependent pipe and bus indexes */ - char px_digital_out, px_analog_in, px_digital_in, px_num; - char bx_digital_out, bx_analog_in, bx_digital_in, bx_num; -#endif - - char nominal_level[ECHO_MAXAUDIOPIPES]; /* True == -10dBV - * False == +4dBu */ - s8 input_gain[ECHO_MAXAUDIOINPUTS]; /* Input level -50..+50 - * unit is 0.5dB */ - s8 output_gain[ECHO_MAXAUDIOOUTPUTS]; /* Output level -128..+6 dB - * (-128=muted) */ - s8 monitor_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOINPUTS]; - /* -128..+6 dB */ - s8 vmixer_gain[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS]; - /* -128..+6 dB */ - - u16 digital_modes; /* Bitmask of supported modes - * (see ECHOCAPS_HAS_DIGITAL_MODE_*) */ - u16 input_clock_types; /* Suppoted input clock types */ - u16 output_clock_types; /* Suppoted output clock types - - * Layla20 only */ - u16 device_id, subdevice_id; - u16 *dsp_code; /* Current DSP code loaded, - * NULL if nothing loaded */ - short dsp_code_to_load; /* DSP code to load */ - short asic_code; /* Current ASIC code */ - u32 comm_page_phys; /* Physical address of the - * memory seen by DSP */ - volatile u32 __iomem *dsp_registers; /* DSP's register base */ - u32 active_mask; /* Chs. active mask or - * punks out */ -#ifdef CONFIG_PM - const struct firmware *fw_cache[8]; /* Cached firmwares */ -#endif - -#ifdef ECHOCARD_HAS_MIDI - u16 mtc_state; /* State for MIDI input parsing state machine */ - u8 midi_buffer[MIDI_IN_BUFFER_SIZE]; -#endif -}; - - -static int init_dsp_comm_page(struct echoaudio *chip); -static int init_line_levels(struct echoaudio *chip); -static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe); -static int load_firmware(struct echoaudio *chip); -static int wait_handshake(struct echoaudio *chip); -static int send_vector(struct echoaudio *chip, u32 command); -static int get_firmware(const struct firmware **fw_entry, - struct echoaudio *chip, const short fw_index); -static void free_firmware(const struct firmware *fw_entry); - -#ifdef ECHOCARD_HAS_MIDI -static int enable_midi_input(struct echoaudio *chip, char enable); -static void snd_echo_midi_output_trigger( - struct snd_rawmidi_substream *substream, int up); -static int midi_service_irq(struct echoaudio *chip); -static int __devinit snd_echo_midi_create(struct snd_card *card, - struct echoaudio *chip); -#endif - - -static inline void clear_handshake(struct echoaudio *chip) -{ - chip->comm_page->handshake = 0; -} - -static inline u32 get_dsp_register(struct echoaudio *chip, u32 index) -{ - return readl(&chip->dsp_registers[index]); -} - -static inline void set_dsp_register(struct echoaudio *chip, u32 index, - u32 value) -{ - writel(value, &chip->dsp_registers[index]); -} - - -/* Pipe and bus indexes. PX_* and BX_* are defined as chip->px_* and chip->bx_* -for 3G cards because they depend on the external box. They are integer -constants for all other cards. -Never use those defines directly, use the following functions instead. */ - -static inline int px_digital_out(const struct echoaudio *chip) -{ - return PX_DIGITAL_OUT; -} - -static inline int px_analog_in(const struct echoaudio *chip) -{ - return PX_ANALOG_IN; -} - -static inline int px_digital_in(const struct echoaudio *chip) -{ - return PX_DIGITAL_IN; -} - -static inline int px_num(const struct echoaudio *chip) -{ - return PX_NUM; -} - -static inline int bx_digital_out(const struct echoaudio *chip) -{ - return BX_DIGITAL_OUT; -} - -static inline int bx_analog_in(const struct echoaudio *chip) -{ - return BX_ANALOG_IN; -} - -static inline int bx_digital_in(const struct echoaudio *chip) -{ - return BX_DIGITAL_IN; -} - -static inline int bx_num(const struct echoaudio *chip) -{ - return BX_NUM; -} - -static inline int num_pipes_out(const struct echoaudio *chip) -{ - return px_analog_in(chip); -} - -static inline int num_pipes_in(const struct echoaudio *chip) -{ - return px_num(chip) - px_analog_in(chip); -} - -static inline int num_busses_out(const struct echoaudio *chip) -{ - return bx_analog_in(chip); -} - -static inline int num_busses_in(const struct echoaudio *chip) -{ - return bx_num(chip) - bx_analog_in(chip); -} - -static inline int num_analog_busses_out(const struct echoaudio *chip) -{ - return bx_digital_out(chip); -} - -static inline int num_analog_busses_in(const struct echoaudio *chip) -{ - return bx_digital_in(chip) - bx_analog_in(chip); -} - -static inline int num_digital_busses_out(const struct echoaudio *chip) -{ - return num_busses_out(chip) - num_analog_busses_out(chip); -} - -static inline int num_digital_busses_in(const struct echoaudio *chip) -{ - return num_busses_in(chip) - num_analog_busses_in(chip); -} - -/* The monitor array is a one-dimensional array; compute the offset - * into the array */ -static inline int monitor_index(const struct echoaudio *chip, int out, int in) -{ - return out * num_busses_in(chip) + in; -} - - -#ifndef pci_device -#define pci_device(chip) (&chip->pci->dev) -#endif - - -#endif /* _ECHOAUDIO_H_ */ diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_3g.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_3g.c deleted file mode 100644 index 658db44e..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_3g.c +++ /dev/null @@ -1,432 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - - -/* These functions are common for all "3G" cards */ - - -static int check_asic_status(struct echoaudio *chip) -{ - u32 box_status; - - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->ext_box_status = cpu_to_le32(E3G_ASIC_NOT_LOADED); - chip->asic_loaded = FALSE; - clear_handshake(chip); - send_vector(chip, DSP_VC_TEST_ASIC); - - if (wait_handshake(chip)) { - chip->dsp_code = NULL; - return -EIO; - } - - box_status = le32_to_cpu(chip->comm_page->ext_box_status); - DE_INIT(("box_status=%x\n", box_status)); - if (box_status == E3G_ASIC_NOT_LOADED) - return -ENODEV; - - chip->asic_loaded = TRUE; - return box_status & E3G_BOX_TYPE_MASK; -} - - - -static inline u32 get_frq_reg(struct echoaudio *chip) -{ - return le32_to_cpu(chip->comm_page->e3g_frq_register); -} - - - -/* Most configuration of 3G cards is accomplished by writing the control -register. write_control_reg sends the new control register value to the DSP. */ -static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, - char force) -{ - if (wait_handshake(chip)) - return -EIO; - - DE_ACT(("WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq)); - - ctl = cpu_to_le32(ctl); - frq = cpu_to_le32(frq); - - if (ctl != chip->comm_page->control_register || - frq != chip->comm_page->e3g_frq_register || force) { - chip->comm_page->e3g_frq_register = frq; - chip->comm_page->control_register = ctl; - clear_handshake(chip); - return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); - } - - DE_ACT(("WriteControlReg: not written, no change\n")); - return 0; -} - - - -/* Set the digital mode - currently for Gina24, Layla24, Mona, 3G */ -static int set_digital_mode(struct echoaudio *chip, u8 mode) -{ - u8 previous_mode; - int err, i, o; - - /* All audio channels must be closed before changing the digital mode */ - if (snd_BUG_ON(chip->pipe_alloc_mask)) - return -EAGAIN; - - if (snd_BUG_ON(!(chip->digital_modes & (1 << mode)))) - return -EINVAL; - - previous_mode = chip->digital_mode; - err = dsp_set_digital_mode(chip, mode); - - /* If we successfully changed the digital mode from or to ADAT, - * then make sure all output, input and monitor levels are - * updated by the DSP comm object. */ - if (err >= 0 && previous_mode != mode && - (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { - spin_lock_irq(&chip->lock); - for (o = 0; o < num_busses_out(chip); o++) - for (i = 0; i < num_busses_in(chip); i++) - set_monitor_gain(chip, o, i, - chip->monitor_gain[o][i]); - -#ifdef ECHOCARD_HAS_INPUT_GAIN - for (i = 0; i < num_busses_in(chip); i++) - set_input_gain(chip, i, chip->input_gain[i]); - update_input_line_level(chip); -#endif - - for (o = 0; o < num_busses_out(chip); o++) - set_output_gain(chip, o, chip->output_gain[o]); - update_output_line_level(chip); - spin_unlock_irq(&chip->lock); - } - - return err; -} - - - -static u32 set_spdif_bits(struct echoaudio *chip, u32 control_reg, u32 rate) -{ - control_reg &= E3G_SPDIF_FORMAT_CLEAR_MASK; - - switch (rate) { - case 32000 : - control_reg |= E3G_SPDIF_SAMPLE_RATE0 | E3G_SPDIF_SAMPLE_RATE1; - break; - case 44100 : - if (chip->professional_spdif) - control_reg |= E3G_SPDIF_SAMPLE_RATE0; - break; - case 48000 : - control_reg |= E3G_SPDIF_SAMPLE_RATE1; - break; - } - - if (chip->professional_spdif) - control_reg |= E3G_SPDIF_PRO_MODE; - - if (chip->non_audio_spdif) - control_reg |= E3G_SPDIF_NOT_AUDIO; - - control_reg |= E3G_SPDIF_24_BIT | E3G_SPDIF_TWO_CHANNEL | - E3G_SPDIF_COPY_PERMIT; - - return control_reg; -} - - - -/* Set the S/PDIF output format */ -static int set_professional_spdif(struct echoaudio *chip, char prof) -{ - u32 control_reg; - - control_reg = le32_to_cpu(chip->comm_page->control_register); - chip->professional_spdif = prof; - control_reg = set_spdif_bits(chip, control_reg, chip->sample_rate); - return write_control_reg(chip, control_reg, get_frq_reg(chip), 0); -} - - - -/* detect_input_clocks() returns a bitmask consisting of all the input clocks -currently connected to the hardware; this changes as the user connects and -disconnects clock inputs. You should use this information to determine which -clocks the user is allowed to select. */ -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock - * detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD) - clock_bits |= ECHO_CLOCK_BIT_WORD; - - switch(chip->digital_mode) { - case DIGITAL_MODE_SPDIF_RCA: - case DIGITAL_MODE_SPDIF_OPTICAL: - if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF) - clock_bits |= ECHO_CLOCK_BIT_SPDIF; - break; - case DIGITAL_MODE_ADAT: - if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_ADAT) - clock_bits |= ECHO_CLOCK_BIT_ADAT; - break; - } - - return clock_bits; -} - - - -static int load_asic(struct echoaudio *chip) -{ - int box_type, err; - - if (chip->asic_loaded) - return 0; - - /* Give the DSP a few milliseconds to settle down */ - mdelay(2); - - err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC); - if (err < 0) - return err; - - chip->asic_code = FW_3G_ASIC; - - /* Now give the new ASIC some time to set up */ - msleep(1000); - /* See if it worked */ - box_type = check_asic_status(chip); - - /* Set up the control register if the load succeeded - - * 48 kHz, internal clock, S/PDIF RCA mode */ - if (box_type >= 0) { - err = write_control_reg(chip, E3G_48KHZ, - E3G_FREQ_REG_DEFAULT, TRUE); - if (err < 0) - return err; - } - - return box_type; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 control_reg, clock, base_rate, frq_reg; - - /* Only set the clock for internal mode. */ - if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); - /* Save the rate anyhow */ - chip->comm_page->sample_rate = cpu_to_le32(rate); - chip->sample_rate = rate; - set_input_clock(chip, chip->input_clock); - return 0; - } - - if (snd_BUG_ON(rate >= 50000 && - chip->digital_mode == DIGITAL_MODE_ADAT)) - return -EINVAL; - - clock = 0; - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= E3G_CLOCK_CLEAR_MASK; - - switch (rate) { - case 96000: - clock = E3G_96KHZ; - break; - case 88200: - clock = E3G_88KHZ; - break; - case 48000: - clock = E3G_48KHZ; - break; - case 44100: - clock = E3G_44KHZ; - break; - case 32000: - clock = E3G_32KHZ; - break; - default: - clock = E3G_CONTINUOUS_CLOCK; - if (rate > 50000) - clock |= E3G_DOUBLE_SPEED_MODE; - break; - } - - control_reg |= clock; - control_reg = set_spdif_bits(chip, control_reg, rate); - - base_rate = rate; - if (base_rate > 50000) - base_rate /= 2; - if (base_rate < 32000) - base_rate = 32000; - - frq_reg = E3G_MAGIC_NUMBER / base_rate - 2; - if (frq_reg > E3G_FREQ_REG_MAX) - frq_reg = E3G_FREQ_REG_MAX; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ - chip->sample_rate = rate; - DE_ACT(("SetSampleRate: %d clock %x\n", rate, control_reg)); - - /* Tell the DSP about it - DSP reads both control reg & freq reg */ - return write_control_reg(chip, control_reg, frq_reg, 0); -} - - - -/* Set the sample clock source to internal, S/PDIF, ADAT */ -static int set_input_clock(struct echoaudio *chip, u16 clock) -{ - u32 control_reg, clocks_from_dsp; - - DE_ACT(("set_input_clock:\n")); - - /* Mask off the clock select bits */ - control_reg = le32_to_cpu(chip->comm_page->control_register) & - E3G_CLOCK_CLEAR_MASK; - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - switch (clock) { - case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Echo3G clock to INTERNAL\n")); - chip->input_clock = ECHO_CLOCK_INTERNAL; - return set_sample_rate(chip, chip->sample_rate); - case ECHO_CLOCK_SPDIF: - if (chip->digital_mode == DIGITAL_MODE_ADAT) - return -EAGAIN; - DE_ACT(("Set Echo3G clock to SPDIF\n")); - control_reg |= E3G_SPDIF_CLOCK; - if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_SPDIF96) - control_reg |= E3G_DOUBLE_SPEED_MODE; - else - control_reg &= ~E3G_DOUBLE_SPEED_MODE; - break; - case ECHO_CLOCK_ADAT: - if (chip->digital_mode != DIGITAL_MODE_ADAT) - return -EAGAIN; - DE_ACT(("Set Echo3G clock to ADAT\n")); - control_reg |= E3G_ADAT_CLOCK; - control_reg &= ~E3G_DOUBLE_SPEED_MODE; - break; - case ECHO_CLOCK_WORD: - DE_ACT(("Set Echo3G clock to WORD\n")); - control_reg |= E3G_WORD_CLOCK; - if (clocks_from_dsp & E3G_CLOCK_DETECT_BIT_WORD96) - control_reg |= E3G_DOUBLE_SPEED_MODE; - else - control_reg &= ~E3G_DOUBLE_SPEED_MODE; - break; - default: - DE_ACT(("Input clock 0x%x not supported for Echo3G\n", clock)); - return -EINVAL; - } - - chip->input_clock = clock; - return write_control_reg(chip, control_reg, get_frq_reg(chip), 1); -} - - - -static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) -{ - u32 control_reg; - int err, incompatible_clock; - - /* Set clock to "internal" if it's not compatible with the new mode */ - incompatible_clock = FALSE; - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - case DIGITAL_MODE_SPDIF_RCA: - if (chip->input_clock == ECHO_CLOCK_ADAT) - incompatible_clock = TRUE; - break; - case DIGITAL_MODE_ADAT: - if (chip->input_clock == ECHO_CLOCK_SPDIF) - incompatible_clock = TRUE; - break; - default: - DE_ACT(("Digital mode not supported: %d\n", mode)); - return -EINVAL; - } - - spin_lock_irq(&chip->lock); - - if (incompatible_clock) { - chip->sample_rate = 48000; - set_input_clock(chip, ECHO_CLOCK_INTERNAL); - } - - /* Clear the current digital mode */ - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= E3G_DIGITAL_MODE_CLEAR_MASK; - - /* Tweak the control reg */ - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - control_reg |= E3G_SPDIF_OPTICAL_MODE; - break; - case DIGITAL_MODE_SPDIF_RCA: - /* E3G_SPDIF_OPTICAL_MODE bit cleared */ - break; - case DIGITAL_MODE_ADAT: - control_reg |= E3G_ADAT_MODE; - control_reg &= ~E3G_DOUBLE_SPEED_MODE; /* @@ useless */ - break; - } - - err = write_control_reg(chip, control_reg, get_frq_reg(chip), 1); - spin_unlock_irq(&chip->lock); - if (err < 0) - return err; - chip->digital_mode = mode; - - DE_ACT(("set_digital_mode(%d)\n", chip->digital_mode)); - return incompatible_clock; -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.c deleted file mode 100644 index d8c670c9..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.c +++ /dev/null @@ -1,1151 +0,0 @@ -/**************************************************************************** - - 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 20ms for the handshake from the DSP */ - for (i = 0; i < HANDSHAKE_TIMEOUT; i++) { - /* Look for the handshake value */ - barrier(); - if (chip->comm_page->handshake) { - 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 < 5; i++) { - if (read_dsp(chip, &sn[i])) { - snd_printk(KERN_ERR "Failed to read serial number\n"); - return -EIO; - } - } - DE_INIT(("Read serial number %08x %08x %08x %08x %08x\n", - sn[0], sn[1], sn[2], sn[3], sn[4])); - return 0; -} - - - -#ifndef ECHOCARD_HAS_ASIC -/* This card has no ASIC, just return ok */ -static inline int check_asic_status(struct echoaudio *chip) -{ - chip->asic_loaded = TRUE; - return 0; -} - -#endif /* !ECHOCARD_HAS_ASIC */ - - - -#ifdef ECHOCARD_HAS_ASIC - -/* Load ASIC code - done after the DSP is loaded */ -static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic) -{ - const struct firmware *fw; - int err; - u32 i, size; - u8 *code; - - err = get_firmware(&fw, chip, asic); - if (err < 0) { - snd_printk(KERN_WARNING "Firmware not found !\n"); - return err; - } - - code = (u8 *)fw->data; - size = fw->size; - - /* Send the "Here comes the ASIC" command */ - if (write_dsp(chip, cmd) < 0) - goto la_error; - - /* Write length of ASIC file in bytes */ - if (write_dsp(chip, size) < 0) - goto la_error; - - for (i = 0; i < size; i++) { - if (write_dsp(chip, code[i]) < 0) - goto la_error; - } - - DE_INIT(("ASIC loaded\n")); - free_firmware(fw); - return 0; - -la_error: - DE_INIT(("failed on write_dsp\n")); - free_firmware(fw); - return -EIO; -} - -#endif /* ECHOCARD_HAS_ASIC */ - - - -#ifdef DSP_56361 - -/* Install the resident loader for 56361 DSPs; The resident loader is on -the EPROM on the board for 56301 DSP. The resident loader is a tiny little -program that is used to load the real DSP code. */ -static int install_resident_loader(struct echoaudio *chip) -{ - u32 address; - int index, words, i; - u16 *code; - u32 status; - const struct firmware *fw; - - /* 56361 cards only! This check is required by the old 56301-based - Mona and Gina24 */ - if (chip->device_id != DEVICE_ID_56361) - return 0; - - /* Look to see if the resident loader is present. If the resident - loader is already installed, host flag 5 will be on. */ - status = get_dsp_register(chip, CHI32_STATUS_REG); - if (status & CHI32_STATUS_REG_HF5) { - DE_INIT(("Resident loader already installed; status is 0x%x\n", - status)); - return 0; - } - - i = get_firmware(&fw, chip, FW_361_LOADER); - if (i < 0) { - snd_printk(KERN_WARNING "Firmware not found !\n"); - return i; - } - - /* The DSP code is an array of 16 bit words. The array is divided up - into sections. The first word of each section is the size in words, - followed by the section type. - Since DSP addresses and data are 24 bits wide, they each take up two - 16 bit words in the array. - This is a lot like the other loader loop, but it's not a loop, you - don't write the memory type, and you don't write a zero at the end. */ - - /* Set DSP format bits for 24 bit mode */ - set_dsp_register(chip, CHI32_CONTROL_REG, - get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); - - code = (u16 *)fw->data; - - /* Skip the header section; the first word in the array is the size - of the first section, so the first real section of code is pointed - to by Code[0]. */ - index = code[0]; - - /* Skip the section size, LRS block type, and DSP memory type */ - index += 3; - - /* Get the number of DSP words to write */ - words = code[index++]; - - /* Get the DSP address for this block; 24 bits, so build from two words */ - address = ((u32)code[index] << 16) + code[index + 1]; - index += 2; - - /* Write the count to the DSP */ - if (write_dsp(chip, words)) { - DE_INIT(("install_resident_loader: Failed to write word count!\n")); - goto irl_error; - } - /* Write the DSP address */ - if (write_dsp(chip, address)) { - DE_INIT(("install_resident_loader: Failed to write DSP address!\n")); - goto irl_error; - } - /* Write out this block of code to the DSP */ - for (i = 0; i < words; i++) { - u32 data; - - data = ((u32)code[index] << 16) + code[index + 1]; - if (write_dsp(chip, data)) { - DE_INIT(("install_resident_loader: Failed to write DSP code\n")); - goto irl_error; - } - index += 2; - } - - /* Wait for flag 5 to come up */ - for (i = 0; i < 200; i++) { /* Timeout is 50us * 200 = 10ms */ - udelay(50); - status = get_dsp_register(chip, CHI32_STATUS_REG); - if (status & CHI32_STATUS_REG_HF5) - break; - } - - if (i == 200) { - DE_INIT(("Resident loader failed to set HF5\n")); - goto irl_error; - } - - DE_INIT(("Resident loader successfully installed\n")); - free_firmware(fw); - return 0; - -irl_error: - free_firmware(fw); - return -EIO; -} - -#endif /* DSP_56361 */ - - -static int load_dsp(struct echoaudio *chip, u16 *code) -{ - u32 address, data; - int index, words, i; - - if (chip->dsp_code == code) { - DE_INIT(("DSP is already loaded!\n")); - return 0; - } - chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ - chip->dsp_code = NULL; /* Current DSP code not loaded */ - chip->asic_loaded = FALSE; /* Loading the DSP code will reset the ASIC */ - - DE_INIT(("load_dsp: Set bad_board to TRUE\n")); - - /* If this board requires a resident loader, install it. */ -#ifdef DSP_56361 - if ((i = install_resident_loader(chip)) < 0) - return i; -#endif - - /* Send software reset command */ - if (send_vector(chip, DSP_VC_RESET) < 0) { - DE_INIT(("LoadDsp: send_vector DSP_VC_RESET failed, Critical Failure\n")); - return -EIO; - } - /* Delay 10us */ - udelay(10); - - /* Wait 10ms for HF3 to indicate that software reset is complete */ - for (i = 0; i < 1000; i++) { /* Timeout is 10us * 1000 = 10ms */ - if (get_dsp_register(chip, CHI32_STATUS_REG) & - CHI32_STATUS_REG_HF3) - break; - udelay(10); - } - - if (i == 1000) { - DE_INIT(("load_dsp: Timeout waiting for CHI32_STATUS_REG_HF3\n")); - return -EIO; - } - - /* Set DSP format bits for 24 bit mode now that soft reset is done */ - set_dsp_register(chip, CHI32_CONTROL_REG, - get_dsp_register(chip, CHI32_CONTROL_REG) | 0x900); - - /* Main loader loop */ - - index = code[0]; - for (;;) { - int block_type, mem_type; - - /* Total Block Size */ - index++; - - /* Block Type */ - block_type = code[index]; - if (block_type == 4) /* We're finished */ - break; - - index++; - - /* Memory Type P=0,X=1,Y=2 */ - mem_type = code[index++]; - - /* Block Code Size */ - words = code[index++]; - if (words == 0) /* We're finished */ - break; - - /* Start Address */ - address = ((u32)code[index] << 16) + code[index + 1]; - index += 2; - - if (write_dsp(chip, words) < 0) { - DE_INIT(("load_dsp: failed to write number of DSP words\n")); - return -EIO; - } - if (write_dsp(chip, address) < 0) { - DE_INIT(("load_dsp: failed to write DSP address\n")); - return -EIO; - } - if (write_dsp(chip, mem_type) < 0) { - DE_INIT(("load_dsp: failed to write DSP memory type\n")); - return -EIO; - } - /* Code */ - for (i = 0; i < words; i++, index+=2) { - data = ((u32)code[index] << 16) + code[index + 1]; - if (write_dsp(chip, data) < 0) { - DE_INIT(("load_dsp: failed to write DSP data\n")); - return -EIO; - } - } - } - - if (write_dsp(chip, 0) < 0) { /* We're done!!! */ - DE_INIT(("load_dsp: Failed to write final zero\n")); - return -EIO; - } - udelay(10); - - for (i = 0; i < 5000; i++) { /* Timeout is 100us * 5000 = 500ms */ - /* Wait for flag 4 - indicates that the DSP loaded OK */ - if (get_dsp_register(chip, CHI32_STATUS_REG) & - CHI32_STATUS_REG_HF4) { - set_dsp_register(chip, CHI32_CONTROL_REG, - get_dsp_register(chip, CHI32_CONTROL_REG) & ~0x1b00); - - if (write_dsp(chip, DSP_FNC_SET_COMMPAGE_ADDR) < 0) { - DE_INIT(("load_dsp: Failed to write DSP_FNC_SET_COMMPAGE_ADDR\n")); - return -EIO; - } - - if (write_dsp(chip, chip->comm_page_phys) < 0) { - DE_INIT(("load_dsp: Failed to write comm page address\n")); - return -EIO; - } - - /* Get the serial number via slave mode. - This is triggered by the SET_COMMPAGE_ADDR command. - We don't actually use the serial number but we have to - get it as part of the DSP init voodoo. */ - if (read_sn(chip) < 0) { - DE_INIT(("load_dsp: Failed to read serial number\n")); - return -EIO; - } - - chip->dsp_code = code; /* Show which DSP code loaded */ - chip->bad_board = FALSE; /* DSP OK */ - DE_INIT(("load_dsp: OK!\n")); - return 0; - } - udelay(100); - } - - DE_INIT(("load_dsp: DSP load timed out waiting for HF4\n")); - return -EIO; -} - - - -/* load_firmware takes care of loading the DSP and any ASIC code. */ -static int load_firmware(struct echoaudio *chip) -{ - const struct firmware *fw; - int box_type, err; - - if (snd_BUG_ON(!chip->comm_page)) - return -EPERM; - - /* See if the ASIC is present and working - only if the DSP is already loaded */ - if (chip->dsp_code) { - if ((box_type = check_asic_status(chip)) >= 0) - return box_type; - /* ASIC check failed; force the DSP to reload */ - chip->dsp_code = NULL; - } - - err = get_firmware(&fw, chip, chip->dsp_code_to_load); - if (err < 0) - return err; - err = load_dsp(chip, (u16 *)fw->data); - free_firmware(fw); - if (err < 0) - return err; - - if ((box_type = load_asic(chip)) < 0) - return box_type; /* error */ - - return box_type; -} - - - -/**************************************************************************** - Mixer functions - ****************************************************************************/ - -#if defined(ECHOCARD_HAS_INPUT_NOMINAL_LEVEL) || \ - defined(ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL) - -/* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */ -static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer) -{ - if (snd_BUG_ON(index >= num_busses_out(chip) + num_busses_in(chip))) - return -EINVAL; - - /* Wait for the handshake (OK even if ASIC is not loaded) */ - if (wait_handshake(chip)) - return -EIO; - - chip->nominal_level[index] = consumer; - - if (consumer) - chip->comm_page->nominal_level_mask |= cpu_to_le32(1 << index); - else - chip->comm_page->nominal_level_mask &= ~cpu_to_le32(1 << index); - - return 0; -} - -#endif /* ECHOCARD_HAS_*_NOMINAL_LEVEL */ - - - -/* Set the gain for a single physical output channel (dB). */ -static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain) -{ - if (snd_BUG_ON(channel >= num_busses_out(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - /* Save the new value */ - chip->output_gain[channel] = gain; - chip->comm_page->line_out_level[channel] = gain; - return 0; -} - - - -#ifdef ECHOCARD_HAS_MONITOR -/* Set the monitor level from an input bus to an output bus. */ -static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input, - s8 gain) -{ - if (snd_BUG_ON(output >= num_busses_out(chip) || - input >= num_busses_in(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->monitor_gain[output][input] = gain; - chip->comm_page->monitors[monitor_index(chip, output, input)] = gain; - return 0; -} -#endif /* ECHOCARD_HAS_MONITOR */ - - -/* Tell the DSP to read and update output, nominal & monitor levels in comm page. */ -static int update_output_line_level(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_OUTVOL); -} - - - -/* Tell the DSP to read and update input levels in comm page */ -static int update_input_line_level(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_INGAIN); -} - - - -/* set_meters_on turns the meters on or off. If meters are turned on, the DSP -will write the meter and clock detect values to the comm page at about 30Hz */ -static void set_meters_on(struct echoaudio *chip, char on) -{ - if (on && !chip->meters_enabled) { - send_vector(chip, DSP_VC_METERS_ON); - chip->meters_enabled = 1; - } else if (!on && chip->meters_enabled) { - send_vector(chip, DSP_VC_METERS_OFF); - chip->meters_enabled = 0; - memset((s8 *)chip->comm_page->vu_meter, ECHOGAIN_MUTED, - DSP_MAXPIPES); - memset((s8 *)chip->comm_page->peak_meter, ECHOGAIN_MUTED, - DSP_MAXPIPES); - } -} - - - -/* Fill out an the given array using the current values in the comm page. -Meters are written in the comm page by the DSP in this order: - Output busses - Input busses - Output pipes (vmixer cards only) - -This function assumes there are no more than 16 in/out busses or pipes -Meters is an array [3][16][2] of long. */ -static void get_audio_meters(struct echoaudio *chip, long *meters) -{ - int i, m, n; - - m = 0; - n = 0; - for (i = 0; i < num_busses_out(chip); i++, m++) { - meters[n++] = chip->comm_page->vu_meter[m]; - meters[n++] = chip->comm_page->peak_meter[m]; - } - for (; n < 32; n++) - meters[n] = 0; - -#ifdef ECHOCARD_ECHO3G - m = E3G_MAX_OUTPUTS; /* Skip unused meters */ -#endif - - for (i = 0; i < num_busses_in(chip); i++, m++) { - meters[n++] = chip->comm_page->vu_meter[m]; - meters[n++] = chip->comm_page->peak_meter[m]; - } - for (; n < 64; n++) - meters[n] = 0; - -#ifdef ECHOCARD_HAS_VMIXER - for (i = 0; i < num_pipes_out(chip); i++, m++) { - meters[n++] = chip->comm_page->vu_meter[m]; - meters[n++] = chip->comm_page->peak_meter[m]; - } -#endif - for (; n < 96; n++) - meters[n] = 0; -} - - - -static int restore_dsp_rettings(struct echoaudio *chip) -{ - int i, o, err; - DE_INIT(("restore_dsp_settings\n")); - - if ((err = check_asic_status(chip)) < 0) - return err; - - /* Gina20/Darla20 only. Should be harmless for other cards. */ - chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; - chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; - chip->comm_page->handshake = 0xffffffff; - - /* Restore output busses */ - for (i = 0; i < num_busses_out(chip); i++) { - err = set_output_gain(chip, i, chip->output_gain[i]); - if (err < 0) - return err; - } - -#ifdef ECHOCARD_HAS_VMIXER - for (i = 0; i < num_pipes_out(chip); i++) - for (o = 0; o < num_busses_out(chip); o++) { - err = set_vmixer_gain(chip, o, i, - chip->vmixer_gain[o][i]); - if (err < 0) - return err; - } - if (update_vmixer_level(chip) < 0) - return -EIO; -#endif /* ECHOCARD_HAS_VMIXER */ - -#ifdef ECHOCARD_HAS_MONITOR - for (o = 0; o < num_busses_out(chip); o++) - for (i = 0; i < num_busses_in(chip); i++) { - err = set_monitor_gain(chip, o, i, - chip->monitor_gain[o][i]); - if (err < 0) - return err; - } -#endif /* ECHOCARD_HAS_MONITOR */ - -#ifdef ECHOCARD_HAS_INPUT_GAIN - for (i = 0; i < num_busses_in(chip); i++) { - err = set_input_gain(chip, i, chip->input_gain[i]); - if (err < 0) - return err; - } -#endif /* ECHOCARD_HAS_INPUT_GAIN */ - - err = update_output_line_level(chip); - if (err < 0) - return err; - - err = update_input_line_level(chip); - if (err < 0) - return err; - - err = set_sample_rate(chip, chip->sample_rate); - if (err < 0) - return err; - - if (chip->meters_enabled) { - err = send_vector(chip, DSP_VC_METERS_ON); - if (err < 0) - return err; - } - -#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH - if (set_digital_mode(chip, chip->digital_mode) < 0) - return -EIO; -#endif - -#ifdef ECHOCARD_HAS_DIGITAL_IO - if (set_professional_spdif(chip, chip->professional_spdif) < 0) - return -EIO; -#endif - -#ifdef ECHOCARD_HAS_PHANTOM_POWER - if (set_phantom_power(chip, chip->phantom_power) < 0) - return -EIO; -#endif - -#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK - /* set_input_clock() also restores automute setting */ - if (set_input_clock(chip, chip->input_clock) < 0) - return -EIO; -#endif - -#ifdef ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH - if (set_output_clock(chip, chip->output_clock) < 0) - return -EIO; -#endif - - if (wait_handshake(chip) < 0) - return -EIO; - clear_handshake(chip); - if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0) - return -EIO; - - DE_INIT(("restore_dsp_rettings done\n")); - return 0; -} - - - -/**************************************************************************** - Transport functions - ****************************************************************************/ - -/* set_audio_format() sets the format of the audio data in host memory for -this pipe. Note that _MS_ (mono-to-stereo) playback modes are not used by ALSA -but they are here because they are just mono while capturing */ -static void set_audio_format(struct echoaudio *chip, u16 pipe_index, - const struct audioformat *format) -{ - u16 dsp_format; - - dsp_format = DSP_AUDIOFORM_SS_16LE; - - /* Look for super-interleave (no big-endian and 8 bits) */ - if (format->interleave > 2) { - switch (format->bits_per_sample) { - case 16: - dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE; - break; - case 24: - dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE; - break; - case 32: - dsp_format = DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE; - break; - } - dsp_format |= format->interleave; - } else if (format->data_are_bigendian) { - /* For big-endian data, only 32 bit samples are supported */ - switch (format->interleave) { - case 1: - dsp_format = DSP_AUDIOFORM_MM_32BE; - break; -#ifdef ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - case 2: - dsp_format = DSP_AUDIOFORM_SS_32BE; - break; -#endif - } - } else if (format->interleave == 1 && - format->bits_per_sample == 32 && !format->mono_to_stereo) { - /* 32 bit little-endian mono->mono case */ - dsp_format = DSP_AUDIOFORM_MM_32LE; - } else { - /* Handle the other little-endian formats */ - switch (format->bits_per_sample) { - case 8: - if (format->interleave == 2) - dsp_format = DSP_AUDIOFORM_SS_8; - else - dsp_format = DSP_AUDIOFORM_MS_8; - break; - default: - case 16: - if (format->interleave == 2) - dsp_format = DSP_AUDIOFORM_SS_16LE; - else - dsp_format = DSP_AUDIOFORM_MS_16LE; - break; - case 24: - if (format->interleave == 2) - dsp_format = DSP_AUDIOFORM_SS_24LE; - else - dsp_format = DSP_AUDIOFORM_MS_24LE; - break; - case 32: - if (format->interleave == 2) - dsp_format = DSP_AUDIOFORM_SS_32LE; - else - dsp_format = DSP_AUDIOFORM_MS_32LE; - break; - } - } - DE_ACT(("set_audio_format[%d] = %x\n", pipe_index, dsp_format)); - chip->comm_page->audio_format[pipe_index] = cpu_to_le16(dsp_format); -} - - - -/* start_transport starts transport for a set of pipes. -The bits 1 in channel_mask specify what pipes to start. Only the bit of the -first channel must be set, regardless its interleave. -Same thing for pause_ and stop_ -trasport below. */ -static int start_transport(struct echoaudio *chip, u32 channel_mask, - u32 cyclic_mask) -{ - DE_ACT(("start_transport %x\n", channel_mask)); - - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->cmd_start |= cpu_to_le32(channel_mask); - - if (chip->comm_page->cmd_start) { - clear_handshake(chip); - send_vector(chip, DSP_VC_START_TRANSFER); - if (wait_handshake(chip)) - return -EIO; - /* Keep track of which pipes are transporting */ - chip->active_mask |= channel_mask; - chip->comm_page->cmd_start = 0; - return 0; - } - - DE_ACT(("start_transport: No pipes to start!\n")); - return -EINVAL; -} - - - -static int pause_transport(struct echoaudio *chip, u32 channel_mask) -{ - DE_ACT(("pause_transport %x\n", channel_mask)); - - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); - chip->comm_page->cmd_reset = 0; - if (chip->comm_page->cmd_stop) { - clear_handshake(chip); - send_vector(chip, DSP_VC_STOP_TRANSFER); - if (wait_handshake(chip)) - return -EIO; - /* Keep track of which pipes are transporting */ - chip->active_mask &= ~channel_mask; - chip->comm_page->cmd_stop = 0; - chip->comm_page->cmd_reset = 0; - return 0; - } - - DE_ACT(("pause_transport: No pipes to stop!\n")); - return 0; -} - - - -static int stop_transport(struct echoaudio *chip, u32 channel_mask) -{ - DE_ACT(("stop_transport %x\n", channel_mask)); - - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->cmd_stop |= cpu_to_le32(channel_mask); - chip->comm_page->cmd_reset |= cpu_to_le32(channel_mask); - if (chip->comm_page->cmd_reset) { - clear_handshake(chip); - send_vector(chip, DSP_VC_STOP_TRANSFER); - if (wait_handshake(chip)) - return -EIO; - /* Keep track of which pipes are transporting */ - chip->active_mask &= ~channel_mask; - chip->comm_page->cmd_stop = 0; - chip->comm_page->cmd_reset = 0; - return 0; - } - - DE_ACT(("stop_transport: No pipes to stop!\n")); - return 0; -} - - - -static inline int is_pipe_allocated(struct echoaudio *chip, u16 pipe_index) -{ - return (chip->pipe_alloc_mask & (1 << pipe_index)); -} - - - -/* Stops everything and turns off the DSP. All pipes should be already -stopped and unallocated. */ -static int rest_in_peace(struct echoaudio *chip) -{ - DE_ACT(("rest_in_peace() open=%x\n", chip->pipe_alloc_mask)); - - /* Stops all active pipes (just to be sure) */ - stop_transport(chip, chip->active_mask); - - set_meters_on(chip, FALSE); - -#ifdef ECHOCARD_HAS_MIDI - enable_midi_input(chip, FALSE); -#endif - - /* Go to sleep */ - if (chip->dsp_code) { - /* Make load_firmware do a complete reload */ - chip->dsp_code = NULL; - /* Put the DSP to sleep */ - return send_vector(chip, DSP_VC_GO_COMATOSE); - } - return 0; -} - - - -/* Fills the comm page with default values */ -static int init_dsp_comm_page(struct echoaudio *chip) -{ - /* Check if the compiler added extra padding inside the structure */ - if (offsetof(struct comm_page, midi_output) != 0xbe0) { - DE_INIT(("init_dsp_comm_page() - Invalid struct comm_page structure\n")); - return -EPERM; - } - - /* Init all the basic stuff */ - chip->card_name = ECHOCARD_NAME; - chip->bad_board = TRUE; /* Set TRUE until DSP loaded */ - chip->dsp_code = NULL; /* Current DSP code not loaded */ - chip->asic_loaded = FALSE; - memset(chip->comm_page, 0, sizeof(struct comm_page)); - - /* Init the comm page */ - chip->comm_page->comm_size = - cpu_to_le32(sizeof(struct comm_page)); - chip->comm_page->handshake = 0xffffffff; - chip->comm_page->midi_out_free_count = - cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); - chip->comm_page->sample_rate = cpu_to_le32(44100); - - /* Set line levels so we don't blast any inputs on startup */ - memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE); - memset(chip->comm_page->vmixer, ECHOGAIN_MUTED, VMIXER_ARRAY_SIZE); - - return 0; -} - - - -/* This function initializes the chip structure with default values, ie. all - * muted and internal clock source. Then it copies the settings to the DSP. - * This MUST be called after the DSP is up and running ! - */ -static int init_line_levels(struct echoaudio *chip) -{ - DE_INIT(("init_line_levels\n")); - memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain)); - memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain)); - memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain)); - memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain)); - chip->input_clock = ECHO_CLOCK_INTERNAL; - chip->output_clock = ECHO_CLOCK_WORD; - chip->sample_rate = 44100; - return restore_dsp_rettings(chip); -} - - - -/* This is low level part of the interrupt handler. -It returns -1 if the IRQ is not ours, or N>=0 if it is, where N is the number -of midi data in the input queue. */ -static int service_irq(struct echoaudio *chip) -{ - int st; - - /* Read the DSP status register and see if this DSP generated this interrupt */ - if (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_IRQ) { - st = 0; -#ifdef ECHOCARD_HAS_MIDI - /* Get and parse midi data if present */ - if (chip->comm_page->midi_input[0]) /* The count is at index 0 */ - st = midi_service_irq(chip); /* Returns how many midi bytes we received */ -#endif - /* Clear the hardware interrupt */ - chip->comm_page->midi_input[0] = 0; - send_vector(chip, DSP_VC_ACK_INT); - return st; - } - return -1; -} - - - - -/****************************************************************************** - Functions for opening and closing pipes - ******************************************************************************/ - -/* allocate_pipes is used to reserve audio pipes for your exclusive use. -The call will fail if some pipes are already allocated. */ -static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, - int pipe_index, int interleave) -{ - int i; - u32 channel_mask; - char is_cyclic; - - DE_ACT(("allocate_pipes: ch=%d int=%d\n", pipe_index, interleave)); - - if (chip->bad_board) - return -EIO; - - is_cyclic = 1; /* This driver uses cyclic buffers only */ - - for (channel_mask = i = 0; i < interleave; i++) - channel_mask |= 1 << (pipe_index + i); - if (chip->pipe_alloc_mask & channel_mask) { - DE_ACT(("allocate_pipes: channel already open\n")); - return -EAGAIN; - } - - chip->comm_page->position[pipe_index] = 0; - chip->pipe_alloc_mask |= channel_mask; - if (is_cyclic) - chip->pipe_cyclic_mask |= channel_mask; - pipe->index = pipe_index; - pipe->interleave = interleave; - pipe->state = PIPE_STATE_STOPPED; - - /* The counter register is where the DSP writes the 32 bit DMA - position for a pipe. The DSP is constantly updating this value as - it moves data. The DMA counter is in units of bytes, not samples. */ - pipe->dma_counter = &chip->comm_page->position[pipe_index]; - *pipe->dma_counter = 0; - DE_ACT(("allocate_pipes: ok\n")); - return pipe_index; -} - - - -static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe) -{ - u32 channel_mask; - int i; - - DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); - if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index))) - return -EINVAL; - if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED)) - return -EINVAL; - - for (channel_mask = i = 0; i < pipe->interleave; i++) - channel_mask |= 1 << (pipe->index + i); - - chip->pipe_alloc_mask &= ~channel_mask; - chip->pipe_cyclic_mask &= ~channel_mask; - return 0; -} - - - -/****************************************************************************** - Functions for managing the scatter-gather list -******************************************************************************/ - -static int sglist_init(struct echoaudio *chip, struct audiopipe *pipe) -{ - pipe->sglist_head = 0; - memset(pipe->sgpage.area, 0, PAGE_SIZE); - chip->comm_page->sglist_addr[pipe->index].addr = - cpu_to_le32(pipe->sgpage.addr); - return 0; -} - - - -static int sglist_add_mapping(struct echoaudio *chip, struct audiopipe *pipe, - dma_addr_t address, size_t length) -{ - int head = pipe->sglist_head; - struct sg_entry *list = (struct sg_entry *)pipe->sgpage.area; - - if (head < MAX_SGLIST_ENTRIES - 1) { - list[head].addr = cpu_to_le32(address); - list[head].size = cpu_to_le32(length); - pipe->sglist_head++; - } else { - DE_ACT(("SGlist: too many fragments\n")); - return -ENOMEM; - } - return 0; -} - - - -static inline int sglist_add_irq(struct echoaudio *chip, struct audiopipe *pipe) -{ - return sglist_add_mapping(chip, pipe, 0, 0); -} - - - -static inline int sglist_wrap(struct echoaudio *chip, struct audiopipe *pipe) -{ - return sglist_add_mapping(chip, pipe, pipe->sgpage.addr, 0); -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.h b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.h deleted file mode 100644 index cb7d75a0..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_dsp.h +++ /dev/null @@ -1,698 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - -#ifndef _ECHO_DSP_ -#define _ECHO_DSP_ - - -/**** Echogals: Darla20, Gina20, Layla20, and Darla24 ****/ -#if defined(ECHOGALS_FAMILY) - -#define NUM_ASIC_TESTS 5 -#define READ_DSP_TIMEOUT 1000000L /* one second */ - -/**** Echo24: Gina24, Layla24, Mona, Mia, Mia-midi ****/ -#elif defined(ECHO24_FAMILY) - -#define DSP_56361 /* Some Echo24 cards use the 56361 DSP */ -#define READ_DSP_TIMEOUT 100000L /* .1 second */ - -/**** 3G: Gina3G, Layla3G ****/ -#elif defined(ECHO3G_FAMILY) - -#define DSP_56361 -#define READ_DSP_TIMEOUT 100000L /* .1 second */ -#define MIN_MTC_1X_RATE 32000 - -/**** Indigo: Indigo, Indigo IO, Indigo DJ ****/ -#elif defined(INDIGO_FAMILY) - -#define DSP_56361 -#define READ_DSP_TIMEOUT 100000L /* .1 second */ - -#else - -#error No family is defined - -#endif - - - -/* - * - * Max inputs and outputs - * - */ - -#define DSP_MAXAUDIOINPUTS 16 /* Max audio input channels */ -#define DSP_MAXAUDIOOUTPUTS 16 /* Max audio output channels */ -#define DSP_MAXPIPES 32 /* Max total pipes (input + output) */ - - -/* - * - * These are the offsets for the memory-mapped DSP registers; the DSP base - * address is treated as the start of a u32 array. - */ - -#define CHI32_CONTROL_REG 4 -#define CHI32_STATUS_REG 5 -#define CHI32_VECTOR_REG 6 -#define CHI32_DATA_REG 7 - - -/* - * - * Interesting bits within the DSP registers - * - */ - -#define CHI32_VECTOR_BUSY 0x00000001 -#define CHI32_STATUS_REG_HF3 0x00000008 -#define CHI32_STATUS_REG_HF4 0x00000010 -#define CHI32_STATUS_REG_HF5 0x00000020 -#define CHI32_STATUS_HOST_READ_FULL 0x00000004 -#define CHI32_STATUS_HOST_WRITE_EMPTY 0x00000002 -#define CHI32_STATUS_IRQ 0x00000040 - - -/* - * - * DSP commands sent via slave mode; these are sent to the DSP by write_dsp() - * - */ - -#define DSP_FNC_SET_COMMPAGE_ADDR 0x02 -#define DSP_FNC_LOAD_LAYLA_ASIC 0xa0 -#define DSP_FNC_LOAD_GINA24_ASIC 0xa0 -#define DSP_FNC_LOAD_MONA_PCI_CARD_ASIC 0xa0 -#define DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC 0xa0 -#define DSP_FNC_LOAD_MONA_EXTERNAL_ASIC 0xa1 -#define DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC 0xa1 -#define DSP_FNC_LOAD_3G_ASIC 0xa0 - - -/* - * - * Defines to handle the MIDI input state engine; these are used to properly - * extract MIDI time code bytes and their timestamps from the MIDI input stream. - * - */ - -#define MIDI_IN_STATE_NORMAL 0 -#define MIDI_IN_STATE_TS_HIGH 1 -#define MIDI_IN_STATE_TS_LOW 2 -#define MIDI_IN_STATE_F1_DATA 3 -#define MIDI_IN_SKIP_DATA (-1) - - -/*---------------------------------------------------------------------------- - -Setting the sample rates on Layla24 is somewhat schizophrenic. - -For standard rates, it works exactly like Mona and Gina24. That is, for -8, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the -appropriate bits in the control register and write the control register. - -In order to support MIDI time code sync (and possibly SMPTE LTC sync in -the future), Layla24 also has "continuous sample rate mode". In this mode, -Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or -50 to 100 kHz inclusive for double speed mode. - -To use continuous mode: - --Set the clock select bits in the control register to 0xe (see the #define - below) - --Set double-speed mode if you want to use sample rates above 50 kHz - --Write the control register as you would normally - --Now, you need to set the frequency register. First, you need to determine the - value for the frequency register. This is given by the following formula: - -frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2 - -Note the #define below for the magic number - --Wait for the DSP handshake --Write the frequency_reg value to the .SampleRate field of the comm page --Send the vector command SET_LAYLA24_FREQUENCY_REG (see vmonkey.h) - -Once you have set the control register up for continuous mode, you can just -write the frequency register to change the sample rate. This could be -used for MIDI time code sync. For MTC sync, the control register is set for -continuous mode. The driver then just keeps writing the -SET_LAYLA24_FREQUENCY_REG command. - ------------------------------------------------------------------------------*/ - -#define LAYLA24_MAGIC_NUMBER 677376000 -#define LAYLA24_CONTINUOUS_CLOCK 0x000e - - -/* - * - * DSP vector commands - * - */ - -#define DSP_VC_RESET 0x80ff - -#ifndef DSP_56361 - -#define DSP_VC_ACK_INT 0x8073 -#define DSP_VC_SET_VMIXER_GAIN 0x0000 /* Not used, only for compile */ -#define DSP_VC_START_TRANSFER 0x0075 /* Handshke rqd. */ -#define DSP_VC_METERS_ON 0x0079 -#define DSP_VC_METERS_OFF 0x007b -#define DSP_VC_UPDATE_OUTVOL 0x007d /* Handshke rqd. */ -#define DSP_VC_UPDATE_INGAIN 0x007f /* Handshke rqd. */ -#define DSP_VC_ADD_AUDIO_BUFFER 0x0081 /* Handshke rqd. */ -#define DSP_VC_TEST_ASIC 0x00eb -#define DSP_VC_UPDATE_CLOCKS 0x00ef /* Handshke rqd. */ -#define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00f1 /* Handshke rqd. */ -#define DSP_VC_SET_GD_AUDIO_STATE 0x00f1 /* Handshke rqd. */ -#define DSP_VC_WRITE_CONTROL_REG 0x00f1 /* Handshke rqd. */ -#define DSP_VC_MIDI_WRITE 0x00f5 /* Handshke rqd. */ -#define DSP_VC_STOP_TRANSFER 0x00f7 /* Handshke rqd. */ -#define DSP_VC_UPDATE_FLAGS 0x00fd /* Handshke rqd. */ -#define DSP_VC_GO_COMATOSE 0x00f9 - -#else /* !DSP_56361 */ - -/* Vector commands for families that use either the 56301 or 56361 */ -#define DSP_VC_ACK_INT 0x80F5 -#define DSP_VC_SET_VMIXER_GAIN 0x00DB /* Handshke rqd. */ -#define DSP_VC_START_TRANSFER 0x00DD /* Handshke rqd. */ -#define DSP_VC_METERS_ON 0x00EF -#define DSP_VC_METERS_OFF 0x00F1 -#define DSP_VC_UPDATE_OUTVOL 0x00E3 /* Handshke rqd. */ -#define DSP_VC_UPDATE_INGAIN 0x00E5 /* Handshke rqd. */ -#define DSP_VC_ADD_AUDIO_BUFFER 0x00E1 /* Handshke rqd. */ -#define DSP_VC_TEST_ASIC 0x00ED -#define DSP_VC_UPDATE_CLOCKS 0x00E9 /* Handshke rqd. */ -#define DSP_VC_SET_LAYLA24_FREQUENCY_REG 0x00E9 /* Handshke rqd. */ -#define DSP_VC_SET_LAYLA_SAMPLE_RATE 0x00EB /* Handshke rqd. */ -#define DSP_VC_SET_GD_AUDIO_STATE 0x00EB /* Handshke rqd. */ -#define DSP_VC_WRITE_CONTROL_REG 0x00EB /* Handshke rqd. */ -#define DSP_VC_MIDI_WRITE 0x00E7 /* Handshke rqd. */ -#define DSP_VC_STOP_TRANSFER 0x00DF /* Handshke rqd. */ -#define DSP_VC_UPDATE_FLAGS 0x00FB /* Handshke rqd. */ -#define DSP_VC_GO_COMATOSE 0x00d9 - -#endif /* !DSP_56361 */ - - -/* - * - * Timeouts - * - */ - -#define HANDSHAKE_TIMEOUT 20000 /* send_vector command timeout (20ms) */ -#define VECTOR_BUSY_TIMEOUT 100000 /* 100ms */ -#define MIDI_OUT_DELAY_USEC 2000 /* How long to wait after MIDI fills up */ - - -/* - * - * Flags for .Flags field in the comm page - * - */ - -#define DSP_FLAG_MIDI_INPUT 0x0001 /* Enable MIDI input */ -#define DSP_FLAG_SPDIF_NONAUDIO 0x0002 /* Sets the "non-audio" bit - * in the S/PDIF out status - * bits. Clear this flag for - * audio data; - * set it for AC3 or WMA or - * some such */ -#define DSP_FLAG_PROFESSIONAL_SPDIF 0x0008 /* 1 Professional, 0 Consumer */ - - -/* - * - * Clock detect bits reported by the DSP for Gina20, Layla20, Darla24, and Mia - * - */ - -#define GLDM_CLOCK_DETECT_BIT_WORD 0x0002 -#define GLDM_CLOCK_DETECT_BIT_SUPER 0x0004 -#define GLDM_CLOCK_DETECT_BIT_SPDIF 0x0008 -#define GLDM_CLOCK_DETECT_BIT_ESYNC 0x0010 - - -/* - * - * Clock detect bits reported by the DSP for Gina24, Mona, and Layla24 - * - */ - -#define GML_CLOCK_DETECT_BIT_WORD96 0x0002 -#define GML_CLOCK_DETECT_BIT_WORD48 0x0004 -#define GML_CLOCK_DETECT_BIT_SPDIF48 0x0008 -#define GML_CLOCK_DETECT_BIT_SPDIF96 0x0010 -#define GML_CLOCK_DETECT_BIT_WORD (GML_CLOCK_DETECT_BIT_WORD96 | GML_CLOCK_DETECT_BIT_WORD48) -#define GML_CLOCK_DETECT_BIT_SPDIF (GML_CLOCK_DETECT_BIT_SPDIF48 | GML_CLOCK_DETECT_BIT_SPDIF96) -#define GML_CLOCK_DETECT_BIT_ESYNC 0x0020 -#define GML_CLOCK_DETECT_BIT_ADAT 0x0040 - - -/* - * - * Layla clock numbers to send to DSP - * - */ - -#define LAYLA20_CLOCK_INTERNAL 0 -#define LAYLA20_CLOCK_SPDIF 1 -#define LAYLA20_CLOCK_WORD 2 -#define LAYLA20_CLOCK_SUPER 3 - - -/* - * - * Gina/Darla clock states - * - */ - -#define GD_CLOCK_NOCHANGE 0 -#define GD_CLOCK_44 1 -#define GD_CLOCK_48 2 -#define GD_CLOCK_SPDIFIN 3 -#define GD_CLOCK_UNDEF 0xff - - -/* - * - * Gina/Darla S/PDIF status bits - * - */ - -#define GD_SPDIF_STATUS_NOCHANGE 0 -#define GD_SPDIF_STATUS_44 1 -#define GD_SPDIF_STATUS_48 2 -#define GD_SPDIF_STATUS_UNDEF 0xff - - -/* - * - * Layla20 output clocks - * - */ - -#define LAYLA20_OUTPUT_CLOCK_SUPER 0 -#define LAYLA20_OUTPUT_CLOCK_WORD 1 - - -/**************************************************************************** - - Magic constants for the Darla24 hardware - - ****************************************************************************/ - -#define GD24_96000 0x0 -#define GD24_48000 0x1 -#define GD24_44100 0x2 -#define GD24_32000 0x3 -#define GD24_22050 0x4 -#define GD24_16000 0x5 -#define GD24_11025 0x6 -#define GD24_8000 0x7 -#define GD24_88200 0x8 -#define GD24_EXT_SYNC 0x9 - - -/* - * - * Return values from the DSP when ASIC is loaded - * - */ - -#define ASIC_ALREADY_LOADED 0x1 -#define ASIC_NOT_LOADED 0x0 - - -/* - * - * DSP Audio formats - * - * These are the audio formats that the DSP can transfer - * via input and output pipes. LE means little-endian, - * BE means big-endian. - * - * DSP_AUDIOFORM_MS_8 - * - * 8-bit mono unsigned samples. For playback, - * mono data is duplicated out the left and right channels - * of the output bus. The "MS" part of the name - * means mono->stereo. - * - * DSP_AUDIOFORM_MS_16LE - * - * 16-bit signed little-endian mono samples. Playback works - * like the previous code. - * - * DSP_AUDIOFORM_MS_24LE - * - * 24-bit signed little-endian mono samples. Data is packed - * three bytes per sample; if you had two samples 0x112233 and 0x445566 - * they would be stored in memory like this: 33 22 11 66 55 44. - * - * DSP_AUDIOFORM_MS_32LE - * - * 24-bit signed little-endian mono samples in a 32-bit - * container. In other words, each sample is a 32-bit signed - * integer, where the actual audio data is left-justified - * in the 32 bits and only the 24 most significant bits are valid. - * - * DSP_AUDIOFORM_SS_8 - * DSP_AUDIOFORM_SS_16LE - * DSP_AUDIOFORM_SS_24LE - * DSP_AUDIOFORM_SS_32LE - * - * Like the previous ones, except now with stereo interleaved - * data. "SS" means stereo->stereo. - * - * DSP_AUDIOFORM_MM_32LE - * - * Similar to DSP_AUDIOFORM_MS_32LE, except that the mono - * data is not duplicated out both the left and right outputs. - * This mode is used by the ASIO driver. Here, "MM" means - * mono->mono. - * - * DSP_AUDIOFORM_MM_32BE - * - * Just like DSP_AUDIOFORM_MM_32LE, but now the data is - * in big-endian format. - * - */ - -#define DSP_AUDIOFORM_MS_8 0 /* 8 bit mono */ -#define DSP_AUDIOFORM_MS_16LE 1 /* 16 bit mono */ -#define DSP_AUDIOFORM_MS_24LE 2 /* 24 bit mono */ -#define DSP_AUDIOFORM_MS_32LE 3 /* 32 bit mono */ -#define DSP_AUDIOFORM_SS_8 4 /* 8 bit stereo */ -#define DSP_AUDIOFORM_SS_16LE 5 /* 16 bit stereo */ -#define DSP_AUDIOFORM_SS_24LE 6 /* 24 bit stereo */ -#define DSP_AUDIOFORM_SS_32LE 7 /* 32 bit stereo */ -#define DSP_AUDIOFORM_MM_32LE 8 /* 32 bit mono->mono little-endian */ -#define DSP_AUDIOFORM_MM_32BE 9 /* 32 bit mono->mono big-endian */ -#define DSP_AUDIOFORM_SS_32BE 10 /* 32 bit stereo big endian */ -#define DSP_AUDIOFORM_INVALID 0xFF /* Invalid audio format */ - - -/* - * - * Super-interleave is defined as interleaving by 4 or more. Darla20 and Gina20 - * do not support super interleave. - * - * 16 bit, 24 bit, and 32 bit little endian samples are supported for super - * interleave. The interleave factor must be even. 16 - way interleave is the - * current maximum, so you can interleave by 4, 6, 8, 10, 12, 14, and 16. - * - * The actual format code is derived by taking the define below and or-ing with - * the interleave factor. So, 32 bit interleave by 6 is 0x86 and - * 16 bit interleave by 16 is (0x40 | 0x10) = 0x50. - * - */ - -#define DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE 0x40 -#define DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE 0xc0 -#define DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE 0x80 - - -/* - * - * Gina24, Mona, and Layla24 control register defines - * - */ - -#define GML_CONVERTER_ENABLE 0x0010 -#define GML_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, - consumer == 0 */ -#define GML_SPDIF_SAMPLE_RATE0 0x0040 -#define GML_SPDIF_SAMPLE_RATE1 0x0080 -#define GML_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, - 0 == one channel */ -#define GML_SPDIF_NOT_AUDIO 0x0200 -#define GML_SPDIF_COPY_PERMIT 0x0400 -#define GML_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ -#define GML_ADAT_MODE 0x1000 /* 1 == ADAT mode, 0 == S/PDIF mode */ -#define GML_SPDIF_OPTICAL_MODE 0x2000 /* 1 == optical mode, 0 == RCA mode */ -#define GML_SPDIF_CDROM_MODE 0x3000 /* 1 == CDROM mode, - * 0 == RCA or optical mode */ -#define GML_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, - 0 == single speed */ - -#define GML_DIGITAL_IN_AUTO_MUTE 0x800000 - -#define GML_96KHZ (0x0 | GML_DOUBLE_SPEED_MODE) -#define GML_88KHZ (0x1 | GML_DOUBLE_SPEED_MODE) -#define GML_48KHZ 0x2 -#define GML_44KHZ 0x3 -#define GML_32KHZ 0x4 -#define GML_22KHZ 0x5 -#define GML_16KHZ 0x6 -#define GML_11KHZ 0x7 -#define GML_8KHZ 0x8 -#define GML_SPDIF_CLOCK 0x9 -#define GML_ADAT_CLOCK 0xA -#define GML_WORD_CLOCK 0xB -#define GML_ESYNC_CLOCK 0xC -#define GML_ESYNCx2_CLOCK 0xD - -#define GML_CLOCK_CLEAR_MASK 0xffffbff0 -#define GML_SPDIF_RATE_CLEAR_MASK (~(GML_SPDIF_SAMPLE_RATE0|GML_SPDIF_SAMPLE_RATE1)) -#define GML_DIGITAL_MODE_CLEAR_MASK 0xffffcfff -#define GML_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f - - -/* - * - * Mia sample rate and clock setting constants - * - */ - -#define MIA_32000 0x0040 -#define MIA_44100 0x0042 -#define MIA_48000 0x0041 -#define MIA_88200 0x0142 -#define MIA_96000 0x0141 - -#define MIA_SPDIF 0x00000044 -#define MIA_SPDIF96 0x00000144 - -#define MIA_MIDI_REV 1 /* Must be Mia rev 1 for MIDI support */ - - -/* - * - * 3G register bits - * - */ - -#define E3G_CONVERTER_ENABLE 0x0010 -#define E3G_SPDIF_PRO_MODE 0x0020 /* Professional S/PDIF == 1, - consumer == 0 */ -#define E3G_SPDIF_SAMPLE_RATE0 0x0040 -#define E3G_SPDIF_SAMPLE_RATE1 0x0080 -#define E3G_SPDIF_TWO_CHANNEL 0x0100 /* 1 == two channels, - 0 == one channel */ -#define E3G_SPDIF_NOT_AUDIO 0x0200 -#define E3G_SPDIF_COPY_PERMIT 0x0400 -#define E3G_SPDIF_24_BIT 0x0800 /* 1 == 24 bit, 0 == 20 bit */ -#define E3G_DOUBLE_SPEED_MODE 0x4000 /* 1 == double speed, - 0 == single speed */ -#define E3G_PHANTOM_POWER 0x8000 /* 1 == phantom power on, - 0 == phantom power off */ - -#define E3G_96KHZ (0x0 | E3G_DOUBLE_SPEED_MODE) -#define E3G_88KHZ (0x1 | E3G_DOUBLE_SPEED_MODE) -#define E3G_48KHZ 0x2 -#define E3G_44KHZ 0x3 -#define E3G_32KHZ 0x4 -#define E3G_22KHZ 0x5 -#define E3G_16KHZ 0x6 -#define E3G_11KHZ 0x7 -#define E3G_8KHZ 0x8 -#define E3G_SPDIF_CLOCK 0x9 -#define E3G_ADAT_CLOCK 0xA -#define E3G_WORD_CLOCK 0xB -#define E3G_CONTINUOUS_CLOCK 0xE - -#define E3G_ADAT_MODE 0x1000 -#define E3G_SPDIF_OPTICAL_MODE 0x2000 - -#define E3G_CLOCK_CLEAR_MASK 0xbfffbff0 -#define E3G_DIGITAL_MODE_CLEAR_MASK 0xffffcfff -#define E3G_SPDIF_FORMAT_CLEAR_MASK 0xfffff01f - -/* Clock detect bits reported by the DSP */ -#define E3G_CLOCK_DETECT_BIT_WORD96 0x0001 -#define E3G_CLOCK_DETECT_BIT_WORD48 0x0002 -#define E3G_CLOCK_DETECT_BIT_SPDIF48 0x0004 -#define E3G_CLOCK_DETECT_BIT_ADAT 0x0004 -#define E3G_CLOCK_DETECT_BIT_SPDIF96 0x0008 -#define E3G_CLOCK_DETECT_BIT_WORD (E3G_CLOCK_DETECT_BIT_WORD96|E3G_CLOCK_DETECT_BIT_WORD48) -#define E3G_CLOCK_DETECT_BIT_SPDIF (E3G_CLOCK_DETECT_BIT_SPDIF48|E3G_CLOCK_DETECT_BIT_SPDIF96) - -/* Frequency control register */ -#define E3G_MAGIC_NUMBER 677376000 -#define E3G_FREQ_REG_DEFAULT (E3G_MAGIC_NUMBER / 48000 - 2) -#define E3G_FREQ_REG_MAX 0xffff - -/* 3G external box types */ -#define E3G_GINA3G_BOX_TYPE 0x00 -#define E3G_LAYLA3G_BOX_TYPE 0x10 -#define E3G_ASIC_NOT_LOADED 0xffff -#define E3G_BOX_TYPE_MASK 0xf0 - -/* Indigo express control register values */ -#define INDIGO_EXPRESS_32000 0x02 -#define INDIGO_EXPRESS_44100 0x01 -#define INDIGO_EXPRESS_48000 0x00 -#define INDIGO_EXPRESS_DOUBLE_SPEED 0x10 -#define INDIGO_EXPRESS_QUAD_SPEED 0x04 -#define INDIGO_EXPRESS_CLOCK_MASK 0x17 - - -/* - * - * Gina20 & Layla20 have input gain controls for the analog inputs; - * this is the magic number for the hardware that gives you 0 dB at -10. - * - */ - -#define GL20_INPUT_GAIN_MAGIC_NUMBER 0xC8 - - -/* - * - * Defines how much time must pass between DSP load attempts - * - */ - -#define DSP_LOAD_ATTEMPT_PERIOD 1000000L /* One second */ - - -/* - * - * Size of arrays for the comm page. MAX_PLAY_TAPS and MAX_REC_TAPS are - * no longer used, but the sizes must still be right for the DSP to see - * the comm page correctly. - * - */ - -#define MONITOR_ARRAY_SIZE 0x180 -#define VMIXER_ARRAY_SIZE 0x40 -#define MIDI_OUT_BUFFER_SIZE 32 -#define MIDI_IN_BUFFER_SIZE 256 -#define MAX_PLAY_TAPS 168 -#define MAX_REC_TAPS 192 -#define DSP_MIDI_OUT_FIFO_SIZE 64 - - -/* sg_entry is a single entry for the scatter-gather list. The array of struct -sg_entry struct is read by the DSP, so all values must be little-endian. */ - -#define MAX_SGLIST_ENTRIES 512 - -struct sg_entry { - u32 addr; - u32 size; -}; - - -/**************************************************************************** - - The comm page. This structure is read and written by the DSP; the - DSP code is a firm believer in the byte offsets written in the comments - at the end of each line. This structure should not be changed. - - Any reads from or writes to this structure should be in little-endian format. - - ****************************************************************************/ - -struct comm_page { /* Base Length*/ - u32 comm_size; /* size of this object 0x000 4 */ - u32 flags; /* See Appendix A below 0x004 4 */ - u32 unused; /* Unused entry 0x008 4 */ - u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */ - u32 handshake; /* DSP command handshake 0x010 4 */ - u32 cmd_start; /* Chs. to start mask 0x014 4 */ - u32 cmd_stop; /* Chs. to stop mask 0x018 4 */ - u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */ - u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */ - struct sg_entry sglist_addr[DSP_MAXPIPES]; - /* Chs. Physical sglist addrs 0x060 32*8 */ - u32 position[DSP_MAXPIPES]; - /* Positions for ea. ch. 0x160 32*4 */ - s8 vu_meter[DSP_MAXPIPES]; - /* VU meters 0x1e0 32*1 */ - s8 peak_meter[DSP_MAXPIPES]; - /* Peak meters 0x200 32*1 */ - s8 line_out_level[DSP_MAXAUDIOOUTPUTS]; - /* Output gain 0x220 16*1 */ - s8 line_in_level[DSP_MAXAUDIOINPUTS]; - /* Input gain 0x230 16*1 */ - s8 monitors[MONITOR_ARRAY_SIZE]; - /* Monitor map 0x240 0x180 */ - u32 play_coeff[MAX_PLAY_TAPS]; - /* Gina/Darla play filters - obsolete 0x3c0 168*4 */ - u32 rec_coeff[MAX_REC_TAPS]; - /* Gina/Darla record filters - obsolete 0x660 192*4 */ - u16 midi_input[MIDI_IN_BUFFER_SIZE]; - /* MIDI input data transfer buffer 0x960 256*2 */ - u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */ - u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */ - u8 gd_resampler_state; /* Should always be 3 0xb62 1 */ - u8 filler2; /* 0xb63 1 */ - u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */ - u16 input_clock; /* Chg. Input clock state 0xb68 2 */ - u16 output_clock; /* Chg. Output clock state 0xb6a 2 */ - u32 status_clocks; /* Current Input clock state 0xb6c 4 */ - u32 ext_box_status; /* External box status 0xb70 4 */ - u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */ - u32 midi_out_free_count; - /* # of bytes free in MIDI output FIFO 0xb78 4 */ - u32 unused2; /* Cyclic pipes 0xb7c 4 */ - u32 control_register; - /* Mona, Gina24, Layla24, 3G ctrl reg 0xb80 4 */ - u32 e3g_frq_register; /* 3G frequency register 0xb84 4 */ - u8 filler[24]; /* filler 0xb88 24*1 */ - s8 vmixer[VMIXER_ARRAY_SIZE]; - /* Vmixer levels 0xba0 64*1 */ - u8 midi_output[MIDI_OUT_BUFFER_SIZE]; - /* MIDI output data 0xbe0 32*1 */ -}; - -#endif /* _ECHO_DSP_ */ diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_gml.c b/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_gml.c deleted file mode 100644 index afa27333..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/echoaudio_gml.c +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -/* These functions are common for Gina24, Layla24 and Mona cards */ - - -/* ASIC status check - some cards have one or two ASICs that need to be -loaded. Once that load is complete, this function is called to see if -the load was successful. -If this load fails, it does not necessarily mean that the hardware is -defective - the external box may be disconnected or turned off. */ -static int check_asic_status(struct echoaudio *chip) -{ - u32 asic_status; - - send_vector(chip, DSP_VC_TEST_ASIC); - - /* The DSP will return a value to indicate whether or not the - ASIC is currently loaded */ - if (read_dsp(chip, &asic_status) < 0) { - DE_INIT(("check_asic_status: failed on read_dsp\n")); - chip->asic_loaded = FALSE; - return -EIO; - } - - chip->asic_loaded = (asic_status == ASIC_ALREADY_LOADED); - return chip->asic_loaded ? 0 : -EIO; -} - - - -/* Most configuration of Gina24, Layla24, or Mona is accomplished by writing -the control register. write_control_reg sends the new control register -value to the DSP. */ -static int write_control_reg(struct echoaudio *chip, u32 value, char force) -{ - /* Handle the digital input auto-mute */ - if (chip->digital_in_automute) - value |= GML_DIGITAL_IN_AUTO_MUTE; - else - value &= ~GML_DIGITAL_IN_AUTO_MUTE; - - DE_ACT(("write_control_reg: 0x%x\n", value)); - - /* Write the control register */ - value = cpu_to_le32(value); - if (value != chip->comm_page->control_register || force) { - if (wait_handshake(chip)) - return -EIO; - chip->comm_page->control_register = value; - clear_handshake(chip); - return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); - } - return 0; -} - - - -/* Gina24, Layla24, and Mona support digital input auto-mute. If the digital -input auto-mute is enabled, the DSP will only enable the digital inputs if -the card is syncing to a valid clock on the ADAT or S/PDIF inputs. -If the auto-mute is disabled, the digital inputs are enabled regardless of -what the input clock is set or what is connected. */ -static int set_input_auto_mute(struct echoaudio *chip, int automute) -{ - DE_ACT(("set_input_auto_mute %d\n", automute)); - - chip->digital_in_automute = automute; - - /* Re-set the input clock to the current value - indirectly causes - the auto-mute flag to be sent to the DSP */ - return set_input_clock(chip, chip->input_clock); -} - - - -/* S/PDIF coax / S/PDIF optical / ADAT - switch */ -static int set_digital_mode(struct echoaudio *chip, u8 mode) -{ - u8 previous_mode; - int err, i, o; - - if (chip->bad_board) - return -EIO; - - /* All audio channels must be closed before changing the digital mode */ - if (snd_BUG_ON(chip->pipe_alloc_mask)) - return -EAGAIN; - - if (snd_BUG_ON(!(chip->digital_modes & (1 << mode)))) - return -EINVAL; - - previous_mode = chip->digital_mode; - err = dsp_set_digital_mode(chip, mode); - - /* If we successfully changed the digital mode from or to ADAT, - then make sure all output, input and monitor levels are - updated by the DSP comm object. */ - if (err >= 0 && previous_mode != mode && - (previous_mode == DIGITAL_MODE_ADAT || mode == DIGITAL_MODE_ADAT)) { - spin_lock_irq(&chip->lock); - for (o = 0; o < num_busses_out(chip); o++) - for (i = 0; i < num_busses_in(chip); i++) - set_monitor_gain(chip, o, i, - chip->monitor_gain[o][i]); - -#ifdef ECHOCARD_HAS_INPUT_GAIN - for (i = 0; i < num_busses_in(chip); i++) - set_input_gain(chip, i, chip->input_gain[i]); - update_input_line_level(chip); -#endif - - for (o = 0; o < num_busses_out(chip); o++) - set_output_gain(chip, o, chip->output_gain[o]); - update_output_line_level(chip); - spin_unlock_irq(&chip->lock); - } - - return err; -} - - - -/* Set the S/PDIF output format */ -static int set_professional_spdif(struct echoaudio *chip, char prof) -{ - u32 control_reg; - int err; - - /* Clear the current S/PDIF flags */ - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= GML_SPDIF_FORMAT_CLEAR_MASK; - - /* Set the new S/PDIF flags depending on the mode */ - control_reg |= GML_SPDIF_TWO_CHANNEL | GML_SPDIF_24_BIT | - GML_SPDIF_COPY_PERMIT; - if (prof) { - /* Professional mode */ - control_reg |= GML_SPDIF_PRO_MODE; - - switch (chip->sample_rate) { - case 32000: - control_reg |= GML_SPDIF_SAMPLE_RATE0 | - GML_SPDIF_SAMPLE_RATE1; - break; - case 44100: - control_reg |= GML_SPDIF_SAMPLE_RATE0; - break; - case 48000: - control_reg |= GML_SPDIF_SAMPLE_RATE1; - break; - } - } else { - /* Consumer mode */ - switch (chip->sample_rate) { - case 32000: - control_reg |= GML_SPDIF_SAMPLE_RATE0 | - GML_SPDIF_SAMPLE_RATE1; - break; - case 48000: - control_reg |= GML_SPDIF_SAMPLE_RATE1; - break; - } - } - - if ((err = write_control_reg(chip, control_reg, FALSE))) - return err; - chip->professional_spdif = prof; - DE_ACT(("set_professional_spdif to %s\n", - prof ? "Professional" : "Consumer")); - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina20.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina20.c deleted file mode 100644 index 039125b7..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/gina20.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHOGALS_FAMILY -#define ECHOCARD_GINA20 -#define ECHOCARD_NAME "Gina20" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_INPUT_GAIN -#define ECHOCARD_HAS_DIGITAL_IO -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_ADAT FALSE - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 2 */ -#define PX_ANALOG_IN 10 /* 2 */ -#define PX_DIGITAL_IN 12 /* 2 */ -#define PX_NUM 14 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 8 */ -#define BX_DIGITAL_OUT 8 /* 2 */ -#define BX_ANALOG_IN 10 /* 2 */ -#define BX_DIGITAL_IN 12 /* 2 */ -#define BX_NUM 14 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/gina20_dsp.fw"); - -#define FW_GINA20_DSP 0 - -static const struct firmware card_fw[] = { - {0, "gina20_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, - .rate_min = 44100, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. */ -}; - - -#include "gina20_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina20_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina20_dsp.c deleted file mode 100644 index d1615a05..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/gina20_dsp.c +++ /dev/null @@ -1,220 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int set_professional_spdif(struct echoaudio *chip, char prof); -static int update_flags(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Gina20\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_GINA20_DSP; - chip->spdif_status = GD_SPDIF_STATUS_UNDEF; - chip->clock_state = GD_CLOCK_UNDEF; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | - ECHO_CLOCK_BIT_SPDIF; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - chip->professional_spdif = FALSE; - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock - detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) - clock_bits |= ECHO_CLOCK_BIT_SPDIF; - - return clock_bits; -} - - - -/* The Gina20 has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u8 clock_state, spdif_status; - - if (wait_handshake(chip)) - return -EIO; - - switch (rate) { - case 44100: - clock_state = GD_CLOCK_44; - spdif_status = GD_SPDIF_STATUS_44; - break; - case 48000: - clock_state = GD_CLOCK_48; - spdif_status = GD_SPDIF_STATUS_48; - break; - default: - clock_state = GD_CLOCK_NOCHANGE; - spdif_status = GD_SPDIF_STATUS_NOCHANGE; - break; - } - - if (chip->clock_state == clock_state) - clock_state = GD_CLOCK_NOCHANGE; - if (spdif_status == chip->spdif_status) - spdif_status = GD_SPDIF_STATUS_NOCHANGE; - - chip->comm_page->sample_rate = cpu_to_le32(rate); - chip->comm_page->gd_clock_state = clock_state; - chip->comm_page->gd_spdif_status = spdif_status; - chip->comm_page->gd_resampler_state = 3; /* magic number - should always be 3 */ - - /* Save the new audio state if it changed */ - if (clock_state != GD_CLOCK_NOCHANGE) - chip->clock_state = clock_state; - if (spdif_status != GD_SPDIF_STATUS_NOCHANGE) - chip->spdif_status = spdif_status; - chip->sample_rate = rate; - - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); -} - - - -static int set_input_clock(struct echoaudio *chip, u16 clock) -{ - DE_ACT(("set_input_clock:\n")); - - switch (clock) { - case ECHO_CLOCK_INTERNAL: - /* Reset the audio state to unknown (just in case) */ - chip->clock_state = GD_CLOCK_UNDEF; - chip->spdif_status = GD_SPDIF_STATUS_UNDEF; - set_sample_rate(chip, chip->sample_rate); - chip->input_clock = clock; - DE_ACT(("Set Gina clock to INTERNAL\n")); - break; - case ECHO_CLOCK_SPDIF: - chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN; - chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE; - clear_handshake(chip); - send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE); - chip->clock_state = GD_CLOCK_SPDIFIN; - DE_ACT(("Set Gina20 clock to SPDIF\n")); - chip->input_clock = clock; - break; - default: - return -EINVAL; - } - - return 0; -} - - - -/* Set input bus gain (one unit is 0.5dB !) */ -static int set_input_gain(struct echoaudio *chip, u16 input, int gain) -{ - if (snd_BUG_ON(input >= num_busses_in(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->input_gain[input] = gain; - gain += GL20_INPUT_GAIN_MAGIC_NUMBER; - chip->comm_page->line_in_level[input] = gain; - return 0; -} - - - -/* Tell the DSP to reread the flags from the comm page */ -static int update_flags(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_FLAGS); -} - - - -static int set_professional_spdif(struct echoaudio *chip, char prof) -{ - DE_ACT(("set_professional_spdif %d\n", prof)); - if (prof) - chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); - else - chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); - chip->professional_spdif = prof; - return update_flags(chip); -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina24.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina24.c deleted file mode 100644 index 5e966f6f..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/gina24.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHO24_FAMILY -#define ECHOCARD_GINA24 -#define ECHOCARD_NAME "Gina24" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_ASIC -#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_DIGITAL_IO -#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE -#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_ADAT 6 -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 8 */ -#define PX_ANALOG_IN 16 /* 2 */ -#define PX_DIGITAL_IN 18 /* 8 */ -#define PX_NUM 26 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 8 */ -#define BX_DIGITAL_OUT 8 /* 8 */ -#define BX_ANALOG_IN 16 /* 2 */ -#define BX_DIGITAL_IN 18 /* 8 */ -#define BX_NUM 26 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/gina24_301_dsp.fw"); -MODULE_FIRMWARE("ea/gina24_361_dsp.fw"); -MODULE_FIRMWARE("ea/gina24_301_asic.fw"); -MODULE_FIRMWARE("ea/gina24_361_asic.fw"); - -#define FW_361_LOADER 0 -#define FW_GINA24_301_DSP 1 -#define FW_GINA24_361_DSP 2 -#define FW_GINA24_301_ASIC 3 -#define FW_GINA24_361_ASIC 4 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "gina24_301_dsp.fw"}, - {0, "gina24_361_dsp.fw"}, - {0, "gina24_301_asic.fw"}, - {0, "gina24_361_asic.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */ - {0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */ - {0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */ - {0x1057, 0x3410, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56361 Gina24 rev.1 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_8000_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 8000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. - 220 ~= (512 - 1 - (BUFFER_BYTES_MAX / PAGE_SIZE)) / 2 */ -}; - -#include "gina24_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio_gml.c" -#include "echoaudio.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/gina24_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/gina24_dsp.c deleted file mode 100644 index 98f7cfa8..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/gina24_dsp.c +++ /dev/null @@ -1,349 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int write_control_reg(struct echoaudio *chip, u32 value, char force); -static int set_input_clock(struct echoaudio *chip, u16 clock); -static int set_professional_spdif(struct echoaudio *chip, char prof); -static int set_digital_mode(struct echoaudio *chip, u8 mode); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); -static int check_asic_status(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Gina24\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->input_clock_types = - ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | - ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 | - ECHO_CLOCK_BIT_ADAT; - - /* Gina24 comes in both '301 and '361 flavors */ - if (chip->device_id == DEVICE_ID_56361) { - chip->dsp_code_to_load = FW_GINA24_361_DSP; - chip->digital_modes = - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | - ECHOCAPS_HAS_DIGITAL_MODE_ADAT; - } else { - chip->dsp_code_to_load = FW_GINA24_301_DSP; - chip->digital_modes = - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | - ECHOCAPS_HAS_DIGITAL_MODE_ADAT | - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_CDROM; - } - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; - chip->professional_spdif = FALSE; - chip->digital_in_automute = TRUE; - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock - detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) - clock_bits |= ECHO_CLOCK_BIT_SPDIF; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) - clock_bits |= ECHO_CLOCK_BIT_ADAT; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ESYNC) - clock_bits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96; - - return clock_bits; -} - - - -/* Gina24 has an ASIC on the PCI card which must be loaded for anything -interesting to happen. */ -static int load_asic(struct echoaudio *chip) -{ - u32 control_reg; - int err; - short asic; - - if (chip->asic_loaded) - return 1; - - /* Give the DSP a few milliseconds to settle down */ - mdelay(10); - - /* Pick the correct ASIC for '301 or '361 Gina24 */ - if (chip->device_id == DEVICE_ID_56361) - asic = FW_GINA24_361_ASIC; - else - asic = FW_GINA24_301_ASIC; - - err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic); - if (err < 0) - return err; - - chip->asic_code = asic; - - /* Now give the new ASIC a little time to set up */ - mdelay(10); - /* See if it worked */ - err = check_asic_status(chip); - - /* Set up the control register if the load succeeded - - 48 kHz, internal clock, S/PDIF RCA mode */ - if (!err) { - control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; - err = write_control_reg(chip, control_reg, TRUE); - } - DE_INIT(("load_asic() done\n")); - return err; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 control_reg, clock; - - if (snd_BUG_ON(rate >= 50000 && - chip->digital_mode == DIGITAL_MODE_ADAT)) - return -EINVAL; - - /* Only set the clock for internal mode. */ - if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); - /* Save the rate anyhow */ - chip->comm_page->sample_rate = cpu_to_le32(rate); - chip->sample_rate = rate; - return 0; - } - - clock = 0; - - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; - - switch (rate) { - case 96000: - clock = GML_96KHZ; - break; - case 88200: - clock = GML_88KHZ; - break; - case 48000: - clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; - break; - case 44100: - clock = GML_44KHZ; - /* Professional mode ? */ - if (control_reg & GML_SPDIF_PRO_MODE) - clock |= GML_SPDIF_SAMPLE_RATE0; - break; - case 32000: - clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | - GML_SPDIF_SAMPLE_RATE1; - break; - case 22050: - clock = GML_22KHZ; - break; - case 16000: - clock = GML_16KHZ; - break; - case 11025: - clock = GML_11KHZ; - break; - case 8000: - clock = GML_8KHZ; - break; - default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); - return -EINVAL; - } - - control_reg |= clock; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ - chip->sample_rate = rate; - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); - - return write_control_reg(chip, control_reg, FALSE); -} - - - -static int set_input_clock(struct echoaudio *chip, u16 clock) -{ - u32 control_reg, clocks_from_dsp; - - DE_ACT(("set_input_clock:\n")); - - /* Mask off the clock select bits */ - control_reg = le32_to_cpu(chip->comm_page->control_register) & - GML_CLOCK_CLEAR_MASK; - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - switch (clock) { - case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Gina24 clock to INTERNAL\n")); - chip->input_clock = ECHO_CLOCK_INTERNAL; - return set_sample_rate(chip, chip->sample_rate); - case ECHO_CLOCK_SPDIF: - if (chip->digital_mode == DIGITAL_MODE_ADAT) - return -EAGAIN; - DE_ACT(("Set Gina24 clock to SPDIF\n")); - control_reg |= GML_SPDIF_CLOCK; - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) - control_reg |= GML_DOUBLE_SPEED_MODE; - else - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - case ECHO_CLOCK_ADAT: - if (chip->digital_mode != DIGITAL_MODE_ADAT) - return -EAGAIN; - DE_ACT(("Set Gina24 clock to ADAT\n")); - control_reg |= GML_ADAT_CLOCK; - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - case ECHO_CLOCK_ESYNC: - DE_ACT(("Set Gina24 clock to ESYNC\n")); - control_reg |= GML_ESYNC_CLOCK; - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - case ECHO_CLOCK_ESYNC96: - DE_ACT(("Set Gina24 clock to ESYNC96\n")); - control_reg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; - break; - default: - DE_ACT(("Input clock 0x%x not supported for Gina24\n", clock)); - return -EINVAL; - } - - chip->input_clock = clock; - return write_control_reg(chip, control_reg, TRUE); -} - - - -static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) -{ - u32 control_reg; - int err, incompatible_clock; - - /* Set clock to "internal" if it's not compatible with the new mode */ - incompatible_clock = FALSE; - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - case DIGITAL_MODE_SPDIF_CDROM: - case DIGITAL_MODE_SPDIF_RCA: - if (chip->input_clock == ECHO_CLOCK_ADAT) - incompatible_clock = TRUE; - break; - case DIGITAL_MODE_ADAT: - if (chip->input_clock == ECHO_CLOCK_SPDIF) - incompatible_clock = TRUE; - break; - default: - DE_ACT(("Digital mode not supported: %d\n", mode)); - return -EINVAL; - } - - spin_lock_irq(&chip->lock); - - if (incompatible_clock) { /* Switch to 48KHz, internal */ - chip->sample_rate = 48000; - set_input_clock(chip, ECHO_CLOCK_INTERNAL); - } - - /* Clear the current digital mode */ - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; - - /* Tweak the control reg */ - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - control_reg |= GML_SPDIF_OPTICAL_MODE; - break; - case DIGITAL_MODE_SPDIF_CDROM: - /* '361 Gina24 cards do not have the S/PDIF CD-ROM mode */ - if (chip->device_id == DEVICE_ID_56301) - control_reg |= GML_SPDIF_CDROM_MODE; - break; - case DIGITAL_MODE_SPDIF_RCA: - /* GML_SPDIF_OPTICAL_MODE bit cleared */ - break; - case DIGITAL_MODE_ADAT: - control_reg |= GML_ADAT_MODE; - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - } - - err = write_control_reg(chip, control_reg, TRUE); - spin_unlock_irq(&chip->lock); - if (err < 0) - return err; - chip->digital_mode = mode; - - DE_ACT(("set_digital_mode to %d\n", chip->digital_mode)); - return incompatible_clock; -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigo.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigo.c deleted file mode 100644 index c166b7ee..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigo.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define INDIGO_FAMILY -#define ECHOCARD_INDIGO -#define ECHOCARD_NAME "Indigo" -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_VMIXER -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 0 */ -#define PX_DIGITAL_IN 8 /* 0 */ -#define PX_NUM 8 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 2 */ -#define BX_DIGITAL_OUT 2 /* 0 */ -#define BX_ANALOG_IN 2 /* 0 */ -#define BX_DIGITAL_IN 2 /* 0 */ -#define BX_NUM 2 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/indigo_dsp.fw"); - -#define FW_361_LOADER 0 -#define FW_INDIGO_DSP 1 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "indigo_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 32000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, -}; - -#include "indigo_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigo_dsp.c deleted file mode 100644 index 5e85f14f..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_dsp.c +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain); -static int update_vmixer_level(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Indigo\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_INDIGO_DSP; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - return ECHO_CLOCK_BIT_INTERNAL; -} - - - -/* The Indigo has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 control_reg; - - switch (rate) { - case 96000: - control_reg = MIA_96000; - break; - case 88200: - control_reg = MIA_88200; - break; - case 48000: - control_reg = MIA_48000; - break; - case 44100: - control_reg = MIA_44100; - break; - case 32000: - control_reg = MIA_32000; - break; - default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); - return -EINVAL; - } - - /* Set the control register if it has changed */ - if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ - chip->comm_page->control_register = cpu_to_le32(control_reg); - chip->sample_rate = rate; - - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_CLOCKS); - } - return 0; -} - - - -/* This function routes the sound from a virtual channel to a real output */ -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain) -{ - int index; - - if (snd_BUG_ON(pipe >= num_pipes_out(chip) || - output >= num_busses_out(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->vmixer_gain[output][pipe] = gain; - index = output * num_pipes_out(chip) + pipe; - chip->comm_page->vmixer[index] = gain; - - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); - return 0; -} - - - -/* Tell the DSP to read and update virtual mixer levels in comm page. */ -static int update_vmixer_level(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); -} - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_express_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigo_express_dsp.c deleted file mode 100644 index 2e4ab3e3..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigo_express_dsp.c +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************************************ - -This file is part of Echo Digital Audio's generic driver library. -Copyright Echo Digital Audio Corporation (c) 1998 - 2005 -All rights reserved -www.echoaudio.com - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; 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> - -*************************************************************************/ - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 clock, control_reg, old_control_reg; - - if (wait_handshake(chip)) - return -EIO; - - old_control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg = old_control_reg & ~INDIGO_EXPRESS_CLOCK_MASK; - - switch (rate) { - case 32000: - clock = INDIGO_EXPRESS_32000; - break; - case 44100: - clock = INDIGO_EXPRESS_44100; - break; - case 48000: - clock = INDIGO_EXPRESS_48000; - break; - case 64000: - clock = INDIGO_EXPRESS_32000|INDIGO_EXPRESS_DOUBLE_SPEED; - break; - case 88200: - clock = INDIGO_EXPRESS_44100|INDIGO_EXPRESS_DOUBLE_SPEED; - break; - case 96000: - clock = INDIGO_EXPRESS_48000|INDIGO_EXPRESS_DOUBLE_SPEED; - break; - default: - return -EINVAL; - } - - control_reg |= clock; - if (control_reg != old_control_reg) { - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); - chip->comm_page->control_register = cpu_to_le32(control_reg); - chip->sample_rate = rate; - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_CLOCKS); - } - return 0; -} - - - -/* This function routes the sound from a virtual channel to a real output */ -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain) -{ - int index; - - if (snd_BUG_ON(pipe >= num_pipes_out(chip) || - output >= num_busses_out(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->vmixer_gain[output][pipe] = gain; - index = output * num_pipes_out(chip) + pipe; - chip->comm_page->vmixer[index] = gain; - - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); - return 0; -} - - - -/* Tell the DSP to read and update virtual mixer levels in comm page. */ -static int update_vmixer_level(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - return ECHO_CLOCK_BIT_INTERNAL; -} - - - -/* The IndigoIO has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodj.c deleted file mode 100644 index a3ef3b99..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define INDIGO_FAMILY -#define ECHOCARD_INDIGO_DJ -#define ECHOCARD_NAME "Indigo DJ" -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_VMIXER -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 0 */ -#define PX_DIGITAL_IN 8 /* 0 */ -#define PX_NUM 8 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 4 */ -#define BX_DIGITAL_OUT 4 /* 0 */ -#define BX_ANALOG_IN 4 /* 0 */ -#define BX_DIGITAL_IN 4 /* 0 */ -#define BX_NUM 4 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/indigo_dj_dsp.fw"); - -#define FW_361_LOADER 0 -#define FW_INDIGO_DJ_DSP 1 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "indigo_dj_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 32000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 4, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, -}; - -#include "indigodj_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodj_dsp.c deleted file mode 100644 index 68f3c8cc..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodj_dsp.c +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain); -static int update_vmixer_level(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Indigo DJ\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_INDIGO_DJ_DSP; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - return ECHO_CLOCK_BIT_INTERNAL; -} - - - -/* The IndigoDJ has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 control_reg; - - switch (rate) { - case 96000: - control_reg = MIA_96000; - break; - case 88200: - control_reg = MIA_88200; - break; - case 48000: - control_reg = MIA_48000; - break; - case 44100: - control_reg = MIA_44100; - break; - case 32000: - control_reg = MIA_32000; - break; - default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); - return -EINVAL; - } - - /* Set the control register if it has changed */ - if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ - chip->comm_page->control_register = cpu_to_le32(control_reg); - chip->sample_rate = rate; - - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_CLOCKS); - } - return 0; -} - - - -/* This function routes the sound from a virtual channel to a real output */ -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain) -{ - int index; - - if (snd_BUG_ON(pipe >= num_pipes_out(chip) || - output >= num_busses_out(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->vmixer_gain[output][pipe] = gain; - index = output * num_pipes_out(chip) + pipe; - chip->comm_page->vmixer[index] = gain; - - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); - return 0; -} - - - -/* Tell the DSP to read and update virtual mixer levels in comm page. */ -static int update_vmixer_level(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); -} - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx.c deleted file mode 100644 index f516444f..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2009 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define INDIGO_FAMILY -#define ECHOCARD_INDIGO_DJX -#define ECHOCARD_NAME "Indigo DJx" -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_VMIXER -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 0 */ -#define PX_DIGITAL_IN 8 /* 0 */ -#define PX_NUM 8 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 4 */ -#define BX_DIGITAL_OUT 4 /* 0 */ -#define BX_ANALOG_IN 4 /* 0 */ -#define BX_DIGITAL_IN 4 /* 0 */ -#define BX_NUM 4 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/indigo_djx_dsp.fw"); - -#define FW_361_LOADER 0 -#define FW_INDIGO_DJX_DSP 1 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "indigo_djx_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_64000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 32000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 4, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, -}; - -#include "indigodjx_dsp.c" -#include "indigo_express_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx_dsp.c deleted file mode 100644 index bb9632c7..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigodjx_dsp.c +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************ - -This file is part of Echo Digital Audio's generic driver library. -Copyright Echo Digital Audio Corporation (c) 1998 - 2005 -All rights reserved -www.echoaudio.com - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; 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> - -*************************************************************************/ - -static int update_vmixer_level(struct echoaudio *chip); -static int set_vmixer_gain(struct echoaudio *chip, u16 output, - u16 pipe, int gain); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Indigo DJx\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJX)) - return -ENODEV; - - err = init_dsp_comm_page(chip); - if (err < 0) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_INDIGO_DJX_DSP; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; - - err = load_firmware(chip); - if (err < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoio.c deleted file mode 100644 index c22c82fd..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define INDIGO_FAMILY -#define ECHOCARD_INDIGO_IO -#define ECHOCARD_NAME "Indigo IO" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_VMIXER -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 2 */ -#define PX_DIGITAL_IN 10 /* 0 */ -#define PX_NUM 10 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 2 */ -#define BX_DIGITAL_OUT 2 /* 0 */ -#define BX_ANALOG_IN 2 /* 2 */ -#define BX_DIGITAL_IN 4 /* 0 */ -#define BX_NUM 4 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/indigo_io_dsp.fw"); - -#define FW_361_LOADER 0 -#define FW_INDIGO_IO_DSP 1 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "indigo_io_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 32000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, -}; - -#include "indigoio_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoio_dsp.c deleted file mode 100644 index beb9a5b6..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoio_dsp.c +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain); -static int update_vmixer_level(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Indigo IO\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_INDIGO_IO_DSP; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - return ECHO_CLOCK_BIT_INTERNAL; -} - - - -/* The IndigoIO has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - if (wait_handshake(chip)) - return -EIO; - - chip->sample_rate = rate; - chip->comm_page->sample_rate = cpu_to_le32(rate); - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_CLOCKS); -} - - - -/* This function routes the sound from a virtual channel to a real output */ -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain) -{ - int index; - - if (snd_BUG_ON(pipe >= num_pipes_out(chip) || - output >= num_busses_out(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->vmixer_gain[output][pipe] = gain; - index = output * num_pipes_out(chip) + pipe; - chip->comm_page->vmixer[index] = gain; - - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); - return 0; -} - - - -/* Tell the DSP to read and update virtual mixer levels in comm page. */ -static int update_vmixer_level(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); -} - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox.c deleted file mode 100644 index 86cf2d07..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2009 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define INDIGO_FAMILY -#define ECHOCARD_INDIGO_IOX -#define ECHOCARD_NAME "Indigo IOx" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_VMIXER -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 2 */ -#define PX_DIGITAL_IN 10 /* 0 */ -#define PX_NUM 10 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 2 */ -#define BX_DIGITAL_OUT 2 /* 0 */ -#define BX_ANALOG_IN 2 /* 2 */ -#define BX_DIGITAL_IN 4 /* 0 */ -#define BX_NUM 4 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/indigo_iox_dsp.fw"); - -#define FW_361_LOADER 0 -#define FW_INDIGO_IOX_DSP 1 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "indigo_iox_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_64000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 32000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, -}; - -#include "indigoiox_dsp.c" -#include "indigo_express_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox_dsp.c deleted file mode 100644 index 394c6e76..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/indigoiox_dsp.c +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************ - -This file is part of Echo Digital Audio's generic driver library. -Copyright Echo Digital Audio Corporation (c) 1998 - 2005 -All rights reserved -www.echoaudio.com - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; 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> - -*************************************************************************/ - -static int update_vmixer_level(struct echoaudio *chip); -static int set_vmixer_gain(struct echoaudio *chip, u16 output, - u16 pipe, int gain); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Indigo IOx\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IOX)) - return -ENODEV; - - err = init_dsp_comm_page(chip); - if (err < 0) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_INDIGO_IOX_DSP; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL; - - err = load_firmware(chip); - if (err < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla20.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla20.c deleted file mode 100644 index 6a027f39..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/layla20.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHOGALS_FAMILY -#define ECHOCARD_LAYLA20 -#define ECHOCARD_NAME "Layla20" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_ASIC -#define ECHOCARD_HAS_INPUT_GAIN -#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_DIGITAL_IO -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_ADAT FALSE -#define ECHOCARD_HAS_OUTPUT_CLOCK_SWITCH -#define ECHOCARD_HAS_MIDI - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 10 */ -#define PX_DIGITAL_OUT 10 /* 2 */ -#define PX_ANALOG_IN 12 /* 8 */ -#define PX_DIGITAL_IN 20 /* 2 */ -#define PX_NUM 22 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 10 */ -#define BX_DIGITAL_OUT 10 /* 2 */ -#define BX_ANALOG_IN 12 /* 8 */ -#define BX_DIGITAL_IN 20 /* 2 */ -#define BX_NUM 22 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <sound/rawmidi.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/layla20_dsp.fw"); -MODULE_FIRMWARE("ea/layla20_asic.fw"); - -#define FW_LAYLA20_DSP 0 -#define FW_LAYLA20_ASIC 1 - -static const struct firmware card_fw[] = { - {0, "layla20_dsp.fw"}, - {0, "layla20_asic.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */ - {0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, - .rate_min = 8000, - .rate_max = 50000, - .channels_min = 1, - .channels_max = 10, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. */ -}; - -#include "layla20_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" -#include "midi.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla20_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla20_dsp.c deleted file mode 100644 index 53ce9460..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/layla20_dsp.c +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int read_dsp(struct echoaudio *chip, u32 *data); -static int set_professional_spdif(struct echoaudio *chip, char prof); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); -static int check_asic_status(struct echoaudio *chip); -static int update_flags(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Layla20\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->has_midi = TRUE; - chip->dsp_code_to_load = FW_LAYLA20_DSP; - chip->input_clock_types = - ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | - ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; - chip->output_clock_types = - ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - chip->professional_spdif = FALSE; - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) - clock_bits |= ECHO_CLOCK_BIT_SPDIF; - - if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_WORD) { - if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SUPER) - clock_bits |= ECHO_CLOCK_BIT_SUPER; - else - clock_bits |= ECHO_CLOCK_BIT_WORD; - } - - return clock_bits; -} - - - -/* ASIC status check - some cards have one or two ASICs that need to be -loaded. Once that load is complete, this function is called to see if -the load was successful. -If this load fails, it does not necessarily mean that the hardware is -defective - the external box may be disconnected or turned off. -This routine sometimes fails for Layla20; for Layla20, the loop runs -5 times and succeeds if it wins on three of the loops. */ -static int check_asic_status(struct echoaudio *chip) -{ - u32 asic_status; - int goodcnt, i; - - chip->asic_loaded = FALSE; - for (i = goodcnt = 0; i < 5; i++) { - send_vector(chip, DSP_VC_TEST_ASIC); - - /* The DSP will return a value to indicate whether or not - the ASIC is currently loaded */ - if (read_dsp(chip, &asic_status) < 0) { - DE_ACT(("check_asic_status: failed on read_dsp\n")); - return -EIO; - } - - if (asic_status == ASIC_ALREADY_LOADED) { - if (++goodcnt == 3) { - chip->asic_loaded = TRUE; - return 0; - } - } - } - return -EIO; -} - - - -/* Layla20 has an ASIC in the external box */ -static int load_asic(struct echoaudio *chip) -{ - int err; - - if (chip->asic_loaded) - return 0; - - err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC, - FW_LAYLA20_ASIC); - if (err < 0) - return err; - - /* Check if ASIC is alive and well. */ - return check_asic_status(chip); -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - if (snd_BUG_ON(rate < 8000 || rate > 50000)) - return -EINVAL; - - /* Only set the clock for internal mode. Do not return failure, - simply treat it as a non-event. */ - if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); - chip->comm_page->sample_rate = cpu_to_le32(rate); - chip->sample_rate = rate; - return 0; - } - - if (wait_handshake(chip)) - return -EIO; - - DE_ACT(("set_sample_rate(%d)\n", rate)); - chip->sample_rate = rate; - chip->comm_page->sample_rate = cpu_to_le32(rate); - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_LAYLA_SAMPLE_RATE); -} - - - -static int set_input_clock(struct echoaudio *chip, u16 clock_source) -{ - u16 clock; - u32 rate; - - DE_ACT(("set_input_clock:\n")); - rate = 0; - switch (clock_source) { - case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Layla20 clock to INTERNAL\n")); - rate = chip->sample_rate; - clock = LAYLA20_CLOCK_INTERNAL; - break; - case ECHO_CLOCK_SPDIF: - DE_ACT(("Set Layla20 clock to SPDIF\n")); - clock = LAYLA20_CLOCK_SPDIF; - break; - case ECHO_CLOCK_WORD: - DE_ACT(("Set Layla20 clock to WORD\n")); - clock = LAYLA20_CLOCK_WORD; - break; - case ECHO_CLOCK_SUPER: - DE_ACT(("Set Layla20 clock to SUPER\n")); - clock = LAYLA20_CLOCK_SUPER; - break; - default: - DE_ACT(("Input clock 0x%x not supported for Layla24\n", - clock_source)); - return -EINVAL; - } - chip->input_clock = clock_source; - - chip->comm_page->input_clock = cpu_to_le16(clock); - clear_handshake(chip); - send_vector(chip, DSP_VC_UPDATE_CLOCKS); - - if (rate) - set_sample_rate(chip, rate); - - return 0; -} - - - -static int set_output_clock(struct echoaudio *chip, u16 clock) -{ - DE_ACT(("set_output_clock: %d\n", clock)); - switch (clock) { - case ECHO_CLOCK_SUPER: - clock = LAYLA20_OUTPUT_CLOCK_SUPER; - break; - case ECHO_CLOCK_WORD: - clock = LAYLA20_OUTPUT_CLOCK_WORD; - break; - default: - DE_ACT(("set_output_clock wrong clock\n")); - return -EINVAL; - } - - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->output_clock = cpu_to_le16(clock); - chip->output_clock = clock; - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_CLOCKS); -} - - - -/* Set input bus gain (one unit is 0.5dB !) */ -static int set_input_gain(struct echoaudio *chip, u16 input, int gain) -{ - if (snd_BUG_ON(input >= num_busses_in(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->input_gain[input] = gain; - gain += GL20_INPUT_GAIN_MAGIC_NUMBER; - chip->comm_page->line_in_level[input] = gain; - return 0; -} - - - -/* Tell the DSP to reread the flags from the comm page */ -static int update_flags(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_FLAGS); -} - - - -static int set_professional_spdif(struct echoaudio *chip, char prof) -{ - DE_ACT(("set_professional_spdif %d\n", prof)); - if (prof) - chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); - else - chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); - chip->professional_spdif = prof; - return update_flags(chip); -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla24.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla24.c deleted file mode 100644 index 96a5991a..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/layla24.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHO24_FAMILY -#define ECHOCARD_LAYLA24 -#define ECHOCARD_NAME "Layla24" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_ASIC -#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_DIGITAL_IO -#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE -#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_ADAT 6 -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 -#define ECHOCARD_HAS_MIDI - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 8 */ -#define PX_ANALOG_IN 16 /* 8 */ -#define PX_DIGITAL_IN 24 /* 8 */ -#define PX_NUM 32 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 8 */ -#define BX_DIGITAL_OUT 8 /* 8 */ -#define BX_ANALOG_IN 16 /* 8 */ -#define BX_DIGITAL_IN 24 /* 8 */ -#define BX_NUM 32 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <sound/rawmidi.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/layla24_dsp.fw"); -MODULE_FIRMWARE("ea/layla24_1_asic.fw"); -MODULE_FIRMWARE("ea/layla24_2A_asic.fw"); -MODULE_FIRMWARE("ea/layla24_2S_asic.fw"); - -#define FW_361_LOADER 0 -#define FW_LAYLA24_DSP 1 -#define FW_LAYLA24_1_ASIC 2 -#define FW_LAYLA24_2A_ASIC 3 -#define FW_LAYLA24_2S_ASIC 4 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "layla24_dsp.fw"}, - {0, "layla24_1_asic.fw"}, - {0, "layla24_2A_asic.fw"}, - {0, "layla24_2S_asic.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_8000_96000, - .rate_min = 8000, - .rate_max = 100000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. */ -}; - - -#include "layla24_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio_gml.c" -#include "echoaudio.c" -#include "midi.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/layla24_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/layla24_dsp.c deleted file mode 100644 index 8c041647..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/layla24_dsp.c +++ /dev/null @@ -1,398 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int write_control_reg(struct echoaudio *chip, u32 value, char force); -static int set_input_clock(struct echoaudio *chip, u16 clock); -static int set_professional_spdif(struct echoaudio *chip, char prof); -static int set_digital_mode(struct echoaudio *chip, u8 mode); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); -static int check_asic_status(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Layla24\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->has_midi = TRUE; - chip->dsp_code_to_load = FW_LAYLA24_DSP; - chip->input_clock_types = - ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | - ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; - chip->digital_modes = - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | - ECHOCAPS_HAS_DIGITAL_MODE_ADAT; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - if ((err = init_line_levels(chip)) < 0) - return err; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; - chip->professional_spdif = FALSE; - chip->digital_in_automute = TRUE; - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) - clock_bits |= ECHO_CLOCK_BIT_SPDIF; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) - clock_bits |= ECHO_CLOCK_BIT_ADAT; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) - clock_bits |= ECHO_CLOCK_BIT_WORD; - - return clock_bits; -} - - - -/* Layla24 has an ASIC on the PCI card and another ASIC in the external box; -both need to be loaded. */ -static int load_asic(struct echoaudio *chip) -{ - int err; - - if (chip->asic_loaded) - return 1; - - DE_INIT(("load_asic\n")); - - /* Give the DSP a few milliseconds to settle down */ - mdelay(10); - - /* Load the ASIC for the PCI card */ - err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC, - FW_LAYLA24_1_ASIC); - if (err < 0) - return err; - - chip->asic_code = FW_LAYLA24_2S_ASIC; - - /* Now give the new ASIC a little time to set up */ - mdelay(10); - - /* Do the external one */ - err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, - FW_LAYLA24_2S_ASIC); - if (err < 0) - return FALSE; - - /* Now give the external ASIC a little time to set up */ - mdelay(10); - - /* See if it worked */ - err = check_asic_status(chip); - - /* Set up the control register if the load succeeded - - 48 kHz, internal clock, S/PDIF RCA mode */ - if (!err) - err = write_control_reg(chip, GML_CONVERTER_ENABLE | GML_48KHZ, - TRUE); - - DE_INIT(("load_asic() done\n")); - return err; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 control_reg, clock, base_rate; - - if (snd_BUG_ON(rate >= 50000 && - chip->digital_mode == DIGITAL_MODE_ADAT)) - return -EINVAL; - - /* Only set the clock for internal mode. */ - if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); - /* Save the rate anyhow */ - chip->comm_page->sample_rate = cpu_to_le32(rate); - chip->sample_rate = rate; - return 0; - } - - /* Get the control register & clear the appropriate bits */ - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= GML_CLOCK_CLEAR_MASK & GML_SPDIF_RATE_CLEAR_MASK; - - clock = 0; - - switch (rate) { - case 96000: - clock = GML_96KHZ; - break; - case 88200: - clock = GML_88KHZ; - break; - case 48000: - clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; - break; - case 44100: - clock = GML_44KHZ; - /* Professional mode */ - if (control_reg & GML_SPDIF_PRO_MODE) - clock |= GML_SPDIF_SAMPLE_RATE0; - break; - case 32000: - clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | - GML_SPDIF_SAMPLE_RATE1; - break; - case 22050: - clock = GML_22KHZ; - break; - case 16000: - clock = GML_16KHZ; - break; - case 11025: - clock = GML_11KHZ; - break; - case 8000: - clock = GML_8KHZ; - break; - default: - /* If this is a non-standard rate, then the driver needs to - use Layla24's special "continuous frequency" mode */ - clock = LAYLA24_CONTINUOUS_CLOCK; - if (rate > 50000) { - base_rate = rate >> 1; - control_reg |= GML_DOUBLE_SPEED_MODE; - } else { - base_rate = rate; - } - - if (base_rate < 25000) - base_rate = 25000; - - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->sample_rate = - cpu_to_le32(LAYLA24_MAGIC_NUMBER / base_rate - 2); - - clear_handshake(chip); - send_vector(chip, DSP_VC_SET_LAYLA24_FREQUENCY_REG); - } - - control_reg |= clock; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP ? */ - chip->sample_rate = rate; - DE_ACT(("set_sample_rate: %d clock %d\n", rate, control_reg)); - - return write_control_reg(chip, control_reg, FALSE); -} - - - -static int set_input_clock(struct echoaudio *chip, u16 clock) -{ - u32 control_reg, clocks_from_dsp; - - /* Mask off the clock select bits */ - control_reg = le32_to_cpu(chip->comm_page->control_register) & - GML_CLOCK_CLEAR_MASK; - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - /* Pick the new clock */ - switch (clock) { - case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Layla24 clock to INTERNAL\n")); - chip->input_clock = ECHO_CLOCK_INTERNAL; - return set_sample_rate(chip, chip->sample_rate); - case ECHO_CLOCK_SPDIF: - if (chip->digital_mode == DIGITAL_MODE_ADAT) - return -EAGAIN; - control_reg |= GML_SPDIF_CLOCK; - /* Layla24 doesn't support 96KHz S/PDIF */ - control_reg &= ~GML_DOUBLE_SPEED_MODE; - DE_ACT(("Set Layla24 clock to SPDIF\n")); - break; - case ECHO_CLOCK_WORD: - control_reg |= GML_WORD_CLOCK; - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) - control_reg |= GML_DOUBLE_SPEED_MODE; - else - control_reg &= ~GML_DOUBLE_SPEED_MODE; - DE_ACT(("Set Layla24 clock to WORD\n")); - break; - case ECHO_CLOCK_ADAT: - if (chip->digital_mode != DIGITAL_MODE_ADAT) - return -EAGAIN; - control_reg |= GML_ADAT_CLOCK; - control_reg &= ~GML_DOUBLE_SPEED_MODE; - DE_ACT(("Set Layla24 clock to ADAT\n")); - break; - default: - DE_ACT(("Input clock 0x%x not supported for Layla24\n", clock)); - return -EINVAL; - } - - chip->input_clock = clock; - return write_control_reg(chip, control_reg, TRUE); -} - - - -/* Depending on what digital mode you want, Layla24 needs different ASICs -loaded. This function checks the ASIC needed for the new mode and sees -if it matches the one already loaded. */ -static int switch_asic(struct echoaudio *chip, short asic) -{ - s8 *monitors; - - /* Check to see if this is already loaded */ - if (asic != chip->asic_code) { - monitors = kmemdup(chip->comm_page->monitors, - MONITOR_ARRAY_SIZE, GFP_KERNEL); - if (! monitors) - return -ENOMEM; - - memset(chip->comm_page->monitors, ECHOGAIN_MUTED, - MONITOR_ARRAY_SIZE); - - /* Load the desired ASIC */ - if (load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC, - asic) < 0) { - memcpy(chip->comm_page->monitors, monitors, - MONITOR_ARRAY_SIZE); - kfree(monitors); - return -EIO; - } - chip->asic_code = asic; - memcpy(chip->comm_page->monitors, monitors, MONITOR_ARRAY_SIZE); - kfree(monitors); - } - - return 0; -} - - - -static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) -{ - u32 control_reg; - int err, incompatible_clock; - short asic; - - /* Set clock to "internal" if it's not compatible with the new mode */ - incompatible_clock = FALSE; - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - case DIGITAL_MODE_SPDIF_RCA: - if (chip->input_clock == ECHO_CLOCK_ADAT) - incompatible_clock = TRUE; - asic = FW_LAYLA24_2S_ASIC; - break; - case DIGITAL_MODE_ADAT: - if (chip->input_clock == ECHO_CLOCK_SPDIF) - incompatible_clock = TRUE; - asic = FW_LAYLA24_2A_ASIC; - break; - default: - DE_ACT(("Digital mode not supported: %d\n", mode)); - return -EINVAL; - } - - if (incompatible_clock) { /* Switch to 48KHz, internal */ - chip->sample_rate = 48000; - spin_lock_irq(&chip->lock); - set_input_clock(chip, ECHO_CLOCK_INTERNAL); - spin_unlock_irq(&chip->lock); - } - - /* switch_asic() can sleep */ - if (switch_asic(chip, asic) < 0) - return -EIO; - - spin_lock_irq(&chip->lock); - - /* Tweak the control register */ - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; - - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - control_reg |= GML_SPDIF_OPTICAL_MODE; - break; - case DIGITAL_MODE_SPDIF_RCA: - /* GML_SPDIF_OPTICAL_MODE bit cleared */ - break; - case DIGITAL_MODE_ADAT: - control_reg |= GML_ADAT_MODE; - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - } - - err = write_control_reg(chip, control_reg, TRUE); - spin_unlock_irq(&chip->lock); - if (err < 0) - return err; - chip->digital_mode = mode; - - DE_ACT(("set_digital_mode to %d\n", mode)); - return incompatible_clock; -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mia.c b/ANDROID_3.4.5/sound/pci/echoaudio/mia.c deleted file mode 100644 index b8ce27e6..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/mia.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHO24_FAMILY -#define ECHOCARD_MIA -#define ECHOCARD_NAME "Mia" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_INPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_OUTPUT_NOMINAL_LEVEL -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_VMIXER -#define ECHOCARD_HAS_DIGITAL_IO -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_ADAT FALSE -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 -#define ECHOCARD_HAS_MIDI -#define ECHOCARD_HAS_LINE_OUT_GAIN - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 8 */ -#define PX_DIGITAL_OUT 8 /* 0 */ -#define PX_ANALOG_IN 8 /* 2 */ -#define PX_DIGITAL_IN 10 /* 2 */ -#define PX_NUM 12 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 2 */ -#define BX_DIGITAL_OUT 2 /* 2 */ -#define BX_ANALOG_IN 4 /* 2 */ -#define BX_DIGITAL_IN 6 /* 2 */ -#define BX_NUM 8 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <sound/rawmidi.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/mia_dsp.fw"); - -#define FW_361_LOADER 0 -#define FW_MIA_DSP 1 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "mia_dsp.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */ - {0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 8000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. */ -}; - - -#include "mia_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio.c" -#include "midi.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mia_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/mia_dsp.c deleted file mode 100644 index 6ebfa6e7..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/mia_dsp.c +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int set_input_clock(struct echoaudio *chip, u16 clock); -static int set_professional_spdif(struct echoaudio *chip, char prof); -static int update_flags(struct echoaudio *chip); -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain); -static int update_vmixer_level(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Mia\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->dsp_code_to_load = FW_MIA_DSP; - /* Since this card has no ASIC, mark it as loaded so everything - works OK */ - chip->asic_loaded = TRUE; - if ((subdevice_id & 0x0000f) == MIA_MIDI_REV) - chip->has_midi = TRUE; - chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | - ECHO_CLOCK_BIT_SPDIF; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock - detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF) - clock_bits |= ECHO_CLOCK_BIT_SPDIF; - - return clock_bits; -} - - - -/* The Mia has no ASIC. Just do nothing */ -static int load_asic(struct echoaudio *chip) -{ - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 control_reg; - - switch (rate) { - case 96000: - control_reg = MIA_96000; - break; - case 88200: - control_reg = MIA_88200; - break; - case 48000: - control_reg = MIA_48000; - break; - case 44100: - control_reg = MIA_44100; - break; - case 32000: - control_reg = MIA_32000; - break; - default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); - return -EINVAL; - } - - /* Override the clock setting if this Mia is set to S/PDIF clock */ - if (chip->input_clock == ECHO_CLOCK_SPDIF) - control_reg |= MIA_SPDIF; - - /* Set the control register if it has changed */ - if (control_reg != le32_to_cpu(chip->comm_page->control_register)) { - if (wait_handshake(chip)) - return -EIO; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ - chip->comm_page->control_register = cpu_to_le32(control_reg); - chip->sample_rate = rate; - - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_CLOCKS); - } - return 0; -} - - - -static int set_input_clock(struct echoaudio *chip, u16 clock) -{ - DE_ACT(("set_input_clock(%d)\n", clock)); - if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL && - clock != ECHO_CLOCK_SPDIF)) - return -EINVAL; - - chip->input_clock = clock; - return set_sample_rate(chip, chip->sample_rate); -} - - - -/* This function routes the sound from a virtual channel to a real output */ -static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, - int gain) -{ - int index; - - if (snd_BUG_ON(pipe >= num_pipes_out(chip) || - output >= num_busses_out(chip))) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - chip->vmixer_gain[output][pipe] = gain; - index = output * num_pipes_out(chip) + pipe; - chip->comm_page->vmixer[index] = gain; - - DE_ACT(("set_vmixer_gain: pipe %d, out %d = %d\n", pipe, output, gain)); - return 0; -} - - - -/* Tell the DSP to read and update virtual mixer levels in comm page. */ -static int update_vmixer_level(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_SET_VMIXER_GAIN); -} - - - -/* Tell the DSP to reread the flags from the comm page */ -static int update_flags(struct echoaudio *chip) -{ - if (wait_handshake(chip)) - return -EIO; - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_FLAGS); -} - - - -static int set_professional_spdif(struct echoaudio *chip, char prof) -{ - DE_ACT(("set_professional_spdif %d\n", prof)); - if (prof) - chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); - else - chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF); - chip->professional_spdif = prof; - return update_flags(chip); -} - diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/midi.c b/ANDROID_3.4.5/sound/pci/echoaudio/midi.c deleted file mode 100644 index a953d142..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/midi.c +++ /dev/null @@ -1,331 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -/****************************************************************************** - MIDI lowlevel code -******************************************************************************/ - -/* Start and stop Midi input */ -static int enable_midi_input(struct echoaudio *chip, char enable) -{ - DE_MID(("enable_midi_input(%d)\n", enable)); - - if (wait_handshake(chip)) - return -EIO; - - if (enable) { - chip->mtc_state = MIDI_IN_STATE_NORMAL; - chip->comm_page->flags |= - cpu_to_le32(DSP_FLAG_MIDI_INPUT); - } else - chip->comm_page->flags &= - ~cpu_to_le32(DSP_FLAG_MIDI_INPUT); - - clear_handshake(chip); - return send_vector(chip, DSP_VC_UPDATE_FLAGS); -} - - - -/* Send a buffer full of MIDI data to the DSP -Returns how many actually written or < 0 on error */ -static int write_midi(struct echoaudio *chip, u8 *data, int bytes) -{ - if (snd_BUG_ON(bytes <= 0 || bytes >= MIDI_OUT_BUFFER_SIZE)) - return -EINVAL; - - if (wait_handshake(chip)) - return -EIO; - - /* HF4 indicates that it is safe to write MIDI output data */ - if (! (get_dsp_register(chip, CHI32_STATUS_REG) & CHI32_STATUS_REG_HF4)) - return 0; - - chip->comm_page->midi_output[0] = bytes; - memcpy(&chip->comm_page->midi_output[1], data, bytes); - chip->comm_page->midi_out_free_count = 0; - clear_handshake(chip); - send_vector(chip, DSP_VC_MIDI_WRITE); - DE_MID(("write_midi: %d\n", bytes)); - return bytes; -} - - - -/* Run the state machine for MIDI input data -MIDI time code sync isn't supported by this code right now, but you still need -this state machine to parse the incoming MIDI data stream. Every time the DSP -sees a 0xF1 byte come in, it adds the DSP sample position to the MIDI data -stream. The DSP sample position is represented as a 32 bit unsigned value, -with the high 16 bits first, followed by the low 16 bits. Since these aren't -real MIDI bytes, the following logic is needed to skip them. */ -static inline int mtc_process_data(struct echoaudio *chip, short midi_byte) -{ - switch (chip->mtc_state) { - case MIDI_IN_STATE_NORMAL: - if (midi_byte == 0xF1) - chip->mtc_state = MIDI_IN_STATE_TS_HIGH; - break; - case MIDI_IN_STATE_TS_HIGH: - chip->mtc_state = MIDI_IN_STATE_TS_LOW; - return MIDI_IN_SKIP_DATA; - break; - case MIDI_IN_STATE_TS_LOW: - chip->mtc_state = MIDI_IN_STATE_F1_DATA; - return MIDI_IN_SKIP_DATA; - break; - case MIDI_IN_STATE_F1_DATA: - chip->mtc_state = MIDI_IN_STATE_NORMAL; - break; - } - return 0; -} - - - -/* This function is called from the IRQ handler and it reads the midi data -from the DSP's buffer. It returns the number of bytes received. */ -static int midi_service_irq(struct echoaudio *chip) -{ - short int count, midi_byte, i, received; - - /* The count is at index 0, followed by actual data */ - count = le16_to_cpu(chip->comm_page->midi_input[0]); - - if (snd_BUG_ON(count >= MIDI_IN_BUFFER_SIZE)) - return 0; - - /* Get the MIDI data from the comm page */ - i = 1; - received = 0; - for (i = 1; i <= count; i++) { - /* Get the MIDI byte */ - midi_byte = le16_to_cpu(chip->comm_page->midi_input[i]); - - /* Parse the incoming MIDI stream. The incoming MIDI data - consists of MIDI bytes and timestamps for the MIDI time code - 0xF1 bytes. mtc_process_data() is a little state machine that - parses the stream. If you get MIDI_IN_SKIP_DATA back, then - this is a timestamp byte, not a MIDI byte, so don't store it - in the MIDI input buffer. */ - if (mtc_process_data(chip, midi_byte) == MIDI_IN_SKIP_DATA) - continue; - - chip->midi_buffer[received++] = (u8)midi_byte; - } - - return received; -} - - - - -/****************************************************************************** - MIDI interface -******************************************************************************/ - -static int snd_echo_midi_input_open(struct snd_rawmidi_substream *substream) -{ - struct echoaudio *chip = substream->rmidi->private_data; - - chip->midi_in = substream; - DE_MID(("rawmidi_iopen\n")); - return 0; -} - - - -static void snd_echo_midi_input_trigger(struct snd_rawmidi_substream *substream, - int up) -{ - struct echoaudio *chip = substream->rmidi->private_data; - - if (up != chip->midi_input_enabled) { - spin_lock_irq(&chip->lock); - enable_midi_input(chip, up); - spin_unlock_irq(&chip->lock); - chip->midi_input_enabled = up; - } -} - - - -static int snd_echo_midi_input_close(struct snd_rawmidi_substream *substream) -{ - struct echoaudio *chip = substream->rmidi->private_data; - - chip->midi_in = NULL; - DE_MID(("rawmidi_iclose\n")); - return 0; -} - - - -static int snd_echo_midi_output_open(struct snd_rawmidi_substream *substream) -{ - struct echoaudio *chip = substream->rmidi->private_data; - - chip->tinuse = 0; - chip->midi_full = 0; - chip->midi_out = substream; - DE_MID(("rawmidi_oopen\n")); - return 0; -} - - - -static void snd_echo_midi_output_write(unsigned long data) -{ - struct echoaudio *chip = (struct echoaudio *)data; - unsigned long flags; - int bytes, sent, time; - unsigned char buf[MIDI_OUT_BUFFER_SIZE - 1]; - - DE_MID(("snd_echo_midi_output_write\n")); - /* No interrupts are involved: we have to check at regular intervals - if the card's output buffer has room for new data. */ - sent = bytes = 0; - spin_lock_irqsave(&chip->lock, flags); - chip->midi_full = 0; - if (!snd_rawmidi_transmit_empty(chip->midi_out)) { - bytes = snd_rawmidi_transmit_peek(chip->midi_out, buf, - MIDI_OUT_BUFFER_SIZE - 1); - DE_MID(("Try to send %d bytes...\n", bytes)); - sent = write_midi(chip, buf, bytes); - if (sent < 0) { - snd_printk(KERN_ERR "write_midi() error %d\n", sent); - /* retry later */ - sent = 9000; - chip->midi_full = 1; - } else if (sent > 0) { - DE_MID(("%d bytes sent\n", sent)); - snd_rawmidi_transmit_ack(chip->midi_out, sent); - } else { - /* Buffer is full. DSP's internal buffer is 64 (128 ?) - bytes long. Let's wait until half of them are sent */ - DE_MID(("Full\n")); - sent = 32; - chip->midi_full = 1; - } - } - - /* We restart the timer only if there is some data left to send */ - if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) { - /* The timer will expire slightly after the data has been - sent */ - time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */ - mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000); - DE_MID(("Timer armed(%d)\n", ((time * HZ + 999) / 1000))); - } - spin_unlock_irqrestore(&chip->lock, flags); -} - - - -static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream, - int up) -{ - struct echoaudio *chip = substream->rmidi->private_data; - - DE_MID(("snd_echo_midi_output_trigger(%d)\n", up)); - spin_lock_irq(&chip->lock); - if (up) { - if (!chip->tinuse) { - init_timer(&chip->timer); - chip->timer.function = snd_echo_midi_output_write; - chip->timer.data = (unsigned long)chip; - chip->tinuse = 1; - } - } else { - if (chip->tinuse) { - chip->tinuse = 0; - spin_unlock_irq(&chip->lock); - del_timer_sync(&chip->timer); - DE_MID(("Timer removed\n")); - return; - } - } - spin_unlock_irq(&chip->lock); - - if (up && !chip->midi_full) - snd_echo_midi_output_write((unsigned long)chip); -} - - - -static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream) -{ - struct echoaudio *chip = substream->rmidi->private_data; - - chip->midi_out = NULL; - DE_MID(("rawmidi_oclose\n")); - return 0; -} - - - -static struct snd_rawmidi_ops snd_echo_midi_input = { - .open = snd_echo_midi_input_open, - .close = snd_echo_midi_input_close, - .trigger = snd_echo_midi_input_trigger, -}; - -static struct snd_rawmidi_ops snd_echo_midi_output = { - .open = snd_echo_midi_output_open, - .close = snd_echo_midi_output_close, - .trigger = snd_echo_midi_output_trigger, -}; - - - -/* <--snd_echo_probe() */ -static int __devinit snd_echo_midi_create(struct snd_card *card, - struct echoaudio *chip) -{ - int err; - - if ((err = snd_rawmidi_new(card, card->shortname, 0, 1, 1, - &chip->rmidi)) < 0) - return err; - - strcpy(chip->rmidi->name, card->shortname); - chip->rmidi->private_data = chip; - - snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_INPUT, - &snd_echo_midi_input); - snd_rawmidi_set_ops(chip->rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, - &snd_echo_midi_output); - - chip->rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | - SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; - DE_INIT(("MIDI ok\n")); - return 0; -} diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mona.c b/ANDROID_3.4.5/sound/pci/echoaudio/mona.c deleted file mode 100644 index 1283bfb2..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/mona.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * ALSA driver for Echoaudio soundcards. - * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> - * - * This program 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; version 2 of the License. - * - * 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. - */ - -#define ECHO24_FAMILY -#define ECHOCARD_MONA -#define ECHOCARD_NAME "Mona" -#define ECHOCARD_HAS_MONITOR -#define ECHOCARD_HAS_ASIC -#define ECHOCARD_HAS_SUPER_INTERLEAVE -#define ECHOCARD_HAS_DIGITAL_IO -#define ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE -#define ECHOCARD_HAS_DIGITAL_MODE_SWITCH -#define ECHOCARD_HAS_EXTERNAL_CLOCK -#define ECHOCARD_HAS_ADAT 6 -#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 - -/* Pipe indexes */ -#define PX_ANALOG_OUT 0 /* 6 */ -#define PX_DIGITAL_OUT 6 /* 8 */ -#define PX_ANALOG_IN 14 /* 4 */ -#define PX_DIGITAL_IN 18 /* 8 */ -#define PX_NUM 26 - -/* Bus indexes */ -#define BX_ANALOG_OUT 0 /* 6 */ -#define BX_DIGITAL_OUT 6 /* 8 */ -#define BX_ANALOG_IN 14 /* 4 */ -#define BX_DIGITAL_IN 18 /* 8 */ -#define BX_NUM 26 - - -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <sound/core.h> -#include <sound/info.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/asoundef.h> -#include <sound/initval.h> -#include <asm/io.h> -#include <linux/atomic.h> -#include "echoaudio.h" - -MODULE_FIRMWARE("ea/loader_dsp.fw"); -MODULE_FIRMWARE("ea/mona_301_dsp.fw"); -MODULE_FIRMWARE("ea/mona_361_dsp.fw"); -MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw"); -MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw"); -MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw"); -MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw"); -MODULE_FIRMWARE("ea/mona_2_asic.fw"); - -#define FW_361_LOADER 0 -#define FW_MONA_301_DSP 1 -#define FW_MONA_361_DSP 2 -#define FW_MONA_301_1_ASIC48 3 -#define FW_MONA_301_1_ASIC96 4 -#define FW_MONA_361_1_ASIC48 5 -#define FW_MONA_361_1_ASIC96 6 -#define FW_MONA_2_ASIC 7 - -static const struct firmware card_fw[] = { - {0, "loader_dsp.fw"}, - {0, "mona_301_dsp.fw"}, - {0, "mona_361_dsp.fw"}, - {0, "mona_301_1_asic_48.fw"}, - {0, "mona_301_1_asic_96.fw"}, - {0, "mona_361_1_asic_48.fw"}, - {0, "mona_361_1_asic_96.fw"}, - {0, "mona_2_asic.fw"} -}; - -static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = { - {0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */ - {0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */ - {0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */ - {0x1057, 0x3410, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56361 Mona rev.0 */ - {0x1057, 0x3410, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56361 Mona rev.1 */ - {0x1057, 0x3410, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56361 Mona rev.2 */ - {0,} -}; - -static struct snd_pcm_hardware pcm_hardware_skel = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, - .formats = SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_3LE | - SNDRV_PCM_FMTBIT_S32_LE | - SNDRV_PCM_FMTBIT_S32_BE, - .rates = SNDRV_PCM_RATE_8000_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000, - .rate_min = 8000, - .rate_max = 96000, - .channels_min = 1, - .channels_max = 8, - .buffer_bytes_max = 262144, - .period_bytes_min = 32, - .period_bytes_max = 131072, - .periods_min = 2, - .periods_max = 220, - /* One page (4k) contains 512 instructions. I don't know if the hw - supports lists longer than this. In this case periods_max=220 is a - safe limit to make sure the list never exceeds 512 instructions. */ -}; - - -#include "mona_dsp.c" -#include "echoaudio_dsp.c" -#include "echoaudio_gml.c" -#include "echoaudio.c" diff --git a/ANDROID_3.4.5/sound/pci/echoaudio/mona_dsp.c b/ANDROID_3.4.5/sound/pci/echoaudio/mona_dsp.c deleted file mode 100644 index 6e6a7eb5..00000000 --- a/ANDROID_3.4.5/sound/pci/echoaudio/mona_dsp.c +++ /dev/null @@ -1,427 +0,0 @@ -/**************************************************************************** - - 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> - -****************************************************************************/ - - -static int write_control_reg(struct echoaudio *chip, u32 value, char force); -static int set_input_clock(struct echoaudio *chip, u16 clock); -static int set_professional_spdif(struct echoaudio *chip, char prof); -static int set_digital_mode(struct echoaudio *chip, u8 mode); -static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic); -static int check_asic_status(struct echoaudio *chip); - - -static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) -{ - int err; - - DE_INIT(("init_hw() - Mona\n")); - if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA)) - return -ENODEV; - - if ((err = init_dsp_comm_page(chip))) { - DE_INIT(("init_hw - could not initialize DSP comm page\n")); - return err; - } - - chip->device_id = device_id; - chip->subdevice_id = subdevice_id; - chip->bad_board = TRUE; - chip->input_clock_types = - ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF | - ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT; - chip->digital_modes = - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | - ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | - ECHOCAPS_HAS_DIGITAL_MODE_ADAT; - - /* Mona comes in both '301 and '361 flavors */ - if (chip->device_id == DEVICE_ID_56361) - chip->dsp_code_to_load = FW_MONA_361_DSP; - else - chip->dsp_code_to_load = FW_MONA_301_DSP; - - if ((err = load_firmware(chip)) < 0) - return err; - chip->bad_board = FALSE; - - DE_INIT(("init_hw done\n")); - return err; -} - - - -static int set_mixer_defaults(struct echoaudio *chip) -{ - chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; - chip->professional_spdif = FALSE; - chip->digital_in_automute = TRUE; - return init_line_levels(chip); -} - - - -static u32 detect_input_clocks(const struct echoaudio *chip) -{ - u32 clocks_from_dsp, clock_bits; - - /* Map the DSP clock detect bits to the generic driver clock - detect bits */ - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - clock_bits = ECHO_CLOCK_BIT_INTERNAL; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF) - clock_bits |= ECHO_CLOCK_BIT_SPDIF; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_ADAT) - clock_bits |= ECHO_CLOCK_BIT_ADAT; - - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD) - clock_bits |= ECHO_CLOCK_BIT_WORD; - - return clock_bits; -} - - - -/* Mona has an ASIC on the PCI card and another ASIC in the external box; -both need to be loaded. */ -static int load_asic(struct echoaudio *chip) -{ - u32 control_reg; - int err; - short asic; - - if (chip->asic_loaded) - return 0; - - mdelay(10); - - if (chip->device_id == DEVICE_ID_56361) - asic = FW_MONA_361_1_ASIC48; - else - asic = FW_MONA_301_1_ASIC48; - - err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic); - if (err < 0) - return err; - - chip->asic_code = asic; - mdelay(10); - - /* Do the external one */ - err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC, - FW_MONA_2_ASIC); - if (err < 0) - return err; - - mdelay(10); - err = check_asic_status(chip); - - /* Set up the control register if the load succeeded - - 48 kHz, internal clock, S/PDIF RCA mode */ - if (!err) { - control_reg = GML_CONVERTER_ENABLE | GML_48KHZ; - err = write_control_reg(chip, control_reg, TRUE); - } - - return err; -} - - - -/* Depending on what digital mode you want, Mona needs different ASICs -loaded. This function checks the ASIC needed for the new mode and sees -if it matches the one already loaded. */ -static int switch_asic(struct echoaudio *chip, char double_speed) -{ - int err; - short asic; - - /* Check the clock detect bits to see if this is - a single-speed clock or a double-speed clock; load - a new ASIC if necessary. */ - if (chip->device_id == DEVICE_ID_56361) { - if (double_speed) - asic = FW_MONA_361_1_ASIC96; - else - asic = FW_MONA_361_1_ASIC48; - } else { - if (double_speed) - asic = FW_MONA_301_1_ASIC96; - else - asic = FW_MONA_301_1_ASIC48; - } - - if (asic != chip->asic_code) { - /* Load the desired ASIC */ - err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, - asic); - if (err < 0) - return err; - chip->asic_code = asic; - } - - return 0; -} - - - -static int set_sample_rate(struct echoaudio *chip, u32 rate) -{ - u32 control_reg, clock; - short asic; - char force_write; - - /* Only set the clock for internal mode. */ - if (chip->input_clock != ECHO_CLOCK_INTERNAL) { - DE_ACT(("set_sample_rate: Cannot set sample rate - " - "clock not set to CLK_CLOCKININTERNAL\n")); - /* Save the rate anyhow */ - chip->comm_page->sample_rate = cpu_to_le32(rate); - chip->sample_rate = rate; - return 0; - } - - /* Now, check to see if the required ASIC is loaded */ - if (rate >= 88200) { - if (chip->digital_mode == DIGITAL_MODE_ADAT) - return -EINVAL; - if (chip->device_id == DEVICE_ID_56361) - asic = FW_MONA_361_1_ASIC96; - else - asic = FW_MONA_301_1_ASIC96; - } else { - if (chip->device_id == DEVICE_ID_56361) - asic = FW_MONA_361_1_ASIC48; - else - asic = FW_MONA_301_1_ASIC48; - } - - force_write = 0; - if (asic != chip->asic_code) { - int err; - /* Load the desired ASIC (load_asic_generic() can sleep) */ - spin_unlock_irq(&chip->lock); - err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, - asic); - spin_lock_irq(&chip->lock); - - if (err < 0) - return err; - chip->asic_code = asic; - force_write = 1; - } - - /* Compute the new control register value */ - clock = 0; - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= GML_CLOCK_CLEAR_MASK; - control_reg &= GML_SPDIF_RATE_CLEAR_MASK; - - switch (rate) { - case 96000: - clock = GML_96KHZ; - break; - case 88200: - clock = GML_88KHZ; - break; - case 48000: - clock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; - break; - case 44100: - clock = GML_44KHZ; - /* Professional mode */ - if (control_reg & GML_SPDIF_PRO_MODE) - clock |= GML_SPDIF_SAMPLE_RATE0; - break; - case 32000: - clock = GML_32KHZ | GML_SPDIF_SAMPLE_RATE0 | - GML_SPDIF_SAMPLE_RATE1; - break; - case 22050: - clock = GML_22KHZ; - break; - case 16000: - clock = GML_16KHZ; - break; - case 11025: - clock = GML_11KHZ; - break; - case 8000: - clock = GML_8KHZ; - break; - default: - DE_ACT(("set_sample_rate: %d invalid!\n", rate)); - return -EINVAL; - } - - control_reg |= clock; - - chip->comm_page->sample_rate = cpu_to_le32(rate); /* ignored by the DSP */ - chip->sample_rate = rate; - DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock)); - - return write_control_reg(chip, control_reg, force_write); -} - - - -static int set_input_clock(struct echoaudio *chip, u16 clock) -{ - u32 control_reg, clocks_from_dsp; - int err; - - DE_ACT(("set_input_clock:\n")); - - /* Prevent two simultaneous calls to switch_asic() */ - if (atomic_read(&chip->opencount)) - return -EAGAIN; - - /* Mask off the clock select bits */ - control_reg = le32_to_cpu(chip->comm_page->control_register) & - GML_CLOCK_CLEAR_MASK; - clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks); - - switch (clock) { - case ECHO_CLOCK_INTERNAL: - DE_ACT(("Set Mona clock to INTERNAL\n")); - chip->input_clock = ECHO_CLOCK_INTERNAL; - return set_sample_rate(chip, chip->sample_rate); - case ECHO_CLOCK_SPDIF: - if (chip->digital_mode == DIGITAL_MODE_ADAT) - return -EAGAIN; - spin_unlock_irq(&chip->lock); - err = switch_asic(chip, clocks_from_dsp & - GML_CLOCK_DETECT_BIT_SPDIF96); - spin_lock_irq(&chip->lock); - if (err < 0) - return err; - DE_ACT(("Set Mona clock to SPDIF\n")); - control_reg |= GML_SPDIF_CLOCK; - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_SPDIF96) - control_reg |= GML_DOUBLE_SPEED_MODE; - else - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - case ECHO_CLOCK_WORD: - DE_ACT(("Set Mona clock to WORD\n")); - spin_unlock_irq(&chip->lock); - err = switch_asic(chip, clocks_from_dsp & - GML_CLOCK_DETECT_BIT_WORD96); - spin_lock_irq(&chip->lock); - if (err < 0) - return err; - control_reg |= GML_WORD_CLOCK; - if (clocks_from_dsp & GML_CLOCK_DETECT_BIT_WORD96) - control_reg |= GML_DOUBLE_SPEED_MODE; - else - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - case ECHO_CLOCK_ADAT: - DE_ACT(("Set Mona clock to ADAT\n")); - if (chip->digital_mode != DIGITAL_MODE_ADAT) - return -EAGAIN; - control_reg |= GML_ADAT_CLOCK; - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - default: - DE_ACT(("Input clock 0x%x not supported for Mona\n", clock)); - return -EINVAL; - } - - chip->input_clock = clock; - return write_control_reg(chip, control_reg, TRUE); -} - - - -static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode) -{ - u32 control_reg; - int err, incompatible_clock; - - /* Set clock to "internal" if it's not compatible with the new mode */ - incompatible_clock = FALSE; - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - case DIGITAL_MODE_SPDIF_RCA: - if (chip->input_clock == ECHO_CLOCK_ADAT) - incompatible_clock = TRUE; - break; - case DIGITAL_MODE_ADAT: - if (chip->input_clock == ECHO_CLOCK_SPDIF) - incompatible_clock = TRUE; - break; - default: - DE_ACT(("Digital mode not supported: %d\n", mode)); - return -EINVAL; - } - - spin_lock_irq(&chip->lock); - - if (incompatible_clock) { /* Switch to 48KHz, internal */ - chip->sample_rate = 48000; - set_input_clock(chip, ECHO_CLOCK_INTERNAL); - } - - /* Clear the current digital mode */ - control_reg = le32_to_cpu(chip->comm_page->control_register); - control_reg &= GML_DIGITAL_MODE_CLEAR_MASK; - - /* Tweak the control reg */ - switch (mode) { - case DIGITAL_MODE_SPDIF_OPTICAL: - control_reg |= GML_SPDIF_OPTICAL_MODE; - break; - case DIGITAL_MODE_SPDIF_RCA: - /* GML_SPDIF_OPTICAL_MODE bit cleared */ - break; - case DIGITAL_MODE_ADAT: - /* If the current ASIC is the 96KHz ASIC, switch the ASIC - and set to 48 KHz */ - if (chip->asic_code == FW_MONA_361_1_ASIC96 || - chip->asic_code == FW_MONA_301_1_ASIC96) { - set_sample_rate(chip, 48000); - } - control_reg |= GML_ADAT_MODE; - control_reg &= ~GML_DOUBLE_SPEED_MODE; - break; - } - - err = write_control_reg(chip, control_reg, FALSE); - spin_unlock_irq(&chip->lock); - if (err < 0) - return err; - chip->digital_mode = mode; - - DE_ACT(("set_digital_mode to %d\n", mode)); - return incompatible_clock; -} |