Lines Matching +full:risc +full:- +full:v

1 // SPDX-License-Identifier: GPL-2.0-or-later
14 #include "cx88-reg.h"
22 #include <linux/dma-mapping.h>
37 chip->core->name, ##arg); \
41 * Data type declarations - Can be moded to a header file later
46 struct cx88_riscmem risc; member
81 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
115 struct cx88_audio_buffer *buf = chip->buf; in _cx88_start_audio_dma()
116 struct cx88_core *core = chip->core; in _cx88_start_audio_dma()
119 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ in _cx88_start_audio_dma()
122 /* setup fifo + format - out channel */ in _cx88_start_audio_dma()
123 cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, buf->risc.dma); in _cx88_start_audio_dma()
126 cx_write(MO_AUDD_LNGTH, buf->bpl); in _cx88_start_audio_dma()
130 atomic_set(&chip->count, 0); in _cx88_start_audio_dma()
134 buf->bpl, cx_read(audio_ch->cmds_start + 8) >> 1, in _cx88_start_audio_dma()
135 chip->num_periods, buf->bpl * chip->num_periods); in _cx88_start_audio_dma()
145 cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT); in _cx88_start_audio_dma()
149 /* Enables Risc Processor */ in _cx88_start_audio_dma()
151 /* audio downstream FIFO and RISC enable */ in _cx88_start_audio_dma()
155 cx88_sram_channel_dump(chip->core, audio_ch); in _cx88_start_audio_dma()
165 struct cx88_core *core = chip->core; in _cx88_stop_audio_dma()
178 cx88_sram_channel_dump(chip->core, in _cx88_stop_audio_dma()
190 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
192 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
194 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
196 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
198 "opc_err", "par_err", "rip_err", /* 16-18 */
199 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
207 struct cx88_core *core = chip->core; in cx8801_aud_irq()
219 /* risc op code error */ in cx8801_aud_irq()
221 pr_warn("Audio risc op code error\n"); in cx8801_aud_irq()
232 atomic_set(&chip->count, cx_read(MO_AUDD_GPCNT)); in cx8801_aud_irq()
233 snd_pcm_period_elapsed(chip->substream); in cx8801_aud_irq()
244 struct cx88_core *core = chip->core; in cx8801_irq()
250 (core->pci_irqmask | PCI_INT_AUDINT); in cx8801_irq()
258 if (status & core->pci_irqmask) in cx8801_irq()
276 struct cx88_audio_buffer *buf = chip->buf; in cx88_alsa_dma_init()
280 buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); in cx88_alsa_dma_init()
281 if (!buf->vaddr) { in cx88_alsa_dma_init()
283 return -ENOMEM; in cx88_alsa_dma_init()
287 buf->vaddr, nr_pages << PAGE_SHIFT); in cx88_alsa_dma_init()
289 memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); in cx88_alsa_dma_init()
290 buf->nr_pages = nr_pages; in cx88_alsa_dma_init()
292 buf->sglist = vzalloc(array_size(sizeof(*buf->sglist), buf->nr_pages)); in cx88_alsa_dma_init()
293 if (!buf->sglist) in cx88_alsa_dma_init()
296 sg_init_table(buf->sglist, buf->nr_pages); in cx88_alsa_dma_init()
297 for (i = 0; i < buf->nr_pages; i++) { in cx88_alsa_dma_init()
298 pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE); in cx88_alsa_dma_init()
301 sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0); in cx88_alsa_dma_init()
306 vfree(buf->sglist); in cx88_alsa_dma_init()
307 buf->sglist = NULL; in cx88_alsa_dma_init()
309 vfree(buf->vaddr); in cx88_alsa_dma_init()
310 buf->vaddr = NULL; in cx88_alsa_dma_init()
311 return -ENOMEM; in cx88_alsa_dma_init()
316 struct cx88_audio_buffer *buf = dev->buf; in cx88_alsa_dma_map()
318 buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist, in cx88_alsa_dma_map()
319 buf->nr_pages, DMA_FROM_DEVICE); in cx88_alsa_dma_map()
321 if (buf->sglen == 0) { in cx88_alsa_dma_map()
323 return -ENOMEM; in cx88_alsa_dma_map()
330 struct cx88_audio_buffer *buf = dev->buf; in cx88_alsa_dma_unmap()
332 if (!buf->sglen) in cx88_alsa_dma_unmap()
335 dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->nr_pages, in cx88_alsa_dma_unmap()
337 buf->sglen = 0; in cx88_alsa_dma_unmap()
343 vfree(buf->sglist); in cx88_alsa_dma_free()
344 buf->sglist = NULL; in cx88_alsa_dma_free()
345 vfree(buf->vaddr); in cx88_alsa_dma_free()
346 buf->vaddr = NULL; in cx88_alsa_dma_free()
352 struct cx88_riscmem *risc = &chip->buf->risc; in dsp_buffer_free() local
354 WARN_ON(!chip->dma_size); in dsp_buffer_free()
358 cx88_alsa_dma_free(chip->buf); in dsp_buffer_free()
359 if (risc->cpu) in dsp_buffer_free()
360 dma_free_coherent(&chip->pci->dev, risc->size, risc->cpu, in dsp_buffer_free()
361 risc->dma); in dsp_buffer_free()
362 kfree(chip->buf); in dsp_buffer_free()
364 chip->buf = NULL; in dsp_buffer_free()
406 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cx88_pcm_open()
411 return -ENODEV; in snd_cx88_pcm_open()
419 chip->substream = substream; in snd_cx88_pcm_open()
421 runtime->hw = snd_cx88_digital_hw; in snd_cx88_pcm_open()
427 runtime->hw.period_bytes_min = bpl; in snd_cx88_pcm_open()
428 runtime->hw.period_bytes_max = bpl; in snd_cx88_pcm_open()
456 if (substream->runtime->dma_area) { in snd_cx88_hw_params()
458 substream->runtime->dma_area = NULL; in snd_cx88_hw_params()
461 chip->period_size = params_period_bytes(hw_params); in snd_cx88_hw_params()
462 chip->num_periods = params_periods(hw_params); in snd_cx88_hw_params()
463 chip->dma_size = chip->period_size * params_periods(hw_params); in snd_cx88_hw_params()
465 WARN_ON(!chip->dma_size); in snd_cx88_hw_params()
466 WARN_ON(chip->num_periods & (chip->num_periods - 1)); in snd_cx88_hw_params()
470 return -ENOMEM; in snd_cx88_hw_params()
472 chip->buf = buf; in snd_cx88_hw_params()
473 buf->bpl = chip->period_size; in snd_cx88_hw_params()
476 (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); in snd_cx88_hw_params()
484 ret = cx88_risc_databuffer(chip->pci, &buf->risc, buf->sglist, in snd_cx88_hw_params()
485 chip->period_size, chip->num_periods, 1); in snd_cx88_hw_params()
490 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); in snd_cx88_hw_params()
491 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); in snd_cx88_hw_params()
493 substream->runtime->dma_area = chip->buf->vaddr; in snd_cx88_hw_params()
494 substream->runtime->dma_bytes = chip->dma_size; in snd_cx88_hw_params()
495 substream->runtime->dma_addr = 0; in snd_cx88_hw_params()
510 if (substream->runtime->dma_area) { in snd_cx88_hw_free()
512 substream->runtime->dma_area = NULL; in snd_cx88_hw_free()
535 spin_lock(&chip->reg_lock); in snd_cx88_card_trigger()
545 err = -EINVAL; in snd_cx88_card_trigger()
549 spin_unlock(&chip->reg_lock); in snd_cx88_card_trigger()
560 struct snd_pcm_runtime *runtime = substream->runtime; in snd_cx88_pointer()
563 count = atomic_read(&chip->count); in snd_cx88_pointer()
565 // dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__, in snd_cx88_pointer()
566 // count, new, count & (runtime->periods-1), in snd_cx88_pointer()
567 // runtime->period_size * (count & (runtime->periods-1))); in snd_cx88_pointer()
568 return runtime->period_size * (count & (runtime->periods - 1)); in snd_cx88_pointer()
577 void *pageptr = substream->runtime->dma_area + offset; in snd_cx88_page()
605 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); in snd_cx88_pcm()
608 pcm->private_data = chip; in snd_cx88_pcm()
609 strscpy(pcm->name, name, sizeof(pcm->name)); in snd_cx88_pcm()
621 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_cx88_volume_info()
622 info->count = 2; in snd_cx88_volume_info()
623 info->value.integer.min = 0; in snd_cx88_volume_info()
624 info->value.integer.max = 0x3f; in snd_cx88_volume_info()
633 struct cx88_core *core = chip->core; in snd_cx88_volume_get()
634 int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f), in snd_cx88_volume_get()
637 value->value.integer.value[(bal & 0x40) ? 0 : 1] = vol; in snd_cx88_volume_get()
638 vol -= (bal & 0x3f); in snd_cx88_volume_get()
639 value->value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol; in snd_cx88_volume_get()
648 struct cx88_core *core = chip->core; in snd_cx88_wm8775_volume_put()
649 u16 left = value->value.integer.value[0]; in snd_cx88_wm8775_volume_put()
650 u16 right = value->value.integer.value[1]; in snd_cx88_wm8775_volume_put()
651 int v, b; in snd_cx88_wm8775_volume_put() local
655 v = left << 10; in snd_cx88_wm8775_volume_put()
658 v = right << 10; in snd_cx88_wm8775_volume_put()
659 b = right ? 0xffff - (0x8000 * left) / right : 0x8000; in snd_cx88_wm8775_volume_put()
661 wm8775_s_ctrl(core, V4L2_CID_AUDIO_VOLUME, v); in snd_cx88_wm8775_volume_put()
665 /* OK - TODO: test it */
670 struct cx88_core *core = chip->core; in snd_cx88_volume_put()
671 int left, right, v, b; in snd_cx88_volume_put() local
675 if (core->sd_wm8775) in snd_cx88_volume_put()
678 left = value->value.integer.value[0] & 0x3f; in snd_cx88_volume_put()
679 right = value->value.integer.value[1] & 0x3f; in snd_cx88_volume_put()
680 b = right - left; in snd_cx88_volume_put()
682 v = 0x3f - left; in snd_cx88_volume_put()
683 b = (-b) | 0x40; in snd_cx88_volume_put()
685 v = 0x3f - right; in snd_cx88_volume_put()
688 spin_lock_irq(&chip->reg_lock); in snd_cx88_volume_put()
690 if (v != (old & 0x3f)) { in snd_cx88_volume_put()
691 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v); in snd_cx88_volume_put()
698 spin_unlock_irq(&chip->reg_lock); in snd_cx88_volume_put()
703 static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0);
709 .name = "Analog-TV Volume",
720 struct cx88_core *core = chip->core; in snd_cx88_switch_get()
721 u32 bit = kcontrol->private_value; in snd_cx88_switch_get()
723 value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit); in snd_cx88_switch_get()
731 struct cx88_core *core = chip->core; in snd_cx88_switch_put()
732 u32 bit = kcontrol->private_value; in snd_cx88_switch_put()
736 spin_lock_irq(&chip->reg_lock); in snd_cx88_switch_put()
738 if (value->value.integer.value[0] != !(vol & bit)) { in snd_cx88_switch_put()
742 if (core->sd_wm8775 && ((1 << 6) == bit)) in snd_cx88_switch_put()
747 spin_unlock_irq(&chip->reg_lock); in snd_cx88_switch_put()
753 .name = "Audio-Out Switch",
762 .name = "Analog-TV Switch",
773 struct cx88_core *core = chip->core; in snd_cx88_alc_get()
777 value->value.integer.value[0] = val ? 1 : 0; in snd_cx88_alc_get()
785 struct cx88_core *core = chip->core; in snd_cx88_alc_put()
788 value->value.integer.value[0] != 0); in snd_cx88_alc_put()
794 .name = "Line-In ALC Switch",
805 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
817 * Chip-specific destructor
822 if (chip->irq >= 0) in snd_cx88_free()
823 free_irq(chip->irq, chip); in snd_cx88_free()
825 cx88_core_put(chip->core, chip->pci); in snd_cx88_free()
827 pci_disable_device(chip->pci); in snd_cx88_free()
836 struct cx88_audio_dev *chip = card->private_data; in snd_cx88_dev_free()
842 * Alsa Constructor - Component probe
863 chip = card->private_data; in snd_cx88_create()
867 err = -EINVAL; in snd_cx88_create()
871 err = dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); in snd_cx88_create()
873 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n", core->name); in snd_cx88_create()
879 chip->card = card; in snd_cx88_create()
880 chip->pci = pci; in snd_cx88_create()
881 chip->irq = -1; in snd_cx88_create()
882 spin_lock_init(&chip->reg_lock); in snd_cx88_create()
884 chip->core = core; in snd_cx88_create()
887 err = request_irq(chip->pci->irq, cx8801_irq, in snd_cx88_create()
888 IRQF_SHARED, chip->core->name, chip); in snd_cx88_create()
891 chip->core->name, chip->pci->irq); in snd_cx88_create()
900 core->name, devno, in snd_cx88_create()
901 pci_name(pci), pci->revision, pci->irq, in snd_cx88_create()
904 chip->irq = pci->irq; in snd_cx88_create()
905 synchronize_irq(chip->irq); in snd_cx88_create()
922 return (-ENODEV); in cx88_audio_initdev()
926 return (-ENOENT); in cx88_audio_initdev()
929 err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE, in cx88_audio_initdev()
934 card->private_free = snd_cx88_dev_free; in cx88_audio_initdev()
954 /* If there's a wm8775 then add a Line-In ALC switch */ in cx88_audio_initdev()
955 if (core->sd_wm8775) { in cx88_audio_initdev()
961 strscpy(card->driver, "CX88x", sizeof(card->driver)); in cx88_audio_initdev()
962 sprintf(card->shortname, "Conexant CX%x", pci->device); in cx88_audio_initdev()
963 sprintf(card->longname, "%s at %#llx", in cx88_audio_initdev()
964 card->shortname, in cx88_audio_initdev()
966 strscpy(card->mixername, "CX88", sizeof(card->mixername)); in cx88_audio_initdev()
969 card->driver, devno); in cx88_audio_initdev()
993 devno--; in cx88_audio_finidev()