diff options
author | Nicola Fagnani <nicfagn@iol.it> | 2007-07-19 17:28:52 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-07-20 05:12:00 -0400 |
commit | c54728d8aa59283ece86cb745e5085ece8b4eedb (patch) | |
tree | d1f4dba33634bdfdec64fb2e6c90a2ada9925c64 /sound/pci | |
parent | c5d9f1cdbf067b5500886c5171159e99657341ce (diff) |
[ALSA] hda-intel: support for iMac 24'' released on 09/2006
Basic audio support for the iMac 24'' model released on 09/2006,
including
headphone jack detection with automatic speaker muting.
This iMac uses the Realtek ALC885 codec, not a Sigmatel one as in
other models.
Functionality has been tested for internal speakers, headphone and
microphone.
Signed-off-by: Nicola Fagnani <nicfagn@iol.it>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5825d9958f34..9a47eec5a27b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -153,6 +153,7 @@ enum { | |||
153 | ALC882_TARGA, | 153 | ALC882_TARGA, |
154 | ALC882_ASUS_A7J, | 154 | ALC882_ASUS_A7J, |
155 | ALC885_MACPRO, | 155 | ALC885_MACPRO, |
156 | ALC885_IMAC24, | ||
156 | ALC882_AUTO, | 157 | ALC882_AUTO, |
157 | ALC882_MODEL_LAST, | 158 | ALC882_MODEL_LAST, |
158 | }; | 159 | }; |
@@ -5118,6 +5119,60 @@ static struct hda_verb alc882_macpro_init_verbs[] = { | |||
5118 | { } | 5119 | { } |
5119 | }; | 5120 | }; |
5120 | 5121 | ||
5122 | /* iMac 24 mixer. */ | ||
5123 | static struct snd_kcontrol_new alc885_imac24_mixer[] = { | ||
5124 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
5125 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), | ||
5126 | { } /* end */ | ||
5127 | }; | ||
5128 | |||
5129 | /* iMac 24 init verbs. */ | ||
5130 | static struct hda_verb alc885_imac24_init_verbs[] = { | ||
5131 | /* Internal speakers: output 0 (0x0c) */ | ||
5132 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
5133 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
5134 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5135 | /* Internal speakers: output 0 (0x0c) */ | ||
5136 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
5137 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
5138 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5139 | /* Headphone: output 0 (0x0c) */ | ||
5140 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
5141 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
5142 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
5143 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
5144 | /* Front Mic: input vref at 80% */ | ||
5145 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
5146 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
5147 | { } | ||
5148 | }; | ||
5149 | |||
5150 | /* Toggle speaker-output according to the hp-jack state */ | ||
5151 | static void alc885_imac24_automute(struct hda_codec *codec) | ||
5152 | { | ||
5153 | unsigned int present; | ||
5154 | |||
5155 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
5156 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
5157 | snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0, | ||
5158 | 0x80, present ? 0x80 : 0); | ||
5159 | snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0, | ||
5160 | 0x80, present ? 0x80 : 0); | ||
5161 | snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, | ||
5162 | 0x80, present ? 0x80 : 0); | ||
5163 | snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, | ||
5164 | 0x80, present ? 0x80 : 0); | ||
5165 | } | ||
5166 | |||
5167 | /* Processes unsolicited events. */ | ||
5168 | static void alc885_imac24_unsol_event(struct hda_codec *codec, | ||
5169 | unsigned int res) | ||
5170 | { | ||
5171 | /* Headphone insertion or removal. */ | ||
5172 | if ((res >> 26) == ALC880_HP_EVENT) | ||
5173 | alc885_imac24_automute(codec); | ||
5174 | } | ||
5175 | |||
5121 | static struct hda_verb alc882_targa_verbs[] = { | 5176 | static struct hda_verb alc882_targa_verbs[] = { |
5122 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 5177 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
5123 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 5178 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -5338,6 +5393,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
5338 | [ALC882_ARIMA] = "arima", | 5393 | [ALC882_ARIMA] = "arima", |
5339 | [ALC882_W2JC] = "w2jc", | 5394 | [ALC882_W2JC] = "w2jc", |
5340 | [ALC885_MACPRO] = "macpro", | 5395 | [ALC885_MACPRO] = "macpro", |
5396 | [ALC885_IMAC24] = "imac24", | ||
5341 | [ALC882_AUTO] = "auto", | 5397 | [ALC882_AUTO] = "auto", |
5342 | }; | 5398 | }; |
5343 | 5399 | ||
@@ -5410,6 +5466,19 @@ static struct alc_config_preset alc882_presets[] = { | |||
5410 | .channel_mode = alc882_ch_modes, | 5466 | .channel_mode = alc882_ch_modes, |
5411 | .input_mux = &alc882_capture_source, | 5467 | .input_mux = &alc882_capture_source, |
5412 | }, | 5468 | }, |
5469 | [ALC885_IMAC24] = { | ||
5470 | .mixers = { alc885_imac24_mixer }, | ||
5471 | .init_verbs = { alc885_imac24_init_verbs }, | ||
5472 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
5473 | .dac_nids = alc882_dac_nids, | ||
5474 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
5475 | .dig_in_nid = ALC882_DIGIN_NID, | ||
5476 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | ||
5477 | .channel_mode = alc882_ch_modes, | ||
5478 | .input_mux = &alc882_capture_source, | ||
5479 | .unsol_event = alc885_imac24_unsol_event, | ||
5480 | .init_hook = alc885_imac24_automute, | ||
5481 | }, | ||
5413 | [ALC882_TARGA] = { | 5482 | [ALC882_TARGA] = { |
5414 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer, | 5483 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer, |
5415 | alc882_capture_mixer }, | 5484 | alc882_capture_mixer }, |
@@ -5582,6 +5651,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
5582 | case 0x106b0c00: /* Mac Pro */ | 5651 | case 0x106b0c00: /* Mac Pro */ |
5583 | board_config = ALC885_MACPRO; | 5652 | board_config = ALC885_MACPRO; |
5584 | break; | 5653 | break; |
5654 | case 0x106b1000: /* iMac 24 */ | ||
5655 | board_config = ALC885_IMAC24; | ||
5656 | break; | ||
5585 | default: | 5657 | default: |
5586 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " | 5658 | printk(KERN_INFO "hda_codec: Unknown model for ALC882, " |
5587 | "trying auto-probe from BIOS...\n"); | 5659 | "trying auto-probe from BIOS...\n"); |
@@ -5608,7 +5680,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
5608 | if (board_config != ALC882_AUTO) | 5680 | if (board_config != ALC882_AUTO) |
5609 | setup_preset(spec, &alc882_presets[board_config]); | 5681 | setup_preset(spec, &alc882_presets[board_config]); |
5610 | 5682 | ||
5611 | if (board_config == ALC885_MACPRO) { | 5683 | if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) { |
5612 | alc882_gpio_mute(codec, 0, 0); | 5684 | alc882_gpio_mute(codec, 0, 0); |
5613 | alc882_gpio_mute(codec, 1, 0); | 5685 | alc882_gpio_mute(codec, 1, 0); |
5614 | } | 5686 | } |