Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.39 1931 lines 48 kB view raw
1/********************************************************************* 2 * 3 * Turtle Beach MultiSound Sound Card Driver for Linux 4 * Linux 2.0/2.2 Version 5 * 6 * msnd_pinnacle.c / msnd_classic.c 7 * 8 * -- If MSND_CLASSIC is defined: 9 * 10 * -> driver for Turtle Beach Classic/Monterey/Tahiti 11 * 12 * -- Else 13 * 14 * -> driver for Turtle Beach Pinnacle/Fiji 15 * 16 * Copyright (C) 1998 Andrew Veliath 17 * 18 * This program is free software; you can redistribute it and/or modify 19 * it under the terms of the GNU General Public License as published by 20 * the Free Software Foundation; either version 2 of the License, or 21 * (at your option) any later version. 22 * 23 * This program is distributed in the hope that it will be useful, 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 * GNU General Public License for more details. 27 * 28 * You should have received a copy of the GNU General Public License 29 * along with this program; if not, write to the Free Software 30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 31 * 32 * 12-3-2000 Modified IO port validation Steve Sycamore 33 * 34 ********************************************************************/ 35 36#include <linux/kernel.h> 37#include <linux/module.h> 38#include <linux/types.h> 39#include <linux/delay.h> 40#include <linux/init.h> 41#include <linux/interrupt.h> 42#include <linux/mutex.h> 43#include <linux/gfp.h> 44#include <asm/irq.h> 45#include <asm/io.h> 46#include "sound_config.h" 47#include "sound_firmware.h" 48#ifdef MSND_CLASSIC 49# ifndef __alpha__ 50# define SLOWIO 51# endif 52#endif 53#include "msnd.h" 54#ifdef MSND_CLASSIC 55# ifdef CONFIG_MSNDCLAS_HAVE_BOOT 56# define HAVE_DSPCODEH 57# endif 58# include "msnd_classic.h" 59# define LOGNAME "msnd_classic" 60#else 61# ifdef CONFIG_MSNDPIN_HAVE_BOOT 62# define HAVE_DSPCODEH 63# endif 64# include "msnd_pinnacle.h" 65# define LOGNAME "msnd_pinnacle" 66#endif 67 68#ifndef CONFIG_MSND_WRITE_NDELAY 69# define CONFIG_MSND_WRITE_NDELAY 1 70#endif 71 72#define get_play_delay_jiffies(size) ((size) * HZ * \ 73 dev.play_sample_size / 8 / \ 74 dev.play_sample_rate / \ 75 dev.play_channels) 76 77#define get_rec_delay_jiffies(size) ((size) * HZ * \ 78 dev.rec_sample_size / 8 / \ 79 dev.rec_sample_rate / \ 80 dev.rec_channels) 81 82static DEFINE_MUTEX(msnd_pinnacle_mutex); 83static multisound_dev_t dev; 84 85#ifndef HAVE_DSPCODEH 86static char *dspini, *permini; 87static int sizeof_dspini, sizeof_permini; 88#endif 89 90static int dsp_full_reset(void); 91static void dsp_write_flush(void); 92 93static __inline__ int chk_send_dsp_cmd(multisound_dev_t *dev, register BYTE cmd) 94{ 95 if (msnd_send_dsp_cmd(dev, cmd) == 0) 96 return 0; 97 dsp_full_reset(); 98 return msnd_send_dsp_cmd(dev, cmd); 99} 100 101static void reset_play_queue(void) 102{ 103 int n; 104 LPDAQD lpDAQ; 105 106 dev.last_playbank = -1; 107 writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wHead); 108 writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DAPQ + JQS_wTail); 109 110 for (n = 0, lpDAQ = dev.base + DAPQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) { 111 writew(PCTODSP_BASED((DWORD)(DAP_BUFF_SIZE * n)), lpDAQ + DAQDS_wStart); 112 writew(0, lpDAQ + DAQDS_wSize); 113 writew(1, lpDAQ + DAQDS_wFormat); 114 writew(dev.play_sample_size, lpDAQ + DAQDS_wSampleSize); 115 writew(dev.play_channels, lpDAQ + DAQDS_wChannels); 116 writew(dev.play_sample_rate, lpDAQ + DAQDS_wSampleRate); 117 writew(HIMT_PLAY_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg); 118 writew(n, lpDAQ + DAQDS_wFlags); 119 } 120} 121 122static void reset_record_queue(void) 123{ 124 int n; 125 LPDAQD lpDAQ; 126 unsigned long flags; 127 128 dev.last_recbank = 2; 129 writew(PCTODSP_OFFSET(0 * DAQDS__size), dev.DARQ + JQS_wHead); 130 writew(PCTODSP_OFFSET(dev.last_recbank * DAQDS__size), dev.DARQ + JQS_wTail); 131 132 /* Critical section: bank 1 access */ 133 spin_lock_irqsave(&dev.lock, flags); 134 msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS); 135 memset_io(dev.base, 0, DAR_BUFF_SIZE * 3); 136 msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS); 137 spin_unlock_irqrestore(&dev.lock, flags); 138 139 for (n = 0, lpDAQ = dev.base + DARQ_DATA_BUFF; n < 3; ++n, lpDAQ += DAQDS__size) { 140 writew(PCTODSP_BASED((DWORD)(DAR_BUFF_SIZE * n)) + 0x4000, lpDAQ + DAQDS_wStart); 141 writew(DAR_BUFF_SIZE, lpDAQ + DAQDS_wSize); 142 writew(1, lpDAQ + DAQDS_wFormat); 143 writew(dev.rec_sample_size, lpDAQ + DAQDS_wSampleSize); 144 writew(dev.rec_channels, lpDAQ + DAQDS_wChannels); 145 writew(dev.rec_sample_rate, lpDAQ + DAQDS_wSampleRate); 146 writew(HIMT_RECORD_DONE * 0x100 + n, lpDAQ + DAQDS_wIntMsg); 147 writew(n, lpDAQ + DAQDS_wFlags); 148 } 149} 150 151static void reset_queues(void) 152{ 153 if (dev.mode & FMODE_WRITE) { 154 msnd_fifo_make_empty(&dev.DAPF); 155 reset_play_queue(); 156 } 157 if (dev.mode & FMODE_READ) { 158 msnd_fifo_make_empty(&dev.DARF); 159 reset_record_queue(); 160 } 161} 162 163static int dsp_set_format(struct file *file, int val) 164{ 165 int data, i; 166 LPDAQD lpDAQ, lpDARQ; 167 168 lpDAQ = dev.base + DAPQ_DATA_BUFF; 169 lpDARQ = dev.base + DARQ_DATA_BUFF; 170 171 switch (val) { 172 case AFMT_U8: 173 case AFMT_S16_LE: 174 data = val; 175 break; 176 default: 177 data = DEFSAMPLESIZE; 178 break; 179 } 180 181 for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) { 182 if (file->f_mode & FMODE_WRITE) 183 writew(data, lpDAQ + DAQDS_wSampleSize); 184 if (file->f_mode & FMODE_READ) 185 writew(data, lpDARQ + DAQDS_wSampleSize); 186 } 187 if (file->f_mode & FMODE_WRITE) 188 dev.play_sample_size = data; 189 if (file->f_mode & FMODE_READ) 190 dev.rec_sample_size = data; 191 192 return data; 193} 194 195static int dsp_get_frag_size(void) 196{ 197 int size; 198 size = dev.fifosize / 4; 199 if (size > 32 * 1024) 200 size = 32 * 1024; 201 return size; 202} 203 204static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 205{ 206 int val, i, data, tmp; 207 LPDAQD lpDAQ, lpDARQ; 208 audio_buf_info abinfo; 209 unsigned long flags; 210 int __user *p = (int __user *)arg; 211 212 lpDAQ = dev.base + DAPQ_DATA_BUFF; 213 lpDARQ = dev.base + DARQ_DATA_BUFF; 214 215 switch (cmd) { 216 case SNDCTL_DSP_SUBDIVIDE: 217 case SNDCTL_DSP_SETFRAGMENT: 218 case SNDCTL_DSP_SETDUPLEX: 219 case SNDCTL_DSP_POST: 220 return 0; 221 222 case SNDCTL_DSP_GETIPTR: 223 case SNDCTL_DSP_GETOPTR: 224 case SNDCTL_DSP_MAPINBUF: 225 case SNDCTL_DSP_MAPOUTBUF: 226 return -EINVAL; 227 228 case SNDCTL_DSP_GETOSPACE: 229 if (!(file->f_mode & FMODE_WRITE)) 230 return -EINVAL; 231 spin_lock_irqsave(&dev.lock, flags); 232 abinfo.fragsize = dsp_get_frag_size(); 233 abinfo.bytes = dev.DAPF.n - dev.DAPF.len; 234 abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize; 235 abinfo.fragments = abinfo.bytes / abinfo.fragsize; 236 spin_unlock_irqrestore(&dev.lock, flags); 237 return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; 238 239 case SNDCTL_DSP_GETISPACE: 240 if (!(file->f_mode & FMODE_READ)) 241 return -EINVAL; 242 spin_lock_irqsave(&dev.lock, flags); 243 abinfo.fragsize = dsp_get_frag_size(); 244 abinfo.bytes = dev.DARF.n - dev.DARF.len; 245 abinfo.fragstotal = dev.DARF.n / abinfo.fragsize; 246 abinfo.fragments = abinfo.bytes / abinfo.fragsize; 247 spin_unlock_irqrestore(&dev.lock, flags); 248 return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; 249 250 case SNDCTL_DSP_RESET: 251 dev.nresets = 0; 252 reset_queues(); 253 return 0; 254 255 case SNDCTL_DSP_SYNC: 256 dsp_write_flush(); 257 return 0; 258 259 case SNDCTL_DSP_GETBLKSIZE: 260 tmp = dsp_get_frag_size(); 261 if (put_user(tmp, p)) 262 return -EFAULT; 263 return 0; 264 265 case SNDCTL_DSP_GETFMTS: 266 val = AFMT_S16_LE | AFMT_U8; 267 if (put_user(val, p)) 268 return -EFAULT; 269 return 0; 270 271 case SNDCTL_DSP_SETFMT: 272 if (get_user(val, p)) 273 return -EFAULT; 274 275 if (file->f_mode & FMODE_WRITE) 276 data = val == AFMT_QUERY 277 ? dev.play_sample_size 278 : dsp_set_format(file, val); 279 else 280 data = val == AFMT_QUERY 281 ? dev.rec_sample_size 282 : dsp_set_format(file, val); 283 284 if (put_user(data, p)) 285 return -EFAULT; 286 return 0; 287 288 case SNDCTL_DSP_NONBLOCK: 289 if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags) && 290 file->f_mode & FMODE_WRITE) 291 dev.play_ndelay = 1; 292 if (file->f_mode & FMODE_READ) 293 dev.rec_ndelay = 1; 294 return 0; 295 296 case SNDCTL_DSP_GETCAPS: 297 val = DSP_CAP_DUPLEX | DSP_CAP_BATCH; 298 if (put_user(val, p)) 299 return -EFAULT; 300 return 0; 301 302 case SNDCTL_DSP_SPEED: 303 if (get_user(val, p)) 304 return -EFAULT; 305 306 if (val < 8000) 307 val = 8000; 308 309 if (val > 48000) 310 val = 48000; 311 312 data = val; 313 314 for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) { 315 if (file->f_mode & FMODE_WRITE) 316 writew(data, lpDAQ + DAQDS_wSampleRate); 317 if (file->f_mode & FMODE_READ) 318 writew(data, lpDARQ + DAQDS_wSampleRate); 319 } 320 if (file->f_mode & FMODE_WRITE) 321 dev.play_sample_rate = data; 322 if (file->f_mode & FMODE_READ) 323 dev.rec_sample_rate = data; 324 325 if (put_user(data, p)) 326 return -EFAULT; 327 return 0; 328 329 case SNDCTL_DSP_CHANNELS: 330 case SNDCTL_DSP_STEREO: 331 if (get_user(val, p)) 332 return -EFAULT; 333 334 if (cmd == SNDCTL_DSP_CHANNELS) { 335 switch (val) { 336 case 1: 337 case 2: 338 data = val; 339 break; 340 default: 341 val = data = 2; 342 break; 343 } 344 } else { 345 switch (val) { 346 case 0: 347 data = 1; 348 break; 349 default: 350 val = 1; 351 case 1: 352 data = 2; 353 break; 354 } 355 } 356 357 for (i = 0; i < 3; ++i, lpDAQ += DAQDS__size, lpDARQ += DAQDS__size) { 358 if (file->f_mode & FMODE_WRITE) 359 writew(data, lpDAQ + DAQDS_wChannels); 360 if (file->f_mode & FMODE_READ) 361 writew(data, lpDARQ + DAQDS_wChannels); 362 } 363 if (file->f_mode & FMODE_WRITE) 364 dev.play_channels = data; 365 if (file->f_mode & FMODE_READ) 366 dev.rec_channels = data; 367 368 if (put_user(val, p)) 369 return -EFAULT; 370 return 0; 371 } 372 373 return -EINVAL; 374} 375 376static int mixer_get(int d) 377{ 378 if (d > 31) 379 return -EINVAL; 380 381 switch (d) { 382 case SOUND_MIXER_VOLUME: 383 case SOUND_MIXER_PCM: 384 case SOUND_MIXER_LINE: 385 case SOUND_MIXER_IMIX: 386 case SOUND_MIXER_LINE1: 387#ifndef MSND_CLASSIC 388 case SOUND_MIXER_MIC: 389 case SOUND_MIXER_SYNTH: 390#endif 391 return (dev.left_levels[d] >> 8) * 100 / 0xff | 392 (((dev.right_levels[d] >> 8) * 100 / 0xff) << 8); 393 default: 394 return 0; 395 } 396} 397 398#define update_volm(a,b) \ 399 writew((dev.left_levels[a] >> 1) * \ 400 readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff, \ 401 dev.SMA + SMA_##b##Left); \ 402 writew((dev.right_levels[a] >> 1) * \ 403 readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \ 404 dev.SMA + SMA_##b##Right); 405 406#define update_potm(d,s,ar) \ 407 writeb((dev.left_levels[d] >> 8) * \ 408 readw(dev.SMA + SMA_wCurrMastVolLeft) / 0xffff, \ 409 dev.SMA + SMA_##s##Left); \ 410 writeb((dev.right_levels[d] >> 8) * \ 411 readw(dev.SMA + SMA_wCurrMastVolRight) / 0xffff, \ 412 dev.SMA + SMA_##s##Right); \ 413 if (msnd_send_word(&dev, 0, 0, ar) == 0) \ 414 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 415 416#define update_pot(d,s,ar) \ 417 writeb(dev.left_levels[d] >> 8, \ 418 dev.SMA + SMA_##s##Left); \ 419 writeb(dev.right_levels[d] >> 8, \ 420 dev.SMA + SMA_##s##Right); \ 421 if (msnd_send_word(&dev, 0, 0, ar) == 0) \ 422 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 423 424static int mixer_set(int d, int value) 425{ 426 int left = value & 0x000000ff; 427 int right = (value & 0x0000ff00) >> 8; 428 int bLeft, bRight; 429 int wLeft, wRight; 430 int updatemaster = 0; 431 432 if (d > 31) 433 return -EINVAL; 434 435 bLeft = left * 0xff / 100; 436 wLeft = left * 0xffff / 100; 437 438 bRight = right * 0xff / 100; 439 wRight = right * 0xffff / 100; 440 441 dev.left_levels[d] = wLeft; 442 dev.right_levels[d] = wRight; 443 444 switch (d) { 445 /* master volume unscaled controls */ 446 case SOUND_MIXER_LINE: /* line pot control */ 447 /* scaled by IMIX in digital mix */ 448 writeb(bLeft, dev.SMA + SMA_bInPotPosLeft); 449 writeb(bRight, dev.SMA + SMA_bInPotPosRight); 450 if (msnd_send_word(&dev, 0, 0, HDEXAR_IN_SET_POTS) == 0) 451 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 452 break; 453#ifndef MSND_CLASSIC 454 case SOUND_MIXER_MIC: /* mic pot control */ 455 /* scaled by IMIX in digital mix */ 456 writeb(bLeft, dev.SMA + SMA_bMicPotPosLeft); 457 writeb(bRight, dev.SMA + SMA_bMicPotPosRight); 458 if (msnd_send_word(&dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0) 459 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 460 break; 461#endif 462 case SOUND_MIXER_VOLUME: /* master volume */ 463 writew(wLeft, dev.SMA + SMA_wCurrMastVolLeft); 464 writew(wRight, dev.SMA + SMA_wCurrMastVolRight); 465 /* fall through */ 466 467 case SOUND_MIXER_LINE1: /* aux pot control */ 468 /* scaled by master volume */ 469 /* fall through */ 470 471 /* digital controls */ 472 case SOUND_MIXER_SYNTH: /* synth vol (dsp mix) */ 473 case SOUND_MIXER_PCM: /* pcm vol (dsp mix) */ 474 case SOUND_MIXER_IMIX: /* input monitor (dsp mix) */ 475 /* scaled by master volume */ 476 updatemaster = 1; 477 break; 478 479 default: 480 return 0; 481 } 482 483 if (updatemaster) { 484 /* update master volume scaled controls */ 485 update_volm(SOUND_MIXER_PCM, wCurrPlayVol); 486 update_volm(SOUND_MIXER_IMIX, wCurrInVol); 487#ifndef MSND_CLASSIC 488 update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol); 489#endif 490 update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS); 491 } 492 493 return mixer_get(d); 494} 495 496static void mixer_setup(void) 497{ 498 update_pot(SOUND_MIXER_LINE, bInPotPos, HDEXAR_IN_SET_POTS); 499 update_potm(SOUND_MIXER_LINE1, bAuxPotPos, HDEXAR_AUX_SET_POTS); 500 update_volm(SOUND_MIXER_PCM, wCurrPlayVol); 501 update_volm(SOUND_MIXER_IMIX, wCurrInVol); 502#ifndef MSND_CLASSIC 503 update_pot(SOUND_MIXER_MIC, bMicPotPos, HDEXAR_MIC_SET_POTS); 504 update_volm(SOUND_MIXER_SYNTH, wCurrMHdrVol); 505#endif 506} 507 508static unsigned long set_recsrc(unsigned long recsrc) 509{ 510 if (dev.recsrc == recsrc) 511 return dev.recsrc; 512#ifdef HAVE_NORECSRC 513 else if (recsrc == 0) 514 dev.recsrc = 0; 515#endif 516 else 517 dev.recsrc ^= recsrc; 518 519#ifndef MSND_CLASSIC 520 if (dev.recsrc & SOUND_MASK_IMIX) { 521 if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0) 522 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 523 } 524 else if (dev.recsrc & SOUND_MASK_SYNTH) { 525 if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_SYNTH_IN) == 0) 526 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 527 } 528 else if ((dev.recsrc & SOUND_MASK_DIGITAL1) && test_bit(F_HAVEDIGITAL, &dev.flags)) { 529 if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_DAT_IN) == 0) 530 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 531 } 532 else { 533#ifdef HAVE_NORECSRC 534 /* Select no input (?) */ 535 dev.recsrc = 0; 536#else 537 dev.recsrc = SOUND_MASK_IMIX; 538 if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0) 539 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ); 540#endif 541 } 542#endif /* MSND_CLASSIC */ 543 544 return dev.recsrc; 545} 546 547static unsigned long force_recsrc(unsigned long recsrc) 548{ 549 dev.recsrc = 0; 550 return set_recsrc(recsrc); 551} 552 553#define set_mixer_info() \ 554 memset(&info, 0, sizeof(info)); \ 555 strlcpy(info.id, "MSNDMIXER", sizeof(info.id)); \ 556 strlcpy(info.name, "MultiSound Mixer", sizeof(info.name)); 557 558static int mixer_ioctl(unsigned int cmd, unsigned long arg) 559{ 560 if (cmd == SOUND_MIXER_INFO) { 561 mixer_info info; 562 set_mixer_info(); 563 info.modify_counter = dev.mixer_mod_count; 564 if (copy_to_user((void __user *)arg, &info, sizeof(info))) 565 return -EFAULT; 566 return 0; 567 } else if (cmd == SOUND_OLD_MIXER_INFO) { 568 _old_mixer_info info; 569 set_mixer_info(); 570 if (copy_to_user((void __user *)arg, &info, sizeof(info))) 571 return -EFAULT; 572 return 0; 573 } else if (cmd == SOUND_MIXER_PRIVATE1) { 574 dev.nresets = 0; 575 dsp_full_reset(); 576 return 0; 577 } else if (((cmd >> 8) & 0xff) == 'M') { 578 int val = 0; 579 580 if (_SIOC_DIR(cmd) & _SIOC_WRITE) { 581 switch (cmd & 0xff) { 582 case SOUND_MIXER_RECSRC: 583 if (get_user(val, (int __user *)arg)) 584 return -EFAULT; 585 val = set_recsrc(val); 586 break; 587 588 default: 589 if (get_user(val, (int __user *)arg)) 590 return -EFAULT; 591 val = mixer_set(cmd & 0xff, val); 592 break; 593 } 594 ++dev.mixer_mod_count; 595 return put_user(val, (int __user *)arg); 596 } else { 597 switch (cmd & 0xff) { 598 case SOUND_MIXER_RECSRC: 599 val = dev.recsrc; 600 break; 601 602 case SOUND_MIXER_DEVMASK: 603 case SOUND_MIXER_STEREODEVS: 604 val = SOUND_MASK_PCM | 605 SOUND_MASK_LINE | 606 SOUND_MASK_IMIX | 607 SOUND_MASK_LINE1 | 608#ifndef MSND_CLASSIC 609 SOUND_MASK_MIC | 610 SOUND_MASK_SYNTH | 611#endif 612 SOUND_MASK_VOLUME; 613 break; 614 615 case SOUND_MIXER_RECMASK: 616#ifdef MSND_CLASSIC 617 val = 0; 618#else 619 val = SOUND_MASK_IMIX | 620 SOUND_MASK_SYNTH; 621 if (test_bit(F_HAVEDIGITAL, &dev.flags)) 622 val |= SOUND_MASK_DIGITAL1; 623#endif 624 break; 625 626 case SOUND_MIXER_CAPS: 627 val = SOUND_CAP_EXCL_INPUT; 628 break; 629 630 default: 631 if ((val = mixer_get(cmd & 0xff)) < 0) 632 return -EINVAL; 633 break; 634 } 635 } 636 637 return put_user(val, (int __user *)arg); 638 } 639 640 return -EINVAL; 641} 642 643static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 644{ 645 int minor = iminor(file->f_path.dentry->d_inode); 646 int ret; 647 648 if (cmd == OSS_GETVERSION) { 649 int sound_version = SOUND_VERSION; 650 return put_user(sound_version, (int __user *)arg); 651 } 652 653 ret = -EINVAL; 654 655 mutex_lock(&msnd_pinnacle_mutex); 656 if (minor == dev.dsp_minor) 657 ret = dsp_ioctl(file, cmd, arg); 658 else if (minor == dev.mixer_minor) 659 ret = mixer_ioctl(cmd, arg); 660 mutex_unlock(&msnd_pinnacle_mutex); 661 662 return ret; 663} 664 665static void dsp_write_flush(void) 666{ 667 if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags)) 668 return; 669 set_bit(F_WRITEFLUSH, &dev.flags); 670 interruptible_sleep_on_timeout( 671 &dev.writeflush, 672 get_play_delay_jiffies(dev.DAPF.len)); 673 clear_bit(F_WRITEFLUSH, &dev.flags); 674 if (!signal_pending(current)) { 675 current->state = TASK_INTERRUPTIBLE; 676 schedule_timeout(get_play_delay_jiffies(DAP_BUFF_SIZE)); 677 } 678 clear_bit(F_WRITING, &dev.flags); 679} 680 681static void dsp_halt(struct file *file) 682{ 683 if ((file ? file->f_mode : dev.mode) & FMODE_READ) { 684 clear_bit(F_READING, &dev.flags); 685 chk_send_dsp_cmd(&dev, HDEX_RECORD_STOP); 686 msnd_disable_irq(&dev); 687 if (file) { 688 printk(KERN_DEBUG LOGNAME ": Stopping read for %p\n", file); 689 dev.mode &= ~FMODE_READ; 690 } 691 clear_bit(F_AUDIO_READ_INUSE, &dev.flags); 692 } 693 if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) { 694 if (test_bit(F_WRITING, &dev.flags)) { 695 dsp_write_flush(); 696 chk_send_dsp_cmd(&dev, HDEX_PLAY_STOP); 697 } 698 msnd_disable_irq(&dev); 699 if (file) { 700 printk(KERN_DEBUG LOGNAME ": Stopping write for %p\n", file); 701 dev.mode &= ~FMODE_WRITE; 702 } 703 clear_bit(F_AUDIO_WRITE_INUSE, &dev.flags); 704 } 705} 706 707static int dsp_release(struct file *file) 708{ 709 dsp_halt(file); 710 return 0; 711} 712 713static int dsp_open(struct file *file) 714{ 715 if ((file ? file->f_mode : dev.mode) & FMODE_WRITE) { 716 set_bit(F_AUDIO_WRITE_INUSE, &dev.flags); 717 clear_bit(F_WRITING, &dev.flags); 718 msnd_fifo_make_empty(&dev.DAPF); 719 reset_play_queue(); 720 if (file) { 721 printk(KERN_DEBUG LOGNAME ": Starting write for %p\n", file); 722 dev.mode |= FMODE_WRITE; 723 } 724 msnd_enable_irq(&dev); 725 } 726 if ((file ? file->f_mode : dev.mode) & FMODE_READ) { 727 set_bit(F_AUDIO_READ_INUSE, &dev.flags); 728 clear_bit(F_READING, &dev.flags); 729 msnd_fifo_make_empty(&dev.DARF); 730 reset_record_queue(); 731 if (file) { 732 printk(KERN_DEBUG LOGNAME ": Starting read for %p\n", file); 733 dev.mode |= FMODE_READ; 734 } 735 msnd_enable_irq(&dev); 736 } 737 return 0; 738} 739 740static void set_default_play_audio_parameters(void) 741{ 742 dev.play_sample_size = DEFSAMPLESIZE; 743 dev.play_sample_rate = DEFSAMPLERATE; 744 dev.play_channels = DEFCHANNELS; 745} 746 747static void set_default_rec_audio_parameters(void) 748{ 749 dev.rec_sample_size = DEFSAMPLESIZE; 750 dev.rec_sample_rate = DEFSAMPLERATE; 751 dev.rec_channels = DEFCHANNELS; 752} 753 754static void set_default_audio_parameters(void) 755{ 756 set_default_play_audio_parameters(); 757 set_default_rec_audio_parameters(); 758} 759 760static int dev_open(struct inode *inode, struct file *file) 761{ 762 int minor = iminor(inode); 763 int err = 0; 764 765 mutex_lock(&msnd_pinnacle_mutex); 766 if (minor == dev.dsp_minor) { 767 if ((file->f_mode & FMODE_WRITE && 768 test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) || 769 (file->f_mode & FMODE_READ && 770 test_bit(F_AUDIO_READ_INUSE, &dev.flags))) { 771 err = -EBUSY; 772 goto out; 773 } 774 775 if ((err = dsp_open(file)) >= 0) { 776 dev.nresets = 0; 777 if (file->f_mode & FMODE_WRITE) { 778 set_default_play_audio_parameters(); 779 if (!test_bit(F_DISABLE_WRITE_NDELAY, &dev.flags)) 780 dev.play_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0; 781 else 782 dev.play_ndelay = 0; 783 } 784 if (file->f_mode & FMODE_READ) { 785 set_default_rec_audio_parameters(); 786 dev.rec_ndelay = (file->f_flags & O_NDELAY) ? 1 : 0; 787 } 788 } 789 } 790 else if (minor == dev.mixer_minor) { 791 /* nothing */ 792 } else 793 err = -EINVAL; 794out: 795 mutex_unlock(&msnd_pinnacle_mutex); 796 return err; 797} 798 799static int dev_release(struct inode *inode, struct file *file) 800{ 801 int minor = iminor(inode); 802 int err = 0; 803 804 mutex_lock(&msnd_pinnacle_mutex); 805 if (minor == dev.dsp_minor) 806 err = dsp_release(file); 807 else if (minor == dev.mixer_minor) { 808 /* nothing */ 809 } else 810 err = -EINVAL; 811 mutex_unlock(&msnd_pinnacle_mutex); 812 return err; 813} 814 815static __inline__ int pack_DARQ_to_DARF(register int bank) 816{ 817 register int size, timeout = 3; 818 register WORD wTmp; 819 LPDAQD DAQD; 820 821 /* Increment the tail and check for queue wrap */ 822 wTmp = readw(dev.DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size); 823 if (wTmp > readw(dev.DARQ + JQS_wSize)) 824 wTmp = 0; 825 while (wTmp == readw(dev.DARQ + JQS_wHead) && timeout--) 826 udelay(1); 827 writew(wTmp, dev.DARQ + JQS_wTail); 828 829 /* Get our digital audio queue struct */ 830 DAQD = bank * DAQDS__size + dev.base + DARQ_DATA_BUFF; 831 832 /* Get length of data */ 833 size = readw(DAQD + DAQDS_wSize); 834 835 /* Read data from the head (unprotected bank 1 access okay 836 since this is only called inside an interrupt) */ 837 msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS); 838 msnd_fifo_write_io( 839 &dev.DARF, 840 dev.base + bank * DAR_BUFF_SIZE, 841 size); 842 msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS); 843 844 return 1; 845} 846 847static __inline__ int pack_DAPF_to_DAPQ(register int start) 848{ 849 register WORD DAPQ_tail; 850 register int protect = start, nbanks = 0; 851 LPDAQD DAQD; 852 853 DAPQ_tail = readw(dev.DAPQ + JQS_wTail); 854 while (DAPQ_tail != readw(dev.DAPQ + JQS_wHead) || start) { 855 register int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size); 856 register int n; 857 unsigned long flags; 858 859 /* Write the data to the new tail */ 860 if (protect) { 861 /* Critical section: protect fifo in non-interrupt */ 862 spin_lock_irqsave(&dev.lock, flags); 863 n = msnd_fifo_read_io( 864 &dev.DAPF, 865 dev.base + bank_num * DAP_BUFF_SIZE, 866 DAP_BUFF_SIZE); 867 spin_unlock_irqrestore(&dev.lock, flags); 868 } else { 869 n = msnd_fifo_read_io( 870 &dev.DAPF, 871 dev.base + bank_num * DAP_BUFF_SIZE, 872 DAP_BUFF_SIZE); 873 } 874 if (!n) 875 break; 876 877 if (start) 878 start = 0; 879 880 /* Get our digital audio queue struct */ 881 DAQD = bank_num * DAQDS__size + dev.base + DAPQ_DATA_BUFF; 882 883 /* Write size of this bank */ 884 writew(n, DAQD + DAQDS_wSize); 885 ++nbanks; 886 887 /* Then advance the tail */ 888 DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size); 889 writew(DAPQ_tail, dev.DAPQ + JQS_wTail); 890 /* Tell the DSP to play the bank */ 891 msnd_send_dsp_cmd(&dev, HDEX_PLAY_START); 892 } 893 return nbanks; 894} 895 896static int dsp_read(char __user *buf, size_t len) 897{ 898 int count = len; 899 char *page = (char *)__get_free_page(GFP_KERNEL); 900 901 if (!page) 902 return -ENOMEM; 903 904 while (count > 0) { 905 int n, k; 906 unsigned long flags; 907 908 k = PAGE_SIZE; 909 if (k > count) 910 k = count; 911 912 /* Critical section: protect fifo in non-interrupt */ 913 spin_lock_irqsave(&dev.lock, flags); 914 n = msnd_fifo_read(&dev.DARF, page, k); 915 spin_unlock_irqrestore(&dev.lock, flags); 916 if (copy_to_user(buf, page, n)) { 917 free_page((unsigned long)page); 918 return -EFAULT; 919 } 920 buf += n; 921 count -= n; 922 923 if (n == k && count) 924 continue; 925 926 if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) { 927 dev.last_recbank = -1; 928 if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0) 929 set_bit(F_READING, &dev.flags); 930 } 931 932 if (dev.rec_ndelay) { 933 free_page((unsigned long)page); 934 return count == len ? -EAGAIN : len - count; 935 } 936 937 if (count > 0) { 938 set_bit(F_READBLOCK, &dev.flags); 939 if (!interruptible_sleep_on_timeout( 940 &dev.readblock, 941 get_rec_delay_jiffies(DAR_BUFF_SIZE))) 942 clear_bit(F_READING, &dev.flags); 943 clear_bit(F_READBLOCK, &dev.flags); 944 if (signal_pending(current)) { 945 free_page((unsigned long)page); 946 return -EINTR; 947 } 948 } 949 } 950 free_page((unsigned long)page); 951 return len - count; 952} 953 954static int dsp_write(const char __user *buf, size_t len) 955{ 956 int count = len; 957 char *page = (char *)__get_free_page(GFP_KERNEL); 958 959 if (!page) 960 return -ENOMEM; 961 962 while (count > 0) { 963 int n, k; 964 unsigned long flags; 965 966 k = PAGE_SIZE; 967 if (k > count) 968 k = count; 969 970 if (copy_from_user(page, buf, k)) { 971 free_page((unsigned long)page); 972 return -EFAULT; 973 } 974 975 /* Critical section: protect fifo in non-interrupt */ 976 spin_lock_irqsave(&dev.lock, flags); 977 n = msnd_fifo_write(&dev.DAPF, page, k); 978 spin_unlock_irqrestore(&dev.lock, flags); 979 buf += n; 980 count -= n; 981 982 if (count && n == k) 983 continue; 984 985 if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) { 986 dev.last_playbank = -1; 987 if (pack_DAPF_to_DAPQ(1) > 0) 988 set_bit(F_WRITING, &dev.flags); 989 } 990 991 if (dev.play_ndelay) { 992 free_page((unsigned long)page); 993 return count == len ? -EAGAIN : len - count; 994 } 995 996 if (count > 0) { 997 set_bit(F_WRITEBLOCK, &dev.flags); 998 interruptible_sleep_on_timeout( 999 &dev.writeblock, 1000 get_play_delay_jiffies(DAP_BUFF_SIZE)); 1001 clear_bit(F_WRITEBLOCK, &dev.flags); 1002 if (signal_pending(current)) { 1003 free_page((unsigned long)page); 1004 return -EINTR; 1005 } 1006 } 1007 } 1008 1009 free_page((unsigned long)page); 1010 return len - count; 1011} 1012 1013static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *off) 1014{ 1015 int minor = iminor(file->f_path.dentry->d_inode); 1016 if (minor == dev.dsp_minor) 1017 return dsp_read(buf, count); 1018 else 1019 return -EINVAL; 1020} 1021 1022static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *off) 1023{ 1024 int minor = iminor(file->f_path.dentry->d_inode); 1025 if (minor == dev.dsp_minor) 1026 return dsp_write(buf, count); 1027 else 1028 return -EINVAL; 1029} 1030 1031static __inline__ void eval_dsp_msg(register WORD wMessage) 1032{ 1033 switch (HIBYTE(wMessage)) { 1034 case HIMT_PLAY_DONE: 1035 if (dev.last_playbank == LOBYTE(wMessage) || !test_bit(F_WRITING, &dev.flags)) 1036 break; 1037 dev.last_playbank = LOBYTE(wMessage); 1038 1039 if (pack_DAPF_to_DAPQ(0) <= 0) { 1040 if (!test_bit(F_WRITEBLOCK, &dev.flags)) { 1041 if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags)) 1042 wake_up_interruptible(&dev.writeflush); 1043 } 1044 clear_bit(F_WRITING, &dev.flags); 1045 } 1046 1047 if (test_bit(F_WRITEBLOCK, &dev.flags)) 1048 wake_up_interruptible(&dev.writeblock); 1049 break; 1050 1051 case HIMT_RECORD_DONE: 1052 if (dev.last_recbank == LOBYTE(wMessage)) 1053 break; 1054 dev.last_recbank = LOBYTE(wMessage); 1055 1056 pack_DARQ_to_DARF(dev.last_recbank); 1057 1058 if (test_bit(F_READBLOCK, &dev.flags)) 1059 wake_up_interruptible(&dev.readblock); 1060 break; 1061 1062 case HIMT_DSP: 1063 switch (LOBYTE(wMessage)) { 1064#ifndef MSND_CLASSIC 1065 case HIDSP_PLAY_UNDER: 1066#endif 1067 case HIDSP_INT_PLAY_UNDER: 1068/* printk(KERN_DEBUG LOGNAME ": Play underflow\n"); */ 1069 clear_bit(F_WRITING, &dev.flags); 1070 break; 1071 1072 case HIDSP_INT_RECORD_OVER: 1073/* printk(KERN_DEBUG LOGNAME ": Record overflow\n"); */ 1074 clear_bit(F_READING, &dev.flags); 1075 break; 1076 1077 default: 1078/* printk(KERN_DEBUG LOGNAME ": DSP message %d 0x%02x\n", 1079 LOBYTE(wMessage), LOBYTE(wMessage)); */ 1080 break; 1081 } 1082 break; 1083 1084 case HIMT_MIDI_IN_UCHAR: 1085 if (dev.midi_in_interrupt) 1086 (*dev.midi_in_interrupt)(&dev); 1087 break; 1088 1089 default: 1090/* printk(KERN_DEBUG LOGNAME ": HIMT message %d 0x%02x\n", HIBYTE(wMessage), HIBYTE(wMessage)); */ 1091 break; 1092 } 1093} 1094 1095static irqreturn_t intr(int irq, void *dev_id) 1096{ 1097 /* Send ack to DSP */ 1098 msnd_inb(dev.io + HP_RXL); 1099 1100 /* Evaluate queued DSP messages */ 1101 while (readw(dev.DSPQ + JQS_wTail) != readw(dev.DSPQ + JQS_wHead)) { 1102 register WORD wTmp; 1103 1104 eval_dsp_msg(readw(dev.pwDSPQData + 2*readw(dev.DSPQ + JQS_wHead))); 1105 1106 if ((wTmp = readw(dev.DSPQ + JQS_wHead) + 1) > readw(dev.DSPQ + JQS_wSize)) 1107 writew(0, dev.DSPQ + JQS_wHead); 1108 else 1109 writew(wTmp, dev.DSPQ + JQS_wHead); 1110 } 1111 return IRQ_HANDLED; 1112} 1113 1114static const struct file_operations dev_fileops = { 1115 .owner = THIS_MODULE, 1116 .read = dev_read, 1117 .write = dev_write, 1118 .unlocked_ioctl = dev_ioctl, 1119 .open = dev_open, 1120 .release = dev_release, 1121 .llseek = noop_llseek, 1122}; 1123 1124static int reset_dsp(void) 1125{ 1126 int timeout = 100; 1127 1128 msnd_outb(HPDSPRESET_ON, dev.io + HP_DSPR); 1129 mdelay(1); 1130#ifndef MSND_CLASSIC 1131 dev.info = msnd_inb(dev.io + HP_INFO); 1132#endif 1133 msnd_outb(HPDSPRESET_OFF, dev.io + HP_DSPR); 1134 mdelay(1); 1135 while (timeout-- > 0) { 1136 if (msnd_inb(dev.io + HP_CVR) == HP_CVR_DEF) 1137 return 0; 1138 mdelay(1); 1139 } 1140 printk(KERN_ERR LOGNAME ": Cannot reset DSP\n"); 1141 1142 return -EIO; 1143} 1144 1145static int __init probe_multisound(void) 1146{ 1147#ifndef MSND_CLASSIC 1148 char *xv, *rev = NULL; 1149 char *pin = "Pinnacle", *fiji = "Fiji"; 1150 char *pinfiji = "Pinnacle/Fiji"; 1151#endif 1152 1153 if (!request_region(dev.io, dev.numio, "probing")) { 1154 printk(KERN_ERR LOGNAME ": I/O port conflict\n"); 1155 return -ENODEV; 1156 } 1157 1158 if (reset_dsp() < 0) { 1159 release_region(dev.io, dev.numio); 1160 return -ENODEV; 1161 } 1162 1163#ifdef MSND_CLASSIC 1164 dev.name = "Classic/Tahiti/Monterey"; 1165 printk(KERN_INFO LOGNAME ": %s, " 1166#else 1167 switch (dev.info >> 4) { 1168 case 0xf: xv = "<= 1.15"; break; 1169 case 0x1: xv = "1.18/1.2"; break; 1170 case 0x2: xv = "1.3"; break; 1171 case 0x3: xv = "1.4"; break; 1172 default: xv = "unknown"; break; 1173 } 1174 1175 switch (dev.info & 0x7) { 1176 case 0x0: rev = "I"; dev.name = pin; break; 1177 case 0x1: rev = "F"; dev.name = pin; break; 1178 case 0x2: rev = "G"; dev.name = pin; break; 1179 case 0x3: rev = "H"; dev.name = pin; break; 1180 case 0x4: rev = "E"; dev.name = fiji; break; 1181 case 0x5: rev = "C"; dev.name = fiji; break; 1182 case 0x6: rev = "D"; dev.name = fiji; break; 1183 case 0x7: 1184 rev = "A-B (Fiji) or A-E (Pinnacle)"; 1185 dev.name = pinfiji; 1186 break; 1187 } 1188 printk(KERN_INFO LOGNAME ": %s revision %s, Xilinx version %s, " 1189#endif /* MSND_CLASSIC */ 1190 "I/O 0x%x-0x%x, IRQ %d, memory mapped to %p-%p\n", 1191 dev.name, 1192#ifndef MSND_CLASSIC 1193 rev, xv, 1194#endif 1195 dev.io, dev.io + dev.numio - 1, 1196 dev.irq, 1197 dev.base, dev.base + 0x7fff); 1198 1199 release_region(dev.io, dev.numio); 1200 return 0; 1201} 1202 1203static int init_sma(void) 1204{ 1205 static int initted; 1206 WORD mastVolLeft, mastVolRight; 1207 unsigned long flags; 1208 1209#ifdef MSND_CLASSIC 1210 msnd_outb(dev.memid, dev.io + HP_MEMM); 1211#endif 1212 msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS); 1213 if (initted) { 1214 mastVolLeft = readw(dev.SMA + SMA_wCurrMastVolLeft); 1215 mastVolRight = readw(dev.SMA + SMA_wCurrMastVolRight); 1216 } else 1217 mastVolLeft = mastVolRight = 0; 1218 memset_io(dev.base, 0, 0x8000); 1219 1220 /* Critical section: bank 1 access */ 1221 spin_lock_irqsave(&dev.lock, flags); 1222 msnd_outb(HPBLKSEL_1, dev.io + HP_BLKS); 1223 memset_io(dev.base, 0, 0x8000); 1224 msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS); 1225 spin_unlock_irqrestore(&dev.lock, flags); 1226 1227 dev.pwDSPQData = (dev.base + DSPQ_DATA_BUFF); 1228 dev.pwMODQData = (dev.base + MODQ_DATA_BUFF); 1229 dev.pwMIDQData = (dev.base + MIDQ_DATA_BUFF); 1230 1231 /* Motorola 56k shared memory base */ 1232 dev.SMA = dev.base + SMA_STRUCT_START; 1233 1234 /* Digital audio play queue */ 1235 dev.DAPQ = dev.base + DAPQ_OFFSET; 1236 msnd_init_queue(dev.DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE); 1237 1238 /* Digital audio record queue */ 1239 dev.DARQ = dev.base + DARQ_OFFSET; 1240 msnd_init_queue(dev.DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); 1241 1242 /* MIDI out queue */ 1243 dev.MODQ = dev.base + MODQ_OFFSET; 1244 msnd_init_queue(dev.MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE); 1245 1246 /* MIDI in queue */ 1247 dev.MIDQ = dev.base + MIDQ_OFFSET; 1248 msnd_init_queue(dev.MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE); 1249 1250 /* DSP -> host message queue */ 1251 dev.DSPQ = dev.base + DSPQ_OFFSET; 1252 msnd_init_queue(dev.DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE); 1253 1254 /* Setup some DSP values */ 1255#ifndef MSND_CLASSIC 1256 writew(1, dev.SMA + SMA_wCurrPlayFormat); 1257 writew(dev.play_sample_size, dev.SMA + SMA_wCurrPlaySampleSize); 1258 writew(dev.play_channels, dev.SMA + SMA_wCurrPlayChannels); 1259 writew(dev.play_sample_rate, dev.SMA + SMA_wCurrPlaySampleRate); 1260#endif 1261 writew(dev.play_sample_rate, dev.SMA + SMA_wCalFreqAtoD); 1262 writew(mastVolLeft, dev.SMA + SMA_wCurrMastVolLeft); 1263 writew(mastVolRight, dev.SMA + SMA_wCurrMastVolRight); 1264#ifndef MSND_CLASSIC 1265 writel(0x00010000, dev.SMA + SMA_dwCurrPlayPitch); 1266 writel(0x00000001, dev.SMA + SMA_dwCurrPlayRate); 1267#endif 1268 writew(0x303, dev.SMA + SMA_wCurrInputTagBits); 1269 1270 initted = 1; 1271 1272 return 0; 1273} 1274 1275static int __init calibrate_adc(WORD srate) 1276{ 1277 writew(srate, dev.SMA + SMA_wCalFreqAtoD); 1278 if (dev.calibrate_signal == 0) 1279 writew(readw(dev.SMA + SMA_wCurrHostStatusFlags) 1280 | 0x0001, dev.SMA + SMA_wCurrHostStatusFlags); 1281 else 1282 writew(readw(dev.SMA + SMA_wCurrHostStatusFlags) 1283 & ~0x0001, dev.SMA + SMA_wCurrHostStatusFlags); 1284 if (msnd_send_word(&dev, 0, 0, HDEXAR_CAL_A_TO_D) == 0 && 1285 chk_send_dsp_cmd(&dev, HDEX_AUX_REQ) == 0) { 1286 current->state = TASK_INTERRUPTIBLE; 1287 schedule_timeout(HZ / 3); 1288 return 0; 1289 } 1290 printk(KERN_WARNING LOGNAME ": ADC calibration failed\n"); 1291 1292 return -EIO; 1293} 1294 1295static int upload_dsp_code(void) 1296{ 1297 msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS); 1298#ifndef HAVE_DSPCODEH 1299 INITCODESIZE = mod_firmware_load(INITCODEFILE, &INITCODE); 1300 if (!INITCODE) { 1301 printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE); 1302 return -EBUSY; 1303 } 1304 1305 PERMCODESIZE = mod_firmware_load(PERMCODEFILE, &PERMCODE); 1306 if (!PERMCODE) { 1307 printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE); 1308 vfree(INITCODE); 1309 return -EBUSY; 1310 } 1311#endif 1312 memcpy_toio(dev.base, PERMCODE, PERMCODESIZE); 1313 if (msnd_upload_host(&dev, INITCODE, INITCODESIZE) < 0) { 1314 printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n"); 1315 return -ENODEV; 1316 } 1317#ifdef HAVE_DSPCODEH 1318 printk(KERN_INFO LOGNAME ": DSP firmware uploaded (resident)\n"); 1319#else 1320 printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n"); 1321#endif 1322 1323#ifndef HAVE_DSPCODEH 1324 vfree(INITCODE); 1325 vfree(PERMCODE); 1326#endif 1327 1328 return 0; 1329} 1330 1331#ifdef MSND_CLASSIC 1332static void reset_proteus(void) 1333{ 1334 msnd_outb(HPPRORESET_ON, dev.io + HP_PROR); 1335 mdelay(TIME_PRO_RESET); 1336 msnd_outb(HPPRORESET_OFF, dev.io + HP_PROR); 1337 mdelay(TIME_PRO_RESET_DONE); 1338} 1339#endif 1340 1341static int initialize(void) 1342{ 1343 int err, timeout; 1344 1345#ifdef MSND_CLASSIC 1346 msnd_outb(HPWAITSTATE_0, dev.io + HP_WAIT); 1347 msnd_outb(HPBITMODE_16, dev.io + HP_BITM); 1348 1349 reset_proteus(); 1350#endif 1351 if ((err = init_sma()) < 0) { 1352 printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n"); 1353 return err; 1354 } 1355 1356 if ((err = reset_dsp()) < 0) 1357 return err; 1358 1359 if ((err = upload_dsp_code()) < 0) { 1360 printk(KERN_WARNING LOGNAME ": Cannot upload DSP code\n"); 1361 return err; 1362 } 1363 1364 timeout = 200; 1365 while (readw(dev.base)) { 1366 mdelay(1); 1367 if (!timeout--) { 1368 printk(KERN_DEBUG LOGNAME ": DSP reset timeout\n"); 1369 return -EIO; 1370 } 1371 } 1372 1373 mixer_setup(); 1374 1375 return 0; 1376} 1377 1378static int dsp_full_reset(void) 1379{ 1380 int rv; 1381 1382 if (test_bit(F_RESETTING, &dev.flags) || ++dev.nresets > 10) 1383 return 0; 1384 1385 set_bit(F_RESETTING, &dev.flags); 1386 printk(KERN_INFO LOGNAME ": DSP reset\n"); 1387 dsp_halt(NULL); /* Unconditionally halt */ 1388 if ((rv = initialize())) 1389 printk(KERN_WARNING LOGNAME ": DSP reset failed\n"); 1390 force_recsrc(dev.recsrc); 1391 dsp_open(NULL); 1392 clear_bit(F_RESETTING, &dev.flags); 1393 1394 return rv; 1395} 1396 1397static int __init attach_multisound(void) 1398{ 1399 int err; 1400 1401 if ((err = request_irq(dev.irq, intr, 0, dev.name, &dev)) < 0) { 1402 printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", dev.irq); 1403 return err; 1404 } 1405 if (request_region(dev.io, dev.numio, dev.name) == NULL) { 1406 free_irq(dev.irq, &dev); 1407 return -EBUSY; 1408 } 1409 1410 err = dsp_full_reset(); 1411 if (err < 0) { 1412 release_region(dev.io, dev.numio); 1413 free_irq(dev.irq, &dev); 1414 return err; 1415 } 1416 1417 if ((err = msnd_register(&dev)) < 0) { 1418 printk(KERN_ERR LOGNAME ": Unable to register MultiSound\n"); 1419 release_region(dev.io, dev.numio); 1420 free_irq(dev.irq, &dev); 1421 return err; 1422 } 1423 1424 if ((dev.dsp_minor = register_sound_dsp(&dev_fileops, -1)) < 0) { 1425 printk(KERN_ERR LOGNAME ": Unable to register DSP operations\n"); 1426 msnd_unregister(&dev); 1427 release_region(dev.io, dev.numio); 1428 free_irq(dev.irq, &dev); 1429 return dev.dsp_minor; 1430 } 1431 1432 if ((dev.mixer_minor = register_sound_mixer(&dev_fileops, -1)) < 0) { 1433 printk(KERN_ERR LOGNAME ": Unable to register mixer operations\n"); 1434 unregister_sound_mixer(dev.mixer_minor); 1435 msnd_unregister(&dev); 1436 release_region(dev.io, dev.numio); 1437 free_irq(dev.irq, &dev); 1438 return dev.mixer_minor; 1439 } 1440 1441 dev.ext_midi_dev = dev.hdr_midi_dev = -1; 1442 1443 disable_irq(dev.irq); 1444 calibrate_adc(dev.play_sample_rate); 1445#ifndef MSND_CLASSIC 1446 force_recsrc(SOUND_MASK_IMIX); 1447#endif 1448 1449 return 0; 1450} 1451 1452static void __exit unload_multisound(void) 1453{ 1454 release_region(dev.io, dev.numio); 1455 free_irq(dev.irq, &dev); 1456 unregister_sound_mixer(dev.mixer_minor); 1457 unregister_sound_dsp(dev.dsp_minor); 1458 msnd_unregister(&dev); 1459} 1460 1461#ifndef MSND_CLASSIC 1462 1463/* Pinnacle/Fiji Logical Device Configuration */ 1464 1465static int __init msnd_write_cfg(int cfg, int reg, int value) 1466{ 1467 msnd_outb(reg, cfg); 1468 msnd_outb(value, cfg + 1); 1469 if (value != msnd_inb(cfg + 1)) { 1470 printk(KERN_ERR LOGNAME ": msnd_write_cfg: I/O error\n"); 1471 return -EIO; 1472 } 1473 return 0; 1474} 1475 1476static int __init msnd_write_cfg_io0(int cfg, int num, WORD io) 1477{ 1478 if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) 1479 return -EIO; 1480 if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io))) 1481 return -EIO; 1482 if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io))) 1483 return -EIO; 1484 return 0; 1485} 1486 1487static int __init msnd_write_cfg_io1(int cfg, int num, WORD io) 1488{ 1489 if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) 1490 return -EIO; 1491 if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io))) 1492 return -EIO; 1493 if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io))) 1494 return -EIO; 1495 return 0; 1496} 1497 1498static int __init msnd_write_cfg_irq(int cfg, int num, WORD irq) 1499{ 1500 if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) 1501 return -EIO; 1502 if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq))) 1503 return -EIO; 1504 if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE)) 1505 return -EIO; 1506 return 0; 1507} 1508 1509static int __init msnd_write_cfg_mem(int cfg, int num, int mem) 1510{ 1511 WORD wmem; 1512 1513 mem >>= 8; 1514 mem &= 0xfff; 1515 wmem = (WORD)mem; 1516 if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) 1517 return -EIO; 1518 if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem))) 1519 return -EIO; 1520 if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem))) 1521 return -EIO; 1522 if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT))) 1523 return -EIO; 1524 return 0; 1525} 1526 1527static int __init msnd_activate_logical(int cfg, int num) 1528{ 1529 if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) 1530 return -EIO; 1531 if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE)) 1532 return -EIO; 1533 return 0; 1534} 1535 1536static int __init msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem) 1537{ 1538 if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num)) 1539 return -EIO; 1540 if (msnd_write_cfg_io0(cfg, num, io0)) 1541 return -EIO; 1542 if (msnd_write_cfg_io1(cfg, num, io1)) 1543 return -EIO; 1544 if (msnd_write_cfg_irq(cfg, num, irq)) 1545 return -EIO; 1546 if (msnd_write_cfg_mem(cfg, num, mem)) 1547 return -EIO; 1548 if (msnd_activate_logical(cfg, num)) 1549 return -EIO; 1550 return 0; 1551} 1552 1553typedef struct msnd_pinnacle_cfg_device { 1554 WORD io0, io1, irq; 1555 int mem; 1556} msnd_pinnacle_cfg_t[4]; 1557 1558static int __init msnd_pinnacle_cfg_devices(int cfg, int reset, msnd_pinnacle_cfg_t device) 1559{ 1560 int i; 1561 1562 /* Reset devices if told to */ 1563 if (reset) { 1564 printk(KERN_INFO LOGNAME ": Resetting all devices\n"); 1565 for (i = 0; i < 4; ++i) 1566 if (msnd_write_cfg_logical(cfg, i, 0, 0, 0, 0)) 1567 return -EIO; 1568 } 1569 1570 /* Configure specified devices */ 1571 for (i = 0; i < 4; ++i) { 1572 1573 switch (i) { 1574 case 0: /* DSP */ 1575 if (!(device[i].io0 && device[i].irq && device[i].mem)) 1576 continue; 1577 break; 1578 case 1: /* MPU */ 1579 if (!(device[i].io0 && device[i].irq)) 1580 continue; 1581 printk(KERN_INFO LOGNAME 1582 ": Configuring MPU to I/O 0x%x IRQ %d\n", 1583 device[i].io0, device[i].irq); 1584 break; 1585 case 2: /* IDE */ 1586 if (!(device[i].io0 && device[i].io1 && device[i].irq)) 1587 continue; 1588 printk(KERN_INFO LOGNAME 1589 ": Configuring IDE to I/O 0x%x, 0x%x IRQ %d\n", 1590 device[i].io0, device[i].io1, device[i].irq); 1591 break; 1592 case 3: /* Joystick */ 1593 if (!(device[i].io0)) 1594 continue; 1595 printk(KERN_INFO LOGNAME 1596 ": Configuring joystick to I/O 0x%x\n", 1597 device[i].io0); 1598 break; 1599 } 1600 1601 /* Configure the device */ 1602 if (msnd_write_cfg_logical(cfg, i, device[i].io0, device[i].io1, device[i].irq, device[i].mem)) 1603 return -EIO; 1604 } 1605 1606 return 0; 1607} 1608#endif 1609 1610#ifdef MODULE 1611MODULE_AUTHOR ("Andrew Veliath <andrewtv@usa.net>"); 1612MODULE_DESCRIPTION ("Turtle Beach " LONGNAME " Linux Driver"); 1613MODULE_LICENSE("GPL"); 1614 1615static int io __initdata = -1; 1616static int irq __initdata = -1; 1617static int mem __initdata = -1; 1618static int write_ndelay __initdata = -1; 1619 1620#ifndef MSND_CLASSIC 1621/* Pinnacle/Fiji non-PnP Config Port */ 1622static int cfg __initdata = -1; 1623 1624/* Extra Peripheral Configuration */ 1625static int reset __initdata = 0; 1626static int mpu_io __initdata = 0; 1627static int mpu_irq __initdata = 0; 1628static int ide_io0 __initdata = 0; 1629static int ide_io1 __initdata = 0; 1630static int ide_irq __initdata = 0; 1631static int joystick_io __initdata = 0; 1632 1633/* If we have the digital daugherboard... */ 1634static int digital __initdata = 0; 1635#endif 1636 1637static int fifosize __initdata = DEFFIFOSIZE; 1638static int calibrate_signal __initdata = 0; 1639 1640#else /* not a module */ 1641 1642static int write_ndelay __initdata = -1; 1643 1644#ifdef MSND_CLASSIC 1645static int io __initdata = CONFIG_MSNDCLAS_IO; 1646static int irq __initdata = CONFIG_MSNDCLAS_IRQ; 1647static int mem __initdata = CONFIG_MSNDCLAS_MEM; 1648#else /* Pinnacle/Fiji */ 1649 1650static int io __initdata = CONFIG_MSNDPIN_IO; 1651static int irq __initdata = CONFIG_MSNDPIN_IRQ; 1652static int mem __initdata = CONFIG_MSNDPIN_MEM; 1653 1654/* Pinnacle/Fiji non-PnP Config Port */ 1655#ifdef CONFIG_MSNDPIN_NONPNP 1656# ifndef CONFIG_MSNDPIN_CFG 1657# define CONFIG_MSNDPIN_CFG 0x250 1658# endif 1659#else 1660# ifdef CONFIG_MSNDPIN_CFG 1661# undef CONFIG_MSNDPIN_CFG 1662# endif 1663# define CONFIG_MSNDPIN_CFG -1 1664#endif 1665static int cfg __initdata = CONFIG_MSNDPIN_CFG; 1666/* If not a module, we don't need to bother with reset=1 */ 1667static int reset; 1668 1669/* Extra Peripheral Configuration (Default: Disable) */ 1670#ifndef CONFIG_MSNDPIN_MPU_IO 1671# define CONFIG_MSNDPIN_MPU_IO 0 1672#endif 1673static int mpu_io __initdata = CONFIG_MSNDPIN_MPU_IO; 1674 1675#ifndef CONFIG_MSNDPIN_MPU_IRQ 1676# define CONFIG_MSNDPIN_MPU_IRQ 0 1677#endif 1678static int mpu_irq __initdata = CONFIG_MSNDPIN_MPU_IRQ; 1679 1680#ifndef CONFIG_MSNDPIN_IDE_IO0 1681# define CONFIG_MSNDPIN_IDE_IO0 0 1682#endif 1683static int ide_io0 __initdata = CONFIG_MSNDPIN_IDE_IO0; 1684 1685#ifndef CONFIG_MSNDPIN_IDE_IO1 1686# define CONFIG_MSNDPIN_IDE_IO1 0 1687#endif 1688static int ide_io1 __initdata = CONFIG_MSNDPIN_IDE_IO1; 1689 1690#ifndef CONFIG_MSNDPIN_IDE_IRQ 1691# define CONFIG_MSNDPIN_IDE_IRQ 0 1692#endif 1693static int ide_irq __initdata = CONFIG_MSNDPIN_IDE_IRQ; 1694 1695#ifndef CONFIG_MSNDPIN_JOYSTICK_IO 1696# define CONFIG_MSNDPIN_JOYSTICK_IO 0 1697#endif 1698static int joystick_io __initdata = CONFIG_MSNDPIN_JOYSTICK_IO; 1699 1700/* Have SPDIF (Digital) Daughterboard */ 1701#ifndef CONFIG_MSNDPIN_DIGITAL 1702# define CONFIG_MSNDPIN_DIGITAL 0 1703#endif 1704static int digital __initdata = CONFIG_MSNDPIN_DIGITAL; 1705 1706#endif /* MSND_CLASSIC */ 1707 1708#ifndef CONFIG_MSND_FIFOSIZE 1709# define CONFIG_MSND_FIFOSIZE DEFFIFOSIZE 1710#endif 1711static int fifosize __initdata = CONFIG_MSND_FIFOSIZE; 1712 1713#ifndef CONFIG_MSND_CALSIGNAL 1714# define CONFIG_MSND_CALSIGNAL 0 1715#endif 1716static int 1717calibrate_signal __initdata = CONFIG_MSND_CALSIGNAL; 1718#endif /* MODULE */ 1719 1720module_param (io, int, 0); 1721module_param (irq, int, 0); 1722module_param (mem, int, 0); 1723module_param (write_ndelay, int, 0); 1724module_param (fifosize, int, 0); 1725module_param (calibrate_signal, int, 0); 1726#ifndef MSND_CLASSIC 1727module_param (digital, bool, 0); 1728module_param (cfg, int, 0); 1729module_param (reset, int, 0); 1730module_param (mpu_io, int, 0); 1731module_param (mpu_irq, int, 0); 1732module_param (ide_io0, int, 0); 1733module_param (ide_io1, int, 0); 1734module_param (ide_irq, int, 0); 1735module_param (joystick_io, int, 0); 1736#endif 1737 1738static int __init msnd_init(void) 1739{ 1740 int err; 1741#ifndef MSND_CLASSIC 1742 static msnd_pinnacle_cfg_t pinnacle_devs; 1743#endif /* MSND_CLASSIC */ 1744 1745 printk(KERN_INFO LOGNAME ": Turtle Beach " LONGNAME " Linux Driver Version " 1746 VERSION ", Copyright (C) 1998 Andrew Veliath\n"); 1747 1748 if (io == -1 || irq == -1 || mem == -1) 1749 printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n"); 1750 1751#ifdef MSND_CLASSIC 1752 if (io == -1 || 1753 !(io == 0x290 || 1754 io == 0x260 || 1755 io == 0x250 || 1756 io == 0x240 || 1757 io == 0x230 || 1758 io == 0x220 || 1759 io == 0x210 || 1760 io == 0x3e0)) { 1761 printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n"); 1762 return -EINVAL; 1763 } 1764#else 1765 if (io == -1 || 1766 io < 0x100 || 1767 io > 0x3e0 || 1768 (io % 0x10) != 0) { 1769 printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n"); 1770 return -EINVAL; 1771 } 1772#endif /* MSND_CLASSIC */ 1773 1774 if (irq == -1 || 1775 !(irq == 5 || 1776 irq == 7 || 1777 irq == 9 || 1778 irq == 10 || 1779 irq == 11 || 1780 irq == 12)) { 1781 printk(KERN_ERR LOGNAME ": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n"); 1782 return -EINVAL; 1783 } 1784 1785 if (mem == -1 || 1786 !(mem == 0xb0000 || 1787 mem == 0xc8000 || 1788 mem == 0xd0000 || 1789 mem == 0xd8000 || 1790 mem == 0xe0000 || 1791 mem == 0xe8000)) { 1792 printk(KERN_ERR LOGNAME ": \"mem\" - must be set to " 1793 "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n"); 1794 return -EINVAL; 1795 } 1796 1797#ifdef MSND_CLASSIC 1798 switch (irq) { 1799 case 5: dev.irqid = HPIRQ_5; break; 1800 case 7: dev.irqid = HPIRQ_7; break; 1801 case 9: dev.irqid = HPIRQ_9; break; 1802 case 10: dev.irqid = HPIRQ_10; break; 1803 case 11: dev.irqid = HPIRQ_11; break; 1804 case 12: dev.irqid = HPIRQ_12; break; 1805 } 1806 1807 switch (mem) { 1808 case 0xb0000: dev.memid = HPMEM_B000; break; 1809 case 0xc8000: dev.memid = HPMEM_C800; break; 1810 case 0xd0000: dev.memid = HPMEM_D000; break; 1811 case 0xd8000: dev.memid = HPMEM_D800; break; 1812 case 0xe0000: dev.memid = HPMEM_E000; break; 1813 case 0xe8000: dev.memid = HPMEM_E800; break; 1814 } 1815#else 1816 if (cfg == -1) { 1817 printk(KERN_INFO LOGNAME ": Assuming PnP mode\n"); 1818 } else if (cfg != 0x250 && cfg != 0x260 && cfg != 0x270) { 1819 printk(KERN_INFO LOGNAME ": Config port must be 0x250, 0x260 or 0x270 (or unspecified for PnP mode)\n"); 1820 return -EINVAL; 1821 } else { 1822 printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%x\n", cfg); 1823 1824 /* DSP */ 1825 pinnacle_devs[0].io0 = io; 1826 pinnacle_devs[0].irq = irq; 1827 pinnacle_devs[0].mem = mem; 1828 1829 /* The following are Pinnacle specific */ 1830 1831 /* MPU */ 1832 pinnacle_devs[1].io0 = mpu_io; 1833 pinnacle_devs[1].irq = mpu_irq; 1834 1835 /* IDE */ 1836 pinnacle_devs[2].io0 = ide_io0; 1837 pinnacle_devs[2].io1 = ide_io1; 1838 pinnacle_devs[2].irq = ide_irq; 1839 1840 /* Joystick */ 1841 pinnacle_devs[3].io0 = joystick_io; 1842 1843 if (!request_region(cfg, 2, "Pinnacle/Fiji Config")) { 1844 printk(KERN_ERR LOGNAME ": Config port 0x%x conflict\n", cfg); 1845 return -EIO; 1846 } 1847 1848 if (msnd_pinnacle_cfg_devices(cfg, reset, pinnacle_devs)) { 1849 printk(KERN_ERR LOGNAME ": Device configuration error\n"); 1850 release_region(cfg, 2); 1851 return -EIO; 1852 } 1853 release_region(cfg, 2); 1854 } 1855#endif /* MSND_CLASSIC */ 1856 1857 if (fifosize < 16) 1858 fifosize = 16; 1859 1860 if (fifosize > 1024) 1861 fifosize = 1024; 1862 1863 set_default_audio_parameters(); 1864#ifdef MSND_CLASSIC 1865 dev.type = msndClassic; 1866#else 1867 dev.type = msndPinnacle; 1868#endif 1869 dev.io = io; 1870 dev.numio = DSP_NUMIO; 1871 dev.irq = irq; 1872 dev.base = ioremap(mem, 0x8000); 1873 dev.fifosize = fifosize * 1024; 1874 dev.calibrate_signal = calibrate_signal ? 1 : 0; 1875 dev.recsrc = 0; 1876 dev.dspq_data_buff = DSPQ_DATA_BUFF; 1877 dev.dspq_buff_size = DSPQ_BUFF_SIZE; 1878 if (write_ndelay == -1) 1879 write_ndelay = CONFIG_MSND_WRITE_NDELAY; 1880 if (write_ndelay) 1881 clear_bit(F_DISABLE_WRITE_NDELAY, &dev.flags); 1882 else 1883 set_bit(F_DISABLE_WRITE_NDELAY, &dev.flags); 1884#ifndef MSND_CLASSIC 1885 if (digital) 1886 set_bit(F_HAVEDIGITAL, &dev.flags); 1887#endif 1888 init_waitqueue_head(&dev.writeblock); 1889 init_waitqueue_head(&dev.readblock); 1890 init_waitqueue_head(&dev.writeflush); 1891 msnd_fifo_init(&dev.DAPF); 1892 msnd_fifo_init(&dev.DARF); 1893 spin_lock_init(&dev.lock); 1894 printk(KERN_INFO LOGNAME ": %u byte audio FIFOs (x2)\n", dev.fifosize); 1895 if ((err = msnd_fifo_alloc(&dev.DAPF, dev.fifosize)) < 0) { 1896 printk(KERN_ERR LOGNAME ": Couldn't allocate write FIFO\n"); 1897 return err; 1898 } 1899 1900 if ((err = msnd_fifo_alloc(&dev.DARF, dev.fifosize)) < 0) { 1901 printk(KERN_ERR LOGNAME ": Couldn't allocate read FIFO\n"); 1902 msnd_fifo_free(&dev.DAPF); 1903 return err; 1904 } 1905 1906 if ((err = probe_multisound()) < 0) { 1907 printk(KERN_ERR LOGNAME ": Probe failed\n"); 1908 msnd_fifo_free(&dev.DAPF); 1909 msnd_fifo_free(&dev.DARF); 1910 return err; 1911 } 1912 1913 if ((err = attach_multisound()) < 0) { 1914 printk(KERN_ERR LOGNAME ": Attach failed\n"); 1915 msnd_fifo_free(&dev.DAPF); 1916 msnd_fifo_free(&dev.DARF); 1917 return err; 1918 } 1919 1920 return 0; 1921} 1922 1923static void __exit msdn_cleanup(void) 1924{ 1925 unload_multisound(); 1926 msnd_fifo_free(&dev.DAPF); 1927 msnd_fifo_free(&dev.DARF); 1928} 1929 1930module_init(msnd_init); 1931module_exit(msdn_cleanup);