Merge branch 'fix/hda' into topic/hda
The fix for power sequence needs to be merged back to topic branch.
This commit is contained in:
		
						commit
						1ade819181
					
				| @ -193,6 +193,7 @@ static const struct platform_device_id ssp_id_table[] = { | ||||
| 	{ "pxa25x-nssp",	PXA25x_NSSP }, | ||||
| 	{ "pxa27x-ssp",		PXA27x_SSP }, | ||||
| 	{ "pxa168-ssp",		PXA168_SSP }, | ||||
| 	{ "pxa910-ssp",		PXA910_SSP }, | ||||
| 	{ }, | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -190,6 +190,19 @@ find_active_client(struct list_head *head) | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| int vga_switcheroo_get_client_state(struct pci_dev *pdev) | ||||
| { | ||||
| 	struct vga_switcheroo_client *client; | ||||
| 
 | ||||
| 	client = find_client_from_pci(&vgasr_priv.clients, pdev); | ||||
| 	if (!client) | ||||
| 		return VGA_SWITCHEROO_NOT_FOUND; | ||||
| 	if (!vgasr_priv.active) | ||||
| 		return VGA_SWITCHEROO_INIT; | ||||
| 	return client->pwr_state; | ||||
| } | ||||
| EXPORT_SYMBOL(vga_switcheroo_get_client_state); | ||||
| 
 | ||||
| void vga_switcheroo_unregister_client(struct pci_dev *pdev) | ||||
| { | ||||
| 	struct vga_switcheroo_client *client; | ||||
| @ -291,8 +304,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) | ||||
| 		vga_switchon(new_client); | ||||
| 
 | ||||
| 	vga_set_default_device(new_client->pdev); | ||||
| 	set_audio_state(new_client->id, VGA_SWITCHEROO_ON); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| @ -308,6 +319,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) | ||||
| 
 | ||||
| 	active->active = false; | ||||
| 
 | ||||
| 	set_audio_state(active->id, VGA_SWITCHEROO_OFF); | ||||
| 
 | ||||
| 	if (new_client->fb_info) { | ||||
| 		struct fb_event event; | ||||
| 		event.info = new_client->fb_info; | ||||
| @ -321,11 +334,11 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) | ||||
| 	if (new_client->ops->reprobe) | ||||
| 		new_client->ops->reprobe(new_client->pdev); | ||||
| 
 | ||||
| 	set_audio_state(active->id, VGA_SWITCHEROO_OFF); | ||||
| 
 | ||||
| 	if (active->pwr_state == VGA_SWITCHEROO_ON) | ||||
| 		vga_switchoff(active); | ||||
| 
 | ||||
| 	set_audio_state(new_client->id, VGA_SWITCHEROO_ON); | ||||
| 
 | ||||
| 	new_client->active = true; | ||||
| 	return 0; | ||||
| } | ||||
| @ -371,8 +384,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, | ||||
| 	/* pwr off the device not in use */ | ||||
| 	if (strncmp(usercmd, "OFF", 3) == 0) { | ||||
| 		list_for_each_entry(client, &vgasr_priv.clients, list) { | ||||
| 			if (client->active) | ||||
| 			if (client->active || client_is_audio(client)) | ||||
| 				continue; | ||||
| 			set_audio_state(client->id, VGA_SWITCHEROO_OFF); | ||||
| 			if (client->pwr_state == VGA_SWITCHEROO_ON) | ||||
| 				vga_switchoff(client); | ||||
| 		} | ||||
| @ -381,10 +395,11 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, | ||||
| 	/* pwr on the device not in use */ | ||||
| 	if (strncmp(usercmd, "ON", 2) == 0) { | ||||
| 		list_for_each_entry(client, &vgasr_priv.clients, list) { | ||||
| 			if (client->active) | ||||
| 			if (client->active || client_is_audio(client)) | ||||
| 				continue; | ||||
| 			if (client->pwr_state == VGA_SWITCHEROO_OFF) | ||||
| 				vga_switchon(client); | ||||
| 			set_audio_state(client->id, VGA_SWITCHEROO_ON); | ||||
| 		} | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| @ -160,7 +160,9 @@ enum pxa_ssp_type { | ||||
| 	PXA25x_SSP,  /* pxa 210, 250, 255, 26x */ | ||||
| 	PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ | ||||
| 	PXA27x_SSP, | ||||
| 	PXA3xx_SSP, | ||||
| 	PXA168_SSP, | ||||
| 	PXA910_SSP, | ||||
| 	CE4100_SSP, | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -43,7 +43,7 @@ struct pxa2xx_spi_chip { | ||||
| 	void (*cs_control)(u32 command); | ||||
| }; | ||||
| 
 | ||||
| #ifdef CONFIG_ARCH_PXA | ||||
| #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) | ||||
| 
 | ||||
| #include <linux/clk.h> | ||||
| #include <mach/dma.h> | ||||
|  | ||||
| @ -12,6 +12,9 @@ | ||||
| enum vga_switcheroo_state { | ||||
| 	VGA_SWITCHEROO_OFF, | ||||
| 	VGA_SWITCHEROO_ON, | ||||
| 	/* below are referred only from vga_switcheroo_get_client_state() */ | ||||
| 	VGA_SWITCHEROO_INIT, | ||||
| 	VGA_SWITCHEROO_NOT_FOUND, | ||||
| }; | ||||
| 
 | ||||
| enum vga_switcheroo_client_id { | ||||
| @ -50,6 +53,8 @@ void vga_switcheroo_unregister_handler(void); | ||||
| 
 | ||||
| int vga_switcheroo_process_delayed_switch(void); | ||||
| 
 | ||||
| int vga_switcheroo_get_client_state(struct pci_dev *dev); | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} | ||||
| @ -62,5 +67,7 @@ static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, | ||||
| 	int id, bool active) { return 0; } | ||||
| static inline void vga_switcheroo_unregister_handler(void) {} | ||||
| static inline int vga_switcheroo_process_delayed_switch(void) { return 0; } | ||||
| static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -502,10 +502,8 @@ static int snd_compr_pause(struct snd_compr_stream *stream) | ||||
| 	if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING) | ||||
| 		return -EPERM; | ||||
| 	retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH); | ||||
| 	if (!retval) { | ||||
| 	if (!retval) | ||||
| 		stream->runtime->state = SNDRV_PCM_STATE_PAUSED; | ||||
| 		wake_up(&stream->runtime->sleep); | ||||
| 	} | ||||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| @ -544,6 +542,10 @@ static int snd_compr_stop(struct snd_compr_stream *stream) | ||||
| 	if (!retval) { | ||||
| 		stream->runtime->state = SNDRV_PCM_STATE_SETUP; | ||||
| 		wake_up(&stream->runtime->sleep); | ||||
| 		stream->runtime->hw_pointer = 0; | ||||
| 		stream->runtime->app_pointer = 0; | ||||
| 		stream->runtime->total_bytes_available = 0; | ||||
| 		stream->runtime->total_bytes_transferred = 0; | ||||
| 	} | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
| @ -4423,20 +4423,19 @@ void snd_hda_update_power_acct(struct hda_codec *codec) | ||||
| 	codec->power_jiffies += delta; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * snd_hda_power_up - Power-up the codec | ||||
|  * @codec: HD-audio codec | ||||
|  * | ||||
|  * Increment the power-up counter and power up the hardware really when | ||||
|  * not turned on yet. | ||||
|  */ | ||||
| void snd_hda_power_up(struct hda_codec *codec) | ||||
| /* Transition to powered up, if wait_power_down then wait for a pending
 | ||||
|  * transition to D3 to complete. A pending D3 transition is indicated | ||||
|  * with power_transition == -1. */ | ||||
| static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) | ||||
| { | ||||
| 	struct hda_bus *bus = codec->bus; | ||||
| 
 | ||||
| 	spin_lock(&codec->power_lock); | ||||
| 	codec->power_count++; | ||||
| 	if (codec->power_on || codec->power_transition > 0) { | ||||
| 	/* Return if power_on or transitioning to power_on, unless currently
 | ||||
| 	 * powering down. */ | ||||
| 	if ((codec->power_on || codec->power_transition > 0) && | ||||
| 	    !(wait_power_down && codec->power_transition < 0)) { | ||||
| 		spin_unlock(&codec->power_lock); | ||||
| 		return; | ||||
| 	} | ||||
| @ -4460,8 +4459,37 @@ void snd_hda_power_up(struct hda_codec *codec) | ||||
| 	codec->power_transition = 0; | ||||
| 	spin_unlock(&codec->power_lock); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * snd_hda_power_up - Power-up the codec | ||||
|  * @codec: HD-audio codec | ||||
|  * | ||||
|  * Increment the power-up counter and power up the hardware really when | ||||
|  * not turned on yet. | ||||
|  */ | ||||
| void snd_hda_power_up(struct hda_codec *codec) | ||||
| { | ||||
| 	__snd_hda_power_up(codec, false); | ||||
| } | ||||
| EXPORT_SYMBOL_HDA(snd_hda_power_up); | ||||
| 
 | ||||
| /**
 | ||||
|  * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending | ||||
|  *   D3 transition to complete.  This differs from snd_hda_power_up() when | ||||
|  *   power_transition == -1.  snd_hda_power_up sees this case as a nop, | ||||
|  *   snd_hda_power_up_d3wait waits for the D3 transition to complete then powers | ||||
|  *   back up. | ||||
|  * @codec: HD-audio codec | ||||
|  * | ||||
|  * Cancel any power down operation hapenning on the work queue, then power up. | ||||
|  */ | ||||
| void snd_hda_power_up_d3wait(struct hda_codec *codec) | ||||
| { | ||||
| 	/* This will cancel and wait for pending power_work to complete. */ | ||||
| 	__snd_hda_power_up(codec, true); | ||||
| } | ||||
| EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait); | ||||
| 
 | ||||
| #define power_save(codec)	\ | ||||
| 	((codec)->bus->power_save ? *(codec)->bus->power_save : 0) | ||||
| 
 | ||||
|  | ||||
| @ -1059,10 +1059,12 @@ const char *snd_hda_get_jack_location(u32 cfg); | ||||
|  */ | ||||
| #ifdef CONFIG_SND_HDA_POWER_SAVE | ||||
| void snd_hda_power_up(struct hda_codec *codec); | ||||
| void snd_hda_power_up_d3wait(struct hda_codec *codec); | ||||
| void snd_hda_power_down(struct hda_codec *codec); | ||||
| void snd_hda_update_power_acct(struct hda_codec *codec); | ||||
| #else | ||||
| static inline void snd_hda_power_up(struct hda_codec *codec) {} | ||||
| static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {} | ||||
| static inline void snd_hda_power_down(struct hda_codec *codec) {} | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -1767,7 +1767,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | ||||
| 				   buff_step); | ||||
| 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | ||||
| 				   buff_step); | ||||
| 	snd_hda_power_up(apcm->codec); | ||||
| 	snd_hda_power_up_d3wait(apcm->codec); | ||||
| 	err = hinfo->ops.open(hinfo, apcm->codec, substream); | ||||
| 	if (err < 0) { | ||||
| 		azx_release_device(azx_dev); | ||||
| @ -2485,9 +2485,9 @@ static void azx_notifier_unregister(struct azx *chip) | ||||
| static int DELAYED_INIT_MARK azx_first_init(struct azx *chip); | ||||
| static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip); | ||||
| 
 | ||||
| #ifdef SUPPORT_VGA_SWITCHEROO | ||||
| static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci); | ||||
| 
 | ||||
| #ifdef SUPPORT_VGA_SWITCHEROO | ||||
| static void azx_vs_set_state(struct pci_dev *pci, | ||||
| 			     enum vga_switcheroo_state state) | ||||
| { | ||||
| @ -2579,6 +2579,7 @@ static int __devinit register_vga_switcheroo(struct azx *chip) | ||||
| #else | ||||
| #define init_vga_switcheroo(chip)		/* NOP */ | ||||
| #define register_vga_switcheroo(chip)		0 | ||||
| #define check_hdmi_disabled(pci)	false | ||||
| #endif /* SUPPORT_VGA_SWITCHER */ | ||||
| 
 | ||||
| /*
 | ||||
| @ -2639,6 +2640,7 @@ static int azx_dev_free(struct snd_device *device) | ||||
| 	return azx_free(device->device_data); | ||||
| } | ||||
| 
 | ||||
| #ifdef SUPPORT_VGA_SWITCHEROO | ||||
| /*
 | ||||
|  * Check of disabled HDMI controller by vga-switcheroo | ||||
|  */ | ||||
| @ -2671,12 +2673,13 @@ static bool __devinit check_hdmi_disabled(struct pci_dev *pci) | ||||
| 	struct pci_dev *p = get_bound_vga(pci); | ||||
| 
 | ||||
| 	if (p) { | ||||
| 		if (vga_default_device() && p != vga_default_device()) | ||||
| 		if (vga_switcheroo_get_client_state(p) == VGA_SWITCHEROO_OFF) | ||||
| 			vga_inactive = true; | ||||
| 		pci_dev_put(p); | ||||
| 	} | ||||
| 	return vga_inactive; | ||||
| } | ||||
| #endif /* SUPPORT_VGA_SWITCHEROO */ | ||||
| 
 | ||||
| /*
 | ||||
|  * white/black-listing for position_fix | ||||
| @ -3360,6 +3363,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | ||||
| 	{ PCI_DEVICE(0x6549, 0x1200), | ||||
| 	  .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, | ||||
| 	/* Creative X-Fi (CA0110-IBG) */ | ||||
| 	/* CTHDA chips */ | ||||
| 	{ PCI_DEVICE(0x1102, 0x0010), | ||||
| 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, | ||||
| 	{ PCI_DEVICE(0x1102, 0x0012), | ||||
| 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, | ||||
| #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) | ||||
| 	/* the following entry conflicts with snd-ctxfi driver,
 | ||||
| 	 * as ctxfi driver mutates from HD-audio to native mode with | ||||
| @ -3376,11 +3384,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | ||||
| 	  .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | | ||||
| 	  AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, | ||||
| #endif | ||||
| 	/* CTHDA chips */ | ||||
| 	{ PCI_DEVICE(0x1102, 0x0010), | ||||
| 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, | ||||
| 	{ PCI_DEVICE(0x1102, 0x0012), | ||||
| 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA }, | ||||
| 	/* Vortex86MX */ | ||||
| 	{ PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, | ||||
| 	/* VMware HDAudio */ | ||||
|  | ||||
| @ -4061,7 +4061,7 @@ static void cx_auto_init_digital(struct hda_codec *codec) | ||||
| static int cx_auto_init(struct hda_codec *codec) | ||||
| { | ||||
| 	struct conexant_spec *spec = codec->spec; | ||||
| 	/*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ | ||||
| 	snd_hda_gen_apply_verbs(codec); | ||||
| 	cx_auto_init_output(codec); | ||||
| 	cx_auto_init_input(codec); | ||||
| 	cx_auto_init_digital(codec); | ||||
|  | ||||
| @ -1896,6 +1896,7 @@ static int alc_init(struct hda_codec *codec) | ||||
| 	alc_fix_pll(codec); | ||||
| 	alc_auto_init_amp(codec, spec->init_amp); | ||||
| 
 | ||||
| 	snd_hda_gen_apply_verbs(codec); | ||||
| 	alc_init_special_input_src(codec); | ||||
| 	alc_auto_init_std(codec); | ||||
| 
 | ||||
| @ -6439,6 +6440,7 @@ enum { | ||||
| 	ALC662_FIXUP_ASUS_MODE7, | ||||
| 	ALC662_FIXUP_ASUS_MODE8, | ||||
| 	ALC662_FIXUP_NO_JACK_DETECT, | ||||
| 	ALC662_FIXUP_ZOTAC_Z68, | ||||
| }; | ||||
| 
 | ||||
| static const struct alc_fixup alc662_fixups[] = { | ||||
| @ -6588,6 +6590,13 @@ static const struct alc_fixup alc662_fixups[] = { | ||||
| 		.type = ALC_FIXUP_FUNC, | ||||
| 		.v.func = alc_fixup_no_jack_detect, | ||||
| 	}, | ||||
| 	[ALC662_FIXUP_ZOTAC_Z68] = { | ||||
| 		.type = ALC_FIXUP_PINS, | ||||
| 		.v.pins = (const struct alc_pincfg[]) { | ||||
| 			{ 0x1b, 0x02214020 }, /* Front HP */ | ||||
| 			{ } | ||||
| 		} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static const struct snd_pci_quirk alc662_fixup_tbl[] = { | ||||
| @ -6601,6 +6610,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | ||||
| 	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | ||||
| 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | ||||
| 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | ||||
| 	SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), | ||||
| 	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), | ||||
| 
 | ||||
| #if 0 | ||||
|  | ||||
| @ -99,8 +99,9 @@ static void wm2000_reset(struct wm2000_priv *wm2000) | ||||
| } | ||||
| 
 | ||||
| static int wm2000_poll_bit(struct i2c_client *i2c, | ||||
| 			   unsigned int reg, u8 mask, int timeout) | ||||
| 			   unsigned int reg, u8 mask) | ||||
| { | ||||
| 	int timeout = 4000; | ||||
| 	int val; | ||||
| 
 | ||||
| 	val = wm2000_read(i2c, reg); | ||||
| @ -119,7 +120,7 @@ static int wm2000_poll_bit(struct i2c_client *i2c, | ||||
| static int wm2000_power_up(struct i2c_client *i2c, int analogue) | ||||
| { | ||||
| 	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); | ||||
| 	int ret, timeout; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	BUG_ON(wm2000->anc_mode != ANC_OFF); | ||||
| 
 | ||||
| @ -140,13 +141,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | ||||
| 
 | ||||
| 	/* Wait for ANC engine to become ready */ | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, | ||||
| 			     WM2000_ANC_ENG_IDLE, 1)) { | ||||
| 			     WM2000_ANC_ENG_IDLE)) { | ||||
| 		dev_err(&i2c->dev, "ANC engine failed to reset\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | ||||
| 			     WM2000_STATUS_BOOT_COMPLETE, 1)) { | ||||
| 			     WM2000_STATUS_BOOT_COMPLETE)) { | ||||
| 		dev_err(&i2c->dev, "ANC engine failed to initialise\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| @ -173,16 +174,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | ||||
| 	dev_dbg(&i2c->dev, "Download complete\n"); | ||||
| 
 | ||||
| 	if (analogue) { | ||||
| 		timeout = 248; | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4); | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4); | ||||
| 
 | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_ANA_SEQ_INCLUDE | | ||||
| 			     WM2000_MODE_MOUSE_ENABLE | | ||||
| 			     WM2000_MODE_THERMAL_ENABLE); | ||||
| 	} else { | ||||
| 		timeout = 10; | ||||
| 
 | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_MOUSE_ENABLE | | ||||
| 			     WM2000_MODE_THERMAL_ENABLE); | ||||
| @ -201,9 +199,8 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | ||||
| 	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | ||||
| 			     WM2000_STATUS_MOUSE_ACTIVE, timeout)) { | ||||
| 		dev_err(&i2c->dev, "Timed out waiting for device after %dms\n", | ||||
| 			timeout * 10); | ||||
| 			     WM2000_STATUS_MOUSE_ACTIVE)) { | ||||
| 		dev_err(&i2c->dev, "Timed out waiting for device\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
| @ -218,28 +215,25 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) | ||||
| static int wm2000_power_down(struct i2c_client *i2c, int analogue) | ||||
| { | ||||
| 	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); | ||||
| 	int timeout; | ||||
| 
 | ||||
| 	if (analogue) { | ||||
| 		timeout = 248; | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4); | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4); | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_ANA_SEQ_INCLUDE | | ||||
| 			     WM2000_MODE_POWER_DOWN); | ||||
| 	} else { | ||||
| 		timeout = 10; | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_POWER_DOWN); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | ||||
| 			     WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) { | ||||
| 			     WM2000_STATUS_POWER_DOWN_COMPLETE)) { | ||||
| 		dev_err(&i2c->dev, "Timeout waiting for ANC power down\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, | ||||
| 			     WM2000_ANC_ENG_IDLE, 1)) { | ||||
| 			     WM2000_ANC_ENG_IDLE)) { | ||||
| 		dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| @ -268,13 +262,13 @@ static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue) | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | ||||
| 			     WM2000_STATUS_ANC_DISABLED, 10)) { | ||||
| 			     WM2000_STATUS_ANC_DISABLED)) { | ||||
| 		dev_err(&i2c->dev, "Timeout waiting for ANC disable\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, | ||||
| 			     WM2000_ANC_ENG_IDLE, 1)) { | ||||
| 			     WM2000_ANC_ENG_IDLE)) { | ||||
| 		dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| @ -311,7 +305,7 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue) | ||||
| 	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | ||||
| 			     WM2000_STATUS_MOUSE_ACTIVE, 10)) { | ||||
| 			     WM2000_STATUS_MOUSE_ACTIVE)) { | ||||
| 		dev_err(&i2c->dev, "Timed out waiting for MOUSE\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| @ -325,38 +319,32 @@ static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue) | ||||
| static int wm2000_enter_standby(struct i2c_client *i2c, int analogue) | ||||
| { | ||||
| 	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); | ||||
| 	int timeout; | ||||
| 
 | ||||
| 	BUG_ON(wm2000->anc_mode != ANC_ACTIVE); | ||||
| 
 | ||||
| 	if (analogue) { | ||||
| 		timeout = 248; | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4); | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, 248 / 4); | ||||
| 
 | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_ANA_SEQ_INCLUDE | | ||||
| 			     WM2000_MODE_THERMAL_ENABLE | | ||||
| 			     WM2000_MODE_STANDBY_ENTRY); | ||||
| 	} else { | ||||
| 		timeout = 10; | ||||
| 
 | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_THERMAL_ENABLE | | ||||
| 			     WM2000_MODE_STANDBY_ENTRY); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | ||||
| 			     WM2000_STATUS_ANC_DISABLED, timeout)) { | ||||
| 			     WM2000_STATUS_ANC_DISABLED)) { | ||||
| 		dev_err(&i2c->dev, | ||||
| 			"Timed out waiting for ANC disable after 1ms\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE, | ||||
| 			     1)) { | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE)) { | ||||
| 		dev_err(&i2c->dev, | ||||
| 			"Timed out waiting for standby after %dms\n", | ||||
| 			timeout * 10); | ||||
| 			"Timed out waiting for standby\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
| @ -374,23 +362,19 @@ static int wm2000_enter_standby(struct i2c_client *i2c, int analogue) | ||||
| static int wm2000_exit_standby(struct i2c_client *i2c, int analogue) | ||||
| { | ||||
| 	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); | ||||
| 	int timeout; | ||||
| 
 | ||||
| 	BUG_ON(wm2000->anc_mode != ANC_STANDBY); | ||||
| 
 | ||||
| 	wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0); | ||||
| 
 | ||||
| 	if (analogue) { | ||||
| 		timeout = 248; | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4); | ||||
| 		wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 248 / 4); | ||||
| 
 | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_ANA_SEQ_INCLUDE | | ||||
| 			     WM2000_MODE_THERMAL_ENABLE | | ||||
| 			     WM2000_MODE_MOUSE_ENABLE); | ||||
| 	} else { | ||||
| 		timeout = 10; | ||||
| 
 | ||||
| 		wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, | ||||
| 			     WM2000_MODE_THERMAL_ENABLE | | ||||
| 			     WM2000_MODE_MOUSE_ENABLE); | ||||
| @ -400,9 +384,8 @@ static int wm2000_exit_standby(struct i2c_client *i2c, int analogue) | ||||
| 	wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR); | ||||
| 
 | ||||
| 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, | ||||
| 			     WM2000_STATUS_MOUSE_ACTIVE, timeout)) { | ||||
| 		dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n", | ||||
| 			timeout * 10); | ||||
| 			     WM2000_STATUS_MOUSE_ACTIVE)) { | ||||
| 		dev_err(&i2c->dev, "Timed out waiting for MOUSE\n"); | ||||
| 		return -ETIMEDOUT; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -1863,6 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, | ||||
| 				return ret; | ||||
| 			} | ||||
| 
 | ||||
| 			regcache_cache_only(wm8904->regmap, false); | ||||
| 			regcache_sync(wm8904->regmap); | ||||
| 
 | ||||
| 			/* Enable bias */ | ||||
| @ -1899,14 +1900,8 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, | ||||
| 		snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, | ||||
| 				    WM8904_BIAS_ENA, 0); | ||||
| 
 | ||||
| #ifdef CONFIG_REGULATOR | ||||
| 		/* Post 2.6.34 we will be able to get a callback when
 | ||||
| 		 * the regulators are disabled which we can use but | ||||
| 		 * for now just assume that the power will be cut if | ||||
| 		 * the regulator API is in use. | ||||
| 		 */ | ||||
| 		codec->cache_sync = 1; | ||||
| #endif | ||||
| 		regcache_cache_only(wm8904->regmap, true); | ||||
| 		regcache_mark_dirty(wm8904->regmap); | ||||
| 
 | ||||
| 		regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), | ||||
| 				       wm8904->supplies); | ||||
| @ -2084,10 +2079,8 @@ static int wm8904_probe(struct snd_soc_codec *codec) | ||||
| { | ||||
| 	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | ||||
| 	struct wm8904_pdata *pdata = wm8904->pdata; | ||||
| 	u16 *reg_cache = codec->reg_cache; | ||||
| 	int ret, i; | ||||
| 
 | ||||
| 	codec->cache_sync = 1; | ||||
| 	codec->control_data = wm8904->regmap; | ||||
| 
 | ||||
| 	switch (wm8904->devtype) { | ||||
| @ -2150,6 +2143,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) | ||||
| 		goto err_enable; | ||||
| 	} | ||||
| 
 | ||||
| 	regcache_cache_only(wm8904->regmap, true); | ||||
| 	/* Change some default settings - latch VU and enable ZC */ | ||||
| 	snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, | ||||
| 			    WM8904_ADC_VU, WM8904_ADC_VU); | ||||
| @ -2180,14 +2174,18 @@ static int wm8904_probe(struct snd_soc_codec *codec) | ||||
| 			if (!pdata->gpio_cfg[i]) | ||||
| 				continue; | ||||
| 
 | ||||
| 			reg_cache[WM8904_GPIO_CONTROL_1 + i] | ||||
| 				= pdata->gpio_cfg[i] & 0xffff; | ||||
| 			regmap_update_bits(wm8904->regmap, | ||||
| 					   WM8904_GPIO_CONTROL_1 + i, | ||||
| 					   0xffff, | ||||
| 					   pdata->gpio_cfg[i]); | ||||
| 		} | ||||
| 
 | ||||
| 		/* Zero is the default value for these anyway */ | ||||
| 		for (i = 0; i < WM8904_MIC_REGS; i++) | ||||
| 			reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] | ||||
| 				= pdata->mic_cfg[i]; | ||||
| 			regmap_update_bits(wm8904->regmap, | ||||
| 					   WM8904_MIC_BIAS_CONTROL_0 + i, | ||||
| 					   0xffff, | ||||
| 					   pdata->mic_cfg[i]); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Set Class W by default - this will be managed by the Class
 | ||||
|  | ||||
| @ -46,6 +46,39 @@ | ||||
| #define WM8994_NUM_DRC 3 | ||||
| #define WM8994_NUM_EQ  3 | ||||
| 
 | ||||
| static struct { | ||||
| 	unsigned int reg; | ||||
| 	unsigned int mask; | ||||
| } wm8994_vu_bits[] = { | ||||
| 	{ WM8994_LEFT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU }, | ||||
| 	{ WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, WM8994_IN1_VU }, | ||||
| 	{ WM8994_LEFT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU }, | ||||
| 	{ WM8994_RIGHT_LINE_INPUT_3_4_VOLUME, WM8994_IN2_VU }, | ||||
| 	{ WM8994_SPEAKER_VOLUME_LEFT, WM8994_SPKOUT_VU }, | ||||
| 	{ WM8994_SPEAKER_VOLUME_RIGHT, WM8994_SPKOUT_VU }, | ||||
| 	{ WM8994_LEFT_OUTPUT_VOLUME, WM8994_HPOUT1_VU }, | ||||
| 	{ WM8994_RIGHT_OUTPUT_VOLUME, WM8994_HPOUT1_VU }, | ||||
| 	{ WM8994_LEFT_OPGA_VOLUME, WM8994_MIXOUT_VU }, | ||||
| 	{ WM8994_RIGHT_OPGA_VOLUME, WM8994_MIXOUT_VU }, | ||||
| 
 | ||||
| 	{ WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1DAC1_VU }, | ||||
| 	{ WM8994_AIF1_DAC1_RIGHT_VOLUME, WM8994_AIF1DAC1_VU }, | ||||
| 	{ WM8994_AIF1_DAC2_LEFT_VOLUME, WM8994_AIF1DAC2_VU }, | ||||
| 	{ WM8994_AIF1_DAC2_RIGHT_VOLUME, WM8994_AIF1DAC2_VU }, | ||||
| 	{ WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2DAC_VU }, | ||||
| 	{ WM8994_AIF2_DAC_RIGHT_VOLUME, WM8994_AIF2DAC_VU }, | ||||
| 	{ WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1ADC1_VU }, | ||||
| 	{ WM8994_AIF1_ADC1_RIGHT_VOLUME, WM8994_AIF1ADC1_VU }, | ||||
| 	{ WM8994_AIF1_ADC2_LEFT_VOLUME, WM8994_AIF1ADC2_VU }, | ||||
| 	{ WM8994_AIF1_ADC2_RIGHT_VOLUME, WM8994_AIF1ADC2_VU }, | ||||
| 	{ WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2ADC_VU }, | ||||
| 	{ WM8994_AIF2_ADC_RIGHT_VOLUME, WM8994_AIF1ADC2_VU }, | ||||
| 	{ WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_VU }, | ||||
| 	{ WM8994_DAC1_RIGHT_VOLUME, WM8994_DAC1_VU }, | ||||
| 	{ WM8994_DAC2_LEFT_VOLUME, WM8994_DAC2_VU }, | ||||
| 	{ WM8994_DAC2_RIGHT_VOLUME, WM8994_DAC2_VU }, | ||||
| }; | ||||
| 
 | ||||
| static int wm8994_drc_base[] = { | ||||
| 	WM8994_AIF1_DRC1_1, | ||||
| 	WM8994_AIF1_DRC2_1, | ||||
| @ -989,6 +1022,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, | ||||
| 	struct snd_soc_codec *codec = w->codec; | ||||
| 	struct wm8994 *control = codec->control_data; | ||||
| 	int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; | ||||
| 	int i; | ||||
| 	int dac; | ||||
| 	int adc; | ||||
| 	int val; | ||||
| @ -1047,6 +1081,13 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w, | ||||
| 				    WM8994_AIF1DAC2L_ENA); | ||||
| 		break; | ||||
| 
 | ||||
| 	case SND_SOC_DAPM_POST_PMU: | ||||
| 		for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) | ||||
| 			snd_soc_write(codec, wm8994_vu_bits[i].reg, | ||||
| 				      snd_soc_read(codec, | ||||
| 						   wm8994_vu_bits[i].reg)); | ||||
| 		break; | ||||
| 
 | ||||
| 	case SND_SOC_DAPM_PRE_PMD: | ||||
| 	case SND_SOC_DAPM_POST_PMD: | ||||
| 		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, | ||||
| @ -1072,6 +1113,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, | ||||
| 		      struct snd_kcontrol *kcontrol, int event) | ||||
| { | ||||
| 	struct snd_soc_codec *codec = w->codec; | ||||
| 	int i; | ||||
| 	int dac; | ||||
| 	int adc; | ||||
| 	int val; | ||||
| @ -1122,6 +1164,13 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w, | ||||
| 				    WM8994_AIF2DACR_ENA); | ||||
| 		break; | ||||
| 
 | ||||
| 	case SND_SOC_DAPM_POST_PMU: | ||||
| 		for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) | ||||
| 			snd_soc_write(codec, wm8994_vu_bits[i].reg, | ||||
| 				      snd_soc_read(codec, | ||||
| 						   wm8994_vu_bits[i].reg)); | ||||
| 		break; | ||||
| 
 | ||||
| 	case SND_SOC_DAPM_PRE_PMD: | ||||
| 	case SND_SOC_DAPM_POST_PMD: | ||||
| 		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, | ||||
| @ -1190,17 +1239,19 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w, | ||||
| 	switch (event) { | ||||
| 	case SND_SOC_DAPM_PRE_PMU: | ||||
| 		if (wm8994->aif1clk_enable) { | ||||
| 			aif1clk_ev(w, kcontrol, event); | ||||
| 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU); | ||||
| 			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, | ||||
| 					    WM8994_AIF1CLK_ENA_MASK, | ||||
| 					    WM8994_AIF1CLK_ENA); | ||||
| 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU); | ||||
| 			wm8994->aif1clk_enable = 0; | ||||
| 		} | ||||
| 		if (wm8994->aif2clk_enable) { | ||||
| 			aif2clk_ev(w, kcontrol, event); | ||||
| 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMU); | ||||
| 			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, | ||||
| 					    WM8994_AIF2CLK_ENA_MASK, | ||||
| 					    WM8994_AIF2CLK_ENA); | ||||
| 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMU); | ||||
| 			wm8994->aif2clk_enable = 0; | ||||
| 		} | ||||
| 		break; | ||||
| @ -1221,15 +1272,17 @@ static int late_disable_ev(struct snd_soc_dapm_widget *w, | ||||
| 	switch (event) { | ||||
| 	case SND_SOC_DAPM_POST_PMD: | ||||
| 		if (wm8994->aif1clk_disable) { | ||||
| 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD); | ||||
| 			snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, | ||||
| 					    WM8994_AIF1CLK_ENA_MASK, 0); | ||||
| 			aif1clk_ev(w, kcontrol, event); | ||||
| 			aif1clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD); | ||||
| 			wm8994->aif1clk_disable = 0; | ||||
| 		} | ||||
| 		if (wm8994->aif2clk_disable) { | ||||
| 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_PRE_PMD); | ||||
| 			snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, | ||||
| 					    WM8994_AIF2CLK_ENA_MASK, 0); | ||||
| 			aif2clk_ev(w, kcontrol, event); | ||||
| 			aif2clk_ev(w, kcontrol, SND_SOC_DAPM_POST_PMD); | ||||
| 			wm8994->aif2clk_disable = 0; | ||||
| 		} | ||||
| 		break; | ||||
| @ -1527,9 +1580,11 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) | ||||
| 
 | ||||
| static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { | ||||
| SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev, | ||||
| 		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), | ||||
| 		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||||
| 		    SND_SOC_DAPM_PRE_PMD), | ||||
| SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev, | ||||
| 		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), | ||||
| 		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | ||||
| 		    SND_SOC_DAPM_PRE_PMD), | ||||
| SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0), | ||||
| SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, | ||||
| 		   left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), | ||||
| @ -3879,39 +3934,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | ||||
| 
 | ||||
| 	pm_runtime_put(codec->dev); | ||||
| 
 | ||||
| 	/* Latch volume updates (right only; we always do left then right). */ | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, | ||||
| 			    WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME, | ||||
| 			    WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_DAC2_LEFT_VOLUME, | ||||
| 			    WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME, | ||||
| 			    WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF2_DAC_LEFT_VOLUME, | ||||
| 			    WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME, | ||||
| 			    WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_ADC1_LEFT_VOLUME, | ||||
| 			    WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME, | ||||
| 			    WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_ADC2_LEFT_VOLUME, | ||||
| 			    WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME, | ||||
| 			    WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF2_ADC_LEFT_VOLUME, | ||||
| 			    WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME, | ||||
| 			    WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_DAC1_LEFT_VOLUME, | ||||
| 			    WM8994_DAC1_VU, WM8994_DAC1_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME, | ||||
| 			    WM8994_DAC1_VU, WM8994_DAC1_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_DAC2_LEFT_VOLUME, | ||||
| 			    WM8994_DAC2_VU, WM8994_DAC2_VU); | ||||
| 	snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME, | ||||
| 			    WM8994_DAC2_VU, WM8994_DAC2_VU); | ||||
| 	/* Latch volume update bits */ | ||||
| 	for (i = 0; i < ARRAY_SIZE(wm8994_vu_bits); i++) | ||||
| 		snd_soc_update_bits(codec, wm8994_vu_bits[i].reg, | ||||
| 				    wm8994_vu_bits[i].mask, | ||||
| 				    wm8994_vu_bits[i].mask); | ||||
| 
 | ||||
| 	/* Set the low bit of the 3D stereo depth so TLV matches */ | ||||
| 	snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2, | ||||
|  | ||||
| @ -2837,8 +2837,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	regcache_cache_only(codec->control_data, true); | ||||
| 
 | ||||
| 	/* Apply platform data settings */ | ||||
| 	snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, | ||||
| 			    WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK, | ||||
| @ -3051,7 +3049,6 @@ static int wm8996_remove(struct snd_soc_codec *codec) | ||||
| 	for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) | ||||
| 		regulator_unregister_notifier(wm8996->supplies[i].consumer, | ||||
| 					      &wm8996->disable_nb[i]); | ||||
| 	regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -3206,14 +3203,15 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, | ||||
| 	dev_info(&i2c->dev, "revision %c\n", | ||||
| 		 (reg & WM8996_CHIP_REV_MASK) + 'A'); | ||||
| 
 | ||||
| 	regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||||
| 
 | ||||
| 	ret = wm8996_reset(wm8996); | ||||
| 	if (ret < 0) { | ||||
| 		dev_err(&i2c->dev, "Failed to issue reset\n"); | ||||
| 		goto err_regmap; | ||||
| 	} | ||||
| 
 | ||||
| 	regcache_cache_only(wm8996->regmap, true); | ||||
| 	regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||||
| 
 | ||||
| 	wm8996_init_gpio(wm8996); | ||||
| 
 | ||||
| 	ret = snd_soc_register_codec(&i2c->dev, | ||||
|  | ||||
| @ -26,6 +26,7 @@ | ||||
| #include <linux/of_device.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/pinctrl/consumer.h> | ||||
| 
 | ||||
| #include "imx-audmux.h" | ||||
| 
 | ||||
| @ -249,6 +250,7 @@ EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); | ||||
| static int __devinit imx_audmux_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct resource *res; | ||||
| 	struct pinctrl *pinctrl; | ||||
| 	const struct of_device_id *of_id = | ||||
| 			of_match_device(imx_audmux_dt_ids, &pdev->dev); | ||||
| 
 | ||||
| @ -257,6 +259,12 @@ static int __devinit imx_audmux_probe(struct platform_device *pdev) | ||||
| 	if (!audmux_base) | ||||
| 		return -EADDRNOTAVAIL; | ||||
| 
 | ||||
| 	pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||||
| 	if (IS_ERR(pinctrl)) { | ||||
| 		dev_err(&pdev->dev, "setup pinctrl failed!"); | ||||
| 		return PTR_ERR(pinctrl); | ||||
| 	} | ||||
| 
 | ||||
| 	audmux_clk = clk_get(&pdev->dev, "audmux"); | ||||
| 	if (IS_ERR(audmux_clk)) { | ||||
| 		dev_dbg(&pdev->dev, "cannot get clock: %ld\n", | ||||
|  | ||||
| @ -33,7 +33,6 @@ | ||||
| 
 | ||||
| #include <mach/hardware.h> | ||||
| #include <mach/dma.h> | ||||
| #include <mach/audio.h> | ||||
| 
 | ||||
| #include "../../arm/pxa2xx-pcm.h" | ||||
| #include "pxa-ssp.h" | ||||
| @ -194,7 +193,7 @@ static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div) | ||||
| { | ||||
| 	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); | ||||
| 
 | ||||
| 	if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { | ||||
| 	if (ssp->type == PXA25x_SSP) { | ||||
| 		sscr0 &= ~0x0000ff00; | ||||
| 		sscr0 |= ((div - 2)/2) << 8; /* 2..512 */ | ||||
| 	} else { | ||||
| @ -212,7 +211,7 @@ static u32 pxa_ssp_get_scr(struct ssp_device *ssp) | ||||
| 	u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); | ||||
| 	u32 div; | ||||
| 
 | ||||
| 	if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) | ||||
| 	if (ssp->type == PXA25x_SSP) | ||||
| 		div = ((sscr0 >> 8) & 0xff) * 2 + 2; | ||||
| 	else | ||||
| 		div = ((sscr0 >> 8) & 0xfff) + 1; | ||||
| @ -242,7 +241,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | ||||
| 		break; | ||||
| 	case PXA_SSP_CLK_PLL: | ||||
| 		/* Internal PLL is fixed */ | ||||
| 		if (cpu_is_pxa25x()) | ||||
| 		if (ssp->type == PXA25x_SSP) | ||||
| 			priv->sysclk = 1843200; | ||||
| 		else | ||||
| 			priv->sysclk = 13000000; | ||||
| @ -266,11 +265,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | ||||
| 
 | ||||
| 	/* The SSP clock must be disabled when changing SSP clock mode
 | ||||
| 	 * on PXA2xx.  On PXA3xx it must be enabled when doing so. */ | ||||
| 	if (!cpu_is_pxa3xx()) | ||||
| 	if (ssp->type != PXA3xx_SSP) | ||||
| 		clk_disable(ssp->clk); | ||||
| 	val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; | ||||
| 	pxa_ssp_write_reg(ssp, SSCR0, val); | ||||
| 	if (!cpu_is_pxa3xx()) | ||||
| 	if (ssp->type != PXA3xx_SSP) | ||||
| 		clk_enable(ssp->clk); | ||||
| 
 | ||||
| 	return 0; | ||||
| @ -294,24 +293,20 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, | ||||
| 	case PXA_SSP_AUDIO_DIV_SCDB: | ||||
| 		val = pxa_ssp_read_reg(ssp, SSACD); | ||||
| 		val &= ~SSACD_SCDB; | ||||
| #if defined(CONFIG_PXA3xx) | ||||
| 		if (cpu_is_pxa3xx()) | ||||
| 		if (ssp->type == PXA3xx_SSP) | ||||
| 			val &= ~SSACD_SCDX8; | ||||
| #endif | ||||
| 		switch (div) { | ||||
| 		case PXA_SSP_CLK_SCDB_1: | ||||
| 			val |= SSACD_SCDB; | ||||
| 			break; | ||||
| 		case PXA_SSP_CLK_SCDB_4: | ||||
| 			break; | ||||
| #if defined(CONFIG_PXA3xx) | ||||
| 		case PXA_SSP_CLK_SCDB_8: | ||||
| 			if (cpu_is_pxa3xx()) | ||||
| 			if (ssp->type == PXA3xx_SSP) | ||||
| 				val |= SSACD_SCDX8; | ||||
| 			else | ||||
| 				return -EINVAL; | ||||
| 			break; | ||||
| #endif | ||||
| 		default: | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| @ -337,10 +332,8 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, | ||||
| 	struct ssp_device *ssp = priv->ssp; | ||||
| 	u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70; | ||||
| 
 | ||||
| #if defined(CONFIG_PXA3xx) | ||||
| 	if (cpu_is_pxa3xx()) | ||||
| 	if (ssp->type == PXA3xx_SSP) | ||||
| 		pxa_ssp_write_reg(ssp, SSACDD, 0); | ||||
| #endif | ||||
| 
 | ||||
| 	switch (freq_out) { | ||||
| 	case 5622000: | ||||
| @ -365,11 +358,10 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| #ifdef CONFIG_PXA3xx | ||||
| 		/* PXA3xx has a clock ditherer which can be used to generate
 | ||||
| 		 * a wider range of frequencies - calculate a value for it. | ||||
| 		 */ | ||||
| 		if (cpu_is_pxa3xx()) { | ||||
| 		if (ssp->type == PXA3xx_SSP) { | ||||
| 			u32 val; | ||||
| 			u64 tmp = 19968; | ||||
| 			tmp *= 1000000; | ||||
| @ -386,7 +378,6 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, | ||||
| 				val, freq_out); | ||||
| 			break; | ||||
| 		} | ||||
| #endif | ||||
| 
 | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| @ -590,10 +581,8 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | ||||
| 	/* bit size */ | ||||
| 	switch (params_format(params)) { | ||||
| 	case SNDRV_PCM_FORMAT_S16_LE: | ||||
| #ifdef CONFIG_PXA3xx | ||||
| 		if (cpu_is_pxa3xx()) | ||||
| 		if (ssp->type == PXA3xx_SSP) | ||||
| 			sscr0 |= SSCR0_FPCKE; | ||||
| #endif | ||||
| 		sscr0 |= SSCR0_DataSize(16); | ||||
| 		break; | ||||
| 	case SNDRV_PCM_FORMAT_S24_LE: | ||||
| @ -618,9 +607,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | ||||
| 			* trying and failing a lot; some of the registers | ||||
| 			* needed for that mode are only available on PXA3xx. | ||||
| 			*/ | ||||
| 
 | ||||
| #ifdef CONFIG_PXA3xx | ||||
| 			if (!cpu_is_pxa3xx()) | ||||
| 			if (ssp->type != PXA3xx_SSP) | ||||
| 				return -EINVAL; | ||||
| 
 | ||||
| 			sspsp |= SSPSP_SFRMWDTH(width * 2); | ||||
| @ -628,9 +615,6 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | ||||
| 			sspsp |= SSPSP_EDMYSTOP(3); | ||||
| 			sspsp |= SSPSP_DMYSTOP(3); | ||||
| 			sspsp |= SSPSP_DMYSTRT(1); | ||||
| #else | ||||
| 			return -EINVAL; | ||||
| #endif | ||||
| 		} else { | ||||
| 			/* The frame width is the width the LRCLK is
 | ||||
| 			 * asserted for; the delay is expressed in | ||||
|  | ||||
| @ -913,7 +913,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, | ||||
| 			/* do we need to add this widget to the list ? */ | ||||
| 			if (list) { | ||||
| 				int err; | ||||
| 				err = dapm_list_add_widget(list, path->sink); | ||||
| 				err = dapm_list_add_widget(list, path->source); | ||||
| 				if (err < 0) { | ||||
| 					dev_err(widget->dapm->dev, "could not add widget %s\n", | ||||
| 						widget->name); | ||||
| @ -954,7 +954,7 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, | ||||
| 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||||
| 		paths = is_connected_output_ep(dai->playback_widget, list); | ||||
| 	else | ||||
| 		paths = is_connected_input_ep(dai->playback_widget, list); | ||||
| 		paths = is_connected_input_ep(dai->capture_widget, list); | ||||
| 
 | ||||
| 	trace_snd_soc_dapm_connected(paths, stream); | ||||
| 	dapm_clear_walk(&card->dapm); | ||||
|  | ||||
| @ -794,6 +794,9 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, | ||||
| 		for (i = 0; i < card->num_links; i++) { | ||||
| 			be = &card->rtd[i]; | ||||
| 
 | ||||
| 			if (!be->dai_link->no_pcm) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (be->cpu_dai->playback_widget == widget || | ||||
| 				be->codec_dai->playback_widget == widget) | ||||
| 				return be; | ||||
| @ -803,6 +806,9 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, | ||||
| 		for (i = 0; i < card->num_links; i++) { | ||||
| 			be = &card->rtd[i]; | ||||
| 
 | ||||
| 			if (!be->dai_link->no_pcm) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (be->cpu_dai->capture_widget == widget || | ||||
| 				be->codec_dai->capture_widget == widget) | ||||
| 				return be; | ||||
|  | ||||
| @ -629,3 +629,4 @@ MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); | ||||
| MODULE_DESCRIPTION("Tegra30 AHUB driver"); | ||||
| MODULE_LICENSE("GPL v2"); | ||||
| MODULE_ALIAS("platform:" DRV_NAME); | ||||
| MODULE_DEVICE_TABLE(of, tegra30_ahub_of_match); | ||||
|  | ||||
| @ -346,6 +346,17 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int tegra_wm8903_remove(struct snd_soc_card *card) | ||||
| { | ||||
| 	struct snd_soc_pcm_runtime *rtd = &(card->rtd[0]); | ||||
| 	struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||||
| 	struct snd_soc_codec *codec = codec_dai->codec; | ||||
| 
 | ||||
| 	wm8903_mic_detect(codec, NULL, 0, 0); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct snd_soc_dai_link tegra_wm8903_dai = { | ||||
| 	.name = "WM8903", | ||||
| 	.stream_name = "WM8903 PCM", | ||||
| @ -363,6 +374,8 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { | ||||
| 	.dai_link = &tegra_wm8903_dai, | ||||
| 	.num_links = 1, | ||||
| 
 | ||||
| 	.remove = tegra_wm8903_remove, | ||||
| 
 | ||||
| 	.controls = tegra_wm8903_controls, | ||||
| 	.num_controls = ARRAY_SIZE(tegra_wm8903_controls), | ||||
| 	.dapm_widgets = tegra_wm8903_dapm_widgets, | ||||
|  | ||||
| @ -119,6 +119,7 @@ struct snd_usb_substream { | ||||
| 	unsigned long unlink_mask;	/* bitmask of unlinked urbs */ | ||||
| 
 | ||||
| 	/* data and sync endpoints for this stream */ | ||||
| 	unsigned int ep_num;		/* the endpoint number */ | ||||
| 	struct snd_usb_endpoint *data_endpoint; | ||||
| 	struct snd_usb_endpoint *sync_endpoint; | ||||
| 	unsigned long flags; | ||||
|  | ||||
| @ -354,17 +354,21 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | ||||
| 		    (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && | ||||
| 		     get_endpoint(alts, 1)->bSynchAddress != 0 && | ||||
| 		     !implicit_fb)) { | ||||
| 			snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", | ||||
| 				   dev->devnum, fmt->iface, fmt->altsetting); | ||||
| 			snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n", | ||||
| 				   dev->devnum, fmt->iface, fmt->altsetting, | ||||
| 				   get_endpoint(alts, 1)->bmAttributes, | ||||
| 				   get_endpoint(alts, 1)->bLength, | ||||
| 				   get_endpoint(alts, 1)->bSynchAddress); | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 		ep = get_endpoint(alts, 1)->bEndpointAddress; | ||||
| 		if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && | ||||
| 		if (!implicit_fb && | ||||
| 		    get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && | ||||
| 		    (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || | ||||
| 		     (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)) || | ||||
| 		     ( is_playback && !implicit_fb))) { | ||||
| 			snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", | ||||
| 				   dev->devnum, fmt->iface, fmt->altsetting); | ||||
| 		     (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { | ||||
| 			snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n", | ||||
| 				   dev->devnum, fmt->iface, fmt->altsetting, | ||||
| 				   is_playback, ep, get_endpoint(alts, 0)->bSynchAddress); | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 
 | ||||
| @ -1147,7 +1151,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea | ||||
| 	return -EINVAL; | ||||
| } | ||||
| 
 | ||||
| int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd) | ||||
| static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, | ||||
| 					     int cmd) | ||||
| { | ||||
| 	int err; | ||||
| 	struct snd_usb_substream *subs = substream->runtime->private_data; | ||||
|  | ||||
| @ -97,6 +97,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, | ||||
| 	subs->formats |= fp->formats; | ||||
| 	subs->num_formats++; | ||||
| 	subs->fmt_type = fp->fmt_type; | ||||
| 	subs->ep_num = fp->endpoint; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
| @ -119,9 +120,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | ||||
| 		if (as->fmt_type != fp->fmt_type) | ||||
| 			continue; | ||||
| 		subs = &as->substream[stream]; | ||||
| 		if (!subs->data_endpoint) | ||||
| 			continue; | ||||
| 		if (subs->data_endpoint->ep_num == fp->endpoint) { | ||||
| 		if (subs->ep_num == fp->endpoint) { | ||||
| 			list_add_tail(&fp->list, &subs->fmt_list); | ||||
| 			subs->num_formats++; | ||||
| 			subs->formats |= fp->formats; | ||||
| @ -134,7 +133,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | ||||
| 		if (as->fmt_type != fp->fmt_type) | ||||
| 			continue; | ||||
| 		subs = &as->substream[stream]; | ||||
| 		if (subs->data_endpoint) | ||||
| 		if (subs->ep_num) | ||||
| 			continue; | ||||
| 		err = snd_pcm_new_stream(as->pcm, stream, 1); | ||||
| 		if (err < 0) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user