Lines Matching +full:mic +full:- +full:pos
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright 2003 Vivien Chappelier <vivien.chappelier@linux-mips.org>
15 #include <linux/dma-mapping.h>
32 MODULE_AUTHOR("Vivien Chappelier <vivien.chappelier@linux-mips.org>");
37 static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
66 #define CHANNEL_RING_MASK (CHANNEL_RING_SIZE - 1)
74 int pos; member
79 /* definition of the chip-specific record */
100 * Returns unsigned register value on success, -errno on failure.
108 spin_lock_irqsave(&chip->ad1843_lock, flags); in read_ad1843_reg()
111 CODEC_CONTROL_READ, &mace->perif.audio.codec_control); in read_ad1843_reg()
113 val = readq(&mace->perif.audio.codec_control); /* flush bus */ in read_ad1843_reg()
116 val = readq(&mace->perif.audio.codec_read); in read_ad1843_reg()
118 spin_unlock_irqrestore(&chip->ad1843_lock, flags); in read_ad1843_reg()
131 spin_lock_irqsave(&chip->ad1843_lock, flags); in write_ad1843_reg()
135 &mace->perif.audio.codec_control); in write_ad1843_reg()
137 val = readq(&mace->perif.audio.codec_control); /* flush bus */ in write_ad1843_reg()
140 spin_unlock_irqrestore(&chip->ad1843_lock, flags); in write_ad1843_reg()
149 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in sgio2audio_gain_info()
150 uinfo->count = 2; in sgio2audio_gain_info()
151 uinfo->value.integer.min = 0; in sgio2audio_gain_info()
152 uinfo->value.integer.max = ad1843_get_gain_max(&chip->ad1843, in sgio2audio_gain_info()
153 (int)kcontrol->private_value); in sgio2audio_gain_info()
163 vol = ad1843_get_gain(&chip->ad1843, (int)kcontrol->private_value); in sgio2audio_gain_get()
165 ucontrol->value.integer.value[0] = (vol >> 8) & 0xFF; in sgio2audio_gain_get()
166 ucontrol->value.integer.value[1] = vol & 0xFF; in sgio2audio_gain_get()
177 oldvol = ad1843_get_gain(&chip->ad1843, kcontrol->private_value); in sgio2audio_gain_put()
178 newvol = (ucontrol->value.integer.value[0] << 8) | in sgio2audio_gain_put()
179 ucontrol->value.integer.value[1]; in sgio2audio_gain_put()
181 newvol = ad1843_set_gain(&chip->ad1843, kcontrol->private_value, in sgio2audio_gain_put()
191 "Cam Mic", "Mic", "Line" in sgio2audio_source_info()
201 ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843); in sgio2audio_source_get()
211 oldsrc = ad1843_get_recsrc(&chip->ad1843); in sgio2audio_source_put()
212 newsrc = ad1843_set_recsrc(&chip->ad1843, in sgio2audio_source_put()
213 ucontrol->value.enumerated.item[0]); in sgio2audio_source_put()
287 /* mic mixer control */
290 .name = "Mic Playback Volume",
303 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
308 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
313 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
318 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
322 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
327 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
332 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
340 /* low-level audio interface DMA */
355 struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime; in snd_sgio2audio_dma_pull_frag()
357 spin_lock_irqsave(&chip->channel[ch].lock, flags); in snd_sgio2audio_dma_pull_frag()
359 src_base = (unsigned long) chip->ring_base | (ch << CHANNEL_RING_SHIFT); in snd_sgio2audio_dma_pull_frag()
360 src_pos = readq(&mace->perif.audio.chan[ch].read_ptr); in snd_sgio2audio_dma_pull_frag()
361 dst_base = runtime->dma_area; in snd_sgio2audio_dma_pull_frag()
362 dst_pos = chip->channel[ch].pos; in snd_sgio2audio_dma_pull_frag()
363 dst_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1; in snd_sgio2audio_dma_pull_frag()
366 chip->channel[ch].size += (count >> 3); /* in frames */ in snd_sgio2audio_dma_pull_frag()
367 ret = chip->channel[ch].size >= runtime->period_size; in snd_sgio2audio_dma_pull_frag()
368 chip->channel[ch].size %= runtime->period_size; in snd_sgio2audio_dma_pull_frag()
380 count -= sizeof(u64); in snd_sgio2audio_dma_pull_frag()
383 writeq(src_pos, &mace->perif.audio.chan[ch].read_ptr); /* in bytes */ in snd_sgio2audio_dma_pull_frag()
384 chip->channel[ch].pos = dst_pos; in snd_sgio2audio_dma_pull_frag()
386 spin_unlock_irqrestore(&chip->channel[ch].lock, flags); in snd_sgio2audio_dma_pull_frag()
403 struct snd_pcm_runtime *runtime = chip->channel[ch].substream->runtime; in snd_sgio2audio_dma_push_frag()
405 spin_lock_irqsave(&chip->channel[ch].lock, flags); in snd_sgio2audio_dma_push_frag()
407 dst_base = (unsigned long)chip->ring_base | (ch << CHANNEL_RING_SHIFT); in snd_sgio2audio_dma_push_frag()
408 dst_pos = readq(&mace->perif.audio.chan[ch].write_ptr); in snd_sgio2audio_dma_push_frag()
409 src_base = runtime->dma_area; in snd_sgio2audio_dma_push_frag()
410 src_pos = chip->channel[ch].pos; in snd_sgio2audio_dma_push_frag()
411 src_mask = frames_to_bytes(runtime, runtime->buffer_size) - 1; in snd_sgio2audio_dma_push_frag()
414 chip->channel[ch].size += (count >> 3); /* in frames */ in snd_sgio2audio_dma_push_frag()
415 ret = chip->channel[ch].size >= runtime->period_size; in snd_sgio2audio_dma_push_frag()
416 chip->channel[ch].size %= runtime->period_size; in snd_sgio2audio_dma_push_frag()
430 count -= sizeof(u64); in snd_sgio2audio_dma_push_frag()
433 writeq(dst_pos, &mace->perif.audio.chan[ch].write_ptr); /* in bytes */ in snd_sgio2audio_dma_push_frag()
434 chip->channel[ch].pos = src_pos; in snd_sgio2audio_dma_push_frag()
436 spin_unlock_irqrestore(&chip->channel[ch].lock, flags); in snd_sgio2audio_dma_push_frag()
443 struct snd_sgio2audio_chan *chan = substream->runtime->private_data; in snd_sgio2audio_dma_start()
444 int ch = chan->idx; in snd_sgio2audio_dma_start()
447 writeq(CHANNEL_CONTROL_RESET, &mace->perif.audio.chan[ch].control); in snd_sgio2audio_dma_start()
449 writeq(0, &mace->perif.audio.chan[ch].control); in snd_sgio2audio_dma_start()
451 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in snd_sgio2audio_dma_start()
453 snd_sgio2audio_dma_push_frag(chip, ch, CHANNEL_RING_SIZE - 32); in snd_sgio2audio_dma_start()
457 &mace->perif.audio.chan[ch].control); in snd_sgio2audio_dma_start()
463 struct snd_sgio2audio_chan *chan = substream->runtime->private_data; in snd_sgio2audio_dma_stop()
465 writeq(0, &mace->perif.audio.chan[chan->idx].control); in snd_sgio2audio_dma_stop()
476 substream = chan->substream; in snd_sgio2audio_dma_in_isr()
478 ch = chan->idx; in snd_sgio2audio_dma_in_isr()
481 count = CHANNEL_RING_SIZE - in snd_sgio2audio_dma_in_isr()
482 readq(&mace->perif.audio.chan[ch].depth) - 32; in snd_sgio2audio_dma_in_isr()
496 substream = chan->substream; in snd_sgio2audio_dma_out_isr()
498 ch = chan->idx; in snd_sgio2audio_dma_out_isr()
500 count = CHANNEL_RING_SIZE - in snd_sgio2audio_dma_out_isr()
501 readq(&mace->perif.audio.chan[ch].depth) - 32; in snd_sgio2audio_dma_out_isr()
513 substream = chan->substream; in snd_sgio2audio_error_isr()
543 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sgio2audio_playback1_open()
545 runtime->hw = snd_sgio2audio_pcm_hw; in snd_sgio2audio_playback1_open()
546 runtime->private_data = &chip->channel[1]; in snd_sgio2audio_playback1_open()
553 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sgio2audio_playback2_open()
555 runtime->hw = snd_sgio2audio_pcm_hw; in snd_sgio2audio_playback2_open()
556 runtime->private_data = &chip->channel[2]; in snd_sgio2audio_playback2_open()
564 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sgio2audio_capture_open()
566 runtime->hw = snd_sgio2audio_pcm_hw; in snd_sgio2audio_capture_open()
567 runtime->private_data = &chip->channel[0]; in snd_sgio2audio_capture_open()
574 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sgio2audio_pcm_close()
576 runtime->private_data = NULL; in snd_sgio2audio_pcm_close()
584 struct snd_pcm_runtime *runtime = substream->runtime; in snd_sgio2audio_pcm_prepare()
585 struct snd_sgio2audio_chan *chan = substream->runtime->private_data; in snd_sgio2audio_pcm_prepare()
586 int ch = chan->idx; in snd_sgio2audio_pcm_prepare()
589 spin_lock_irqsave(&chip->channel[ch].lock, flags); in snd_sgio2audio_pcm_prepare()
591 /* Setup the pseudo-dma transfer pointers. */ in snd_sgio2audio_pcm_prepare()
592 chip->channel[ch].pos = 0; in snd_sgio2audio_pcm_prepare()
593 chip->channel[ch].size = 0; in snd_sgio2audio_pcm_prepare()
594 chip->channel[ch].substream = substream; in snd_sgio2audio_pcm_prepare()
598 switch (substream->stream) { in snd_sgio2audio_pcm_prepare()
600 ad1843_setup_dac(&chip->ad1843, in snd_sgio2audio_pcm_prepare()
601 ch - 1, in snd_sgio2audio_pcm_prepare()
602 runtime->rate, in snd_sgio2audio_pcm_prepare()
604 runtime->channels); in snd_sgio2audio_pcm_prepare()
607 ad1843_setup_adc(&chip->ad1843, in snd_sgio2audio_pcm_prepare()
608 runtime->rate, in snd_sgio2audio_pcm_prepare()
610 runtime->channels); in snd_sgio2audio_pcm_prepare()
613 spin_unlock_irqrestore(&chip->channel[ch].lock, flags); in snd_sgio2audio_pcm_prepare()
631 return -EINVAL; in snd_sgio2audio_pcm_trigger()
641 struct snd_sgio2audio_chan *chan = substream->runtime->private_data; in snd_sgio2audio_pcm_pointer()
644 return bytes_to_frames(substream->runtime, in snd_sgio2audio_pcm_pointer()
645 chip->channel[chan->idx].pos); in snd_sgio2audio_pcm_pointer()
684 err = snd_pcm_new(chip->card, "SGI O2 Audio", 0, 1, 1, &pcm); in snd_sgio2audio_new_pcm()
688 pcm->private_data = chip; in snd_sgio2audio_new_pcm()
689 strcpy(pcm->name, "SGI O2 DAC1"); in snd_sgio2audio_new_pcm()
699 err = snd_pcm_new(chip->card, "SGI O2 Audio", 1, 1, 0, &pcm); in snd_sgio2audio_new_pcm()
703 pcm->private_data = chip; in snd_sgio2audio_new_pcm()
704 strcpy(pcm->name, "SGI O2 DAC2"); in snd_sgio2audio_new_pcm()
760 writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control); in snd_sgio2audio_free()
762 writeq(0, &mace->perif.audio.control); in snd_sgio2audio_free()
767 &chip->channel[snd_sgio2_isr_table[i].idx]); in snd_sgio2audio_free()
769 dma_free_coherent(chip->card->dev, MACEISA_RINGBUFFERS_SIZE, in snd_sgio2audio_free()
770 chip->ring_base, chip->ring_base_dma); in snd_sgio2audio_free()
779 struct snd_sgio2audio *chip = device->device_data; in snd_sgio2audio_dev_free()
798 if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) in snd_sgio2audio_create()
799 return -ENOENT; in snd_sgio2audio_create()
803 return -ENOMEM; in snd_sgio2audio_create()
805 chip->card = card; in snd_sgio2audio_create()
807 chip->ring_base = dma_alloc_coherent(card->dev, in snd_sgio2audio_create()
809 &chip->ring_base_dma, GFP_KERNEL); in snd_sgio2audio_create()
810 if (chip->ring_base == NULL) { in snd_sgio2audio_create()
814 return -ENOMEM; in snd_sgio2audio_create()
817 spin_lock_init(&chip->ad1843_lock); in snd_sgio2audio_create()
821 spin_lock_init(&chip->channel[i].lock); in snd_sgio2audio_create()
822 chip->channel[i].idx = i; in snd_sgio2audio_create()
831 &chip->channel[snd_sgio2_isr_table[i].idx])) { in snd_sgio2audio_create()
835 return -EBUSY; in snd_sgio2audio_create()
840 writeq(AUDIO_CONTROL_RESET, &mace->perif.audio.control); in snd_sgio2audio_create()
842 writeq(0, &mace->perif.audio.control); in snd_sgio2audio_create()
846 writeq(chip->ring_base_dma, &mace->perif.ctrl.ringbase); in snd_sgio2audio_create()
849 chip->ad1843.read = read_ad1843_reg; in snd_sgio2audio_create()
850 chip->ad1843.write = write_ad1843_reg; in snd_sgio2audio_create()
851 chip->ad1843.chip = chip; in snd_sgio2audio_create()
854 err = ad1843_init(&chip->ad1843); in snd_sgio2audio_create()
875 err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card); in snd_sgio2audio_probe()
896 strcpy(card->driver, "SGI O2 Audio"); in snd_sgio2audio_probe()
897 strcpy(card->shortname, "SGI O2 Audio"); in snd_sgio2audio_probe()
898 sprintf(card->longname, "%s irq %i-%i", in snd_sgio2audio_probe()
899 card->shortname, in snd_sgio2audio_probe()