Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 585a7c66 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: use linux/io.h to fix compile warnings
  ALSA: hda - Fix memory leaks in conexant jack arrays
  ASoC: CX20442: fix NULL pointer dereference
  ASoC: Amstrad Delta: fix const related build error
  ALSA: oxygen: fix output routing on Xonar DG
  sound: silent echo'ed messages in Makefile
  ASoC: Fix mask/val_mask confusion snd_soc_dapm_put_volsw()
  ASoC: DaVinci: fix kernel panic due to uninitialized platform_data
  ALSA: HDA: Fix microphone(s) on Lenovo Edge 13
  ASoC: Fix module refcount for auxiliary devices
  ALSA: HDA: cxt5066 - Use asus model for Asus U50F, select correct SPDIF output
  ALSA: HDA: Add a new model "asus" for Conexant 5066/205xx
  ALSA: HDA: Refactor some redundant code for Conexant 5066/205xx
parents 44f2c5c8 00e6a319
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -296,6 +296,7 @@ Conexant 5066
=============
  laptop	Basic Laptop config (default)
  hp-laptop	HP laptops, e g G60
  asus		Asus K52JU, Lenovo G560
  dell-laptop	Dell laptops
  dell-vostro	Dell Vostro
  olpc-xo-1_5	OLPC XO 1.5
+1 −2
Original line number Diff line number Diff line
@@ -55,14 +55,13 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/rawmidi.h>
#include <linux/delay.h>

#include <asm/io.h>

/*
 *      globals
 */
+2 −2
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ ifeq ($(CONFIG_PSS_HAVE_BOOT),y)
	$(obj)/bin2hex pss_synth < $< > $@
else
    $(obj)/pss_boot.h:
	(							\
	$(Q)(							\
	    echo 'static unsigned char * pss_synth = NULL;';	\
	    echo 'static int pss_synthLen = 0;';		\
	) > $@
@@ -102,7 +102,7 @@ ifeq ($(CONFIG_TRIX_HAVE_BOOT),y)
	$(obj)/hex2hex -i trix_boot < $< > $@
else
    $(obj)/trix_boot.h:
	(							\
	$(Q)(							\
	    echo 'static unsigned char * trix_boot = NULL;';	\
	    echo 'static int trix_boot_len = 0;';		\
	) > $@
+85 −64
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ struct conexant_spec {
	unsigned int auto_mic;
	int auto_mic_ext;		/* autocfg.inputs[] index for ext mic */
	unsigned int need_dac_fix;
	hda_nid_t slave_dig_outs[2];

	/* capture */
	unsigned int num_adc_nids;
@@ -127,6 +128,7 @@ struct conexant_spec {
	unsigned int ideapad:1;
	unsigned int thinkpad:1;
	unsigned int hp_laptop:1;
	unsigned int asus:1;

	unsigned int ext_mic_present;
	unsigned int recording;
@@ -352,6 +354,8 @@ static int conexant_build_pcms(struct hda_codec *codec)
			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
				spec->dig_in_nid;
		}
		if (spec->slave_dig_outs[0])
			codec->slave_dig_outs = spec->slave_dig_outs;
	}

	return 0;
@@ -403,10 +407,16 @@ static int conexant_add_jack(struct hda_codec *codec,
	struct conexant_spec *spec;
	struct conexant_jack *jack;
	const char *name;
	int err;
	int i, err;

	spec = codec->spec;
	snd_array_init(&spec->jacks, sizeof(*jack), 32);

	jack = spec->jacks.list;
	for (i = 0; i < spec->jacks.used; i++, jack++)
		if (jack->nid == nid)
			return 0 ; /* already present */

	jack = snd_array_new(&spec->jacks);
	name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;

@@ -2100,7 +2110,7 @@ static int patch_cxt5051(struct hda_codec *codec)
static hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
#define CXT5066_SPDIF_OUT	0x21
static hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };

/* OLPC's microphone port is DC coupled for use with external sensors,
 * therefore we use a 50% mic bias in order to center the input signal with
@@ -2312,6 +2322,19 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
	}
}


/* toggle input of built-in digital mic and mic jack appropriately */
static void cxt5066_asus_automic(struct hda_codec *codec)
{
	unsigned int present;

	present = snd_hda_jack_detect(codec, 0x1b);
	snd_printdd("CXT5066: external microphone present=%d\n", present);
	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
			    present ? 1 : 0);
}


/* toggle input of built-in digital mic and mic jack appropriately */
static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
{
@@ -2387,79 +2410,55 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
	cxt5066_update_speaker(codec);
}

/* unsolicited event for jack sensing */
static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
/* Dispatch the right mic autoswitch function */
static void cxt5066_automic(struct hda_codec *codec)
{
	struct conexant_spec *spec = codec->spec;
	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
	switch (res >> 26) {
	case CONEXANT_HP_EVENT:
		cxt5066_hp_automute(codec);
		break;
	case CONEXANT_MIC_EVENT:
		/* ignore mic events in DC mode; we're always using the jack */
		if (!spec->dc_enable)
			cxt5066_olpc_automic(codec);
		break;
	}
}

/* unsolicited event for jack sensing */
static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
{
	snd_printdd("CXT5066_vostro: unsol event %x (%x)\n", res, res >> 26);
	switch (res >> 26) {
	case CONEXANT_HP_EVENT:
		cxt5066_hp_automute(codec);
		break;
	case CONEXANT_MIC_EVENT:
	if (spec->dell_vostro)
		cxt5066_vostro_automic(codec);
		break;
	}
}

/* unsolicited event for jack sensing */
static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
{
	snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26);
	switch (res >> 26) {
	case CONEXANT_HP_EVENT:
		cxt5066_hp_automute(codec);
		break;
	case CONEXANT_MIC_EVENT:
	else if (spec->ideapad)
		cxt5066_ideapad_automic(codec);
		break;
	}
	else if (spec->thinkpad)
		cxt5066_thinkpad_automic(codec);
	else if (spec->hp_laptop)
		cxt5066_hp_laptop_automic(codec);
	else if (spec->asus)
		cxt5066_asus_automic(codec);
}

/* unsolicited event for jack sensing */
static void cxt5066_hp_laptop_event(struct hda_codec *codec, unsigned int res)
static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
{
	snd_printdd("CXT5066_hp_laptop: unsol event %x (%x)\n", res, res >> 26);
	struct conexant_spec *spec = codec->spec;
	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
	switch (res >> 26) {
	case CONEXANT_HP_EVENT:
		cxt5066_hp_automute(codec);
		break;
	case CONEXANT_MIC_EVENT:
		cxt5066_hp_laptop_automic(codec);
		/* ignore mic events in DC mode; we're always using the jack */
		if (!spec->dc_enable)
			cxt5066_olpc_automic(codec);
		break;
	}
}

/* unsolicited event for jack sensing */
static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res)
static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
{
	snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26);
	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
	switch (res >> 26) {
	case CONEXANT_HP_EVENT:
		cxt5066_hp_automute(codec);
		break;
	case CONEXANT_MIC_EVENT:
		cxt5066_thinkpad_automic(codec);
		cxt5066_automic(codec);
		break;
	}
}


static const struct hda_input_mux cxt5066_analog_mic_boost = {
	.num_items = 5,
	.items = {
@@ -2633,6 +2632,27 @@ static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
	spec->recording = 0;
}

static void conexant_check_dig_outs(struct hda_codec *codec,
				    hda_nid_t *dig_pins,
				    int num_pins)
{
	struct conexant_spec *spec = codec->spec;
	hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
	int i;

	for (i = 0; i < num_pins; i++, dig_pins++) {
		unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
		if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
			continue;
		if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
			continue;
		if (spec->slave_dig_outs[0])
			nid_loc++;
		else
			nid_loc = spec->slave_dig_outs;
	}
}

static struct hda_input_mux cxt5066_capture_source = {
	.num_items = 4,
	.items = {
@@ -3039,20 +3059,11 @@ static struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
/* initialize jack-sensing, too */
static int cxt5066_init(struct hda_codec *codec)
{
	struct conexant_spec *spec = codec->spec;

	snd_printdd("CXT5066: init\n");
	conexant_init(codec);
	if (codec->patch_ops.unsol_event) {
		cxt5066_hp_automute(codec);
		if (spec->dell_vostro)
			cxt5066_vostro_automic(codec);
		else if (spec->ideapad)
			cxt5066_ideapad_automic(codec);
		else if (spec->thinkpad)
			cxt5066_thinkpad_automic(codec);
		else if (spec->hp_laptop)
			cxt5066_hp_laptop_automic(codec);
		cxt5066_automic(codec);
	}
	cxt5066_set_mic_boost(codec);
	return 0;
@@ -3080,6 +3091,7 @@ enum {
	CXT5066_DELL_VOSTRO,	/* Dell Vostro 1015i */
	CXT5066_IDEAPAD,	/* Lenovo IdeaPad U150 */
	CXT5066_THINKPAD,	/* Lenovo ThinkPad T410s, others? */
	CXT5066_ASUS,		/* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
	CXT5066_HP_LAPTOP,      /* HP Laptop */
	CXT5066_MODELS
};
@@ -3091,6 +3103,7 @@ static const char * const cxt5066_models[CXT5066_MODELS] = {
	[CXT5066_DELL_VOSTRO]	= "dell-vostro",
	[CXT5066_IDEAPAD]	= "ideapad",
	[CXT5066_THINKPAD]	= "thinkpad",
	[CXT5066_ASUS]		= "asus",
	[CXT5066_HP_LAPTOP]	= "hp-laptop",
};

@@ -3102,7 +3115,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
	SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
	SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
	SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
	SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP),
	SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
	SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
	SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
	SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
	SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
	SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
@@ -3111,7 +3126,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
	SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
	SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
 	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
	{}
};
@@ -3133,7 +3150,8 @@ static int patch_cxt5066(struct hda_codec *codec)
	spec->multiout.max_channels = 2;
	spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
	spec->multiout.dac_nids = cxt5066_dac_nids;
	spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT;
	conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
	    ARRAY_SIZE(cxt5066_digout_pin_nids));
	spec->num_adc_nids = 1;
	spec->adc_nids = cxt5066_adc_nids;
	spec->capsrc_nids = cxt5066_capsrc_nids;
@@ -3167,16 +3185,19 @@ static int patch_cxt5066(struct hda_codec *codec)
		spec->num_init_verbs++;
		spec->dell_automute = 1;
		break;
	case CXT5066_ASUS:
	case CXT5066_HP_LAPTOP:
		codec->patch_ops.init = cxt5066_init;
		codec->patch_ops.unsol_event = cxt5066_hp_laptop_event;
		codec->patch_ops.unsol_event = cxt5066_unsol_event;
		spec->init_verbs[spec->num_init_verbs] =
			cxt5066_init_verbs_hp_laptop;
		spec->num_init_verbs++;
		spec->hp_laptop = 1;
		spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
		spec->asus = board_config == CXT5066_ASUS;
		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
		/* no S/PDIF out */
		if (board_config == CXT5066_HP_LAPTOP)
			spec->multiout.dig_out_nid = 0;
		/* input source automatically selected */
		spec->input_mux = NULL;
@@ -3207,7 +3228,7 @@ static int patch_cxt5066(struct hda_codec *codec)
		break;
	case CXT5066_DELL_VOSTRO:
		codec->patch_ops.init = cxt5066_init;
		codec->patch_ops.unsol_event = cxt5066_vostro_event;
		codec->patch_ops.unsol_event = cxt5066_unsol_event;
		spec->init_verbs[0] = cxt5066_init_verbs_vostro;
		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
@@ -3224,7 +3245,7 @@ static int patch_cxt5066(struct hda_codec *codec)
		break;
	case CXT5066_IDEAPAD:
		codec->patch_ops.init = cxt5066_init;
		codec->patch_ops.unsol_event = cxt5066_ideapad_event;
		codec->patch_ops.unsol_event = cxt5066_unsol_event;
		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
		spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
@@ -3240,7 +3261,7 @@ static int patch_cxt5066(struct hda_codec *codec)
		break;
	case CXT5066_THINKPAD:
		codec->patch_ops.init = cxt5066_init;
		codec->patch_ops.unsol_event = cxt5066_thinkpad_event;
		codec->patch_ops.unsol_event = cxt5066_unsol_event;
		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
		spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
+2 −0
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ struct oxygen_model {
	void (*update_dac_volume)(struct oxygen *chip);
	void (*update_dac_mute)(struct oxygen *chip);
	void (*update_center_lfe_mix)(struct oxygen *chip, bool mixed);
	unsigned int (*adjust_dac_routing)(struct oxygen *chip,
					   unsigned int play_routing);
	void (*gpio_changed)(struct oxygen *chip);
	void (*uart_input)(struct oxygen *chip);
	void (*ac97_switch)(struct oxygen *chip,
Loading