{ 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 },
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;
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) {
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;
}
{
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;
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;
}
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
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);
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));
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) {
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
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;
}
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) {
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;
}
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)
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