1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/delay.h>
24#include <sound/core.h>
25#include <sound/vx_core.h>
26#include "vx_cmd.h"
27
28
29
30
31
32
33static int vx_modify_board_clock(struct vx_core *chip, int sync)
34{
35 struct vx_rmh rmh;
36
37 vx_init_rmh(&rmh, CMD_MODIFY_CLOCK);
38
39 if (sync)
40 rmh.Cmd[0] |= CMD_MODIFY_CLOCK_S_BIT;
41 return vx_send_msg(chip, &rmh);
42}
43
44
45
46
47static int vx_modify_board_inputs(struct vx_core *chip)
48{
49 struct vx_rmh rmh;
50
51 vx_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
52 rmh.Cmd[0] |= 1 << 0;
53 return vx_send_msg(chip, &rmh);
54}
55
56
57
58
59
60
61static int vx_read_one_cbit(struct vx_core *chip, int index)
62{
63 unsigned long flags;
64 int val;
65 spin_lock_irqsave(&chip->lock, flags);
66 if (chip->type >= VX_TYPE_VXPOCKET) {
67 vx_outb(chip, CSUER, 1);
68 vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
69 val = (vx_inb(chip, RUER) >> 7) & 0x01;
70 } else {
71 vx_outl(chip, CSUER, 1);
72 vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
73 val = (vx_inl(chip, RUER) >> 7) & 0x01;
74 }
75 spin_unlock_irqrestore(&chip->lock, flags);
76 return val;
77}
78
79
80
81
82
83
84static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
85{
86 unsigned long flags;
87 val = !!val;
88 spin_lock_irqsave(&chip->lock, flags);
89 if (vx_is_pcmcia(chip)) {
90 vx_outb(chip, CSUER, 0);
91 vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
92 } else {
93 vx_outl(chip, CSUER, 0);
94 vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
95 }
96 spin_unlock_irqrestore(&chip->lock, flags);
97}
98
99
100
101
102
103
104
105
106static int vx_read_uer_status(struct vx_core *chip, unsigned int *mode)
107{
108 int val, freq;
109
110
111 freq = 0;
112
113
114 if (vx_is_pcmcia(chip))
115 val = vx_inb(chip, CSUER);
116 else
117 val = vx_inl(chip, CSUER);
118 if (val < 0)
119 return val;
120
121 if (val & VX_SUER_CLOCK_PRESENT_MASK) {
122 switch (val & VX_SUER_FREQ_MASK) {
123 case VX_SUER_FREQ_32KHz_MASK:
124 freq = 32000;
125 break;
126 case VX_SUER_FREQ_44KHz_MASK:
127 freq = 44100;
128 break;
129 case VX_SUER_FREQ_48KHz_MASK:
130 freq = 48000;
131 break;
132 }
133 }
134 if (val & VX_SUER_DATA_PRESENT_MASK)
135
136 *mode = vx_read_one_cbit(chip, 0) ?
137 VX_UER_MODE_PROFESSIONAL : VX_UER_MODE_CONSUMER;
138 else
139 *mode = VX_UER_MODE_NOT_PRESENT;
140
141 return freq;
142}
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
163{
164 int hexfreq;
165
166 if (snd_BUG_ON(freq <= 0))
167 return 0;
168
169 hexfreq = (28224000 * 10) / freq;
170 hexfreq = (hexfreq + 5) / 10;
171
172
173 if (snd_BUG_ON(hexfreq <= 0x00000200))
174 return 0;
175
176 if (hexfreq <= 0x03ff)
177 return hexfreq - 0x00000201;
178 if (hexfreq <= 0x07ff)
179 return (hexfreq / 2) - 1;
180 if (hexfreq <= 0x0fff)
181 return (hexfreq / 4) + 0x000001ff;
182
183 return 0x5fe;
184}
185
186
187
188
189
190
191static void vx_change_clock_source(struct vx_core *chip, int source)
192{
193 unsigned long flags;
194
195
196 vx_toggle_dac_mute(chip, 1);
197 spin_lock_irqsave(&chip->lock, flags);
198 chip->ops->set_clock_source(chip, source);
199 chip->clock_source = source;
200 spin_unlock_irqrestore(&chip->lock, flags);
201
202 vx_toggle_dac_mute(chip, 0);
203}
204
205
206
207
208
209void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
210{
211 int clock;
212 unsigned long flags;
213
214 clock = vx_calc_clock_from_freq(chip, freq);
215 snd_printdd(KERN_DEBUG "set internal clock to 0x%x from freq %d\n", clock, freq);
216 spin_lock_irqsave(&chip->lock, flags);
217 if (vx_is_pcmcia(chip)) {
218 vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f);
219 vx_outb(chip, LOFREQ, clock & 0xff);
220 } else {
221 vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f);
222 vx_outl(chip, LOFREQ, clock & 0xff);
223 }
224 spin_unlock_irqrestore(&chip->lock, flags);
225}
226
227
228
229
230
231
232void vx_set_iec958_status(struct vx_core *chip, unsigned int bits)
233{
234 int i;
235
236 if (chip->chip_status & VX_STAT_IS_STALE)
237 return;
238
239 for (i = 0; i < 32; i++)
240 vx_write_one_cbit(chip, i, bits & (1 << i));
241}
242
243
244
245
246
247int vx_set_clock(struct vx_core *chip, unsigned int freq)
248{
249 int src_changed = 0;
250
251 if (chip->chip_status & VX_STAT_IS_STALE)
252 return 0;
253
254
255 vx_sync_audio_source(chip);
256
257 if (chip->clock_mode == VX_CLOCK_MODE_EXTERNAL ||
258 (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
259 chip->audio_source == VX_AUDIO_SRC_DIGITAL)) {
260 if (chip->clock_source != UER_SYNC) {
261 vx_change_clock_source(chip, UER_SYNC);
262 mdelay(6);
263 src_changed = 1;
264 }
265 } else if (chip->clock_mode == VX_CLOCK_MODE_INTERNAL ||
266 (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
267 chip->audio_source != VX_AUDIO_SRC_DIGITAL)) {
268 if (chip->clock_source != INTERNAL_QUARTZ) {
269 vx_change_clock_source(chip, INTERNAL_QUARTZ);
270 src_changed = 1;
271 }
272 if (chip->freq == freq)
273 return 0;
274 vx_set_internal_clock(chip, freq);
275 if (src_changed)
276 vx_modify_board_inputs(chip);
277 }
278 if (chip->freq == freq)
279 return 0;
280 chip->freq = freq;
281 vx_modify_board_clock(chip, 1);
282 return 0;
283}
284
285
286
287
288
289int vx_change_frequency(struct vx_core *chip)
290{
291 int freq;
292
293 if (chip->chip_status & VX_STAT_IS_STALE)
294 return 0;
295
296 if (chip->clock_source == INTERNAL_QUARTZ)
297 return 0;
298
299
300
301 freq = vx_read_uer_status(chip, &chip->uer_detected);
302 if (freq < 0)
303 return freq;
304
305
306
307
308 if (freq == 48000 || freq == 44100 || freq == 32000)
309 chip->freq_detected = freq;
310
311 return 0;
312}
313