Commit 78f1ae19 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: ice1724 - aureon - modify WM8770 Master & DAC volume
  ALSA: hda/realtek: quirk for D945GCLF2 mainboard
  ALSA: hda - Terradici HDA controllers does not support 64-bit mode
  ALSA: document: Add direct git link to grub hda-analyzer
  ALSA: radio/sound/miro: fix build, cleanup depends/selects
  ALSA: hda - Generalize EAPD inversion check in patch_analog.c
  ASoC: Wrong variable returned on error
  ALSA: snd-usb-us122l: add product IDs of US-122MKII and US-144MKII
  ALSA: hda - Exclude unusable ADCs for ALC88x
  ALSA: hda - Add missing Line-Out and PCM switches as slave
  ALSA: hda - iMac 9,1 sound patch.
  ALSA: opti93x: set MC indirect registers base from PnP data
parents fa395aae 84194883
...@@ -126,6 +126,7 @@ ALC882/883/885/888/889 ...@@ -126,6 +126,7 @@ ALC882/883/885/888/889
mb5 Macbook 5,1 mb5 Macbook 5,1
mbp3 Macbook Pro rev3 mbp3 Macbook Pro rev3
imac24 iMac 24'' with jack detection imac24 iMac 24'' with jack detection
imac91 iMac 9,1
w2jc ASUS W2JC w2jc ASUS W2JC
3stack-2ch-dig 3-jack with SPDIF I/O (ALC883) 3stack-2ch-dig 3-jack with SPDIF I/O (ALC883)
alc883-6stack-dig 6-jack digital with SPDIF I/O (ALC883) alc883-6stack-dig 6-jack digital with SPDIF I/O (ALC883)
......
...@@ -624,11 +624,13 @@ hda-verb. The program gives you an easy-to-use GUI stuff for showing ...@@ -624,11 +624,13 @@ hda-verb. The program gives you an easy-to-use GUI stuff for showing
the widget information and adjusting the amp values, as well as the the widget information and adjusting the amp values, as well as the
proc-compatible output. proc-compatible output.
The hda-analyzer is a part of alsa.git repository in The hda-analyzer:
alsa-project.org:
- http://git.alsa-project.org/?p=alsa.git;a=tree;f=hda-analyzer - http://git.alsa-project.org/?p=alsa.git;a=tree;f=hda-analyzer
is a part of alsa.git repository in alsa-project.org:
- git://git.alsa-project.org/alsa.git
Codecgraph Codecgraph
~~~~~~~~~~ ~~~~~~~~~~
......
...@@ -197,7 +197,8 @@ config RADIO_MAESTRO ...@@ -197,7 +197,8 @@ config RADIO_MAESTRO
config RADIO_MIROPCM20 config RADIO_MIROPCM20
tristate "miroSOUND PCM20 radio" tristate "miroSOUND PCM20 radio"
depends on ISA && VIDEO_V4L2 depends on ISA && VIDEO_V4L2 && SND
select SND_ISA
select SND_MIRO select SND_MIRO
---help--- ---help---
Choose Y here if you have this FM radio card. You also need to enable Choose Y here if you have this FM radio card. You also need to enable
......
...@@ -135,6 +135,8 @@ struct snd_opti9xx { ...@@ -135,6 +135,8 @@ struct snd_opti9xx {
unsigned long mc_base_size; unsigned long mc_base_size;
#ifdef OPTi93X #ifdef OPTi93X
unsigned long mc_indir_index; unsigned long mc_indir_index;
unsigned long mc_indir_size;
struct resource *res_mc_indir;
struct snd_wss *codec; struct snd_wss *codec;
#endif /* OPTi93X */ #endif /* OPTi93X */
unsigned long pwd_reg; unsigned long pwd_reg;
...@@ -231,7 +233,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, ...@@ -231,7 +233,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
case OPTi9XX_HW_82C931: case OPTi9XX_HW_82C931:
case OPTi9XX_HW_82C933: case OPTi9XX_HW_82C933:
chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
if (!chip->mc_indir_index) {
chip->mc_indir_index = 0xe0e; chip->mc_indir_index = 0xe0e;
chip->mc_indir_size = 2;
}
chip->password = 0xe4; chip->password = 0xe4;
chip->pwd_reg = 0; chip->pwd_reg = 0;
break; break;
...@@ -560,60 +565,72 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) ...@@ -560,60 +565,72 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
#endif /* OPTi93X */ #endif /* OPTi93X */
static int __devinit snd_card_opti9xx_detect(struct snd_card *card, static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
struct snd_opti9xx *chip)
{ {
int i, err;
#ifndef OPTi93X
for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
unsigned char value; unsigned char value;
#ifdef OPTi93X
unsigned long flags;
#endif
if ((err = snd_opti9xx_init(chip, i)) < 0) chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
return err; "OPTi9xx MC");
if (chip->res_mc_base == NULL)
if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) return -EBUSY;
continue; #ifndef OPTi93X
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)); value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
if ((value != 0xff) && (value != inb(chip->mc_base + 1))) if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
return 1; return 0;
release_and_free_resource(chip->res_mc_base);
chip->res_mc_base = NULL;
}
#else /* OPTi93X */ #else /* OPTi93X */
for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) { chip->res_mc_indir = request_region(chip->mc_indir_index,
unsigned long flags; chip->mc_indir_size,
unsigned char value; "OPTi93x MC");
if (chip->res_mc_indir == NULL)
if ((err = snd_opti9xx_init(chip, i)) < 0) return -EBUSY;
return err;
if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL)
continue;
spin_lock_irqsave(&chip->lock, flags); spin_lock_irqsave(&chip->lock, flags);
outb(chip->password, chip->mc_base + chip->pwd_reg); outb(chip->password, chip->mc_base + chip->pwd_reg);
outb(((chip->mc_indir_index & (1 << 8)) >> 4) | outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
spin_unlock_irqrestore(&chip->lock, flags); spin_unlock_irqrestore(&chip->lock, flags);
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)); value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value); snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value) if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
return 1; return 0;
release_and_free_resource(chip->res_mc_indir);
chip->res_mc_indir = NULL;
#endif /* OPTi93X */
release_and_free_resource(chip->res_mc_base); release_and_free_resource(chip->res_mc_base);
chip->res_mc_base = NULL; chip->res_mc_base = NULL;
}
#endif /* OPTi93X */
return -ENODEV; return -ENODEV;
} }
static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
struct snd_opti9xx *chip)
{
int i, err;
#ifndef OPTi93X
for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
#else
for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
#endif
err = snd_opti9xx_init(chip, i);
if (err < 0)
return err;
err = snd_opti9xx_read_check(chip);
if (err == 0)
return 1;
#ifdef OPTi93X
chip->mc_indir_index = 0;
#endif
}
return -ENODEV;
}
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
struct pnp_card_link *card, struct pnp_card_link *card,
...@@ -639,6 +656,8 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, ...@@ -639,6 +656,8 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
#ifdef OPTi93X #ifdef OPTi93X
port = pnp_port_start(pdev, 0) - 4; port = pnp_port_start(pdev, 0) - 4;
fm_port = pnp_port_start(pdev, 1) + 8; fm_port = pnp_port_start(pdev, 1) + 8;
chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
#else #else
if (pid->driver_data != 0x0924) if (pid->driver_data != 0x0924)
port = pnp_port_start(pdev, 1); port = pnp_port_start(pdev, 1);
...@@ -677,6 +696,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) ...@@ -677,6 +696,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
disable_irq(codec->irq); disable_irq(codec->irq);
free_irq(codec->irq, codec); free_irq(codec->irq, codec);
} }
release_and_free_resource(chip->res_mc_indir);
#endif #endif
release_and_free_resource(chip->res_mc_base); release_and_free_resource(chip->res_mc_base);
} }
...@@ -696,11 +716,6 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) ...@@ -696,11 +716,6 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
struct snd_rawmidi *rmidi; struct snd_rawmidi *rmidi;
struct snd_hwdep *synth; struct snd_hwdep *synth;
if (! chip->res_mc_base &&
(chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
"OPTi9xx MC")) == NULL)
return -ENOMEM;
#if defined(CS4231) || defined(OPTi93X) #if defined(CS4231) || defined(OPTi93X)
xdma2 = dma2; xdma2 = dma2;
#else #else
...@@ -954,6 +969,13 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, ...@@ -954,6 +969,13 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
} }
if (hw <= OPTi9XX_HW_82C930) if (hw <= OPTi9XX_HW_82C930)
chip->mc_base -= 0x80; chip->mc_base -= 0x80;
error = snd_opti9xx_read_check(chip);
if (error) {
snd_printk(KERN_ERR "OPTI chip not found\n");
snd_card_free(card);
return error;
}
snd_card_set_dev(card, &pcard->card->dev); snd_card_set_dev(card, &pcard->card->dev);
if ((error = snd_opti9xx_probe(card)) < 0) { if ((error = snd_opti9xx_probe(card)) < 0) {
snd_card_free(card); snd_card_free(card);
......
...@@ -2450,6 +2450,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -2450,6 +2450,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
} }
} }
/* disable 64bit DMA address for Teradici */
/* it does not work with device 6549:1200 subsys e4a2:040b */
if (chip->driver_type == AZX_DRIVER_TERA)
gcap &= ~ICH6_GCAP_64OK;
/* allow 64bit DMA address if supported by H/W */ /* allow 64bit DMA address if supported by H/W */
if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
......
...@@ -72,7 +72,8 @@ struct ad198x_spec { ...@@ -72,7 +72,8 @@ struct ad198x_spec {
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
unsigned int jack_present :1; unsigned int jack_present :1;
unsigned int inv_jack_detect:1; unsigned int inv_jack_detect:1; /* inverted jack-detection */
unsigned int inv_eapd:1; /* inverted EAPD implementation */
#ifdef CONFIG_SND_HDA_POWER_SAVE #ifdef CONFIG_SND_HDA_POWER_SAVE
struct hda_loopback_check loopback; struct hda_loopback_check loopback;
...@@ -458,7 +459,7 @@ static struct hda_codec_ops ad198x_patch_ops = { ...@@ -458,7 +459,7 @@ static struct hda_codec_ops ad198x_patch_ops = {
/* /*
* EAPD control * EAPD control
* the private value = nid | (invert << 8) * the private value = nid
*/ */
#define ad198x_eapd_info snd_ctl_boolean_mono_info #define ad198x_eapd_info snd_ctl_boolean_mono_info
...@@ -467,8 +468,7 @@ static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, ...@@ -467,8 +468,7 @@ static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
{ {
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ad198x_spec *spec = codec->spec; struct ad198x_spec *spec = codec->spec;
int invert = (kcontrol->private_value >> 8) & 1; if (spec->inv_eapd)
if (invert)
ucontrol->value.integer.value[0] = ! spec->cur_eapd; ucontrol->value.integer.value[0] = ! spec->cur_eapd;
else else
ucontrol->value.integer.value[0] = spec->cur_eapd; ucontrol->value.integer.value[0] = spec->cur_eapd;
...@@ -480,11 +480,10 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, ...@@ -480,11 +480,10 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
{ {
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ad198x_spec *spec = codec->spec; struct ad198x_spec *spec = codec->spec;
int invert = (kcontrol->private_value >> 8) & 1;
hda_nid_t nid = kcontrol->private_value & 0xff; hda_nid_t nid = kcontrol->private_value & 0xff;
unsigned int eapd; unsigned int eapd;
eapd = !!ucontrol->value.integer.value[0]; eapd = !!ucontrol->value.integer.value[0];
if (invert) if (spec->inv_eapd)
eapd = !eapd; eapd = !eapd;
if (eapd == spec->cur_eapd) if (eapd == spec->cur_eapd)
return 0; return 0;
...@@ -705,7 +704,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { ...@@ -705,7 +704,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
.info = ad198x_eapd_info, .info = ad198x_eapd_info,
.get = ad198x_eapd_get, .get = ad198x_eapd_get,
.put = ad198x_eapd_put, .put = ad198x_eapd_put,
.private_value = 0x1b | (1 << 8), /* port-D, inversed */ .private_value = 0x1b, /* port-D */
}, },
{ } /* end */ { } /* end */
}; };
...@@ -1074,6 +1073,7 @@ static int patch_ad1986a(struct hda_codec *codec) ...@@ -1074,6 +1073,7 @@ static int patch_ad1986a(struct hda_codec *codec)
spec->loopback.amplist = ad1986a_loopbacks; spec->loopback.amplist = ad1986a_loopbacks;
#endif #endif
spec->vmaster_nid = 0x1b; spec->vmaster_nid = 0x1b;
spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
codec->patch_ops = ad198x_patch_ops; codec->patch_ops = ad198x_patch_ops;
...@@ -2124,7 +2124,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = { ...@@ -2124,7 +2124,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
.info = ad198x_eapd_info, .info = ad198x_eapd_info,
.get = ad198x_eapd_get, .get = ad198x_eapd_get,
.put = ad198x_eapd_put, .put = ad198x_eapd_put,
.private_value = 0x12 | (1 << 8), /* port-D, inversed */ .private_value = 0x12, /* port-D */
}, },
{ } /* end */ { } /* end */
...@@ -3065,6 +3065,7 @@ static int patch_ad1988(struct hda_codec *codec) ...@@ -3065,6 +3065,7 @@ static int patch_ad1988(struct hda_codec *codec)
spec->input_mux = &ad1988_laptop_capture_source; spec->input_mux = &ad1988_laptop_capture_source;
spec->num_mixers = 1; spec->num_mixers = 1;
spec->mixers[0] = ad1988_laptop_mixers; spec->mixers[0] = ad1988_laptop_mixers;
spec->inv_eapd = 1; /* inverted EAPD */
spec->num_init_verbs = 1; spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1988_laptop_init_verbs; spec->init_verbs[0] = ad1988_laptop_init_verbs;
if (board_config == AD1988_LAPTOP_DIG) if (board_config == AD1988_LAPTOP_DIG)
......
...@@ -208,6 +208,7 @@ enum { ...@@ -208,6 +208,7 @@ enum {
ALC885_MBP3, ALC885_MBP3,
ALC885_MB5, ALC885_MB5,
ALC885_IMAC24, ALC885_IMAC24,
ALC885_IMAC91,
ALC883_3ST_2ch_DIG, ALC883_3ST_2ch_DIG,
ALC883_3ST_6ch_DIG, ALC883_3ST_6ch_DIG,
ALC883_3ST_6ch, ALC883_3ST_6ch,
...@@ -2400,6 +2401,8 @@ static const char *alc_slave_sws[] = { ...@@ -2400,6 +2401,8 @@ static const char *alc_slave_sws[] = {
"Speaker Playback Switch", "Speaker Playback Switch",
"Mono Playback Switch", "Mono Playback Switch",
"IEC958 Playback Switch", "IEC958 Playback Switch",
"Line-Out Playback Switch",
"PCM Playback Switch",
NULL, NULL,
}; };
...@@ -7050,6 +7053,20 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { ...@@ -7050,6 +7053,20 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
{ } /* end */ { } /* end */
}; };
static struct snd_kcontrol_new alc885_imac91_mixer[] = {
HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
{ } /* end */
};
static struct snd_kcontrol_new alc882_w2jc_mixer[] = { static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
...@@ -7505,6 +7522,66 @@ static struct hda_verb alc885_mbp3_init_verbs[] = { ...@@ -7505,6 +7522,66 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {
{ } { }
}; };
/* iMac 9,1 */
static struct hda_verb alc885_imac91_init_verbs[] = {
/* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
/* Rear mixer */
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
/* HP Pin: output 0 (0x0c) */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
/* Internal Speakers: output 0 (0x0d) */
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
/* Mic (rear) pin: input vref at 80% */
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
/* Front Mic pin: input vref at 80% */
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
/* Line In pin: use output 1 when in LineOut mode */
{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
/* FIXME: use matrix-type input source selection */
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* Input mixer2 */
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* Input mixer3 */
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* ADC1: mute amp left and right */
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
/* ADC2: mute amp left and right */
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
/* ADC3: mute amp left and right */
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{ }
};
/* iMac 24 mixer. */ /* iMac 24 mixer. */
static struct snd_kcontrol_new alc885_imac24_mixer[] = { static struct snd_kcontrol_new alc885_imac24_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
...@@ -7551,6 +7628,26 @@ static void alc885_mbp3_setup(struct hda_codec *codec) ...@@ -7551,6 +7628,26 @@ static void alc885_mbp3_setup(struct hda_codec *codec)
spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x14;
} }
static void alc885_imac91_automute(struct hda_codec *codec)
{
unsigned int present;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc885_imac91_unsol_event(struct hda_codec *codec,
unsigned int res)
{
/* Headphone insertion or removal. */
if ((res >> 26) == ALC880_HP_EVENT)
alc885_imac91_automute(codec);
}
static struct hda_verb alc882_targa_verbs[] = { static struct hda_verb alc882_targa_verbs[] = {
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
...@@ -8718,6 +8815,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { ...@@ -8718,6 +8815,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
[ALC885_MB5] = "mb5", [ALC885_MB5] = "mb5",
[ALC885_MBP3] = "mbp3", [ALC885_MBP3] = "mbp3",
[ALC885_IMAC24] = "imac24", [ALC885_IMAC24] = "imac24",
[ALC885_IMAC91] = "imac91",
[ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
[ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
[ALC883_3ST_6ch] = "3stack-6ch", [ALC883_3ST_6ch] = "3stack-6ch",
...@@ -8891,6 +8989,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { ...@@ -8891,6 +8989,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
* so apparently no perfect solution yet * so apparently no perfect solution yet
...@@ -9002,6 +9101,20 @@ static struct alc_config_preset alc882_presets[] = { ...@@ -9002,6 +9101,20 @@ static struct alc_config_preset alc882_presets[] = {
.setup = alc885_imac24_setup, .setup = alc885_imac24_setup,
.init_hook = alc885_imac24_init_hook, .init_hook = alc885_imac24_init_hook,
}, },
[ALC885_IMAC91] = {
.mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
.init_verbs = { alc885_imac91_init_verbs,
alc880_gpio1_init_verbs },
.num_dacs = ARRAY_SIZE(alc882_dac_nids),
.dac_nids = alc882_dac_nids,
.channel_mode = alc885_mbp_4ch_modes,
.num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
.input_mux = &alc882_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID,
.unsol_event = alc885_imac91_unsol_event,
.init_hook = alc885_imac91_automute,
},
[ALC882_TARGA] = { [ALC882_TARGA] = {
.mixers = { alc882_targa_mixer, alc882_chmode_mixer }, .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
.init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
...@@ -9908,10 +10021,12 @@ static int patch_alc882(struct hda_codec *codec) ...@@ -9908,10 +10021,12 @@ static int patch_alc882(struct hda_codec *codec)
spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
if (!spec->adc_nids && spec->input_mux) { if (!spec->adc_nids && spec->input_mux) {
int i; int i, j;
spec->num_adc_nids = 0; spec->num_adc_nids = 0;
for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
const struct hda_input_mux *imux = spec->input_mux;
hda_nid_t cap; hda_nid_t cap;
hda_nid_t items[16];
hda_nid_t nid = alc882_adc_nids[i]; hda_nid_t nid = alc882_adc_nids[i];
unsigned int wcap = get_wcaps(codec, nid); unsigned int wcap = get_wcaps(codec, nid);
/* get type */ /* get type */
...@@ -9922,6 +10037,15 @@ static int patch_alc882(struct hda_codec *codec) ...@@ -9922,6 +10037,15 @@ static int patch_alc882(struct hda_codec *codec)
err = snd_hda_get_connections(codec, nid, &cap, 1); err = snd_hda_get_connections(codec, nid, &cap, 1);
if (err < 0) if (err < 0)
continue; continue;
err = snd_hda_get_connections(codec, cap, items,
ARRAY_SIZE(items));
if (err < 0)
continue;
for (j = 0; j < imux->num_items; j++)
if (imux->items[j].index >= err)
break;
if (j < imux->num_items)
continue;
spec->private_capsrc_nids[spec->num_adc_nids] = cap; spec->private_capsrc_nids[spec->num_adc_nids] = cap;
spec->num_adc_nids++; spec->num_adc_nids++;
} }
...@@ -16846,6 +16970,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { ...@@ -16846,6 +16970,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
ALC662_3ST_6ch_DIG), ALC662_3ST_6ch_DIG),
SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
ALC663_ASUS_H13), ALC663_ASUS_H13),
SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
{} {}
}; };
......
...@@ -689,32 +689,14 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e ...@@ -689,32 +689,14 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
return change; return change;
} }
static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
/* #define WM_VOL_MAX 100
* Logarithmic volume values for WM8770 #define WM_VOL_CNT 101 /* 0dB .. -100dB */
* Computed as 20 * Log10(255 / x)
*/
static const unsigned char wm_vol[256] = {
127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0
};
#define WM_VOL_MAX (sizeof(wm_vol) - 1)
#define WM_VOL_MUTE 0x8000 #define WM_VOL_MUTE 0x8000
static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
...@@ -724,7 +706,8 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho ...@@ -724,7 +706,8 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
nvol = 0; nvol = 0;
else else
nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
WM_VOL_MAX;
wm_put(ice, index, nvol); wm_put(ice, index, nvol);
wm_put_nocache(ice, index, 0x180 | nvol); wm_put_nocache(ice, index, 0x180 | nvol);
...@@ -820,7 +803,7 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info * ...@@ -820,7 +803,7 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = voices; uinfo->count = voices;
uinfo->value.integer.min = 0; /* mute (-101dB) */ uinfo->value.integer.min = 0; /* mute (-101dB) */
uinfo->value.integer.max = 0x7F; /* 0dB */ uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
return 0; return 0;
} }
...@@ -850,7 +833,7 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value * ...@@ -850,7 +833,7 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
snd_ice1712_save_gpio_status(ice); snd_ice1712_save_gpio_status(ice);
for (i = 0; i < voices; i++) { for (i = 0; i < voices; i++) {
unsigned int vol = ucontrol->value.integer.value[i]; unsigned int vol = ucontrol->value.integer.value[i];
if (vol > 0x7f) if (vol > WM_VOL_MAX)
continue; continue;
vol |= spec->vol[ofs+i]; vol |= spec->vol[ofs+i];
if (vol != spec->vol[ofs+i]) { if (vol != spec->vol[ofs+i]) {
......
...@@ -322,12 +322,12 @@ static int mx1_mx2_pcm_open(struct snd_pcm_substream *substream) ...@@ -322,12 +322,12 @@ static int mx1_mx2_pcm_open(struct snd_pcm_substream *substream)
pr_debug("%s: Requesting dma channel (%s)\n", __func__, pr_debug("%s: Requesting dma channel (%s)\n", __func__,
prtd->dma_params->name); prtd->dma_params->name);
prtd->dma_ch = imx_dma_request_by_prio(prtd->dma_params->name, ret = imx_dma_request_by_prio(prtd->dma_params->name, DMA_PRIO_HIGH);
DMA_PRIO_HIGH); if (ret < 0) {
if (prtd->dma_ch < 0) {
printk(KERN_ERR "Error %d requesting dma channel\n", ret); printk(KERN_ERR "Error %d requesting dma channel\n", ret);
return ret; return ret;
} }
prtd->dma_ch = ret;
imx_dma_config_burstlen(prtd->dma_ch, imx_dma_config_burstlen(prtd->dma_ch,
prtd->dma_params->watermark_level); prtd->dma_params->watermark_level);
......
...@@ -194,7 +194,8 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file) ...@@ -194,7 +194,8 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
if (!us122l->first) if (!us122l->first)
us122l->first = file; us122l->first = file;
if (us122l->dev->descriptor.idProduct == USB_ID_US144) { if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
iface = usb_ifnum_to_if(us122l->dev, 0); iface = usb_ifnum_to_if(us122l->dev, 0);
usb_autopm_get_interface(iface); usb_autopm_get_interface(iface);
} }
...@@ -209,7 +210,8 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file) ...@@ -209,7 +210,8 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
struct usb_interface *iface; struct usb_interface *iface;
snd_printdd(KERN_DEBUG "%p %p\n", hw, file); snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
if (us122l->dev->descriptor.idProduct == USB_ID_US144) { if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
iface = usb_ifnum_to_if(us122l->dev, 0); iface = usb_ifnum_to_if(us122l->dev, 0);
usb_autopm_put_interface(iface); usb_autopm_put_interface(iface);
} }
...@@ -476,7 +478,8 @@ static bool us122l_create_card(struct snd_card *card) ...@@ -476,7 +478,8 @@ static bool us122l_create_card(struct snd_card *card)
int err; int err;
struct us122l *us122l = US122L(card); struct us122l *us122l = US122L(card);
if (us122l->dev->descriptor.idProduct == USB_ID_US144) { if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
err = usb_set_interface(us122l->dev, 0, 1); err = usb_set_interface(us122l->dev, 0, 1);
if (err) { if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n"); snd_printk(KERN_ERR "usb_set_interface error \n");
...@@ -495,7 +498,8 @@ static bool us122l_create_card(struct snd_card *card) ...@@ -495,7 +498,8 @@ static bool us122l_create_card(struct snd_card *card)
if (!us122l_start(us122l, 44100, 256)) if (!us122l_start(us122l, 44100, 256))
return false; return false;
if (us122l->dev->descriptor.idProduct == USB_ID_US144) if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
us122l->dev->descriptor.idProduct == USB_ID_US144MKII)
err = us144_create_usbmidi(card); err = us144_create_usbmidi(card);
else else
err = us122l_create_usbmidi(card); err = us122l_create_usbmidi(card);
...@@ -597,7 +601,8 @@ static int snd_us122l_probe(struct usb_interface *intf, ...@@ -597,7 +601,8 @@ static int snd_us122l_probe(struct usb_interface *intf,
struct snd_card *card; struct snd_card *card;
int err; int err;
if (device->descriptor.idProduct == USB_ID_US144 if ((device->descriptor.idProduct == USB_ID_US144 ||
device->descriptor.idProduct == USB_ID_US144MKII)
&& device->speed == USB_SPEED_HIGH) { && device->speed == USB_SPEED_HIGH) {
snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n"); snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
return -ENODEV; return -ENODEV;
...@@ -692,7 +697,8 @@ static int snd_us122l_resume(struct usb_interface *intf) ...@@ -692,7 +697,8 @@ static int snd_us122l_resume(struct usb_interface *intf)
mutex_lock(&us122l->mutex); mutex_lock(&us122l->mutex);
/* needed, doesn't restart without: */ /* needed, doesn't restart without: */
if (us122l->dev->descriptor.idProduct == USB_ID_US144) { if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
err = usb_set_interface(us122l->dev, 0, 1); err = usb_set_interface(us122l->dev, 0, 1);
if (err) { if (err) {
snd_printk(KERN_ERR "usb_set_interface error \n"); snd_printk(KERN_ERR "usb_set_interface error \n");
...@@ -737,6 +743,16 @@ static struct usb_device_id snd_us122l_usb_id_table[] = { ...@@ -737,6 +743,16 @@ static struct usb_device_id snd_us122l_usb_id_table[] = {
.idVendor = 0x0644, .idVendor = 0x0644,
.idProduct = USB_ID_US144 .idProduct = USB_ID_US144
}, },
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x0644,
.idProduct = USB_ID_US122MKII
},
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x0644,
.idProduct = USB_ID_US144MKII
},
{ /* terminator */ } { /* terminator */ }
}; };
......
...@@ -25,5 +25,7 @@ struct us122l { ...@@ -25,5 +25,7 @@ struct us122l {
#define USB_ID_US122L 0x800E #define USB_ID_US122L 0x800E
#define USB_ID_US144 0x800F #define USB_ID_US144 0x800F
#define USB_ID_US122MKII 0x8021
#define USB_ID_US144MKII 0x8020
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment