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