patch-2.4.10 linux/drivers/sound/ac97_codec.c
Next file: linux/drivers/sound/ad1848.c
Previous file: linux/drivers/sound/ac97.h
Back to the patch index
Back to the overall index
- Lines: 94
- Date:
Fri Sep 7 09:28:37 2001
- Orig file:
v2.4.9/linux/drivers/sound/ac97_codec.c
- Orig date:
Mon Aug 27 12:41:45 2001
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
@@ -104,6 +104,7 @@
{0x41445303, "Analog Devices AD1819", &null_ops},
{0x41445340, "Analog Devices AD1881", &null_ops},
{0x41445348, "Analog Devices AD1881A", &null_ops},
+ {0x41445360, "Analog Devices AD1885", &default_ops},
{0x41445460, "Analog Devices AD1885", &default_ops},
{0x414B4D00, "Asahi Kasei AK4540", &null_ops},
{0x414B4D01, "Asahi Kasei AK4542", &null_ops},
@@ -937,3 +938,85 @@
EXPORT_SYMBOL(ac97_read_proc);
EXPORT_SYMBOL(ac97_probe_codec);
+
+/*
+ * AC97 library support routines
+ */
+
+/**
+ * ac97_set_dac_rate - set codec rate adaption
+ * @codec: ac97 code
+ * @rate: rate in hertz
+ *
+ * Set the DAC rate. Assumes the codec supports VRA. The caller is
+ * expected to have checked this little detail.
+ */
+
+unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate)
+{
+ unsigned int new_rate = rate;
+ u32 dacp;
+ u32 mast_vol, phone_vol, mono_vol, pcm_vol;
+ u32 mute_vol = 0x8000; /* The mute volume? */
+
+ if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE))
+ {
+ /* Mute several registers */
+ mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);
+ mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);
+ phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);
+ pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);
+ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);
+ codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);
+ codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);
+ codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);
+
+ /* Power down the DAC */
+ dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);
+ /* Power it back up */
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+
+ /* Restore volumes */
+ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);
+ codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);
+ codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);
+ codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);
+ }
+ return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_dac_rate);
+
+/**
+ * ac97_set_adc_rate - set codec rate adaption
+ * @codec: ac97 code
+ * @rate: rate in hertz
+ *
+ * Set the ADC rate. Assumes the codec supports VRA. The caller is
+ * expected to have checked this little detail.
+ */
+
+unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate)
+{
+ unsigned int new_rate = rate;
+ u32 dacp;
+
+ if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE))
+ {
+ /* Power down the ADC */
+ dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);
+ /* Power it back up */
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+ }
+ return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_adc_rate);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)