18c2ecf20Sopenharmony_ci/**************************************************************************** 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci Copyright Echo Digital Audio Corporation (c) 1998 - 2004 48c2ecf20Sopenharmony_ci All rights reserved 58c2ecf20Sopenharmony_ci www.echoaudio.com 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci This file is part of Echo Digital Audio's generic driver library. 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci Echo Digital Audio's generic driver library is free software; 108c2ecf20Sopenharmony_ci you can redistribute it and/or modify it under the terms of 118c2ecf20Sopenharmony_ci the GNU General Public License as published by the Free Software 128c2ecf20Sopenharmony_ci Foundation. 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci This program is distributed in the hope that it will be useful, 158c2ecf20Sopenharmony_ci but WITHOUT ANY WARRANTY; without even the implied warranty of 168c2ecf20Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 178c2ecf20Sopenharmony_ci GNU General Public License for more details. 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci You should have received a copy of the GNU General Public License 208c2ecf20Sopenharmony_ci along with this program; if not, write to the Free Software 218c2ecf20Sopenharmony_ci Foundation, Inc., 59 Temple Place - Suite 330, Boston, 228c2ecf20Sopenharmony_ci MA 02111-1307, USA. 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci ************************************************************************* 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci Translation from C++ and adaptation for use in ALSA-Driver 278c2ecf20Sopenharmony_ci were made by Giuliano Pochini <pochini@shiny.it> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci****************************************************************************/ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic int load_asic(struct echoaudio *chip); 328c2ecf20Sopenharmony_cistatic int dsp_set_digital_mode(struct echoaudio *chip, u8 mode); 338c2ecf20Sopenharmony_cistatic int set_digital_mode(struct echoaudio *chip, u8 mode); 348c2ecf20Sopenharmony_cistatic int check_asic_status(struct echoaudio *chip); 358c2ecf20Sopenharmony_cistatic int set_sample_rate(struct echoaudio *chip, u32 rate); 368c2ecf20Sopenharmony_cistatic int set_input_clock(struct echoaudio *chip, u16 clock); 378c2ecf20Sopenharmony_cistatic int set_professional_spdif(struct echoaudio *chip, char prof); 388c2ecf20Sopenharmony_cistatic int set_phantom_power(struct echoaudio *chip, char on); 398c2ecf20Sopenharmony_cistatic int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, 408c2ecf20Sopenharmony_ci char force); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci int err; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci local_irq_enable(); 498c2ecf20Sopenharmony_ci if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G)) 508c2ecf20Sopenharmony_ci return -ENODEV; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci if ((err = init_dsp_comm_page(chip))) { 538c2ecf20Sopenharmony_ci dev_err(chip->card->dev, 548c2ecf20Sopenharmony_ci "init_hw - could not initialize DSP comm page\n"); 558c2ecf20Sopenharmony_ci return err; 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci chip->comm_page->e3g_frq_register = 598c2ecf20Sopenharmony_ci cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2); 608c2ecf20Sopenharmony_ci chip->device_id = device_id; 618c2ecf20Sopenharmony_ci chip->subdevice_id = subdevice_id; 628c2ecf20Sopenharmony_ci chip->bad_board = true; 638c2ecf20Sopenharmony_ci chip->has_midi = true; 648c2ecf20Sopenharmony_ci chip->dsp_code_to_load = FW_ECHO3G_DSP; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* Load the DSP code and the ASIC on the PCI card and get 678c2ecf20Sopenharmony_ci what type of external box is attached */ 688c2ecf20Sopenharmony_ci err = load_firmware(chip); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (err < 0) { 718c2ecf20Sopenharmony_ci return err; 728c2ecf20Sopenharmony_ci } else if (err == E3G_GINA3G_BOX_TYPE) { 738c2ecf20Sopenharmony_ci chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | 748c2ecf20Sopenharmony_ci ECHO_CLOCK_BIT_SPDIF | 758c2ecf20Sopenharmony_ci ECHO_CLOCK_BIT_ADAT; 768c2ecf20Sopenharmony_ci chip->card_name = "Gina3G"; 778c2ecf20Sopenharmony_ci chip->px_digital_out = chip->bx_digital_out = 6; 788c2ecf20Sopenharmony_ci chip->px_analog_in = chip->bx_analog_in = 14; 798c2ecf20Sopenharmony_ci chip->px_digital_in = chip->bx_digital_in = 16; 808c2ecf20Sopenharmony_ci chip->px_num = chip->bx_num = 24; 818c2ecf20Sopenharmony_ci chip->has_phantom_power = true; 828c2ecf20Sopenharmony_ci chip->hasnt_input_nominal_level = true; 838c2ecf20Sopenharmony_ci } else if (err == E3G_LAYLA3G_BOX_TYPE) { 848c2ecf20Sopenharmony_ci chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL | 858c2ecf20Sopenharmony_ci ECHO_CLOCK_BIT_SPDIF | 868c2ecf20Sopenharmony_ci ECHO_CLOCK_BIT_ADAT | 878c2ecf20Sopenharmony_ci ECHO_CLOCK_BIT_WORD; 888c2ecf20Sopenharmony_ci chip->card_name = "Layla3G"; 898c2ecf20Sopenharmony_ci chip->px_digital_out = chip->bx_digital_out = 8; 908c2ecf20Sopenharmony_ci chip->px_analog_in = chip->bx_analog_in = 16; 918c2ecf20Sopenharmony_ci chip->px_digital_in = chip->bx_digital_in = 24; 928c2ecf20Sopenharmony_ci chip->px_num = chip->bx_num = 32; 938c2ecf20Sopenharmony_ci } else { 948c2ecf20Sopenharmony_ci return -ENODEV; 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA | 988c2ecf20Sopenharmony_ci ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL | 998c2ecf20Sopenharmony_ci ECHOCAPS_HAS_DIGITAL_MODE_ADAT; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci return err; 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic int set_mixer_defaults(struct echoaudio *chip) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci chip->digital_mode = DIGITAL_MODE_SPDIF_RCA; 1098c2ecf20Sopenharmony_ci chip->professional_spdif = false; 1108c2ecf20Sopenharmony_ci chip->non_audio_spdif = false; 1118c2ecf20Sopenharmony_ci chip->bad_board = false; 1128c2ecf20Sopenharmony_ci chip->phantom_power = false; 1138c2ecf20Sopenharmony_ci return init_line_levels(chip); 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic int set_phantom_power(struct echoaudio *chip, char on) 1198c2ecf20Sopenharmony_ci{ 1208c2ecf20Sopenharmony_ci u32 control_reg = le32_to_cpu(chip->comm_page->control_register); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci if (on) 1238c2ecf20Sopenharmony_ci control_reg |= E3G_PHANTOM_POWER; 1248c2ecf20Sopenharmony_ci else 1258c2ecf20Sopenharmony_ci control_reg &= ~E3G_PHANTOM_POWER; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci chip->phantom_power = on; 1288c2ecf20Sopenharmony_ci return write_control_reg(chip, control_reg, 1298c2ecf20Sopenharmony_ci le32_to_cpu(chip->comm_page->e3g_frq_register), 1308c2ecf20Sopenharmony_ci 0); 1318c2ecf20Sopenharmony_ci} 132