sound/pci/vx222/vx222_ops.c

Source file repositories/reference/linux-study-clean/sound/pci/vx222/vx222_ops.c

File Facts

System
Linux kernel
Corpus path
sound/pci/vx222/vx222_ops.c
Extension
.c
Size
34804 bytes
Lines
1025
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 ((data & VX_STATUS_VAL_TEST1_MASK) == VX_STATUS_VAL_TEST1_MASK) {
			dev_dbg(_chip->card->dev, "bad! #3\n");
			return -ENODEV;
		}

		/* We write 0 on CDSP.TEST1. We should get 1 on STATUS.TEST1. */
		vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_TEST1_MASK);
		vx_inl(chip, ISR);
		data = vx_inl(chip, STATUS);
		if (! (data & VX_STATUS_VAL_TEST1_MASK)) {
			dev_dbg(_chip->card->dev, "bad! #4\n");
			return -ENODEV;
		}
	}
	dev_dbg(_chip->card->dev, "ok, xilinx fine.\n");
	return 0;
}


/**
 * vx2_setup_pseudo_dma - set up the pseudo dma read/write mode.
 * @chip: VX core instance
 * @do_write: 0 = read, 1 = set up for DMA write
 */
static void vx2_setup_pseudo_dma(struct vx_core *chip, int do_write)
{
	/* Interrupt mode and HREQ pin enabled for host transmit data transfers
	 * (in case of the use of the pseudo-dma facility).
	 */
	vx_outl(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);

	/* Reset the pseudo-dma register (in case of the use of the
	 * pseudo-dma facility).
	 */
	vx_outl(chip, RESET_DMA, 0);
}

/*
 * vx_release_pseudo_dma - disable the pseudo-DMA mode
 */
static inline void vx2_release_pseudo_dma(struct vx_core *chip)
{
	/* HREQ pin disabled. */
	vx_outl(chip, ICR, 0);
}



/* pseudo-dma write */
static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
			  struct vx_pipe *pipe, int count)
{
	unsigned long port = vx2_reg_addr(chip, VX_DMA);
	int offset = pipe->hw_ptr;
	u32 *addr = (u32 *)(runtime->dma_area + offset);

	if (snd_BUG_ON(count % 4))
		return;

	vx2_setup_pseudo_dma(chip, 1);

	/* Transfer using pseudo-dma.
	 */
	if (offset + count >= pipe->buffer_bytes) {
		int length = pipe->buffer_bytes - offset;
		count -= length;
		length >>= 2; /* in 32bit words */
		/* Transfer using pseudo-dma. */
		for (; length > 0; length--) {
			outl(*addr, port);
			addr++;
		}
		addr = (u32 *)runtime->dma_area;
		pipe->hw_ptr = 0;
	}
	pipe->hw_ptr += count;
	count >>= 2; /* in 32bit words */
	/* Transfer using pseudo-dma. */
	for (; count > 0; count--) {
		outl(*addr, port);
		addr++;
	}

	vx2_release_pseudo_dma(chip);
}


/* pseudo dma read */
static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
			 struct vx_pipe *pipe, int count)

Annotation

Implementation Notes