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

Commit decf7abc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "A few last-minute fixes for 3.12-rc1.  All patches are driver
  specific.

   - HD-audio fixes: MacBook 6,1/6,2 speaker fix, ASUS TX300 dock
     speaker fix, Toshiba Satellite irq fix, Haswell HDMI audio
     cleanups)

   - ASoC fixes: atmel irq fix, fsl DT fix, mc13783 spi fix, kirkwood
     compatible string change, etc"

* tag 'sound-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ASoC: mc13783: add spi errata fix
  ASoC: rsnd: fixup flag name of rsnd_scu_platform_info
  ALSA: hda - Add CS4208 codec support for MacBook 6,1 and 6,2
  ALSA: hda - Add Toshiba Satellite C870 to MSI blacklist
  ASoC: fsl_spdif: Select regmap-mmio
  ALSA: hda - unmute pin amplifier in infoframe setup for Haswell
  ALSA: hda - define is_haswell() to check if a display audio codec is Haswell
  ALSA: hda - Add dock speaker support for ASUS TX300
  ASoC: kirkwood: change the compatible string of the kirkwood-i2s driver
  ASoC: atmel: disable error interrupt
  ASoC: fsl: imx-audmux: Do not call imx_audmux_parse_dt_defaults() on non-dt kernel
parents 24ba4058 3d0049e8
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -2,13 +2,17 @@

Required properties:

- compatible: "marvell,mvebu-audio"
- compatible:
  "marvell,kirkwood-audio" for Kirkwood platforms
  "marvell,dove-audio" for Dove platforms

- reg: physical base address of the controller and length of memory mapped
  region.

- interrupts: list of two irq numbers.
  The first irq is used for data flow and the second one is used for errors.
- interrupts:
  with "marvell,kirkwood-audio", the audio interrupt
  with "marvell,dove-audio", a list of two interrupts, the first for
  the data flow, and the second for errors.

- clocks: one or two phandles.
  The first one is mandatory and defines the internal clock.
@@ -21,7 +25,7 @@ Required properties:
Example:

i2s1: audio-controller@b4000 {
	compatible = "marvell,mvebu-audio";
	compatible = "marvell,dove-audio";
	reg = <0xb4000 0x2210>;
	interrupts = <21>, <22>;
	clocks = <&gate_clk 13>;
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ struct rsnd_ssi_platform_info {
/*
 * flags
 */
#define RSND_SCU_USB_HPBIF		(1 << 31) /* it needs RSND_SSI_DEPENDENT */
#define RSND_SCU_USE_HPBIF		(1 << 31) /* it needs RSND_SSI_DEPENDENT */

struct rsnd_scu_platform_info {
	u32 flags;
+1 −0
Original line number Diff line number Diff line
@@ -3428,6 +3428,7 @@ static struct snd_pci_quirk msi_black_list[] = {
	SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
	SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
	SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
	SND_PCI_QUIRK(0x1179, 0xfb44, "Toshiba Satellite C870", 0), /* AMD Hudson */
	SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
	SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
	{}
+82 −7
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ static void cs_automute(struct hda_codec *codec)

	snd_hda_gen_update_outputs(codec);

	if (spec->gpio_eapd_hp) {
	if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {
		spec->gpio_data = spec->gen.hp_jack_present ?
			spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
		snd_hda_codec_write(codec, 0x01, 0,
@@ -291,10 +291,11 @@ static int cs_init(struct hda_codec *codec)
{
	struct cs_spec *spec = codec->spec;

	if (spec->vendor_nid == CS420X_VENDOR_NID) {
		/* init_verb sequence for C0/C1/C2 errata*/
		snd_hda_sequence_write(codec, cs_errata_init_verbs);

		snd_hda_sequence_write(codec, cs_coef_init_verbs);
	}

	snd_hda_gen_init(codec);

@@ -307,8 +308,10 @@ static int cs_init(struct hda_codec *codec)
				    spec->gpio_data);
	}

	if (spec->vendor_nid == CS420X_VENDOR_NID) {
		init_input_coef(codec);
		init_digital_coef(codec);
	}

	return 0;
}
@@ -551,6 +554,76 @@ static int patch_cs420x(struct hda_codec *codec)
	return err;
}

/*
 * CS4208 support:
 * Its layout is no longer compatible with CS4206/CS4207, and the generic
 * parser seems working fairly well, except for trivial fixups.
 */
enum {
	CS4208_GPIO0,
};

static const struct hda_model_fixup cs4208_models[] = {
	{ .id = CS4208_GPIO0, .name = "gpio0" },
	{}
};

static const struct snd_pci_quirk cs4208_fixup_tbl[] = {
	/* codec SSID */
	SND_PCI_QUIRK(0x106b, 0x7100, "MacBookPro 6,1", CS4208_GPIO0),
	SND_PCI_QUIRK(0x106b, 0x7200, "MacBookPro 6,2", CS4208_GPIO0),
	{} /* terminator */
};

static void cs4208_fixup_gpio0(struct hda_codec *codec,
			       const struct hda_fixup *fix, int action)
{
	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
		struct cs_spec *spec = codec->spec;
		spec->gpio_eapd_hp = 0;
		spec->gpio_eapd_speaker = 1;
		spec->gpio_mask = spec->gpio_dir =
			spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
	}
}

static const struct hda_fixup cs4208_fixups[] = {
	[CS4208_GPIO0] = {
		.type = HDA_FIXUP_FUNC,
		.v.func = cs4208_fixup_gpio0,
	},
};

static int patch_cs4208(struct hda_codec *codec)
{
	struct cs_spec *spec;
	int err;

	spec = cs_alloc_spec(codec, 0); /* no specific w/a */
	if (!spec)
		return -ENOMEM;

	spec->gen.automute_hook = cs_automute;

	snd_hda_pick_fixup(codec, cs4208_models, cs4208_fixup_tbl,
			   cs4208_fixups);
	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);

	err = cs_parse_auto_config(codec);
	if (err < 0)
		goto error;

	codec->patch_ops = cs_patch_ops;

	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);

	return 0;

 error:
	cs_free(codec);
	return err;
}

/*
 * Cirrus Logic CS4210
 *
@@ -991,6 +1064,7 @@ static int patch_cs4213(struct hda_codec *codec)
static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
	{ .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
	{ .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
	{ .id = 0x10134208, .name = "CS4208", .patch = patch_cs4208 },
	{ .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 },
	{ .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 },
	{} /* terminator */
@@ -998,6 +1072,7 @@ static const struct hda_codec_preset snd_hda_preset_cirrus[] = {

MODULE_ALIAS("snd-hda-codec-id:10134206");
MODULE_ALIAS("snd-hda-codec-id:10134207");
MODULE_ALIAS("snd-hda-codec-id:10134208");
MODULE_ALIAS("snd-hda-codec-id:10134210");
MODULE_ALIAS("snd-hda-codec-id:10134213");

+17 −33
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ static bool static_hdmi_pcm;
module_param(static_hdmi_pcm, bool, 0644);
MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");

#define is_haswell(codec)  ((codec)->vendor_id == 0x80862807)

struct hdmi_spec_per_cvt {
	hda_nid_t cvt_nid;
	int assigned;
@@ -894,6 +896,11 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
	if (!channels)
		return;

	if (is_haswell(codec))
		snd_hda_codec_write(codec, pin_nid, 0,
					    AC_VERB_SET_AMP_GAIN_MUTE,
					    AMP_OUT_UNMUTE);

	eld = &per_pin->sink_eld;
	if (!eld->monitor_present)
		return;
@@ -1033,10 +1040,10 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
		hdmi_non_intrinsic_event(codec, res);
}

static void haswell_verify_pin_D0(struct hda_codec *codec,
static void haswell_verify_D0(struct hda_codec *codec,
		hda_nid_t cvt_nid, hda_nid_t nid)
{
	int pwr, lamp, ramp;
	int pwr;

	/* For Haswell, the converter 1/2 may keep in D3 state after bootup,
	 * thus pins could only choose converter 0 for use. Make sure the
@@ -1052,25 +1059,6 @@ static void haswell_verify_pin_D0(struct hda_codec *codec,
		pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT;
		snd_printd("Haswell HDMI audio: Power for pin 0x%x is now D%d\n", nid, pwr);
	}

	lamp = snd_hda_codec_read(codec, nid, 0,
				  AC_VERB_GET_AMP_GAIN_MUTE,
				  AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT);
	ramp = snd_hda_codec_read(codec, nid, 0,
				  AC_VERB_GET_AMP_GAIN_MUTE,
				  AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT);
	if (lamp != ramp) {
		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
				    AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT | lamp);

		lamp = snd_hda_codec_read(codec, nid, 0,
				  AC_VERB_GET_AMP_GAIN_MUTE,
				  AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT);
		ramp = snd_hda_codec_read(codec, nid, 0,
				  AC_VERB_GET_AMP_GAIN_MUTE,
				  AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT);
		snd_printd("Haswell HDMI audio: Mute after set on pin 0x%x: [0x%x 0x%x]\n", nid, lamp, ramp);
	}
}

/*
@@ -1087,8 +1075,8 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
	int pinctl;
	int new_pinctl = 0;

	if (codec->vendor_id == 0x80862807)
		haswell_verify_pin_D0(codec, cvt_nid, pin_nid);
	if (is_haswell(codec))
		haswell_verify_D0(codec, cvt_nid, pin_nid);

	if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
		pinctl = snd_hda_codec_read(codec, pin_nid, 0,
@@ -1227,7 +1215,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
			    mux_idx);

	/* configure unused pins to choose other converters */
	if (codec->vendor_id == 0x80862807)
	if (is_haswell(codec))
		haswell_config_cvts(codec, pin_idx, mux_idx);

	snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
@@ -1358,15 +1346,11 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
		/* Haswell-specific workaround: re-setup when the transcoder is
		 * changed during the stream playback
		 */
		if (codec->vendor_id == 0x80862807 &&
		    eld->eld_valid && !old_eld_valid && per_pin->setup) {
			snd_hda_codec_write(codec, pin_nid, 0,
					    AC_VERB_SET_AMP_GAIN_MUTE,
					    AMP_OUT_UNMUTE);
		if (is_haswell(codec) &&
		    eld->eld_valid && !old_eld_valid && per_pin->setup)
			hdmi_setup_audio_infoframe(codec, per_pin,
						   per_pin->non_pcm);
	}
	}
	mutex_unlock(&pin_eld->lock);

	if (eld_changed)
@@ -1405,7 +1389,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
	if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
		return 0;

	if (codec->vendor_id == 0x80862807)
	if (is_haswell(codec))
		intel_haswell_fixup_connect_list(codec, pin_nid);

	pin_idx = spec->num_pins;
@@ -2014,7 +1998,7 @@ static int patch_generic_hdmi(struct hda_codec *codec)
	codec->spec = spec;
	hdmi_array_init(spec, 4);

	if (codec->vendor_id == 0x80862807) {
	if (is_haswell(codec)) {
		intel_haswell_enable_all_pins(codec, true);
		intel_haswell_fixup_enable_dp12(codec);
	}
@@ -2025,7 +2009,7 @@ static int patch_generic_hdmi(struct hda_codec *codec)
		return -EINVAL;
	}
	codec->patch_ops = generic_hdmi_patch_ops;
	if (codec->vendor_id == 0x80862807) {
	if (is_haswell(codec)) {
		codec->patch_ops.set_power_state = haswell_set_power_state;
		codec->dp_mst = true;
	}
Loading