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

Commit 19566b0b authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'for-linus' into for-next

This merges the USB-audio disconnect fix and resolves the conflicts
so that we can continue working on development of usb-audio stuff.

Conflicts:
	sound/usb/card.c
parents 9161bd0d 0725dda2
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -210,6 +210,8 @@ static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
	if (err < 0)
	if (err < 0)
		return err;
		return err;


	if (clear_user(src, sizeof(*src)))
		return -EFAULT;
	if (put_user(status.state, &src->state) ||
	if (put_user(status.state, &src->state) ||
	    compat_put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
	    compat_put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
	    compat_put_timespec(&status.tstamp, &src->tstamp) ||
	    compat_put_timespec(&status.tstamp, &src->tstamp) ||
+3 −1
Original line number Original line Diff line number Diff line
@@ -374,6 +374,8 @@ static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool
#ifdef CONFIG_SND_DMA_SGBUF
#ifdef CONFIG_SND_DMA_SGBUF
	if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
	if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
		struct snd_sg_buf *sgbuf = dmab->private_data;
		struct snd_sg_buf *sgbuf = dmab->private_data;
		if (chip->driver_type == AZX_DRIVER_CMEDIA)
			return; /* deal with only CORB/RIRB buffers */
		if (on)
		if (on)
			set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
			set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
		else
		else
@@ -1769,7 +1771,7 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
#ifdef CONFIG_X86
#ifdef CONFIG_X86
	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
	struct azx *chip = apcm->chip;
	struct azx *chip = apcm->chip;
	if (!azx_snoop(chip))
	if (!azx_snoop(chip) && chip->driver_type != AZX_DRIVER_CMEDIA)
		area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
		area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
#endif
#endif
}
}
+50 −32
Original line number Original line Diff line number Diff line
@@ -291,18 +291,14 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
/* additional initialization for ALC888 variants */
/* additional initialization for ALC888 variants */
static void alc888_coef_init(struct hda_codec *codec)
static void alc888_coef_init(struct hda_codec *codec)
{
{
	if (alc_get_coef0(codec) == 0x20)
	switch (alc_get_coef0(codec) & 0x00f0) {
		/* alc888S-VC */
	/* alc888-VA */
		alc_write_coef_idx(codec, 7, 0x830);
	case 0x00:
	 else
	/* alc888-VB */
	/* alc888-VB */
		alc_write_coef_idx(codec, 7, 0x3030);
	case 0x10:
		alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
		break;
	}
	}

/* additional initialization for ALC889 variants */
static void alc889_coef_init(struct hda_codec *codec)
{
	alc_update_coef_idx(codec, 7, 0, 0x2010);
}
}


/* turn on/off EAPD control (only if available) */
/* turn on/off EAPD control (only if available) */
@@ -359,25 +355,15 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
		case 0x10ec0260:
		case 0x10ec0260:
			alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
			alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
			break;
			break;
		case 0x10ec0262:
		case 0x10ec0880:
		case 0x10ec0880:
		case 0x10ec0882:
		case 0x10ec0882:
		case 0x10ec0883:
		case 0x10ec0883:
		case 0x10ec0885:
		case 0x10ec0885:
		case 0x10ec0887:
			alc_update_coef_idx(codec, 7, 0, 0x2030);
		/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
		case 0x10ec0900:
			alc889_coef_init(codec);
			break;
			break;
		case 0x10ec0888:
		case 0x10ec0888:
			alc888_coef_init(codec);
			alc888_coef_init(codec);
			break;
			break;
#if 0 /* XXX: This may cause the silent output on speaker on some machines */
		case 0x10ec0267:
		case 0x10ec0268:
			alc_update_coef_idx(codec, 7, 0, 0x3000);
			break;
#endif /* XXX */
		}
		}
		break;
		break;
	}
	}
@@ -1710,7 +1696,7 @@ static void alc889_fixup_coef(struct hda_codec *codec,
{
{
	if (action != HDA_FIXUP_ACT_INIT)
	if (action != HDA_FIXUP_ACT_INIT)
		return;
		return;
	alc889_coef_init(codec);
	alc_update_coef_idx(codec, 7, 0, 0x2030);
}
}


/* toggle speaker-output according to the hp-jack state */
/* toggle speaker-output according to the hp-jack state */
@@ -3350,6 +3336,27 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
	}
	}
}
}


static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
				   const struct hda_fixup *fix, int action)
{
	/* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
	struct alc_spec *spec = codec->spec;
	static const struct hda_verb gpio_init[] = {
		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
		{}
	};

	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
		spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook;
		spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
		spec->gpio_led = 0;
		spec->cap_mute_led_nid = 0x18;
		snd_hda_add_verbs(codec, gpio_init);
		codec->power_filter = led_power_filter;
	}
}

static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
				const struct hda_fixup *fix, int action)
				const struct hda_fixup *fix, int action)
{
{
@@ -4217,6 +4224,7 @@ enum {
	ALC283_FIXUP_BXBT2807_MIC,
	ALC283_FIXUP_BXBT2807_MIC,
	ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
	ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
	ALC282_FIXUP_ASPIRE_V5_PINS,
	ALC282_FIXUP_ASPIRE_V5_PINS,
	ALC280_FIXUP_HP_GPIO4,
};
};


static const struct hda_fixup alc269_fixups[] = {
static const struct hda_fixup alc269_fixups[] = {
@@ -4680,7 +4688,10 @@ static const struct hda_fixup alc269_fixups[] = {
			{ },
			{ },
		},
		},
	},
	},

	[ALC280_FIXUP_HP_GPIO4] = {
		.type = HDA_FIXUP_FUNC,
		.v.func = alc280_fixup_hp_gpio4,
	},
};
};


static const struct snd_pci_quirk alc269_fixup_tbl[] = {
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -4728,21 +4739,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x8004, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	/* ALC290 */
	/* ALC290 */
	SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2247, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2248, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2249, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2258, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -4751,7 +4757,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2277, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
	SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
	SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
@@ -4804,7 +4809,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
	SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
	SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
	SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
	SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
	SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
	SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
	SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -4984,6 +4989,19 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
		{0x17, 0x40000000},
		{0x17, 0x40000000},
		{0x1d, 0x40700001},
		{0x1d, 0x40700001},
		{0x21, 0x02211040}),
		{0x21, 0x02211040}),
	SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
		{0x12, 0x90a60130},
		{0x13, 0x40000000},
		{0x14, 0x90170110},
		{0x15, 0x0421101f},
		{0x16, 0x411111f0},
		{0x17, 0x411111f0},
		{0x18, 0x411111f0},
		{0x19, 0x411111f0},
		{0x1a, 0x04a11020},
		{0x1b, 0x411111f0},
		{0x1d, 0x40748605},
		{0x1e, 0x411111f0}),
	SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
	SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
		{0x12, 0x90a60140},
		{0x12, 0x90a60140},
		{0x13, 0x40000000},
		{0x13, 0x40000000},
+7 −2
Original line number Original line Diff line number Diff line
@@ -585,18 +585,19 @@ static void usb_audio_disconnect(struct usb_interface *intf)
	struct snd_usb_audio *chip = usb_get_intfdata(intf);
	struct snd_usb_audio *chip = usb_get_intfdata(intf);
	struct snd_card *card;
	struct snd_card *card;
	struct list_head *p;
	struct list_head *p;
	bool was_shutdown;


	if (chip == (void *)-1L)
	if (chip == (void *)-1L)
		return;
		return;


	card = chip->card;
	card = chip->card;
	down_write(&chip->shutdown_rwsem);
	down_write(&chip->shutdown_rwsem);
	was_shutdown = chip->shutdown;
	chip->shutdown = 1;
	chip->shutdown = 1;
	up_write(&chip->shutdown_rwsem);
	up_write(&chip->shutdown_rwsem);


	mutex_lock(&register_mutex);
	mutex_lock(&register_mutex);
	chip->num_interfaces--;
	if (!was_shutdown) {
	if (chip->num_interfaces <= 0) {
		struct snd_usb_stream *as;
		struct snd_usb_stream *as;
		struct snd_usb_endpoint *ep;
		struct snd_usb_endpoint *ep;
		struct usb_mixer_interface *mixer;
		struct usb_mixer_interface *mixer;
@@ -618,6 +619,10 @@ static void usb_audio_disconnect(struct usb_interface *intf)
		list_for_each_entry(mixer, &chip->mixer_list, list) {
		list_for_each_entry(mixer, &chip->mixer_list, list) {
			snd_usb_mixer_disconnect(mixer);
			snd_usb_mixer_disconnect(mixer);
		}
		}
	}

	chip->num_interfaces--;
	if (chip->num_interfaces <= 0) {
		usb_chip[chip->index] = NULL;
		usb_chip[chip->index] = NULL;
		mutex_unlock(&register_mutex);
		mutex_unlock(&register_mutex);
		snd_card_free_when_closed(card);
		snd_card_free_when_closed(card);