1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Routines for control of MPU-401 in UART mode
6 * Modified for the Aureal Vortex based Soundcards
7 * by Manuel Jander (mjande@embedded.cl).
10 #include <linux/time.h>
11 #include <linux/init.h>
12 #include <sound/core.h>
13 #include <sound/mpu401.h>
16 /* Check for mpu401 mmio support. */
17 /* MPU401 legacy support is only provided as a emergency fallback *
18 * for older versions of ALSA. Its usage is strongly discouraged. */
19 #ifndef MPU401_HW_AUREAL
20 #define VORTEX_MPU401_LEGACY
23 /* Vortex MPU401 defines. */
24 #define MIDI_CLOCK_DIV 0x61
25 /* Standart MPU401 defines. */
26 #define MPU401_RESET 0xff
27 #define MPU401_ENTER_UART 0x3f
28 #define MPU401_ACK 0xfe
30 static int snd_vortex_midi(vortex_t
*vortex
)
32 struct snd_rawmidi
*rmidi
;
34 struct snd_mpu401
*mpu
;
37 #ifdef VORTEX_MPU401_LEGACY
38 /* EnableHardCodedMPU401Port() */
39 /* Enable Legacy MIDI Interface port. */
40 port
= (0x03 << 5); /* FIXME: static address. 0x330 */
42 (hwread(vortex
->mmio
, VORTEX_CTRL
) & ~CTRL_MIDI_PORT
) |
44 hwwrite(vortex
->mmio
, VORTEX_CTRL
, temp
);
46 /* Disable Legacy MIDI Interface port. */
48 (hwread(vortex
->mmio
, VORTEX_CTRL
) & ~CTRL_MIDI_PORT
) &
50 hwwrite(vortex
->mmio
, VORTEX_CTRL
, temp
);
52 /* Mpu401UartInit() */
54 temp
= hwread(vortex
->mmio
, VORTEX_CTRL2
) & 0xffff00cf;
55 temp
|= (MIDI_CLOCK_DIV
<< 8) | ((mode
>> 24) & 0xff) << 4;
56 hwwrite(vortex
->mmio
, VORTEX_CTRL2
, temp
);
57 hwwrite(vortex
->mmio
, VORTEX_MIDI_CMD
, MPU401_RESET
);
59 /* Check if anything is OK. */
60 temp
= hwread(vortex
->mmio
, VORTEX_MIDI_DATA
);
61 if (temp
!= MPU401_ACK
/*0xfe */ ) {
62 dev_err(vortex
->card
->dev
, "midi port doesn't acknowledge!\n");
65 /* Enable MPU401 interrupts. */
66 hwwrite(vortex
->mmio
, VORTEX_IRQ_CTRL
,
67 hwread(vortex
->mmio
, VORTEX_IRQ_CTRL
) | IRQ_MIDI
);
69 /* Create MPU401 instance. */
70 #ifdef VORTEX_MPU401_LEGACY
72 snd_mpu401_uart_new(vortex
->card
, 0, MPU401_HW_MPU401
, 0x330,
73 MPU401_INFO_IRQ_HOOK
, -1, &rmidi
)) != 0) {
74 hwwrite(vortex
->mmio
, VORTEX_CTRL
,
75 (hwread(vortex
->mmio
, VORTEX_CTRL
) &
76 ~CTRL_MIDI_PORT
) & ~CTRL_MIDI_EN
);
80 port
= (unsigned long)(vortex
->mmio
+ VORTEX_MIDI_DATA
);
82 snd_mpu401_uart_new(vortex
->card
, 0, MPU401_HW_AUREAL
, port
,
83 MPU401_INFO_INTEGRATED
| MPU401_INFO_MMIO
|
84 MPU401_INFO_IRQ_HOOK
, -1, &rmidi
)) != 0) {
85 hwwrite(vortex
->mmio
, VORTEX_CTRL
,
86 (hwread(vortex
->mmio
, VORTEX_CTRL
) &
87 ~CTRL_MIDI_PORT
) & ~CTRL_MIDI_EN
);
90 mpu
= rmidi
->private_data
;
91 mpu
->cport
= (unsigned long)(vortex
->mmio
+ VORTEX_MIDI_CMD
);
93 /* Overwrite MIDI name */
94 snprintf(rmidi
->name
, sizeof(rmidi
->name
), "%s MIDI %d", CARD_NAME_SHORT
, vortex
->card
->number
);
96 vortex
->rmidi
= rmidi
;