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

Reply via email to