Update of /cvsroot/alsa/alsa-kernel/pci In directory sc8-pr-cvs1:/tmp/cvs-serv21327/pci
Modified Files: intel8x0.c Log Message: Moved AC97 slot allocation from intel8x0 to ac97_pcm.c. Index: intel8x0.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/pci/intel8x0.c,v retrieving revision 1.96 retrieving revision 1.97 diff -u -r1.96 -r1.97 --- intel8x0.c 23 Oct 2003 14:34:52 -0000 1.96 +++ intel8x0.c 18 Nov 2003 11:38:40 -0000 1.97 @@ -366,9 +366,8 @@ unsigned int roff_picb; unsigned int int_sta_mask; /* interrupt status mask */ unsigned int ali_slot; /* ALI DMA slot */ - ac97_t *ac97; - unsigned short ac97_rate_regs[3]; - int ac97_rates_idx; + struct ac97_pcm *pcm; + int pcm_open_flag; } ichdev_t; typedef struct _snd_intel8x0 intel8x0_t; @@ -887,11 +886,28 @@ static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params) { - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + ichdev_t *ichdev = get_ichdev(substream); + int err; + + err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + if (err < 0) + return err; + if (ichdev->pcm_open_flag) + snd_ac97_pcm_close(ichdev->pcm); + err = snd_ac97_pcm_open(ichdev->pcm, params_rate(hw_params), + params_channels(hw_params), + ichdev->pcm->r[0].slots); + if (err >= 0) + ichdev->pcm_open_flag = 1; + return err; } static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream) { + ichdev_t *ichdev = get_ichdev(substream); + + if (ichdev->pcm_open_flag) + snd_ac97_pcm_close(ichdev->pcm); return snd_pcm_lib_free_pages(substream); } @@ -934,7 +950,6 @@ intel8x0_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ichdev_t *ichdev = get_ichdev(substream); - int i; ichdev->physbuf = runtime->dma_addr; ichdev->size = snd_pcm_lib_buffer_bytes(substream); @@ -944,14 +959,9 @@ snd_intel8x0_setup_multi_channels(chip, runtime->channels); spin_unlock(&chip->reg_lock); } - if (ichdev->ac97) { - for (i = 0; i < 3; i++) - if (ichdev->ac97_rate_regs[i]) - snd_ac97_set_rate(ichdev->ac97, ichdev->ac97_rate_regs[i], runtime->rate); - /* FIXME: hack to enable spdif support */ - if (ichdev->ichd == ICHD_PCMOUT && chip->device_type == DEVICE_SIS) - snd_ac97_set_rate(ichdev->ac97, AC97_SPDIF, runtime->rate); - } + /* FIXME: hack to enable spdif support */ + if (ichdev->ichd == ICHD_PCMOUT && chip->device_type == DEVICE_SIS) + snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF, runtime->rate); snd_intel8x0_setup_periods(chip, ichdev); return 0; } @@ -1030,13 +1040,11 @@ ichdev->substream = substream; runtime->hw = snd_intel8x0_stream; - if (ichdev->ac97 && ichdev->ac97_rates_idx >= 0) { - runtime->hw.rates = ichdev->ac97->rates[ichdev->ac97_rates_idx]; - for (i = 0; i < ARRAY_SIZE(rates); i++) { - if (runtime->hw.rates & (1 << i)) { - runtime->hw.rate_min = rates[i]; - break; - } + runtime->hw.rates = ichdev->pcm->rates; + for (i = 0; i < ARRAY_SIZE(rates); i++) { + if (runtime->hw.rates & (1 << i)) { + runtime->hw.rate_min = rates[i]; + break; } } if (chip->device_type == DEVICE_SIS) { @@ -1512,7 +1520,7 @@ rec = tbl + i; if (i > 0 && rec->ac97_idx) { /* activate PCM only when associated AC'97 codec */ - if (! chip->ichd[rec->ac97_idx].ac97) + if (! chip->ichd[rec->ac97_idx].pcm) continue; } err = snd_intel8x0_pcm1(chip, device, rec); @@ -1542,44 +1550,67 @@ chip->ac97[ac97->num] = NULL; } -struct _ac97_rate_regs { - unsigned int ichd; - unsigned short regs[3]; - short rates_idx; -}; - -static struct _ac97_rate_regs intel_ac97_rate_regs[] __devinitdata = { - { ICHD_PCMOUT, { AC97_PCM_FRONT_DAC_RATE, AC97_PCM_SURR_DAC_RATE, AC97_PCM_LFE_DAC_RATE }, AC97_RATES_FRONT_DAC }, - { ICHD_PCMIN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, - { ICHD_MIC, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, - { ICHD_MIC2, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, - { ICHD_PCM2IN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, - { ICHD_SPBAR, { AC97_SPDIF, 0, 0 }, AC97_RATES_SPDIF }, -}; - -static struct _ac97_rate_regs nforce_ac97_rate_regs[] __devinitdata = { - { NVD_PCMOUT, { AC97_PCM_FRONT_DAC_RATE, AC97_PCM_SURR_DAC_RATE, AC97_PCM_LFE_DAC_RATE }, AC97_RATES_FRONT_DAC }, - { NVD_PCMIN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, - { NVD_MIC, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, - { NVD_SPBAR, { AC97_SPDIF, AC97_PCM_FRONT_DAC_RATE, 0 }, -1 }, /* spdif is 48k only */ -}; - -static struct _ac97_rate_regs ali_ac97_rate_regs[] __devinitdata = { -#if 0 /* FIXME: my test board doens't work well with VRA... */ - { ALID_PCMOUT, { AC97_PCM_FRONT_DAC_RATE, AC97_PCM_SURR_DAC_RATE, AC97_PCM_LFE_DAC_RATE }, AC97_RATES_FRONT_DAC }, - { ALID_PCMIN, { AC97_PCM_LR_ADC_RATE, 0, 0 }, AC97_RATES_ADC }, - { ALID_MIC, { AC97_PCM_MIC_ADC_RATE, 0, 0 }, AC97_RATES_MIC_ADC }, - { ALID_AC97SPDIFOUT, { AC97_SPDIF, 0, 0 }, AC97_RATES_SPDIF }, - { ALID_SPDIFOUT, { 0, 0, 0 }, -1 }, - { ALID_SPDIFIN, { 0, 0, 0 }, -1 }, -#else - { ALID_PCMOUT, { AC97_PCM_FRONT_DAC_RATE }, -1 }, - { ALID_PCMIN, { AC97_PCM_LR_ADC_RATE }, -1 }, - { ALID_MIC, { AC97_PCM_MIC_ADC_RATE }, -1 }, - { ALID_AC97SPDIFOUT, { AC97_SPDIF }, -1 }, - { ALID_SPDIFOUT, { }, -1 }, - { ALID_SPDIFIN, { }, -1 }, -#endif +static struct ac97_pcm ac97_pcm_defs[] __devinitdata = { + /* front PCM */ + { + .exclusive = 1, + .r = { { + .slots = (1 << AC97_SLOT_PCM_LEFT) | + (1 << AC97_SLOT_PCM_RIGHT) | + (1 << AC97_SLOT_PCM_CENTER) | + (1 << AC97_SLOT_PCM_SLEFT) | + (1 << AC97_SLOT_PCM_SRIGHT) | + (1 << AC97_SLOT_LFE) + } + } + }, + /* PCM IN #1 */ + { + .stream = 1, + .exclusive = 1, + .r = { { + .slots = (1 << AC97_SLOT_PCM_LEFT) | + (1 << AC97_SLOT_PCM_RIGHT) + } + } + }, + /* MIC IN #1 */ + { + .stream = 1, + .exclusive = 1, + .r = { { + .slots = (1 << AC97_SLOT_MIC) + } + } + }, + /* S/PDIF PCM */ + { + .exclusive = 1, + .r = { { + .slots = (1 << AC97_SLOT_SPDIF_LEFT2) | + (1 << AC97_SLOT_SPDIF_RIGHT2) + } + } + }, + /* PCM IN #2 */ + { + .stream = 1, + .exclusive = 1, + .r = { { + .slots = (1 << AC97_SLOT_PCM_LEFT) | + (1 << AC97_SLOT_PCM_RIGHT) + } + } + }, + /* MIC IN #2 */ + { + .stream = 1, + .exclusive = 1, + .r = { { + .slots = (1 << AC97_SLOT_MIC) + } + } + }, }; static struct ac97_quirk ac97_quirks[] __devinitdata = { @@ -1657,38 +1688,25 @@ static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock) { - ac97_bus_t bus; + ac97_bus_t bus, *pbus; ac97_t ac97, *x97; - ichdev_t *ichdev; int err; - unsigned int i, num, codecs, _codecs; + unsigned int i, codecs; unsigned int glob_sta = 0; - struct _ac97_rate_regs *tbl; int spdif_idx = -1; /* disabled */ switch (chip->device_type) { case DEVICE_NFORCE: - tbl = nforce_ac97_rate_regs; spdif_idx = NVD_SPBAR; break; case DEVICE_ALI: - tbl = ali_ac97_rate_regs; spdif_idx = ALID_AC97SPDIFOUT; break; default: - tbl = intel_ac97_rate_regs; if (chip->device_type == DEVICE_INTEL_ICH4) spdif_idx = ICHD_SPBAR; break; }; - for (i = 0; i < chip->bdbars_count; i++) { - struct _ac97_rate_regs *aregs = tbl + i; - ichdev = &chip->ichd[aregs->ichd]; - ichdev->ac97_rate_regs[0] = aregs->regs[0]; - ichdev->ac97_rate_regs[1] = aregs->regs[1]; - ichdev->ac97_rate_regs[2] = aregs->regs[2]; - ichdev->ac97_rates_idx = aregs->rates_idx; - } chip->in_ac97_init = 1; memset(&bus, 0, sizeof(bus)); @@ -1725,6 +1743,7 @@ } else { codecs = glob_sta & ICH_SCR ? 2 : 1; } + bus.vra = 1; } else { bus.write = snd_intel8x0_ali_codec_write; bus.read = snd_intel8x0_ali_codec_read; @@ -1739,11 +1758,14 @@ iputdword(chip, ICHREG(ALI_RTSR), reg | 0x40); udelay(1); } + /* FIXME: my test board doens't work well with VRA... */ + bus.vra = 0; } - if ((err = snd_ac97_bus(chip->card, &bus, &chip->ac97_bus)) < 0) + if ((err = snd_ac97_bus(chip->card, &bus, &pbus)) < 0) goto __err; + chip->ac97_bus = pbus; ac97.pci = chip->pci; - if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &x97)) < 0) { + if ((err = snd_ac97_mixer(pbus, &ac97, &x97)) < 0) { __err: /* clear the cold-reset bit for the next chance */ if (chip->device_type != DEVICE_ALI) @@ -1753,130 +1775,54 @@ chip->ac97[0] = x97; /* tune up the primary codec */ snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks); - /* the following three entries are common among all devices */ - chip->ichd[ICHD_PCMOUT].ac97 = x97; - chip->ichd[ICHD_PCMIN].ac97 = x97; - if (x97->ext_id & AC97_EI_VRM) - chip->ichd[ICHD_MIC].ac97 = x97; - /* spdif */ - if ((x97->ext_id & AC97_EI_SPDIF) && spdif_idx >= 0) - chip->ichd[spdif_idx].ac97 = x97; - /* make sure, that we have DACs at right slot for rev2.2 */ - if (ac97_is_rev22(x97)) - snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 0); - /* AnalogDevices CNR boards uses special codec chaining */ - /* skip standard test method for secondary codecs in this case */ - if (x97->flags & AC97_AD_MULTI) - codecs = 1; - if (codecs < 2) - goto __skip_secondary; - for (i = 1, num = 1, _codecs = codecs; num < _codecs; num++) { - ac97.num = num; - if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &x97)) < 0) { - snd_printk("Unable to initialize codec #%i [device = %i, GLOB_STA = 0x%x]\n", i, chip->device_type, glob_sta); - codecs--; - continue; - } - chip->ac97[i++] = x97; - if (!ac97_is_audio(x97)) - continue; - switch (chip->device_type) { - case DEVICE_INTEL_ICH4: - if (chip->ichd[ICHD_PCM2IN].ac97 == NULL) - chip->ichd[ICHD_PCM2IN].ac97 = x97; - if (x97->ext_id & AC97_EI_VRM) { - if (chip->ichd[ICHD_MIC].ac97 == NULL) - chip->ichd[ICHD_MIC].ac97 = x97; - else if (chip->ichd[ICHD_MIC2].ac97 == NULL && - chip->ichd[ICHD_PCM2IN].ac97 == x97) - chip->ichd[ICHD_MIC2].ac97 = x97; - } - break; - default: - if (x97->ext_id & AC97_EI_VRM) { - if (chip->ichd[ICHD_MIC].ac97 == NULL) - chip->ichd[ICHD_MIC].ac97 = x97; - } - break; - } - if ((x97->ext_id & AC97_EI_SPDIF) && spdif_idx >= 0) { - if (chip->ichd[spdif_idx].ac97 == NULL) - chip->ichd[spdif_idx].ac97 = x97; - } + /* enable separate SDINs for ICH4 */ + if (chip->device_type == DEVICE_INTEL_ICH4) + pbus->isdin = 1; + /* find the available PCM streams */ + i = ARRAY_SIZE(ac97_pcm_defs); + if (chip->device_type != DEVICE_INTEL_ICH4) + i -= 2; /* do not allocate PCM2IN and MIC2 */ + if (spdif_idx < 0) + i--; /* do not allocate S/PDIF */ + err = snd_ac97_pcm_assign(pbus, ARRAY_SIZE(ac97_pcm_defs), ac97_pcm_defs); + if (err < 0) + goto __err; + chip->ichd[ICHD_PCMOUT].pcm = &pbus->pcms[0]; + chip->ichd[ICHD_PCMIN].pcm = &pbus->pcms[1]; + chip->ichd[ICHD_MIC].pcm = &pbus->pcms[2]; + if (spdif_idx >= 0) + chip->ichd[spdif_idx].pcm = &pbus->pcms[3]; + if (chip->device_type == DEVICE_INTEL_ICH4) { + chip->ichd[ICHD_PCM2IN].pcm = &pbus->pcms[4]; + chip->ichd[ICHD_MIC2].pcm = &pbus->pcms[5]; } - - __skip_secondary: + /* enable separate SDINs for ICH4 */ if (chip->device_type == DEVICE_INTEL_ICH4) { + struct ac97_pcm *pcm = chip->ichd[ICHD_PCM2IN].pcm; u8 tmp = igetbyte(chip, ICHREG(SDM)); tmp &= ~(ICH_DI2L_MASK|ICH_DI1L_MASK); - if (chip->ichd[ICHD_PCM2IN].ac97) { + if (pcm) { tmp |= ICH_SE; /* steer enable for multiple SDINs */ tmp |= chip->ac97_sdin[0] << ICH_DI1L_SHIFT; - tmp |= chip->ac97_sdin[chip->ichd[ICHD_PCM2IN].ac97->num] << ICH_DI2L_SHIFT; + for (i = 1; i < 4; i++) { + if (pcm->r[0].codec[i]) { + tmp |= chip->ac97_sdin[pcm->r[0].codec[1]->num] << ICH_DI2L_SHIFT; + break; + } + } } else { - tmp &= ~ICH_SE; + tmp &= ~ICH_SE; /* steer disable */ } iputbyte(chip, ICHREG(SDM), tmp); } - for (i = 0; i < codecs; i++) { - x97 = chip->ac97[i]; - if (!ac97_is_audio(x97)) - continue; - if (x97->scaps & AC97_SCAP_SURROUND_DAC) - chip->multi4 = 1; - } - for (i = 0; i < codecs && chip->multi4; i++) { - x97 = chip->ac97[i]; - if (!ac97_is_audio(x97)) - continue; - if (x97->scaps & AC97_SCAP_CENTER_LFE_DAC) + if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) { + chip->multi4 = 1; + if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE)) chip->multi6 = 1; } - if (chip->device_type == DEVICE_ALI && chip->ac97[1]) { - /* set secondary codec id */ - iputdword(chip, ICHREG(ALI_SSR), - (igetdword(chip, ICHREG(ALI_SSR)) & ~ICH_ALI_SS_SEC_ID) | - (chip->ac97[1]->addr << 5)); - } - if (codecs > 1 && !chip->multi6) { - /* assign right slots for rev2.2 codecs */ - i = 1; - for ( ; i < codecs && !chip->multi4; i++) { - x97 = chip->ac97[i]; - if (!ac97_is_audio(x97)) - continue; - if (ac97_is_rev22(x97)) { - snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 1); - chip->multi4 = 1; - } - } - for ( ; i < codecs && chip->multi4; i++) { - x97 = chip->ac97[i]; - if (!ac97_is_audio(x97)) - continue; - if (ac97_is_rev22(x97)) { - snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 2); - chip->multi6 = 1; - break; - } - } - /* ok, some older codecs might support only AMAP */ - if (!chip->multi4) { - int cnums = 0; - for (i = 1; i < codecs; i++) { - x97 = chip->ac97[i]; - if (!ac97_is_audio(x97)) - continue; - if (ac97_can_amap(x97)) { - if (x97->addr > 0) - cnums++; - } - } - if (cnums >= 2) - chip->multi6 = 1; - if (cnums >= 1) - chip->multi4 = 1; - } + if (chip->device_type == DEVICE_NFORCE) { + /* 48kHz only */ + chip->ichd[spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000; } chip->in_ac97_init = 0; return 0; ------------------------------------------------------- This SF. Net email is sponsored by: GoToMyPC GoToMyPC is the fast, easy and secure way to access your computer from any Web browser or wireless device. Click here to Try it Free! https://www.gotomypc.com/tr/OSDN/AW/Q4_2003/t/g22lp?Target=mm/g22lp.tmpl _______________________________________________ Alsa-cvslog mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-cvslog