xref: /linux/sound/pci/echoaudio/echo3g_dsp.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3 
4    Copyright Echo Digital Audio Corporation (c) 1998 - 2004
5    All rights reserved
6    www.echoaudio.com
7 
8    This file is part of Echo Digital Audio's generic driver library.
9    *************************************************************************
10 
11  Translation from C++ and adaptation for use in ALSA-Driver
12  were made by Giuliano Pochini <pochini@shiny.it>
13 
14 ****************************************************************************/
15 
16 static int load_asic(struct echoaudio *chip);
17 static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode);
18 static int set_digital_mode(struct echoaudio *chip, u8 mode);
19 static int check_asic_status(struct echoaudio *chip);
20 static int set_sample_rate(struct echoaudio *chip, u32 rate);
21 static int set_input_clock(struct echoaudio *chip, u16 clock);
22 static int set_professional_spdif(struct echoaudio *chip, char prof);
23 static int set_phantom_power(struct echoaudio *chip, char on);
24 static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
25 			     char force);
26 
27 #include <linux/interrupt.h>
28 
29 static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
30 {
31 	int err;
32 
33 	local_irq_enable();
34 	if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G))
35 		return -ENODEV;
36 
37 	err = init_dsp_comm_page(chip);
38 	if (err) {
39 		dev_err(chip->card->dev,
40 			"init_hw - could not initialize DSP comm page\n");
41 		return err;
42 	}
43 
44 	chip->comm_page->e3g_frq_register =
45 		cpu_to_le32((E3G_MAGIC_NUMBER / 48000) - 2);
46 	chip->device_id = device_id;
47 	chip->subdevice_id = subdevice_id;
48 	chip->bad_board = true;
49 	chip->has_midi = true;
50 	chip->dsp_code_to_load = FW_ECHO3G_DSP;
51 
52 	/* Load the DSP code and the ASIC on the PCI card and get
53 	what type of external box is attached */
54 	err = load_firmware(chip);
55 
56 	if (err < 0) {
57 		return err;
58 	} else if (err == E3G_GINA3G_BOX_TYPE) {
59 		chip->input_clock_types =	ECHO_CLOCK_BIT_INTERNAL |
60 						ECHO_CLOCK_BIT_SPDIF |
61 						ECHO_CLOCK_BIT_ADAT;
62 		chip->card_name = "Gina3G";
63 		chip->px_digital_out = chip->bx_digital_out = 6;
64 		chip->px_analog_in = chip->bx_analog_in = 14;
65 		chip->px_digital_in = chip->bx_digital_in = 16;
66 		chip->px_num = chip->bx_num = 24;
67 		chip->has_phantom_power = true;
68 		chip->hasnt_input_nominal_level = true;
69 	} else if (err == E3G_LAYLA3G_BOX_TYPE) {
70 		chip->input_clock_types =	ECHO_CLOCK_BIT_INTERNAL |
71 						ECHO_CLOCK_BIT_SPDIF |
72 						ECHO_CLOCK_BIT_ADAT |
73 						ECHO_CLOCK_BIT_WORD;
74 		chip->card_name = "Layla3G";
75 		chip->px_digital_out = chip->bx_digital_out = 8;
76 		chip->px_analog_in = chip->bx_analog_in = 16;
77 		chip->px_digital_in = chip->bx_digital_in = 24;
78 		chip->px_num = chip->bx_num = 32;
79 	} else {
80 		return -ENODEV;
81 	}
82 
83 	chip->digital_modes =	ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
84 				ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
85 				ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
86 
87 	return err;
88 }
89 
90 
91 
92 static int set_mixer_defaults(struct echoaudio *chip)
93 {
94 	chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
95 	chip->professional_spdif = false;
96 	chip->non_audio_spdif = false;
97 	chip->bad_board = false;
98 	chip->phantom_power = false;
99 	return init_line_levels(chip);
100 }
101 
102 
103 
104 static int set_phantom_power(struct echoaudio *chip, char on)
105 {
106 	u32 control_reg = le32_to_cpu(chip->comm_page->control_register);
107 
108 	if (on)
109 		control_reg |= E3G_PHANTOM_POWER;
110 	else
111 		control_reg &= ~E3G_PHANTOM_POWER;
112 
113 	chip->phantom_power = on;
114 	return write_control_reg(chip, control_reg,
115 				 le32_to_cpu(chip->comm_page->e3g_frq_register),
116 				 0);
117 }
118