All of lore.kernel.org
 help / color / mirror / Atom feed
* Test Patch6 for Conexant HD Audio.
@ 2006-10-25  6:18 Tobin Davis
  2006-10-25  8:03 ` Guyjo
  0 siblings, 1 reply; 8+ messages in thread
From: Tobin Davis @ 2006-10-25  6:18 UTC (permalink / raw)
  To: alsa-devel

[-- Attachment #1: Type: text/plain, Size: 346 bytes --]

Here's test patch 6 (alsa-kernel).  Test mode "should" work now (it compiles).

Let me know how it works.  Please include your system model (Ex: HP
DV8000) and your subvendor and subdevice ID from "lspci -s 0:1b -vn" so
that I can start tracking what worked and what didn't.

Thanks again for testing this.

-- 
Tobin Davis <tdavis@dsl-only.net>

[-- Attachment #2: conexant-kernel-test6.patch --]
[-- Type: text/x-patch, Size: 30217 bytes --]

--- /dev/null	2006-10-23 04:17:47.000000000 -0700
+++ alsa-kernel/pci/hda/patch_conexant.c	2006-10-24 23:06:33.000000000 -0700
@@ -0,0 +1,946 @@
+/*
+ * HD audio interface patch for Conexant HDA audio codec
+ *
+ * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
+ * 		      Takashi Iwai <tiwai@suse.de>
+ * 		      Tobin Davis  <tdavis@dsl-only.net>
+ *
+ *  This driver is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This driver is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+#define MAIN_MUX	0x1A
+#define DAC		0x10
+#define ADC		0x12
+#define SPDIF_OUT	0x11
+#define CXT_PIN_DIR_IN              0x00
+#define CXT_PIN_DIR_OUT             0x01
+#define CXT_PIN_DIR_INOUT           0x02
+#define CXT_PIN_DIR_IN_NOMICBIAS    0x03
+#define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
+
+
+
+struct conexant_spec {
+
+	struct snd_kcontrol_new *mixers[5];
+	int num_mixers;
+
+	const struct hda_verb *init_verbs[5];	/* initialization verbs
+						 * don't forget NULL termination!
+						 */
+	unsigned int num_init_verbs;
+
+	/* playback */
+	struct hda_multi_out multiout;	/* playback set-up
+					 * max_channels, dacs must be set
+					 * dig_out_nid and hp_nid are optional
+					 */
+	unsigned int cur_eapd;
+	unsigned int need_dac_fix;
+
+	/* capture */
+	unsigned int num_adc_nids;
+	hda_nid_t *adc_nids;
+	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
+
+	/* capture source */
+	const struct hda_input_mux *input_mux;
+	hda_nid_t *capsrc_nids;
+	unsigned int cur_mux[3];
+
+	/* channel model */
+	const struct hda_channel_mode *channel_mode;
+	int num_channel_mode;
+
+	/* PCM information */
+	struct hda_pcm pcm_rec[2];	/* used in build_pcms() */
+
+	struct mutex amp_mutex;	/* PCM volume/mute control mutex */
+	unsigned int spdif_route;
+
+	/* dynamic controls, init_verbs and input_mux */
+	struct auto_pin_cfg autocfg;
+	unsigned int num_kctl_alloc, num_kctl_used;
+	struct snd_kcontrol_new *kctl_alloc;
+	struct hda_input_mux private_imux;
+	hda_nid_t private_dac_nids[4];
+
+};
+
+static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
+				    struct hda_codec *codec,
+				    struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
+}
+
+static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       unsigned int stream_tag,
+				       unsigned int format,
+				       struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
+						format, substream);
+}
+
+static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
+}
+
+/*
+ * Digital out
+ */
+static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+/*
+ * Analog capture
+ */
+static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      unsigned int stream_tag,
+				      unsigned int format,
+				      struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   stream_tag, 0, format);
+	return 0;
+}
+
+static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   0, 0, 0);
+	return 0;
+}
+
+
+
+static struct hda_pcm_stream conexant_pcm_analog_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.open = conexant_playback_pcm_open,
+		.prepare = conexant_playback_pcm_prepare,
+		.cleanup = conexant_playback_pcm_cleanup
+	},
+
+};
+
+static struct hda_pcm_stream conexant_pcm_analog_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.prepare = conexant_capture_pcm_prepare,
+		.cleanup = conexant_capture_pcm_cleanup
+	},
+
+};
+
+
+static struct hda_pcm_stream conexant_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.open = conexant_dig_playback_pcm_open,
+		.close = conexant_dig_playback_pcm_close
+	},
+};
+
+static struct hda_pcm_stream conexant_pcm_digital_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in alc_build_pcms */
+};
+
+static int conexant_build_pcms(struct hda_codec *codec) {
+	struct conexant_spec *spec = codec->spec;
+	struct hda_pcm *info = spec->pcm_rec;
+
+	codec->num_pcms = 1;
+	codec->pcm_info = info;
+
+	info->name = "CONEXANT Analog";
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+	info->stream[SNDRV_PCM_STREAM_CAPTURE] = conexant_pcm_analog_capture;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+
+	if (spec->multiout.dig_out_nid) {
+		info++;
+		codec->num_pcms++;
+		info->name = "Conexant Digital";
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_digital_playback;
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+		if (spec->dig_in_nid) {
+			info->stream[SNDRV_PCM_STREAM_CAPTURE] = conexant_pcm_digital_capture;
+			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+		}
+	}
+
+	return 0;
+}
+/*   */
+static struct hda_input_mux conexant_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "ExtMic", 0x1 },
+		{ "IntMic", 0x2 },
+		{ "Line", 0x3 },
+		{ "CD", 0x4 }
+	}
+};
+
+static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
+	       			  struct snd_ctl_elem_info *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+
+	return snd_hda_input_mux_info(spec->input_mux, uinfo);
+}
+
+static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
+	return 0;
+}
+
+static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
+				     spec->capsrc_nids[adc_idx],
+				     &spec->cur_mux[adc_idx]);
+}
+
+static int conexant_init(struct hda_codec *codec) {
+	struct conexant_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->num_init_verbs; i++)
+		snd_hda_sequence_write(codec, spec->init_verbs[i]);
+	return 0;
+}
+
+static void conexant_free(struct hda_codec *codec) {
+        struct conexant_spec *spec = codec->spec;
+        unsigned int i;
+
+        if (spec->kctl_alloc) {
+                for (i = 0; i < spec->num_kctl_used; i++)
+                        kfree(spec->kctl_alloc[i].name);
+                kfree(spec->kctl_alloc);
+        }
+
+	kfree(codec->spec);
+}
+
+#ifdef CONFIG_PM
+static int conexant_resume(struct hda_codec *codec)
+{
+	struct conexant_spec *spec = codec->spec;
+	int i;
+
+	codec->patch_ops.init(codec);
+	for (i = 0; i < spec->num_mixers; i++)
+		snd_hda_resume_ctls(codec, spec->mixers[i]);
+	if (spec->multiout.dig_out_nid)
+		snd_hda_resume_spdif_out(codec);
+	if (spec->dig_in_nid)
+		snd_hda_resume_spdif_in(codec);
+	return 0;
+}
+#endif
+
+static int conexant_build_controls(struct hda_codec *codec) {
+	struct conexant_spec *spec = codec->spec;
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < spec->num_mixers; i++) {
+		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
+		if (err < 0)
+			return err;
+	}
+	if (spec->multiout.dig_out_nid) {
+		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+		if (err < 0)
+			return err;
+	} 
+	if (spec->dig_in_nid) {
+		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+static struct hda_codec_ops conexant_patch_ops = {
+	.build_controls = conexant_build_controls,
+	.build_pcms = conexant_build_pcms,
+	.init = conexant_init,
+	.free = conexant_free,
+#ifdef CONFIG_PM
+	.resume = conexant_resume,
+#endif
+};
+
+/*
+ * EAPD control
+ * the private value = nid | (invert << 8)
+ */
+
+#define CXT5047_HP_EVENT	0x37
+#define CXT5047_MIC_EVENT	0x38
+
+
+static int conexant_eapd_info(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int conexant_eapd_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int invert = (kcontrol->private_value >> 8) & 1;
+	if (invert)
+		ucontrol->value.integer.value[0] = ! spec->cur_eapd;
+	else
+		ucontrol->value.integer.value[0] = spec->cur_eapd;
+	return 0;
+}
+
+static int conexant_eapd_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int invert = (kcontrol->private_value >> 8) & 1;
+	hda_nid_t nid = kcontrol->private_value & 0xff;
+	unsigned int eapd;
+	eapd = ucontrol->value.integer.value[0];
+	if (invert)
+		eapd = !eapd;
+	if (eapd == spec->cur_eapd && ! codec->in_resume)
+		return 0;
+	spec->cur_eapd = eapd;
+	snd_hda_codec_write(codec, nid,
+			    0, AC_VERB_SET_EAPD_BTLENABLE,
+			    eapd ? 0x02 : 0x00);
+	return 1;
+}
+
+static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
+				    spec->num_channel_mode);
+}
+
+static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
+				   spec->num_channel_mode, spec->multiout.max_channels);
+}
+
+static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
+				      spec->num_channel_mode,
+				      &spec->multiout.max_channels);
+	if (err >= 0 && spec->need_dac_fix)
+		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
+	return err;
+}
+
+
+/* Conexant 5047 specific */
+
+static hda_nid_t cxt5047_dac_nids[1] = { 0x10 };
+static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
+static hda_nid_t cxt5047_capsrc_nids[1] = { 0x19 };
+
+
+/* turn on/off EAPD (+ mute HP) as a master switch */
+static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+
+	if (! conexant_eapd_put(kcontrol, ucontrol))
+		return 0;
+
+	/* toggle HP mute appropriately */
+	snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
+				 0x80, spec->cur_eapd ? 0 : 0x80);
+	snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
+				 0x80, spec->cur_eapd ? 0 : 0x80);
+	return 1;
+}
+
+/* bind volumes of both NID 0x13 and 0x14 */
+static int cxt5047_hp_master_vol_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,
+					  0x7f, valp[0] & 0x7f);
+	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+					   0x7f, valp[1] & 0x7f);
+	snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
+				 0x7f, valp[0] & 0x7f);
+	snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
+				 0x7f, valp[1] & 0x7f);
+	return change;
+}
+
+
+/* mute internal speaker if HP is plugged */
+static void cxt5047_hp_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x13, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+}
+
+/* toggle input of built-in and mic jack appropriately */
+static void cxt5047_hp_automic(struct hda_codec *codec)
+{
+	static struct hda_verb mic_jack_on[] = {
+		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+		{}
+	};
+	static struct hda_verb mic_jack_off[] = {
+		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+		{}
+	};
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x08, 0,
+			    	 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	if (present)
+		snd_hda_sequence_write(codec, mic_jack_on);
+	else
+		snd_hda_sequence_write(codec, mic_jack_off);
+}
+
+/* unsolicited event for HP jack sensing */
+static void cxt5047_hp_unsol_event(struct hda_codec *codec,
+				  unsigned int res)
+{
+	res >>= 26;
+	switch (res) {
+	case CXT5047_HP_EVENT:
+		cxt5047_hp_automute(codec);
+		break;
+	case CXT5047_MIC_EVENT:
+		cxt5047_hp_automic(codec);
+		break;
+	}
+}
+
+static struct snd_kcontrol_new cxt5047_mixers[] = {
+	{
+	  .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	  .name = "Capture Source",
+	  .info = conexant_mux_enum_info,
+	  .get = conexant_mux_enum_get,
+	  .put = conexant_mux_enum_put
+	},
+	HDA_CODEC_VOLUME("Mic Bypass Capture Volume",0x19,0x02,HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Bypass Capture Switch",0x19,0x02,HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume",0x12,0x03,HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch",0x12,0x03,HDA_INPUT),
+	HDA_CODEC_VOLUME("PCM Volume",0x10,0x00,HDA_OUTPUT),
+	HDA_CODEC_MUTE("PCM Switch",0x10,0x00,HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume",0x13,0x00,HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch",0x13,0x00,HDA_OUTPUT),
+	{}
+};
+#if 0
+static struct snd_kcontrol_new cxt5047_hp_mixers[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Volume",
+		.info = snd_hda_mixer_amp_volume_info,
+		.get = snd_hda_mixer_amp_volume_get,
+		.put = cxt5047_hp_master_vol_put,
+		.private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = conexant_eapd_info,
+		.get = conexant_eapd_get,
+		.put = cxt5047_hp_master_sw_put,
+		.private_value = 0x13,
+	},
+	HDA_CODEC_VOLUME("PCM Playback Volume", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("PCM Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = conexant_mux_enum_info,
+		.get = conexant_mux_enum_get,
+		.put = conexant_mux_enum_put,
+	},
+	{ } /* end */
+};
+#endif
+
+static struct hda_verb cxt5047_init_verbs[] = {
+	/* Line in, Mic, Built-in Mic */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
+	/* HP, Amp  */
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{0x1A, AC_VERB_SET_CONNECT_SEL,0x01},
+	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
+	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
+	/* Record selector: Front mic */
+	{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
+	/* SPDIF route: PCM */
+	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
+	{ } /* end */
+};
+
+/* configuration for Toshiba Laptops */
+static struct hda_verb cxt5047_toshiba_init_verbs[] = {
+	{0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
+	/* pin sensing on HP and Mic jacks */
+	{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_HP_EVENT},
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_MIC_EVENT},
+	{}
+};
+
+/* configuration for HP Laptops */
+static struct hda_verb cxt5047_hp_init_verbs[] = {
+	/* pin sensing on HP and Mic jacks */
+	{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_HP_EVENT},
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_MIC_EVENT},
+	{}
+};
+/* Test configuration for debugging, modelled after the ALC260 test
+ * configuration.
+ */
+#ifdef CONFIG_SND_DEBUG
+static struct hda_input_mux cxt5047_test_capture_sources[1] = {
+	{
+		.num_items = 6,
+		.items = {
+			{ "MIXER", 0x0 },
+			{ "LINE1 pin", 0x1 },
+			{ "MIC1 pin", 0x2 },
+			{ "MIC2 pin", 0x3 },
+			{ "CD pin", 0x4 },
+			{ "HP-OUT pin", 0x5 },
+		},
+        },
+};
+
+#define CXT_PIN_MODE(xname, nid, dir) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = conexant_ch_mode_info, \
+	  .get = conexant_ch_mode_get, \
+	  .put = conexant_ch_mode_put, \
+	  .private_value = nid | (dir<<16) }
+
+static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}                                
+
+static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
+	unsigned int val = snd_hda_codec_read(codec, nid, 0,
+					      AC_VERB_GET_GPIO_DATA, 0x00);
+
+	*valp = (val & mask) != 0;
+	return 0;
+}
+
+static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	signed int change;
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long val = *ucontrol->value.integer.value;
+	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
+						    AC_VERB_GET_GPIO_DATA,
+						    0x00);
+
+	/* Set/unset the masked GPIO bit(s) as needed */
+	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
+	if (val == 0)
+		gpio_data &= ~mask;
+	else
+		gpio_data |= mask;
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
+
+	return change;
+}
+
+#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = cxt_gpio_data_info, \
+	  .get = cxt_gpio_data_get, \
+	  .put = cxt_gpio_data_put, \
+	  .private_value = nid | (mask<<16) }
+
+static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}                                
+
+static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
+	unsigned int val = snd_hda_codec_read(codec, nid, 0,
+					      AC_VERB_GET_DIGI_CONVERT, 0x00);
+
+	*valp = (val & mask) != 0;
+	return 0;
+}
+
+static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	signed int change;
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long val = *ucontrol->value.integer.value;
+	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
+						    AC_VERB_GET_DIGI_CONVERT,
+						    0x00);
+
+	/* Set/unset the masked control bit(s) as needed */
+	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
+	if (val==0)
+		ctrl_data &= ~mask;
+	else
+		ctrl_data |= mask;
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+			    ctrl_data);
+
+	return change;
+}
+
+#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = cxt_spdif_ctrl_info, \
+	  .get = cxt_spdif_ctrl_get, \
+	  .put = cxt_spdif_ctrl_put, \
+	  .private_value = nid | (mask<<16) }
+
+static struct snd_kcontrol_new cxt5047_test_mixer[] = {
+
+	/* Modes for retasking pin widgets */
+	CXT_PIN_MODE("HP-OUT pin mode", 0x13, CXT_PIN_DIR_INOUT),
+	CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
+	CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
+
+	/* Loopback mixer controls */
+	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x19, 0x00, HDA_INPUT),
+	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x19, 0x00, HDA_INPUT),
+	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x19, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x19, 0x01, HDA_INPUT),
+	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x19, 0x03, HDA_INPUT),
+	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x19, 0x03, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x19, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x19, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x19, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x19, 0x05, HDA_INPUT),
+	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x19, 0x06, HDA_INPUT),
+	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x19, 0x06, HDA_INPUT),
+	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x19, 0x07, HDA_INPUT),
+	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x19, 0x07, HDA_INPUT),
+
+	/* Controls for GPIO pins, assuming they exist and are configured as outputs */
+	CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
+	CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
+	CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
+	CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
+
+	CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x18, 0x01),
+
+	HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input Source",
+		.info = conexant_mux_enum_info,
+		.get = conexant_mux_enum_get,
+		.put = conexant_mux_enum_put,
+	},
+
+	{ } /* end */
+};
+
+static struct hda_verb cxt5047_test_init_verbs[] = {
+	/* Enable all GPIOs as outputs with an initial value of 0 */
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
+
+	/* Enable retasking pins as output, initially without power amp */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+	/* Disable digital (SPDIF) pins initially, but users can enable
+	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
+	 * payload also sets the generation to 0, output to be in "consumer"
+	 * PCM format, copyright asserted, no pre-emphasis and no validity
+	 * control.
+	 */
+	{0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
+
+	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
+	 * OUT1 sum bus when acting as an output.
+	 */
+	{0x1a, AC_VERB_SET_CONNECT_SEL, 0},
+	{0x1b, AC_VERB_SET_CONNECT_SEL, 0},
+
+	/* Start with output sum widgets muted and their output gains at min */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+
+	/* Unmute retasking pin widget output buffers since the default
+	 * state appears to be output.  As the pin mode is changed by the
+	 * user the pin mode control will take care of enabling the pin's
+	 * input/output buffers as needed.
+	 */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	/* Mute capture amp left and right */
+	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+
+	/* Set ADC connection select to match default mixer setting (mic1
+	 * pin)
+	 */
+	{0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+	/* Mute all inputs to mixer widget (even unconnected ones) */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+
+	{ }
+};
+#endif
+
+
+/* initialize jack-sensing, too */
+static int cxt5047_hp_init(struct hda_codec *codec)
+{
+	conexant_init(codec);
+	cxt5047_hp_automute(codec);
+	cxt5047_hp_automic(codec);
+	return 0;
+}
+
+
+enum {  CXT5047_LAPTOP,
+#ifdef CONFIG_SND_DEBUG
+	CXT5047_TEST,
+#endif
+	CXT5047_LAPTOP_EAPD };
+
+static struct hda_board_config cxt5047_cfg_tbl[] = {
+	/* Laptops w/o EAPD support */
+	{ .modelname = "laptop", .config = CXT5047_LAPTOP },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30a0, 
+	  .config = CXT5047_LAPTOP }, /*HP DV1000 */
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30b2,
+	  .config = CXT5047_LAPTOP }, /*HP DV2000T */
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30a5,
+	  .config = CXT5047_LAPTOP }, /*HP DV8000 */
+	/* Laptops with EAPD support */
+	{ .modelname = "laptop-eapd", .config = CXT5047_LAPTOP_EAPD },
+	{ .pci_subvendor = 0x1179, .pci_subdevice = 0xff31,
+	  .config = CXT5047_LAPTOP_EAPD }, /* Toshiba P100 */
+#ifdef CONFIG_SND_DEBUG
+	{ .modelname = "test", .config = CXT5047_TEST },
+#endif
+	
+	{}
+};
+
+static int patch_cxt5047(struct hda_codec *codec) {
+	struct conexant_spec *spec;
+	int board_config;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if ( !spec )
+		return -ENOMEM;
+	mutex_init(&spec->amp_mutex);
+	codec->spec = spec;
+
+	spec->multiout.max_channels = 2;
+	spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
+	spec->multiout.dac_nids = cxt5047_dac_nids;
+	spec->multiout.dig_out_nid = SPDIF_OUT;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = cxt5047_adc_nids;
+	spec->capsrc_nids = cxt5047_capsrc_nids;
+	spec->input_mux = &conexant_capture_source;
+	spec->num_mixers = 1;
+	spec->mixers[0] = cxt5047_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = cxt5047_init_verbs;
+	spec->spdif_route = 0;
+
+	codec->patch_ops = conexant_patch_ops;
+	codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
+	/* Place holder for different board configurations */
+	board_config = snd_hda_check_board_config(codec, cxt5047_cfg_tbl);
+	switch (board_config) {
+	case CXT5047_LAPTOP:
+		spec->num_init_verbs = 2;
+		spec->init_verbs[1] = cxt5047_hp_init_verbs;
+
+		codec->patch_ops.init = cxt5047_hp_init;
+		break;
+	case CXT5047_LAPTOP_EAPD:
+		spec->num_init_verbs = 2;
+		spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
+		break;
+#ifdef CONFIG_SND_DEBUG
+	case CXT5047_TEST:
+		spec->input_mux = cxt5047_test_capture_sources;
+		spec->mixers[0] = cxt5047_test_mixer;
+		spec->init_verbs[0] = cxt5047_test_init_verbs;
+#endif	
+	}
+	return 0;
+}
+
+struct hda_codec_preset snd_hda_preset_conexant[] = {
+	{ .id = 0x14f15047, .name = "CXT5047", .patch = patch_cxt5047 },
+	{} /* terminator */
+};

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 161 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Test Patch6 for Conexant HD Audio.
  2006-10-25  6:18 Test Patch6 for Conexant HD Audio Tobin Davis
@ 2006-10-25  8:03 ` Guyjo
  0 siblings, 0 replies; 8+ messages in thread
From: Guyjo @ 2006-10-25  8:03 UTC (permalink / raw)
  To: alsa-devel

Hi All,
My system: Toshiba P100-114
*lspci -s 0:1b -vn*:
00:1b.0 0403: 8086:27d8 (rev 02)
        Subsystem: 1179:ff31
        Flags: bus master, fast devsel, latency 0, IRQ 21
        Memory at b0000000 (64-bit, non-prefetchable) [size=16K]
        Capabilities: [50] Power Management version 2
        Capabilities: [60] Message Signalled Interrupts: 64bit+
Queue=0/0 Enable-
        Capabilities: [70] Express Unknown type IRQ 0
        Capabilities: [100] Virtual Channel
        Capabilities: [130] Unknown (5)

Patch 6 applied:

4 options in alsamixer (Master, PCM, Line, and Mic) with only Master
mutable/unmutable !
Still no sound !

@+
Guyjo!

PS:
*cat /proc/asound/card0/codec#0*
Codec: Conexant ID 5047
Address: 0
Vendor Id: 0x14f15047
Subsystem Id: 0x1179ff31
Revision Id: 0x100000
Default PCM: rates 0x040, bits 0x02, types 0x1
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
Node 0x10 [Audio Output] wcaps 0x41d: Stereo Amp-Out
  Amp-Out caps: ofs=0x17, nsteps=0x1e, stepsize=0x05, mute=1
  Amp-Out vals:  [0x1e 0x1e]
  PCM: rates 0x040, bits 0x02, types 0x1
  Power: 0x0
Node 0x11 [Audio Output] wcaps 0x611: Stereo Digital
  PCM: rates 0x040, bits 0x02, types 0x1
  Power: 0x0
Node 0x12 [Audio Input] wcaps 0x100d1b: Stereo Amp-In
  Amp-In caps: ofs=0x00, nsteps=0x0e, stepsize=0x05, mute=1
  Amp-In vals:  [0x0e 0x0e] [0x80 0x80] [0x80 0x80] [0x80 0x80] [0x80
0x80] [0x80 0x80]
  PCM: rates 0x040, bits 0x02, types 0x1
  Power: 0x0
  Connection: 6
     0x19 0x14* 0x15 0x1a 0x16 0x10
Node 0x13 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
  Amp-Out caps: ofs=0x1f, nsteps=0x1e, stepsize=0x05, mute=1
  Amp-Out vals:  [0x1e 0x1e]
  Pincap 0x081001c: OUT HP EAPD Detect
  Pin Default 0xc3111010: [Both] Speaker at Ext Left
    Conn = 1/8, Color = Black
  Pin-ctls: 0xc0: OUT HP
  Power: 0x0
  Connection: 3
     0x19* 0x10 0x16
Node 0x14 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
  Amp-Out caps: ofs=0x1f, nsteps=0x1e, stepsize=0x05, mute=1
  Amp-Out vals:  [0x1f 0x1f]
  Pincap 0x0833c: IN OUT HP Detect
  Pin Default 0x03811011: [Jack] Line In at Ext Left
    Conn = 1/8, Color = Black
  Pin-ctls: 0x20: IN
  Power: 0x0
  Connection: 2
     0x19* 0x16
Node 0x15 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
  Amp-Out caps: ofs=0x1f, nsteps=0x1e, stepsize=0x05, mute=1
  Amp-Out vals:  [0x1f 0x1f]
  Pincap 0x0833c: IN OUT HP Detect
  Pin Default 0x03a11012: [Jack] Mic at Ext Left
    Conn = 1/8, Color = Black
  Pin-ctls: 0x20: IN
  Power: 0x0
  Connection: 3
     0x1c 0x19* 0x16
Node 0x16 [Pin Complex] wcaps 0x400401: Stereo
  Pincap 0x0860: IN
  Pin Default 0x99330100: [Fixed] CD at Int ATAPI
    Conn = ATAPI, Color = Unknown
  Pin-ctls: 0x20: IN
  Power: 0x0
Node 0x17 [Pin Complex] wcaps 0x400481: Stereo
  Pincap 0x08324: IN Detect
  Pin Default 0xb7a00100: [Fixed] Mic at Oth Mobile-In
    Conn = Unknown, Color = Unknown
  Pin-ctls: 0x00:
  Power: 0x0
Node 0x18 [Pin Complex] wcaps 0x400701: Stereo Digital
  Pincap 0x0810: OUT
  Pin Default 0x21440100: [Jack] SPDIF Out at Sep Rear
    Conn = RCA, Color = Unknown
  Pin-ctls: 0x00:
  Power: 0x0
  Connection: 1
     0x11
Node 0x19 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
  Amp-In caps: ofs=0x17, nsteps=0x1e, stepsize=0x05, mute=1
  Amp-In vals:  [0x07 0x07] [0x80 0x80] [0x80 0x80] [0x17 0x17]
  Power: 0x0
  Connection: 4
     0x10 0x1b 0x1a 0x16
Node 0x1a [Audio Selector] wcaps 0x30050d: Stereo Amp-Out
  Amp-Out caps: ofs=0x00, nsteps=0x03, stepsize=0x1f, mute=0
  Amp-Out vals:  [0x00 0x00]
  Power: 0x0
  Connection: 3
     0x15* 0x14 0x17
Node 0x1b [Audio Selector] wcaps 0x300501: Stereo
  Power: 0x0
  Connection: 2
     0x14* 0x15
Node 0x1c [Audio Output] wcaps 0x41d: Stereo Amp-Out
  Amp-Out caps: ofs=0x17, nsteps=0x1e, stepsize=0x05, mute=1
  Amp-Out vals:  [0x80 0x80]
  PCM: rates 0x040, bits 0x02, types 0x1
  Power: 0x0
Node 0x1d [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
  Amp-Out caps: ofs=0x1f, nsteps=0x1e, stepsize=0x05, mute=1
  Amp-Out vals:  [0x1f 0x1f]
  Pincap 0x08314: OUT Detect
  Pin Default 0x90100112: [Fixed] Speaker at Int N/A
    Conn = Unknown, Color = Unknown
  Pin-ctls: 0x40: OUT
  Power: 0x0
  Connection: 3
     0x1c 0x19* 0x16
Node 0x1e [Vendor Defined Widget] wcaps 0xf00000: Mono

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Test Patch6 for Conexant HD Audio.
@ 2006-10-26 17:30 Nick Fortune
  2006-10-26 17:34 ` Takashi Iwai
  2006-10-26 18:13 ` Tobin Davis
  0 siblings, 2 replies; 8+ messages in thread
From: Nick Fortune @ 2006-10-26 17:30 UTC (permalink / raw)
  To: alsa-devel

> Here's test patch 6 (alsa-kernel). 

I'd like to help test this, but the patch on the sourceforge archive
seems to be truncated. 

Is it worth sending me a copy, or should I jsut wait for the next 
patch? I've got a Tosh P100-240 running Gentoo with a 2.6.18 kernel
if that helps at all

Nick
-- 
Don't let THEM immanentize the Eschaton!


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Test Patch6 for Conexant HD Audio.
  2006-10-26 17:30 Nick Fortune
@ 2006-10-26 17:34 ` Takashi Iwai
  2006-10-26 18:13 ` Tobin Davis
  1 sibling, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2006-10-26 17:34 UTC (permalink / raw)
  To: Nick Fortune; +Cc: alsa-devel

At Thu, 26 Oct 2006 18:30:31 +0100,
Nick Fortune wrote:
> 
> > Here's test patch 6 (alsa-kernel). 
> 
> I'd like to help test this, but the patch on the sourceforge archive
> seems to be truncated. 
> 
> Is it worth sending me a copy, or should I jsut wait for the next 
> patch? I've got a Tosh P100-240 running Gentoo with a 2.6.18 kernel
> if that helps at all

You can get it from gmane, too:
	http://article.gmane.org/gmane.linux.alsa.devel/41480


Takashi

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Test Patch6 for Conexant HD Audio.
  2006-10-26 17:30 Nick Fortune
  2006-10-26 17:34 ` Takashi Iwai
@ 2006-10-26 18:13 ` Tobin Davis
  2006-10-26 18:45   ` Nick Fortune
  1 sibling, 1 reply; 8+ messages in thread
From: Tobin Davis @ 2006-10-26 18:13 UTC (permalink / raw)
  To: Nick Fortune; +Cc: alsa-devel

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

I just looked over the patch and found that it was incomplete.  In
reviewing my commandline history, I discovered that test6 didn't get the
alsa-kernel base patch (it only had the patch_conexant.c code), required
for building this code.

Here is the real test6 patch.  It should work against both the alsa HG
tip and the alsa-driver-1.0.13.tar.bz2 download.  Earlier versions of
alsa have not been compile tested.

Tobin

On Thu, 2006-10-26 at 18:30 +0100, Nick Fortune wrote:
> > Here's test patch 6 (alsa-kernel). 
> 
> I'd like to help test this, but the patch on the sourceforge archive
> seems to be truncated. 
> 
> Is it worth sending me a copy, or should I jsut wait for the next 
> patch? I've got a Tosh P100-240 running Gentoo with a 2.6.18 kernel
> if that helps at all
> 
> Nick
-- 
Tobin Davis <tdavis@dsl-only.net>

[-- Attachment #2: conexant-kernel-test6.patch --]
[-- Type: text/x-patch, Size: 32011 bytes --]

diff -r d7fe584f7395 Documentation/ALSA-Configuration.txt
--- a/Documentation/ALSA-Configuration.txt	Thu Oct 19 20:35:56 2006 +0200
+++ b/Documentation/ALSA-Configuration.txt	Sun Oct 22 10:03:13 2006 -0700
@@ -865,6 +865,9 @@ Prior to version 0.9.0rc4 options had a 
 	  laptop	3-jack with hp-jack automute
 	  laptop-dig	ditto with SPDIF
 	  auto		auto-config reading BIOS (default)
+	
+	Conexant
+	  laptop	Laptop config with SPDIF
 
 	STAC9200/9205/9220/9221/9254
 	  ref		Reference board
diff -r d7fe584f7395 pci/hda/Makefile
--- a/pci/hda/Makefile	Thu Oct 19 20:35:56 2006 +0200
+++ b/pci/hda/Makefile	Sun Oct 22 10:03:13 2006 -0700
@@ -1,5 +1,5 @@ snd-hda-intel-objs := hda_intel.o
 snd-hda-intel-objs := hda_intel.o
-snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o patch_atihdmi.o
+snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o patch_atihdmi.o patch_conexant.o
 ifdef CONFIG_PROC_FS
 snd-hda-codec-objs += hda_proc.o
 endif
diff -r d7fe584f7395 pci/hda/hda_patch.h
--- a/pci/hda/hda_patch.h	Thu Oct 19 20:35:56 2006 +0200
+++ b/pci/hda/hda_patch.h	Sun Oct 22 10:03:13 2006 -0700
@@ -14,6 +14,8 @@ extern struct hda_codec_preset snd_hda_p
 extern struct hda_codec_preset snd_hda_preset_si3054[];
 /* ATI HDMI codecs */
 extern struct hda_codec_preset snd_hda_preset_atihdmi[];
+/* Conexant audio codec */
+extern struct hda_codec_preset snd_hda_preset_conexant[];
 
 static const struct hda_codec_preset *hda_preset_tables[] = {
 	snd_hda_preset_realtek,
@@ -22,5 +24,6 @@ static const struct hda_codec_preset *hd
 	snd_hda_preset_sigmatel,
 	snd_hda_preset_si3054,
 	snd_hda_preset_atihdmi,
+	snd_hda_preset_conexant,
 	NULL
 };
--- /dev/null	2006-10-23 04:17:47.000000000 -0700
+++ alsa-kernel/pci/hda/patch_conexant.c	2006-10-24 23:06:33.000000000 -0700
@@ -0,0 +1,946 @@
+/*
+ * HD audio interface patch for Conexant HDA audio codec
+ *
+ * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
+ * 		      Takashi Iwai <tiwai@suse.de>
+ * 		      Tobin Davis  <tdavis@dsl-only.net>
+ *
+ *  This driver is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This driver is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+#define MAIN_MUX	0x1A
+#define DAC		0x10
+#define ADC		0x12
+#define SPDIF_OUT	0x11
+#define CXT_PIN_DIR_IN              0x00
+#define CXT_PIN_DIR_OUT             0x01
+#define CXT_PIN_DIR_INOUT           0x02
+#define CXT_PIN_DIR_IN_NOMICBIAS    0x03
+#define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
+
+
+
+struct conexant_spec {
+
+	struct snd_kcontrol_new *mixers[5];
+	int num_mixers;
+
+	const struct hda_verb *init_verbs[5];	/* initialization verbs
+						 * don't forget NULL termination!
+						 */
+	unsigned int num_init_verbs;
+
+	/* playback */
+	struct hda_multi_out multiout;	/* playback set-up
+					 * max_channels, dacs must be set
+					 * dig_out_nid and hp_nid are optional
+					 */
+	unsigned int cur_eapd;
+	unsigned int need_dac_fix;
+
+	/* capture */
+	unsigned int num_adc_nids;
+	hda_nid_t *adc_nids;
+	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
+
+	/* capture source */
+	const struct hda_input_mux *input_mux;
+	hda_nid_t *capsrc_nids;
+	unsigned int cur_mux[3];
+
+	/* channel model */
+	const struct hda_channel_mode *channel_mode;
+	int num_channel_mode;
+
+	/* PCM information */
+	struct hda_pcm pcm_rec[2];	/* used in build_pcms() */
+
+	struct mutex amp_mutex;	/* PCM volume/mute control mutex */
+	unsigned int spdif_route;
+
+	/* dynamic controls, init_verbs and input_mux */
+	struct auto_pin_cfg autocfg;
+	unsigned int num_kctl_alloc, num_kctl_used;
+	struct snd_kcontrol_new *kctl_alloc;
+	struct hda_input_mux private_imux;
+	hda_nid_t private_dac_nids[4];
+
+};
+
+static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
+				    struct hda_codec *codec,
+				    struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
+}
+
+static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       unsigned int stream_tag,
+				       unsigned int format,
+				       struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
+						format, substream);
+}
+
+static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
+}
+
+/*
+ * Digital out
+ */
+static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+/*
+ * Analog capture
+ */
+static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      unsigned int stream_tag,
+				      unsigned int format,
+				      struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   stream_tag, 0, format);
+	return 0;
+}
+
+static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   0, 0, 0);
+	return 0;
+}
+
+
+
+static struct hda_pcm_stream conexant_pcm_analog_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.open = conexant_playback_pcm_open,
+		.prepare = conexant_playback_pcm_prepare,
+		.cleanup = conexant_playback_pcm_cleanup
+	},
+
+};
+
+static struct hda_pcm_stream conexant_pcm_analog_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.prepare = conexant_capture_pcm_prepare,
+		.cleanup = conexant_capture_pcm_cleanup
+	},
+
+};
+
+
+static struct hda_pcm_stream conexant_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.open = conexant_dig_playback_pcm_open,
+		.close = conexant_dig_playback_pcm_close
+	},
+};
+
+static struct hda_pcm_stream conexant_pcm_digital_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in alc_build_pcms */
+};
+
+static int conexant_build_pcms(struct hda_codec *codec) {
+	struct conexant_spec *spec = codec->spec;
+	struct hda_pcm *info = spec->pcm_rec;
+
+	codec->num_pcms = 1;
+	codec->pcm_info = info;
+
+	info->name = "CONEXANT Analog";
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+	info->stream[SNDRV_PCM_STREAM_CAPTURE] = conexant_pcm_analog_capture;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+
+	if (spec->multiout.dig_out_nid) {
+		info++;
+		codec->num_pcms++;
+		info->name = "Conexant Digital";
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_digital_playback;
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+		if (spec->dig_in_nid) {
+			info->stream[SNDRV_PCM_STREAM_CAPTURE] = conexant_pcm_digital_capture;
+			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+		}
+	}
+
+	return 0;
+}
+/*   */
+static struct hda_input_mux conexant_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "ExtMic", 0x1 },
+		{ "IntMic", 0x2 },
+		{ "Line", 0x3 },
+		{ "CD", 0x4 }
+	}
+};
+
+static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
+	       			  struct snd_ctl_elem_info *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+
+	return snd_hda_input_mux_info(spec->input_mux, uinfo);
+}
+
+static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
+	return 0;
+}
+
+static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
+				     spec->capsrc_nids[adc_idx],
+				     &spec->cur_mux[adc_idx]);
+}
+
+static int conexant_init(struct hda_codec *codec) {
+	struct conexant_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->num_init_verbs; i++)
+		snd_hda_sequence_write(codec, spec->init_verbs[i]);
+	return 0;
+}
+
+static void conexant_free(struct hda_codec *codec) {
+        struct conexant_spec *spec = codec->spec;
+        unsigned int i;
+
+        if (spec->kctl_alloc) {
+                for (i = 0; i < spec->num_kctl_used; i++)
+                        kfree(spec->kctl_alloc[i].name);
+                kfree(spec->kctl_alloc);
+        }
+
+	kfree(codec->spec);
+}
+
+#ifdef CONFIG_PM
+static int conexant_resume(struct hda_codec *codec)
+{
+	struct conexant_spec *spec = codec->spec;
+	int i;
+
+	codec->patch_ops.init(codec);
+	for (i = 0; i < spec->num_mixers; i++)
+		snd_hda_resume_ctls(codec, spec->mixers[i]);
+	if (spec->multiout.dig_out_nid)
+		snd_hda_resume_spdif_out(codec);
+	if (spec->dig_in_nid)
+		snd_hda_resume_spdif_in(codec);
+	return 0;
+}
+#endif
+
+static int conexant_build_controls(struct hda_codec *codec) {
+	struct conexant_spec *spec = codec->spec;
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < spec->num_mixers; i++) {
+		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
+		if (err < 0)
+			return err;
+	}
+	if (spec->multiout.dig_out_nid) {
+		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+		if (err < 0)
+			return err;
+	} 
+	if (spec->dig_in_nid) {
+		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+static struct hda_codec_ops conexant_patch_ops = {
+	.build_controls = conexant_build_controls,
+	.build_pcms = conexant_build_pcms,
+	.init = conexant_init,
+	.free = conexant_free,
+#ifdef CONFIG_PM
+	.resume = conexant_resume,
+#endif
+};
+
+/*
+ * EAPD control
+ * the private value = nid | (invert << 8)
+ */
+
+#define CXT5047_HP_EVENT	0x37
+#define CXT5047_MIC_EVENT	0x38
+
+
+static int conexant_eapd_info(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int conexant_eapd_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int invert = (kcontrol->private_value >> 8) & 1;
+	if (invert)
+		ucontrol->value.integer.value[0] = ! spec->cur_eapd;
+	else
+		ucontrol->value.integer.value[0] = spec->cur_eapd;
+	return 0;
+}
+
+static int conexant_eapd_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int invert = (kcontrol->private_value >> 8) & 1;
+	hda_nid_t nid = kcontrol->private_value & 0xff;
+	unsigned int eapd;
+	eapd = ucontrol->value.integer.value[0];
+	if (invert)
+		eapd = !eapd;
+	if (eapd == spec->cur_eapd && ! codec->in_resume)
+		return 0;
+	spec->cur_eapd = eapd;
+	snd_hda_codec_write(codec, nid,
+			    0, AC_VERB_SET_EAPD_BTLENABLE,
+			    eapd ? 0x02 : 0x00);
+	return 1;
+}
+
+static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
+				    spec->num_channel_mode);
+}
+
+static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
+				   spec->num_channel_mode, spec->multiout.max_channels);
+}
+
+static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
+				      spec->num_channel_mode,
+				      &spec->multiout.max_channels);
+	if (err >= 0 && spec->need_dac_fix)
+		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
+	return err;
+}
+
+
+/* Conexant 5047 specific */
+
+static hda_nid_t cxt5047_dac_nids[1] = { 0x10 };
+static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
+static hda_nid_t cxt5047_capsrc_nids[1] = { 0x19 };
+
+
+/* turn on/off EAPD (+ mute HP) as a master switch */
+static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+
+	if (! conexant_eapd_put(kcontrol, ucontrol))
+		return 0;
+
+	/* toggle HP mute appropriately */
+	snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
+				 0x80, spec->cur_eapd ? 0 : 0x80);
+	snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
+				 0x80, spec->cur_eapd ? 0 : 0x80);
+	return 1;
+}
+
+/* bind volumes of both NID 0x13 and 0x14 */
+static int cxt5047_hp_master_vol_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,
+					  0x7f, valp[0] & 0x7f);
+	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+					   0x7f, valp[1] & 0x7f);
+	snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
+				 0x7f, valp[0] & 0x7f);
+	snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
+				 0x7f, valp[1] & 0x7f);
+	return change;
+}
+
+
+/* mute internal speaker if HP is plugged */
+static void cxt5047_hp_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x13, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+}
+
+/* toggle input of built-in and mic jack appropriately */
+static void cxt5047_hp_automic(struct hda_codec *codec)
+{
+	static struct hda_verb mic_jack_on[] = {
+		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+		{}
+	};
+	static struct hda_verb mic_jack_off[] = {
+		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+		{}
+	};
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x08, 0,
+			    	 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	if (present)
+		snd_hda_sequence_write(codec, mic_jack_on);
+	else
+		snd_hda_sequence_write(codec, mic_jack_off);
+}
+
+/* unsolicited event for HP jack sensing */
+static void cxt5047_hp_unsol_event(struct hda_codec *codec,
+				  unsigned int res)
+{
+	res >>= 26;
+	switch (res) {
+	case CXT5047_HP_EVENT:
+		cxt5047_hp_automute(codec);
+		break;
+	case CXT5047_MIC_EVENT:
+		cxt5047_hp_automic(codec);
+		break;
+	}
+}
+
+static struct snd_kcontrol_new cxt5047_mixers[] = {
+	{
+	  .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	  .name = "Capture Source",
+	  .info = conexant_mux_enum_info,
+	  .get = conexant_mux_enum_get,
+	  .put = conexant_mux_enum_put
+	},
+	HDA_CODEC_VOLUME("Mic Bypass Capture Volume",0x19,0x02,HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Bypass Capture Switch",0x19,0x02,HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume",0x12,0x03,HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch",0x12,0x03,HDA_INPUT),
+	HDA_CODEC_VOLUME("PCM Volume",0x10,0x00,HDA_OUTPUT),
+	HDA_CODEC_MUTE("PCM Switch",0x10,0x00,HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume",0x13,0x00,HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch",0x13,0x00,HDA_OUTPUT),
+	{}
+};
+#if 0
+static struct snd_kcontrol_new cxt5047_hp_mixers[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Volume",
+		.info = snd_hda_mixer_amp_volume_info,
+		.get = snd_hda_mixer_amp_volume_get,
+		.put = cxt5047_hp_master_vol_put,
+		.private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = conexant_eapd_info,
+		.get = conexant_eapd_get,
+		.put = cxt5047_hp_master_sw_put,
+		.private_value = 0x13,
+	},
+	HDA_CODEC_VOLUME("PCM Playback Volume", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("PCM Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = conexant_mux_enum_info,
+		.get = conexant_mux_enum_get,
+		.put = conexant_mux_enum_put,
+	},
+	{ } /* end */
+};
+#endif
+
+static struct hda_verb cxt5047_init_verbs[] = {
+	/* Line in, Mic, Built-in Mic */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
+	/* HP, Amp  */
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{0x1A, AC_VERB_SET_CONNECT_SEL,0x01},
+	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
+	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
+	/* Record selector: Front mic */
+	{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
+	/* SPDIF route: PCM */
+	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
+	{ } /* end */
+};
+
+/* configuration for Toshiba Laptops */
+static struct hda_verb cxt5047_toshiba_init_verbs[] = {
+	{0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
+	/* pin sensing on HP and Mic jacks */
+	{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_HP_EVENT},
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_MIC_EVENT},
+	{}
+};
+
+/* configuration for HP Laptops */
+static struct hda_verb cxt5047_hp_init_verbs[] = {
+	/* pin sensing on HP and Mic jacks */
+	{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_HP_EVENT},
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CXT5047_MIC_EVENT},
+	{}
+};
+/* Test configuration for debugging, modelled after the ALC260 test
+ * configuration.
+ */
+#ifdef CONFIG_SND_DEBUG
+static struct hda_input_mux cxt5047_test_capture_sources[1] = {
+	{
+		.num_items = 6,
+		.items = {
+			{ "MIXER", 0x0 },
+			{ "LINE1 pin", 0x1 },
+			{ "MIC1 pin", 0x2 },
+			{ "MIC2 pin", 0x3 },
+			{ "CD pin", 0x4 },
+			{ "HP-OUT pin", 0x5 },
+		},
+        },
+};
+
+#define CXT_PIN_MODE(xname, nid, dir) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = conexant_ch_mode_info, \
+	  .get = conexant_ch_mode_get, \
+	  .put = conexant_ch_mode_put, \
+	  .private_value = nid | (dir<<16) }
+
+static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}                                
+
+static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
+	unsigned int val = snd_hda_codec_read(codec, nid, 0,
+					      AC_VERB_GET_GPIO_DATA, 0x00);
+
+	*valp = (val & mask) != 0;
+	return 0;
+}
+
+static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	signed int change;
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long val = *ucontrol->value.integer.value;
+	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
+						    AC_VERB_GET_GPIO_DATA,
+						    0x00);
+
+	/* Set/unset the masked GPIO bit(s) as needed */
+	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
+	if (val == 0)
+		gpio_data &= ~mask;
+	else
+		gpio_data |= mask;
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
+
+	return change;
+}
+
+#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = cxt_gpio_data_info, \
+	  .get = cxt_gpio_data_get, \
+	  .put = cxt_gpio_data_put, \
+	  .private_value = nid | (mask<<16) }
+
+static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}                                
+
+static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
+	unsigned int val = snd_hda_codec_read(codec, nid, 0,
+					      AC_VERB_GET_DIGI_CONVERT, 0x00);
+
+	*valp = (val & mask) != 0;
+	return 0;
+}
+
+static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	signed int change;
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
+	long val = *ucontrol->value.integer.value;
+	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
+						    AC_VERB_GET_DIGI_CONVERT,
+						    0x00);
+
+	/* Set/unset the masked control bit(s) as needed */
+	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
+	if (val==0)
+		ctrl_data &= ~mask;
+	else
+		ctrl_data |= mask;
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+			    ctrl_data);
+
+	return change;
+}
+
+#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = cxt_spdif_ctrl_info, \
+	  .get = cxt_spdif_ctrl_get, \
+	  .put = cxt_spdif_ctrl_put, \
+	  .private_value = nid | (mask<<16) }
+
+static struct snd_kcontrol_new cxt5047_test_mixer[] = {
+
+	/* Modes for retasking pin widgets */
+	CXT_PIN_MODE("HP-OUT pin mode", 0x13, CXT_PIN_DIR_INOUT),
+	CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
+	CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
+
+	/* Loopback mixer controls */
+	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x19, 0x00, HDA_INPUT),
+	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x19, 0x00, HDA_INPUT),
+	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x19, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x19, 0x01, HDA_INPUT),
+	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x19, 0x03, HDA_INPUT),
+	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x19, 0x03, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x19, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x19, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x19, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x19, 0x05, HDA_INPUT),
+	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x19, 0x06, HDA_INPUT),
+	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x19, 0x06, HDA_INPUT),
+	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x19, 0x07, HDA_INPUT),
+	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x19, 0x07, HDA_INPUT),
+
+	/* Controls for GPIO pins, assuming they exist and are configured as outputs */
+	CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
+	CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
+	CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
+	CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
+
+	CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x18, 0x01),
+
+	HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input Source",
+		.info = conexant_mux_enum_info,
+		.get = conexant_mux_enum_get,
+		.put = conexant_mux_enum_put,
+	},
+
+	{ } /* end */
+};
+
+static struct hda_verb cxt5047_test_init_verbs[] = {
+	/* Enable all GPIOs as outputs with an initial value of 0 */
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
+
+	/* Enable retasking pins as output, initially without power amp */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+	/* Disable digital (SPDIF) pins initially, but users can enable
+	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
+	 * payload also sets the generation to 0, output to be in "consumer"
+	 * PCM format, copyright asserted, no pre-emphasis and no validity
+	 * control.
+	 */
+	{0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
+
+	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
+	 * OUT1 sum bus when acting as an output.
+	 */
+	{0x1a, AC_VERB_SET_CONNECT_SEL, 0},
+	{0x1b, AC_VERB_SET_CONNECT_SEL, 0},
+
+	/* Start with output sum widgets muted and their output gains at min */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+
+	/* Unmute retasking pin widget output buffers since the default
+	 * state appears to be output.  As the pin mode is changed by the
+	 * user the pin mode control will take care of enabling the pin's
+	 * input/output buffers as needed.
+	 */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	/* Mute capture amp left and right */
+	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+
+	/* Set ADC connection select to match default mixer setting (mic1
+	 * pin)
+	 */
+	{0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+	/* Mute all inputs to mixer widget (even unconnected ones) */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+
+	{ }
+};
+#endif
+
+
+/* initialize jack-sensing, too */
+static int cxt5047_hp_init(struct hda_codec *codec)
+{
+	conexant_init(codec);
+	cxt5047_hp_automute(codec);
+	cxt5047_hp_automic(codec);
+	return 0;
+}
+
+
+enum {  CXT5047_LAPTOP,
+#ifdef CONFIG_SND_DEBUG
+	CXT5047_TEST,
+#endif
+	CXT5047_LAPTOP_EAPD };
+
+static struct hda_board_config cxt5047_cfg_tbl[] = {
+	/* Laptops w/o EAPD support */
+	{ .modelname = "laptop", .config = CXT5047_LAPTOP },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30a0, 
+	  .config = CXT5047_LAPTOP }, /*HP DV1000 */
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30b2,
+	  .config = CXT5047_LAPTOP }, /*HP DV2000T */
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30a5,
+	  .config = CXT5047_LAPTOP }, /*HP DV8000 */
+	/* Laptops with EAPD support */
+	{ .modelname = "laptop-eapd", .config = CXT5047_LAPTOP_EAPD },
+	{ .pci_subvendor = 0x1179, .pci_subdevice = 0xff31,
+	  .config = CXT5047_LAPTOP_EAPD }, /* Toshiba P100 */
+#ifdef CONFIG_SND_DEBUG
+	{ .modelname = "test", .config = CXT5047_TEST },
+#endif
+	
+	{}
+};
+
+static int patch_cxt5047(struct hda_codec *codec) {
+	struct conexant_spec *spec;
+	int board_config;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if ( !spec )
+		return -ENOMEM;
+	mutex_init(&spec->amp_mutex);
+	codec->spec = spec;
+
+	spec->multiout.max_channels = 2;
+	spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
+	spec->multiout.dac_nids = cxt5047_dac_nids;
+	spec->multiout.dig_out_nid = SPDIF_OUT;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = cxt5047_adc_nids;
+	spec->capsrc_nids = cxt5047_capsrc_nids;
+	spec->input_mux = &conexant_capture_source;
+	spec->num_mixers = 1;
+	spec->mixers[0] = cxt5047_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = cxt5047_init_verbs;
+	spec->spdif_route = 0;
+
+	codec->patch_ops = conexant_patch_ops;
+	codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
+	/* Place holder for different board configurations */
+	board_config = snd_hda_check_board_config(codec, cxt5047_cfg_tbl);
+	switch (board_config) {
+	case CXT5047_LAPTOP:
+		spec->num_init_verbs = 2;
+		spec->init_verbs[1] = cxt5047_hp_init_verbs;
+
+		codec->patch_ops.init = cxt5047_hp_init;
+		break;
+	case CXT5047_LAPTOP_EAPD:
+		spec->num_init_verbs = 2;
+		spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
+		break;
+#ifdef CONFIG_SND_DEBUG
+	case CXT5047_TEST:
+		spec->input_mux = cxt5047_test_capture_sources;
+		spec->mixers[0] = cxt5047_test_mixer;
+		spec->init_verbs[0] = cxt5047_test_init_verbs;
+#endif	
+	}
+	return 0;
+}
+
+struct hda_codec_preset snd_hda_preset_conexant[] = {
+	{ .id = 0x14f15047, .name = "CXT5047", .patch = patch_cxt5047 },
+	{} /* terminator */
+};

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 161 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Test Patch6 for Conexant HD Audio.
  2006-10-26 18:13 ` Tobin Davis
@ 2006-10-26 18:45   ` Nick Fortune
  2006-10-26 20:44     ` Nick Fortune
  0 siblings, 1 reply; 8+ messages in thread
From: Nick Fortune @ 2006-10-26 18:45 UTC (permalink / raw)
  To: alsa-devel

I get:

> make[5]: *** No rule to make target `/var/tmp/portage/media-sound/alsa-driver-1.0.13/work/alsa-driver-1.0.13/pci/hda/patch_conexant.o', needed by `/var/tmp/portage/media-sound/alsa-driver-1.0.13/work/alsa-driver-1.0.13/pci/hda/snd-hda-intel

I had a quick look at things and couldn't see anything obvious, but
I'm not realy familiar with the structure of the alsa project.

Could the file be in the wrong place?

On 11:13 Thu 26 Oct     , Tobin Davis wrote:
> I just looked over the patch and found that it was incomplete.  In
> reviewing my commandline history, I discovered that test6 didn't get the
> alsa-kernel base patch (it only had the patch_conexant.c code), required
> for building this code.
> 
> Here is the real test6 patch.  It should work against both the alsa HG
> tip and the alsa-driver-1.0.13.tar.bz2 download.  Earlier versions of
> alsa have not been compile tested.
> 
> Tobin

-- 
Don't let THEM immanentize the Eschaton!

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Test Patch6 for Conexant HD Audio.
  2006-10-26 18:45   ` Nick Fortune
@ 2006-10-26 20:44     ` Nick Fortune
  2006-10-26 21:39       ` Tobin Davis
  0 siblings, 1 reply; 8+ messages in thread
From: Nick Fortune @ 2006-10-26 20:44 UTC (permalink / raw)
  To: alsa-devel

Bit more progress. First I downloaded a clean alsa-devel tarball to
make sureit wasn't some gentoo patch casing the problem. The alsa
tarball gave the same error.

So I copied alsa-kernel/pci/hda/patch_conexant.c to pci/hda/patch_conexant.o
which then compiled. I have no idea if this makes sense, except that the 
compilation worked.

When I tested it, I got no sound.

> # lspci -s 0:1b -vn
> 00:1b.0 0403: 8086:27d8 (rev 02)
>      Subsystem: 1179:ff31
>      Flags: bus master, fast devsel, latency 0, IRQ 21
>      Memory at b0000000 (64-bit, non-prefetchable) [size=16K]
>      Capabilities: [50] Power Management version 2
>      Capabilities: [60] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
>      Capabilities: [70] Express Unknown type IRQ 0
>      Capabilities: [100] Virtual Channel
>      Capabilities: [130] Unknown (5)

Distro is Gentoo, Machine is a Tosh P100-240. 

On 19:45 Thu 26 Oct     , Nick Fortune wrote:
> I get:
> 
> > make[5]: *** No rule to make target `/var/tmp/portage/media-sound/alsa-driver-1.0.13/work/alsa-driver-1.0.13/pci/hda/patch_conexant.o', needed by `/var/tmp/portage/media-sound/alsa-driver-1.0.13/work/alsa-driver-1.0.13/pci/hda/snd-hda-intel
> 
> I had a quick look at things and couldn't see anything obvious, but
> I'm not realy familiar with the structure of the alsa project.
> 
> Could the file be in the wrong place?
> 
> On 11:13 Thu 26 Oct     , Tobin Davis wrote:
> > I just looked over the patch and found that it was incomplete.  In
> > reviewing my commandline history, I discovered that test6 didn't get the
> > alsa-kernel base patch (it only had the patch_conexant.c code), required
> > for building this code.
> > 
> > Here is the real test6 patch.  It should work against both the alsa HG
> > tip and the alsa-driver-1.0.13.tar.bz2 download.  Earlier versions of
> > alsa have not been compile tested.
> > 
> > Tobin
> 
> -- 
> Don't let THEM immanentize the Eschaton!
> 
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job easier
> Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/alsa-devel

-- 
Don't let THEM immanentize the Eschaton!


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Test Patch6 for Conexant HD Audio.
  2006-10-26 20:44     ` Nick Fortune
@ 2006-10-26 21:39       ` Tobin Davis
  0 siblings, 0 replies; 8+ messages in thread
From: Tobin Davis @ 2006-10-26 21:39 UTC (permalink / raw)
  To: Nick Fortune; +Cc: alsa-devel

[-- Attachment #1: Type: text/plain, Size: 2862 bytes --]

I didn't email the alsa-driver patch that fixes that.  It was posted to
bugtrack #2485 earlier, and hasn't changed.  Here it is for
completeness.

Tobin

On Thu, 2006-10-26 at 21:44 +0100, Nick Fortune wrote:
> Bit more progress. First I downloaded a clean alsa-devel tarball to
> make sureit wasn't some gentoo patch casing the problem. The alsa
> tarball gave the same error.
> 
> So I copied alsa-kernel/pci/hda/patch_conexant.c to pci/hda/patch_conexant.o
> which then compiled. I have no idea if this makes sense, except that the 
> compilation worked.
> 
> When I tested it, I got no sound.
> 
> > # lspci -s 0:1b -vn
> > 00:1b.0 0403: 8086:27d8 (rev 02)
> >      Subsystem: 1179:ff31
> >      Flags: bus master, fast devsel, latency 0, IRQ 21
> >      Memory at b0000000 (64-bit, non-prefetchable) [size=16K]
> >      Capabilities: [50] Power Management version 2
> >      Capabilities: [60] Message Signalled Interrupts: 64bit+ Queue=0/0 Enable-
> >      Capabilities: [70] Express Unknown type IRQ 0
> >      Capabilities: [100] Virtual Channel
> >      Capabilities: [130] Unknown (5)
> 
> Distro is Gentoo, Machine is a Tosh P100-240. 
> 
> On 19:45 Thu 26 Oct     , Nick Fortune wrote:
> > I get:
> > 
> > > make[5]: *** No rule to make target `/var/tmp/portage/media-sound/alsa-driver-1.0.13/work/alsa-driver-1.0.13/pci/hda/patch_conexant.o', needed by `/var/tmp/portage/media-sound/alsa-driver-1.0.13/work/alsa-driver-1.0.13/pci/hda/snd-hda-intel
> > 
> > I had a quick look at things and couldn't see anything obvious, but
> > I'm not realy familiar with the structure of the alsa project.
> > 
> > Could the file be in the wrong place?
> > 
> > On 11:13 Thu 26 Oct     , Tobin Davis wrote:
> > > I just looked over the patch and found that it was incomplete.  In
> > > reviewing my commandline history, I discovered that test6 didn't get the
> > > alsa-kernel base patch (it only had the patch_conexant.c code), required
> > > for building this code.
> > > 
> > > Here is the real test6 patch.  It should work against both the alsa HG
> > > tip and the alsa-driver-1.0.13.tar.bz2 download.  Earlier versions of
> > > alsa have not been compile tested.
> > > 
> > > Tobin
> > 
> > -- 
> > Don't let THEM immanentize the Eschaton!
> > 
> > -------------------------------------------------------------------------
> > Using Tomcat but need to do more? Need to support web services, security?
> > Get stuff done quickly with pre-integrated technology to make your job easier
> > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> > _______________________________________________
> > Alsa-devel mailing list
> > Alsa-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/alsa-devel
> 
-- 
Tobin Davis <tdavis@dsl-only.net>

[-- Attachment #2: conexant-driver-test1.patch --]
[-- Type: text/x-patch, Size: 212 bytes --]

--- /dev/null	2006-09-13 00:29:45.000000000 -0700
+++ b/pci/hda/patch_conexant.c	2006-10-21 21:30:35.000000000 -0700
@@ -0,0 +1,2 @@
+#define __NO_VERSION__
+#include "../../alsa-kernel/pci/hda/patch_conexant.c"

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 161 bytes --]

_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-10-26 21:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-25  6:18 Test Patch6 for Conexant HD Audio Tobin Davis
2006-10-25  8:03 ` Guyjo
  -- strict thread matches above, loose matches on Subject: below --
2006-10-26 17:30 Nick Fortune
2006-10-26 17:34 ` Takashi Iwai
2006-10-26 18:13 ` Tobin Davis
2006-10-26 18:45   ` Nick Fortune
2006-10-26 20:44     ` Nick Fortune
2006-10-26 21:39       ` Tobin Davis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.