Глава 8. Интерфейс MIDI (MPU401-UART) |
Предыдущая Содержание Следующая |
Общие сведенияМногие звуковые карты имеют встроенные интерфейсы MIDI (MPU401-UART). Если звуковая карта поддерживает стандартный интерфейс MPU401-UART, скорее всего, можно использовать ALSA MPU401-UART API. MPU401-UART API определён в <sound/mpu401.h>.
Некоторые звуковые чипы имеют похожую, но немного отличающуюся реализацию mpu401. Например, emu10k1 имеет свои собственные процедуры mpu401. КонструкторЧтобы создать объект rawmidi, вызовите snd_mpu401_uart_new().
struct snd_rawmidi *rmidi; snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags, irq, irq_flags, &rmidi);
Первым аргументом является указатель карты, а вторым - индекс этого компонента. Можно создать до 8 устройств rawmidi.
Третий аргумент - тип оборудования, MPU401_HW_XXX. Если он не какой-то особый, можно использовать MPU401_HW_MPU401.
4-м аргументом является адрес порта ввода/вывода. Многие обратно совместимые MPU401 имеют такой порт ввода/вывода, как 0x330. Или он может быть частью его собственной области ввода/вывода PCI. Это зависит от дизайна чипа.
Пятый аргумент - битовый флаг для дополнительной информации. Когда вышеупомянутый адрес порта ввода/вывода является частью области ввода/вывода PCI, порт ввода/вывода MPU401 может быть уже выделен (зарезервирован) самим драйвером. В таком случае передайте битовый флаг MPU401_INFO_INTEGRATED и уровень MPU401-UART выделит порты ввода/вывода самостоятельно.
Если контроллер поддерживает только поток ввод или вывода MIDI, передайте соответственно битовый флаг MPU401_INFO_INPUT или MPU401_INFO_OUTPUT. В таком случае экземпляр rawmidi создаётся как однопоточный.
Битовый флаг MPU401_INFO_MMIO используется для изменения метода доступа к MMIO (через readb и writeb) вместо iob и outb. В этом случае в snd_mpu401_uart_new() необходимо передать отображённый в пространство памяти адрес ввода/вывода.
Когда установлен MPU401_INFO_TX_IRQ, выходной поток не контролируется в обработчике прерывания, установленном по умолчанию. Драйвер должен сам вызывать snd_mpu401_uart_interrupt_tx() для начала обработки выходного потока в обработчике прерывания.
Обычно, адрес порта соответствует командному порту, а адрес порта + 1 соответствует порту данных. Если это не так, можно изменить поле cport структуры snd_mpu401 вручную позже. Однако, указатель snd_mpu401 функцией snd_mpu401_uart_new() не возвращается явно. Вы должны явно привести rmidi->private_data к типу snd_mpu401,
struct snd_mpu401 *mpu; mpu = rmidi->private_data;
и переустановить cport, как требуется:
mpu->cport = my_own_control_port;
(а как установить порт данных?)
Шестой аргумент указывает номер прерывания для UART. Если это прерывание уже выделено, передайте 0 в 7-м аргументе (irq_flags). В противном случае передайте флаги для выделения прерывания (биты SA_XXX) к нему, и прерывание будет зарезервировано уровнем MPU401-UART. Если карта не генерирует прерывания UART, в качестве номера прерывания передайте -1. Тогда для опроса будут вызываться прерывания по таймеру. Обработчик прерыванияЕсли прерывание выделено в snd_mpu401_uart_new(), используется закрытый (встроенный) обработчик прерывания, поэтому не придётся ничего делать, кроме создания создания объекта MPU401. В противном случае, необходимо явно вызывать snd_mpu401_uart_interrupt(), если прерывание UART вызывается и управляется в собственном обработчике прерывания.
В этом случае в качестве второго аргумента snd_mpu401_uart_interrupt() необходимо передать private_data возвращённого из snd_mpu401_uart_new() объекта rawmidi.
snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);
|
Предыдущая Содержание Следующая |