Lines Matching +full:enable +full:- +full:modem +full:- +full:interrupt

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ALSA modem driver for Intel ICH (i8x0) chipsets
7 * This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
13 #include <linux/interrupt.h>
29 static int index = -2; /* Exclude the first card */
38 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
41 static bool enable;
42 module_param(enable, bool, 0444);
53 ICH_REG_##name##_BDBAR = base + 0x0, /* dword - buffer descriptor list base address */ \
54 ICH_REG_##name##_CIV = base + 0x04, /* byte - current index value */ \
55 ICH_REG_##name##_LVI = base + 0x05, /* byte - last valid index */ \
56 ICH_REG_##name##_SR = base + 0x06, /* byte - status register */ \
57 ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
58 ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
59 ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
72 #define ICH_BCIS 0x08 /* buffer completion interrupt status */
73 #define ICH_LVBCI 0x04 /* last valid buffer completion interrupt */
81 #define ICH_IOCE 0x10 /* interrupt on completion enable */
82 #define ICH_FEIE 0x08 /* fifo error interrupt enable */
83 #define ICH_LVBIE 0x04 /* last valid buffer interrupt enable */
89 #define ICH_REG_GLOB_CNT 0x3c /* dword - global control */
90 #define ICH_TRIE 0x00000040 /* tertiary resume interrupt enable */
91 #define ICH_SRIE 0x00000020 /* secondary resume interrupt enable */
92 #define ICH_PRIE 0x00000010 /* primary resume interrupt enable */
96 #define ICH_GIE 0x00000001 /* GPI interrupt enable */
97 #define ICH_REG_GLOB_STA 0x40 /* dword - global status */
98 #define ICH_TRI 0x20000000 /* ICH4: tertiary (AC_SDIN2) resume interrupt */
101 #define ICH_SPINT 0x04000000 /* ICH4: S/PDIF interrupt */
102 #define ICH_P2INT 0x02000000 /* ICH4: PCM2-In interrupt */
103 #define ICH_M2INT 0x01000000 /* ICH4: Mic2-In interrupt */
105 #define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */
106 #define ICH_MD3 0x00020000 /* modem power down semaphore */
112 #define ICH_SRI 0x00000800 /* secondary (AC_SDIN1) resume interrupt */
113 #define ICH_PRI 0x00000400 /* primary (AC_SDIN0) resume interrupt */
116 #define ICH_MCINT 0x00000080 /* MIC capture interrupt */
117 #define ICH_POINT 0x00000040 /* playback interrupt */
118 #define ICH_PIINT 0x00000020 /* capture interrupt */
119 #define ICH_NVSPINT 0x00000010 /* nforce spdif interrupt */
120 #define ICH_MOINT 0x00000004 /* modem playback interrupt */
121 #define ICH_MIINT 0x00000002 /* modem capture interrupt */
122 #define ICH_GSCI 0x00000001 /* GPI status change interrupt */
123 #define ICH_REG_ACC_SEMA 0x44 /* byte - codec write semaphore */
136 #define get_ichdev(substream) (substream->runtime->private_data)
158 unsigned int int_sta_mask; /* interrupt status mask */
187 u32 int_sta_reg; /* interrupt status register */
188 u32 int_sta_mask; /* interrupt status mask */
218 * Lowlevel I/O - busmaster
223 return ioread8(chip->bmaddr + offset);
228 return ioread16(chip->bmaddr + offset);
233 return ioread32(chip->bmaddr + offset);
238 iowrite8(val, chip->bmaddr + offset);
243 iowrite16(val, chip->bmaddr + offset);
248 iowrite32(val, chip->bmaddr + offset);
252 * Lowlevel I/O - AC'97 registers
257 return ioread16(chip->addr + offset);
262 iowrite16(val, chip->addr + offset);
289 return -EIO;
294 return -EIO;
302 } while (time--);
307 dev_err(chip->card->dev,
312 return -EBUSY;
319 struct intel8x0m *chip = ac97->private_data;
321 if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
322 if (! chip->in_ac97_init)
323 dev_err(chip->card->dev,
325 ac97->num, reg);
327 iaputword(chip, reg + ac97->num * 0x80, val);
333 struct intel8x0m *chip = ac97->private_data;
337 if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
338 if (! chip->in_ac97_init)
339 dev_err(chip->card->dev,
341 ac97->num, reg);
344 res = iagetword(chip, reg + ac97->num * 0x80);
350 if (! chip->in_ac97_init)
351 dev_err(chip->card->dev,
353 ac97->num, reg);
369 __le32 *bdbar = ichdev->bdbar;
370 unsigned long port = ichdev->reg_offset;
372 iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
373 if (ichdev->size == ichdev->fragsize) {
374 ichdev->ack_reload = ichdev->ack = 2;
375 ichdev->fragsize1 = ichdev->fragsize >> 1;
377 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
378 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
379 ichdev->fragsize1 >> chip->pcm_pos_shift);
380 bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
381 bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
382 ichdev->fragsize1 >> chip->pcm_pos_shift);
384 ichdev->frags = 2;
386 ichdev->ack_reload = ichdev->ack = 1;
387 ichdev->fragsize1 = ichdev->fragsize;
389 bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
390 bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
391 ichdev->fragsize >> chip->pcm_pos_shift);
393 dev_dbg(chip->card->dev, "bdbar[%i] = 0x%x [0x%x]\n",
397 ichdev->frags = ichdev->size / ichdev->fragsize;
399 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
400 ichdev->civ = 0;
402 ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
403 ichdev->position = 0;
405 dev_dbg(chip->card->dev,
407 ichdev->lvi_frag, ichdev->frags, ichdev->fragsize,
408 ichdev->fragsize1);
411 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
415 * Interrupt handler
420 unsigned long port = ichdev->reg_offset;
425 if (civ == ichdev->civ) {
427 ichdev->civ++;
428 ichdev->civ &= ICH_REG_LVI_MASK;
430 step = civ - ichdev->civ;
433 ichdev->civ = civ;
436 ichdev->position += step * ichdev->fragsize1;
437 ichdev->position %= ichdev->size;
438 ichdev->lvi += step;
439 ichdev->lvi &= ICH_REG_LVI_MASK;
440 iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
442 ichdev->lvi_frag++;
443 ichdev->lvi_frag %= ichdev->frags;
444 ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf +
445 ichdev->lvi_frag *
446 ichdev->fragsize1);
448 dev_dbg(chip->card->dev,
450 ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
451 ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
454 if (--ichdev->ack == 0) {
455 ichdev->ack = ichdev->ack_reload;
459 if (ack && ichdev->substream) {
460 spin_unlock(&chip->reg_lock);
461 snd_pcm_period_elapsed(ichdev->substream);
462 spin_lock(&chip->reg_lock);
464 iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
474 guard(spinlock)(&chip->reg_lock);
475 status = igetdword(chip, chip->int_sta_reg);
478 if ((status & chip->int_sta_mask) == 0) {
480 iputdword(chip, chip->int_sta_reg, status);
484 for (i = 0; i < chip->bdbars_count; i++) {
485 ichdev = &chip->ichd[i];
486 if (status & ichdev->int_sta_mask)
491 iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
505 unsigned long port = ichdev->reg_offset;
523 return -EINVAL;
528 while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
541 ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << chip->pcm_pos_shift;
543 ptr = ichdev->fragsize1 - ptr1;
546 ptr += ichdev->position;
547 if (ptr >= ichdev->size)
549 return bytes_to_frames(substream->runtime, ptr);
555 struct snd_pcm_runtime *runtime = substream->runtime;
558 ichdev->physbuf = runtime->dma_addr;
559 ichdev->size = snd_pcm_lib_buffer_bytes(substream);
560 ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
561 snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate);
562 snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0);
597 struct snd_pcm_runtime *runtime = substream->runtime;
600 ichdev->substream = substream;
601 runtime->hw = snd_intel8x0m_stream;
606 runtime->private_data = ichdev;
614 return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMOUT]);
621 chip->ichd[ICHD_MDMOUT].substream = NULL;
629 return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMIN]);
636 chip->ichd[ICHD_MDMIN].substream = NULL;
674 if (rec->suffix)
675 sprintf(name, "Intel ICH - %s", rec->suffix);
678 err = snd_pcm_new(chip->card, name, device,
679 rec->playback_ops ? 1 : 0,
680 rec->capture_ops ? 1 : 0, &pcm);
684 if (rec->playback_ops)
685 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, rec->playback_ops);
686 if (rec->capture_ops)
687 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, rec->capture_ops);
689 pcm->private_data = chip;
690 pcm->info_flags = 0;
691 pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
692 if (rec->suffix)
693 sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
695 strscpy(pcm->name, chip->card->shortname);
696 chip->pcm[device] = pcm;
699 &chip->pci->dev,
700 rec->prealloc_size,
701 rec->prealloc_max_size);
708 .suffix = "Modem",
725 switch (chip->device_type) {
743 if (i > 0 && rec->ac97_idx) {
745 if (! chip->ichd[rec->ac97_idx].ac97)
754 chip->pcm_devs = device;
765 struct intel8x0m *chip = bus->private_data;
766 chip->ac97_bus = NULL;
771 struct intel8x0m *chip = ac97->private_data;
772 chip->ac97 = NULL;
788 chip->in_ac97_init = 1;
797 err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus);
800 pbus->private_free = snd_intel8x0m_mixer_free_ac97_bus;
802 pbus->clock = ac97_clock;
803 chip->ac97_bus = pbus;
805 ac97.pci = chip->pci;
809 dev_err(chip->card->dev,
815 chip->ac97 = x97;
816 if(ac97_is_modem(x97) && !chip->ichd[ICHD_MDMIN].ac97) {
817 chip->ichd[ICHD_MDMIN].ac97 = x97;
818 chip->ichd[ICHD_MDMOUT].ac97 = x97;
821 chip->in_ac97_init = 0;
825 /* clear the cold-reset bit for the next chance */
826 if (chip->device_type != DEVICE_ALI)
861 dev_err(chip->card->dev, "AC'97 warm reset still in progress? [0x%x]\n",
863 return -EIO;
881 dev_err(chip->card->dev,
884 return -EIO;
887 /* up to two codecs (modem cannot be tertiary with ICH4) */
900 if (chip->ac97)
901 status |= get_ich_codec_bit(chip, chip->ac97->num);
913 if (chip->device_type == DEVICE_SIS) {
932 for (i = 0; i < chip->bdbars_count; i++)
933 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
935 for (i = 0; i < chip->bdbars_count; i++)
936 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
938 for (i = 0; i < chip->bdbars_count; i++)
939 iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, chip->ichd[i].bdbar_addr);
945 struct intel8x0m *chip = card->private_data;
948 if (chip->irq < 0)
951 for (i = 0; i < chip->bdbars_count; i++)
952 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
954 for (i = 0; i < chip->bdbars_count; i++)
955 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
957 if (chip->irq >= 0)
958 free_irq(chip->irq, chip);
967 struct intel8x0m *chip = card->private_data;
970 snd_ac97_suspend(chip->ac97);
971 if (chip->irq >= 0) {
972 free_irq(chip->irq, chip);
973 chip->irq = -1;
974 card->sync_irq = -1;
983 struct intel8x0m *chip = card->private_data;
985 if (request_irq(pci->irq, snd_intel8x0m_interrupt,
988 pci->irq);
990 return -EIO;
992 chip->irq = pci->irq;
993 card->sync_irq = chip->irq;
995 snd_ac97_resume(chip->ac97);
1006 struct intel8x0m *chip = entry->private_data;
1010 if (chip->device_type == DEVICE_ALI)
1025 snd_card_ro_proc_new(chip->card, "intel8x0m", chip,
1038 struct intel8x0m *chip = card->private_data;
1053 spin_lock_init(&chip->reg_lock);
1054 chip->device_type = device_type;
1055 chip->card = card;
1056 chip->pci = pci;
1057 chip->irq = -1;
1059 err = pcim_request_all_regions(pci, card->shortname);
1065 chip->bmaddr = pcim_iomap(pci, 0, 0);
1068 chip->addr = pcim_iomap(pci, 2, 0);
1070 chip->addr = pcim_iomap(pci, 0, 0);
1072 chip->bmaddr = pcim_iomap(pci, 3, 0);
1074 chip->bmaddr = pcim_iomap(pci, 1, 0);
1078 chip->bdbars_count = 2;
1081 for (i = 0; i < chip->bdbars_count; i++) {
1082 ichdev = &chip->ichd[i];
1083 ichdev->ichd = i;
1084 ichdev->reg_offset = tbl[i].offset;
1085 ichdev->int_sta_mask = tbl[i].int_sta_mask;
1088 ichdev->roff_sr = ICH_REG_OFF_PICB;
1089 ichdev->roff_picb = ICH_REG_OFF_SR;
1091 ichdev->roff_sr = ICH_REG_OFF_SR;
1092 ichdev->roff_picb = ICH_REG_OFF_PICB;
1095 ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
1098 chip->pcm_pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;
1102 chip->bdbars = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV,
1103 chip->bdbars_count * sizeof(u32) *
1105 if (!chip->bdbars)
1106 return -ENOMEM;
1111 for (i = 0; i < chip->bdbars_count; i++) {
1112 ichdev = &chip->ichd[i];
1113 ichdev->bdbar = ((__le32 *)chip->bdbars->area) + (i * ICH_MAX_FRAGS * 2);
1114 ichdev->bdbar_addr = chip->bdbars->addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
1115 int_sta_masks |= ichdev->int_sta_mask;
1117 chip->int_sta_reg = ICH_REG_GLOB_STA;
1118 chip->int_sta_mask = int_sta_masks;
1127 * re-acquired in PM callbacks.
1130 if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
1132 dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
1133 return -EBUSY;
1135 chip->irq = pci->irq;
1136 card->sync_irq = chip->irq;
1138 card->private_free = snd_intel8x0m_free;
1147 { PCI_DEVICE_ID_INTEL_82801AA_6, "Intel 82801AA-ICH" },
1148 { PCI_DEVICE_ID_INTEL_82801AB_6, "Intel 82901AB-ICH0" },
1149 { PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" },
1151 { PCI_DEVICE_ID_INTEL_82801CA_6, "Intel 82801CA-ICH3" },
1152 { PCI_DEVICE_ID_INTEL_82801DB_6, "Intel 82801DB-ICH4" },
1177 err = snd_devm_card_new(&pci->dev, index, id, THIS_MODULE,
1181 chip = card->private_data;
1183 strscpy(card->driver, "ICH-MODEM");
1184 strscpy(card->shortname, "Intel ICH");
1185 for (name = shortnames; name->id; name++) {
1186 if (pci->device == name->id) {
1187 strscpy(card->shortname, name->s);
1191 strcat(card->shortname," Modem");
1193 err = snd_intel8x0m_init(card, pci, pci_id->driver_data);
1206 sprintf(card->longname, "%s at irq %i",
1207 card->shortname, chip->irq);
1219 return snd_card_free_on_error(&pci->dev, __snd_intel8x0m_probe(pci, pci_id));