1 | /*
|
---|
2 | * Driver for generic MPU-401 boards (UART mode only)
|
---|
3 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
|
---|
4 | *
|
---|
5 | *
|
---|
6 | * This program is free software; you can redistribute it and/or modify
|
---|
7 | * it under the terms of the GNU General Public License as published by
|
---|
8 | * the Free Software Foundation; either version 2 of the License, or
|
---|
9 | * (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This program is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | * GNU General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU General Public License
|
---|
17 | * along with this program; if not, write to the Free Software
|
---|
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
---|
19 | *
|
---|
20 | */
|
---|
21 |
|
---|
22 | #define SNDRV_MAIN_OBJECT_FILE
|
---|
23 | #include <sound/driver.h>
|
---|
24 | #include <sound/mpu401.h>
|
---|
25 | #define SNDRV_GET_ID
|
---|
26 | #include <sound/initval.h>
|
---|
27 |
|
---|
28 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
|
---|
29 | MODULE_DESCRIPTION("MPU-401 UART");
|
---|
30 | MODULE_LICENSE("GPL");
|
---|
31 | MODULE_CLASSES("{sound}");
|
---|
32 |
|
---|
33 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
|
---|
34 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
|
---|
35 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
|
---|
36 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
|
---|
37 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
|
---|
38 | #ifdef CONFIG_X86_PC9800
|
---|
39 | static int pc98ii[SNDRV_CARDS]; /* PC98-II dauther board */
|
---|
40 | #endif
|
---|
41 |
|
---|
42 | MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
|
---|
43 | MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
|
---|
44 | MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
|
---|
45 | MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
|
---|
46 | MODULE_PARM_DESC(id, "ID string for MPU-401 device.");
|
---|
47 | MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
|
---|
48 | MODULE_PARM(enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
|
---|
49 | MODULE_PARM_DESC(enable, "Enable MPU-401 device.");
|
---|
50 | MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
|
---|
51 | MODULE_PARM(port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
|
---|
52 | MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
|
---|
53 | MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
|
---|
54 | MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
|
---|
55 | MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
|
---|
56 | MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
|
---|
57 | #ifdef CONFIG_X86_PC9800
|
---|
58 | MODULE_PARM(pc98ii, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
|
---|
59 | MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
|
---|
60 | MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
|
---|
61 | #endif
|
---|
62 |
|
---|
63 | static snd_card_t *snd_mpu401_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
|
---|
64 |
|
---|
65 | static int __init snd_card_mpu401_probe(int dev)
|
---|
66 | {
|
---|
67 | snd_card_t *card;
|
---|
68 | int err;
|
---|
69 |
|
---|
70 | if (port[dev] == SNDRV_AUTO_PORT) {
|
---|
71 | snd_printk("specify port\n");
|
---|
72 | return -EINVAL;
|
---|
73 | }
|
---|
74 | if (irq[dev] == SNDRV_AUTO_IRQ) {
|
---|
75 | snd_printk("specify or disable IRQ port\n");
|
---|
76 | return -EINVAL;
|
---|
77 | }
|
---|
78 |
|
---|
79 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
|
---|
80 | if (card == NULL)
|
---|
81 | return -ENOMEM;
|
---|
82 | if (snd_mpu401_uart_new(card, 0,
|
---|
83 | #ifdef CONFIG_X86_PC9800
|
---|
84 | pc98ii[dev] ? MPU401_HW_PC98II :
|
---|
85 | #endif
|
---|
86 | MPU401_HW_MPU401,
|
---|
87 | port[dev], 0,
|
---|
88 | irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
|
---|
89 | printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
|
---|
90 | snd_card_free(card);
|
---|
91 | return -ENODEV;
|
---|
92 | }
|
---|
93 | strcpy(card->driver, "MPU-401 UART");
|
---|
94 | strcpy(card->shortname, card->driver);
|
---|
95 | sprintf(card->longname, "%s at 0x%lx, ", card->shortname, port[dev]);
|
---|
96 | if (irq[dev] >= 0) {
|
---|
97 | sprintf(card->longname + strlen(card->longname), "IRQ %d", irq[dev]);
|
---|
98 | } else {
|
---|
99 | strcat(card->longname, "polled");
|
---|
100 | }
|
---|
101 | if ((err = snd_card_register(card)) < 0) {
|
---|
102 | snd_card_free(card);
|
---|
103 | return err;
|
---|
104 | }
|
---|
105 | snd_mpu401_cards[dev] = card;
|
---|
106 | return 0;
|
---|
107 | }
|
---|
108 |
|
---|
109 | static int __init alsa_card_mpu401_init(void)
|
---|
110 | {
|
---|
111 | int dev, cards = 0;
|
---|
112 |
|
---|
113 | for (dev = 0; dev < SNDRV_CARDS; dev++) {
|
---|
114 | if (!enable[dev])
|
---|
115 | continue;
|
---|
116 | if (snd_card_mpu401_probe(dev) >= 0)
|
---|
117 | cards++;
|
---|
118 | }
|
---|
119 | if (!cards) {
|
---|
120 | #ifdef MODULE
|
---|
121 | snd_printk("MPU-401 device not found or device busy\n");
|
---|
122 | #endif
|
---|
123 | return -ENODEV;
|
---|
124 | }
|
---|
125 | return 0;
|
---|
126 | }
|
---|
127 |
|
---|
128 | static void __exit alsa_card_mpu401_exit(void)
|
---|
129 | {
|
---|
130 | int idx;
|
---|
131 |
|
---|
132 | for (idx = 0; idx < SNDRV_CARDS; idx++)
|
---|
133 | snd_card_free(snd_mpu401_cards[idx]);
|
---|
134 | }
|
---|
135 |
|
---|
136 | module_init(alsa_card_mpu401_init)
|
---|
137 | module_exit(alsa_card_mpu401_exit)
|
---|
138 |
|
---|
139 | #ifndef MODULE
|
---|
140 |
|
---|
141 | /* format is: snd-mpu401=enable,index,id,port,irq */
|
---|
142 |
|
---|
143 | static int __init alsa_card_mpu401_setup(char *str)
|
---|
144 | {
|
---|
145 | static unsigned __initdata nr_dev = 0;
|
---|
146 |
|
---|
147 | if (nr_dev >= SNDRV_CARDS)
|
---|
148 | return 0;
|
---|
149 | (void)(get_option(&str,&enable[nr_dev]) == 2 &&
|
---|
150 | get_option(&str,&index[nr_dev]) == 2 &&
|
---|
151 | get_id(&str,&id[nr_dev]) == 2 &&
|
---|
152 | #ifdef CONFIG_X86_PC9800
|
---|
153 | get_option(&str,&pc98ii[nr_dev]) == 2 &&
|
---|
154 | #endif
|
---|
155 | get_option_long(&str,&port[nr_dev]) == 2 &&
|
---|
156 | get_option(&str,&irq[nr_dev]) == 2);
|
---|
157 | nr_dev++;
|
---|
158 | return 1;
|
---|
159 | }
|
---|
160 |
|
---|
161 | __setup("snd-mpu401=", alsa_card_mpu401_setup);
|
---|
162 |
|
---|
163 | #endif /* ifndef MODULE */
|
---|