To create a rawmidi object, call snd_mpu401_uart_new().

  struct snd_rawmidi *rmidi;
  snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
                      irq, irq_flags, &rmidi);


The first argument is the card pointer, and the second is the index of this component. You can create up to 8 rawmidi devices.

The third argument is the type of the hardware, MPU401_HW_XXX. If it's not a special one, you can use MPU401_HW_MPU401.

The 4th argument is the I/O port address. Many backward-compatible MPU401 have an I/O port such as 0x330. Or, it might be a part of its own PCI I/O region. It depends on the chip design.

The 5th argument is a bitflag for additional information. When the I/O port address above is part of the PCI I/O region, the MPU401 I/O port might have been already allocated (reserved) by the driver itself. In such a case, pass a bit flag MPU401_INFO_INTEGRATED, and the mpu401-uart layer will allocate the I/O ports by itself.

When the controller supports only the input or output MIDI stream, pass the MPU401_INFO_INPUT or MPU401_INFO_OUTPUT bitflag, respectively. Then the rawmidi instance is created as a single stream.

MPU401_INFO_MMIO bitflag is used to change the access method to MMIO (via readb and writeb) instead of iob and outb. In this case, you have to pass the iomapped address to snd_mpu401_uart_new().

When MPU401_INFO_TX_IRQ is set, the output stream isn't checked in the default interrupt handler. The driver needs to call snd_mpu401_uart_interrupt_tx() by itself to start processing the output stream in the irq handler.

Usually, the port address corresponds to the command port and port + 1 corresponds to the data port. If not, you may change the cport field of struct snd_mpu401 manually afterward. However, snd_mpu401 pointer is not returned explicitly by snd_mpu401_uart_new(). You need to cast rmidi->private_data to snd_mpu401 explicitly,

  struct snd_mpu401 *mpu;
  mpu = rmidi->private_data;


and reset the cport as you like:

  mpu->cport = my_own_control_port;


The 6th argument specifies the irq number for UART. If the irq is already allocated, pass 0 to the 7th argument (irq_flags). Otherwise, pass the flags for irq allocation (SA_XXX bits) to it, and the irq will be reserved by the mpu401-uart layer. If the card doesn't generate UART interrupts, pass -1 as the irq number. Then a timer interrupt will be invoked for polling.