1 /********************************************************************* 2 * 3 * 2002/06/30 Karsten Wiese: 4 * removed kernel-version dependencies. 5 * ripped from linux kernel 2.4.18 (OSS Implementation) by me. 6 * In the OSS Version, this file is compiled to a separate MODULE, 7 * that is used by the pinnacle and the classic driver. 8 * since there is no classic driver for alsa yet (i dont have a classic 9 * & writing one blindfold is difficult) this file's object is statically 10 * linked into the pinnacle-driver-module for now. look for the string 11 * "uncomment this to make this a module again" 12 * to do guess what. 13 * 14 * the following is a copy of the 2.4.18 OSS FREE file-heading comment: 15 * 16 * msnd.c - Driver Base 17 * 18 * Turtle Beach MultiSound Sound Card Driver for Linux 19 * 20 * Copyright (C) 1998 Andrew Veliath 21 * 22 * This program is free software; you can redistribute it and/or modify 23 * it under the terms of the GNU General Public License as published by 24 * the Free Software Foundation; either version 2 of the License, or 25 * (at your option) any later version. 26 * 27 * This program is distributed in the hope that it will be useful, 28 * but WITHOUT ANY WARRANTY; without even the implied warranty of 29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 * GNU General Public License for more details. 31 * 32 * You should have received a copy of the GNU General Public License 33 * along with this program; if not, write to the Free Software 34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 35 * 36 ********************************************************************/ 37 38 #include <linux/kernel.h> 39 #include <linux/types.h> 40 #include <linux/interrupt.h> 41 #include <linux/io.h> 42 #include <linux/fs.h> 43 #include <linux/delay.h> 44 45 #include <sound/core.h> 46 #include <sound/initval.h> 47 #include <sound/pcm.h> 48 #include <sound/pcm_params.h> 49 50 #include "msnd.h" 51 52 #define LOGNAME "msnd" 53 54 55 void snd_msnd_init_queue(void *base, int start, int size) 56 { 57 writew(PCTODSP_BASED(start), base + JQS_wStart); 58 writew(PCTODSP_OFFSET(size) - 1, base + JQS_wSize); 59 writew(0, base + JQS_wHead); 60 writew(0, base + JQS_wTail); 61 } 62 EXPORT_SYMBOL(snd_msnd_init_queue); 63 64 static int snd_msnd_wait_TXDE(struct snd_msnd *dev) 65 { 66 unsigned int io = dev->io; 67 int timeout = 1000; 68 69 while (timeout-- > 0) 70 if (inb(io + HP_ISR) & HPISR_TXDE) 71 return 0; 72 73 return -EIO; 74 } 75 76 static int snd_msnd_wait_HC0(struct snd_msnd *dev) 77 { 78 unsigned int io = dev->io; 79 int timeout = 1000; 80 81 while (timeout-- > 0) 82 if (!(inb(io + HP_CVR) & HPCVR_HC)) 83 return 0; 84 85 return -EIO; 86 } 87 88 int snd_msnd_send_dsp_cmd(struct snd_msnd *dev, u8 cmd) 89 { 90 unsigned long flags; 91 92 spin_lock_irqsave(&dev->lock, flags); 93 if (snd_msnd_wait_HC0(dev) == 0) { 94 outb(cmd, dev->io + HP_CVR); 95 spin_unlock_irqrestore(&dev->lock, flags); 96 return 0; 97 } 98 spin_unlock_irqrestore(&dev->lock, flags); 99 100 snd_printd(KERN_ERR LOGNAME ": Send DSP command timeout\n"); 101 102 return -EIO; 103 } 104 EXPORT_SYMBOL(snd_msnd_send_dsp_cmd); 105 106 int snd_msnd_send_word(struct snd_msnd *dev, unsigned char high, 107 unsigned char mid, unsigned char low) 108 { 109 unsigned int io = dev->io; 110 111 if (snd_msnd_wait_TXDE(dev) == 0) { 112 outb(high, io + HP_TXH); 113 outb(mid, io + HP_TXM); 114 outb(low, io + HP_TXL); 115 return 0; 116 } 117 118 snd_printd(KERN_ERR LOGNAME ": Send host word timeout\n"); 119 120 return -EIO; 121 } 122 EXPORT_SYMBOL(snd_msnd_send_word); 123 124 int snd_msnd_upload_host(struct snd_msnd *dev, const u8 *bin, int len) 125 { 126 int i; 127 128 if (len % 3 != 0) { 129 snd_printk(KERN_ERR LOGNAME 130 ": Upload host data not multiple of 3!\n"); 131 return -EINVAL; 132 } 133 134 for (i = 0; i < len; i += 3) 135 if (snd_msnd_send_word(dev, bin[i], bin[i + 1], bin[i + 2])) 136 return -EIO; 137 138 inb(dev->io + HP_RXL); 139 inb(dev->io + HP_CVR); 140 141 return 0; 142 } 143 EXPORT_SYMBOL(snd_msnd_upload_host); 144 145 int snd_msnd_enable_irq(struct snd_msnd *dev) 146 { 147 unsigned long flags; 148 149 if (dev->irq_ref++) 150 return 0; 151 152 snd_printdd(LOGNAME ": Enabling IRQ\n"); 153 154 spin_lock_irqsave(&dev->lock, flags); 155 if (snd_msnd_wait_TXDE(dev) == 0) { 156 outb(inb(dev->io + HP_ICR) | HPICR_TREQ, dev->io + HP_ICR); 157 if (dev->type == msndClassic) 158 outb(dev->irqid, dev->io + HP_IRQM); 159 160 outb(inb(dev->io + HP_ICR) & ~HPICR_TREQ, dev->io + HP_ICR); 161 outb(inb(dev->io + HP_ICR) | HPICR_RREQ, dev->io + HP_ICR); 162 enable_irq(dev->irq); 163 snd_msnd_init_queue(dev->DSPQ, dev->dspq_data_buff, 164 dev->dspq_buff_size); 165 spin_unlock_irqrestore(&dev->lock, flags); 166 return 0; 167 } 168 spin_unlock_irqrestore(&dev->lock, flags); 169 170 snd_printd(KERN_ERR LOGNAME ": Enable IRQ failed\n"); 171 172 return -EIO; 173 } 174 EXPORT_SYMBOL(snd_msnd_enable_irq); 175 176 int snd_msnd_disable_irq(struct snd_msnd *dev) 177 { 178 unsigned long flags; 179 180 if (--dev->irq_ref > 0) 181 return 0; 182 183 if (dev->irq_ref < 0) 184 snd_printd(KERN_WARNING LOGNAME ": IRQ ref count is %d\n", 185 dev->irq_ref); 186 187 snd_printdd(LOGNAME ": Disabling IRQ\n"); 188 189 spin_lock_irqsave(&dev->lock, flags); 190 if (snd_msnd_wait_TXDE(dev) == 0) { 191 outb(inb(dev->io + HP_ICR) & ~HPICR_RREQ, dev->io + HP_ICR); 192 if (dev->type == msndClassic) 193 outb(HPIRQ_NONE, dev->io + HP_IRQM); 194 disable_irq(dev->irq); 195 spin_unlock_irqrestore(&dev->lock, flags); 196 return 0; 197 } 198 spin_unlock_irqrestore(&dev->lock, flags); 199 200 snd_printd(KERN_ERR LOGNAME ": Disable IRQ failed\n"); 201 202 return -EIO; 203 } 204 EXPORT_SYMBOL(snd_msnd_disable_irq); 205 206 static inline long get_play_delay_jiffies(struct snd_msnd *chip, long size) 207 { 208 long tmp = (size * HZ * chip->play_sample_size) / 8; 209 return tmp / (chip->play_sample_rate * chip->play_channels); 210 } 211 212 static void snd_msnd_dsp_write_flush(struct snd_msnd *chip) 213 { 214 if (!(chip->mode & FMODE_WRITE) || !test_bit(F_WRITING, &chip->flags)) 215 return; 216 set_bit(F_WRITEFLUSH, &chip->flags); 217 /* interruptible_sleep_on_timeout( 218 &chip->writeflush, 219 get_play_delay_jiffies(&chip, chip->DAPF.len));*/ 220 clear_bit(F_WRITEFLUSH, &chip->flags); 221 if (!signal_pending(current)) 222 schedule_timeout_interruptible( 223 get_play_delay_jiffies(chip, chip->play_period_bytes)); 224 clear_bit(F_WRITING, &chip->flags); 225 } 226 227 void snd_msnd_dsp_halt(struct snd_msnd *chip, struct file *file) 228 { 229 if ((file ? file->f_mode : chip->mode) & FMODE_READ) { 230 clear_bit(F_READING, &chip->flags); 231 snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP); 232 snd_msnd_disable_irq(chip); 233 if (file) { 234 snd_printd(KERN_INFO LOGNAME 235 ": Stopping read for %p\n", file); 236 chip->mode &= ~FMODE_READ; 237 } 238 clear_bit(F_AUDIO_READ_INUSE, &chip->flags); 239 } 240 if ((file ? file->f_mode : chip->mode) & FMODE_WRITE) { 241 if (test_bit(F_WRITING, &chip->flags)) { 242 snd_msnd_dsp_write_flush(chip); 243 snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP); 244 } 245 snd_msnd_disable_irq(chip); 246 if (file) { 247 snd_printd(KERN_INFO 248 LOGNAME ": Stopping write for %p\n", file); 249 chip->mode &= ~FMODE_WRITE; 250 } 251 clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags); 252 } 253 } 254 EXPORT_SYMBOL(snd_msnd_dsp_halt); 255 256 257 int snd_msnd_DARQ(struct snd_msnd *chip, int bank) 258 { 259 int /*size, n,*/ timeout = 3; 260 u16 wTmp; 261 /* void *DAQD; */ 262 263 /* Increment the tail and check for queue wrap */ 264 wTmp = readw(chip->DARQ + JQS_wTail) + PCTODSP_OFFSET(DAQDS__size); 265 if (wTmp > readw(chip->DARQ + JQS_wSize)) 266 wTmp = 0; 267 while (wTmp == readw(chip->DARQ + JQS_wHead) && timeout--) 268 udelay(1); 269 270 if (chip->capturePeriods == 2) { 271 void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF + 272 bank * DAQDS__size + DAQDS_wStart; 273 unsigned short offset = 0x3000 + chip->capturePeriodBytes; 274 275 if (readw(pDAQ) != PCTODSP_BASED(0x3000)) 276 offset = 0x3000; 277 writew(PCTODSP_BASED(offset), pDAQ); 278 } 279 280 writew(wTmp, chip->DARQ + JQS_wTail); 281 282 #if 0 283 /* Get our digital audio queue struct */ 284 DAQD = bank * DAQDS__size + chip->mappedbase + DARQ_DATA_BUFF; 285 286 /* Get length of data */ 287 size = readw(DAQD + DAQDS_wSize); 288 289 /* Read data from the head (unprotected bank 1 access okay 290 since this is only called inside an interrupt) */ 291 outb(HPBLKSEL_1, chip->io + HP_BLKS); 292 n = msnd_fifo_write(&chip->DARF, 293 (char *)(chip->base + bank * DAR_BUFF_SIZE), 294 size, 0); 295 if (n <= 0) { 296 outb(HPBLKSEL_0, chip->io + HP_BLKS); 297 return n; 298 } 299 outb(HPBLKSEL_0, chip->io + HP_BLKS); 300 #endif 301 302 return 1; 303 } 304 EXPORT_SYMBOL(snd_msnd_DARQ); 305 306 int snd_msnd_DAPQ(struct snd_msnd *chip, int start) 307 { 308 u16 DAPQ_tail; 309 int protect = start, nbanks = 0; 310 void *DAQD; 311 static int play_banks_submitted; 312 /* unsigned long flags; 313 spin_lock_irqsave(&chip->lock, flags); not necessary */ 314 315 DAPQ_tail = readw(chip->DAPQ + JQS_wTail); 316 while (DAPQ_tail != readw(chip->DAPQ + JQS_wHead) || start) { 317 int bank_num = DAPQ_tail / PCTODSP_OFFSET(DAQDS__size); 318 319 if (start) { 320 start = 0; 321 play_banks_submitted = 0; 322 } 323 324 /* Get our digital audio queue struct */ 325 DAQD = bank_num * DAQDS__size + chip->mappedbase + 326 DAPQ_DATA_BUFF; 327 328 /* Write size of this bank */ 329 writew(chip->play_period_bytes, DAQD + DAQDS_wSize); 330 if (play_banks_submitted < 3) 331 ++play_banks_submitted; 332 else if (chip->playPeriods == 2) { 333 unsigned short offset = chip->play_period_bytes; 334 335 if (readw(DAQD + DAQDS_wStart) != PCTODSP_BASED(0x0)) 336 offset = 0; 337 338 writew(PCTODSP_BASED(offset), DAQD + DAQDS_wStart); 339 } 340 ++nbanks; 341 342 /* Then advance the tail */ 343 /* 344 if (protect) 345 snd_printd(KERN_INFO "B %X %lX\n", 346 bank_num, xtime.tv_usec); 347 */ 348 349 DAPQ_tail = (++bank_num % 3) * PCTODSP_OFFSET(DAQDS__size); 350 writew(DAPQ_tail, chip->DAPQ + JQS_wTail); 351 /* Tell the DSP to play the bank */ 352 snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_START); 353 if (protect) 354 if (2 == bank_num) 355 break; 356 } 357 /* 358 if (protect) 359 snd_printd(KERN_INFO "%lX\n", xtime.tv_usec); 360 */ 361 /* spin_unlock_irqrestore(&chip->lock, flags); not necessary */ 362 return nbanks; 363 } 364 EXPORT_SYMBOL(snd_msnd_DAPQ); 365 366 static void snd_msnd_play_reset_queue(struct snd_msnd *chip, 367 unsigned int pcm_periods, 368 unsigned int pcm_count) 369 { 370 int n; 371 void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF; 372 373 chip->last_playbank = -1; 374 chip->playLimit = pcm_count * (pcm_periods - 1); 375 chip->playPeriods = pcm_periods; 376 writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wHead); 377 writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DAPQ + JQS_wTail); 378 379 chip->play_period_bytes = pcm_count; 380 381 for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) { 382 writew(PCTODSP_BASED((u32)(pcm_count * n)), 383 pDAQ + DAQDS_wStart); 384 writew(0, pDAQ + DAQDS_wSize); 385 writew(1, pDAQ + DAQDS_wFormat); 386 writew(chip->play_sample_size, pDAQ + DAQDS_wSampleSize); 387 writew(chip->play_channels, pDAQ + DAQDS_wChannels); 388 writew(chip->play_sample_rate, pDAQ + DAQDS_wSampleRate); 389 writew(HIMT_PLAY_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg); 390 writew(n, pDAQ + DAQDS_wFlags); 391 } 392 } 393 394 static void snd_msnd_capture_reset_queue(struct snd_msnd *chip, 395 unsigned int pcm_periods, 396 unsigned int pcm_count) 397 { 398 int n; 399 void *pDAQ; 400 /* unsigned long flags; */ 401 402 /* snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE); */ 403 404 chip->last_recbank = 2; 405 chip->captureLimit = pcm_count * (pcm_periods - 1); 406 chip->capturePeriods = pcm_periods; 407 writew(PCTODSP_OFFSET(0 * DAQDS__size), chip->DARQ + JQS_wHead); 408 writew(PCTODSP_OFFSET(chip->last_recbank * DAQDS__size), 409 chip->DARQ + JQS_wTail); 410 411 #if 0 /* Critical section: bank 1 access. this is how the OSS driver does it:*/ 412 spin_lock_irqsave(&chip->lock, flags); 413 outb(HPBLKSEL_1, chip->io + HP_BLKS); 414 memset_io(chip->mappedbase, 0, DAR_BUFF_SIZE * 3); 415 outb(HPBLKSEL_0, chip->io + HP_BLKS); 416 spin_unlock_irqrestore(&chip->lock, flags); 417 #endif 418 419 chip->capturePeriodBytes = pcm_count; 420 snd_printdd("snd_msnd_capture_reset_queue() %i\n", pcm_count); 421 422 pDAQ = chip->mappedbase + DARQ_DATA_BUFF; 423 424 for (n = 0; n < pcm_periods; ++n, pDAQ += DAQDS__size) { 425 u32 tmp = pcm_count * n; 426 427 writew(PCTODSP_BASED(tmp + 0x3000), pDAQ + DAQDS_wStart); 428 writew(pcm_count, pDAQ + DAQDS_wSize); 429 writew(1, pDAQ + DAQDS_wFormat); 430 writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize); 431 writew(chip->capture_channels, pDAQ + DAQDS_wChannels); 432 writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate); 433 writew(HIMT_RECORD_DONE * 0x100 + n, pDAQ + DAQDS_wIntMsg); 434 writew(n, pDAQ + DAQDS_wFlags); 435 } 436 } 437 438 static struct snd_pcm_hardware snd_msnd_playback = { 439 .info = SNDRV_PCM_INFO_MMAP | 440 SNDRV_PCM_INFO_INTERLEAVED | 441 SNDRV_PCM_INFO_MMAP_VALID | 442 SNDRV_PCM_INFO_BATCH, 443 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, 444 .rates = SNDRV_PCM_RATE_8000_48000, 445 .rate_min = 8000, 446 .rate_max = 48000, 447 .channels_min = 1, 448 .channels_max = 2, 449 .buffer_bytes_max = 0x3000, 450 .period_bytes_min = 0x40, 451 .period_bytes_max = 0x1800, 452 .periods_min = 2, 453 .periods_max = 3, 454 .fifo_size = 0, 455 }; 456 457 static struct snd_pcm_hardware snd_msnd_capture = { 458 .info = SNDRV_PCM_INFO_MMAP | 459 SNDRV_PCM_INFO_INTERLEAVED | 460 SNDRV_PCM_INFO_MMAP_VALID | 461 SNDRV_PCM_INFO_BATCH, 462 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, 463 .rates = SNDRV_PCM_RATE_8000_48000, 464 .rate_min = 8000, 465 .rate_max = 48000, 466 .channels_min = 1, 467 .channels_max = 2, 468 .buffer_bytes_max = 0x3000, 469 .period_bytes_min = 0x40, 470 .period_bytes_max = 0x1800, 471 .periods_min = 2, 472 .periods_max = 3, 473 .fifo_size = 0, 474 }; 475 476 477 static int snd_msnd_playback_open(struct snd_pcm_substream *substream) 478 { 479 struct snd_pcm_runtime *runtime = substream->runtime; 480 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 481 482 set_bit(F_AUDIO_WRITE_INUSE, &chip->flags); 483 clear_bit(F_WRITING, &chip->flags); 484 snd_msnd_enable_irq(chip); 485 486 runtime->dma_area = chip->mappedbase; 487 runtime->dma_bytes = 0x3000; 488 489 chip->playback_substream = substream; 490 runtime->hw = snd_msnd_playback; 491 return 0; 492 } 493 494 static int snd_msnd_playback_close(struct snd_pcm_substream *substream) 495 { 496 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 497 498 snd_msnd_disable_irq(chip); 499 clear_bit(F_AUDIO_WRITE_INUSE, &chip->flags); 500 return 0; 501 } 502 503 504 static int snd_msnd_playback_hw_params(struct snd_pcm_substream *substream, 505 struct snd_pcm_hw_params *params) 506 { 507 int i; 508 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 509 void *pDAQ = chip->mappedbase + DAPQ_DATA_BUFF; 510 511 chip->play_sample_size = snd_pcm_format_width(params_format(params)); 512 chip->play_channels = params_channels(params); 513 chip->play_sample_rate = params_rate(params); 514 515 for (i = 0; i < 3; ++i, pDAQ += DAQDS__size) { 516 writew(chip->play_sample_size, pDAQ + DAQDS_wSampleSize); 517 writew(chip->play_channels, pDAQ + DAQDS_wChannels); 518 writew(chip->play_sample_rate, pDAQ + DAQDS_wSampleRate); 519 } 520 /* dont do this here: 521 * snd_msnd_calibrate_adc(chip->play_sample_rate); 522 */ 523 524 return 0; 525 } 526 527 static int snd_msnd_playback_prepare(struct snd_pcm_substream *substream) 528 { 529 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 530 unsigned int pcm_size = snd_pcm_lib_buffer_bytes(substream); 531 unsigned int pcm_count = snd_pcm_lib_period_bytes(substream); 532 unsigned int pcm_periods = pcm_size / pcm_count; 533 534 snd_msnd_play_reset_queue(chip, pcm_periods, pcm_count); 535 chip->playDMAPos = 0; 536 return 0; 537 } 538 539 static int snd_msnd_playback_trigger(struct snd_pcm_substream *substream, 540 int cmd) 541 { 542 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 543 int result = 0; 544 545 if (cmd == SNDRV_PCM_TRIGGER_START) { 546 snd_printdd("snd_msnd_playback_trigger(START)\n"); 547 chip->banksPlayed = 0; 548 set_bit(F_WRITING, &chip->flags); 549 snd_msnd_DAPQ(chip, 1); 550 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { 551 snd_printdd("snd_msnd_playback_trigger(STop)\n"); 552 /* interrupt diagnostic, comment this out later */ 553 clear_bit(F_WRITING, &chip->flags); 554 snd_msnd_send_dsp_cmd(chip, HDEX_PLAY_STOP); 555 } else { 556 snd_printd(KERN_ERR "snd_msnd_playback_trigger(?????)\n"); 557 result = -EINVAL; 558 } 559 560 snd_printdd("snd_msnd_playback_trigger() ENDE\n"); 561 return result; 562 } 563 564 static snd_pcm_uframes_t 565 snd_msnd_playback_pointer(struct snd_pcm_substream *substream) 566 { 567 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 568 569 return bytes_to_frames(substream->runtime, chip->playDMAPos); 570 } 571 572 573 static struct snd_pcm_ops snd_msnd_playback_ops = { 574 .open = snd_msnd_playback_open, 575 .close = snd_msnd_playback_close, 576 .ioctl = snd_pcm_lib_ioctl, 577 .hw_params = snd_msnd_playback_hw_params, 578 .prepare = snd_msnd_playback_prepare, 579 .trigger = snd_msnd_playback_trigger, 580 .pointer = snd_msnd_playback_pointer, 581 }; 582 583 static int snd_msnd_capture_open(struct snd_pcm_substream *substream) 584 { 585 struct snd_pcm_runtime *runtime = substream->runtime; 586 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 587 588 set_bit(F_AUDIO_READ_INUSE, &chip->flags); 589 snd_msnd_enable_irq(chip); 590 runtime->dma_area = chip->mappedbase + 0x3000; 591 runtime->dma_bytes = 0x3000; 592 memset(runtime->dma_area, 0, runtime->dma_bytes); 593 chip->capture_substream = substream; 594 runtime->hw = snd_msnd_capture; 595 return 0; 596 } 597 598 static int snd_msnd_capture_close(struct snd_pcm_substream *substream) 599 { 600 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 601 602 snd_msnd_disable_irq(chip); 603 clear_bit(F_AUDIO_READ_INUSE, &chip->flags); 604 return 0; 605 } 606 607 static int snd_msnd_capture_prepare(struct snd_pcm_substream *substream) 608 { 609 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 610 unsigned int pcm_size = snd_pcm_lib_buffer_bytes(substream); 611 unsigned int pcm_count = snd_pcm_lib_period_bytes(substream); 612 unsigned int pcm_periods = pcm_size / pcm_count; 613 614 snd_msnd_capture_reset_queue(chip, pcm_periods, pcm_count); 615 chip->captureDMAPos = 0; 616 return 0; 617 } 618 619 static int snd_msnd_capture_trigger(struct snd_pcm_substream *substream, 620 int cmd) 621 { 622 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 623 624 if (cmd == SNDRV_PCM_TRIGGER_START) { 625 chip->last_recbank = -1; 626 set_bit(F_READING, &chip->flags); 627 if (snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_START) == 0) 628 return 0; 629 630 clear_bit(F_READING, &chip->flags); 631 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { 632 clear_bit(F_READING, &chip->flags); 633 snd_msnd_send_dsp_cmd(chip, HDEX_RECORD_STOP); 634 return 0; 635 } 636 return -EINVAL; 637 } 638 639 640 static snd_pcm_uframes_t 641 snd_msnd_capture_pointer(struct snd_pcm_substream *substream) 642 { 643 struct snd_pcm_runtime *runtime = substream->runtime; 644 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 645 646 return bytes_to_frames(runtime, chip->captureDMAPos); 647 } 648 649 650 static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream, 651 struct snd_pcm_hw_params *params) 652 { 653 int i; 654 struct snd_msnd *chip = snd_pcm_substream_chip(substream); 655 void *pDAQ = chip->mappedbase + DARQ_DATA_BUFF; 656 657 chip->capture_sample_size = snd_pcm_format_width(params_format(params)); 658 chip->capture_channels = params_channels(params); 659 chip->capture_sample_rate = params_rate(params); 660 661 for (i = 0; i < 3; ++i, pDAQ += DAQDS__size) { 662 writew(chip->capture_sample_size, pDAQ + DAQDS_wSampleSize); 663 writew(chip->capture_channels, pDAQ + DAQDS_wChannels); 664 writew(chip->capture_sample_rate, pDAQ + DAQDS_wSampleRate); 665 } 666 return 0; 667 } 668 669 670 static struct snd_pcm_ops snd_msnd_capture_ops = { 671 .open = snd_msnd_capture_open, 672 .close = snd_msnd_capture_close, 673 .ioctl = snd_pcm_lib_ioctl, 674 .hw_params = snd_msnd_capture_hw_params, 675 .prepare = snd_msnd_capture_prepare, 676 .trigger = snd_msnd_capture_trigger, 677 .pointer = snd_msnd_capture_pointer, 678 }; 679 680 681 int snd_msnd_pcm(struct snd_card *card, int device, 682 struct snd_pcm **rpcm) 683 { 684 struct snd_msnd *chip = card->private_data; 685 struct snd_pcm *pcm; 686 int err; 687 688 err = snd_pcm_new(card, "MSNDPINNACLE", device, 1, 1, &pcm); 689 if (err < 0) 690 return err; 691 692 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_msnd_playback_ops); 693 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_msnd_capture_ops); 694 695 pcm->private_data = chip; 696 strcpy(pcm->name, "Hurricane"); 697 698 699 if (rpcm) 700 *rpcm = pcm; 701 return 0; 702 } 703 EXPORT_SYMBOL(snd_msnd_pcm); 704 705 MODULE_DESCRIPTION("Common routines for Turtle Beach Multisound drivers"); 706 MODULE_LICENSE("GPL"); 707 708