Lines Matching +full:has +full:- +full:chip +full:- +full:id
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 */
38 static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ variable
42 module_param(id, charp, 0444);
43 MODULE_PARM_DESC(id, "ID string for SGI O2 soundcard.");
66 #define CHANNEL_RING_MASK (CHANNEL_RING_SIZE - 1)
79 /* definition of the chip-specific record */
100 * Returns unsigned register value on success, -errno on failure.
104 struct snd_sgio2audio *chip = priv; in read_ad1843_reg() local
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()
127 struct snd_sgio2audio *chip = priv; in write_ad1843_reg() local
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()
147 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); in sgio2audio_gain_info() local
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()
160 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); in sgio2audio_gain_get() local
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()
174 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); in sgio2audio_gain_put() local
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()
199 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); in sgio2audio_source_get() local
201 ucontrol->value.enumerated.item[0] = ad1843_get_recsrc(&chip->ad1843); in sgio2audio_source_get()
208 struct snd_sgio2audio *chip = snd_kcontrol_chip(kcontrol); in sgio2audio_source_put() local
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()
299 static int snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip) in snd_sgio2audio_new_mixer() argument
303 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
304 snd_ctl_new1(&sgio2audio_ctrl_pcm0, chip)); in snd_sgio2audio_new_mixer()
308 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
309 snd_ctl_new1(&sgio2audio_ctrl_pcm1, chip)); in snd_sgio2audio_new_mixer()
313 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
314 snd_ctl_new1(&sgio2audio_ctrl_reclevel, chip)); in snd_sgio2audio_new_mixer()
318 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
319 snd_ctl_new1(&sgio2audio_ctrl_recsource, chip)); in snd_sgio2audio_new_mixer()
322 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
323 snd_ctl_new1(&sgio2audio_ctrl_line, chip)); in snd_sgio2audio_new_mixer()
327 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
328 snd_ctl_new1(&sgio2audio_ctrl_cd, chip)); in snd_sgio2audio_new_mixer()
332 err = snd_ctl_add(chip->card, in snd_sgio2audio_new_mixer()
333 snd_ctl_new1(&sgio2audio_ctrl_mic, chip)); in snd_sgio2audio_new_mixer()
340 /* low-level audio interface DMA */
343 /* returns 1 if a period has elapsed */
344 static int snd_sgio2audio_dma_pull_frag(struct snd_sgio2audio *chip, in snd_sgio2audio_dma_pull_frag() argument
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()
365 /* check if a period has elapsed */ 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()
391 /* returns 1 if a period has elapsed */
392 static int snd_sgio2audio_dma_push_frag(struct snd_sgio2audio *chip, in snd_sgio2audio_dma_push_frag() argument
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()
413 /* check if a period has elapsed */ 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()
442 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); in snd_sgio2audio_dma_start() local
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()
473 struct snd_sgio2audio *chip; in snd_sgio2audio_dma_in_isr() local
476 substream = chan->substream; in snd_sgio2audio_dma_in_isr()
477 chip = snd_pcm_substream_chip(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()
483 if (snd_sgio2audio_dma_pull_frag(chip, ch, count)) in snd_sgio2audio_dma_in_isr()
493 struct snd_sgio2audio *chip; in snd_sgio2audio_dma_out_isr() local
496 substream = chan->substream; in snd_sgio2audio_dma_out_isr()
497 chip = snd_pcm_substream_chip(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()
502 if (snd_sgio2audio_dma_push_frag(chip, ch, count)) in snd_sgio2audio_dma_out_isr()
513 substream = chan->substream; in snd_sgio2audio_error_isr()
542 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); in snd_sgio2audio_playback1_open() local
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()
552 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); in snd_sgio2audio_playback2_open() local
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()
563 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); in snd_sgio2audio_capture_open() local
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()
583 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); in snd_sgio2audio_pcm_prepare() local
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()
640 struct snd_sgio2audio *chip = snd_pcm_substream_chip(substream); in snd_sgio2audio_pcm_pointer() local
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()
678 static int snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip) in snd_sgio2audio_new_pcm() argument
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()
755 static int snd_sgio2audio_free(struct snd_sgio2audio *chip) in snd_sgio2audio_free() argument
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()
773 kfree(chip); in snd_sgio2audio_free()
779 struct snd_sgio2audio *chip = device->device_data; in snd_sgio2audio_dev_free() local
781 return snd_sgio2audio_free(chip); in snd_sgio2audio_dev_free()
791 struct snd_sgio2audio *chip; in snd_sgio2audio_create() local
798 if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) in snd_sgio2audio_create()
799 return -ENOENT; in snd_sgio2audio_create()
801 chip = kzalloc(sizeof(*chip), GFP_KERNEL); in snd_sgio2audio_create()
802 if (chip == NULL) 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()
813 kfree(chip); 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()
832 snd_sgio2audio_free(chip); 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()
856 snd_sgio2audio_free(chip); in snd_sgio2audio_create()
860 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); in snd_sgio2audio_create()
862 snd_sgio2audio_free(chip); in snd_sgio2audio_create()
865 *rchip = chip; in snd_sgio2audio_create()
872 struct snd_sgio2audio *chip; in snd_sgio2audio_probe() local
875 err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card); in snd_sgio2audio_probe()
879 err = snd_sgio2audio_create(card, &chip); in snd_sgio2audio_probe()
885 err = snd_sgio2audio_new_pcm(chip); in snd_sgio2audio_probe()
890 err = snd_sgio2audio_new_mixer(chip); 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()