1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32static int set_professional_spdif(struct echoaudio *chip, char prof);
33static int update_flags(struct echoaudio *chip);
34
35
36static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
37{
38 int err;
39
40 DE_INIT(("init_hw() - Gina20\n"));
41 if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20))
42 return -ENODEV;
43
44 if ((err = init_dsp_comm_page(chip))) {
45 DE_INIT(("init_hw - could not initialize DSP comm page\n"));
46 return err;
47 }
48
49 chip->device_id = device_id;
50 chip->subdevice_id = subdevice_id;
51 chip->bad_board = TRUE;
52 chip->dsp_code_to_load = FW_GINA20_DSP;
53 chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
54 chip->clock_state = GD_CLOCK_UNDEF;
55
56
57 chip->asic_loaded = TRUE;
58 chip->input_clock_types = ECHO_CLOCK_BIT_INTERNAL |
59 ECHO_CLOCK_BIT_SPDIF;
60
61 if ((err = load_firmware(chip)) < 0)
62 return err;
63 chip->bad_board = FALSE;
64
65 DE_INIT(("init_hw done\n"));
66 return err;
67}
68
69
70
71static int set_mixer_defaults(struct echoaudio *chip)
72{
73 chip->professional_spdif = FALSE;
74 return init_line_levels(chip);
75}
76
77
78
79static u32 detect_input_clocks(const struct echoaudio *chip)
80{
81 u32 clocks_from_dsp, clock_bits;
82
83
84
85 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
86
87 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
88
89 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
90 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
91
92 return clock_bits;
93}
94
95
96
97
98static int load_asic(struct echoaudio *chip)
99{
100 return 0;
101}
102
103
104
105static int set_sample_rate(struct echoaudio *chip, u32 rate)
106{
107 u8 clock_state, spdif_status;
108
109 if (wait_handshake(chip))
110 return -EIO;
111
112 switch (rate) {
113 case 44100:
114 clock_state = GD_CLOCK_44;
115 spdif_status = GD_SPDIF_STATUS_44;
116 break;
117 case 48000:
118 clock_state = GD_CLOCK_48;
119 spdif_status = GD_SPDIF_STATUS_48;
120 break;
121 default:
122 clock_state = GD_CLOCK_NOCHANGE;
123 spdif_status = GD_SPDIF_STATUS_NOCHANGE;
124 break;
125 }
126
127 if (chip->clock_state == clock_state)
128 clock_state = GD_CLOCK_NOCHANGE;
129 if (spdif_status == chip->spdif_status)
130 spdif_status = GD_SPDIF_STATUS_NOCHANGE;
131
132 chip->comm_page->sample_rate = cpu_to_le32(rate);
133 chip->comm_page->gd_clock_state = clock_state;
134 chip->comm_page->gd_spdif_status = spdif_status;
135 chip->comm_page->gd_resampler_state = 3;
136
137
138 if (clock_state != GD_CLOCK_NOCHANGE)
139 chip->clock_state = clock_state;
140 if (spdif_status != GD_SPDIF_STATUS_NOCHANGE)
141 chip->spdif_status = spdif_status;
142 chip->sample_rate = rate;
143
144 clear_handshake(chip);
145 return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
146}
147
148
149
150static int set_input_clock(struct echoaudio *chip, u16 clock)
151{
152 DE_ACT(("set_input_clock:\n"));
153
154 switch (clock) {
155 case ECHO_CLOCK_INTERNAL:
156
157 chip->clock_state = GD_CLOCK_UNDEF;
158 chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
159 set_sample_rate(chip, chip->sample_rate);
160 chip->input_clock = clock;
161 DE_ACT(("Set Gina clock to INTERNAL\n"));
162 break;
163 case ECHO_CLOCK_SPDIF:
164 chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN;
165 chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE;
166 clear_handshake(chip);
167 send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
168 chip->clock_state = GD_CLOCK_SPDIFIN;
169 DE_ACT(("Set Gina20 clock to SPDIF\n"));
170 chip->input_clock = clock;
171 break;
172 default:
173 return -EINVAL;
174 }
175
176 return 0;
177}
178
179
180
181
182static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
183{
184 if (snd_BUG_ON(input >= num_busses_in(chip)))
185 return -EINVAL;
186
187 if (wait_handshake(chip))
188 return -EIO;
189
190 chip->input_gain[input] = gain;
191 gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
192 chip->comm_page->line_in_level[input] = gain;
193 return 0;
194}
195
196
197
198
199static int update_flags(struct echoaudio *chip)
200{
201 if (wait_handshake(chip))
202 return -EIO;
203 clear_handshake(chip);
204 return send_vector(chip, DSP_VC_UPDATE_FLAGS);
205}
206
207
208
209static int set_professional_spdif(struct echoaudio *chip, char prof)
210{
211 DE_ACT(("set_professional_spdif %d\n", prof));
212 if (prof)
213 chip->comm_page->flags |=
214 cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
215 else
216 chip->comm_page->flags &=
217 ~cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
218 chip->professional_spdif = prof;
219 return update_flags(chip);
220}
221