~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/isa/msnd/msnd_pinnacle.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*********************************************************************
  3  *
  4  * Linux multisound pinnacle/fiji driver for ALSA.
  5  *
  6  * 2002/06/30 Karsten Wiese:
  7  *      for now this is only used to build a pinnacle / fiji driver.
  8  *      the OSS parent of this code is designed to also support
  9  *      the multisound classic via the file msnd_classic.c.
 10  *      to make it easier for some brave heart to implemt classic
 11  *      support in alsa, i left all the MSND_CLASSIC tokens in this file.
 12  *      but for now this untested & undone.
 13  *
 14  * ripped from linux kernel 2.4.18 by Karsten Wiese.
 15  *
 16  * the following is a copy of the 2.4.18 OSS FREE file-heading comment:
 17  *
 18  * Turtle Beach MultiSound Sound Card Driver for Linux
 19  * msnd_pinnacle.c / msnd_classic.c
 20  *
 21  * -- If MSND_CLASSIC is defined:
 22  *
 23  *     -> driver for Turtle Beach Classic/Monterey/Tahiti
 24  *
 25  * -- Else
 26  *
 27  *     -> driver for Turtle Beach Pinnacle/Fiji
 28  *
 29  * 12-3-2000  Modified IO port validation  Steve Sycamore
 30  *
 31  * Copyright (C) 1998 Andrew Veliath
 32  *
 33  ********************************************************************/
 34 
 35 #include <linux/kernel.h>
 36 #include <linux/module.h>
 37 #include <linux/interrupt.h>
 38 #include <linux/types.h>
 39 #include <linux/delay.h>
 40 #include <linux/ioport.h>
 41 #include <linux/firmware.h>
 42 #include <linux/isa.h>
 43 #include <linux/isapnp.h>
 44 #include <linux/irq.h>
 45 #include <linux/io.h>
 46 
 47 #include <sound/core.h>
 48 #include <sound/initval.h>
 49 #include <sound/asound.h>
 50 #include <sound/pcm.h>
 51 #include <sound/mpu401.h>
 52 
 53 #ifdef MSND_CLASSIC
 54 # ifndef __alpha__
 55 #  define SLOWIO
 56 # endif
 57 #endif
 58 #include "msnd.h"
 59 #ifdef MSND_CLASSIC
 60 #  include "msnd_classic.h"
 61 #  define LOGNAME                       "msnd_classic"
 62 #  define DEV_NAME                      "msnd-classic"
 63 #else
 64 #  include "msnd_pinnacle.h"
 65 #  define LOGNAME                       "snd_msnd_pinnacle"
 66 #  define DEV_NAME                      "msnd-pinnacle"
 67 #endif
 68 
 69 static void set_default_audio_parameters(struct snd_msnd *chip)
 70 {
 71         chip->play_sample_size = snd_pcm_format_width(DEFSAMPLESIZE);
 72         chip->play_sample_rate = DEFSAMPLERATE;
 73         chip->play_channels = DEFCHANNELS;
 74         chip->capture_sample_size = snd_pcm_format_width(DEFSAMPLESIZE);
 75         chip->capture_sample_rate = DEFSAMPLERATE;
 76         chip->capture_channels = DEFCHANNELS;
 77 }
 78 
 79 static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage)
 80 {
 81         switch (HIBYTE(wMessage)) {
 82         case HIMT_PLAY_DONE: {
 83                 if (chip->banksPlayed < 3)
 84                         snd_printdd("%08X: HIMT_PLAY_DONE: %i\n",
 85                                 (unsigned)jiffies, LOBYTE(wMessage));
 86 
 87                 if (chip->last_playbank == LOBYTE(wMessage)) {
 88                         snd_printdd("chip.last_playbank == LOBYTE(wMessage)\n");
 89                         break;
 90                 }
 91                 chip->banksPlayed++;
 92 
 93                 if (test_bit(F_WRITING, &chip->flags))
 94                         snd_msnd_DAPQ(chip, 0);
 95 
 96                 chip->last_playbank = LOBYTE(wMessage);
 97                 chip->playDMAPos += chip->play_period_bytes;
 98                 if (chip->playDMAPos > chip->playLimit)
 99                         chip->playDMAPos = 0;
100                 snd_pcm_period_elapsed(chip->playback_substream);
101 
102                 break;
103         }
104         case HIMT_RECORD_DONE:
105                 if (chip->last_recbank == LOBYTE(wMessage))
106                         break;
107                 chip->last_recbank = LOBYTE(wMessage);
108                 chip->captureDMAPos += chip->capturePeriodBytes;
109                 if (chip->captureDMAPos > (chip->captureLimit))
110                         chip->captureDMAPos = 0;
111 
112                 if (test_bit(F_READING, &chip->flags))
113                         snd_msnd_DARQ(chip, chip->last_recbank);
114 
115                 snd_pcm_period_elapsed(chip->capture_substream);
116                 break;
117 
118         case HIMT_DSP:
119                 switch (LOBYTE(wMessage)) {
120 #ifndef MSND_CLASSIC
121                 case HIDSP_PLAY_UNDER:
122 #endif
123                 case HIDSP_INT_PLAY_UNDER:
124                         snd_printd(KERN_WARNING LOGNAME ": Play underflow %i\n",
125                                 chip->banksPlayed);
126                         if (chip->banksPlayed > 2)
127                                 clear_bit(F_WRITING, &chip->flags);
128                         break;
129 
130                 case HIDSP_INT_RECORD_OVER:
131                         snd_printd(KERN_WARNING LOGNAME ": Record overflow\n");
132                         clear_bit(F_READING, &chip->flags);
133                         break;
134 
135                 default:
136                         snd_printd(KERN_WARNING LOGNAME
137                                    ": DSP message %d 0x%02x\n",
138                                    LOBYTE(wMessage), LOBYTE(wMessage));
139                         break;
140                 }
141                 break;
142 
143         case HIMT_MIDI_IN_UCHAR:
144                 if (chip->msndmidi_mpu)
145                         snd_msndmidi_input_read(chip->msndmidi_mpu);
146                 break;
147 
148         default:
149                 snd_printd(KERN_WARNING LOGNAME ": HIMT message %d 0x%02x\n",
150                            HIBYTE(wMessage), HIBYTE(wMessage));
151                 break;
152         }
153 }
154 
155 static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id)
156 {
157         struct snd_msnd *chip = dev_id;
158         void __iomem *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
159         u16 head, tail, size;
160 
161         /* Send ack to DSP */
162         /* inb(chip->io + HP_RXL); */
163 
164         /* Evaluate queued DSP messages */
165         head = readw(chip->DSPQ + JQS_wHead);
166         tail = readw(chip->DSPQ + JQS_wTail);
167         size = readw(chip->DSPQ + JQS_wSize);
168         if (head > size || tail > size)
169                 goto out;
170         while (head != tail) {
171                 snd_msnd_eval_dsp_msg(chip, readw(pwDSPQData + 2 * head));
172                 if (++head > size)
173                         head = 0;
174                 writew(head, chip->DSPQ + JQS_wHead);
175         }
176  out:
177         /* Send ack to DSP */
178         inb(chip->io + HP_RXL);
179         return IRQ_HANDLED;
180 }
181 
182 
183 static int snd_msnd_reset_dsp(long io, unsigned char *info)
184 {
185         int timeout = 100;
186 
187         outb(HPDSPRESET_ON, io + HP_DSPR);
188         msleep(1);
189 #ifndef MSND_CLASSIC
190         if (info)
191                 *info = inb(io + HP_INFO);
192 #endif
193         outb(HPDSPRESET_OFF, io + HP_DSPR);
194         msleep(1);
195         while (timeout-- > 0) {
196                 if (inb(io + HP_CVR) == HP_CVR_DEF)
197                         return 0;
198                 msleep(1);
199         }
200         snd_printk(KERN_ERR LOGNAME ": Cannot reset DSP\n");
201 
202         return -EIO;
203 }
204 
205 static int snd_msnd_probe(struct snd_card *card)
206 {
207         struct snd_msnd *chip = card->private_data;
208         unsigned char info;
209 #ifndef MSND_CLASSIC
210         char *xv, *rev = NULL;
211         char *pin = "TB Pinnacle", *fiji = "TB Fiji";
212         char *pinfiji = "TB Pinnacle/Fiji";
213 #endif
214 
215         if (!request_region(chip->io, DSP_NUMIO, "probing")) {
216                 snd_printk(KERN_ERR LOGNAME ": I/O port conflict\n");
217                 return -ENODEV;
218         }
219 
220         if (snd_msnd_reset_dsp(chip->io, &info) < 0) {
221                 release_region(chip->io, DSP_NUMIO);
222                 return -ENODEV;
223         }
224 
225 #ifdef MSND_CLASSIC
226         strcpy(card->shortname, "Classic/Tahiti/Monterey");
227         strcpy(card->longname, "Turtle Beach Multisound");
228         printk(KERN_INFO LOGNAME ": %s, "
229                "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
230                card->shortname,
231                chip->io, chip->io + DSP_NUMIO - 1,
232                chip->irq,
233                chip->base, chip->base + 0x7fff);
234 #else
235         switch (info >> 4) {
236         case 0xf:
237                 xv = "<= 1.15";
238                 break;
239         case 0x1:
240                 xv = "1.18/1.2";
241                 break;
242         case 0x2:
243                 xv = "1.3";
244                 break;
245         case 0x3:
246                 xv = "1.4";
247                 break;
248         default:
249                 xv = "unknown";
250                 break;
251         }
252 
253         switch (info & 0x7) {
254         case 0x0:
255                 rev = "I";
256                 strcpy(card->shortname, pin);
257                 break;
258         case 0x1:
259                 rev = "F";
260                 strcpy(card->shortname, pin);
261                 break;
262         case 0x2:
263                 rev = "G";
264                 strcpy(card->shortname, pin);
265                 break;
266         case 0x3:
267                 rev = "H";
268                 strcpy(card->shortname, pin);
269                 break;
270         case 0x4:
271                 rev = "E";
272                 strcpy(card->shortname, fiji);
273                 break;
274         case 0x5:
275                 rev = "C";
276                 strcpy(card->shortname, fiji);
277                 break;
278         case 0x6:
279                 rev = "D";
280                 strcpy(card->shortname, fiji);
281                 break;
282         case 0x7:
283                 rev = "A-B (Fiji) or A-E (Pinnacle)";
284                 strcpy(card->shortname, pinfiji);
285                 break;
286         }
287         strcpy(card->longname, "Turtle Beach Multisound Pinnacle");
288         printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, "
289                "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
290                card->shortname,
291                rev, xv,
292                chip->io, chip->io + DSP_NUMIO - 1,
293                chip->irq,
294                chip->base, chip->base + 0x7fff);
295 #endif
296 
297         release_region(chip->io, DSP_NUMIO);
298         return 0;
299 }
300 
301 static int snd_msnd_init_sma(struct snd_msnd *chip)
302 {
303         static int initted;
304         u16 mastVolLeft, mastVolRight;
305         unsigned long flags;
306 
307 #ifdef MSND_CLASSIC
308         outb(chip->memid, chip->io + HP_MEMM);
309 #endif
310         outb(HPBLKSEL_0, chip->io + HP_BLKS);
311         /* Motorola 56k shared memory base */
312         chip->SMA = chip->mappedbase + SMA_STRUCT_START;
313 
314         if (initted) {
315                 mastVolLeft = readw(chip->SMA + SMA_wCurrMastVolLeft);
316                 mastVolRight = readw(chip->SMA + SMA_wCurrMastVolRight);
317         } else
318                 mastVolLeft = mastVolRight = 0;
319         memset_io(chip->mappedbase, 0, 0x8000);
320 
321         /* Critical section: bank 1 access */
322         spin_lock_irqsave(&chip->lock, flags);
323         outb(HPBLKSEL_1, chip->io + HP_BLKS);
324         memset_io(chip->mappedbase, 0, 0x8000);
325         outb(HPBLKSEL_0, chip->io + HP_BLKS);
326         spin_unlock_irqrestore(&chip->lock, flags);
327 
328         /* Digital audio play queue */
329         chip->DAPQ = chip->mappedbase + DAPQ_OFFSET;
330         snd_msnd_init_queue(chip->DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE);
331 
332         /* Digital audio record queue */
333         chip->DARQ = chip->mappedbase + DARQ_OFFSET;
334         snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE);
335 
336         /* MIDI out queue */
337         chip->MODQ = chip->mappedbase + MODQ_OFFSET;
338         snd_msnd_init_queue(chip->MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE);
339 
340         /* MIDI in queue */
341         chip->MIDQ = chip->mappedbase + MIDQ_OFFSET;
342         snd_msnd_init_queue(chip->MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE);
343 
344         /* DSP -> host message queue */
345         chip->DSPQ = chip->mappedbase + DSPQ_OFFSET;
346         snd_msnd_init_queue(chip->DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE);
347 
348         /* Setup some DSP values */
349 #ifndef MSND_CLASSIC
350         writew(1, chip->SMA + SMA_wCurrPlayFormat);
351         writew(chip->play_sample_size, chip->SMA + SMA_wCurrPlaySampleSize);
352         writew(chip->play_channels, chip->SMA + SMA_wCurrPlayChannels);
353         writew(chip->play_sample_rate, chip->SMA + SMA_wCurrPlaySampleRate);
354 #endif
355         writew(chip->play_sample_rate, chip->SMA + SMA_wCalFreqAtoD);
356         writew(mastVolLeft, chip->SMA + SMA_wCurrMastVolLeft);
357         writew(mastVolRight, chip->SMA + SMA_wCurrMastVolRight);
358 #ifndef MSND_CLASSIC
359         writel(0x00010000, chip->SMA + SMA_dwCurrPlayPitch);
360         writel(0x00000001, chip->SMA + SMA_dwCurrPlayRate);
361 #endif
362         writew(0x303, chip->SMA + SMA_wCurrInputTagBits);
363 
364         initted = 1;
365 
366         return 0;
367 }
368 
369 
370 static int upload_dsp_code(struct snd_card *card)
371 {
372         struct snd_msnd *chip = card->private_data;
373         const struct firmware *init_fw = NULL, *perm_fw = NULL;
374         int err;
375 
376         outb(HPBLKSEL_0, chip->io + HP_BLKS);
377 
378         err = request_firmware(&init_fw, INITCODEFILE, card->dev);
379         if (err < 0) {
380                 printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE);
381                 goto cleanup1;
382         }
383         err = request_firmware(&perm_fw, PERMCODEFILE, card->dev);
384         if (err < 0) {
385                 printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE);
386                 goto cleanup;
387         }
388 
389         memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size);
390         if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) {
391                 printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n");
392                 err = -ENODEV;
393                 goto cleanup;
394         }
395         printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n");
396         err = 0;
397 
398 cleanup:
399         release_firmware(perm_fw);
400 cleanup1:
401         release_firmware(init_fw);
402         return err;
403 }
404 
405 #ifdef MSND_CLASSIC
406 static void reset_proteus(struct snd_msnd *chip)
407 {
408         outb(HPPRORESET_ON, chip->io + HP_PROR);
409         msleep(TIME_PRO_RESET);
410         outb(HPPRORESET_OFF, chip->io + HP_PROR);
411         msleep(TIME_PRO_RESET_DONE);
412 }
413 #endif
414 
415 static int snd_msnd_initialize(struct snd_card *card)
416 {
417         struct snd_msnd *chip = card->private_data;
418         int err, timeout;
419 
420 #ifdef MSND_CLASSIC
421         outb(HPWAITSTATE_0, chip->io + HP_WAIT);
422         outb(HPBITMODE_16, chip->io + HP_BITM);
423 
424         reset_proteus(chip);
425 #endif
426         err = snd_msnd_init_sma(chip);
427         if (err < 0) {
428                 printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n");
429                 return err;
430         }
431 
432         err = snd_msnd_reset_dsp(chip->io, NULL);
433         if (err < 0)
434                 return err;
435 
436         err = upload_dsp_code(card);
437         if (err < 0) {
438                 printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n");
439                 return err;
440         }
441 
442         timeout = 200;
443 
444         while (readw(chip->mappedbase)) {
445                 msleep(1);
446                 if (!timeout--) {
447                         snd_printd(KERN_ERR LOGNAME ": DSP reset timeout\n");
448                         return -EIO;
449                 }
450         }
451 
452         snd_msndmix_setup(chip);
453         return 0;
454 }
455 
456 static int snd_msnd_dsp_full_reset(struct snd_card *card)
457 {
458         struct snd_msnd *chip = card->private_data;
459         int rv;
460 
461         if (test_bit(F_RESETTING, &chip->flags) || ++chip->nresets > 10)
462                 return 0;
463 
464         set_bit(F_RESETTING, &chip->flags);
465         snd_msnd_dsp_halt(chip, NULL);  /* Unconditionally halt */
466 
467         rv = snd_msnd_initialize(card);
468         if (rv)
469                 printk(KERN_WARNING LOGNAME ": DSP reset failed\n");
470         snd_msndmix_force_recsrc(chip, 0);
471         clear_bit(F_RESETTING, &chip->flags);
472         return rv;
473 }
474 
475 
476 static int snd_msnd_send_dsp_cmd_chk(struct snd_msnd *chip, u8 cmd)
477 {
478         if (snd_msnd_send_dsp_cmd(chip, cmd) == 0)
479                 return 0;
480         snd_msnd_dsp_full_reset(chip->card);
481         return snd_msnd_send_dsp_cmd(chip, cmd);
482 }
483 
484 static int snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate)
485 {
486         snd_printdd("snd_msnd_calibrate_adc(%i)\n", srate);
487         writew(srate, chip->SMA + SMA_wCalFreqAtoD);
488         if (chip->calibrate_signal == 0)
489                 writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
490                        | 0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
491         else
492                 writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
493                        & ~0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
494         if (snd_msnd_send_word(chip, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
495             snd_msnd_send_dsp_cmd_chk(chip, HDEX_AUX_REQ) == 0) {
496                 schedule_timeout_interruptible(msecs_to_jiffies(333));
497                 return 0;
498         }
499         printk(KERN_WARNING LOGNAME ": ADC calibration failed\n");
500         return -EIO;
501 }
502 
503 /*
504  * ALSA callback function, called when attempting to open the MIDI device.
505  */
506 static int snd_msnd_mpu401_open(struct snd_mpu401 *mpu)
507 {
508         snd_msnd_enable_irq(mpu->private_data);
509         snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_START);
510         return 0;
511 }
512 
513 static void snd_msnd_mpu401_close(struct snd_mpu401 *mpu)
514 {
515         snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_STOP);
516         snd_msnd_disable_irq(mpu->private_data);
517 }
518 
519 static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
520 static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
521 
522 static int snd_msnd_attach(struct snd_card *card)
523 {
524         struct snd_msnd *chip = card->private_data;
525         int err;
526 
527         err = devm_request_irq(card->dev, chip->irq, snd_msnd_interrupt, 0,
528                                card->shortname, chip);
529         if (err < 0) {
530                 printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq);
531                 return err;
532         }
533         card->sync_irq = chip->irq;
534         if (!devm_request_region(card->dev, chip->io, DSP_NUMIO,
535                                  card->shortname))
536                 return -EBUSY;
537 
538         if (!devm_request_mem_region(card->dev, chip->base, BUFFSIZE,
539                                      card->shortname)) {
540                 printk(KERN_ERR LOGNAME
541                         ": unable to grab memory region 0x%lx-0x%lx\n",
542                         chip->base, chip->base + BUFFSIZE - 1);
543                 return -EBUSY;
544         }
545         chip->mappedbase = devm_ioremap(card->dev, chip->base, 0x8000);
546         if (!chip->mappedbase) {
547                 printk(KERN_ERR LOGNAME
548                         ": unable to map memory region 0x%lx-0x%lx\n",
549                         chip->base, chip->base + BUFFSIZE - 1);
550                 return -EIO;
551         }
552 
553         err = snd_msnd_dsp_full_reset(card);
554         if (err < 0)
555                 return err;
556 
557         err = snd_msnd_pcm(card, 0);
558         if (err < 0) {
559                 printk(KERN_ERR LOGNAME ": error creating new PCM device\n");
560                 return err;
561         }
562 
563         err = snd_msndmix_new(card);
564         if (err < 0) {
565                 printk(KERN_ERR LOGNAME ": error creating new Mixer device\n");
566                 return err;
567         }
568 
569 
570         if (mpu_io[0] != SNDRV_AUTO_PORT) {
571                 struct snd_mpu401 *mpu;
572 
573                 err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
574                                           mpu_io[0],
575                                           MPU401_MODE_INPUT |
576                                           MPU401_MODE_OUTPUT,
577                                           mpu_irq[0],
578                                           &chip->rmidi);
579                 if (err < 0) {
580                         printk(KERN_ERR LOGNAME
581                                 ": error creating new Midi device\n");
582                         return err;
583                 }
584                 mpu = chip->rmidi->private_data;
585 
586                 mpu->open_input = snd_msnd_mpu401_open;
587                 mpu->close_input = snd_msnd_mpu401_close;
588                 mpu->private_data = chip;
589         }
590 
591         disable_irq(chip->irq);
592         snd_msnd_calibrate_adc(chip, chip->play_sample_rate);
593         snd_msndmix_force_recsrc(chip, 0);
594 
595         err = snd_card_register(card);
596         if (err < 0)
597                 return err;
598 
599         return 0;
600 }
601 
602 
603 #ifndef MSND_CLASSIC
604 
605 /* Pinnacle/Fiji Logical Device Configuration */
606 
607 static int snd_msnd_write_cfg(int cfg, int reg, int value)
608 {
609         outb(reg, cfg);
610         outb(value, cfg + 1);
611         if (value != inb(cfg + 1)) {
612                 printk(KERN_ERR LOGNAME ": snd_msnd_write_cfg: I/O error\n");
613                 return -EIO;
614         }
615         return 0;
616 }
617 
618 static int snd_msnd_write_cfg_io0(int cfg, int num, u16 io)
619 {
620         if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
621                 return -EIO;
622         if (snd_msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
623                 return -EIO;
624         if (snd_msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
625                 return -EIO;
626         return 0;
627 }
628 
629 static int snd_msnd_write_cfg_io1(int cfg, int num, u16 io)
630 {
631         if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
632                 return -EIO;
633         if (snd_msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
634                 return -EIO;
635         if (snd_msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
636                 return -EIO;
637         return 0;
638 }
639 
640 static int snd_msnd_write_cfg_irq(int cfg, int num, u16 irq)
641 {
642         if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
643                 return -EIO;
644         if (snd_msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
645                 return -EIO;
646         if (snd_msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
647                 return -EIO;
648         return 0;
649 }
650 
651 static int snd_msnd_write_cfg_mem(int cfg, int num, int mem)
652 {
653         u16 wmem;
654 
655         mem >>= 8;
656         wmem = (u16)(mem & 0xfff);
657         if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
658                 return -EIO;
659         if (snd_msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
660                 return -EIO;
661         if (snd_msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
662                 return -EIO;
663         if (wmem && snd_msnd_write_cfg(cfg, IREG_MEMCONTROL,
664                                        MEMTYPE_HIADDR | MEMTYPE_16BIT))
665                 return -EIO;
666         return 0;
667 }
668 
669 static int snd_msnd_activate_logical(int cfg, int num)
670 {
671         if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
672                 return -EIO;
673         if (snd_msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
674                 return -EIO;
675         return 0;
676 }
677 
678 static int snd_msnd_write_cfg_logical(int cfg, int num, u16 io0,
679                                       u16 io1, u16 irq, int mem)
680 {
681         if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
682                 return -EIO;
683         if (snd_msnd_write_cfg_io0(cfg, num, io0))
684                 return -EIO;
685         if (snd_msnd_write_cfg_io1(cfg, num, io1))
686                 return -EIO;
687         if (snd_msnd_write_cfg_irq(cfg, num, irq))
688                 return -EIO;
689         if (snd_msnd_write_cfg_mem(cfg, num, mem))
690                 return -EIO;
691         if (snd_msnd_activate_logical(cfg, num))
692                 return -EIO;
693         return 0;
694 }
695 
696 static int snd_msnd_pinnacle_cfg_reset(int cfg)
697 {
698         int i;
699 
700         /* Reset devices if told to */
701         printk(KERN_INFO LOGNAME ": Resetting all devices\n");
702         for (i = 0; i < 4; ++i)
703                 if (snd_msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0))
704                         return -EIO;
705 
706         return 0;
707 }
708 #endif
709 
710 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* Index 0-MAX */
711 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
712 
713 module_param_array(index, int, NULL, 0444);
714 MODULE_PARM_DESC(index, "Index value for msnd_pinnacle soundcard.");
715 module_param_array(id, charp, NULL, 0444);
716 MODULE_PARM_DESC(id, "ID string for msnd_pinnacle soundcard.");
717 
718 static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
719 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
720 static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
721 
722 #ifndef MSND_CLASSIC
723 static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
724 
725 /* Extra Peripheral Configuration (Default: Disable) */
726 static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
727 static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
728 static int ide_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
729 
730 static long joystick_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
731 /* If we have the digital daugherboard... */
732 static int digital[SNDRV_CARDS];
733 
734 /* Extra Peripheral Configuration */
735 static int reset[SNDRV_CARDS];
736 #endif
737 
738 static int write_ndelay[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
739 
740 static int calibrate_signal;
741 
742 #ifdef CONFIG_PNP
743 static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
744 module_param_array(isapnp, bool, NULL, 0444);
745 MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
746 #define has_isapnp(x) isapnp[x]
747 #else
748 #define has_isapnp(x) 0
749 #endif
750 
751 MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
752 MODULE_DESCRIPTION("Turtle Beach " LONGNAME " Linux Driver");
753 MODULE_LICENSE("GPL");
754 MODULE_FIRMWARE(INITCODEFILE);
755 MODULE_FIRMWARE(PERMCODEFILE);
756 
757 module_param_hw_array(io, long, ioport, NULL, 0444);
758 MODULE_PARM_DESC(io, "IO port #");
759 module_param_hw_array(irq, int, irq, NULL, 0444);
760 module_param_hw_array(mem, long, iomem, NULL, 0444);
761 module_param_array(write_ndelay, int, NULL, 0444);
762 module_param(calibrate_signal, int, 0444);
763 #ifndef MSND_CLASSIC
764 module_param_array(digital, int, NULL, 0444);
765 module_param_hw_array(cfg, long, ioport, NULL, 0444);
766 module_param_array(reset, int, NULL, 0444);
767 module_param_hw_array(mpu_io, long, ioport, NULL, 0444);
768 module_param_hw_array(mpu_irq, int, irq, NULL, 0444);
769 module_param_hw_array(ide_io0, long, ioport, NULL, 0444);
770 module_param_hw_array(ide_io1, long, ioport, NULL, 0444);
771 module_param_hw_array(ide_irq, int, irq, NULL, 0444);
772 module_param_hw_array(joystick_io, long, ioport, NULL, 0444);
773 #endif
774 
775 
776 static int snd_msnd_isa_match(struct device *pdev, unsigned int i)
777 {
778         if (io[i] == SNDRV_AUTO_PORT)
779                 return 0;
780 
781         if (irq[i] == SNDRV_AUTO_PORT || mem[i] == SNDRV_AUTO_PORT) {
782                 printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
783                 return 0;
784         }
785 
786 #ifdef MSND_CLASSIC
787         if (!(io[i] == 0x290 ||
788               io[i] == 0x260 ||
789               io[i] == 0x250 ||
790               io[i] == 0x240 ||
791               io[i] == 0x230 ||
792               io[i] == 0x220 ||
793               io[i] == 0x210 ||
794               io[i] == 0x3e0)) {
795                 printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set "
796                         " to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, "
797                         "or 0x3E0\n");
798                 return 0;
799         }
800 #else
801         if (io[i] < 0x100 || io[i] > 0x3e0 || (io[i] % 0x10) != 0) {
802                 printk(KERN_ERR LOGNAME
803                         ": \"io\" - DSP I/O base must within the range 0x100 "
804                         "to 0x3E0 and must be evenly divisible by 0x10\n");
805                 return 0;
806         }
807 #endif /* MSND_CLASSIC */
808 
809         if (!(irq[i] == 5 ||
810               irq[i] == 7 ||
811               irq[i] == 9 ||
812               irq[i] == 10 ||
813               irq[i] == 11 ||
814               irq[i] == 12)) {
815                 printk(KERN_ERR LOGNAME
816                         ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
817                 return 0;
818         }
819 
820         if (!(mem[i] == 0xb0000 ||
821               mem[i] == 0xc8000 ||
822               mem[i] == 0xd0000 ||
823               mem[i] == 0xd8000 ||
824               mem[i] == 0xe0000 ||
825               mem[i] == 0xe8000)) {
826                 printk(KERN_ERR LOGNAME ": \"mem\" - must be set to "
827                        "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or "
828                        "0xe8000\n");
829                 return 0;
830         }
831 
832 #ifndef MSND_CLASSIC
833         if (cfg[i] == SNDRV_AUTO_PORT) {
834                 printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
835         } else if (cfg[i] != 0x250 && cfg[i] != 0x260 && cfg[i] != 0x270) {
836                 printk(KERN_INFO LOGNAME
837                         ": Config port must be 0x250, 0x260 or 0x270 "
838                         "(or unspecified for PnP mode)\n");
839                 return 0;
840         }
841 #endif /* MSND_CLASSIC */
842 
843         return 1;
844 }
845 
846 static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
847 {
848         int err;
849         struct snd_card *card;
850         struct snd_msnd *chip;
851 
852         if (has_isapnp(idx)
853 #ifndef MSND_CLASSIC
854             || cfg[idx] == SNDRV_AUTO_PORT
855 #endif
856             ) {
857                 printk(KERN_INFO LOGNAME ": Assuming PnP mode\n");
858                 return -ENODEV;
859         }
860 
861         err = snd_devm_card_new(pdev, index[idx], id[idx], THIS_MODULE,
862                                 sizeof(struct snd_msnd), &card);
863         if (err < 0)
864                 return err;
865 
866         chip = card->private_data;
867         chip->card = card;
868 
869 #ifdef MSND_CLASSIC
870         switch (irq[idx]) {
871         case 5:
872                 chip->irqid = HPIRQ_5; break;
873         case 7:
874                 chip->irqid = HPIRQ_7; break;
875         case 9:
876                 chip->irqid = HPIRQ_9; break;
877         case 10:
878                 chip->irqid = HPIRQ_10; break;
879         case 11:
880                 chip->irqid = HPIRQ_11; break;
881         case 12:
882                 chip->irqid = HPIRQ_12; break;
883         }
884 
885         switch (mem[idx]) {
886         case 0xb0000:
887                 chip->memid = HPMEM_B000; break;
888         case 0xc8000:
889                 chip->memid = HPMEM_C800; break;
890         case 0xd0000:
891                 chip->memid = HPMEM_D000; break;
892         case 0xd8000:
893                 chip->memid = HPMEM_D800; break;
894         case 0xe0000:
895                 chip->memid = HPMEM_E000; break;
896         case 0xe8000:
897                 chip->memid = HPMEM_E800; break;
898         }
899 #else
900         printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%lx\n",
901                         cfg[idx]);
902 
903         if (!devm_request_region(card->dev, cfg[idx], 2,
904                                  "Pinnacle/Fiji Config")) {
905                 printk(KERN_ERR LOGNAME ": Config port 0x%lx conflict\n",
906                            cfg[idx]);
907                 return -EIO;
908         }
909         if (reset[idx])
910                 if (snd_msnd_pinnacle_cfg_reset(cfg[idx]))
911                         return -EIO;
912 
913         /* DSP */
914         err = snd_msnd_write_cfg_logical(cfg[idx], 0,
915                                          io[idx], 0,
916                                          irq[idx], mem[idx]);
917 
918         if (err)
919                 return err;
920 
921         /* The following are Pinnacle specific */
922 
923         /* MPU */
924         if (mpu_io[idx] != SNDRV_AUTO_PORT
925             && mpu_irq[idx] != SNDRV_AUTO_IRQ) {
926                 printk(KERN_INFO LOGNAME
927                        ": Configuring MPU to I/O 0x%lx IRQ %d\n",
928                        mpu_io[idx], mpu_irq[idx]);
929                 err = snd_msnd_write_cfg_logical(cfg[idx], 1,
930                                                  mpu_io[idx], 0,
931                                                  mpu_irq[idx], 0);
932 
933                 if (err)
934                         return err;
935         }
936 
937         /* IDE */
938         if (ide_io0[idx] != SNDRV_AUTO_PORT
939             && ide_io1[idx] != SNDRV_AUTO_PORT
940             && ide_irq[idx] != SNDRV_AUTO_IRQ) {
941                 printk(KERN_INFO LOGNAME
942                        ": Configuring IDE to I/O 0x%lx, 0x%lx IRQ %d\n",
943                        ide_io0[idx], ide_io1[idx], ide_irq[idx]);
944                 err = snd_msnd_write_cfg_logical(cfg[idx], 2,
945                                                  ide_io0[idx], ide_io1[idx],
946                                                  ide_irq[idx], 0);
947 
948                 if (err)
949                         return err;
950         }
951 
952         /* Joystick */
953         if (joystick_io[idx] != SNDRV_AUTO_PORT) {
954                 printk(KERN_INFO LOGNAME
955                        ": Configuring joystick to I/O 0x%lx\n",
956                        joystick_io[idx]);
957                 err = snd_msnd_write_cfg_logical(cfg[idx], 3,
958                                                  joystick_io[idx], 0,
959                                                  0, 0);
960 
961                 if (err)
962                         return err;
963         }
964 
965 #endif /* MSND_CLASSIC */
966 
967         set_default_audio_parameters(chip);
968 #ifdef MSND_CLASSIC
969         chip->type = msndClassic;
970 #else
971         chip->type = msndPinnacle;
972 #endif
973         chip->io = io[idx];
974         chip->irq = irq[idx];
975         chip->base = mem[idx];
976 
977         chip->calibrate_signal = calibrate_signal ? 1 : 0;
978         chip->recsrc = 0;
979         chip->dspq_data_buff = DSPQ_DATA_BUFF;
980         chip->dspq_buff_size = DSPQ_BUFF_SIZE;
981         if (write_ndelay[idx])
982                 clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
983         else
984                 set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
985 #ifndef MSND_CLASSIC
986         if (digital[idx])
987                 set_bit(F_HAVEDIGITAL, &chip->flags);
988 #endif
989         spin_lock_init(&chip->lock);
990         err = snd_msnd_probe(card);
991         if (err < 0) {
992                 printk(KERN_ERR LOGNAME ": Probe failed\n");
993                 return err;
994         }
995 
996         err = snd_msnd_attach(card);
997         if (err < 0) {
998                 printk(KERN_ERR LOGNAME ": Attach failed\n");
999                 return err;
1000         }
1001         dev_set_drvdata(pdev, card);
1002 
1003         return 0;
1004 }
1005 
1006 static struct isa_driver snd_msnd_driver = {
1007         .match          = snd_msnd_isa_match,
1008         .probe          = snd_msnd_isa_probe,
1009         /* FIXME: suspend, resume */
1010         .driver         = {
1011                 .name   = DEV_NAME
1012         },
1013 };
1014 
1015 #ifdef CONFIG_PNP
1016 static int snd_msnd_pnp_detect(struct pnp_card_link *pcard,
1017                                const struct pnp_card_device_id *pid)
1018 {
1019         static int idx;
1020         struct pnp_dev *pnp_dev;
1021         struct pnp_dev *mpu_dev;
1022         struct snd_card *card;
1023         struct snd_msnd *chip;
1024         int ret;
1025 
1026         for ( ; idx < SNDRV_CARDS; idx++) {
1027                 if (has_isapnp(idx))
1028                         break;
1029         }
1030         if (idx >= SNDRV_CARDS)
1031                 return -ENODEV;
1032 
1033         /*
1034          * Check that we still have room for another sound card ...
1035          */
1036         pnp_dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
1037         if (!pnp_dev)
1038                 return -ENODEV;
1039 
1040         mpu_dev = pnp_request_card_device(pcard, pid->devs[1].id, NULL);
1041         if (!mpu_dev)
1042                 return -ENODEV;
1043 
1044         if (!pnp_is_active(pnp_dev) && pnp_activate_dev(pnp_dev) < 0) {
1045                 printk(KERN_INFO "msnd_pinnacle: device is inactive\n");
1046                 return -EBUSY;
1047         }
1048 
1049         if (!pnp_is_active(mpu_dev) && pnp_activate_dev(mpu_dev) < 0) {
1050                 printk(KERN_INFO "msnd_pinnacle: MPU device is inactive\n");
1051                 return -EBUSY;
1052         }
1053 
1054         /*
1055          * Create a new ALSA sound card entry, in anticipation
1056          * of detecting our hardware ...
1057          */
1058         ret = snd_devm_card_new(&pcard->card->dev,
1059                                 index[idx], id[idx], THIS_MODULE,
1060                                 sizeof(struct snd_msnd), &card);
1061         if (ret < 0)
1062                 return ret;
1063 
1064         chip = card->private_data;
1065         chip->card = card;
1066 
1067         /*
1068          * Read the correct parameters off the ISA PnP bus ...
1069          */
1070         io[idx] = pnp_port_start(pnp_dev, 0);
1071         irq[idx] = pnp_irq(pnp_dev, 0);
1072         mem[idx] = pnp_mem_start(pnp_dev, 0);
1073         mpu_io[idx] = pnp_port_start(mpu_dev, 0);
1074         mpu_irq[idx] = pnp_irq(mpu_dev, 0);
1075 
1076         set_default_audio_parameters(chip);
1077 #ifdef MSND_CLASSIC
1078         chip->type = msndClassic;
1079 #else
1080         chip->type = msndPinnacle;
1081 #endif
1082         chip->io = io[idx];
1083         chip->irq = irq[idx];
1084         chip->base = mem[idx];
1085 
1086         chip->calibrate_signal = calibrate_signal ? 1 : 0;
1087         chip->recsrc = 0;
1088         chip->dspq_data_buff = DSPQ_DATA_BUFF;
1089         chip->dspq_buff_size = DSPQ_BUFF_SIZE;
1090         if (write_ndelay[idx])
1091                 clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
1092         else
1093                 set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
1094 #ifndef MSND_CLASSIC
1095         if (digital[idx])
1096                 set_bit(F_HAVEDIGITAL, &chip->flags);
1097 #endif
1098         spin_lock_init(&chip->lock);
1099         ret = snd_msnd_probe(card);
1100         if (ret < 0) {
1101                 printk(KERN_ERR LOGNAME ": Probe failed\n");
1102                 return ret;
1103         }
1104 
1105         ret = snd_msnd_attach(card);
1106         if (ret < 0) {
1107                 printk(KERN_ERR LOGNAME ": Attach failed\n");
1108                 return ret;
1109         }
1110 
1111         pnp_set_card_drvdata(pcard, card);
1112         ++idx;
1113         return 0;
1114 }
1115 
1116 static int isa_registered;
1117 static int pnp_registered;
1118 
1119 static const struct pnp_card_device_id msnd_pnpids[] = {
1120         /* Pinnacle PnP */
1121         { .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } },
1122         { .id = "" }    /* end */
1123 };
1124 
1125 MODULE_DEVICE_TABLE(pnp_card, msnd_pnpids);
1126 
1127 static struct pnp_card_driver msnd_pnpc_driver = {
1128         .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
1129         .name = "msnd_pinnacle",
1130         .id_table = msnd_pnpids,
1131         .probe = snd_msnd_pnp_detect,
1132 };
1133 #endif /* CONFIG_PNP */
1134 
1135 static int __init snd_msnd_init(void)
1136 {
1137         int err;
1138 
1139         err = isa_register_driver(&snd_msnd_driver, SNDRV_CARDS);
1140 #ifdef CONFIG_PNP
1141         if (!err)
1142                 isa_registered = 1;
1143 
1144         err = pnp_register_card_driver(&msnd_pnpc_driver);
1145         if (!err)
1146                 pnp_registered = 1;
1147 
1148         if (isa_registered)
1149                 err = 0;
1150 #endif
1151         return err;
1152 }
1153 
1154 static void __exit snd_msnd_exit(void)
1155 {
1156 #ifdef CONFIG_PNP
1157         if (pnp_registered)
1158                 pnp_unregister_card_driver(&msnd_pnpc_driver);
1159         if (isa_registered)
1160 #endif
1161                 isa_unregister_driver(&snd_msnd_driver);
1162 }
1163 
1164 module_init(snd_msnd_init);
1165 module_exit(snd_msnd_exit);
1166 
1167 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php