^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ALSA modem driver for Intel ICH (i8x0) chipsets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * of ALSA ICH sound driver intel8x0.c .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/ac97_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) "SiS 7013; NVidia MCP/2/2S/3 modems");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) "{Intel,82901AB-ICH0},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) "{Intel,82801BA-ICH2},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) "{Intel,82801CA-ICH3},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) "{Intel,82801DB-ICH4},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) "{Intel,ICH5},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) "{Intel,ICH6},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) "{Intel,ICH7},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "{Intel,MX440},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "{SiS,7013},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) "{NVidia,NForce Modem},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) "{NVidia,NForce2 Modem},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "{NVidia,NForce2s Modem},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "{NVidia,NForce3 Modem},"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) "{AMD,AMD768}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int index = -2; /* Exclude the first card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int ac97_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) module_param(index, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) module_param(id, charp, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MODULE_PARM_DESC(id, "ID string for Intel i8x0 modemcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) module_param(ac97_clock, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* just for backward compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static bool enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) module_param(enable, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Direct registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) enum { DEVICE_INTEL, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define ICHREG(x) ICH_REG_##x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define DEFINE_REGSET(name,base) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) enum { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ICH_REG_##name##_BDBAR = base + 0x0, /* dword - buffer descriptor list base address */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ICH_REG_##name##_CIV = base + 0x04, /* byte - current index value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ICH_REG_##name##_LVI = base + 0x05, /* byte - last valid index */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ICH_REG_##name##_SR = base + 0x06, /* byte - status register */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ICH_REG_##name##_PICB = base + 0x08, /* word - position in current buffer */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ICH_REG_##name##_PIV = base + 0x0a, /* byte - prefetched index value */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ICH_REG_##name##_CR = base + 0x0b, /* byte - control register */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* busmaster blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) DEFINE_REGSET(OFF, 0); /* offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* values for each busmaster block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* LVI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define ICH_REG_LVI_MASK 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* SR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define ICH_FIFOE 0x10 /* FIFO error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ICH_BCIS 0x08 /* buffer completion interrupt status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define ICH_LVBCI 0x04 /* last valid buffer completion interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define ICH_CELV 0x02 /* current equals last valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define ICH_DCH 0x01 /* DMA controller halted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* PIV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define ICH_REG_PIV_MASK 0x1f /* mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* CR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define ICH_IOCE 0x10 /* interrupt on completion enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define ICH_FEIE 0x08 /* fifo error interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define ICH_LVBIE 0x04 /* last valid buffer interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define ICH_RESETREGS 0x02 /* reset busmaster registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define ICH_STARTBM 0x01 /* start busmaster operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* global block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ICH_REG_GLOB_CNT 0x3c /* dword - global control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define ICH_TRIE 0x00000040 /* tertiary resume interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define ICH_SRIE 0x00000020 /* secondary resume interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ICH_PRIE 0x00000010 /* primary resume interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define ICH_ACLINK 0x00000008 /* AClink shut off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define ICH_AC97WARM 0x00000004 /* AC'97 warm reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define ICH_AC97COLD 0x00000002 /* AC'97 cold reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define ICH_GIE 0x00000001 /* GPI interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define ICH_REG_GLOB_STA 0x40 /* dword - global status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define ICH_TRI 0x20000000 /* ICH4: tertiary (AC_SDIN2) resume interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define ICH_TCR 0x10000000 /* ICH4: tertiary (AC_SDIN2) codec ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define ICH_BCS 0x08000000 /* ICH4: bit clock stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define ICH_SPINT 0x04000000 /* ICH4: S/PDIF interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define ICH_P2INT 0x02000000 /* ICH4: PCM2-In interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define ICH_M2INT 0x01000000 /* ICH4: Mic2-In interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define ICH_MD3 0x00020000 /* modem power down semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define ICH_AD3 0x00010000 /* audio power down semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define ICH_RCS 0x00008000 /* read completion status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define ICH_BIT3 0x00004000 /* bit 3 slot 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define ICH_BIT2 0x00002000 /* bit 2 slot 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define ICH_BIT1 0x00001000 /* bit 1 slot 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define ICH_SRI 0x00000800 /* secondary (AC_SDIN1) resume interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define ICH_PRI 0x00000400 /* primary (AC_SDIN0) resume interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define ICH_SCR 0x00000200 /* secondary (AC_SDIN1) codec ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define ICH_PCR 0x00000100 /* primary (AC_SDIN0) codec ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define ICH_MCINT 0x00000080 /* MIC capture interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define ICH_POINT 0x00000040 /* playback interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define ICH_PIINT 0x00000020 /* capture interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define ICH_NVSPINT 0x00000010 /* nforce spdif interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define ICH_MOINT 0x00000004 /* modem playback interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define ICH_MIINT 0x00000002 /* modem capture interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define ICH_GSCI 0x00000001 /* GPI status change interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define ICH_REG_ACC_SEMA 0x44 /* byte - codec write semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define ICH_CAS 0x01 /* codec access semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define ICH_MAX_FRAGS 32 /* max hw frags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) enum { ICHD_MDMIN, ICHD_MDMOUT, ICHD_MDMLAST = ICHD_MDMOUT };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) enum { ALID_MDMIN, ALID_MDMOUT, ALID_MDMLAST = ALID_MDMOUT };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define get_ichdev(substream) (substream->runtime->private_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct ichdev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned int ichd; /* ich device number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned long reg_offset; /* offset to bmaddr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) __le32 *bdbar; /* CPU address (32bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned int bdbar_addr; /* PCI bus address (32bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned int physbuf; /* physical address (32bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned int fragsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned int fragsize1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsigned int position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int lvi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int lvi_frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int civ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int ack_reload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned int ack_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned int roff_sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned int roff_picb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) unsigned int int_sta_mask; /* interrupt status mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int ali_slot; /* ALI DMA slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct snd_ac97 *ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct intel8x0m {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned int device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) void __iomem *bmaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct pci_dev *pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int pcm_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct snd_pcm *pcm[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct ichdev ichd[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) unsigned int in_ac97_init: 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct snd_ac97_bus *ac97_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct snd_ac97 *ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct snd_dma_buffer bdbars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u32 bdbars_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 int_sta_reg; /* interrupt status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 int_sta_mask; /* interrupt status mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned int pcm_pos_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static const struct pci_device_id snd_intel8x0m_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { PCI_VDEVICE(INTEL, 0x2486), DEVICE_INTEL }, /* ICH3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) { PCI_VDEVICE(INTEL, 0x24c6), DEVICE_INTEL }, /* ICH4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { PCI_VDEVICE(INTEL, 0x24d6), DEVICE_INTEL }, /* ICH5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) { PCI_VDEVICE(INTEL, 0x266d), DEVICE_INTEL }, /* ICH6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) { PCI_VDEVICE(INTEL, 0x27dd), DEVICE_INTEL }, /* ICH7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) { PCI_VDEVICE(INTEL, 0x7196), DEVICE_INTEL }, /* 440MX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) { PCI_VDEVICE(AMD, 0x7446), DEVICE_INTEL }, /* AMD768 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) { PCI_VDEVICE(SI, 0x7013), DEVICE_SIS }, /* SI7013 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) { PCI_VDEVICE(NVIDIA, 0x01c1), DEVICE_NFORCE }, /* NFORCE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL }, /* AMD8111 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * Lowlevel I/O - busmaster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static inline u8 igetbyte(struct intel8x0m *chip, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return ioread8(chip->bmaddr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static inline u16 igetword(struct intel8x0m *chip, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return ioread16(chip->bmaddr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static inline u32 igetdword(struct intel8x0m *chip, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return ioread32(chip->bmaddr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static inline void iputbyte(struct intel8x0m *chip, u32 offset, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) iowrite8(val, chip->bmaddr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static inline void iputword(struct intel8x0m *chip, u32 offset, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) iowrite16(val, chip->bmaddr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static inline void iputdword(struct intel8x0m *chip, u32 offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) iowrite32(val, chip->bmaddr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Lowlevel I/O - AC'97 registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline u16 iagetword(struct intel8x0m *chip, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return ioread16(chip->addr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static inline void iaputword(struct intel8x0m *chip, u32 offset, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) iowrite16(val, chip->addr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * Basic I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * access to AC97 codec via normal i/o (for ICH and SIS7013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* return the GLOB_STA bit for the corresponding codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static unsigned int get_ich_codec_bit(struct intel8x0m *chip, unsigned int codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static const unsigned int codec_bit[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ICH_PCR, ICH_SCR, ICH_TCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (snd_BUG_ON(codec >= 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return ICH_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return codec_bit[codec];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int snd_intel8x0m_codec_semaphore(struct intel8x0m *chip, unsigned int codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (codec > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) codec = get_ich_codec_bit(chip, codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* codec ready ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Anyone holding a semaphore for 1 msec should be shot... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) time = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!(igetbyte(chip, ICHREG(ACC_SEMA)) & ICH_CAS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) } while (time--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* access to some forbidden (non existent) ac97 registers will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * reset the semaphore. So even if you don't get the semaphore, still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * continue the access. We don't need the semaphore anyway. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) iagetword(chip, 0); /* clear semaphore flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* I don't care about the semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static void snd_intel8x0m_codec_write(struct snd_ac97 *ac97,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned short reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct intel8x0m *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (! chip->in_ac97_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) "codec_write %d: semaphore is not ready for register 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ac97->num, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) iaputword(chip, reg + ac97->num * 0x80, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static unsigned short snd_intel8x0m_codec_read(struct snd_ac97 *ac97,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct intel8x0m *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) unsigned short res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (! chip->in_ac97_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) "codec_read %d: semaphore is not ready for register 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ac97->num, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) res = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) res = iagetword(chip, reg + ac97->num * 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* reset RCS and preserve other R/WC bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) iputdword(chip, ICHREG(GLOB_STA),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (! chip->in_ac97_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) "codec_read %d: read timeout for register 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ac97->num, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) res = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (reg == AC97_GPIO_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) iagetword(chip, 0); /* clear semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * DMA I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static void snd_intel8x0m_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) __le32 *bdbar = ichdev->bdbar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) unsigned long port = ichdev->reg_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ichdev->size == ichdev->fragsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ichdev->ack_reload = ichdev->ack = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ichdev->fragsize1 = ichdev->fragsize >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ichdev->fragsize1 >> chip->pcm_pos_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ichdev->fragsize1 >> chip->pcm_pos_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ichdev->frags = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ichdev->ack_reload = ichdev->ack = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ichdev->fragsize1 = ichdev->fragsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ichdev->fragsize >> chip->pcm_pos_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) dev_dbg(chip->card->dev, "bdbar[%i] = 0x%x [0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ichdev->frags = ichdev->size / ichdev->fragsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi = ICH_REG_LVI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ichdev->civ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) iputbyte(chip, port + ICH_REG_OFF_CIV, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ichdev->lvi_frag = ICH_REG_LVI_MASK % ichdev->frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ichdev->position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) "lvi_frag = %i, frags = %i, period_size = 0x%x, period_size1 = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ichdev->lvi_frag, ichdev->frags, ichdev->fragsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ichdev->fragsize1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* clear interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * Interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static inline void snd_intel8x0m_update(struct intel8x0m *chip, struct ichdev *ichdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) unsigned long port = ichdev->reg_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int civ, i, step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (civ == ichdev->civ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) // snd_printd("civ same %d\n", civ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ichdev->civ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ichdev->civ &= ICH_REG_LVI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) step = civ - ichdev->civ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (step < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) step += ICH_REG_LVI_MASK + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) // if (step != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) // snd_printd("step = %d, %d -> %d\n", step, ichdev->civ, civ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ichdev->civ = civ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ichdev->position += step * ichdev->fragsize1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ichdev->position %= ichdev->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ichdev->lvi += step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ichdev->lvi &= ICH_REG_LVI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) for (i = 0; i < step; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ichdev->lvi_frag++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ichdev->lvi_frag %= ichdev->frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ichdev->lvi_frag *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ichdev->fragsize1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) "new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) inl(port + 4), inb(port + ICH_REG_OFF_CR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (--ichdev->ack == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ichdev->ack = ichdev->ack_reload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ack = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (ack && ichdev->substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) snd_pcm_period_elapsed(ichdev->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static irqreturn_t snd_intel8x0m_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct intel8x0m *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct ichdev *ichdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) status = igetdword(chip, chip->int_sta_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (status == 0xffffffff) { /* we are not yet resumed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if ((status & chip->int_sta_mask) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) iputdword(chip, chip->int_sta_reg, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) for (i = 0; i < chip->bdbars_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ichdev = &chip->ichd[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (status & ichdev->int_sta_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) snd_intel8x0m_update(chip, ichdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* ack them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) iputdword(chip, chip->int_sta_reg, status & chip->int_sta_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * PCM part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int snd_intel8x0m_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct intel8x0m *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct ichdev *ichdev = get_ichdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned char val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) unsigned long port = ichdev->reg_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) val = ICH_IOCE | ICH_STARTBM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) val = ICH_IOCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) val = ICH_IOCE | ICH_STARTBM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) iputbyte(chip, port + ICH_REG_OFF_CR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (cmd == SNDRV_PCM_TRIGGER_STOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* wait until DMA stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) while (!(igetbyte(chip, port + ichdev->roff_sr) & ICH_DCH)) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* reset whole DMA things */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static snd_pcm_uframes_t snd_intel8x0m_pcm_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct intel8x0m *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct ichdev *ichdev = get_ichdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) size_t ptr1, ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << chip->pcm_pos_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (ptr1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) ptr = ichdev->fragsize1 - ptr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ptr += ichdev->position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ptr >= ichdev->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return bytes_to_frames(substream->runtime, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct intel8x0m *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct ichdev *ichdev = get_ichdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ichdev->physbuf = runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ichdev->size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ichdev->fragsize = snd_pcm_lib_period_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) snd_ac97_write(ichdev->ac97, AC97_LINE1_RATE, runtime->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) snd_ac97_write(ichdev->ac97, AC97_LINE1_LEVEL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) snd_intel8x0m_setup_periods(chip, ichdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static const struct snd_pcm_hardware snd_intel8x0m_stream =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) SNDRV_PCM_INFO_PAUSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) SNDRV_PCM_INFO_RESUME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .formats = SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .rate_max = 16000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .channels_max = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) .buffer_bytes_max = 64 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .period_bytes_min = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .period_bytes_max = 64 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int snd_intel8x0m_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static const unsigned int rates[] = { 8000, 9600, 12000, 16000 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .count = ARRAY_SIZE(rates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .list = rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ichdev->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) runtime->hw = snd_intel8x0m_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) &hw_constraints_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if ( err < 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) runtime->private_data = ichdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static int snd_intel8x0m_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct intel8x0m *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMOUT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static int snd_intel8x0m_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct intel8x0m *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) chip->ichd[ICHD_MDMOUT].substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int snd_intel8x0m_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct intel8x0m *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMIN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static int snd_intel8x0m_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct intel8x0m *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) chip->ichd[ICHD_MDMIN].substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static const struct snd_pcm_ops snd_intel8x0m_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) .open = snd_intel8x0m_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .close = snd_intel8x0m_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .prepare = snd_intel8x0m_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .trigger = snd_intel8x0m_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .pointer = snd_intel8x0m_pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static const struct snd_pcm_ops snd_intel8x0m_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .open = snd_intel8x0m_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) .close = snd_intel8x0m_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .prepare = snd_intel8x0m_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) .trigger = snd_intel8x0m_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) .pointer = snd_intel8x0m_pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct ich_pcm_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) char *suffix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) const struct snd_pcm_ops *playback_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) const struct snd_pcm_ops *capture_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) size_t prealloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) size_t prealloc_max_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int ac97_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int snd_intel8x0m_pcm1(struct intel8x0m *chip, int device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) const struct ich_pcm_table *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) char name[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (rec->suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sprintf(name, "Intel ICH - %s", rec->suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) strcpy(name, "Intel ICH");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) err = snd_pcm_new(chip->card, name, device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) rec->playback_ops ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) rec->capture_ops ? 1 : 0, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (rec->playback_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, rec->playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (rec->capture_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, rec->capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (rec->suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) strcpy(pcm->name, chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) chip->pcm[device] = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) &chip->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) rec->prealloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) rec->prealloc_max_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static const struct ich_pcm_table intel_pcms[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) .suffix = "Modem",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .playback_ops = &snd_intel8x0m_playback_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .capture_ops = &snd_intel8x0m_capture_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .prealloc_size = 32 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .prealloc_max_size = 64 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static int snd_intel8x0m_pcm(struct intel8x0m *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int i, tblsize, device, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) const struct ich_pcm_table *tbl, *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) tbl = intel_pcms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) tblsize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) switch (chip->device_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) case DEVICE_NFORCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) tbl = nforce_pcms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) tblsize = ARRAY_SIZE(nforce_pcms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case DEVICE_ALI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) tbl = ali_pcms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) tblsize = ARRAY_SIZE(ali_pcms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) tbl = intel_pcms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) tblsize = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) device = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) for (i = 0; i < tblsize; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) rec = tbl + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (i > 0 && rec->ac97_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /* activate PCM only when associated AC'97 codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (! chip->ichd[rec->ac97_idx].ac97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) err = snd_intel8x0m_pcm1(chip, device, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) device++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) chip->pcm_devs = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * Mixer part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static void snd_intel8x0m_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct intel8x0m *chip = bus->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) chip->ac97_bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static void snd_intel8x0m_mixer_free_ac97(struct snd_ac97 *ac97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct intel8x0m *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) chip->ac97 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static int snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct snd_ac97_bus *pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct snd_ac97_template ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct snd_ac97 *x97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) unsigned int glob_sta = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static const struct snd_ac97_bus_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .write = snd_intel8x0m_codec_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .read = snd_intel8x0m_codec_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) chip->in_ac97_init = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) memset(&ac97, 0, sizeof(ac97));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ac97.private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ac97.private_free = snd_intel8x0m_mixer_free_ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) glob_sta = igetdword(chip, ICHREG(GLOB_STA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) pbus->private_free = snd_intel8x0m_mixer_free_ac97_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (ac97_clock >= 8000 && ac97_clock <= 48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) pbus->clock = ac97_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) chip->ac97_bus = pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ac97.pci = chip->pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ac97.num = glob_sta & ICH_SCR ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if ((err = snd_ac97_mixer(pbus, &ac97, &x97)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) "Unable to initialize codec #%d\n", ac97.num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (ac97.num == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) goto __err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) chip->ac97 = x97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if(ac97_is_modem(x97) && !chip->ichd[ICHD_MDMIN].ac97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) chip->ichd[ICHD_MDMIN].ac97 = x97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) chip->ichd[ICHD_MDMOUT].ac97 = x97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) chip->in_ac97_init = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) __err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /* clear the cold-reset bit for the next chance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (chip->device_type != DEVICE_ALI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) iputdword(chip, ICHREG(GLOB_CNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static int snd_intel8x0m_ich_chip_init(struct intel8x0m *chip, int probing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) unsigned long end_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) unsigned int cnt, status, nstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /* put logic to right state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* first clear status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) status = ICH_RCS | ICH_MIINT | ICH_MOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) cnt = igetdword(chip, ICHREG(GLOB_STA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) iputdword(chip, ICHREG(GLOB_STA), cnt & status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* ACLink on, 2 channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) cnt = igetdword(chip, ICHREG(GLOB_CNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) cnt &= ~(ICH_ACLINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* finish cold or do warm reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) cnt |= (cnt & ICH_AC97COLD) == 0 ? ICH_AC97COLD : ICH_AC97WARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) iputdword(chip, ICHREG(GLOB_CNT), cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) usleep_range(500, 1000); /* give warm reset some time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) end_time = jiffies + HZ / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) goto __ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) } while (time_after_eq(end_time, jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_err(chip->card->dev, "AC'97 warm reset still in progress? [0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) igetdword(chip, ICHREG(GLOB_CNT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) __ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (probing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* wait for any codec ready status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * Once it becomes ready it should remain ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * as long as we do not disable the ac97 link.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) end_time = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) status = igetdword(chip, ICHREG(GLOB_STA)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) (ICH_PCR | ICH_SCR | ICH_TCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) } while (time_after_eq(end_time, jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (! status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* no codec is found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev_err(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) "codec_ready: codec is not ready [0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) igetdword(chip, ICHREG(GLOB_STA)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* up to two codecs (modem cannot be tertiary with ICH4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) nstatus = ICH_PCR | ICH_SCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* wait for other codecs ready status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) end_time = jiffies + HZ / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) while (status != nstatus && time_after_eq(end_time, jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* resume phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (chip->ac97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) status |= get_ich_codec_bit(chip, chip->ac97->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* wait until all the probed codecs are ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) end_time = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) nstatus = igetdword(chip, ICHREG(GLOB_STA)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) (ICH_PCR | ICH_SCR | ICH_TCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (status == nstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) } while (time_after_eq(end_time, jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (chip->device_type == DEVICE_SIS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* unmute the output on SIS7012 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static int snd_intel8x0m_chip_init(struct intel8x0m *chip, int probing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if ((err = snd_intel8x0m_ich_chip_init(chip, probing)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) iagetword(chip, 0); /* clear semaphore flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /* disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) for (i = 0; i < chip->bdbars_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* reset channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) for (i = 0; i < chip->bdbars_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /* initialize Buffer Descriptor Lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) for (i = 0; i < chip->bdbars_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, chip->ichd[i].bdbar_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) static int snd_intel8x0m_free(struct intel8x0m *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (chip->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) goto __hw_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /* disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) for (i = 0; i < chip->bdbars_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /* reset channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) for (i = 0; i < chip->bdbars_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) __hw_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (chip->bdbars.area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) snd_dma_free_pages(&chip->bdbars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (chip->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pci_iounmap(chip->pci, chip->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (chip->bmaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) pci_iounmap(chip->pci, chip->bmaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) pci_release_regions(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) pci_disable_device(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * power management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static int intel8x0m_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct intel8x0m *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) snd_ac97_suspend(chip->ac97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (chip->irq >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) card->sync_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static int intel8x0m_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct pci_dev *pci = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct intel8x0m *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (request_irq(pci->irq, snd_intel8x0m_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) IRQF_SHARED, KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) dev_err(dev, "unable to grab IRQ %d, disabling device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) snd_card_disconnect(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) snd_intel8x0m_chip_init(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) snd_ac97_resume(chip->ac97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) snd_power_change_state(card, SNDRV_CTL_POWER_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static SIMPLE_DEV_PM_OPS(intel8x0m_pm, intel8x0m_suspend, intel8x0m_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) #define INTEL8X0M_PM_OPS &intel8x0m_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) #define INTEL8X0M_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) static void snd_intel8x0m_proc_read(struct snd_info_entry * entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct intel8x0m *chip = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) snd_iprintf(buffer, "Intel8x0m\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (chip->device_type == DEVICE_ALI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) tmp = igetdword(chip, ICHREG(GLOB_STA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) snd_iprintf(buffer, "Global control : 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) igetdword(chip, ICHREG(GLOB_CNT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) snd_iprintf(buffer, "Global status : 0x%08x\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) snd_iprintf(buffer, "AC'97 codecs ready :%s%s%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) tmp & ICH_PCR ? " primary" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) tmp & ICH_SCR ? " secondary" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) tmp & ICH_TCR ? " tertiary" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) (tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static void snd_intel8x0m_proc_init(struct intel8x0m *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) snd_card_ro_proc_new(chip->card, "intel8x0m", chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) snd_intel8x0m_proc_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static int snd_intel8x0m_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct intel8x0m *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return snd_intel8x0m_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct ich_reg_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) unsigned int int_sta_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static int snd_intel8x0m_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) unsigned long device_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct intel8x0m **r_intel8x0m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct intel8x0m *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) unsigned int int_sta_masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct ichdev *ichdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .dev_free = snd_intel8x0m_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static const struct ich_reg_info intel_regs[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) { ICH_MIINT, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) { ICH_MOINT, 0x10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) const struct ich_reg_info *tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) *r_intel8x0m = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if ((err = pci_enable_device(pci)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (chip == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) spin_lock_init(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) chip->device_type = device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) chip->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if ((err = pci_request_regions(pci, card->shortname)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (device_type == DEVICE_ALI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /* ALI5455 has no ac97 region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) chip->bmaddr = pci_iomap(pci, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) goto port_inited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) chip->addr = pci_iomap(pci, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) chip->addr = pci_iomap(pci, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (!chip->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) dev_err(card->dev, "AC'97 space ioremap problem\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) snd_intel8x0m_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) chip->bmaddr = pci_iomap(pci, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) chip->bmaddr = pci_iomap(pci, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (!chip->bmaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) dev_err(card->dev, "Controller space ioremap problem\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) snd_intel8x0m_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) port_inited:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /* initialize offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) chip->bdbars_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) tbl = intel_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) for (i = 0; i < chip->bdbars_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ichdev = &chip->ichd[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) ichdev->ichd = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) ichdev->reg_offset = tbl[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) ichdev->int_sta_mask = tbl[i].int_sta_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (device_type == DEVICE_SIS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /* SiS 7013 swaps the registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ichdev->roff_sr = ICH_REG_OFF_PICB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) ichdev->roff_picb = ICH_REG_OFF_SR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) ichdev->roff_sr = ICH_REG_OFF_SR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) ichdev->roff_picb = ICH_REG_OFF_PICB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (device_type == DEVICE_ALI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ichdev->ali_slot = (ichdev->reg_offset - 0x40) / 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /* SIS7013 handles the pcm data in bytes, others are in words */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) chip->pcm_pos_shift = (device_type == DEVICE_SIS) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /* allocate buffer descriptor lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* the start of each lists must be aligned to 8 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) &chip->bdbars) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) snd_intel8x0m_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /* tables must be aligned to 8 bytes here, but the kernel pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) are much bigger, so we don't care (on i386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) int_sta_masks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) for (i = 0; i < chip->bdbars_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) ichdev = &chip->ichd[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ichdev->bdbar = ((__le32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) int_sta_masks |= ichdev->int_sta_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) chip->int_sta_reg = ICH_REG_GLOB_STA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) chip->int_sta_mask = int_sta_masks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if ((err = snd_intel8x0m_chip_init(chip, 1)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) snd_intel8x0m_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) snd_intel8x0m_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) snd_intel8x0m_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) *r_intel8x0m = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static struct shortname_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) const char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) } shortnames[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) { PCI_DEVICE_ID_INTEL_82801AA_6, "Intel 82801AA-ICH" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) { PCI_DEVICE_ID_INTEL_82801AB_6, "Intel 82901AB-ICH0" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) { PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) { PCI_DEVICE_ID_INTEL_440MX_6, "Intel 440MX" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) { PCI_DEVICE_ID_INTEL_82801CA_6, "Intel 82801CA-ICH3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) { PCI_DEVICE_ID_INTEL_82801DB_6, "Intel 82801DB-ICH4" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) { PCI_DEVICE_ID_INTEL_82801EB_6, "Intel ICH5" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) { PCI_DEVICE_ID_INTEL_ICH6_17, "Intel ICH6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) { PCI_DEVICE_ID_INTEL_ICH7_19, "Intel ICH7" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) { 0x7446, "AMD AMD768" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) { PCI_DEVICE_ID_SI_7013, "SiS SI7013" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) { PCI_DEVICE_ID_NVIDIA_MCP1_MODEM, "NVidia nForce" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) { 0x746e, "AMD AMD8111" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) { 0x5455, "ALi M5455" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static int snd_intel8x0m_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) struct intel8x0m *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct shortname_table *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) strcpy(card->driver, "ICH-MODEM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) strcpy(card->shortname, "Intel ICH");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) for (name = shortnames; name->id; name++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (pci->device == name->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) strcpy(card->shortname, name->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) strcat(card->shortname," Modem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if ((err = snd_intel8x0m_create(card, pci, pci_id->driver_data, &chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) card->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if ((err = snd_intel8x0m_mixer(chip, ac97_clock)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if ((err = snd_intel8x0m_pcm(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) snd_intel8x0m_proc_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) sprintf(card->longname, "%s at irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) card->shortname, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if ((err = snd_card_register(card)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static void snd_intel8x0m_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static struct pci_driver intel8x0m_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) .id_table = snd_intel8x0m_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) .probe = snd_intel8x0m_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .remove = snd_intel8x0m_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) .pm = INTEL8X0M_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) module_pci_driver(intel8x0m_driver);