Lines Matching +full:8 +full:- +full:channel

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
8 * Output fixed at S32_LE, 2 channel to hw:0,0
15 * Use 2 channel output streams instead of 8 channel.
16 * (8 channel output streams might be good for ASIO type output)
17 * Corrected speaker output, so Front -> Front etc.
36 * Merging with snd-emu10k1 driver.
38 * One stereo channel at 24bit now works.
42 * Integrated with snd-emu10k1 driver.
50 * setting HD Capture channel to 0 captures from CDROM digital input.
51 * setting HD Capture channel to 1 captures from SPDIF in.
56 * Some stability problems when unloading the snd-p16v kernel module.
57 * --
64 * --
67 * P16V Chip: CA0151-DBS
68 * Audigy 2 Chip: CA0102-IAT
71 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
92 #define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
103 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
104 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1 Model:SB0240
105 …* Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum Model:SB msb02402300092…
106 …* Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB038047200190…
118 .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
122 .channels_min = 8,
123 .channels_max = 8,
124 .buffer_bytes_max = ((65536 - 64) * 8),
126 .period_bytes_max = (65536 - 64),
128 .periods_max = 8,
144 .buffer_bytes_max = (65536 - 64),
146 .period_bytes_max = (65536 - 128) >> 1, /* size has to be N*64 bytes */
155 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_pcm_open_playback_channel()
159 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n", in snd_p16v_pcm_open_playback_channel()
160 substream->pcm->device, channel_id); in snd_p16v_pcm_open_playback_channel()
163 runtime->hw = snd_p16v_playback_hw; in snd_p16v_pcm_open_playback_channel()
166 dev_dbg(emu->card->dev, in snd_p16v_pcm_open_playback_channel()
167 "p16v: open channel_id=%d, channel=%p, use=0x%x\n", in snd_p16v_pcm_open_playback_channel()
168 channel_id, channel, channel->use); in snd_p16v_pcm_open_playback_channel()
169 dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n", in snd_p16v_pcm_open_playback_channel()
170 channel_id, chip, channel); in snd_p16v_pcm_open_playback_channel()
172 /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */ in snd_p16v_pcm_open_playback_channel()
177 runtime->sync.id32[0] = substream->pcm->card->number; in snd_p16v_pcm_open_playback_channel()
178 runtime->sync.id32[1] = 'P'; in snd_p16v_pcm_open_playback_channel()
179 runtime->sync.id32[2] = 16; in snd_p16v_pcm_open_playback_channel()
180 runtime->sync.id32[3] = 'V'; in snd_p16v_pcm_open_playback_channel()
188 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_pcm_open_capture_channel()
192 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n", in snd_p16v_pcm_open_capture_channel()
193 substream->pcm->device, channel_id); in snd_p16v_pcm_open_capture_channel()
196 runtime->hw = snd_p16v_capture_hw; in snd_p16v_pcm_open_capture_channel()
225 // Only using channel 0 for now, but the card has 2 channels. in snd_p16v_pcm_open_capture()
233 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_pcm_prepare_playback()
234 int channel = substream->pcm->device - emu->p16v_device_offset; in snd_p16v_pcm_prepare_playback() local
235 u32 *table_base = (u32 *)(emu->p16v_buffer->area+(8*16*channel)); in snd_p16v_pcm_prepare_playback()
236 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); in snd_p16v_pcm_prepare_playback()
241 dev_dbg(emu->card->dev, in snd_p16v_pcm_prepare_playback()
245 channel, runtime->rate, runtime->format, runtime->channels, in snd_p16v_pcm_prepare_playback()
246 runtime->buffer_size, runtime->period_size, in snd_p16v_pcm_prepare_playback()
247 runtime->periods, frames_to_bytes(runtime, 1)); in snd_p16v_pcm_prepare_playback()
248 dev_dbg(emu->card->dev, in snd_p16v_pcm_prepare_playback()
250 runtime->dma_addr, runtime->dma_area, table_base); in snd_p16v_pcm_prepare_playback()
251 dev_dbg(emu->card->dev, in snd_p16v_pcm_prepare_playback()
253 emu->p16v_buffer->addr, emu->p16v_buffer->area, in snd_p16v_pcm_prepare_playback()
254 emu->p16v_buffer->bytes); in snd_p16v_pcm_prepare_playback()
256 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); in snd_p16v_pcm_prepare_playback()
258 switch (runtime->rate) { in snd_p16v_pcm_prepare_playback()
260 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, in snd_p16v_pcm_prepare_playback()
264 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, in snd_p16v_pcm_prepare_playback()
268 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, in snd_p16v_pcm_prepare_playback()
273 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, in snd_p16v_pcm_prepare_playback()
277 /* FIXME: Check emu->buffer.size before actually writing to it. */ in snd_p16v_pcm_prepare_playback()
278 for(i = 0; i < runtime->periods; i++) { in snd_p16v_pcm_prepare_playback()
279 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); in snd_p16v_pcm_prepare_playback()
283 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer->addr+(8*16*channel)); in snd_p16v_pcm_prepare_playback()
284 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19); in snd_p16v_pcm_prepare_playback()
285 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0); in snd_p16v_pcm_prepare_playback()
286 snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr); in snd_p16v_pcm_prepare_playback()
287 …//snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->pe… in snd_p16v_pcm_prepare_playback()
288 snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes in snd_p16v_pcm_prepare_playback()
289 snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0); in snd_p16v_pcm_prepare_playback()
290 snd_emu10k1_ptr20_write(emu, PLAYBACK_FIFO_END_ADDRESS, channel, 0); in snd_p16v_pcm_prepare_playback()
291 snd_emu10k1_ptr20_write(emu, PLAYBACK_FIFO_POINTER, channel, 0); in snd_p16v_pcm_prepare_playback()
300 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_pcm_prepare_capture()
301 int channel = substream->pcm->device - emu->p16v_device_offset; in snd_p16v_pcm_prepare_capture() local
304 dev_dbg(emu->card->dev, "prepare capture:channel_number=%d, rate=%d, " in snd_p16v_pcm_prepare_capture()
307 channel, runtime->rate, runtime->format, runtime->channels, in snd_p16v_pcm_prepare_capture()
308 runtime->buffer_size, runtime->period_size, in snd_p16v_pcm_prepare_capture()
311 switch (runtime->rate) { in snd_p16v_pcm_prepare_capture()
313 snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_44100); in snd_p16v_pcm_prepare_capture()
316 snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_96000); in snd_p16v_pcm_prepare_capture()
319 snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_192000); in snd_p16v_pcm_prepare_capture()
323 snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, channel, A_I2S_CAPTURE_48000); in snd_p16v_pcm_prepare_capture()
326 /* FIXME: Check emu->buffer.size before actually writing to it. */ in snd_p16v_pcm_prepare_capture()
327 snd_emu10k1_ptr20_write(emu, CAPTURE_FIFO_POINTER, channel, 0); in snd_p16v_pcm_prepare_capture()
328 snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); in snd_p16v_pcm_prepare_capture()
329 …snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffe… in snd_p16v_pcm_prepare_capture()
330 snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); in snd_p16v_pcm_prepare_capture()
332 …mu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel)); in snd_p16v_pcm_prepare_capture()
342 spin_lock_irqsave(&emu->emu_lock, flags); in snd_p16v_intr_enable()
343 enable = inl(emu->port + INTE2) | intrenb; in snd_p16v_intr_enable()
344 outl(enable, emu->port + INTE2); in snd_p16v_intr_enable()
345 spin_unlock_irqrestore(&emu->emu_lock, flags); in snd_p16v_intr_enable()
353 spin_lock_irqsave(&emu->emu_lock, flags); in snd_p16v_intr_disable()
354 disable = inl(emu->port + INTE2) & (~intrenb); in snd_p16v_intr_disable()
355 outl(disable, emu->port + INTE2); in snd_p16v_intr_disable()
356 spin_unlock_irqrestore(&emu->emu_lock, flags); in snd_p16v_intr_disable()
363 while ((status = inl(emu->port + IPR2)) != 0) { in snd_p16v_interrupt()
366 /* dev_dbg(emu->card->dev, "p16v status=0x%x\n", status); */ in snd_p16v_interrupt()
369 emu->pcm_p16v->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; in snd_p16v_interrupt()
370 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_interrupt()
372 if (runtime && runtime->private_data) { in snd_p16v_interrupt()
375 dev_err(emu->card->dev, in snd_p16v_interrupt()
382 emu->pcm_p16v->streams[SNDRV_PCM_STREAM_CAPTURE].substream; in snd_p16v_interrupt()
383 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_interrupt()
385 /* dev_info(emu->card->dev, "capture int found\n"); */ in snd_p16v_interrupt()
386 if (runtime && runtime->private_data) { in snd_p16v_interrupt()
387 /* dev_info(emu->card->dev, "capture period_elapsed\n"); */ in snd_p16v_interrupt()
391 outl(status, emu->port + IPR2); /* ack all */ in snd_p16v_interrupt()
401 int channel; in snd_p16v_pcm_trigger_playback() local
419 s->stream != SNDRV_PCM_STREAM_PLAYBACK) in snd_p16v_pcm_trigger_playback()
421 runtime = s->runtime; in snd_p16v_pcm_trigger_playback()
422 channel = substream->pcm->device-emu->p16v_device_offset; in snd_p16v_pcm_trigger_playback()
423 /* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */ in snd_p16v_pcm_trigger_playback()
424 runtime->private_data = (void *)(ptrdiff_t)running; in snd_p16v_pcm_trigger_playback()
425 basic |= (0x1<<channel); in snd_p16v_pcm_trigger_playback()
426 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel); in snd_p16v_pcm_trigger_playback()
429 /* dev_dbg(emu->card->dev, "basic=0x%x, inte=0x%x\n", basic, inte); */ in snd_p16v_pcm_trigger_playback()
441 result = -EINVAL; in snd_p16v_pcm_trigger_playback()
452 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_pcm_trigger_capture()
453 int channel = 0; in snd_p16v_pcm_trigger_capture() local
460 …0_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel)); in snd_p16v_pcm_trigger_capture()
461 runtime->private_data = (void *)1; in snd_p16v_pcm_trigger_capture()
464 …rite(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel)); in snd_p16v_pcm_trigger_capture()
466 …u, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel)); in snd_p16v_pcm_trigger_capture()
467 runtime->private_data = NULL; in snd_p16v_pcm_trigger_capture()
470 result = -EINVAL; in snd_p16v_pcm_trigger_capture()
481 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_pcm_pointer_playback()
483 int channel = substream->pcm->device - emu->p16v_device_offset; in snd_p16v_pcm_pointer_playback() local
485 if (!runtime->private_data) in snd_p16v_pcm_pointer_playback()
488 ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel); in snd_p16v_pcm_pointer_playback()
489 ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel); in snd_p16v_pcm_pointer_playback()
490 ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel); in snd_p16v_pcm_pointer_playback()
491 if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel); in snd_p16v_pcm_pointer_playback()
493 ptr2+= (ptr4 >> 3) * runtime->period_size; in snd_p16v_pcm_pointer_playback()
495 if (ptr >= runtime->buffer_size) in snd_p16v_pcm_pointer_playback()
496 ptr -= runtime->buffer_size; in snd_p16v_pcm_pointer_playback()
506 struct snd_pcm_runtime *runtime = substream->runtime; in snd_p16v_pcm_pointer_capture()
508 int channel = 0; in snd_p16v_pcm_pointer_capture() local
510 if (!runtime->private_data) in snd_p16v_pcm_pointer_capture()
513 ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel); in snd_p16v_pcm_pointer_capture()
516 if (ptr >= runtime->buffer_size) { in snd_p16v_pcm_pointer_capture()
517 ptr -= runtime->buffer_size; in snd_p16v_pcm_pointer_capture()
518 dev_warn(emu->card->dev, "buffer capture limited!\n"); in snd_p16v_pcm_pointer_capture()
521 dev_dbg(emu->card->dev, "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " in snd_p16v_pcm_pointer_capture()
523 ptr1, ptr2, ptr, (int)runtime->buffer_size, in snd_p16v_pcm_pointer_capture()
524 (int)runtime->period_size, (int)runtime->frame_bits, in snd_p16v_pcm_pointer_capture()
525 (int)runtime->rate); in snd_p16v_pcm_pointer_capture()
554 /* dev_dbg(emu->card->dev, "snd_p16v_pcm called. device=%d\n", device); */ in snd_p16v_pcm()
555 emu->p16v_device_offset = device; in snd_p16v_pcm()
557 err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm); in snd_p16v_pcm()
561 pcm->private_data = emu; in snd_p16v_pcm()
562 // Single playback 8 channel device. in snd_p16v_pcm()
563 // Single capture 2 channel device. in snd_p16v_pcm()
567 pcm->info_flags = 0; in snd_p16v_pcm()
568 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; in snd_p16v_pcm()
569 strcpy(pcm->name, "p16v"); in snd_p16v_pcm()
570 emu->pcm_p16v = pcm; in snd_p16v_pcm()
571 emu->p16v_interrupt = snd_p16v_interrupt; in snd_p16v_pcm()
573 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; in snd_p16v_pcm()
575 substream = substream->next) { in snd_p16v_pcm()
577 &emu->pci->dev, in snd_p16v_pcm()
578 (65536 - 64) * 8, in snd_p16v_pcm()
579 (65536 - 64) * 8); in snd_p16v_pcm()
581 dev_dbg(emu->card->dev, in snd_p16v_pcm()
586 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; in snd_p16v_pcm()
588 substream = substream->next) { in snd_p16v_pcm()
590 &emu->pci->dev, in snd_p16v_pcm()
591 65536 - 64, 65536 - 64); in snd_p16v_pcm()
593 dev_dbg(emu->card->dev, in snd_p16v_pcm()
604 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_p16v_volume_info()
605 uinfo->count = 2; in snd_p16v_volume_info()
606 uinfo->value.integer.min = 0; in snd_p16v_volume_info()
607 uinfo->value.integer.max = 255; in snd_p16v_volume_info()
615 int high_low = (kcontrol->private_value >> 8) & 0xff; in snd_p16v_volume_get()
616 int reg = kcontrol->private_value & 0xff; in snd_p16v_volume_get()
621 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */ in snd_p16v_volume_get()
622 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */ in snd_p16v_volume_get()
624 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */ in snd_p16v_volume_get()
625 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */ in snd_p16v_volume_get()
634 int high_low = (kcontrol->private_value >> 8) & 0xff; in snd_p16v_volume_put()
635 int reg = kcontrol->private_value & 0xff; in snd_p16v_volume_put()
641 value |= ((0xff - ucontrol->value.integer.value[0]) << 24) | in snd_p16v_volume_put()
642 ((0xff - ucontrol->value.integer.value[1]) << 16); in snd_p16v_volume_put()
645 value |= ((0xff - ucontrol->value.integer.value[0]) << 8) | in snd_p16v_volume_put()
646 ((0xff - ucontrol->value.integer.value[1]) ); in snd_p16v_volume_put()
658 static const char * const texts[8] = { in snd_p16v_capture_source_info()
663 return snd_ctl_enum_info(uinfo, 1, 8, texts); in snd_p16v_capture_source_info()
671 ucontrol->value.enumerated.item[0] = emu->p16v_capture_source; in snd_p16v_capture_source_get()
684 val = ucontrol->value.enumerated.item[0] ; in snd_p16v_capture_source_put()
686 return -EINVAL; in snd_p16v_capture_source_put()
687 change = (emu->p16v_capture_source != val); in snd_p16v_capture_source_put()
689 emu->p16v_capture_source = val; in snd_p16v_capture_source_put()
710 ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel; in snd_p16v_capture_channel_get()
722 val = ucontrol->value.enumerated.item[0] ; in snd_p16v_capture_channel_put()
724 return -EINVAL; in snd_p16v_capture_channel_put()
725 change = (emu->p16v_capture_channel != val); in snd_p16v_capture_channel_put()
727 emu->p16v_capture_channel = val; in snd_p16v_capture_channel_put()
733 static const DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1);
743 .private_value = ((xreg) | ((xhl) << 8)) \
764 .name = "HD channel Capture",
775 struct snd_card *card = emu->card; in snd_p16v_mixer()
787 #define NUM_CHS 1 /* up to 4, but only first channel is used */
791 emu->p16v_saved = vmalloc(array_size(NUM_CHS * 4, 0x80)); in snd_p16v_alloc_pm_buffer()
792 if (! emu->p16v_saved) in snd_p16v_alloc_pm_buffer()
793 return -ENOMEM; in snd_p16v_alloc_pm_buffer()
799 vfree(emu->p16v_saved); in snd_p16v_free_pm_buffer()
807 val = emu->p16v_saved; in snd_p16v_suspend()
818 val = emu->p16v_saved; in snd_p16v_resume()