Lines Matching +full:ati +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ALSA driver for ATI IXP 150/200/250 AC97 modem controllers
24 MODULE_DESCRIPTION("ATI IXP MC97 controller");
26 MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
28 static int index = -2; /* Exclude the first card */
33 MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
35 MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
215 int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */
219 * ATI IXP chip
251 { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */
252 { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */
270 void __iomem *addr = chip->remap_addr + reg; in snd_atiixp_update_bits()
285 writel(value, chip->remap_addr + ATI_REG_##reg)
287 readl(chip->remap_addr + ATI_REG_##reg)
295 * in a future version, a scatter-gather buffer should be implemented.
321 return -ENOMEM; in atiixp_build_dma_packets()
323 if (dma->desc_buf.area == NULL) { in atiixp_build_dma_packets()
324 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev, in atiixp_build_dma_packets()
325 ATI_DESC_LIST_SIZE, &dma->desc_buf) < 0) in atiixp_build_dma_packets()
326 return -ENOMEM; in atiixp_build_dma_packets()
327 dma->period_bytes = dma->periods = 0; /* clear */ in atiixp_build_dma_packets()
330 if (dma->periods == periods && dma->period_bytes == period_bytes) in atiixp_build_dma_packets()
334 spin_lock_irqsave(&chip->reg_lock, flags); in atiixp_build_dma_packets()
335 writel(0, chip->remap_addr + dma->ops->llp_offset); in atiixp_build_dma_packets()
336 dma->ops->enable_dma(chip, 0); in atiixp_build_dma_packets()
337 dma->ops->enable_dma(chip, 1); in atiixp_build_dma_packets()
338 spin_unlock_irqrestore(&chip->reg_lock, flags); in atiixp_build_dma_packets()
341 addr = (u32)substream->runtime->dma_addr; in atiixp_build_dma_packets()
342 desc_addr = (u32)dma->desc_buf.addr; in atiixp_build_dma_packets()
345 desc = &((struct atiixp_dma_desc *)dma->desc_buf.area)[i]; in atiixp_build_dma_packets()
346 desc->addr = cpu_to_le32(addr); in atiixp_build_dma_packets()
347 desc->status = 0; in atiixp_build_dma_packets()
348 desc->size = period_bytes >> 2; /* in dwords */ in atiixp_build_dma_packets()
350 if (i == periods - 1) in atiixp_build_dma_packets()
351 desc->next = cpu_to_le32((u32)dma->desc_buf.addr); in atiixp_build_dma_packets()
353 desc->next = cpu_to_le32(desc_addr); in atiixp_build_dma_packets()
357 writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN, in atiixp_build_dma_packets()
358 chip->remap_addr + dma->ops->llp_offset); in atiixp_build_dma_packets()
360 dma->period_bytes = period_bytes; in atiixp_build_dma_packets()
361 dma->periods = periods; in atiixp_build_dma_packets()
373 if (dma->desc_buf.area) { in atiixp_clear_dma_packets()
374 writel(0, chip->remap_addr + dma->ops->llp_offset); in atiixp_clear_dma_packets()
375 snd_dma_free_pages(&dma->desc_buf); in atiixp_clear_dma_packets()
376 dma->desc_buf.area = NULL; in atiixp_clear_dma_packets()
388 if (! timeout--) { in snd_atiixp_acquire_codec()
389 dev_warn(chip->card->dev, "codec acquire timeout\n"); in snd_atiixp_acquire_codec()
390 return -EBUSY; in snd_atiixp_acquire_codec()
419 } while (--timeout); in snd_atiixp_codec_read()
422 dev_warn(chip->card->dev, "codec read timeout (reg %x)\n", reg); in snd_atiixp_codec_read()
445 struct atiixp_modem *chip = ac97->private_data; in snd_atiixp_ac97_read()
446 return snd_atiixp_codec_read(chip, ac97->num, reg); in snd_atiixp_ac97_read()
453 struct atiixp_modem *chip = ac97->private_data; in snd_atiixp_ac97_write()
459 snd_atiixp_codec_write(chip, ac97->num, reg, val); in snd_atiixp_ac97_write()
487 if (!--timeout) { in snd_atiixp_aclink_reset()
488 dev_err(chip->card->dev, "codec reset timeout\n"); in snd_atiixp_aclink_reset()
504 // return -EBUSY; in snd_atiixp_aclink_down()
513 * auto-detection of codecs
515 * the IXP chip can generate interrupts for the non-existing codecs.
530 chip->codec_not_ready_bits = 0; in snd_atiixp_codec_detect()
534 while (timeout-- > 0) { in snd_atiixp_codec_detect()
536 if (chip->codec_not_ready_bits) in snd_atiixp_codec_detect()
541 if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) { in snd_atiixp_codec_detect()
542 dev_err(chip->card->dev, "no codec detected!\n"); in snd_atiixp_codec_detect()
543 return -ENXIO; in snd_atiixp_codec_detect()
556 /* set up spdif, enable burst mode */ in snd_atiixp_chip_start()
593 * position. when SG-buffer is implemented, the offset must be calculated
599 struct snd_pcm_runtime *runtime = substream->runtime; in snd_atiixp_pcm_pointer()
600 struct atiixp_dma *dma = runtime->private_data; in snd_atiixp_pcm_pointer()
604 while (timeout--) { in snd_atiixp_pcm_pointer()
605 curptr = readl(chip->remap_addr + dma->ops->dt_cur); in snd_atiixp_pcm_pointer()
606 if (curptr < dma->buf_addr) in snd_atiixp_pcm_pointer()
608 curptr -= dma->buf_addr; in snd_atiixp_pcm_pointer()
609 if (curptr >= dma->buf_bytes) in snd_atiixp_pcm_pointer()
613 dev_dbg(chip->card->dev, "invalid DMA pointer read 0x%x (buf=%x)\n", in snd_atiixp_pcm_pointer()
614 readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr); in snd_atiixp_pcm_pointer()
624 if (! dma->substream || ! dma->running) in snd_atiixp_xrun_dma()
626 dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); in snd_atiixp_xrun_dma()
627 snd_pcm_stop_xrun(dma->substream); in snd_atiixp_xrun_dma()
636 if (! dma->substream || ! dma->running) in snd_atiixp_update_dma()
638 snd_pcm_period_elapsed(dma->substream); in snd_atiixp_update_dma()
660 struct atiixp_dma *dma = substream->runtime->private_data; in snd_atiixp_pcm_trigger()
663 if (snd_BUG_ON(!dma->ops->enable_transfer || in snd_atiixp_pcm_trigger()
664 !dma->ops->flush_dma)) in snd_atiixp_pcm_trigger()
665 return -EINVAL; in snd_atiixp_pcm_trigger()
667 spin_lock(&chip->reg_lock); in snd_atiixp_pcm_trigger()
670 dma->ops->enable_transfer(chip, 1); in snd_atiixp_pcm_trigger()
671 dma->running = 1; in snd_atiixp_pcm_trigger()
674 dma->ops->enable_transfer(chip, 0); in snd_atiixp_pcm_trigger()
675 dma->running = 0; in snd_atiixp_pcm_trigger()
678 err = -EINVAL; in snd_atiixp_pcm_trigger()
684 dma->ops->flush_dma(chip); in snd_atiixp_pcm_trigger()
688 spin_unlock(&chip->reg_lock); in snd_atiixp_pcm_trigger()
696 * every callback is supposed to be called in chip->reg_lock spinlock
759 spin_lock_irq(&chip->reg_lock); in snd_atiixp_playback_prepare()
765 spin_unlock_irq(&chip->reg_lock); in snd_atiixp_playback_prepare()
776 * hw_params - allocate the buffer and set up buffer descriptors
782 struct atiixp_dma *dma = substream->runtime->private_data; in snd_atiixp_pcm_hw_params()
786 dma->buf_addr = substream->runtime->dma_addr; in snd_atiixp_pcm_hw_params()
787 dma->buf_bytes = params_buffer_bytes(hw_params); in snd_atiixp_pcm_hw_params()
797 if (! chip->ac97[i]) in snd_atiixp_pcm_hw_params()
799 snd_ac97_write(chip->ac97[i], AC97_LINE1_RATE, params_rate(hw_params)); in snd_atiixp_pcm_hw_params()
800 snd_ac97_write(chip->ac97[i], AC97_LINE1_LEVEL, 0); in snd_atiixp_pcm_hw_params()
809 struct atiixp_dma *dma = substream->runtime->private_data; in snd_atiixp_pcm_hw_free()
843 struct snd_pcm_runtime *runtime = substream->runtime; in snd_atiixp_pcm_open()
852 if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma)) in snd_atiixp_pcm_open()
853 return -EINVAL; in snd_atiixp_pcm_open()
855 if (dma->opened) in snd_atiixp_pcm_open()
856 return -EBUSY; in snd_atiixp_pcm_open()
857 dma->substream = substream; in snd_atiixp_pcm_open()
858 runtime->hw = snd_atiixp_pcm_hw; in snd_atiixp_pcm_open()
859 dma->ac97_pcm_type = pcm_type; in snd_atiixp_pcm_open()
867 runtime->private_data = dma; in snd_atiixp_pcm_open()
870 spin_lock_irq(&chip->reg_lock); in snd_atiixp_pcm_open()
871 dma->ops->enable_dma(chip, 1); in snd_atiixp_pcm_open()
872 spin_unlock_irq(&chip->reg_lock); in snd_atiixp_pcm_open()
873 dma->opened = 1; in snd_atiixp_pcm_open()
883 if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma)) in snd_atiixp_pcm_close()
884 return -EINVAL; in snd_atiixp_pcm_close()
885 spin_lock_irq(&chip->reg_lock); in snd_atiixp_pcm_close()
886 dma->ops->enable_dma(chip, 0); in snd_atiixp_pcm_close()
887 spin_unlock_irq(&chip->reg_lock); in snd_atiixp_pcm_close()
888 dma->substream = NULL; in snd_atiixp_pcm_close()
889 dma->opened = 0; in snd_atiixp_pcm_close()
900 mutex_lock(&chip->open_mutex); in snd_atiixp_playback_open()
901 err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); in snd_atiixp_playback_open()
902 mutex_unlock(&chip->open_mutex); in snd_atiixp_playback_open()
912 mutex_lock(&chip->open_mutex); in snd_atiixp_playback_close()
913 err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); in snd_atiixp_playback_close()
914 mutex_unlock(&chip->open_mutex); in snd_atiixp_playback_close()
921 return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1); in snd_atiixp_capture_open()
927 return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]); in snd_atiixp_capture_close()
977 chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops; in snd_atiixp_pcm_new()
978 chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops; in snd_atiixp_pcm_new()
981 err = snd_pcm_new(chip->card, "ATI IXP MC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm); in snd_atiixp_pcm_new()
986 pcm->dev_class = SNDRV_PCM_CLASS_MODEM; in snd_atiixp_pcm_new()
987 pcm->private_data = chip; in snd_atiixp_pcm_new()
988 strcpy(pcm->name, "ATI IXP MC97"); in snd_atiixp_pcm_new()
989 chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm; in snd_atiixp_pcm_new()
992 &chip->pci->dev, 64*1024, 128*1024); in snd_atiixp_pcm_new()
1014 snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]); in snd_atiixp_interrupt()
1016 snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]); in snd_atiixp_interrupt()
1018 snd_atiixp_xrun_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]); in snd_atiixp_interrupt()
1020 snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]); in snd_atiixp_interrupt()
1026 spin_lock(&chip->reg_lock); in snd_atiixp_interrupt()
1027 chip->codec_not_ready_bits |= detected; in snd_atiixp_interrupt()
1029 spin_unlock(&chip->reg_lock); in snd_atiixp_interrupt()
1060 return -ENXIO; in snd_atiixp_mixer_new()
1062 if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0) in snd_atiixp_mixer_new()
1064 pbus->clock = clock; in snd_atiixp_mixer_new()
1065 chip->ac97_bus = pbus; in snd_atiixp_mixer_new()
1069 if (chip->codec_not_ready_bits & codec_skip[i]) in snd_atiixp_mixer_new()
1073 ac97.pci = chip->pci; in snd_atiixp_mixer_new()
1076 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { in snd_atiixp_mixer_new()
1077 chip->ac97[i] = NULL; /* to be sure */ in snd_atiixp_mixer_new()
1078 dev_dbg(chip->card->dev, in snd_atiixp_mixer_new()
1086 dev_err(chip->card->dev, "no codec available\n"); in snd_atiixp_mixer_new()
1087 return -ENODEV; in snd_atiixp_mixer_new()
1090 /* snd_ac97_tune_hardware(chip->ac97, ac97_quirks); */ in snd_atiixp_mixer_new()
1103 struct atiixp_modem *chip = card->private_data; in snd_atiixp_suspend()
1108 snd_ac97_suspend(chip->ac97[i]); in snd_atiixp_suspend()
1117 struct atiixp_modem *chip = card->private_data; in snd_atiixp_resume()
1124 snd_ac97_resume(chip->ac97[i]); in snd_atiixp_resume()
1143 struct atiixp_modem *chip = entry->private_data; in snd_atiixp_proc_read()
1147 snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i)); in snd_atiixp_proc_read()
1152 snd_card_ro_proc_new(chip->card, "atiixp-modem", chip, in snd_atiixp_proc_init()
1163 if (chip->irq < 0) in snd_atiixp_free()
1168 if (chip->irq >= 0) in snd_atiixp_free()
1169 free_irq(chip->irq, chip); in snd_atiixp_free()
1170 iounmap(chip->remap_addr); in snd_atiixp_free()
1171 pci_release_regions(chip->pci); in snd_atiixp_free()
1172 pci_disable_device(chip->pci); in snd_atiixp_free()
1179 struct atiixp_modem *chip = device->device_data; in snd_atiixp_dev_free()
1202 return -ENOMEM; in snd_atiixp_create()
1205 spin_lock_init(&chip->reg_lock); in snd_atiixp_create()
1206 mutex_init(&chip->open_mutex); in snd_atiixp_create()
1207 chip->card = card; in snd_atiixp_create()
1208 chip->pci = pci; in snd_atiixp_create()
1209 chip->irq = -1; in snd_atiixp_create()
1210 if ((err = pci_request_regions(pci, "ATI IXP MC97")) < 0) { in snd_atiixp_create()
1215 chip->addr = pci_resource_start(pci, 0); in snd_atiixp_create()
1216 chip->remap_addr = pci_ioremap_bar(pci, 0); in snd_atiixp_create()
1217 if (chip->remap_addr == NULL) { in snd_atiixp_create()
1218 dev_err(card->dev, "AC'97 space ioremap problem\n"); in snd_atiixp_create()
1220 return -EIO; in snd_atiixp_create()
1223 if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED, in snd_atiixp_create()
1225 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); in snd_atiixp_create()
1227 return -EBUSY; in snd_atiixp_create()
1229 chip->irq = pci->irq; in snd_atiixp_create()
1230 card->sync_irq = chip->irq; in snd_atiixp_create()
1250 err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card); in snd_atiixp_probe()
1254 strcpy(card->driver, "ATIIXP-MODEM"); in snd_atiixp_probe()
1255 strcpy(card->shortname, "ATI IXP Modem"); in snd_atiixp_probe()
1258 card->private_data = chip; in snd_atiixp_probe()
1273 sprintf(card->longname, "%s rev %x at 0x%lx, irq %i", in snd_atiixp_probe()
1274 card->shortname, pci->revision, chip->addr, chip->irq); in snd_atiixp_probe()