diff -ru alsa-driver-1.0.15/alsa-kernel/pci/hda/patch_realtek.c alsa-driver-1.0.15-patched/alsa-kernel/pci/hda/patch_realtek.c --- alsa-driver-1.0.15/alsa-kernel/pci/hda/patch_realtek.c 2007-10-15 10:45:06.000000000 +0200 +++ alsa-driver-1.0.15-patched/alsa-kernel/pci/hda/patch_realtek.c 2007-11-03 16:18:38.000000000 +0100 @@ -159,6 +159,7 @@ ALC885_MACPRO, ALC885_MBP3, ALC885_IMAC24, + ALC885_IMAC_M07, ALC882_AUTO, ALC882_MODEL_LAST, }; @@ -5313,6 +5314,56 @@ alc885_imac24_automute(codec); } +/* iMac (mid 2007) mixer. */ +static struct snd_kcontrol_new alc885_imac_m07_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), + { } /* end */ +}; + +/* iMac (mid 2007) init verbs. */ +static struct hda_verb alc885_imac_m07_init_verbs[] = { + /* Internal speakers: output 0 (0x0c) */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Internal speakers: output 0 (0x0c) */ + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Headphone: output 0 (0x0c) */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + /* Front Mic: input vref at 80% */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + { } +}; + +/* Toggle speaker-output according to the hp-jack state */ +static void alc885_imac_m07_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); + snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); +} + +/* Processes unsolicited events. */ +static void alc885_imac_m07_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + /* Headphone insertion or removal. */ + if ((res >> 26) == ALC880_HP_EVENT) + alc885_imac_m07_automute(codec); +} + static void alc885_mbp3_automute(struct hda_codec *codec) { unsigned int present; @@ -5457,6 +5508,13 @@ alc885_imac24_automute(codec); } +/* set up GPIO and update auto-muting at initialization */ +static void alc885_imac_m07_init_hook(struct hda_codec *codec) +{ + alc885_macpro_init_hook(codec); + alc885_imac_m07_automute(codec); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -5594,6 +5652,7 @@ [ALC885_MACPRO] = "macpro", [ALC885_MBP3] = "mbp3", [ALC885_IMAC24] = "imac24", + [ALC885_IMAC_M07] = "imac-m07", [ALC882_AUTO] = "auto", }; @@ -5696,6 +5755,19 @@ .unsol_event = alc885_imac24_unsol_event, .init_hook = alc885_imac24_init_hook, }, + [ALC885_IMAC_M07] = { + .mixers = { alc885_imac_m07_mixer }, + .init_verbs = { alc885_imac_m07_init_verbs }, + .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .dac_nids = alc882_dac_nids, + .dig_out_nid = ALC882_DIGOUT_NID, + .dig_in_nid = ALC882_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), + .channel_mode = alc882_ch_modes, + .input_mux = &alc882_capture_source, + .unsol_event = alc885_imac_m07_unsol_event, + .init_hook = alc885_imac_m07_init_hook, + }, [ALC882_TARGA] = { .mixers = { alc882_targa_mixer, alc882_chmode_mixer, alc882_capture_mixer }, @@ -5914,12 +5986,16 @@ case 0x106b0c00: /* Mac Pro */ board_config = ALC885_MACPRO; break; - case 0x106b1000: /* iMac 24 */ + case 0x106b1000: /* iMac 24'' late 2006 */ board_config = ALC885_IMAC24; break; case 0x106b2c00: /* Macbook Pro rev3 */ board_config = ALC885_MBP3; break; + case 0x106b3000: /* iMac 20 '' mid 2007 */ + case 0x106b3200: /* iMac 24 '' mid 2007 */ + board_config = ALC885_IMAC_M07; + break; default: printk(KERN_INFO "hda_codec: Unknown model for ALC882, " "trying auto-probe from BIOS...\n");