File Index
Files and directories
Sign in
FILE

io.c

File preview with syntax highlighting.

linux-6.19.14/sound/pci/emu10k1/io.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  4 *                   Lee Revell <rlrevell@joe-job.com>
  5 *                   James Courtier-Dutton <James@superbug.co.uk>
  6 *                   Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
  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
 19static 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
 31unsigned 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
 58EXPORT_SYMBOL(snd_emu10k1_ptr_read);
 59
 60void 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
 89EXPORT_SYMBOL(snd_emu10k1_ptr_write);
 90
 91void 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
118EXPORT_SYMBOL(snd_emu10k1_ptr_write_multiple);
119
120unsigned 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
133void 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
147int 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 */
194int 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
254static 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
271void 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
278void 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
284void 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 */
307void 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
319u32 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
332int 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
365void 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
404void 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
457void 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
466void 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
475void 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
492void 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
509void 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
522void 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
539void 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
556void 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
570void 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
587void 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
605void 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
614void 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
623int 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
681void 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
700unsigned 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
709void 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}
~/ Read-only file preview.