sound/pci/aw2/aw2-saa7146.c

Source file repositories/reference/linux-study-clean/sound/pci/aw2/aw2-saa7146.c

File Facts

System
Linux kernel
Corpus path
sound/pci/aw2/aw2-saa7146.c
Extension
.c
Size
12088 bytes
Lines
449
Domain
Driver Families
Bucket
sound/pci
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (arr_substream_it_playback_cb[1].p_it_callback != NULL) {
			arr_substream_it_playback_cb[1].
			    p_it_callback(arr_substream_it_playback_cb[1].
					  p_callback_param);
		}
	}
	if (isr & A2_out) {
		if (arr_substream_it_playback_cb[0].p_it_callback != NULL) {
			arr_substream_it_playback_cb[0].
			    p_it_callback(arr_substream_it_playback_cb[0].
					  p_callback_param);
		}

	}
	if (isr & A1_in) {
		if (arr_substream_it_capture_cb[0].p_it_callback != NULL) {
			arr_substream_it_capture_cb[0].
			    p_it_callback(arr_substream_it_capture_cb[0].
					  p_callback_param);
		}
	}
	return IRQ_HANDLED;
}

unsigned int snd_aw2_saa7146_get_hw_ptr_playback(struct snd_aw2_saa7146 *chip,
						 int stream_number,
						 unsigned char *start_addr,
						 unsigned int buffer_size)
{
	long pci_adp = 0;
	size_t ptr = 0;

	if (stream_number == 0) {
		pci_adp = READREG(PCI_ADP3);
		ptr = pci_adp - (long)start_addr;

		if (ptr == buffer_size)
			ptr = 0;
	}
	if (stream_number == 1) {
		pci_adp = READREG(PCI_ADP1);
		ptr = pci_adp - (size_t) start_addr;

		if (ptr == buffer_size)
			ptr = 0;
	}
	return ptr;
}

unsigned int snd_aw2_saa7146_get_hw_ptr_capture(struct snd_aw2_saa7146 *chip,
						int stream_number,
						unsigned char *start_addr,
						unsigned int buffer_size)
{
	size_t pci_adp = 0;
	size_t ptr = 0;
	if (stream_number == 0) {
		pci_adp = READREG(PCI_ADP2);
		ptr = pci_adp - (size_t) start_addr;

		if (ptr == buffer_size)
			ptr = 0;
	}
	return ptr;
}

void snd_aw2_saa7146_use_digital_input(struct snd_aw2_saa7146 *chip,
				       int use_digital)
{
	/* FIXME: switch between analog and digital input does not always work.
	   It can produce a kind of white noise. It seams that received data
	   are inverted sometime (endian inversion). Why ? I don't know, maybe
	   a problem of synchronization... However for the time being I have
	   not found the problem. Workaround: switch again (and again) between
	   digital and analog input until it works. */
	if (use_digital)
		WRITEREG(0x40, GPIO_CTRL);
	else
		WRITEREG(0x50, GPIO_CTRL);
}

int snd_aw2_saa7146_is_using_digital_input(struct snd_aw2_saa7146 *chip)
{
	unsigned int reg_val = READREG(GPIO_CTRL);
	if ((reg_val & 0xFF) == 0x40)
		return 1;
	else
		return 0;
}

Annotation

Implementation Notes