Ignore:
Timestamp:
Jan 23, 2007, 10:34:32 PM (19 years ago)
Author:
vladest
Message:

Added missed files
Applied latest modifications of ALSA
Reworked sharing strategy between MMOS2 and UNIAUD API

Location:
GPL/trunk/alsa-kernel/pci/ac97
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • GPL/trunk/alsa-kernel/pci/ac97/ac97_codec.c

    r77 r86  
    3131#include <sound/core.h>
    3232#include <sound/pcm.h>
     33#include <sound/tlv.h>
    3334#include <sound/ac97_codec.h>
    3435#include <sound/asoundef.h>
     
    110111{ 0x41445374, 0xffffffff, "AD1981B",            patch_ad1981b,  NULL },
    111112{ 0x41445375, 0xffffffff, "AD1985",             patch_ad1985,   NULL },
    112 { 0x41445378, 0xffffffff, "AD1986",             patch_ad1985,   NULL },
     113{ 0x41445378, 0xffffffff, "AD1986",             patch_ad1986,   NULL },
    113114{ 0x414c4300, 0xffffff00, "ALC100,100P",        NULL,           NULL },
    114115{ 0x414c4710, 0xfffffff0, "ALC200,200P",        NULL,           NULL },
     
    128129{ 0x434d4961, 0xffffffff, "CMI9739",            patch_cm9739,   NULL },
    129130{ 0x434d4969, 0xffffffff, "CMI9780",            patch_cm9780,   NULL },
    130 { 0x434d4978, 0xffffffff, "CMI9761",            patch_cm9761,   NULL },
    131 { 0x434d4982, 0xffffffff, "CMI9761",            patch_cm9761,   NULL },
    132 { 0x434d4983, 0xffffffff, "CMI9761",            patch_cm9761,   NULL },
     131{ 0x434d4978, 0xffffffff, "CMI9761A",           patch_cm9761,   NULL },
     132{ 0x434d4982, 0xffffffff, "CMI9761B",           patch_cm9761,   NULL },
     133{ 0x434d4983, 0xffffffff, "CMI9761A+",          patch_cm9761,   NULL },
    133134{ 0x43525900, 0xfffffff8, "CS4297",             NULL,           NULL },
    134135{ 0x43525910, 0xfffffff8, "CS4297A",            patch_cirrus_spdif,     NULL },
     
    155156{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL,           NULL }, // only guess --jk
    156157{ 0x4e534331, 0xffffffff, "LM4549",             NULL,           NULL },
    157 { 0x4e534350, 0xffffffff, "LM4550",             NULL,           NULL },
    158158{ 0x4e534350, 0xffffffff, "LM4550",             patch_lm4550,   NULL }, // volume wrap fix
    159159{ 0x50534304, 0xffffffff, "UCB1400",            patch_ucb1400,  NULL },
     
    166166{ 0x56494161, 0xffffffff, "VIA1612A",           NULL,           NULL }, // modified ICE1232 with S/PDIF
    167167{ 0x56494170, 0xffffffff, "VIA1617A",           patch_vt1617a,  NULL }, // modified VT1616 with S/PDIF
     168{ 0x56494182, 0xffffffff, "VIA1618",            NULL,           NULL },
    168169{ 0x57454301, 0xffffffff, "W83971D",            NULL,           NULL },
    169170{ 0x574d4c00, 0xffffffff, "WM9701A",            NULL,           NULL },
     
    192193
    193194static void update_power_regs(struct snd_ac97 *ac97);
     195#ifdef CONFIG_SND_AC97_POWER_SAVE
     196#define ac97_is_power_save_mode(ac97) \
     197        ((ac97->scaps & AC97_SCAP_POWER_SAVE) && power_save)
     198#else
     199#define ac97_is_power_save_mode(ac97) 0
     200#endif
     201
    194202
    195203/*
     
    259267}
    260268
     269EXPORT_SYMBOL(snd_ac97_write);
     270
    261271/**
    262272 * snd_ac97_read - read a value from the given register
     
    276286        return ac97->bus->ops->read(ac97, reg);
    277287}
     288
     289EXPORT_SYMBOL(snd_ac97_read);
    278290
    279291/* read a register - return the cached value if already read */
     
    369381        unsigned short old, new;
    370382
    371         old = snd_ac97_read_cache(ac97, reg);
    372         new = (old & ~mask) | value;
     383        old = snd_ac97_read_cache(ac97, reg);
     384        new = (old & ~mask) | (value & mask);
    373385        change = old != new;
    374386        if (change) {
     
    386398
    387399        down(&ac97->page_mutex);
    388         old = ac97->spec.ad18xx.pcmreg[codec];
    389         new = (old & ~mask) | value;
     400        old = ac97->spec.ad18xx.pcmreg[codec];
     401        new = (old & ~mask) | (value & mask);
    390402        change = old != new;
    391403        if (change) {
     
    557569                        ac97->power_up &= ~(1 << (reg>>1));
    558570                else
    559                         ac97->power_up |= 1 << (reg>>1);
    560                 if (power_save)
    561                         update_power_regs(ac97);
     571                    ac97->power_up |= 1 << (reg>>1);
     572                update_power_regs(ac97);
    562573        }
    563574#endif
     
    11731184                kctl = snd_ctl_new1(&tmp, ac97);
    11741185        } else {
    1175                 struct snd_kcontrol_new tmp = AC97_SINGLE(name, reg, 15, 1, 1);
     1186            struct snd_kcontrol_new tmp = AC97_SINGLE(name, reg, 15, 1, 1);
     1187            if (check_amix)
     1188                tmp.private_value |= (1 << 30);
     1189
    11761190                tmp.index = ac97->num;
    11771191                kctl = snd_ctl_new1(&tmp, ac97);
     
    11871201
    11881202/*
     1203 * set dB information
     1204 */
     1205static DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
     1206static DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
     1207static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
     1208static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
     1209static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
     1210
     1211static unsigned int *find_db_scale(unsigned int maxval)
     1212{
     1213        switch (maxval) {
     1214        case 0x0f: return db_scale_4bit;
     1215        case 0x1f: return db_scale_5bit;
     1216        case 0x3f: return db_scale_6bit;
     1217        }
     1218        return NULL;
     1219}
     1220
     1221static void set_tlv_db_scale(struct snd_kcontrol *kctl, unsigned int *tlv)
     1222{       
     1223        kctl->tlv.p = tlv;
     1224        if (tlv)
     1225                kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
     1226}
     1227
     1228/*
     1229
    11891230 * create a volume for normal stereo/mono controls
    11901231 */
     
    12281269        }
    12291270#endif
    1230         err = snd_ctl_add(card, kctl);
     1271        if (reg >= AC97_PHONE && reg <= AC97_PCM)
     1272                set_tlv_db_scale(kctl, db_scale_5bit_12db_max);
     1273        else
     1274                set_tlv_db_scale(kctl, find_db_scale(lo_max));
     1275        err = snd_ctl_add(card, kctl);
    12311276        if (err < 0)
    12321277                return err;
     
    13081353                snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 0, &max);
    13091354                kctl->private_value &= ~(0xff << 16);
    1310                 kctl->private_value |= (int)max << 16;
     1355                kctl->private_value |= (int)max << 16;
     1356                set_tlv_db_scale(kctl, find_db_scale(max));
    13111357                snd_ac97_write_cache(ac97, AC97_CENTER_LFE_MASTER, ac97->regs[AC97_CENTER_LFE_MASTER] | max);
    13121358        }
     
    13211367                snd_ac97_change_volume_params2(ac97, AC97_CENTER_LFE_MASTER, 8, &max);
    13221368                kctl->private_value &= ~(0xff << 16);
    1323                 kctl->private_value |= (int)max << 16;
     1369                kctl->private_value |= (int)max << 16;
     1370                set_tlv_db_scale(kctl, find_db_scale(max));
    13241371                snd_ac97_write_cache(ac97, AC97_CENTER_LFE_MASTER, ac97->regs[AC97_CENTER_LFE_MASTER] | max << 8);
    13251372        }
     
    13691416            snd_ac97_try_volume_mix(ac97, AC97_PC_BEEP))) {
    13701417                for (idx = 0; idx < 2; idx++)
    1371                         if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
    1372                                 return err;
     1418                        if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_pc_beep[idx], ac97))) < 0)
     1419                                return err;
     1420                set_tlv_db_scale(kctl, db_scale_4bit);
    13731421                snd_ac97_write_cache(ac97, AC97_PC_BEEP,
    13741422                                     snd_ac97_read(ac97, AC97_PC_BEEP) | 0x801e);
     
    14361484                else
    14371485                        init_val = 0x9f1f;
    1438                 for (idx = 0; idx < 2; idx++)
    1439                         if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97))) < 0)
    1440                                 return err;
     1486                for (idx = 0; idx < 2; idx++)
     1487                    if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_pcm[idx], ac97))) < 0)
     1488                        return err;
     1489                set_tlv_db_scale(kctl, db_scale_5bit);
    14411490                ac97->spec.ad18xx.pcmreg[0] = init_val;
    14421491                if (ac97->scaps & AC97_SCAP_SURROUND_DAC) {
    1443                         for (idx = 0; idx < 2; idx++)
    1444                                 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97))) < 0)
    1445                                         return err;
    1446                         ac97->spec.ad18xx.pcmreg[1] = init_val;
     1492                    for (idx = 0; idx < 2; idx++)
     1493                        if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_surround[idx], ac97))) < 0)
     1494                            return err;
     1495                    set_tlv_db_scale(kctl, db_scale_5bit);
     1496                    ac97->spec.ad18xx.pcmreg[1] = init_val;
    14471497                }
    14481498                if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC) {
    1449                         for (idx = 0; idx < 2; idx++)
    1450                                 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97))) < 0)
    1451                                         return err;
    1452                         for (idx = 0; idx < 2; idx++)
    1453                                 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97))) < 0)
    1454                                         return err;
     1499                    for (idx = 0; idx < 2; idx++)
     1500                        if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_center[idx], ac97))) < 0)
     1501                            return err;
     1502                    set_tlv_db_scale(kctl, db_scale_5bit);
     1503                    for (idx = 0; idx < 2; idx++)
     1504                        if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_ad18xx_lfe[idx], ac97))) < 0)
     1505                            return err;
     1506                    set_tlv_db_scale(kctl, db_scale_5bit);
    14551507                        ac97->spec.ad18xx.pcmreg[2] = init_val;
    14561508                }
     
    14811533                    if (err < 0)
    14821534                        return err;
    1483                 }
    1484                 if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_control_capture_vol, ac97))) < 0)
    1485                         return err;
     1535                }
     1536                if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_control_capture_vol, ac97))) < 0)
     1537                    return err;
     1538                set_tlv_db_scale(kctl, db_scale_rec_gain);
    14861539                snd_ac97_write_cache(ac97, AC97_REC_SEL, 0x0000);
    14871540                snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x0000);
     
    14891542        /* build MIC Capture controls */
    14901543        if (snd_ac97_try_volume_mix(ac97, AC97_REC_GAIN_MIC)) {
    1491                 for (idx = 0; idx < 2; idx++)
    1492                         if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_capture[idx], ac97))) < 0)
    1493                                 return err;
    1494                 snd_ac97_write_cache(ac97, AC97_REC_GAIN_MIC, 0x0000);
     1544            for (idx = 0; idx < 2; idx++)
     1545                if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_mic_capture[idx], ac97))) < 0)
     1546                    return err;
     1547            set_tlv_db_scale(kctl, db_scale_rec_gain);
     1548            snd_ac97_write_cache(ac97, AC97_REC_GAIN_MIC, 0x0000);
    14951549        }
    14961550
     
    15611615        }
    15621616
    1563         /* build S/PDIF controls */
     1617        /* build S/PDIF controls */
     1618
     1619        /* Hack for ASUS P5P800-VM, which does not indicate S/PDIF capability */
     1620        if (ac97->subsystem_vendor == 0x1043 &&
     1621            ac97->subsystem_device == 0x810f)
     1622                ac97->ext_id |= AC97_EI_SPDIF;
     1623
    15641624        if ((ac97->ext_id & AC97_EI_SPDIF) && !(ac97->scaps & AC97_SCAP_NO_SPDIF)) {
    15651625                if (ac97->build_ops->build_spdif) {
     
    16421702        unsigned short saved;
    16431703
    1644         if (ac97->bus->no_vra || !(ac97->ext_id & AC97_EI_VRA) ) {
     1704        if (ac97->bus->no_vra) {
    16451705                *r_result = SNDRV_PCM_RATE_48000;
    16461706                if ((ac97->flags & AC97_DOUBLE_RATE) &&
     
    22612321        power |= AC97_PD_PR2 | AC97_PD_PR3;     /* Analog Mixer powerdown */
    22622322        snd_ac97_write(ac97, AC97_POWERDOWN, power);
    2263 #ifdef CONFIG_SND_AC97_POWER_SAVE
    2264         if (power_save) {
     2323        if (ac97_is_power_save_mode(ac97)) {
    22652324            udelay(100);
    22662325            /* AC-link powerdown, internal Clk disable */
     
    22692328            snd_ac97_write(ac97, AC97_POWERDOWN, power);
    22702329        }
    2271 #endif
    22722330}
    22732331
     
    23232381    }
    23242382
    2325     if (! power_save)
    2326         return 0;
    2327 
    2328     if (! powerup && ac97->power_workq)
     2383    if (ac97_is_power_save_mode(ac97) && !powerup)
    23292384        /* adjust power-down bits after two seconds delay
    23302385         * (for avoiding loud click noises for many (OSS) apps
     
    23462401    int i;
    23472402
    2348 #ifdef CONFIG_SND_AC97_POWER_SAVE
    2349     if (power_save)
    2350         power_up = ac97->power_up;
    2351     else {
    2352 #endif
    23532403        power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
    23542404        power_up |= (1 << PWIDX_MIC);
     
    23582408            power_up |= (1 << PWIDX_CLFE);
    23592409#ifdef CONFIG_SND_AC97_POWER_SAVE
    2360     }
     2410        if (ac97_is_power_save_mode(ac97))
     2411                power_up = ac97->power_up;
    23612412#endif
    23622413    if (power_up) {
  • GPL/trunk/alsa-kernel/pci/ac97/ac97_patch.c

    r77 r86  
    3131#include <sound/pcm.h>
    3232#include <sound/control.h>
     33#include <sound/tlv.h>
    3334#include <sound/ac97_codec.h>
    3435#include "ac97_patch.h"
     
    4849                        return err;
    4950        return 0;
     51}
     52
     53/* replace with a new TLV */
     54static void reset_tlv(struct snd_ac97 *ac97, const char *name,
     55                      unsigned int *tlv)
     56{
     57        struct snd_ctl_elem_id sid;
     58        struct snd_kcontrol *kctl;
     59        memset(&sid, 0, sizeof(sid));
     60        strcpy(sid.name, name);
     61        sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
     62        kctl = snd_ctl_find_id(ac97->bus->card, &sid);
     63        if (kctl && kctl->tlv.p)
     64                kctl->tlv.p = tlv;
    5065}
    5166
     
    174189}
    175190
     191/* system has shared jacks with surround out enabled */
     192static inline int is_shared_surrout(struct snd_ac97 *ac97)
     193{
     194        return ! ac97->indep_surround && is_surround_on(ac97);
     195}
     196
     197/* system has shared jacks with center/lfe out enabled */
     198static inline int is_shared_clfeout(struct snd_ac97 *ac97)
     199{
     200        return ! ac97->indep_surround && is_clfe_on(ac97);
     201}
     202
     203/* system has shared jacks with line in enabled */
    176204static inline int is_shared_linein(struct snd_ac97 *ac97)
    177205{
    178         return ! ac97->indep_surround && is_surround_on(ac97);
    179 }
    180 
     206        return !ac97->indep_surround && !is_surround_on(ac97);
     207}
     208
     209/* system has shared jacks with mic in enabled */
    181210static inline int is_shared_micin(struct snd_ac97 *ac97)
    182211{
    183         return ! ac97->indep_surround && is_clfe_on(ac97);
    184 }
    185 
     212        return !ac97->indep_surround && !is_clfe_on(ac97);
     213}
    186214
    187215/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
     
    514542
    515543AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
    516 AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1),
     544AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0),
    517545AC97_ENUM("Out3 Mux", wm9711_enum[2]),
    518546AC97_ENUM("Out3 LR Mux", wm9711_enum[3]),
     
    559587AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1),
    560588AC97_ENUM("Capture Volume Steps", wm9711_enum[6]),
    561 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1),
     589AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
    562590AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
    563591
     
    565593AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1),
    566594AC97_ENUM("Mic Select Source", wm9711_enum[7]),
    567 AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1),
     595AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
     596AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
    568597AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
    569598
     
    923952{
    924953        int err;
     954
     955        /* the register bit is writable, but the function is not implemented: */
     956        snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL);
    925957
    926958        snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
     
    13791411#endif
    13801412
     1413static const struct snd_ac97_res_table ad1819_restbl[] = {
     1414        { AC97_PHONE, 0x9f1f },
     1415        { AC97_MIC, 0x9f1f },
     1416        { AC97_LINE, 0x9f1f },
     1417        { AC97_CD, 0x9f1f },
     1418        { AC97_VIDEO, 0x9f1f },
     1419        { AC97_AUX, 0x9f1f },
     1420        { AC97_PCM, 0x9f1f },
     1421        {0} /* terminator */
     1422};
     1423
    13811424int patch_ad1819(struct snd_ac97 * ac97)
    13821425{
     
    13851428        // patch for Analog Devices
    13861429        scfg = snd_ac97_read(ac97, AC97_AD_SERIAL_CFG);
    1387         snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000); /* select all codecs */
     1430        snd_ac97_write_cache(ac97, AC97_AD_SERIAL_CFG, scfg | 0x7000); /* select all codecs */
     1431        ac97->res_table = ad1819_restbl;
    13881432        return 0;
    13891433}
     
    14381482        ac97->spec.ad18xx.codec_cfg[unchained_idx] = 0x0002;
    14391483        if (cidx1 >= 0) {
    1440                 if (patch_ad1881_chained1(ac97, cidx1, 0x0006))         // SDIE | ID1C
     1484                if (cidx2 < 0)
     1485                        patch_ad1881_chained1(ac97, cidx1, 0);
     1486                else if (patch_ad1881_chained1(ac97, cidx1, 0x0006))    // SDIE | ID1C
    14411487                        patch_ad1881_chained1(ac97, cidx2, 0);
    14421488                else if (patch_ad1881_chained1(ac97, cidx2, 0x0006))    // SDIE | ID1C
     
    15211567};
    15221568
     1569static DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0);
     1570
    15231571static int patch_ad1885_specific(struct snd_ac97 * ac97)
    15241572{
     
    15271575        if ((err = patch_build_controls(ac97, snd_ac97_controls_ad1885, ARRAY_SIZE(snd_ac97_controls_ad1885))) < 0)
    15281576                return err;
     1577        reset_tlv(ac97, "Headphone Playback Volume",
     1578                  db_scale_6bit_6db_max);
    15291579        return 0;
    15301580}
     
    15501600}
    15511601
     1602static int patch_ad1886_specific(struct snd_ac97 * ac97)
     1603{
     1604        reset_tlv(ac97, "Headphone Playback Volume",
     1605                  db_scale_6bit_6db_max);
     1606        return 0;
     1607}
     1608
     1609static struct snd_ac97_build_ops patch_ad1886_build_ops = {
     1610        .build_specific = &patch_ad1886_specific,
     1611#ifdef CONFIG_PM
     1612        .resume = ad18xx_resume
     1613#endif
     1614};
     1615
    15521616int patch_ad1886(struct snd_ac97 * ac97)
    15531617{
     
    15551619        /* Presario700 workaround */
    15561620        /* for Jack Sense/SPDIF Register misetting causing */
    1557         snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010);
    1558         return 0;
    1559 }
    1560 
    1561 /* MISC bits */
     1621        snd_ac97_write_cache(ac97, AC97_AD_JACK_SPDIF, 0x0010);
     1622        ac97->build_ops = &patch_ad1886_build_ops;
     1623        return 0;
     1624}
     1625
     1626/* MISC bits (AD1888/AD1980/AD1985 register 0x76) */
    15621627#define AC97_AD198X_MBC         0x0003  /* mic boost */
    15631628#define AC97_AD198X_MBC_20      0x0000  /* +20dB */
     
    15651630#define AC97_AD198X_MBC_30      0x0002  /* +30dB */
    15661631#define AC97_AD198X_VREFD       0x0004  /* VREF high-Z */
    1567 #define AC97_AD198X_VREFH       0x0008  /* 2.25V, 3.7V */
    1568 #define AC97_AD198X_VREF_0      0x000c  /* 0V */
     1632#define AC97_AD198X_VREFH       0x0008  /* 0=2.25V, 1=3.7V */
     1633#define AC97_AD198X_VREF_0      0x000c  /* 0V (AD1985 only) */
     1634#define AC97_AD198X_VREF_MASK   (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
     1635#define AC97_AD198X_VREF_SHIFT  2
    15691636#define AC97_AD198X_SRU         0x0010  /* sample rate unlock */
    15701637#define AC97_AD198X_LOSEL       0x0020  /* LINE_OUT amplifiers input select */
    15711638#define AC97_AD198X_2MIC        0x0040  /* 2-channel mic select */
    15721639#define AC97_AD198X_SPRD        0x0080  /* SPREAD enable */
    1573 #define AC97_AD198X_DMIX0       0x0100  /* downmix mode: 0 = 6-to-4, 1 = 6-to-2 downmix */
     1640#define AC97_AD198X_DMIX0       0x0100  /* downmix mode: */
     1641                                        /*  0 = 6-to-4, 1 = 6-to-2 downmix */
    15741642#define AC97_AD198X_DMIX1       0x0200  /* downmix mode: 1 = enabled */
    15751643#define AC97_AD198X_HPSEL       0x0400  /* headphone amplifier input select */
     
    15791647#define AC97_AD198X_AC97NC      0x4000  /* AC97 no compatible mode */
    15801648#define AC97_AD198X_DACZ        0x8000  /* DAC zero-fill mode */
     1649
     1650/* MISC 1 bits (AD1986 register 0x76) */
     1651#define AC97_AD1986_MBC         0x0003  /* mic boost */
     1652#define AC97_AD1986_MBC_20      0x0000  /* +20dB */
     1653#define AC97_AD1986_MBC_10      0x0001  /* +10dB */
     1654#define AC97_AD1986_MBC_30      0x0002  /* +30dB */
     1655#define AC97_AD1986_LISEL0      0x0004  /* LINE_IN select bit 0 */
     1656#define AC97_AD1986_LISEL1      0x0008  /* LINE_IN select bit 1 */
     1657#define AC97_AD1986_LISEL_MASK  (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
     1658#define AC97_AD1986_LISEL_LI    0x0000  /* LINE_IN pins as LINE_IN source */
     1659#define AC97_AD1986_LISEL_SURR  0x0004  /* SURROUND pins as LINE_IN source */
     1660#define AC97_AD1986_LISEL_MIC   0x0008  /* MIC_1/2 pins as LINE_IN source */
     1661#define AC97_AD1986_SRU         0x0010  /* sample rate unlock */
     1662#define AC97_AD1986_SOSEL       0x0020  /* SURROUND_OUT amplifiers input sel */
     1663#define AC97_AD1986_2MIC        0x0040  /* 2-channel mic select */
     1664#define AC97_AD1986_SPRD        0x0080  /* SPREAD enable */
     1665#define AC97_AD1986_DMIX0       0x0100  /* downmix mode: */
     1666                                        /*  0 = 6-to-4, 1 = 6-to-2 downmix */
     1667#define AC97_AD1986_DMIX1       0x0200  /* downmix mode: 1 = enabled */
     1668#define AC97_AD1986_CLDIS       0x0800  /* center/lfe disable */
     1669#define AC97_AD1986_SODIS       0x1000  /* SURROUND_OUT disable */
     1670#define AC97_AD1986_MSPLT       0x2000  /* mute split (read only 1) */
     1671#define AC97_AD1986_AC97NC      0x4000  /* AC97 no compatible mode (r/o 1) */
     1672#define AC97_AD1986_DACZ        0x8000  /* DAC zero-fill mode */
     1673
     1674/* MISC 2 bits (AD1986 register 0x70) */
     1675#define AC97_AD_MISC2           0x70    /* Misc Control Bits 2 (AD1986) */
     1676
     1677#define AC97_AD1986_CVREF0      0x0004  /* C/LFE VREF_OUT 2.25V */
     1678#define AC97_AD1986_CVREF1      0x0008  /* C/LFE VREF_OUT 0V */
     1679#define AC97_AD1986_CVREF2      0x0010  /* C/LFE VREF_OUT 3.7V */
     1680#define AC97_AD1986_CVREF_MASK \
     1681        (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
     1682#define AC97_AD1986_JSMAP       0x0020  /* Jack Sense Mapping 1 = alternate */
     1683#define AC97_AD1986_MMDIS       0x0080  /* Mono Mute Disable */
     1684#define AC97_AD1986_MVREF0      0x0400  /* MIC VREF_OUT 2.25V */
     1685#define AC97_AD1986_MVREF1      0x0800  /* MIC VREF_OUT 0V */
     1686#define AC97_AD1986_MVREF2      0x1000  /* MIC VREF_OUT 3.7V */
     1687#define AC97_AD1986_MVREF_MASK \
     1688        (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
     1689
     1690/* MISC 3 bits (AD1986 register 0x7a) */
     1691#define AC97_AD_MISC3           0x7a    /* Misc Control Bits 3 (AD1986) */
     1692
     1693#define AC97_AD1986_MMIX        0x0004  /* Mic Mix, left/right */
     1694#define AC97_AD1986_GPO         0x0008  /* General Purpose Out */
     1695#define AC97_AD1986_LOHPEN      0x0010  /* LINE_OUT headphone drive */
     1696#define AC97_AD1986_LVREF0      0x0100  /* LINE_OUT VREF_OUT 2.25V */
     1697#define AC97_AD1986_LVREF1      0x0200  /* LINE_OUT VREF_OUT 0V */
     1698#define AC97_AD1986_LVREF2      0x0400  /* LINE_OUT VREF_OUT 3.7V */
     1699#define AC97_AD1986_LVREF_MASK \
     1700        (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
     1701#define AC97_AD1986_JSINVA      0x0800  /* Jack Sense Invert SENSE_A */
     1702#define AC97_AD1986_LOSEL       0x1000  /* LINE_OUT amplifiers input select */
     1703#define AC97_AD1986_HPSEL0      0x2000  /* Headphone amplifiers */
     1704                                        /*   input select Surround DACs */
     1705#define AC97_AD1986_HPSEL1      0x4000  /* Headphone amplifiers input */
     1706                                        /*   select C/LFE DACs */
     1707#define AC97_AD1986_JSINVB      0x8000  /* Jack Sense Invert SENSE_B */
     1708
     1709/* Serial Config bits (AD1986 register 0x74) (incomplete) */
     1710#define AC97_AD1986_OMS0        0x0100  /* Optional Mic Selector bit 0 */
     1711#define AC97_AD1986_OMS1        0x0200  /* Optional Mic Selector bit 1 */
     1712#define AC97_AD1986_OMS2        0x0400  /* Optional Mic Selector bit 2 */
     1713#define AC97_AD1986_OMS_MASK \
     1714        (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
     1715#define AC97_AD1986_OMS_M       0x0000  /* MIC_1/2 pins are MIC sources */
     1716#define AC97_AD1986_OMS_L       0x0100  /* LINE_IN pins are MIC sources */
     1717#define AC97_AD1986_OMS_C       0x0200  /* Center/LFE pins are MCI sources */
     1718#define AC97_AD1986_OMS_MC      0x0400  /* Mix of MIC and C/LFE pins */
     1719                                        /*   are MIC sources */
     1720#define AC97_AD1986_OMS_ML      0x0500  /* MIX of MIC and LINE_IN pins */
     1721                                        /*   are MIC sources */
     1722#define AC97_AD1986_OMS_LC      0x0600  /* MIX of LINE_IN and C/LFE pins */
     1723                                        /*   are MIC sources */
     1724#define AC97_AD1986_OMS_MLC     0x0700  /* MIX of MIC, LINE_IN, C/LFE pins */
     1725                                        /*   are MIC sources */
    15811726
    15821727
     
    19022047}
    19032048
     2049static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol,
     2050                                        struct snd_ctl_elem_info *uinfo)
     2051{
     2052        static char *texts[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"};
     2053
     2054        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
     2055        uinfo->count = 1;
     2056        uinfo->value.enumerated.items = 4;
     2057        if (uinfo->value.enumerated.item > 3)
     2058                uinfo->value.enumerated.item = 3;
     2059        strcpy(uinfo->value.enumerated.name,
     2060               texts[uinfo->value.enumerated.item]);
     2061        return 0;
     2062}
     2063
     2064static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol,
     2065                                       struct snd_ctl_elem_value *ucontrol)
     2066{
     2067        static const int reg2ctrl[4] = {2, 0, 1, 3};
     2068        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2069        unsigned short val;
     2070        val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK)
     2071              >> AC97_AD198X_VREF_SHIFT;
     2072        ucontrol->value.enumerated.item[0] = reg2ctrl[val];
     2073        return 0;
     2074}
     2075
     2076static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol,
     2077                                       struct snd_ctl_elem_value *ucontrol)
     2078{
     2079        static const int ctrl2reg[4] = {1, 2, 0, 3};
     2080        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2081        unsigned short val;
     2082
     2083        if (ucontrol->value.enumerated.item[0] > 3
     2084            || ucontrol->value.enumerated.item[0] < 0)
     2085                return -EINVAL;
     2086        val = ctrl2reg[ucontrol->value.enumerated.item[0]]
     2087              << AC97_AD198X_VREF_SHIFT;
     2088        return snd_ac97_update_bits(ac97, AC97_AD_MISC,
     2089                                    AC97_AD198X_VREF_MASK, val);
     2090}
     2091
     2092
    19042093static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = {
    1905         AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0)
     2094        AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
     2095        {
     2096                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2097                .name = "Exchange Front/Surround",
     2098                .info = snd_ac97_ad1888_lohpsel_info,
     2099                .get = snd_ac97_ad1888_lohpsel_get,
     2100                .put = snd_ac97_ad1888_lohpsel_put
     2101        },
     2102        AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1),
     2103        AC97_SINGLE("Spread Front to Surround and Center/LFE",
     2104                    AC97_AD_MISC, 7, 1, 0),
     2105        {
     2106                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2107                .name = "Downmix",
     2108                .info = snd_ac97_ad1888_downmix_info,
     2109                .get = snd_ac97_ad1888_downmix_get,
     2110                .put = snd_ac97_ad1888_downmix_put
     2111        },
     2112        {
     2113                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2114                .name = "V_REFOUT",
     2115                .info = snd_ac97_ad1985_vrefout_info,
     2116                .get = snd_ac97_ad1985_vrefout_get,
     2117                .put = snd_ac97_ad1985_vrefout_put
     2118        },
     2119        AC97_SURROUND_JACK_MODE_CTL,
     2120        AC97_CHANNEL_MODE_CTL,
     2121
     2122        AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
     2123        AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
    19062124};
    19072125
     
    19172135        int err;
    19182136
    1919         if ((err = patch_ad1980_specific(ac97)) < 0)
     2137        /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
     2138        snd_ac97_rename_vol_ctl(ac97, "Master Playback",
     2139                                "Master Surround Playback");
     2140        snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
     2141
     2142        if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
    19202143                return err;
    1921         return patch_build_controls(ac97, snd_ac97_ad1985_controls, ARRAY_SIZE(snd_ac97_ad1985_controls));
     2144
     2145        return patch_build_controls(ac97, snd_ac97_ad1985_controls,
     2146                                    ARRAY_SIZE(snd_ac97_ad1985_controls));
    19222147}
    19232148
     
    19392164        misc = snd_ac97_read(ac97, AC97_AD_MISC);
    19402165        /* switch front/surround line-out/hp-out */
    1941         /* center/LFE, mic in 3.75V mode */
    19422166        /* AD-compatible mode */
    19432167        /* Stereo mutes enabled */
    1944         /* in accordance with ADI driver: misc | 0x5c28 */
    19452168        snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
    1946                              AC97_AD198X_VREFH |
    19472169                             AC97_AD198X_LOSEL |
    19482170                             AC97_AD198X_HPSEL |
    1949                              AC97_AD198X_CLDIS |
    1950                              AC97_AD198X_LODIS |
    19512171                             AC97_AD198X_MSPLT |
    19522172                             AC97_AD198X_AC97NC);
    19532173        ac97->flags |= AC97_STEREO_MUTES;
    1954         /* on AD1985 rev. 3, AC'97 revision bits are zero */
     2174
     2175        /* update current jack configuration */
     2176        ad1985_update_jacks(ac97);
     2177
     2178        /* on AD1985 rev. 3, AC'97 revision bits are zero */
    19552179        ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;
    19562180        return 0;
    19572181}
     2182
     2183static int snd_ac97_ad1986_bool_info(struct snd_kcontrol *kcontrol,
     2184                                     struct snd_ctl_elem_info *uinfo)
     2185{
     2186        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
     2187        uinfo->count = 1;
     2188        uinfo->value.integer.min = 0;
     2189        uinfo->value.integer.max = 1;
     2190        return 0;
     2191}
     2192
     2193static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol,
     2194                                       struct snd_ctl_elem_value *ucontrol)
     2195{
     2196        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2197        unsigned short val;
     2198
     2199        val = ac97->regs[AC97_AD_MISC3];
     2200        ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0;
     2201        return 0;
     2202}
     2203
     2204static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol,
     2205                                       struct snd_ctl_elem_value *ucontrol)
     2206{
     2207        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2208        int ret0;
     2209        int ret1;
     2210        int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0;
     2211
     2212        ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL,
     2213                                        ucontrol->value.integer.value[0] != 0
     2214                                    ? AC97_AD1986_LOSEL : 0);
     2215        if (ret0 < 0)
     2216                return ret0;
     2217
     2218        /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
     2219        ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
     2220                                    (ucontrol->value.integer.value[0] != 0
     2221                                     || sprd)
     2222                                    ? AC97_AD1986_SOSEL : 0);
     2223        if (ret1 < 0)
     2224                return ret1;
     2225
     2226        return (ret0 > 0 || ret1 > 0) ? 1 : 0;
     2227}
     2228
     2229static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol,
     2230                                      struct snd_ctl_elem_value *ucontrol)
     2231{
     2232        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2233        unsigned short val;
     2234
     2235        val = ac97->regs[AC97_AD_MISC];
     2236        ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0;
     2237        return 0;
     2238}
     2239
     2240static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol,
     2241                                      struct snd_ctl_elem_value *ucontrol)
     2242{
     2243        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2244        int ret0;
     2245        int ret1;
     2246        int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0;
     2247
     2248        ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD,
     2249                                        ucontrol->value.integer.value[0] != 0
     2250                                    ? AC97_AD1986_SPRD : 0);
     2251        if (ret0 < 0)
     2252                return ret0;
     2253
     2254        /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
     2255        ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
     2256                                    (ucontrol->value.integer.value[0] != 0
     2257                                     || sprd)
     2258                                    ? AC97_AD1986_SOSEL : 0);
     2259        if (ret1 < 0)
     2260                return ret1;
     2261
     2262        return (ret0 > 0 || ret1 > 0) ? 1 : 0;
     2263}
     2264
     2265static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol,
     2266                                        struct snd_ctl_elem_value *ucontrol)
     2267{
     2268        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2269
     2270        ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein;
     2271        return 0;
     2272}
     2273
     2274static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol,
     2275                                        struct snd_ctl_elem_value *ucontrol)
     2276{
     2277        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2278        unsigned char swap = ucontrol->value.integer.value[0] != 0;
     2279
     2280        if (swap != ac97->spec.ad18xx.swap_mic_linein) {
     2281                ac97->spec.ad18xx.swap_mic_linein = swap;
     2282                if (ac97->build_ops->update_jacks)
     2283                        ac97->build_ops->update_jacks(ac97);
     2284                return 1;
     2285        }
     2286        return 0;
     2287}
     2288
     2289static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol,
     2290                                       struct snd_ctl_elem_value *ucontrol)
     2291{
     2292        /* Use MIC_1/2 V_REFOUT as the "get" value */
     2293        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2294        unsigned short val;
     2295        unsigned short reg = ac97->regs[AC97_AD_MISC2];
     2296        if ((reg & AC97_AD1986_MVREF0) != 0)
     2297                val = 2;
     2298        else if ((reg & AC97_AD1986_MVREF1) != 0)
     2299                val = 3;
     2300        else if ((reg & AC97_AD1986_MVREF2) != 0)
     2301                val = 1;
     2302        else
     2303                val = 0;
     2304        ucontrol->value.enumerated.item[0] = val;
     2305        return 0;
     2306}
     2307
     2308static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol,
     2309                                       struct snd_ctl_elem_value *ucontrol)
     2310{
     2311        struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
     2312        unsigned short cval;
     2313        unsigned short lval;
     2314        unsigned short mval;
     2315        int cret;
     2316        int lret;
     2317        int mret;
     2318
     2319        switch (ucontrol->value.enumerated.item[0])
     2320        {
     2321        case 0: /* High-Z */
     2322                cval = 0;
     2323                lval = 0;
     2324                mval = 0;
     2325                break;
     2326        case 1: /* 3.7 V */
     2327                cval = AC97_AD1986_CVREF2;
     2328                lval = AC97_AD1986_LVREF2;
     2329                mval = AC97_AD1986_MVREF2;
     2330                break;
     2331        case 2: /* 2.25 V */
     2332                cval = AC97_AD1986_CVREF0;
     2333                lval = AC97_AD1986_LVREF0;
     2334                mval = AC97_AD1986_MVREF0;
     2335                break;
     2336        case 3: /* 0 V */
     2337                cval = AC97_AD1986_CVREF1;
     2338                lval = AC97_AD1986_LVREF1;
     2339                mval = AC97_AD1986_MVREF1;
     2340                break;
     2341        default:
     2342                return -EINVAL;
     2343        }
     2344
     2345        cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
     2346                                    AC97_AD1986_CVREF_MASK, cval);
     2347        if (cret < 0)
     2348                return cret;
     2349        lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3,
     2350                                    AC97_AD1986_LVREF_MASK, lval);
     2351        if (lret < 0)
     2352                return lret;
     2353        mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
     2354                                    AC97_AD1986_MVREF_MASK, mval);
     2355        if (mret < 0)
     2356                return mret;
     2357
     2358        return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0;
     2359}
     2360
     2361static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = {
     2362        AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
     2363        {
     2364                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2365                .name = "Exchange Front/Surround",
     2366                .info = snd_ac97_ad1986_bool_info,
     2367                .get = snd_ac97_ad1986_lososel_get,
     2368                .put = snd_ac97_ad1986_lososel_put
     2369        },
     2370        {
     2371                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2372                .name = "Exchange Mic/Line In",
     2373                .info = snd_ac97_ad1986_bool_info,
     2374                .get = snd_ac97_ad1986_miclisel_get,
     2375                .put = snd_ac97_ad1986_miclisel_put
     2376        },
     2377        {
     2378                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2379                .name = "Spread Front to Surround and Center/LFE",
     2380                .info = snd_ac97_ad1986_bool_info,
     2381                .get = snd_ac97_ad1986_spread_get,
     2382                .put = snd_ac97_ad1986_spread_put
     2383        },
     2384        {
     2385                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2386                .name = "Downmix",
     2387                .info = snd_ac97_ad1888_downmix_info,
     2388                .get = snd_ac97_ad1888_downmix_get,
     2389                .put = snd_ac97_ad1888_downmix_put
     2390        },
     2391        {
     2392                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
     2393                .name = "V_REFOUT",
     2394                .info = snd_ac97_ad1985_vrefout_info,
     2395                .get = snd_ac97_ad1986_vrefout_get,
     2396                .put = snd_ac97_ad1986_vrefout_put
     2397        },
     2398        AC97_SURROUND_JACK_MODE_CTL,
     2399        AC97_CHANNEL_MODE_CTL,
     2400
     2401        AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
     2402        AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0)
     2403};
     2404
     2405static void ad1986_update_jacks(struct snd_ac97 *ac97)
     2406{
     2407        unsigned short misc_val = 0;
     2408        unsigned short ser_val;
     2409
     2410        /* disable SURROUND and CENTER/LFE if not surround mode */
     2411        if (! is_surround_on(ac97))
     2412                misc_val |= AC97_AD1986_SODIS;
     2413        if (! is_clfe_on(ac97))
     2414                misc_val |= AC97_AD1986_CLDIS;
     2415
     2416        /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */
     2417        if (is_shared_linein(ac97))
     2418                misc_val |= AC97_AD1986_LISEL_SURR;
     2419        else if (ac97->spec.ad18xx.swap_mic_linein != 0)
     2420                misc_val |= AC97_AD1986_LISEL_MIC;
     2421        snd_ac97_update_bits(ac97, AC97_AD_MISC,
     2422                             AC97_AD1986_SODIS | AC97_AD1986_CLDIS |
     2423                             AC97_AD1986_LISEL_MASK,
     2424                             misc_val);
     2425
     2426        /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */
     2427        if (is_shared_micin(ac97))
     2428                ser_val = AC97_AD1986_OMS_C;
     2429        else if (ac97->spec.ad18xx.swap_mic_linein != 0)
     2430                ser_val = AC97_AD1986_OMS_L;
     2431        else
     2432                ser_val = AC97_AD1986_OMS_M;
     2433        snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG,
     2434                             AC97_AD1986_OMS_MASK,
     2435                             ser_val);
     2436}
     2437
     2438static int patch_ad1986_specific(struct snd_ac97 *ac97)
     2439{
     2440        int err;
     2441
     2442        if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
     2443                return err;
     2444
     2445        return patch_build_controls(ac97, snd_ac97_ad1986_controls,
     2446                                    ARRAY_SIZE(snd_ac97_ad1985_controls));
     2447}
     2448
     2449static struct snd_ac97_build_ops patch_ad1986_build_ops = {
     2450        .build_post_spdif = patch_ad198x_post_spdif,
     2451        .build_specific = patch_ad1986_specific,
     2452#ifdef CONFIG_PM
     2453        .resume = ad18xx_resume,
     2454#endif
     2455        .update_jacks = ad1986_update_jacks,
     2456};
     2457
     2458int patch_ad1986(struct snd_ac97 * ac97)
     2459{
     2460        patch_ad1881(ac97);
     2461        ac97->build_ops = &patch_ad1986_build_ops;
     2462        ac97->flags |= AC97_STEREO_MUTES;
     2463
     2464        /* update current jack configuration */
     2465        ad1986_update_jacks(ac97);
     2466
     2467        return 0;
     2468}
     2469
    19582470
    19592471/*
     
    19642476        int shared;
    19652477
    1966         /* shared Line-In */
    1967         shared = is_shared_linein(ac97);
     2478        /* shared Line-In / Surround Out */
     2479        shared = is_shared_surrout(ac97);
    19682480        snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9,
    19692481                             shared ? (1 << 9) : 0);
    1970         /* update shared Mic */
    1971         shared = is_shared_micin(ac97);
     2482        /* update shared Mic In / Center/LFE Out */
     2483        shared = is_shared_clfeout(ac97);
    19722484        /* disable/enable vref */
    19732485        snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
     
    20142526};
    20152527
     2528static DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0);
     2529
    20162530static int patch_alc650_specific(struct snd_ac97 * ac97)
    20172531{
     
    20242538                        return err;
    20252539        }
     2540        if (ac97->id != AC97_ID_ALC650F)
     2541                reset_tlv(ac97, "Master Playback Volume",
     2542                          db_scale_5bit_3db_max);
    20262543        return 0;
    20272544}
     
    20942611        int shared;
    20952612
    2096         /* shared Line-In */
    2097         shared = is_shared_linein(ac97);
     2613        /* shared Line-In / Surround Out */
     2614        shared = is_shared_surrout(ac97);
    20982615        ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9,
    20992616                              shared ? (1 << 9) : 0, 0);
    2100         /* update shared mic */
    2101         shared = is_shared_micin(ac97);
     2617        /* update shared Mic In / Center/LFE Out */
     2618        shared = is_shared_clfeout(ac97);
    21022619        /* misc control; vrefout disable */
    21032620        snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
     
    22072724        else { /* ALC655 */
    22082725                if (ac97->subsystem_vendor == 0x1462 &&
    2209                     ac97->subsystem_device == 0x0131) /* MSI S270 laptop */
     2726                    (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
     2727                     ac97->subsystem_device == 0x0161 || /* LG K1 Express */
     2728                     ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
     2729                     ac97->subsystem_device == 0x0061))  /* MSI S250 laptop */
    22102730                        val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
    22112731                else
     
    22402760        int shared;
    22412761
    2242         /* shared Line-In */
    2243         shared = is_shared_linein(ac97);
     2762        /* shared Line-In / Surround Out */
     2763        shared = is_shared_surrout(ac97);
    22442764        /* SURR 1kOhm (bit4), Amp (bit5) */
    22452765        snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
     
    22482768        snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
    22492769                             shared ? (2<<12) : (0<<12));
    2250         /* update shared mic */
    2251         shared = is_shared_micin(ac97);
     2770        /* update shared Mic In / Center/LFE Out */
     2771        shared = is_shared_clfeout(ac97);
    22522772        /* Vref disable (bit12), 1kOhm (bit13) */
    22532773        snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
     
    23222842static void cm9738_update_jacks(struct snd_ac97 *ac97)
    23232843{
    2324         /* shared Line-In */
     2844        /* shared Line-In / Surround Out */
    23252845        snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10,
    2326                              is_shared_linein(ac97) ? (1 << 10) : 0);
     2846                             is_shared_surrout(ac97) ? (1 << 10) : 0);
    23272847}
    23282848
     
    24062926static void cm9739_update_jacks(struct snd_ac97 *ac97)
    24072927{
    2408         /* shared Line-In */
     2928        /* shared Line-In / Surround Out */
    24092929        snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10,
    2410                              is_shared_linein(ac97) ? (1 << 10) : 0);
    2411         /* shared Mic */
     2930                             is_shared_surrout(ac97) ? (1 << 10) : 0);
     2931        /* shared Mic In / Center/LFE Out **/
    24122932        snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
    2413                              is_shared_micin(ac97) ? 0x1000 : 0x2000);
     2933                             is_shared_clfeout(ac97) ? 0x1000 : 0x2000);
    24142934}
    24152935
     
    25233043        val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
    25243044        val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
    2525         val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)];
    2526         val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)];
     3045        val |= surr_shared[ac97->spec.dev_flags][is_shared_surrout(ac97)];
     3046        val |= clfe_shared[ac97->spec.dev_flags][is_shared_clfeout(ac97)];
    25273047
    25283048        snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
     
    27583278int patch_vt1617a(struct snd_ac97 * ac97)
    27593279{
     3280        /* bring analog power consumption to normal, like WinXP driver
     3281         * for EPIA SP
     3282         */
     3283        snd_ac97_write_cache(ac97, 0x5c, 0x20);
    27603284        ac97->ext_id |= AC97_EI_SPDIF;  /* force the detection of spdif */
    2761         ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
     3285        ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
     3286        ac97->build_ops = &patch_vt1616_ops;
    27623287        return 0;
    27633288}
     
    27673292static void it2646_update_jacks(struct snd_ac97 *ac97)
    27683293{
    2769         /* shared Line-In */
    2770         snd_ac97_update_bits(ac97, 0x76, 1 << 9,
    2771                              is_shared_linein(ac97) ? (1<<9) : 0);
    2772         /* shared Mic */
     3294    /* shared Line-In / Surround Out */
     3295    snd_ac97_update_bits(ac97, 0x76, 1 << 9,
     3296                             is_shared_surrout(ac97) ? (1<<9) : 0);
     3297        /* shared Mic / Center/LFE Out */
     3298
    27733299        snd_ac97_update_bits(ac97, 0x76, 1 << 10,
    2774                              is_shared_micin(ac97) ? (1<<10) : 0);
     3300                             is_shared_clfeout(ac97) ? (1<<10) : 0);
    27753301}
    27763302
  • GPL/trunk/alsa-kernel/pci/ac97/ac97_patch.h

    r77 r86  
    4949int patch_ad1981b(struct snd_ac97 * ac97);
    5050int patch_ad1985(struct snd_ac97 * ac97);
     51int patch_ad1986(struct snd_ac97 * ac97);
    5152int patch_alc650(struct snd_ac97 * ac97);
    5253int patch_alc655(struct snd_ac97 * ac97);
Note: See TracChangeset for help on using the changeset viewer.