patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / sound / isa / cs423x / pc98.c
1 /*
2  *  Driver for CS4232 on NEC PC9800 series
3  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4  *                   Osamu Tomita <tomita@cinet.co.jp>
5  *                   Takashi Iwai <tiwai@suse.de>
6  *                   Hideaki Okubo <okubo@msh.biglobe.ne.jp>
7  *
8  *
9  *   This program is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU General Public License as published by
11  *   the Free Software Foundation; either version 2 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This program is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with this program; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  *
23  */
24
25 #include <sound/driver.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/moduleparam.h>
29 #include <sound/core.h>
30 #include <sound/cs4231.h>
31 #include <sound/mpu401.h>
32 #include <sound/opl3.h>
33 #include <sound/initval.h>
34 #include "sound_pc9800.h"
35
36 #define chip_t cs4231_t
37
38 MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
39 MODULE_LICENSE("GPL");
40 MODULE_CLASSES("{sound}");
41 MODULE_DESCRIPTION("NEC PC9800 CS4232");
42 MODULE_DEVICES("{{NEC,PC9800}}");
43
44 #define IDENT "PC98-CS4232"
45
46 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
47 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
48 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
49 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;     /* PnP setup */
50 #if 0 /* NOT USED */
51 static long cport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;    /* PnP setup */
52 #endif
53 static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;/* PnP setup */
54 static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;  /* PnP setup */
55 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;        /* 5,7,9,11,12,15 */
56 static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;    /* 9,11,12,15 */
57 static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;       /* 0,1,3,5,6,7 */
58 static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;       /* 0,1,3,5,6,7 */
59 static int pc98ii[SNDRV_CARDS];                         /* PC98II */
60 static int boot_devs;
61
62 module_param_array(index, int, boot_devs, 0444);
63 MODULE_PARM_DESC(index, "Index value for " IDENT " soundcard.");
64 MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
65 module_param_array(id, charp, boot_devs, 0444);
66 MODULE_PARM_DESC(id, "ID string for " IDENT " soundcard.");
67 MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
68 module_param_array(enable, bool, boot_devs, 0444);
69 MODULE_PARM_DESC(enable, "Enable " IDENT " soundcard.");
70 MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
71 module_param_array(port, long, boot_devs, 0444);
72 MODULE_PARM_DESC(port, "Port # for " IDENT " driver.");
73 MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
74 #if 0 /* NOT USED */
75 module_param_array(cport, long, boot_devs, 0444);
76 MODULE_PARM_DESC(cport, "Control port # for " IDENT " driver.");
77 MODULE_PARM_SYNTAX(cport, SNDRV_PORT12_DESC);
78 #endif
79 module_param_array(mpu_port, long, boot_devs, 0444);
80 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " IDENT " driver.");
81 MODULE_PARM_SYNTAX(mpu_port, SNDRV_PORT12_DESC);
82 module_param_array(fm_port, long, boot_devs, 0444);
83 MODULE_PARM_DESC(fm_port, "FM port # for " IDENT " driver.");
84 MODULE_PARM_SYNTAX(fm_port, SNDRV_PORT12_DESC);
85 module_param_array(irq, int, boot_devs, 0444);
86 MODULE_PARM_DESC(irq, "IRQ # for " IDENT " driver.");
87 MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
88 module_param_array(mpu_irq, int, boot_devs, 0444);
89 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " IDENT " driver.");
90 MODULE_PARM_SYNTAX(mpu_irq, SNDRV_IRQ_DESC);
91 module_param_array(dma1, int, boot_devs, 0444);
92 MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
93 MODULE_PARM_SYNTAX(dma1, SNDRV_DMA_DESC);
94 module_param_array(dma2, int, boot_devs, 0444);
95 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
96 MODULE_PARM_SYNTAX(dma2, SNDRV_DMA_DESC);
97 module_param_array(pc98ii, bool, boot_devs, 0444);
98 MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
99 MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
100
101
102 static snd_card_t *snd_pc98_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
103
104 /*
105  * initialize MPU401-UART
106  */
107
108 static int __init pc98_mpu401_init(int irq)
109 {
110 #include "pc9801_118_magic.h"
111 #define outp118(reg,data) outb((reg),0x148e);outb((data),0x148f)
112 #define WAIT118 outb(0x00,0x5f)
113         int     mpu_intr, count;
114 #ifdef OOKUBO_ORIGINAL
115         int     err = 0;
116 #endif /* OOKUBO_ORIGINAL */
117
118         switch (irq) {
119         case 3:
120                 mpu_intr = 3;
121                 break;
122         case 5:
123                 mpu_intr = 2;
124                 break;
125         case 6:
126                 mpu_intr = 1;
127                 break;
128         case 10:
129                 mpu_intr = 0;
130                 break;
131         default:
132                 snd_printk(KERN_ERR IDENT ": Bad IRQ %d\n", irq);
133                 return -EINVAL;
134         }
135
136         outp118(0x21, mpu_intr);
137         WAIT118;
138         outb(0x00, 0x148e);
139         if (inb(0x148f) & 0x08) {
140                 snd_printk(KERN_INFO IDENT ": No MIDI daughter board found\n");
141                 return 0;
142         }
143
144         outp118(0x20, 0x00);
145         outp118(0x05, 0x04);
146         for (count = 0; count < 35000; count ++)
147                 WAIT118;
148         outb(0x05, 0x148e);
149         for (count = 0; count < 65000; count ++)
150                 if (inb(0x148f) == 0x04)
151                         goto set_mode_118;
152         snd_printk(KERN_ERR IDENT ": MIDI daughter board initialize failed at stage1\n\n");
153         return -EINVAL;
154
155  set_mode_118:
156         outp118(0x05, 0x0c);
157         outb(0xaa, 0x485);
158         outb(0x99, 0x485);
159         outb(0x2a, 0x485);
160         for (count = 0; count < sizeof(Data0485_99); count ++) {
161                 outb(Data0485_99[count], 0x485);
162                 WAIT118;
163         }
164
165         outb(0x00, 0x486);
166         outb(0xaa, 0x485);
167         outb(0x9e, 0x485);
168         outb(0x2a, 0x485);
169         for (count = 0; count < sizeof(Data0485_9E); count ++)
170                 if (inb(0x485) != Data0485_9E[count]) {
171 #ifdef OOKUBO_ORIGINAL
172                         err = 1;
173 #endif /* OOKUBO_ORIGINAL */
174                         break;
175                 }
176         outb(0x00, 0x486);
177         for (count = 0; count < 2000; count ++)
178                 WAIT118;
179 #ifdef OOKUBO_ORIGINAL
180         if (!err) {
181                 outb(0xaa, 0x485);
182                 outb(0x36, 0x485);
183                 outb(0x28, 0x485);
184                 for (count = 0; count < sizeof(Data0485_36); count ++)
185                         outb(Data0485_36[count], 0x485);
186                 outb(0x00, 0x486);
187                 for (count = 0; count < 1500; count ++)
188                         WAIT118;
189                 outp118(0x05, inb(0x148f) | 0x08);
190                 outb(0xff, 0x148c);
191                 outp118(0x05, inb(0x148f) & 0xf7);
192                 for (count = 0; count < 1500; count ++)
193                         WAIT118;
194         }
195 #endif /* OOKUBO_ORIGINAL */
196
197         outb(0xaa, 0x485);
198         outb(0xa9, 0x485);
199         outb(0x21, 0x485);
200         for (count = 0; count < sizeof(Data0485_A9); count ++) {
201                 outb(Data0485_A9[count], 0x485);
202                 WAIT118;
203         }
204
205         outb(0x00, 0x486);
206         outb(0xaa, 0x485);
207         outb(0x0c, 0x485);
208         outb(0x20, 0x485);
209         for (count = 0; count < sizeof(Data0485_0C); count ++) {
210                 outb(Data0485_0C[count], 0x485);
211                 WAIT118;
212         }
213
214         outb(0x00, 0x486);
215         outb(0xaa, 0x485);
216         outb(0x66, 0x485);
217         outb(0x20, 0x485);
218         for (count = 0; count < sizeof(Data0485_66); count ++) {
219                 outb(Data0485_66[count], 0x485);
220                 WAIT118;
221         }
222
223         outb(0x00, 0x486);
224         outb(0xaa, 0x485);
225         outb(0x60, 0x485);
226         outb(0x20, 0x485);
227         for (count = 0; count < sizeof(Data0485_60); count ++) {
228                 outb(Data0485_60[count], 0x485);
229                 WAIT118;
230         }
231
232         outb(0x00, 0x486);
233         outp118(0x05, 0x04);
234         outp118(0x05, 0x00);
235         for (count = 0; count < 35000; count ++)
236                 WAIT118;
237         outb(0x05, 0x148e);
238         for (count = 0; count < 65000; count ++)
239                 if (inb(0x148f) == 0x00)
240                         goto end_mode_118;
241         snd_printk(KERN_ERR IDENT ": MIDI daughter board initialize failed at stage2\n");
242         return -EINVAL;
243
244  end_mode_118:
245         outb(0x3f, 0x148d);
246         snd_printk(KERN_INFO IDENT ": MIDI daughter board initialized\n");
247         return 0;
248 }
249
250 static int __init pc98_cs4231_chip_init(int dev)
251 {
252         int intr_bits, intr_bits2, dma_bits;
253
254         switch (irq[dev]) {
255         case 3:
256                 intr_bits = 0x08;
257                 intr_bits2 = 0x03;
258                 break;
259         case 5:
260                 intr_bits = 0x10;
261                 intr_bits2 = 0x08;
262                 break;
263         case 10:
264                 intr_bits = 0x18;
265                 intr_bits2 = 0x02;
266                 break;
267         case 12:
268                 intr_bits = 0x20;
269                 intr_bits2 = 0x00;
270                 break;
271         default:
272                 snd_printk(KERN_ERR IDENT ": Bad IRQ %d\n", irq[dev]);
273                 return -EINVAL;
274         }
275
276         switch (dma1[dev]) {
277         case 0:
278                 dma_bits = 0x01;
279                 break;
280         case 1:
281                 dma_bits = 0x02;
282                 break;
283         case 3:
284                 dma_bits = 0x03;
285                 break;
286         default:
287                 snd_printk(KERN_ERR IDENT ": Bad DMA %d\n", dma1[dev]);
288                 return -EINVAL;
289         }
290
291         if (dma2[dev] >= 2) {
292                 snd_printk(KERN_ERR IDENT ": Bad DMA %d\n", dma2[dev]);
293                 return -EINVAL;
294         }
295
296         outb(dma1[dev], 0x29);          /* dma1 boundary 64KB */
297         if (dma1[dev] != dma2[dev] && dma2[dev] >= 0) {
298                 outb(0, 0x5f);          /* wait */
299                 outb(dma2[dev], 0x29);  /* dma2 boundary 64KB */
300                 intr_bits |= 0x04;
301         }
302
303         if (PC9800_SOUND_ID() == PC9800_SOUND_ID_118) {
304                 /* Set up CanBe control registers. */
305                 snd_printd(KERN_INFO "Setting up CanBe Sound System\n");
306                 outb(inb(PC9800_SOUND_IO_ID) | 0x03, PC9800_SOUND_IO_ID);
307                 outb(0x01, 0x0f4a);
308                 outb(intr_bits2, 0x0f4b);
309         }
310
311         outb(intr_bits | dma_bits, 0xf40);
312         return 0;
313 }
314
315
316 static int __init snd_card_pc98_probe(int dev)
317 {
318         snd_card_t *card;
319         snd_pcm_t *pcm = NULL;
320         cs4231_t *chip;
321         opl3_t *opl3;
322         int err;
323
324         if (port[dev] == SNDRV_AUTO_PORT) {
325                 snd_printk(KERN_ERR IDENT ": specify port\n");
326                 return -EINVAL;
327         }
328         card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
329         if (card == NULL)
330                 return -ENOMEM;
331
332         if ((err = pc98_cs4231_chip_init(dev)) < 0) {
333                 snd_card_free(card);
334                 return err;
335         }
336
337         if ((err = snd_cs4231_create(card,
338                                      port[dev],
339                                      -1,
340                                      irq[dev],
341                                      dma1[dev],
342                                      dma2[dev],
343                                      CS4231_HW_DETECT,
344                                      0,
345                                      &chip)) < 0) {
346                 snd_card_free(card);
347                 return err;
348         }
349         if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
350                 snd_card_free(card);
351                 return err;
352         }
353         if ((err = snd_cs4231_mixer(chip)) < 0) {
354                 snd_card_free(card);
355                 return err;
356         }
357
358         if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) {
359                 snd_card_free(card);
360                 return err;
361         }
362
363         if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
364                 /* ??? */
365                 outb(0x00, fm_port[dev] + 6);
366                 inb(fm_port[dev] + 7);
367                 /* Enable OPL-3 Function */
368                 outb(inb(PC9800_SOUND_IO_ID) | 0x03, PC9800_SOUND_IO_ID);
369                 if (snd_opl3_create(card,
370                                     fm_port[dev], fm_port[dev] + 2,
371                                     OPL3_HW_OPL3_PC98, 0, &opl3) < 0) {
372                         printk(KERN_ERR IDENT ": OPL3 not detected\n");
373                 } else {
374                         if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
375                                 snd_card_free(card);
376                                 return err;
377                         }
378                 }
379         }
380
381         if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
382                 err = pc98_mpu401_init(mpu_irq[dev]);
383                 if (! err) {
384                         err = snd_mpu401_uart_new(card, 0,
385                                                   pc98ii[dev] ? MPU401_HW_PC98II : MPU401_HW_MPU401,
386                                                   mpu_port[dev], 0,
387                                                   mpu_irq[dev], SA_INTERRUPT, NULL);
388                         if (err < 0)
389                                 snd_printk(KERN_INFO IDENT ": MPU401 not detected\n");
390                 }
391         }
392
393         strcpy(card->driver, pcm->name);
394         strcpy(card->shortname, pcm->name);
395         sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i",
396                 pcm->name,
397                 chip->port,
398                 irq[dev],
399                 dma1[dev]);
400         if (dma2[dev] >= 0)
401                 sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
402         if ((err = snd_card_register(card)) < 0) {
403                 snd_card_free(card);
404                 return err;
405         }
406         snd_pc98_cards[dev] = card;
407         return 0;
408 }
409
410 static int __init alsa_card_pc98_init(void)
411 {
412         int dev, cards = 0;
413
414         for (dev = 0; dev < SNDRV_CARDS; dev++) {
415                 if (!enable[dev])
416                         continue;
417                 if (snd_card_pc98_probe(dev) >= 0)
418                         cards++;
419         }
420         if (!cards) {
421 #ifdef MODULE
422                 printk(KERN_ERR IDENT " soundcard not found or device busy\n");
423 #endif
424                 return -ENODEV;
425         }
426         return 0;
427 }
428
429 static void __exit alsa_card_pc98_exit(void)
430 {
431         int idx;
432
433         for (idx = 0; idx < SNDRV_CARDS; idx++)
434                 snd_card_free(snd_pc98_cards[idx]);
435 }
436
437 module_init(alsa_card_pc98_init)
438 module_exit(alsa_card_pc98_exit)