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 = &card_fw[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 if ((err = init_line_levels(chip)) < 0)
66 return err;
67
68 err = set_professional_spdif(chip, TRUE);
69
70 DE_INIT(("init_hw done\n"));
71 return err;
72}
73
74
75
76static u32 detect_input_clocks(const struct echoaudio *chip)
77{
78 u32 clocks_from_dsp, clock_bits;
79
80
81
82 clocks_from_dsp = le32_to_cpu(chip->comm_page->status_clocks);
83
84 clock_bits = ECHO_CLOCK_BIT_INTERNAL;
85
86 if (clocks_from_dsp & GLDM_CLOCK_DETECT_BIT_SPDIF)
87 clock_bits |= ECHO_CLOCK_BIT_SPDIF;
88
89 return clock_bits;
90}
91
92
93
94
95static int load_asic(struct echoaudio *chip)
96{
97 return 0;
98}
99
100
101
102static int set_sample_rate(struct echoaudio *chip, u32 rate)
103{
104 u8 clock_state, spdif_status;
105
106 if (wait_handshake(chip))
107 return -EIO;
108
109 switch (rate) {
110 case 44100:
111 clock_state = GD_CLOCK_44;
112 spdif_status = GD_SPDIF_STATUS_44;
113 break;
114 case 48000:
115 clock_state = GD_CLOCK_48;
116 spdif_status = GD_SPDIF_STATUS_48;
117 break;
118 default:
119 clock_state = GD_CLOCK_NOCHANGE;
120 spdif_status = GD_SPDIF_STATUS_NOCHANGE;
121 break;
122 }
123
124 if (chip->clock_state == clock_state)
125 clock_state = GD_CLOCK_NOCHANGE;
126 if (spdif_status == chip->spdif_status)
127 spdif_status = GD_SPDIF_STATUS_NOCHANGE;
128
129 chip->comm_page->sample_rate = cpu_to_le32(rate);
130 chip->comm_page->gd_clock_state = clock_state;
131 chip->comm_page->gd_spdif_status = spdif_status;
132 chip->comm_page->gd_resampler_state = 3;
133
134
135 if (clock_state != GD_CLOCK_NOCHANGE)
136 chip->clock_state = clock_state;
137 if (spdif_status != GD_SPDIF_STATUS_NOCHANGE)
138 chip->spdif_status = spdif_status;
139 chip->sample_rate = rate;
140
141 clear_handshake(chip);
142 return send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
143}
144
145
146
147static int set_input_clock(struct echoaudio *chip, u16 clock)
148{
149 DE_ACT(("set_input_clock:\n"));
150
151 switch (clock) {
152 case ECHO_CLOCK_INTERNAL:
153
154 chip->clock_state = GD_CLOCK_UNDEF;
155 chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
156 set_sample_rate(chip, chip->sample_rate);
157 chip->input_clock = clock;
158 DE_ACT(("Set Gina clock to INTERNAL\n"));
159 break;
160 case ECHO_CLOCK_SPDIF:
161 chip->comm_page->gd_clock_state = GD_CLOCK_SPDIFIN;
162 chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_NOCHANGE;
163 clear_handshake(chip);
164 send_vector(chip, DSP_VC_SET_GD_AUDIO_STATE);
165 chip->clock_state = GD_CLOCK_SPDIFIN;
166 DE_ACT(("Set Gina20 clock to SPDIF\n"));
167 chip->input_clock = clock;
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 return 0;
174}
175
176
177
178
179static int set_input_gain(struct echoaudio *chip, u16 input, int gain)
180{
181 if (snd_BUG_ON(input >= num_busses_in(chip)))
182 return -EINVAL;
183
184 if (wait_handshake(chip))
185 return -EIO;
186
187 chip->input_gain[input] = gain;
188 gain += GL20_INPUT_GAIN_MAGIC_NUMBER;
189 chip->comm_page->line_in_level[input] = gain;
190 return 0;
191}
192
193
194
195
196static int update_flags(struct echoaudio *chip)
197{
198 if (wait_handshake(chip))
199 return -EIO;
200 clear_handshake(chip);
201 return send_vector(chip, DSP_VC_UPDATE_FLAGS);
202}
203
204
205
206static int set_professional_spdif(struct echoaudio *chip, char prof)
207{
208 DE_ACT(("set_professional_spdif %d\n", prof));
209 if (prof)
210 chip->comm_page->flags |=
211 __constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
212 else
213 chip->comm_page->flags &=
214 ~__constant_cpu_to_le32(DSP_FLAG_PROFESSIONAL_SPDIF);
215 chip->professional_spdif = prof;
216 return update_flags(chip);
217}
218