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