diff -Nru kernel-2.6.23mamba.orig/sound/pci/hda/hda_codec.c kernel-2.6.23mamba/sound/pci/hda/hda_codec.c
--- kernel-2.6.23mamba.orig/sound/pci/hda/hda_codec.c	2007-10-09 22:31:38.000000000 +0200
+++ kernel-2.6.23mamba/sound/pci/hda/hda_codec.c	2007-12-23 17:45:32.000000000 +0100
@@ -798,6 +798,18 @@
 	return 1;
 }
 
+/*
+ * update the AMP stereo with the same mask and value
+ */
+int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
+			     int direction, int idx, int mask, int val)
+{
+	int ch, ret = 0;
+	for (ch = 0; ch < 2; ch++)
+		ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
+						idx, mask, val);
+	return ret;
+}
 
 /*
  * AMP control callbacks
@@ -1002,6 +1014,93 @@
 }
 
 /*
+ * generic bound volume/swtich controls
+ */
+int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct hda_bind_ctls *c;
+	int err;
+
+	c = (struct hda_bind_ctls *)kcontrol->private_value;
+	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+	kcontrol->private_value = *c->values;
+	err = c->ops->info(kcontrol, uinfo);
+	kcontrol->private_value = (long)c;
+	mutex_unlock(&codec->spdif_mutex);
+	return err;
+}
+
+int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct hda_bind_ctls *c;
+	int err;
+
+	c = (struct hda_bind_ctls *)kcontrol->private_value;
+	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+	kcontrol->private_value = *c->values;
+	err = c->ops->get(kcontrol, ucontrol);
+	kcontrol->private_value = (long)c;
+	mutex_unlock(&codec->spdif_mutex);
+	return err;
+}
+
+int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct hda_bind_ctls *c;
+	unsigned long *vals;
+	int err = 0, change = 0;
+
+	c = (struct hda_bind_ctls *)kcontrol->private_value;
+	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+	for (vals = c->values; *vals; vals++) {
+		kcontrol->private_value = *vals;
+		err = c->ops->put(kcontrol, ucontrol);
+		if (err < 0)
+			break;
+		change |= err;
+	}
+	kcontrol->private_value = (long)c;
+	mutex_unlock(&codec->spdif_mutex);
+	return err < 0 ? err : change;
+}
+
+int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+			   unsigned int size, unsigned int __user *tlv)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct hda_bind_ctls *c;
+	int err;
+
+	c = (struct hda_bind_ctls *)kcontrol->private_value;
+	mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+	kcontrol->private_value = *c->values;
+	err = c->ops->tlv(kcontrol, op_flag, size, tlv);
+	kcontrol->private_value = (long)c;
+	mutex_unlock(&codec->spdif_mutex);
+	return err;
+}
+
+struct hda_ctl_ops snd_hda_bind_vol = {
+	.info = snd_hda_mixer_amp_volume_info,
+	.get = snd_hda_mixer_amp_volume_get,
+	.put = snd_hda_mixer_amp_volume_put,
+	.tlv = snd_hda_mixer_amp_tlv
+};
+
+struct hda_ctl_ops snd_hda_bind_sw = {
+	.info = snd_hda_mixer_amp_switch_info,
+	.get = snd_hda_mixer_amp_switch_get,
+	.put = snd_hda_mixer_amp_switch_put,
+	.tlv = snd_hda_mixer_amp_tlv
+};
+
+/*
  * SPDIF out controls
  */
 
diff -Nru kernel-2.6.23mamba.orig/sound/pci/hda/hda_local.h kernel-2.6.23mamba/sound/pci/hda/hda_local.h
--- kernel-2.6.23mamba.orig/sound/pci/hda/hda_local.h	2007-10-09 22:31:38.000000000 +0200
+++ kernel-2.6.23mamba/sound/pci/hda/hda_local.h	2007-12-23 17:46:04.000000000 +0100
@@ -76,6 +76,12 @@
 			   int direction, int index);
 int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
 			     int direction, int idx, int mask, int val);
+int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
+			     int dir, int idx, int mask, int val);
+/* amp value bits */
+#define HDA_AMP_MUTE	0x80
+#define HDA_AMP_UNMUTE	0x00
+#define HDA_AMP_VOLMASK	0x7f
 
 /* mono switch binding multiple inputs */
 #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
@@ -91,6 +97,53 @@
 int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 
+/* more generic bound controls */
+struct hda_ctl_ops {
+	snd_kcontrol_info_t *info;
+	snd_kcontrol_get_t *get;
+	snd_kcontrol_put_t *put;
+	snd_kcontrol_tlv_rw_t *tlv;
+};
+
+extern struct hda_ctl_ops snd_hda_bind_vol;	/* for bind-volume with TLV */
+extern struct hda_ctl_ops snd_hda_bind_sw;	/* for bind-switch */
+
+struct hda_bind_ctls {
+	struct hda_ctl_ops *ops;
+	long values[];
+};
+
+int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo);
+int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+			   unsigned int size, unsigned int __user *tlv);
+
+#define HDA_BIND_VOL(xname, bindrec) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	  .name = xname, \
+	  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
+			  SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+			  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\
+	  .info = snd_hda_mixer_bind_ctls_info,\
+	  .get =  snd_hda_mixer_bind_ctls_get,\
+	  .put = snd_hda_mixer_bind_ctls_put,\
+	  .tlv = { .c = snd_hda_mixer_bind_tlv },\
+	  .private_value = (long) (bindrec) }
+#define HDA_BIND_SW(xname, bindrec) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
+	  .name = xname, \
+	  .info = snd_hda_mixer_bind_ctls_info,\
+	  .get =  snd_hda_mixer_bind_ctls_get,\
+	  .put = snd_hda_mixer_bind_ctls_put,\
+	  .private_value = (long) (bindrec) }
+
+/*
+ * SPDIF I/O
+ */
 int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
 
diff -Nru kernel-2.6.23mamba.orig/sound/pci/hda/patch_realtek.c kernel-2.6.23mamba/sound/pci/hda/patch_realtek.c
--- kernel-2.6.23mamba.orig/sound/pci/hda/patch_realtek.c	2007-10-09 22:31:38.000000000 +0200
+++ kernel-2.6.23mamba/sound/pci/hda/patch_realtek.c	2007-12-23 17:45:06.000000000 +0100
@@ -102,6 +102,8 @@
 /* ALC268 models */
 enum {
 	ALC268_3ST,
+	ALC268_TOSHIBA,
+	ALC268_ACER,
 	ALC268_AUTO,
 	ALC268_MODEL_LAST /* last tag */
 };
@@ -8170,9 +8172,125 @@
 	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
+	{ }
+};
+
+static struct hda_verb alc268_eapd_verbs[] = {
+	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
 	{ }
 };
 
+/* Toshiba specific */
+#define alc268_toshiba_automute	alc262_hippo_automute
+
+static struct hda_verb alc268_toshiba_verbs[] = {
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+	{ } /* end */
+};
+
+/* Acer specific */
+/* bind volumes of both NID 0x02 and 0x03 */
+static struct hda_bind_ctls alc268_acer_bind_master_vol = {
+	.ops = &snd_hda_bind_vol,
+	.values = {
+		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
+		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
+		0
+	},
+};
+
+/* mute/unmute internal speaker according to the hp jack and mute state */
+static void alc268_acer_automute(struct hda_codec *codec, int force)
+{
+	struct alc_spec *spec = codec->spec;
+	unsigned int mute;
+
+	if (force || !spec->sense_updated) {
+		unsigned int present;
+		present = snd_hda_codec_read(codec, 0x14, 0,
+				    	 AC_VERB_GET_PIN_SENSE, 0);
+		spec->jack_present = (present & 0x80000000) != 0;
+		spec->sense_updated = 1;
+	}
+	if (spec->jack_present)
+		mute = HDA_AMP_MUTE; /* mute internal speaker */
+	else /* unmute internal speaker if necessary */
+		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
+	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+				 HDA_AMP_MUTE, mute);
+}
+
+
+/* bind hp and internal speaker mute (with plug check) */
+static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	long *valp = ucontrol->value.integer.value;
+	int change;
+
+	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+					  HDA_AMP_MUTE,
+					  valp[0] ? 0 : HDA_AMP_MUTE);
+	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+					   HDA_AMP_MUTE,
+					   valp[1] ? 0 : HDA_AMP_MUTE);
+	if (change)
+		alc268_acer_automute(codec, 0);
+	return change;
+}
+
+static struct snd_kcontrol_new alc268_acer_mixer[] = {
+	/* output mixer control */
+	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = snd_hda_mixer_amp_switch_info,
+		.get = snd_hda_mixer_amp_switch_get,
+		.put = alc268_acer_master_sw_put,
+		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+	},
+	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
+	{ }
+};
+
+static struct hda_verb alc268_acer_verbs[] = {
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+	{ }
+};
+
+/* unsolicited event for HP jack sensing */
+static void alc268_toshiba_unsol_event(struct hda_codec *codec,
+				       unsigned int res)
+{
+	if ((res >> 26) != ALC880_HP_EVENT)
+		return;
+	alc268_toshiba_automute(codec,1);
+}
+
+static void alc268_acer_unsol_event(struct hda_codec *codec,
+				       unsigned int res)
+{
+	if ((res >> 26) != ALC880_HP_EVENT)
+		return;
+	alc268_acer_automute(codec, 1);
+}
+
+static void alc268_acer_init_hook(struct hda_codec *codec)
+{
+	alc268_acer_automute(codec, 1);
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -8551,11 +8669,19 @@
  */
 static const char *alc268_models[ALC268_MODEL_LAST] = {
 	[ALC268_3ST]		= "3stack",
+	[ALC268_TOSHIBA]	= "toshiba",
+	[ALC268_ACER]		= "acer",
 	[ALC268_AUTO]		= "auto",
 };
 
 static struct snd_pci_quirk alc268_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
+	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
+	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
+	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
+	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
+	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
+	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
 	{}
 };
 
@@ -8573,6 +8699,37 @@
 		.channel_mode = alc268_modes,
 		.input_mux = &alc268_capture_source,
 	},
+	[ALC268_TOSHIBA] = {
+		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
+		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+				alc268_toshiba_verbs },
+		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
+		.dac_nids = alc268_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
+		.adc_nids = alc268_adc_nids_alt,
+		.hp_nid = 0x03,
+		.num_channel_mode = ARRAY_SIZE(alc268_modes),
+		.channel_mode = alc268_modes,
+		.input_mux = &alc268_capture_source,
+		.input_mux = &alc268_capture_source,
+		.unsol_event = alc268_toshiba_unsol_event,
+		.init_hook = alc268_toshiba_automute,
+	},
+	[ALC268_ACER] = {
+		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
+		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+				alc268_acer_verbs },
+		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
+		.dac_nids = alc268_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
+		.adc_nids = alc268_adc_nids_alt,
+		.hp_nid = 0x02,
+		.num_channel_mode = ARRAY_SIZE(alc268_modes),
+		.channel_mode = alc268_modes,
+		.input_mux = &alc268_capture_source,
+		.unsol_event = alc268_acer_unsol_event,
+		.init_hook = alc268_acer_init_hook,
+	},	
 };
 
 static int patch_alc268(struct hda_codec *codec)
