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

Commit 5e682c0e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "There are nothing scaring, contains only small fixes for HD-audio and
  USB-audio:
   - EPSS regression fix and GPIO fix for HD-audio IDT codecs
   - A series of USB-audio regression fixes that are found since 3.5
     kernel"

* tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: snd-usb: fix cross-interface streaming devices
  ALSA: snd-usb: fix calls to next_packet_size
  ALSA: snd-usb: restore delay information
  ALSA: snd-usb: use list_for_each_safe for endpoint resources
  ALSA: snd-usb: Fix URB cancellation at stream start
  ALSA: hda - Don't trust codec EPSS bit for IDT 92HD83xx & co
  ALSA: hda - Avoid unnecessary parameter read for EPSS
  ALSA: hda - Do not set GPIOs for speakers on IDT if there are no speakers
parents 6d1a0503 2e4a263c
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1209,6 +1209,9 @@ static void snd_hda_codec_free(struct hda_codec *codec)
	kfree(codec);
}

static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,
				hda_nid_t fg, unsigned int power_state);

static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
				unsigned int power_state);

@@ -1317,6 +1320,10 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
					   AC_VERB_GET_SUBSYSTEM_ID, 0);
	}

	codec->epss = snd_hda_codec_get_supported_ps(codec,
					codec->afg ? codec->afg : codec->mfg,
					AC_PWRST_EPSS);

	/* power-up all before initialization */
	hda_set_power_state(codec,
			    codec->afg ? codec->afg : codec->mfg,
@@ -3543,8 +3550,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
	/* this delay seems necessary to avoid click noise at power-down */
	if (power_state == AC_PWRST_D3) {
		/* transition time less than 10ms for power down */
		bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS);
		msleep(epss ? 10 : 100);
		msleep(codec->epss ? 10 : 100);
	}

	/* repeat power states setting at most 10 times*/
+1 −0
Original line number Diff line number Diff line
@@ -862,6 +862,7 @@ struct hda_codec {
	unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
	unsigned int no_jack_detect:1;	/* Machine has no jack-detection */
	unsigned int pcm_format_first:1; /* PCM format must be set first */
	unsigned int epss:1;		/* supporting EPSS? */
#ifdef CONFIG_SND_HDA_POWER_SAVE
	unsigned int power_on :1;	/* current (global) power-state */
	int power_transition;	/* power-state in transition */
+4 −0
Original line number Diff line number Diff line
@@ -4543,6 +4543,9 @@ static void stac92xx_line_out_detect(struct hda_codec *codec,
	struct auto_pin_cfg *cfg = &spec->autocfg;
	int i;

	if (cfg->speaker_outs == 0)
		return;

	for (i = 0; i < cfg->line_outs; i++) {
		if (presence)
			break;
@@ -5531,6 +5534,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
		snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
	}

	codec->epss = 0; /* longer delay needed for D3 */
	codec->no_trigger_sense = 1;
	codec->spec = spec;

+2 −2
Original line number Diff line number Diff line
@@ -553,7 +553,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
				     struct snd_usb_audio *chip)
{
	struct snd_card *card;
	struct list_head *p;
	struct list_head *p, *n;

	if (chip == (void *)-1L)
		return;
@@ -570,7 +570,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
			snd_usb_stream_disconnect(p);
		}
		/* release the endpoint resources */
		list_for_each(p, &chip->ep_list) {
		list_for_each_safe(p, n, &chip->ep_list) {
			snd_usb_endpoint_free(p);
		}
		/* release the midi resources */
+10 −14
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep)
 *
 * For implicit feedback, next_packet_size() is unused.
 */
static int next_packet_size(struct snd_usb_endpoint *ep)
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep)
{
	unsigned long flags;
	int ret;
@@ -177,15 +177,6 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep,
		ep->retire_data_urb(ep->data_subs, urb);
}

static void prepare_outbound_urb_sizes(struct snd_usb_endpoint *ep,
				       struct snd_urb_ctx *ctx)
{
	int i;

	for (i = 0; i < ctx->packets; ++i)
		ctx->packet_size[i] = next_packet_size(ep);
}

/*
 * Prepare a PLAYBACK urb for submission to the bus.
 */
@@ -370,7 +361,6 @@ static void snd_complete_urb(struct urb *urb)
			goto exit_clear;
		}

		prepare_outbound_urb_sizes(ep, ctx);
		prepare_outbound_urb(ep, ctx);
	} else {
		retire_inbound_urb(ep, ctx);
@@ -800,6 +790,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
 * snd_usb_endpoint_start: start an snd_usb_endpoint
 *
 * @ep:		the endpoint to start
 * @can_sleep:	flag indicating whether the operation is executed in
 * 		non-atomic context
 *
 * A call to this function will increment the use count of the endpoint.
 * In case it is not already running, the URBs for this endpoint will be
@@ -809,7 +801,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
 *
 * Returns an error if the URB submission failed, 0 in all other cases.
 */
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
{
	int err;
	unsigned int i;
@@ -821,6 +813,11 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
	if (++ep->use_count != 1)
		return 0;

	/* just to be sure */
	deactivate_urbs(ep, 0, can_sleep);
	if (can_sleep)
		wait_clear_urbs(ep);

	ep->active_mask = 0;
	ep->unlink_mask = 0;
	ep->phase = 0;
@@ -850,7 +847,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
			goto __error;

		if (usb_pipeout(ep->pipe)) {
			prepare_outbound_urb_sizes(ep, urb->context);
			prepare_outbound_urb(ep, urb->context);
		} else {
			prepare_inbound_urb(ep, urb->context);
Loading