Update of /cvsroot/alsa/alsa-kernel/pci/ac97
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25233/ac97

Modified Files:
        ac97_codec.c ac97_pcm.c 
Log Message:
- fixed the possibl ac97 register cache mismatch.
- added the detection of spdif sample rates.










Index: ac97_codec.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ac97/ac97_codec.c,v
retrieving revision 1.125
retrieving revision 1.126
diff -u -r1.125 -r1.126
--- ac97_codec.c        29 Mar 2004 07:05:00 -0000      1.125
+++ ac97_codec.c        4 Apr 2004 16:03:58 -0000       1.126
@@ -299,6 +299,16 @@
        return ac97->bus->read(ac97, reg);
 }
 
+/* read a register - return the cached value if already read */
+static inline unsigned short snd_ac97_read_cache(ac97_t *ac97, unsigned short reg)
+{
+       if (! test_bit(reg, ac97->reg_accessed)) {
+               ac97->regs[reg] = ac97->bus->read(ac97, reg);
+               // set_bit(reg, ac97->reg_accessed);
+       }
+       return ac97->regs[reg];
+}
+
 /**
  * snd_ac97_write_cache - write a value on the given register and update the cache
  * @ac97: the ac97 instance
@@ -370,7 +380,7 @@
        if (!snd_ac97_valid_reg(ac97, reg))
                return -EINVAL;
        spin_lock(&ac97->reg_lock);
-       old = ac97->regs[reg];
+       old = snd_ac97_read_cache(ac97, reg);
        new = (old & ~mask) | value;
        change = old != new;
        if (change) {
@@ -385,25 +395,26 @@
 static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned short 
mask, unsigned short value)
 {
        int change;
-       unsigned short old, new;
+       unsigned short old, new, cfg;
 
        down(&ac97->spec.ad18xx.mutex);
        spin_lock(&ac97->reg_lock);
        old = ac97->spec.ad18xx.pcmreg[codec];
        new = (old & ~mask) | value;
+       cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
        change = old != new;
        if (change) {
                ac97->spec.ad18xx.pcmreg[codec] = new;
                spin_unlock(&ac97->reg_lock);
                /* select single codec */
                ac97->bus->write(ac97, AC97_AD_SERIAL_CFG,
-                                (ac97->regs[AC97_AD_SERIAL_CFG] & ~0x7000) |
+                                (cfg & ~0x7000) |
                                 ac97->spec.ad18xx.unchained[codec] | 
ac97->spec.ad18xx.chained[codec]);
                /* update PCM bits */
                ac97->bus->write(ac97, AC97_PCM, new);
                /* select all codecs */
                ac97->bus->write(ac97, AC97_AD_SERIAL_CFG,
-                                ac97->regs[AC97_AD_SERIAL_CFG] | 0x7000);
+                                cfg | 0x7000);
        } else
                spin_unlock(&ac97->reg_lock);
        up(&ac97->spec.ad18xx.mutex);
@@ -435,7 +446,7 @@
        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
        unsigned short val;
        
-       val = ac97->regs[AC97_REC_SEL];
+       val = snd_ac97_read_cache(ac97, AC97_REC_SEL);
        ucontrol->value.enumerated.item[0] = (val >> 8) & 7;
        ucontrol->value.enumerated.item[1] = (val >> 0) & 7;
        return 0;
@@ -493,7 +504,7 @@
        int shift = (kcontrol->private_value >> 8) & 0xff;
        int invert = (kcontrol->private_value >> 24) & 0xff;
        
-       val = (ac97->regs[reg] >> shift) & 1;
+       val = (snd_ac97_read_cache(ac97, reg) >> shift) & 1;
        if (invert)
                val ^= 1;
        ucontrol->value.enumerated.item[0] = val;
@@ -535,7 +546,7 @@
        int mask = (kcontrol->private_value >> 16) & 0xff;
        int invert = (kcontrol->private_value >> 24) & 0xff;
        
-       ucontrol->value.integer.value[0] = (ac97->regs[reg] >> shift) & mask;
+       ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> shift) & 
mask;
        if (invert)
                ucontrol->value.integer.value[0] = mask - 
ucontrol->value.integer.value[0];
        return 0;
@@ -582,8 +593,8 @@
        int invert = (kcontrol->private_value >> 24) & 0xff;
        
        spin_lock(&ac97->reg_lock);
-       ucontrol->value.integer.value[0] = (ac97->regs[reg] >> shift_left) & mask;
-       ucontrol->value.integer.value[1] = (ac97->regs[reg] >> shift_right) & mask;
+       ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> 
shift_left) & mask;
+       ucontrol->value.integer.value[1] = (snd_ac97_read_cache(ac97, reg) >> 
shift_right) & mask;
        spin_unlock(&ac97->reg_lock);
        if (invert) {
                ucontrol->value.integer.value[0] = mask - 
ucontrol->value.integer.value[0];
@@ -796,7 +807,7 @@
                                               AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
                                               v);
        } else {
-               unsigned short extst = ac97->regs[AC97_EXTENDED_STATUS];
+               unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
                snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* 
turn off */
 
                change |= snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val);
@@ -822,13 +833,13 @@
        mask <<= shift;
        value <<= shift;
        spin_lock(&ac97->reg_lock);
-       old = ac97->regs[reg];
+       old = snd_ac97_read_cache(ac97, reg);
        new = (old & ~mask) | value;
        spin_unlock(&ac97->reg_lock);
 
        if (old != new) {
                int change;
-               unsigned short extst = ac97->regs[AC97_EXTENDED_STATUS];
+               unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
                snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* 
turn off */
                change = snd_ac97_update_bits(ac97, reg, mask, value);
                if (extst & AC97_EA_SPDIF)
@@ -1572,6 +1583,26 @@
        *r_result = result;
 }
 
+/* check AC97_SPDIF register to accept which sample rates */
+static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97)
+{
+       unsigned int result = 0;
+       int i;
+       static unsigned short ctl_bits[] = {
+               AC97_SC_SPSR_44K, AC97_SC_SPSR_32K, AC97_SC_SPSR_48K
+       };
+       static unsigned int rate_bits[] = {
+               SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_32000, SNDRV_PCM_RATE_48000
+       };
+
+       for (i = 0; i < (int)ARRAY_SIZE(ctl_bits); i++) {
+               snd_ac97_update_bits(ac97, AC97_SPDIF, AC97_SC_SPSR_MASK, ctl_bits[i]);
+               if ((snd_ac97_read(ac97, AC97_SPDIF) & AC97_SC_SPSR_MASK) == 
ctl_bits[i])
+                       result |= rate_bits[i];
+       }
+       return result;
+}
+
 void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem)
 {
        const ac97_codec_id_t *pid;
@@ -1889,9 +1920,7 @@
                else if (ac97->id == AC97_ID_CM9739)
                        ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000;
                else
-                       ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000 |
-                                               SNDRV_PCM_RATE_44100 |
-                                               SNDRV_PCM_RATE_32000;
+                       ac97->rates[AC97_RATES_SPDIF] = 
snd_ac97_determine_spdif_rates(ac97);
        }
        if (ac97->ext_id & AC97_EI_VRM) {       /* MIC VRA support */
                snd_ac97_determine_rates(ac97, AC97_PCM_MIC_ADC_RATE, 0, 
&ac97->rates[AC97_RATES_MIC_ADC]);

Index: ac97_pcm.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ac97/ac97_pcm.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ac97_pcm.c  29 Mar 2004 06:58:36 -0000      1.12
+++ ac97_pcm.c  4 Apr 2004 16:03:59 -0000       1.13
@@ -210,7 +210,7 @@
        }
 
        spin_lock(&ac97->reg_lock);
-       old = ac97->regs[reg] & mask;
+       old = snd_ac97_read(ac97, reg) & mask;
        spin_unlock(&ac97->reg_lock);
        if (old != bits) {
                snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to