Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/pci/emu10k1/io.c
29269 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright (c) by Jaroslav Kysela <[email protected]>
4
* Lee Revell <[email protected]>
5
* James Courtier-Dutton <[email protected]>
6
* Oswald Buddenhagen <[email protected]>
7
* Creative Labs, Inc.
8
*
9
* Routines for control of EMU10K1 chips
10
*/
11
12
#include <linux/time.h>
13
#include <sound/core.h>
14
#include <sound/emu10k1.h>
15
#include <linux/delay.h>
16
#include <linux/export.h>
17
#include "p17v.h"
18
19
static inline bool check_ptr_reg(struct snd_emu10k1 *emu, unsigned int reg)
20
{
21
if (snd_BUG_ON(!emu))
22
return false;
23
if (snd_BUG_ON(reg & (emu->audigy ? (0xffff0000 & ~A_PTR_ADDRESS_MASK)
24
: (0xffff0000 & ~PTR_ADDRESS_MASK))))
25
return false;
26
if (snd_BUG_ON(reg & 0x0000ffff & ~PTR_CHANNELNUM_MASK))
27
return false;
28
return true;
29
}
30
31
unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
32
{
33
unsigned int regptr, val;
34
unsigned int mask;
35
36
regptr = (reg << 16) | chn;
37
if (!check_ptr_reg(emu, regptr))
38
return 0;
39
40
scoped_guard(spinlock_irqsave, &emu->emu_lock) {
41
outl(regptr, emu->port + PTR);
42
val = inl(emu->port + DATA);
43
}
44
45
if (reg & 0xff000000) {
46
unsigned char size, offset;
47
48
size = (reg >> 24) & 0x3f;
49
offset = (reg >> 16) & 0x1f;
50
mask = (1 << size) - 1;
51
52
return (val >> offset) & mask;
53
} else {
54
return val;
55
}
56
}
57
58
EXPORT_SYMBOL(snd_emu10k1_ptr_read);
59
60
void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
61
{
62
unsigned int regptr;
63
unsigned int mask;
64
65
regptr = (reg << 16) | chn;
66
if (!check_ptr_reg(emu, regptr))
67
return;
68
69
guard(spinlock_irqsave)(&emu->emu_lock);
70
if (reg & 0xff000000) {
71
unsigned char size, offset;
72
73
size = (reg >> 24) & 0x3f;
74
offset = (reg >> 16) & 0x1f;
75
mask = (1 << size) - 1;
76
if (snd_BUG_ON(data & ~mask))
77
return;
78
mask <<= offset;
79
data <<= offset;
80
81
outl(regptr, emu->port + PTR);
82
data |= inl(emu->port + DATA) & ~mask;
83
} else {
84
outl(regptr, emu->port + PTR);
85
}
86
outl(data, emu->port + DATA);
87
}
88
89
EXPORT_SYMBOL(snd_emu10k1_ptr_write);
90
91
void snd_emu10k1_ptr_write_multiple(struct snd_emu10k1 *emu, unsigned int chn, ...)
92
{
93
va_list va;
94
u32 addr_mask;
95
96
if (snd_BUG_ON(!emu))
97
return;
98
if (snd_BUG_ON(chn & ~PTR_CHANNELNUM_MASK))
99
return;
100
addr_mask = ~((emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK) >> 16);
101
102
va_start(va, chn);
103
guard(spinlock_irqsave)(&emu->emu_lock);
104
for (;;) {
105
u32 data;
106
u32 reg = va_arg(va, u32);
107
if (reg == REGLIST_END)
108
break;
109
data = va_arg(va, u32);
110
if (snd_BUG_ON(reg & addr_mask)) // Only raw registers supported here
111
continue;
112
outl((reg << 16) | chn, emu->port + PTR);
113
outl(data, emu->port + DATA);
114
}
115
va_end(va);
116
}
117
118
EXPORT_SYMBOL(snd_emu10k1_ptr_write_multiple);
119
120
unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu,
121
unsigned int reg,
122
unsigned int chn)
123
{
124
unsigned int regptr;
125
126
regptr = (reg << 16) | chn;
127
128
guard(spinlock_irqsave)(&emu->emu_lock);
129
outl(regptr, emu->port + PTR2);
130
return inl(emu->port + DATA2);
131
}
132
133
void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu,
134
unsigned int reg,
135
unsigned int chn,
136
unsigned int data)
137
{
138
unsigned int regptr;
139
140
regptr = (reg << 16) | chn;
141
142
guard(spinlock_irqsave)(&emu->emu_lock);
143
outl(regptr, emu->port + PTR2);
144
outl(data, emu->port + DATA2);
145
}
146
147
int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
148
unsigned int data)
149
{
150
unsigned int reset, set;
151
unsigned int reg, tmp;
152
int n, result;
153
154
/* This function is not re-entrant, so protect against it. */
155
guard(spinlock)(&emu->spi_lock);
156
if (emu->card_capabilities->ca0108_chip)
157
reg = P17V_SPI;
158
else {
159
/* For other chip types the SPI register
160
* is currently unknown. */
161
return 1;
162
}
163
if (data > 0xffff) {
164
/* Only 16bit values allowed */
165
return 1;
166
}
167
168
tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
169
reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
170
set = reset | 0x10000; /* Set xxx1xxxx */
171
snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
172
tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */
173
snd_emu10k1_ptr20_write(emu, reg, 0, set | data);
174
result = 1;
175
/* Wait for status bit to return to 0 */
176
for (n = 0; n < 100; n++) {
177
udelay(10);
178
tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
179
if (!(tmp & 0x10000)) {
180
result = 0;
181
break;
182
}
183
}
184
if (result) {
185
/* Timed out */
186
return 1;
187
}
188
snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
189
tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
190
return 0;
191
}
192
193
/* The ADC does not support i2c read, so only write is implemented */
194
int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
195
u32 reg,
196
u32 value)
197
{
198
u32 tmp;
199
int timeout = 0;
200
int status;
201
int retry;
202
203
if ((reg > 0x7f) || (value > 0x1ff)) {
204
dev_err(emu->card->dev, "i2c_write: invalid values.\n");
205
return -EINVAL;
206
}
207
208
/* This function is not re-entrant, so protect against it. */
209
guard(spinlock)(&emu->i2c_lock);
210
211
tmp = reg << 25 | value << 16;
212
213
/* This controls the I2C connected to the WM8775 ADC Codec */
214
snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp);
215
tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */
216
217
for (retry = 0; retry < 10; retry++) {
218
/* Send the data to i2c */
219
tmp = 0;
220
tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
221
snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp);
222
223
/* Wait till the transaction ends */
224
while (1) {
225
mdelay(1);
226
status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0);
227
timeout++;
228
if ((status & I2C_A_ADC_START) == 0)
229
break;
230
231
if (timeout > 1000) {
232
dev_warn(emu->card->dev,
233
"emu10k1:I2C:timeout status=0x%x\n",
234
status);
235
break;
236
}
237
}
238
//Read back and see if the transaction is successful
239
if ((status & I2C_A_ADC_ABORT) == 0)
240
break;
241
}
242
243
if (retry == 10) {
244
dev_err(emu->card->dev, "Writing to ADC failed!\n");
245
dev_err(emu->card->dev, "status=0x%x, reg=%d, value=%d\n",
246
status, reg, value);
247
/* dump_stack(); */
248
return -EINVAL;
249
}
250
251
return 0;
252
}
253
254
static void snd_emu1010_fpga_write_locked(struct snd_emu10k1 *emu, u32 reg, u32 value)
255
{
256
if (snd_BUG_ON(reg > 0x3f))
257
return;
258
reg += 0x40; /* 0x40 upwards are registers. */
259
if (snd_BUG_ON(value > 0x3f)) /* 0 to 0x3f are values */
260
return;
261
outw(reg, emu->port + A_GPIO);
262
udelay(10);
263
outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
264
udelay(10);
265
outw(value, emu->port + A_GPIO);
266
udelay(10);
267
outw(value | 0x80 , emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
268
udelay(10);
269
}
270
271
void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
272
{
273
if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))
274
return;
275
snd_emu1010_fpga_write_locked(emu, reg, value);
276
}
277
278
void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value)
279
{
280
guard(snd_emu1010_fpga_lock)(emu);
281
snd_emu1010_fpga_write_locked(emu, reg, value);
282
}
283
284
void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
285
{
286
// The higest input pin is used as the designated interrupt trigger,
287
// so it needs to be masked out.
288
// But note that any other input pin change will also cause an IRQ,
289
// so using this function often causes an IRQ as a side effect.
290
u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;
291
292
if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))
293
return;
294
if (snd_BUG_ON(reg > 0x3f))
295
return;
296
reg += 0x40; /* 0x40 upwards are registers. */
297
outw(reg, emu->port + A_GPIO);
298
udelay(10);
299
outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
300
udelay(10);
301
*value = ((inw(emu->port + A_GPIO) >> 8) & mask);
302
}
303
304
/* Each Destination has one and only one Source,
305
* but one Source can feed any number of Destinations simultaneously.
306
*/
307
void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src)
308
{
309
if (snd_BUG_ON(dst & ~0x71f))
310
return;
311
if (snd_BUG_ON(src & ~0x71f))
312
return;
313
snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);
314
snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);
315
snd_emu1010_fpga_write(emu, EMU_HANA_SRCHI, src >> 8);
316
snd_emu1010_fpga_write(emu, EMU_HANA_SRCLO, src & 0x1f);
317
}
318
319
u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst)
320
{
321
u32 hi, lo;
322
323
if (snd_BUG_ON(dst & ~0x71f))
324
return 0;
325
snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);
326
snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);
327
snd_emu1010_fpga_read(emu, EMU_HANA_SRCHI, &hi);
328
snd_emu1010_fpga_read(emu, EMU_HANA_SRCLO, &lo);
329
return (hi << 8) | lo;
330
}
331
332
int snd_emu1010_get_raw_rate(struct snd_emu10k1 *emu, u8 src)
333
{
334
u32 reg_lo, reg_hi, value, value2;
335
336
switch (src) {
337
case EMU_HANA_WCLOCK_HANA_SPDIF_IN:
338
snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &value);
339
if (value & EMU_HANA_SPDIF_MODE_RX_INVALID)
340
return 0;
341
reg_lo = EMU_HANA_WC_SPDIF_LO;
342
reg_hi = EMU_HANA_WC_SPDIF_HI;
343
break;
344
case EMU_HANA_WCLOCK_HANA_ADAT_IN:
345
reg_lo = EMU_HANA_WC_ADAT_LO;
346
reg_hi = EMU_HANA_WC_ADAT_HI;
347
break;
348
case EMU_HANA_WCLOCK_SYNC_BNC:
349
reg_lo = EMU_HANA_WC_BNC_LO;
350
reg_hi = EMU_HANA_WC_BNC_HI;
351
break;
352
case EMU_HANA_WCLOCK_2ND_HANA:
353
reg_lo = EMU_HANA2_WC_SPDIF_LO;
354
reg_hi = EMU_HANA2_WC_SPDIF_HI;
355
break;
356
default:
357
return 0;
358
}
359
snd_emu1010_fpga_read(emu, reg_hi, &value);
360
snd_emu1010_fpga_read(emu, reg_lo, &value2);
361
// FIXME: The /4 is valid for 0404b, but contradicts all other info.
362
return 0x1770000 / 4 / (((value << 5) | value2) + 1);
363
}
364
365
void snd_emu1010_update_clock(struct snd_emu10k1 *emu)
366
{
367
int clock;
368
u32 leds;
369
370
switch (emu->emu1010.wclock) {
371
case EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X:
372
clock = 44100;
373
leds = EMU_HANA_DOCK_LEDS_2_44K;
374
break;
375
case EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X:
376
clock = 48000;
377
leds = EMU_HANA_DOCK_LEDS_2_48K;
378
break;
379
default:
380
clock = snd_emu1010_get_raw_rate(
381
emu, emu->emu1010.wclock & EMU_HANA_WCLOCK_SRC_MASK);
382
// The raw rate reading is rather coarse (it cannot accurately
383
// represent 44.1 kHz) and fluctuates slightly. Luckily, the
384
// clock comes from digital inputs, which use standardized rates.
385
// So we round to the closest standard rate and ignore discrepancies.
386
if (clock < 46000) {
387
clock = 44100;
388
leds = EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_44K;
389
} else {
390
clock = 48000;
391
leds = EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_48K;
392
}
393
break;
394
}
395
emu->emu1010.word_clock = clock;
396
397
// FIXME: this should probably represent the AND of all currently
398
// used sources' lock status. But we don't know how to get that ...
399
leds |= EMU_HANA_DOCK_LEDS_2_LOCK;
400
401
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);
402
}
403
404
void snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, int dock,
405
const struct firmware *fw_entry)
406
{
407
__always_unused u16 write_post;
408
409
// On E-MU 1010 rev1 the FPGA is a Xilinx Spartan IIE XC2S50E.
410
// On E-MU 0404b it is a Xilinx Spartan III XC3S50.
411
// The wiring is as follows:
412
// GPO7 -> FPGA input & 1K resistor -> FPGA /PGMN <- FPGA output
413
// In normal operation, the active low reset line is held up by
414
// an FPGA output, while the GPO pin performs its duty as control
415
// register access strobe signal. Writing the respective bit to
416
// EMU_HANA_FPGA_CONFIG puts the FPGA output into high-Z mode, at
417
// which point the GPO pin can control the reset line through the
418
// resistor.
419
// GPO6 -> FPGA CCLK & FPGA input
420
// GPO5 -> FPGA DIN (dual function)
421
422
// If the FPGA is already programmed, return it to programming mode
423
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,
424
dock ? EMU_HANA_FPGA_CONFIG_AUDIODOCK :
425
EMU_HANA_FPGA_CONFIG_HANA);
426
427
// Assert reset line for 100uS
428
outw(0x00, emu->port + A_GPIO);
429
write_post = inw(emu->port + A_GPIO);
430
udelay(100);
431
outw(0x80, emu->port + A_GPIO);
432
write_post = inw(emu->port + A_GPIO);
433
udelay(100); // Allow FPGA memory to clean
434
435
// Upload the netlist. Keep reset line high!
436
for (int n = 0; n < fw_entry->size; n++) {
437
u8 value = fw_entry->data[n];
438
for (int i = 0; i < 8; i++) {
439
u16 reg = 0x80;
440
if (value & 1)
441
reg |= 0x20;
442
value >>= 1;
443
outw(reg, emu->port + A_GPIO);
444
write_post = inw(emu->port + A_GPIO);
445
outw(reg | 0x40, emu->port + A_GPIO);
446
write_post = inw(emu->port + A_GPIO);
447
}
448
}
449
450
// After programming, set GPIO bit 4 high again.
451
// This appears to be a config word that the rev1 Hana
452
// firmware reads; weird things happen without this.
453
outw(0x10, emu->port + A_GPIO);
454
write_post = inw(emu->port + A_GPIO);
455
}
456
457
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
458
{
459
unsigned int enable;
460
461
guard(spinlock_irqsave)(&emu->emu_lock);
462
enable = inl(emu->port + INTE) | intrenb;
463
outl(enable, emu->port + INTE);
464
}
465
466
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
467
{
468
unsigned int enable;
469
470
guard(spinlock_irqsave)(&emu->emu_lock);
471
enable = inl(emu->port + INTE) & ~intrenb;
472
outl(enable, emu->port + INTE);
473
}
474
475
void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
476
{
477
unsigned int val;
478
479
guard(spinlock_irqsave)(&emu->emu_lock);
480
if (voicenum >= 32) {
481
outl(CLIEH << 16, emu->port + PTR);
482
val = inl(emu->port + DATA);
483
val |= 1 << (voicenum - 32);
484
} else {
485
outl(CLIEL << 16, emu->port + PTR);
486
val = inl(emu->port + DATA);
487
val |= 1 << voicenum;
488
}
489
outl(val, emu->port + DATA);
490
}
491
492
void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
493
{
494
unsigned int val;
495
496
guard(spinlock_irqsave)(&emu->emu_lock);
497
if (voicenum >= 32) {
498
outl(CLIEH << 16, emu->port + PTR);
499
val = inl(emu->port + DATA);
500
val &= ~(1 << (voicenum - 32));
501
} else {
502
outl(CLIEL << 16, emu->port + PTR);
503
val = inl(emu->port + DATA);
504
val &= ~(1 << voicenum);
505
}
506
outl(val, emu->port + DATA);
507
}
508
509
void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
510
{
511
guard(spinlock_irqsave)(&emu->emu_lock);
512
if (voicenum >= 32) {
513
outl(CLIPH << 16, emu->port + PTR);
514
voicenum = 1 << (voicenum - 32);
515
} else {
516
outl(CLIPL << 16, emu->port + PTR);
517
voicenum = 1 << voicenum;
518
}
519
outl(voicenum, emu->port + DATA);
520
}
521
522
void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
523
{
524
unsigned int val;
525
526
guard(spinlock_irqsave)(&emu->emu_lock);
527
if (voicenum >= 32) {
528
outl(HLIEH << 16, emu->port + PTR);
529
val = inl(emu->port + DATA);
530
val |= 1 << (voicenum - 32);
531
} else {
532
outl(HLIEL << 16, emu->port + PTR);
533
val = inl(emu->port + DATA);
534
val |= 1 << voicenum;
535
}
536
outl(val, emu->port + DATA);
537
}
538
539
void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
540
{
541
unsigned int val;
542
543
guard(spinlock_irqsave)(&emu->emu_lock);
544
if (voicenum >= 32) {
545
outl(HLIEH << 16, emu->port + PTR);
546
val = inl(emu->port + DATA);
547
val &= ~(1 << (voicenum - 32));
548
} else {
549
outl(HLIEL << 16, emu->port + PTR);
550
val = inl(emu->port + DATA);
551
val &= ~(1 << voicenum);
552
}
553
outl(val, emu->port + DATA);
554
}
555
556
void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
557
{
558
guard(spinlock_irqsave)(&emu->emu_lock);
559
if (voicenum >= 32) {
560
outl(HLIPH << 16, emu->port + PTR);
561
voicenum = 1 << (voicenum - 32);
562
} else {
563
outl(HLIPL << 16, emu->port + PTR);
564
voicenum = 1 << voicenum;
565
}
566
outl(voicenum, emu->port + DATA);
567
}
568
569
#if 0
570
void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
571
{
572
unsigned int sol;
573
574
guard(spinlock_irqsave)(&emu->emu_lock);
575
if (voicenum >= 32) {
576
outl(SOLEH << 16, emu->port + PTR);
577
sol = inl(emu->port + DATA);
578
sol |= 1 << (voicenum - 32);
579
} else {
580
outl(SOLEL << 16, emu->port + PTR);
581
sol = inl(emu->port + DATA);
582
sol |= 1 << voicenum;
583
}
584
outl(sol, emu->port + DATA);
585
}
586
587
void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
588
{
589
unsigned int sol;
590
591
guard(spinlock_irqsave)(&emu->emu_lock);
592
if (voicenum >= 32) {
593
outl(SOLEH << 16, emu->port + PTR);
594
sol = inl(emu->port + DATA);
595
sol &= ~(1 << (voicenum - 32));
596
} else {
597
outl(SOLEL << 16, emu->port + PTR);
598
sol = inl(emu->port + DATA);
599
sol &= ~(1 << voicenum);
600
}
601
outl(sol, emu->port + DATA);
602
}
603
#endif
604
605
void snd_emu10k1_voice_set_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices)
606
{
607
guard(spinlock_irqsave)(&emu->emu_lock);
608
outl(SOLEL << 16, emu->port + PTR);
609
outl(inl(emu->port + DATA) | (u32)voices, emu->port + DATA);
610
outl(SOLEH << 16, emu->port + PTR);
611
outl(inl(emu->port + DATA) | (u32)(voices >> 32), emu->port + DATA);
612
}
613
614
void snd_emu10k1_voice_clear_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices)
615
{
616
guard(spinlock_irqsave)(&emu->emu_lock);
617
outl(SOLEL << 16, emu->port + PTR);
618
outl(inl(emu->port + DATA) & (u32)~voices, emu->port + DATA);
619
outl(SOLEH << 16, emu->port + PTR);
620
outl(inl(emu->port + DATA) & (u32)(~voices >> 32), emu->port + DATA);
621
}
622
623
int snd_emu10k1_voice_clear_loop_stop_multiple_atomic(struct snd_emu10k1 *emu, u64 voices)
624
{
625
unsigned long flags;
626
u32 soll, solh;
627
int ret = -EIO;
628
629
spin_lock_irqsave(&emu->emu_lock, flags);
630
631
outl(SOLEL << 16, emu->port + PTR);
632
soll = inl(emu->port + DATA);
633
outl(SOLEH << 16, emu->port + PTR);
634
solh = inl(emu->port + DATA);
635
636
soll &= (u32)~voices;
637
solh &= (u32)(~voices >> 32);
638
639
for (int tries = 0; tries < 1000; tries++) {
640
const u32 quart = 1U << (REG_SIZE(WC_CURRENTCHANNEL) - 2);
641
// First we wait for the third quarter of the sample cycle ...
642
u32 wc = inl(emu->port + WC);
643
u32 cc = REG_VAL_GET(WC_CURRENTCHANNEL, wc);
644
if (cc >= quart * 2 && cc < quart * 3) {
645
// ... and release the low voices, while the high ones are serviced.
646
outl(SOLEL << 16, emu->port + PTR);
647
outl(soll, emu->port + DATA);
648
// Then we wait for the first quarter of the next sample cycle ...
649
for (; tries < 1000; tries++) {
650
cc = REG_VAL_GET(WC_CURRENTCHANNEL, inl(emu->port + WC));
651
if (cc < quart)
652
goto good;
653
// We will block for 10+ us with interrupts disabled. This is
654
// not nice at all, but necessary for reasonable reliability.
655
udelay(1);
656
}
657
break;
658
good:
659
// ... and release the high voices, while the low ones are serviced.
660
outl(SOLEH << 16, emu->port + PTR);
661
outl(solh, emu->port + DATA);
662
// Finally we verify that nothing interfered in fact.
663
if (REG_VAL_GET(WC_SAMPLECOUNTER, inl(emu->port + WC)) ==
664
((REG_VAL_GET(WC_SAMPLECOUNTER, wc) + 1) & REG_MASK0(WC_SAMPLECOUNTER))) {
665
ret = 0;
666
} else {
667
ret = -EAGAIN;
668
}
669
break;
670
}
671
// Don't block for too long
672
spin_unlock_irqrestore(&emu->emu_lock, flags);
673
udelay(1);
674
spin_lock_irqsave(&emu->emu_lock, flags);
675
}
676
677
spin_unlock_irqrestore(&emu->emu_lock, flags);
678
return ret;
679
}
680
681
void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
682
{
683
volatile unsigned count;
684
unsigned int newtime = 0, curtime;
685
686
curtime = inl(emu->port + WC) >> 6;
687
while (wait-- > 0) {
688
count = 0;
689
while (count++ < 16384) {
690
newtime = inl(emu->port + WC) >> 6;
691
if (newtime != curtime)
692
break;
693
}
694
if (count > 16384)
695
break;
696
curtime = newtime;
697
}
698
}
699
700
unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
701
{
702
struct snd_emu10k1 *emu = ac97->private_data;
703
704
guard(spinlock_irqsave)(&emu->emu_lock);
705
outb(reg, emu->port + AC97ADDRESS);
706
return inw(emu->port + AC97DATA);
707
}
708
709
void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data)
710
{
711
struct snd_emu10k1 *emu = ac97->private_data;
712
713
guard(spinlock_irqsave)(&emu->emu_lock);
714
outb(reg, emu->port + AC97ADDRESS);
715
outw(data, emu->port + AC97DATA);
716
}
717
718