This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / sound / pci / ac97 / ac97_codec.c
index b5c0320..b88a198 100644 (file)
@@ -118,12 +118,9 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
 { 0x414c4770, 0xfffffff0, "ALC203",            NULL,           NULL },
 { 0x434d4941, 0xffffffff, "CMI9738",           patch_cm9738,   NULL },
 { 0x434d4961, 0xffffffff, "CMI9739",           patch_cm9739,   NULL },
-{ 0x434d4978, 0xffffffff, "CMI9761",           patch_cm9761,   NULL },
-{ 0x434d4982, 0xffffffff, "CMI9761",           patch_cm9761,   NULL },
-{ 0x434d4983, 0xffffffff, "CMI9761",           patch_cm9761,   NULL },
 { 0x43525900, 0xfffffff8, "CS4297",            NULL,           NULL },
 { 0x43525910, 0xfffffff8, "CS4297A",           patch_cirrus_spdif,     NULL },
-{ 0x43525920, 0xfffffff8, "CS4298",            patch_cirrus_spdif,             NULL },
+{ 0x43525920, 0xfffffff8, "CS4294/4298",       NULL,           NULL },
 { 0x43525928, 0xfffffff8, "CS4294",            NULL,           NULL },
 { 0x43525930, 0xfffffff8, "CS4299",            patch_cirrus_cs4299,    NULL },
 { 0x43525948, 0xfffffff8, "CS4201",            NULL,           NULL },
@@ -752,14 +749,6 @@ AC97_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
 static const snd_kcontrol_new_t snd_ac97_control_eapd =
 AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1);
 
-/* change the existing EAPD control as inverted */
-static void set_inv_eapd(ac97_t *ac97, snd_kcontrol_t *kctl)
-{
-       kctl->private_value = AC97_SINGLE_VALUE(AC97_POWERDOWN, 15, 1, 0);
-       snd_ac97_update_bits(ac97, AC97_POWERDOWN, (1<<15), (1<<15)); /* EAPD up */
-       ac97->scaps |= AC97_SCAP_INV_EAPD;
-}
-
 static int snd_ac97_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
@@ -1570,7 +1559,7 @@ static int snd_ac97_mixer_build(ac97_t * ac97)
                        return err;
        }
 
-       snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, ~AC97_GP_DRSS_MASK, 0x0000);
+       snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x0000);
 
        /* build 3D controls */
        if (ac97->build_ops && ac97->build_ops->build_3d) {
@@ -1621,12 +1610,7 @@ static int snd_ac97_mixer_build(ac97_t * ac97)
                        return err;
 
        if (snd_ac97_try_bit(ac97, AC97_POWERDOWN, 15)) {
-               kctl = snd_ac97_cnew(&snd_ac97_control_eapd, ac97);
-               if (! kctl)
-                       return -ENOMEM;
-               if (ac97->scaps & AC97_SCAP_INV_EAPD)
-                       set_inv_eapd(ac97, kctl);
-               if ((err = snd_ctl_add(card, kctl)) < 0)
+               if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_eapd, ac97))) < 0)
                        return err;
        }
 
@@ -1662,9 +1646,6 @@ static void snd_ac97_determine_rates(ac97_t *ac97, int reg, int shadow_reg, unsi
 {
        unsigned int result = 0;
 
-       if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE)
-               snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
-                                    AC97_EA_DRA, 0);
        /* test a non-standard rate */
        if (snd_ac97_test_rate(ac97, reg, shadow_reg, 11000))
                result |= SNDRV_PCM_RATE_CONTINUOUS;
@@ -1683,23 +1664,6 @@ static void snd_ac97_determine_rates(ac97_t *ac97, int reg, int shadow_reg, unsi
                result |= SNDRV_PCM_RATE_44100;
        if (snd_ac97_test_rate(ac97, reg, shadow_reg, 48000))
                result |= SNDRV_PCM_RATE_48000;
-       if ((ac97->flags & AC97_DOUBLE_RATE) &&
-           reg == AC97_PCM_FRONT_DAC_RATE) {
-               /* test standard double rates */
-               snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
-                                    AC97_EA_DRA, AC97_EA_DRA);
-               if (snd_ac97_test_rate(ac97, reg, shadow_reg, 64000 / 2))
-                       result |= SNDRV_PCM_RATE_64000;
-               if (snd_ac97_test_rate(ac97, reg, shadow_reg, 88200 / 2))
-                       result |= SNDRV_PCM_RATE_88200;
-               if (snd_ac97_test_rate(ac97, reg, shadow_reg, 96000 / 2))
-                       result |= SNDRV_PCM_RATE_96000;
-               /* some codecs don't support variable double rates */
-               if (!snd_ac97_test_rate(ac97, reg, shadow_reg, 76100 / 2))
-                       result &= ~SNDRV_PCM_RATE_CONTINUOUS;
-               snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
-                                    AC97_EA_DRA, 0);
-       }
        *r_result = result;
 }
 
@@ -1762,22 +1726,6 @@ void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem)
        sprintf(name + strlen(name), " id %x", id & 0xff);
 }
 
-/**
- * snd_ac97_get_short_name - retrieve codec name
- * @ac97: the codec instance
- *
- * Returns the short identifying name of the codec.
- */
-const char *snd_ac97_get_short_name(ac97_t *ac97)
-{
-       const ac97_codec_id_t *pid;
-
-       for (pid = snd_ac97_codec_ids; pid->id; pid++)
-               if (pid->id == (ac97->id & pid->mask))
-                       return pid->name;
-       return "unknown codec";
-}
-
 
 /* wait for a while until registers are accessible after RESET
  * return 0 if ok, negative not ready
@@ -1785,10 +1733,9 @@ const char *snd_ac97_get_short_name(ac97_t *ac97)
 static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
 {
        unsigned long end_time;
-       unsigned short val;
-
        end_time = jiffies + timeout;
        do {
+               unsigned short ext_mid;
                
                /* use preliminary reads to settle the communication */
                snd_ac97_read(ac97, AC97_RESET);
@@ -1796,24 +1743,17 @@ static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
                snd_ac97_read(ac97, AC97_VENDOR_ID2);
                /* modem? */
                if (with_modem) {
-                       val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
-                       if (val != 0xffff && (val & 1) != 0)
-                               return 0;
-               }
-               if (ac97->scaps & AC97_SCAP_DETECT_BY_VENDOR) {
-                       /* probably only Xbox issue - all registers are read as zero */
-                       val = snd_ac97_read(ac97, AC97_VENDOR_ID1);
-                       if (val != 0 && val != 0xffff)
-                               return 0;
-               } else {
-                       /* because the PCM or MASTER volume registers can be modified,
-                        * the REC_GAIN register is used for tests
-                        */
-                       /* test if we can write to the record gain volume register */
-                       snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
-                       if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
+                       ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID);
+                       if (ext_mid != 0xffff && (ext_mid & 1) != 0)
                                return 0;
                }
+               /* because the PCM or MASTER volume registers can be modified,
+                * the REC_GAIN register is used for tests
+                */
+               /* test if we can write to the record gain volume register */
+               snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05);
+               if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
+                       return 0;
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout(1);
        } while (time_after_eq(end_time, jiffies));
@@ -2064,25 +2004,13 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
                ac97->addr = (ac97->ext_id & AC97_EI_ADDR_MASK) >> AC97_EI_ADDR_SHIFT;
        else
                ac97->addr = (ac97->ext_mid & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT;
-       if (ac97->ext_id & 0x0189) {    /* L/R, MIC, SDAC, LDAC VRA support */
-               reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
-               reg |= ac97->ext_id & 0x0189;
-               snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, reg);
-       }
-       if ((ac97->ext_id & AC97_EI_DRA) && bus->dra) {
-               /* Intel controllers require double rate data to be put in
-                * slots 7+8, so let's hope the codec supports it. */
-               snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
-               if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
-                       ac97->flags |= AC97_DOUBLE_RATE;
-       }
+       if (ac97->ext_id & 0x0189)      /* L/R, MIC, SDAC, LDAC VRA support */
+               snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, ac97->ext_id & 0x0189);
        if (ac97->ext_id & AC97_EI_VRA) {       /* VRA support */
                snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
                snd_ac97_determine_rates(ac97, AC97_PCM_LR_ADC_RATE, 0, &ac97->rates[AC97_RATES_ADC]);
        } else {
                ac97->rates[AC97_RATES_FRONT_DAC] = SNDRV_PCM_RATE_48000;
-               if (ac97->flags & AC97_DOUBLE_RATE)
-                       ac97->rates[AC97_RATES_FRONT_DAC] |= SNDRV_PCM_RATE_96000;
                ac97->rates[AC97_RATES_ADC] = SNDRV_PCM_RATE_48000;
        }
        if (ac97->ext_id & AC97_EI_SPDIF) {
@@ -2389,9 +2317,9 @@ int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *
 
 static int swap_headphone(ac97_t *ac97, int remove_master)
 {
-       if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
-               return -ENOENT;
        if (remove_master) {
+               if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
+                       return 0;
                snd_ac97_remove_ctl(ac97, "Master Playback", "Switch");
                snd_ac97_remove_ctl(ac97, "Master Playback", "Volume");
        } else
@@ -2402,9 +2330,9 @@ static int swap_headphone(ac97_t *ac97, int remove_master)
 
 static int swap_surround(ac97_t *ac97)
 {
-       if (snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch") ||
-           snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume"))
-               return -ENOENT;
+       /* FIXME: error checks.. */
+       snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch");
+       snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume");
        return 0;
 }
 
@@ -2435,15 +2363,6 @@ static int tune_alc_jack(ac97_t *ac97)
        return snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_alc_jack_detect, ac97));
 }
 
-static int tune_inv_eapd(ac97_t *ac97)
-{
-       snd_kcontrol_t *kctl = ctl_find(ac97, "External Amplifier", NULL);
-       if (! kctl)
-               return -ENOENT;
-       set_inv_eapd(ac97, kctl);
-       return 0;
-}
-
 static int apply_quirk(ac97_t *ac97, int quirk)
 {
        switch (quirk) {
@@ -2459,8 +2378,6 @@ static int apply_quirk(ac97_t *ac97, int quirk)
                return tune_ad_sharing(ac97);
        case AC97_TUNE_ALC_JACK:
                return tune_alc_jack(ac97);
-       case AC97_TUNE_INV_EAPD:
-               return tune_inv_eapd(ac97);
        }
        return -EINVAL;
 }
@@ -2496,8 +2413,6 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, int override)
                        continue;
                if ((! quirk->mask && quirk->device == ac97->subsystem_device) ||
                    quirk->device == (quirk->mask & ac97->subsystem_device)) {
-                       if (quirk->codec_id && quirk->codec_id != ac97->id)
-                               continue;
                        snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device);
                        result = apply_quirk(ac97, quirk->type);
                        if (result < 0)
@@ -2518,13 +2433,11 @@ EXPORT_SYMBOL(snd_ac97_read);
 EXPORT_SYMBOL(snd_ac97_write_cache);
 EXPORT_SYMBOL(snd_ac97_update);
 EXPORT_SYMBOL(snd_ac97_update_bits);
-EXPORT_SYMBOL(snd_ac97_get_short_name);
 EXPORT_SYMBOL(snd_ac97_bus);
 EXPORT_SYMBOL(snd_ac97_mixer);
 EXPORT_SYMBOL(snd_ac97_pcm_assign);
 EXPORT_SYMBOL(snd_ac97_pcm_open);
 EXPORT_SYMBOL(snd_ac97_pcm_close);
-EXPORT_SYMBOL(snd_ac97_pcm_double_rate_rules);
 EXPORT_SYMBOL(snd_ac97_tune_hardware);
 EXPORT_SYMBOL(snd_ac97_set_rate);
 #ifdef CONFIG_PM