mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00: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
@ -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 New Issue
Block a user