mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	sound fixes for 5.0-rc4
A significant amount of fixes at this time, mostly for covering the
 recent ASoC issues.
 
 - Fixes for the missing ASoC driver initialization with non-deferred
   probes; these triggered other problems in chain, which resulted in
   yet more fix commits
 
 - DaVinci runtime PM fix; the diff looks large but it's just a code
   shuffling
 
 - Various fixes for ASoC Intel drivers: a regression in HD-A HDMI,
   Kconfig dependency, machine driver adjustments, PLL fix.
 
 - Other ASoC driver-specific stuff including the trivial fixes
   caught by static analysis
 
 - Usual HD-audio quirks
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAlxIgl0OHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE8qxA//ZazLs6ervVtPwiMJxHuhn1zfzC664K+qnCf7
 ioz3UA7c8CzEaVsmhfVwT3+kzGEaVC9fl+q2Pff0fozeRGEs83Rwbs6miWmRGlIc
 xULg+B5YqFMIspZY4gtCpjUk+msDD2sr7vPSpvZaR925Hb4HsMuAItyrYVe4JmXe
 PQVYuoDDHcZoko+BsXlzjr6n63Um8937yxx3dEwtdtI/12CxQTebjzdIt9HbyUTC
 q4BzBOLQ+NLFL5Fefg7dp+8SIvzklApmZgsUzJTf9IlH5tVClS63DfXhCT2X//fO
 jSDEkQAQlrm5EOPDFB2Jc5awIcrPpq8OColfoYSEIVw8oPbqaXcurTcERGZOBkTJ
 DEsTGcXLumnEf6CCzEqRyIYJq9p/uZ+pkFL4FI6AtxV3GyAa5llerZN1rn2QDoLU
 QmbX1bX3BfcFNnU64rXEyo2A3ceNp71bBSJH3Oe7x4um3OTry9AJqT3l4/lrhC7Z
 xAiF5PfUuaaYPyx8fOpCVnJpe5EyfgqF2VnAmltqhhaqpFC13RKiw1pHwxLHfcz9
 UApQAYT5gDrFAR3Pd1m6lJm0EpXozUPJ/geBsYpIU2k4chJVyjLx93fpbc5TSUEX
 CSJlyCQSJB8IWq5imew9U2PqOWFV87JgQC4E/vlfwLzyo9DSArdiYs+HBfdm9XeY
 uSuqa/E=
 =gEDB
 -----END PGP SIGNATURE-----
Merge tag 'sound-5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
 "A significant amount of fixes at this time, mostly for covering the
  recent ASoC issues.
   - Fixes for the missing ASoC driver initialization with non-deferred
     probes; these triggered other problems in chain, which resulted in
     yet more fix commits
   - DaVinci runtime PM fix; the diff looks large but it's just a code
     shuffling
   - Various fixes for ASoC Intel drivers: a regression in HD-A HDMI,
     Kconfig dependency, machine driver adjustments, PLL fix.
   - Other ASoC driver-specific stuff including the trivial fixes caught
     by static analysis
   - Usual HD-audio quirks"
* tag 'sound-5.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (30 commits)
  ALSA: hda - Add mute LED support for HP ProBook 470 G5
  ASoC: amd: Fix potential NULL pointer dereference
  ASoC: imx-audmux: change snprintf to scnprintf for possible overflow
  ASoC: rt5514-spi: Fix potential NULL pointer dereference
  ASoC: dapm: change snprintf to scnprintf for possible overflow
  ASoC: rt5682: Fix PLL source register definitions
  ASoC: core: Don't defer probe on optional, NULL components
  ASoC: core: Make snd_soc_find_component() more robust
  ASoC: soc-core: fix init platform memory handling
  ASoC: intel: skl: Fix display power regression
  ALSA: hda/realtek - Fix typo for ALC225 model
  ASoC: soc-core: Hold client_mutex around soc_init_dai_link()
  ASoC: Intel: Boards: move the codec PLL configuration to _init
  ASoC: soc-core: defer card probe until all component is added to list
  ASoC: atom: fix a missing check of snd_pcm_lib_malloc_pages
  ASoC: tlv320aic32x4: Kernel OOPS while entering DAPM standby mode
  ASoC: ti: davinci-mcasp: Move context save/restore to runtime_pm callbacks
  ASoC: Variable "val" in function rt274_i2c_probe() could be uninitialized
  ASoC: rt5682: Fix recording no sound issue
  ASoC: Intel: atom: Make PCI dependency explicit
  ...
			
			
This commit is contained in:
		
						commit
						aa7b98459f
					
				
					 27 changed files with 227 additions and 297 deletions
				
			
		| 
						 | 
				
			
			@ -985,6 +985,12 @@ struct snd_soc_dai_link {
 | 
			
		|||
	/* Do not create a PCM for this DAI link (Backend link) */
 | 
			
		||||
	unsigned int ignore:1;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * This driver uses legacy platform naming. Set by the core, machine
 | 
			
		||||
	 * drivers should not modify this value.
 | 
			
		||||
	 */
 | 
			
		||||
	unsigned int legacy_platform:1;
 | 
			
		||||
 | 
			
		||||
	struct list_head list; /* DAI link list of the soc card */
 | 
			
		||||
	struct snd_soc_dobj dobj; /* For topology */
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -541,7 +541,8 @@ static int snd_compress_check_input(struct snd_compr_params *params)
 | 
			
		|||
{
 | 
			
		||||
	/* first let's check the buffer parameter's */
 | 
			
		||||
	if (params->buffer.fragment_size == 0 ||
 | 
			
		||||
	    params->buffer.fragments > INT_MAX / params->buffer.fragment_size)
 | 
			
		||||
	    params->buffer.fragments > INT_MAX / params->buffer.fragment_size ||
 | 
			
		||||
	    params->buffer.fragments == 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	/* now codec parameters */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -931,6 +931,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
 | 
			
		|||
	SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
 | 
			
		||||
	SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO),
 | 
			
		||||
	SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO),
 | 
			
		||||
	SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO),
 | 
			
		||||
	SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
 | 
			
		||||
	SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
 | 
			
		||||
	SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6926,7 +6926,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
 | 
			
		|||
	{.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
 | 
			
		||||
	{.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
 | 
			
		||||
	{.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"},
 | 
			
		||||
	{.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"},
 | 
			
		||||
	{.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc225-dell1"},
 | 
			
		||||
	{.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
 | 
			
		||||
	{.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
 | 
			
		||||
	{.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -611,14 +611,16 @@ static int acp3x_audio_probe(struct platform_device *pdev)
 | 
			
		|||
	}
 | 
			
		||||
	irqflags = *((unsigned int *)(pdev->dev.platform_data));
 | 
			
		||||
 | 
			
		||||
	adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data),
 | 
			
		||||
			     GFP_KERNEL);
 | 
			
		||||
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
			
		||||
	if (!res) {
 | 
			
		||||
		dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
 | 
			
		||||
			return -ENODEV;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
 | 
			
		||||
	if (!adata)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
 | 
			
		||||
					 resource_size(res));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1890,51 +1890,31 @@ static void hdmi_codec_remove(struct snd_soc_component *component)
 | 
			
		|||
	pm_runtime_disable(&hdev->dev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PM
 | 
			
		||||
static int hdmi_codec_prepare(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct hdac_device *hdev = dev_to_hdac_dev(dev);
 | 
			
		||||
 | 
			
		||||
	pm_runtime_get_sync(&hdev->dev);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Power down afg.
 | 
			
		||||
	 * codec_read is preferred over codec_write to set the power state.
 | 
			
		||||
	 * This way verb is send to set the power state and response
 | 
			
		||||
	 * is received. So setting power state is ensured without using loop
 | 
			
		||||
	 * to read the state.
 | 
			
		||||
	 */
 | 
			
		||||
	snd_hdac_codec_read(hdev, hdev->afg, 0,	AC_VERB_SET_POWER_STATE,
 | 
			
		||||
							AC_PWRST_D3);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void hdmi_codec_complete(struct device *dev)
 | 
			
		||||
#ifdef CONFIG_PM_SLEEP
 | 
			
		||||
static int hdmi_codec_resume(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct hdac_device *hdev = dev_to_hdac_dev(dev);
 | 
			
		||||
	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	/* Power up afg */
 | 
			
		||||
	snd_hdac_codec_read(hdev, hdev->afg, 0,	AC_VERB_SET_POWER_STATE,
 | 
			
		||||
							AC_PWRST_D0);
 | 
			
		||||
 | 
			
		||||
	hdac_hdmi_skl_enable_all_pins(hdev);
 | 
			
		||||
	hdac_hdmi_skl_enable_dp12(hdev);
 | 
			
		||||
 | 
			
		||||
	ret = pm_runtime_force_resume(dev);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
	/*
 | 
			
		||||
	 * As the ELD notify callback request is not entertained while the
 | 
			
		||||
	 * device is in suspend state. Need to manually check detection of
 | 
			
		||||
	 * all pins here. pin capablity change is not support, so use the
 | 
			
		||||
	 * already set pin caps.
 | 
			
		||||
	 *
 | 
			
		||||
	 * NOTE: this is safe to call even if the codec doesn't actually resume.
 | 
			
		||||
	 * The pin check involves only with DRM audio component hooks, so it
 | 
			
		||||
	 * works even if the HD-audio side is still dreaming peacefully.
 | 
			
		||||
	 */
 | 
			
		||||
	hdac_hdmi_present_sense_all_pins(hdev, hdmi, false);
 | 
			
		||||
 | 
			
		||||
	pm_runtime_put_sync(&hdev->dev);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#define hdmi_codec_prepare NULL
 | 
			
		||||
#define hdmi_codec_complete NULL
 | 
			
		||||
#define hdmi_codec_resume NULL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static const struct snd_soc_component_driver hdmi_hda_codec = {
 | 
			
		||||
| 
						 | 
				
			
			@ -2135,75 +2115,6 @@ static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PM
 | 
			
		||||
/*
 | 
			
		||||
 * Power management sequences
 | 
			
		||||
 * ==========================
 | 
			
		||||
 *
 | 
			
		||||
 * The following explains the PM handling of HDAC HDMI with its parent
 | 
			
		||||
 * device SKL and display power usage
 | 
			
		||||
 *
 | 
			
		||||
 * Probe
 | 
			
		||||
 * -----
 | 
			
		||||
 * In SKL probe,
 | 
			
		||||
 * 1. skl_probe_work() powers up the display (refcount++ -> 1)
 | 
			
		||||
 * 2. enumerates the codecs on the link
 | 
			
		||||
 * 3. powers down the display  (refcount-- -> 0)
 | 
			
		||||
 *
 | 
			
		||||
 * In HDAC HDMI probe,
 | 
			
		||||
 * 1. hdac_hdmi_dev_probe() powers up the display (refcount++ -> 1)
 | 
			
		||||
 * 2. probe the codec
 | 
			
		||||
 * 3. put the HDAC HDMI device to runtime suspend
 | 
			
		||||
 * 4. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
 | 
			
		||||
 *
 | 
			
		||||
 * Once children are runtime suspended, SKL device also goes to runtime
 | 
			
		||||
 * suspend
 | 
			
		||||
 *
 | 
			
		||||
 * HDMI Playback
 | 
			
		||||
 * -------------
 | 
			
		||||
 * Open HDMI device,
 | 
			
		||||
 * 1. skl_runtime_resume() invoked
 | 
			
		||||
 * 2. hdac_hdmi_runtime_resume() powers up the display (refcount++ -> 1)
 | 
			
		||||
 *
 | 
			
		||||
 * Close HDMI device,
 | 
			
		||||
 * 1. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
 | 
			
		||||
 * 2. skl_runtime_suspend() invoked
 | 
			
		||||
 *
 | 
			
		||||
 * S0/S3 Cycle with playback in progress
 | 
			
		||||
 * -------------------------------------
 | 
			
		||||
 * When the device is opened for playback, the device is runtime active
 | 
			
		||||
 * already and the display refcount is 1 as explained above.
 | 
			
		||||
 *
 | 
			
		||||
 * Entering to S3,
 | 
			
		||||
 * 1. hdmi_codec_prepare() invoke the runtime resume of codec which just
 | 
			
		||||
 *    increments the PM runtime usage count of the codec since the device
 | 
			
		||||
 *    is in use already
 | 
			
		||||
 * 2. skl_suspend() powers down the display (refcount-- -> 0)
 | 
			
		||||
 *
 | 
			
		||||
 * Wakeup from S3,
 | 
			
		||||
 * 1. skl_resume() powers up the display (refcount++ -> 1)
 | 
			
		||||
 * 2. hdmi_codec_complete() invokes the runtime suspend of codec which just
 | 
			
		||||
 *    decrements the PM runtime usage count of the codec since the device
 | 
			
		||||
 *    is in use already
 | 
			
		||||
 *
 | 
			
		||||
 * Once playback is stopped, the display refcount is set to 0 as explained
 | 
			
		||||
 * above in the HDMI playback sequence. The PM handlings are designed in
 | 
			
		||||
 * such way that to balance the refcount of display power when the codec
 | 
			
		||||
 * device put to S3 while playback is going on.
 | 
			
		||||
 *
 | 
			
		||||
 * S0/S3 Cycle without playback in progress
 | 
			
		||||
 * ----------------------------------------
 | 
			
		||||
 * Entering to S3,
 | 
			
		||||
 * 1. hdmi_codec_prepare() invoke the runtime resume of codec
 | 
			
		||||
 * 2. skl_runtime_resume() invoked
 | 
			
		||||
 * 3. hdac_hdmi_runtime_resume() powers up the display (refcount++ -> 1)
 | 
			
		||||
 * 4. skl_suspend() powers down the display (refcount-- -> 0)
 | 
			
		||||
 *
 | 
			
		||||
 * Wakeup from S3,
 | 
			
		||||
 * 1. skl_resume() powers up the display (refcount++ -> 1)
 | 
			
		||||
 * 2. hdmi_codec_complete() invokes the runtime suspend of codec
 | 
			
		||||
 * 3. hdac_hdmi_runtime_suspend() powers down the display (refcount-- -> 0)
 | 
			
		||||
 * 4. skl_runtime_suspend() invoked
 | 
			
		||||
 */
 | 
			
		||||
static int hdac_hdmi_runtime_suspend(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct hdac_device *hdev = dev_to_hdac_dev(dev);
 | 
			
		||||
| 
						 | 
				
			
			@ -2277,8 +2188,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
 | 
			
		|||
 | 
			
		||||
static const struct dev_pm_ops hdac_hdmi_pm = {
 | 
			
		||||
	SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
 | 
			
		||||
	.prepare = hdmi_codec_prepare,
 | 
			
		||||
	.complete = hdmi_codec_complete,
 | 
			
		||||
	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, hdmi_codec_resume)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct hda_device_id hdmi_list[] = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1400,24 +1400,20 @@ static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
 | 
			
		|||
		if (ret != 0) {
 | 
			
		||||
			dev_err(component->dev,
 | 
			
		||||
				"Failed to set digital mute: %d\n", ret);
 | 
			
		||||
			mutex_unlock(&pcm512x->mutex);
 | 
			
		||||
			return ret;
 | 
			
		||||
			goto unlock;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		regmap_read_poll_timeout(pcm512x->regmap,
 | 
			
		||||
					 PCM512x_ANALOG_MUTE_DET,
 | 
			
		||||
					 mute_det, (mute_det & 0x3) == 0,
 | 
			
		||||
					 200, 10000);
 | 
			
		||||
 | 
			
		||||
		mutex_unlock(&pcm512x->mutex);
 | 
			
		||||
	} else {
 | 
			
		||||
		pcm512x->mute &= ~0x1;
 | 
			
		||||
		ret = pcm512x_update_mute(pcm512x);
 | 
			
		||||
		if (ret != 0) {
 | 
			
		||||
			dev_err(component->dev,
 | 
			
		||||
				"Failed to update digital mute: %d\n", ret);
 | 
			
		||||
			mutex_unlock(&pcm512x->mutex);
 | 
			
		||||
			return ret;
 | 
			
		||||
			goto unlock;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		regmap_read_poll_timeout(pcm512x->regmap,
 | 
			
		||||
| 
						 | 
				
			
			@ -1428,9 +1424,10 @@ static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
 | 
			
		|||
					 200, 10000);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
unlock:
 | 
			
		||||
	mutex_unlock(&pcm512x->mutex);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct snd_soc_dai_ops pcm512x_dai_ops = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1128,8 +1128,11 @@ static int rt274_i2c_probe(struct i2c_client *i2c,
 | 
			
		|||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	regmap_read(rt274->regmap,
 | 
			
		||||
	ret = regmap_read(rt274->regmap,
 | 
			
		||||
		RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	if (val != RT274_VENDOR_ID) {
 | 
			
		||||
		dev_err(&i2c->dev,
 | 
			
		||||
			"Device with ID register %#x is not rt274\n", val);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,6 +280,8 @@ static int rt5514_spi_pcm_probe(struct snd_soc_component *component)
 | 
			
		|||
 | 
			
		||||
	rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp),
 | 
			
		||||
			GFP_KERNEL);
 | 
			
		||||
	if (!rt5514_dsp)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	rt5514_dsp->dev = &rt5514_spi->dev;
 | 
			
		||||
	mutex_init(&rt5514_dsp->dma_lock);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2512,6 +2512,7 @@ static void rt5682_calibrate(struct rt5682_priv *rt5682)
 | 
			
		|||
	regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x0000);
 | 
			
		||||
	regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x2000);
 | 
			
		||||
	regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x2005);
 | 
			
		||||
	regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0xc0c4);
 | 
			
		||||
 | 
			
		||||
	mutex_unlock(&rt5682->calibrate_mutex);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -849,18 +849,18 @@
 | 
			
		|||
#define RT5682_SCLK_SRC_PLL2			(0x2 << 13)
 | 
			
		||||
#define RT5682_SCLK_SRC_SDW			(0x3 << 13)
 | 
			
		||||
#define RT5682_SCLK_SRC_RCCLK			(0x4 << 13)
 | 
			
		||||
#define RT5682_PLL1_SRC_MASK			(0x3 << 10)
 | 
			
		||||
#define RT5682_PLL1_SRC_SFT			10
 | 
			
		||||
#define RT5682_PLL1_SRC_MCLK			(0x0 << 10)
 | 
			
		||||
#define RT5682_PLL1_SRC_BCLK1			(0x1 << 10)
 | 
			
		||||
#define RT5682_PLL1_SRC_SDW			(0x2 << 10)
 | 
			
		||||
#define RT5682_PLL1_SRC_RC			(0x3 << 10)
 | 
			
		||||
#define RT5682_PLL2_SRC_MASK			(0x3 << 8)
 | 
			
		||||
#define RT5682_PLL2_SRC_SFT			8
 | 
			
		||||
#define RT5682_PLL2_SRC_MCLK			(0x0 << 8)
 | 
			
		||||
#define RT5682_PLL2_SRC_BCLK1			(0x1 << 8)
 | 
			
		||||
#define RT5682_PLL2_SRC_SDW			(0x2 << 8)
 | 
			
		||||
#define RT5682_PLL2_SRC_RC			(0x3 << 8)
 | 
			
		||||
#define RT5682_PLL2_SRC_MASK			(0x3 << 10)
 | 
			
		||||
#define RT5682_PLL2_SRC_SFT			10
 | 
			
		||||
#define RT5682_PLL2_SRC_MCLK			(0x0 << 10)
 | 
			
		||||
#define RT5682_PLL2_SRC_BCLK1			(0x1 << 10)
 | 
			
		||||
#define RT5682_PLL2_SRC_SDW			(0x2 << 10)
 | 
			
		||||
#define RT5682_PLL2_SRC_RC			(0x3 << 10)
 | 
			
		||||
#define RT5682_PLL1_SRC_MASK			(0x3 << 8)
 | 
			
		||||
#define RT5682_PLL1_SRC_SFT			8
 | 
			
		||||
#define RT5682_PLL1_SRC_MCLK			(0x0 << 8)
 | 
			
		||||
#define RT5682_PLL1_SRC_BCLK1			(0x1 << 8)
 | 
			
		||||
#define RT5682_PLL1_SRC_SDW			(0x2 << 8)
 | 
			
		||||
#define RT5682_PLL1_SRC_RC			(0x3 << 8)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -822,6 +822,10 @@ static int aic32x4_set_bias_level(struct snd_soc_component *component,
 | 
			
		|||
	case SND_SOC_BIAS_PREPARE:
 | 
			
		||||
		break;
 | 
			
		||||
	case SND_SOC_BIAS_STANDBY:
 | 
			
		||||
		/* Initial cold start */
 | 
			
		||||
		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		/* Switch off BCLK_N Divider */
 | 
			
		||||
		snd_soc_component_update_bits(component, AIC32X4_BCLKN,
 | 
			
		||||
				    AIC32X4_BCLKEN, 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,49 +86,49 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
 | 
			
		|||
	if (!buf)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
 | 
			
		||||
	ret = scnprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
 | 
			
		||||
		       pdcr, ptcr);
 | 
			
		||||
 | 
			
		||||
	if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
 | 
			
		||||
		ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
				"TxFS output from %s, ",
 | 
			
		||||
				audmux_port_string((ptcr >> 27) & 0x7));
 | 
			
		||||
	else
 | 
			
		||||
		ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
				"TxFS input, ");
 | 
			
		||||
 | 
			
		||||
	if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR)
 | 
			
		||||
		ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
				"TxClk output from %s",
 | 
			
		||||
				audmux_port_string((ptcr >> 22) & 0x7));
 | 
			
		||||
	else
 | 
			
		||||
		ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
				"TxClk input");
 | 
			
		||||
 | 
			
		||||
	ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
 | 
			
		||||
	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
 | 
			
		||||
 | 
			
		||||
	if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
 | 
			
		||||
		ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
				"Port is symmetric");
 | 
			
		||||
	} else {
 | 
			
		||||
		if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR)
 | 
			
		||||
			ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
			ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
					"RxFS output from %s, ",
 | 
			
		||||
					audmux_port_string((ptcr >> 17) & 0x7));
 | 
			
		||||
		else
 | 
			
		||||
			ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
			ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
					"RxFS input, ");
 | 
			
		||||
 | 
			
		||||
		if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR)
 | 
			
		||||
			ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
			ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
					"RxClk output from %s",
 | 
			
		||||
					audmux_port_string((ptcr >> 12) & 0x7));
 | 
			
		||||
		else
 | 
			
		||||
			ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
			ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
					"RxClk input");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
	ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
			"\nData received from %s\n",
 | 
			
		||||
			audmux_port_string((pdcr >> 13) & 0x7));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,7 +91,7 @@ config SND_SST_ATOM_HIFI2_PLATFORM_PCI
 | 
			
		|||
config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
 | 
			
		||||
	tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
 | 
			
		||||
	default ACPI
 | 
			
		||||
	depends on X86 && ACPI
 | 
			
		||||
	depends on X86 && ACPI && PCI
 | 
			
		||||
	select SND_SST_IPC_ACPI
 | 
			
		||||
	select SND_SST_ATOM_HIFI2_PLATFORM
 | 
			
		||||
	select SND_SOC_ACPI_INTEL_MATCH
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -399,7 +399,13 @@ static int sst_media_hw_params(struct snd_pcm_substream *substream,
 | 
			
		|||
				struct snd_pcm_hw_params *params,
 | 
			
		||||
				struct snd_soc_dai *dai)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret =
 | 
			
		||||
		snd_pcm_lib_malloc_pages(substream,
 | 
			
		||||
				params_buffer_bytes(params));
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
	memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -192,7 +192,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
 | 
			
		|||
		.stream_name = "Loopback",
 | 
			
		||||
		.cpu_dai_name = "Loopback Pin",
 | 
			
		||||
		.platform_name = "haswell-pcm-audio",
 | 
			
		||||
		.dynamic = 0,
 | 
			
		||||
		.dynamic = 1,
 | 
			
		||||
		.codec_name = "snd-soc-dummy",
 | 
			
		||||
		.codec_dai_name = "snd-soc-dummy-dai",
 | 
			
		||||
		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,39 +55,6 @@ enum {
 | 
			
		|||
	GLK_DPCM_AUDIO_HDMI3_PB,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int platform_clock_control(struct snd_soc_dapm_widget *w,
 | 
			
		||||
					struct snd_kcontrol *k, int  event)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_dapm_context *dapm = w->dapm;
 | 
			
		||||
	struct snd_soc_card *card = dapm->card;
 | 
			
		||||
	struct snd_soc_dai *codec_dai;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	codec_dai = snd_soc_card_get_codec_dai(card, GLK_REALTEK_CODEC_DAI);
 | 
			
		||||
	if (!codec_dai) {
 | 
			
		||||
		dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
 | 
			
		||||
		return -EIO;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (SND_SOC_DAPM_EVENT_OFF(event)) {
 | 
			
		||||
		ret = snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
 | 
			
		||||
		if (ret)
 | 
			
		||||
			dev_err(card->dev, "failed to stop sysclk: %d\n", ret);
 | 
			
		||||
	} else if (SND_SOC_DAPM_EVENT_ON(event)) {
 | 
			
		||||
		ret = snd_soc_dai_set_pll(codec_dai, 0, RT5682_PLL1_S_MCLK,
 | 
			
		||||
					GLK_PLAT_CLK_FREQ, RT5682_PLL_FREQ);
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			dev_err(card->dev, "can't set codec pll: %d\n", ret);
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ret)
 | 
			
		||||
		dev_err(card->dev, "failed to start internal clk: %d\n", ret);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct snd_kcontrol_new geminilake_controls[] = {
 | 
			
		||||
	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
 | 
			
		||||
	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 | 
			
		||||
| 
						 | 
				
			
			@ -102,14 +69,10 @@ static const struct snd_soc_dapm_widget geminilake_widgets[] = {
 | 
			
		|||
	SND_SOC_DAPM_SPK("HDMI1", NULL),
 | 
			
		||||
	SND_SOC_DAPM_SPK("HDMI2", NULL),
 | 
			
		||||
	SND_SOC_DAPM_SPK("HDMI3", NULL),
 | 
			
		||||
	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
 | 
			
		||||
			platform_clock_control, SND_SOC_DAPM_PRE_PMU |
 | 
			
		||||
			SND_SOC_DAPM_POST_PMD),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct snd_soc_dapm_route geminilake_map[] = {
 | 
			
		||||
	/* HP jack connectors - unknown if we have jack detection */
 | 
			
		||||
	{ "Headphone Jack", NULL, "Platform Clock" },
 | 
			
		||||
	{ "Headphone Jack", NULL, "HPOL" },
 | 
			
		||||
	{ "Headphone Jack", NULL, "HPOR" },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +80,6 @@ static const struct snd_soc_dapm_route geminilake_map[] = {
 | 
			
		|||
	{ "Spk", NULL, "Speaker" },
 | 
			
		||||
 | 
			
		||||
	/* other jacks */
 | 
			
		||||
	{ "Headset Mic", NULL, "Platform Clock" },
 | 
			
		||||
	{ "IN1P", NULL, "Headset Mic" },
 | 
			
		||||
 | 
			
		||||
	/* digital mics */
 | 
			
		||||
| 
						 | 
				
			
			@ -177,6 +139,13 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
 | 
			
		|||
	struct snd_soc_jack *jack;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret = snd_soc_dai_set_pll(codec_dai, 0, RT5682_PLL1_S_MCLK,
 | 
			
		||||
					GLK_PLAT_CLK_FREQ, RT5682_PLL_FREQ);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Configure sysclk for codec */
 | 
			
		||||
	ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
 | 
			
		||||
					RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = {
 | 
			
		|||
		.stream_name = "Loopback",
 | 
			
		||||
		.cpu_dai_name = "Loopback Pin",
 | 
			
		||||
		.platform_name = "haswell-pcm-audio",
 | 
			
		||||
		.dynamic = 0,
 | 
			
		||||
		.dynamic = 1,
 | 
			
		||||
		.codec_name = "snd-soc-dummy",
 | 
			
		||||
		.codec_dai_name = "snd-soc-dummy-dai",
 | 
			
		||||
		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -336,9 +336,6 @@ static int skl_suspend(struct device *dev)
 | 
			
		|||
		skl->skl_sst->fw_loaded = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
 | 
			
		||||
		snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -350,10 +347,6 @@ static int skl_resume(struct device *dev)
 | 
			
		|||
	struct hdac_ext_link *hlink = NULL;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	/* Turned OFF in HDMI codec driver after codec reconfiguration */
 | 
			
		||||
	if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
 | 
			
		||||
		snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * resume only when we are not in suspend active, otherwise need to
 | 
			
		||||
	 * restore the device
 | 
			
		||||
| 
						 | 
				
			
			@ -446,8 +439,10 @@ static int skl_free(struct hdac_bus *bus)
 | 
			
		|||
	snd_hdac_ext_bus_exit(bus);
 | 
			
		||||
 | 
			
		||||
	cancel_work_sync(&skl->probe_work);
 | 
			
		||||
	if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
 | 
			
		||||
	if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
 | 
			
		||||
		snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
 | 
			
		||||
		snd_hdac_i915_exit(bus);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -814,7 +809,7 @@ static void skl_probe_work(struct work_struct *work)
 | 
			
		|||
	err = skl_platform_register(bus->dev);
 | 
			
		||||
	if (err < 0) {
 | 
			
		||||
		dev_err(bus->dev, "platform register failed: %d\n", err);
 | 
			
		||||
		return;
 | 
			
		||||
		goto out_err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = skl_machine_device_register(skl);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -570,10 +570,10 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
 | 
			
		|||
	prtd->audio_client = q6asm_audio_client_alloc(dev,
 | 
			
		||||
					(q6asm_cb)compress_event_handler,
 | 
			
		||||
					prtd, stream_id, LEGACY_PCM_MODE);
 | 
			
		||||
	if (!prtd->audio_client) {
 | 
			
		||||
	if (IS_ERR(prtd->audio_client)) {
 | 
			
		||||
		dev_err(dev, "Could not allocate memory\n");
 | 
			
		||||
		kfree(prtd);
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
		ret = PTR_ERR(prtd->audio_client);
 | 
			
		||||
		goto free_prtd;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE *
 | 
			
		||||
| 
						 | 
				
			
			@ -582,7 +582,7 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
 | 
			
		|||
				  &prtd->dma_buffer);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		dev_err(dev, "Cannot allocate buffer(s)\n");
 | 
			
		||||
		return ret;
 | 
			
		||||
		goto free_client;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pdata->sid < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -595,6 +595,13 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
 | 
			
		|||
	runtime->private_data = prtd;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
free_client:
 | 
			
		||||
	q6asm_audio_client_free(prtd->audio_client);
 | 
			
		||||
free_prtd:
 | 
			
		||||
	kfree(prtd);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int q6asm_dai_compr_free(struct snd_compr_stream *stream)
 | 
			
		||||
| 
						 | 
				
			
			@ -874,7 +881,7 @@ static int of_q6asm_parse_dai_data(struct device *dev,
 | 
			
		|||
 | 
			
		||||
	for_each_child_of_node(dev->of_node, node) {
 | 
			
		||||
		ret = of_property_read_u32(node, "reg", &id);
 | 
			
		||||
		if (ret || id > MAX_SESSIONS || id < 0) {
 | 
			
		||||
		if (ret || id >= MAX_SESSIONS || id < 0) {
 | 
			
		||||
			dev_err(dev, "valid dai id not found:%d\n", ret);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -158,17 +158,24 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sdm845_jack_free(struct snd_jack *jack)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_component *component = jack->private_data;
 | 
			
		||||
 | 
			
		||||
	snd_soc_component_set_jack(component, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
 | 
			
		||||
{
 | 
			
		||||
	struct snd_soc_component *component;
 | 
			
		||||
	struct snd_soc_dai_link *dai_link = rtd->dai_link;
 | 
			
		||||
	struct snd_soc_card *card = rtd->card;
 | 
			
		||||
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 | 
			
		||||
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 | 
			
		||||
	struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
 | 
			
		||||
	int i, rval;
 | 
			
		||||
	struct snd_jack *jack;
 | 
			
		||||
	int rval;
 | 
			
		||||
 | 
			
		||||
	if (!pdata->jack_setup) {
 | 
			
		||||
		struct snd_jack *jack;
 | 
			
		||||
 | 
			
		||||
		rval = snd_soc_card_jack_new(card, "Headset Jack",
 | 
			
		||||
				SND_JACK_HEADSET |
 | 
			
		||||
				SND_JACK_HEADPHONE |
 | 
			
		||||
| 
						 | 
				
			
			@ -190,16 +197,22 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
 | 
			
		|||
		pdata->jack_setup = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0 ; i < dai_link->num_codecs; i++) {
 | 
			
		||||
		struct snd_soc_dai *dai = rtd->codec_dais[i];
 | 
			
		||||
	switch (cpu_dai->id) {
 | 
			
		||||
	case PRIMARY_MI2S_RX:
 | 
			
		||||
		jack  = pdata->jack.jack;
 | 
			
		||||
		component = codec_dai->component;
 | 
			
		||||
 | 
			
		||||
		component = dai->component;
 | 
			
		||||
		rval = snd_soc_component_set_jack(
 | 
			
		||||
				component, &pdata->jack, NULL);
 | 
			
		||||
		jack->private_data = component;
 | 
			
		||||
		jack->private_free = sdm845_jack_free;
 | 
			
		||||
		rval = snd_soc_component_set_jack(component,
 | 
			
		||||
						  &pdata->jack, NULL);
 | 
			
		||||
		if (rval != 0 && rval != -ENOTSUPP) {
 | 
			
		||||
			dev_warn(card->dev, "Failed to set jack: %d\n", rval);
 | 
			
		||||
			return rval;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ static int camelot_prepare(struct snd_pcm_substream *substream)
 | 
			
		|||
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 | 
			
		||||
	struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
 | 
			
		||||
 | 
			
		||||
	pr_debug("PCM data: addr 0x%08ulx len %d\n",
 | 
			
		||||
	pr_debug("PCM data: addr 0x%08lx len %d\n",
 | 
			
		||||
		 (u32)runtime->dma_addr, runtime->dma_bytes);
 | 
			
		||||
 
 | 
			
		||||
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -742,7 +742,7 @@ static struct snd_soc_component *soc_find_component(
 | 
			
		|||
		if (of_node) {
 | 
			
		||||
			if (component->dev->of_node == of_node)
 | 
			
		||||
				return component;
 | 
			
		||||
		} else if (strcmp(component->name, name) == 0) {
 | 
			
		||||
		} else if (name && strcmp(component->name, name) == 0) {
 | 
			
		||||
			return component;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,17 +1034,18 @@ static int snd_soc_init_platform(struct snd_soc_card *card,
 | 
			
		|||
	 * this function should be removed in the future
 | 
			
		||||
	 */
 | 
			
		||||
	/* convert Legacy platform link */
 | 
			
		||||
	if (!platform) {
 | 
			
		||||
	if (!platform || dai_link->legacy_platform) {
 | 
			
		||||
		platform = devm_kzalloc(card->dev,
 | 
			
		||||
				sizeof(struct snd_soc_dai_link_component),
 | 
			
		||||
				GFP_KERNEL);
 | 
			
		||||
		if (!platform)
 | 
			
		||||
			return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
		dai_link->platform	= platform;
 | 
			
		||||
		platform->name		= dai_link->platform_name;
 | 
			
		||||
		platform->of_node	= dai_link->platform_of_node;
 | 
			
		||||
		platform->dai_name	= NULL;
 | 
			
		||||
		dai_link->platform	  = platform;
 | 
			
		||||
		dai_link->legacy_platform = 1;
 | 
			
		||||
		platform->name		  = dai_link->platform_name;
 | 
			
		||||
		platform->of_node	  = dai_link->platform_of_node;
 | 
			
		||||
		platform->dai_name	  = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* if there's no platform we match on the empty platform */
 | 
			
		||||
| 
						 | 
				
			
			@ -1129,6 +1130,15 @@ static int soc_init_dai_link(struct snd_soc_card *card,
 | 
			
		|||
			link->name);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Defer card registartion if platform dai component is not added to
 | 
			
		||||
	 * component list.
 | 
			
		||||
	 */
 | 
			
		||||
	if ((link->platform->of_node || link->platform->name) &&
 | 
			
		||||
	    !soc_find_component(link->platform->of_node, link->platform->name))
 | 
			
		||||
		return -EPROBE_DEFER;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * CPU device may be specified by either name or OF node, but
 | 
			
		||||
	 * can be left unspecified, and will be matched based on DAI
 | 
			
		||||
| 
						 | 
				
			
			@ -1140,6 +1150,15 @@ static int soc_init_dai_link(struct snd_soc_card *card,
 | 
			
		|||
			link->name);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Defer card registartion if cpu dai component is not added to
 | 
			
		||||
	 * component list.
 | 
			
		||||
	 */
 | 
			
		||||
	if ((link->cpu_of_node || link->cpu_name) &&
 | 
			
		||||
	    !soc_find_component(link->cpu_of_node, link->cpu_name))
 | 
			
		||||
		return -EPROBE_DEFER;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * At least one of CPU DAI name or CPU device name/node must be
 | 
			
		||||
	 * specified
 | 
			
		||||
| 
						 | 
				
			
			@ -2739,15 +2758,18 @@ int snd_soc_register_card(struct snd_soc_card *card)
 | 
			
		|||
	if (!card->name || !card->dev)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&client_mutex);
 | 
			
		||||
	for_each_card_prelinks(card, i, link) {
 | 
			
		||||
 | 
			
		||||
		ret = soc_init_dai_link(card, link);
 | 
			
		||||
		if (ret) {
 | 
			
		||||
			dev_err(card->dev, "ASoC: failed to init link %s\n",
 | 
			
		||||
				link->name);
 | 
			
		||||
			mutex_unlock(&client_mutex);
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	mutex_unlock(&client_mutex);
 | 
			
		||||
 | 
			
		||||
	dev_set_drvdata(card->dev, card);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2019,19 +2019,19 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
 | 
			
		|||
		out = is_connected_output_ep(w, NULL, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = snprintf(buf, PAGE_SIZE, "%s: %s%s  in %d out %d",
 | 
			
		||||
	ret = scnprintf(buf, PAGE_SIZE, "%s: %s%s  in %d out %d",
 | 
			
		||||
		       w->name, w->power ? "On" : "Off",
 | 
			
		||||
		       w->force ? " (forced)" : "", in, out);
 | 
			
		||||
 | 
			
		||||
	if (w->reg >= 0)
 | 
			
		||||
		ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
		ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
				" - R%d(0x%x) mask 0x%x",
 | 
			
		||||
				w->reg, w->reg, w->mask << w->shift);
 | 
			
		||||
 | 
			
		||||
	ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
 | 
			
		||||
	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
 | 
			
		||||
 | 
			
		||||
	if (w->sname)
 | 
			
		||||
		ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
 | 
			
		||||
		ret += scnprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
 | 
			
		||||
				w->sname,
 | 
			
		||||
				w->active ? "active" : "inactive");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2044,7 +2044,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
 | 
			
		|||
			if (!p->connect)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			ret += snprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
			ret += scnprintf(buf + ret, PAGE_SIZE - ret,
 | 
			
		||||
					" %s  \"%s\" \"%s\"\n",
 | 
			
		||||
					(rdir == SND_SOC_DAPM_DIR_IN) ? "in" : "out",
 | 
			
		||||
					p->name ? p->name : "static",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ struct davinci_mcasp {
 | 
			
		|||
	/* Used for comstraint setting on the second stream */
 | 
			
		||||
	u32	channels;
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PM_SLEEP
 | 
			
		||||
#ifdef CONFIG_PM
 | 
			
		||||
	struct davinci_mcasp_context context;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1486,74 +1486,6 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PM_SLEEP
 | 
			
		||||
static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
 | 
			
		||||
{
 | 
			
		||||
	struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 | 
			
		||||
	struct davinci_mcasp_context *context = &mcasp->context;
 | 
			
		||||
	u32 reg;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	context->pm_state = pm_runtime_active(mcasp->dev);
 | 
			
		||||
	if (!context->pm_state)
 | 
			
		||||
		pm_runtime_get_sync(mcasp->dev);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
 | 
			
		||||
		context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
 | 
			
		||||
 | 
			
		||||
	if (mcasp->txnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
 | 
			
		||||
		context->afifo_regs[0] = mcasp_get_reg(mcasp, reg);
 | 
			
		||||
	}
 | 
			
		||||
	if (mcasp->rxnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
 | 
			
		||||
		context->afifo_regs[1] = mcasp_get_reg(mcasp, reg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < mcasp->num_serializer; i++)
 | 
			
		||||
		context->xrsr_regs[i] = mcasp_get_reg(mcasp,
 | 
			
		||||
						DAVINCI_MCASP_XRSRCTL_REG(i));
 | 
			
		||||
 | 
			
		||||
	pm_runtime_put_sync(mcasp->dev);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int davinci_mcasp_resume(struct snd_soc_dai *dai)
 | 
			
		||||
{
 | 
			
		||||
	struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
 | 
			
		||||
	struct davinci_mcasp_context *context = &mcasp->context;
 | 
			
		||||
	u32 reg;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	pm_runtime_get_sync(mcasp->dev);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
 | 
			
		||||
		mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
 | 
			
		||||
 | 
			
		||||
	if (mcasp->txnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
 | 
			
		||||
		mcasp_set_reg(mcasp, reg, context->afifo_regs[0]);
 | 
			
		||||
	}
 | 
			
		||||
	if (mcasp->rxnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
 | 
			
		||||
		mcasp_set_reg(mcasp, reg, context->afifo_regs[1]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < mcasp->num_serializer; i++)
 | 
			
		||||
		mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
 | 
			
		||||
			      context->xrsr_regs[i]);
 | 
			
		||||
 | 
			
		||||
	if (!context->pm_state)
 | 
			
		||||
		pm_runtime_put_sync(mcasp->dev);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#define davinci_mcasp_suspend NULL
 | 
			
		||||
#define davinci_mcasp_resume NULL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DAVINCI_MCASP_RATES	SNDRV_PCM_RATE_8000_192000
 | 
			
		||||
 | 
			
		||||
#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
 | 
			
		||||
| 
						 | 
				
			
			@ -1571,8 +1503,6 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
 | 
			
		|||
	{
 | 
			
		||||
		.name		= "davinci-mcasp.0",
 | 
			
		||||
		.probe		= davinci_mcasp_dai_probe,
 | 
			
		||||
		.suspend	= davinci_mcasp_suspend,
 | 
			
		||||
		.resume		= davinci_mcasp_resume,
 | 
			
		||||
		.playback	= {
 | 
			
		||||
			.channels_min	= 1,
 | 
			
		||||
			.channels_max	= 32 * 16,
 | 
			
		||||
| 
						 | 
				
			
			@ -1976,7 +1906,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	mcasp->num_serializer = pdata->num_serializer;
 | 
			
		||||
#ifdef CONFIG_PM_SLEEP
 | 
			
		||||
#ifdef CONFIG_PM
 | 
			
		||||
	mcasp->context.xrsr_regs = devm_kcalloc(&pdev->dev,
 | 
			
		||||
					mcasp->num_serializer, sizeof(u32),
 | 
			
		||||
					GFP_KERNEL);
 | 
			
		||||
| 
						 | 
				
			
			@ -2196,11 +2126,73 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_PM
 | 
			
		||||
static int davinci_mcasp_runtime_suspend(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
 | 
			
		||||
	struct davinci_mcasp_context *context = &mcasp->context;
 | 
			
		||||
	u32 reg;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
 | 
			
		||||
		context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
 | 
			
		||||
 | 
			
		||||
	if (mcasp->txnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
 | 
			
		||||
		context->afifo_regs[0] = mcasp_get_reg(mcasp, reg);
 | 
			
		||||
	}
 | 
			
		||||
	if (mcasp->rxnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
 | 
			
		||||
		context->afifo_regs[1] = mcasp_get_reg(mcasp, reg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < mcasp->num_serializer; i++)
 | 
			
		||||
		context->xrsr_regs[i] = mcasp_get_reg(mcasp,
 | 
			
		||||
						DAVINCI_MCASP_XRSRCTL_REG(i));
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int davinci_mcasp_runtime_resume(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
 | 
			
		||||
	struct davinci_mcasp_context *context = &mcasp->context;
 | 
			
		||||
	u32 reg;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(context_regs); i++)
 | 
			
		||||
		mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
 | 
			
		||||
 | 
			
		||||
	if (mcasp->txnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
 | 
			
		||||
		mcasp_set_reg(mcasp, reg, context->afifo_regs[0]);
 | 
			
		||||
	}
 | 
			
		||||
	if (mcasp->rxnumevt) {
 | 
			
		||||
		reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
 | 
			
		||||
		mcasp_set_reg(mcasp, reg, context->afifo_regs[1]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < mcasp->num_serializer; i++)
 | 
			
		||||
		mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
 | 
			
		||||
			      context->xrsr_regs[i]);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static const struct dev_pm_ops davinci_mcasp_pm_ops = {
 | 
			
		||||
	SET_RUNTIME_PM_OPS(davinci_mcasp_runtime_suspend,
 | 
			
		||||
			   davinci_mcasp_runtime_resume,
 | 
			
		||||
			   NULL)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct platform_driver davinci_mcasp_driver = {
 | 
			
		||||
	.probe		= davinci_mcasp_probe,
 | 
			
		||||
	.remove		= davinci_mcasp_remove,
 | 
			
		||||
	.driver		= {
 | 
			
		||||
		.name	= "davinci-mcasp",
 | 
			
		||||
		.pm     = &davinci_mcasp_pm_ops,
 | 
			
		||||
		.of_match_table = mcasp_dt_ids,
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
config SND_SOC_XILINX_I2S
 | 
			
		||||
	tristate "Audio support for the the Xilinx I2S"
 | 
			
		||||
	tristate "Audio support for the Xilinx I2S"
 | 
			
		||||
	help
 | 
			
		||||
	  Select this option to enable Xilinx I2S Audio. This enables
 | 
			
		||||
	  I2S playback and capture using xilinx soft IP. In transmitter
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,11 @@
 | 
			
		|||
// SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
/*
 | 
			
		||||
 * Xilinx ASoC I2S audio support
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2018 Xilinx, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Praveen Vuppala <praveenv@xilinx.com>
 | 
			
		||||
 * Author: Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com>
 | 
			
		||||
 */
 | 
			
		||||
//
 | 
			
		||||
// Xilinx ASoC I2S audio support
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2018 Xilinx, Inc.
 | 
			
		||||
//
 | 
			
		||||
// Author: Praveen Vuppala <praveenv@xilinx.com>
 | 
			
		||||
// Author: Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com>
 | 
			
		||||
 | 
			
		||||
#include <linux/io.h>
 | 
			
		||||
#include <linux/module.h>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue