sound/drivers/mpu401/mpu401_uart.c

Source file repositories/reference/linux-study-clean/sound/drivers/mpu401/mpu401_uart.c

File Facts

System
Linux kernel
Corpus path
sound/drivers/mpu401/mpu401_uart.c
Extension
.c
Size
15398 bytes
Lines
596
Domain
Driver Families
Bucket
sound/drivers
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
		guard(spinlock_irqsave)(&mpu->output_lock);
		snd_mpu401_uart_output_write(mpu);
	}
}

static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
{
	if (mpu->info_flags & MPU401_INFO_INPUT) {
		guard(spinlock_irqsave)(&mpu->input_lock);
		if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
			snd_mpu401_uart_input_read(mpu);
		else
			snd_mpu401_uart_clear_rx(mpu);
	}
	if (! (mpu->info_flags & MPU401_INFO_TX_IRQ))
		/* ok. for better Tx performance try do some output
		   when input is done */
		uart_interrupt_tx(mpu);
}

/**
 * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
 * @irq: the irq number
 * @dev_id: mpu401 instance
 *
 * Processes the interrupt for MPU401-UART i/o.
 *
 * Return: %IRQ_HANDLED if the interrupt was handled. %IRQ_NONE otherwise.
 */
irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id)
{
	struct snd_mpu401 *mpu = dev_id;
	
	if (!mpu)
		return IRQ_NONE;
	_snd_mpu401_uart_interrupt(mpu);
	return IRQ_HANDLED;
}

EXPORT_SYMBOL(snd_mpu401_uart_interrupt);

/**
 * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler
 * @irq: the irq number
 * @dev_id: mpu401 instance
 *
 * Processes the interrupt for MPU401-UART output.
 *
 * Return: %IRQ_HANDLED if the interrupt was handled. %IRQ_NONE otherwise.
 */
irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id)
{
	struct snd_mpu401 *mpu = dev_id;
	
	if (!mpu)
		return IRQ_NONE;
	uart_interrupt_tx(mpu);
	return IRQ_HANDLED;
}

EXPORT_SYMBOL(snd_mpu401_uart_interrupt_tx);

/*
 * timer callback
 * reprogram the timer and call the interrupt job
 */
static void snd_mpu401_uart_timer(struct timer_list *t)
{
	struct snd_mpu401 *mpu = timer_container_of(mpu, t, timer);

	scoped_guard(spinlock_irqsave, &mpu->timer_lock) {
		/*mpu->mode |= MPU401_MODE_TIMER;*/
		mod_timer(&mpu->timer,  1 + jiffies);
	}
	if (mpu->rmidi)
		_snd_mpu401_uart_interrupt(mpu);
}

/*
 * initialize the timer callback if not programmed yet
 */
static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
{
	guard(spinlock_irqsave)(&mpu->timer_lock);
	if (mpu->timer_invoked == 0) {
		timer_setup(&mpu->timer, snd_mpu401_uart_timer, 0);
		mod_timer(&mpu->timer, 1 + jiffies);
	} 
	mpu->timer_invoked |= input ? MPU401_MODE_INPUT_TIMER :

Annotation

Implementation Notes