Merge branch 'for-linus' into for-next

Pull 5.0 branch for further development of USB-audio quirks

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2019-01-29 11:07:24 +01:00
commit 286406c2e1
30 changed files with 256 additions and 300 deletions

View File

@ -985,6 +985,12 @@ struct snd_soc_dai_link {
/* Do not create a PCM for this DAI link (Backend link) */ /* Do not create a PCM for this DAI link (Backend link) */
unsigned int ignore:1; 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 list_head list; /* DAI link list of the soc card */
struct snd_soc_dobj dobj; /* For topology */ struct snd_soc_dobj dobj; /* For topology */
}; };

View File

@ -541,7 +541,8 @@ static int snd_compress_check_input(struct snd_compr_params *params)
{ {
/* first let's check the buffer parameter's */ /* first let's check the buffer parameter's */
if (params->buffer.fragment_size == 0 || 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; return -EINVAL;
/* now codec parameters */ /* now codec parameters */

View File

@ -2112,6 +2112,13 @@ int pcm_lib_apply_appl_ptr(struct snd_pcm_substream *substream,
return 0; return 0;
} }
/* allow waiting for a capture stream that hasn't been started */
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
#define wait_capture_start(substream) ((substream)->oss.oss)
#else
#define wait_capture_start(substream) false
#endif
/* the common loop for read/write data */ /* the common loop for read/write data */
snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
void *data, bool interleaved, void *data, bool interleaved,
@ -2182,7 +2189,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
err = snd_pcm_start(substream); err = snd_pcm_start(substream);
if (err < 0) if (err < 0)
goto _end_unlock; goto _end_unlock;
} else { } else if (!wait_capture_start(substream)) {
/* nothing to do */ /* nothing to do */
err = 0; err = 0;
goto _end_unlock; goto _end_unlock;

View File

@ -903,6 +903,9 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip)
struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_spos_instance * ins = chip->dsp_spos_instance;
int i; int i;
if (!ins)
return 0;
snd_info_free_entry(ins->proc_sym_info_entry); snd_info_free_entry(ins->proc_sym_info_entry);
ins->proc_sym_info_entry = NULL; ins->proc_sym_info_entry = NULL;

View File

@ -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, 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, 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, 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, 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, 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), SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE),

View File

@ -4102,6 +4102,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
case 0x10ec0295: case 0x10ec0295:
case 0x10ec0289: case 0x10ec0289:
case 0x10ec0299: case 0x10ec0299:
alc_process_coef_fw(codec, alc225_pre_hsmode);
alc_process_coef_fw(codec, coef0225); alc_process_coef_fw(codec, coef0225);
break; break;
case 0x10ec0867: case 0x10ec0867:
@ -5440,6 +5441,13 @@ static void alc_fixup_headset_jack(struct hda_codec *codec,
} }
} }
static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
if (action == HDA_FIXUP_ACT_PRE_PROBE)
snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
}
/* for hda_fixup_thinkpad_acpi() */ /* for hda_fixup_thinkpad_acpi() */
#include "thinkpad_helper.c" #include "thinkpad_helper.c"
@ -5549,6 +5557,7 @@ enum {
ALC293_FIXUP_LENOVO_SPK_NOISE, ALC293_FIXUP_LENOVO_SPK_NOISE,
ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
ALC255_FIXUP_DELL_SPK_NOISE, ALC255_FIXUP_DELL_SPK_NOISE,
ALC225_FIXUP_DISABLE_MIC_VREF,
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC295_FIXUP_DISABLE_DAC3, ALC295_FIXUP_DISABLE_DAC3,
ALC280_FIXUP_HP_HEADSET_MIC, ALC280_FIXUP_HP_HEADSET_MIC,
@ -6268,6 +6277,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
}, },
[ALC225_FIXUP_DISABLE_MIC_VREF] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_disable_mic_vref,
.chained = true,
.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
},
[ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = { [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
.type = HDA_FIXUP_VERBS, .type = HDA_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) { .v.verbs = (const struct hda_verb[]) {
@ -6277,7 +6292,7 @@ static const struct hda_fixup alc269_fixups[] = {
{} {}
}, },
.chained = true, .chained = true,
.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
}, },
[ALC280_FIXUP_HP_HEADSET_MIC] = { [ALC280_FIXUP_HP_HEADSET_MIC] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
@ -6911,7 +6926,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"}, {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"},
{.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"}, {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"},
{.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"}, {.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 = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"},
{.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"}, {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"},
{.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"}, {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"},

View File

@ -611,14 +611,16 @@ static int acp3x_audio_probe(struct platform_device *pdev)
} }
irqflags = *((unsigned int *)(pdev->dev.platform_data)); 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); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { if (!res) {
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
return -ENODEV; return -ENODEV;
} }
adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
if (!adata)
return -ENOMEM;
adata->acp3x_base = devm_ioremap(&pdev->dev, res->start, adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res)); resource_size(res));

View File

@ -1890,51 +1890,31 @@ static void hdmi_codec_remove(struct snd_soc_component *component)
pm_runtime_disable(&hdev->dev); pm_runtime_disable(&hdev->dev);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int hdmi_codec_prepare(struct device *dev) static int hdmi_codec_resume(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)
{ {
struct hdac_device *hdev = dev_to_hdac_dev(dev); struct hdac_device *hdev = dev_to_hdac_dev(dev);
struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
int ret;
/* Power up afg */ ret = pm_runtime_force_resume(dev);
snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, if (ret < 0)
AC_PWRST_D0); return ret;
hdac_hdmi_skl_enable_all_pins(hdev);
hdac_hdmi_skl_enable_dp12(hdev);
/* /*
* As the ELD notify callback request is not entertained while the * As the ELD notify callback request is not entertained while the
* device is in suspend state. Need to manually check detection of * device is in suspend state. Need to manually check detection of
* all pins here. pin capablity change is not support, so use the * all pins here. pin capablity change is not support, so use the
* already set pin caps. * 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); hdac_hdmi_present_sense_all_pins(hdev, hdmi, false);
return 0;
pm_runtime_put_sync(&hdev->dev);
} }
#else #else
#define hdmi_codec_prepare NULL #define hdmi_codec_resume NULL
#define hdmi_codec_complete NULL
#endif #endif
static const struct snd_soc_component_driver hdmi_hda_codec = { 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 #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) static int hdac_hdmi_runtime_suspend(struct device *dev)
{ {
struct hdac_device *hdev = dev_to_hdac_dev(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 = { static const struct dev_pm_ops hdac_hdmi_pm = {
SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL) SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
.prepare = hdmi_codec_prepare, SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, hdmi_codec_resume)
.complete = hdmi_codec_complete,
}; };
static const struct hda_device_id hdmi_list[] = { static const struct hda_device_id hdmi_list[] = {

View File

@ -1400,24 +1400,20 @@ static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
if (ret != 0) { if (ret != 0) {
dev_err(component->dev, dev_err(component->dev,
"Failed to set digital mute: %d\n", ret); "Failed to set digital mute: %d\n", ret);
mutex_unlock(&pcm512x->mutex); goto unlock;
return ret;
} }
regmap_read_poll_timeout(pcm512x->regmap, regmap_read_poll_timeout(pcm512x->regmap,
PCM512x_ANALOG_MUTE_DET, PCM512x_ANALOG_MUTE_DET,
mute_det, (mute_det & 0x3) == 0, mute_det, (mute_det & 0x3) == 0,
200, 10000); 200, 10000);
mutex_unlock(&pcm512x->mutex);
} else { } else {
pcm512x->mute &= ~0x1; pcm512x->mute &= ~0x1;
ret = pcm512x_update_mute(pcm512x); ret = pcm512x_update_mute(pcm512x);
if (ret != 0) { if (ret != 0) {
dev_err(component->dev, dev_err(component->dev,
"Failed to update digital mute: %d\n", ret); "Failed to update digital mute: %d\n", ret);
mutex_unlock(&pcm512x->mutex); goto unlock;
return ret;
} }
regmap_read_poll_timeout(pcm512x->regmap, regmap_read_poll_timeout(pcm512x->regmap,
@ -1428,9 +1424,10 @@ static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
200, 10000); 200, 10000);
} }
unlock:
mutex_unlock(&pcm512x->mutex); mutex_unlock(&pcm512x->mutex);
return 0; return ret;
} }
static const struct snd_soc_dai_ops pcm512x_dai_ops = { static const struct snd_soc_dai_ops pcm512x_dai_ops = {

View File

@ -1128,8 +1128,11 @@ static int rt274_i2c_probe(struct i2c_client *i2c,
return ret; return ret;
} }
regmap_read(rt274->regmap, ret = regmap_read(rt274->regmap,
RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val); RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
if (ret)
return ret;
if (val != RT274_VENDOR_ID) { if (val != RT274_VENDOR_ID) {
dev_err(&i2c->dev, dev_err(&i2c->dev,
"Device with ID register %#x is not rt274\n", val); "Device with ID register %#x is not rt274\n", val);

View File

@ -280,6 +280,8 @@ static int rt5514_spi_pcm_probe(struct snd_soc_component *component)
rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp), rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp),
GFP_KERNEL); GFP_KERNEL);
if (!rt5514_dsp)
return -ENOMEM;
rt5514_dsp->dev = &rt5514_spi->dev; rt5514_dsp->dev = &rt5514_spi->dev;
mutex_init(&rt5514_dsp->dma_lock); mutex_init(&rt5514_dsp->dma_lock);

View File

@ -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_PWR_DIG_1, 0x0000);
regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x2000); regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x2000);
regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x2005); regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x2005);
regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0xc0c4);
mutex_unlock(&rt5682->calibrate_mutex); mutex_unlock(&rt5682->calibrate_mutex);

View File

@ -849,18 +849,18 @@
#define RT5682_SCLK_SRC_PLL2 (0x2 << 13) #define RT5682_SCLK_SRC_PLL2 (0x2 << 13)
#define RT5682_SCLK_SRC_SDW (0x3 << 13) #define RT5682_SCLK_SRC_SDW (0x3 << 13)
#define RT5682_SCLK_SRC_RCCLK (0x4 << 13) #define RT5682_SCLK_SRC_RCCLK (0x4 << 13)
#define RT5682_PLL1_SRC_MASK (0x3 << 10) #define RT5682_PLL2_SRC_MASK (0x3 << 10)
#define RT5682_PLL1_SRC_SFT 10 #define RT5682_PLL2_SRC_SFT 10
#define RT5682_PLL1_SRC_MCLK (0x0 << 10) #define RT5682_PLL2_SRC_MCLK (0x0 << 10)
#define RT5682_PLL1_SRC_BCLK1 (0x1 << 10) #define RT5682_PLL2_SRC_BCLK1 (0x1 << 10)
#define RT5682_PLL1_SRC_SDW (0x2 << 10) #define RT5682_PLL2_SRC_SDW (0x2 << 10)
#define RT5682_PLL1_SRC_RC (0x3 << 10) #define RT5682_PLL2_SRC_RC (0x3 << 10)
#define RT5682_PLL2_SRC_MASK (0x3 << 8) #define RT5682_PLL1_SRC_MASK (0x3 << 8)
#define RT5682_PLL2_SRC_SFT 8 #define RT5682_PLL1_SRC_SFT 8
#define RT5682_PLL2_SRC_MCLK (0x0 << 8) #define RT5682_PLL1_SRC_MCLK (0x0 << 8)
#define RT5682_PLL2_SRC_BCLK1 (0x1 << 8) #define RT5682_PLL1_SRC_BCLK1 (0x1 << 8)
#define RT5682_PLL2_SRC_SDW (0x2 << 8) #define RT5682_PLL1_SRC_SDW (0x2 << 8)
#define RT5682_PLL2_SRC_RC (0x3 << 8) #define RT5682_PLL1_SRC_RC (0x3 << 8)

View File

@ -822,6 +822,10 @@ static int aic32x4_set_bias_level(struct snd_soc_component *component,
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: 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 */ /* Switch off BCLK_N Divider */
snd_soc_component_update_bits(component, AIC32X4_BCLKN, snd_soc_component_update_bits(component, AIC32X4_BCLKN,
AIC32X4_BCLKEN, 0); AIC32X4_BCLKEN, 0);

View File

@ -86,49 +86,49 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n", ret = scnprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
pdcr, ptcr); pdcr, ptcr);
if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR) 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, ", "TxFS output from %s, ",
audmux_port_string((ptcr >> 27) & 0x7)); audmux_port_string((ptcr >> 27) & 0x7));
else else
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"TxFS input, "); "TxFS input, ");
if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR) 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", "TxClk output from %s",
audmux_port_string((ptcr >> 22) & 0x7)); audmux_port_string((ptcr >> 22) & 0x7));
else else
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"TxClk input"); "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) { if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) {
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"Port is symmetric"); "Port is symmetric");
} else { } else {
if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR) 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, ", "RxFS output from %s, ",
audmux_port_string((ptcr >> 17) & 0x7)); audmux_port_string((ptcr >> 17) & 0x7));
else else
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"RxFS input, "); "RxFS input, ");
if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR) 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", "RxClk output from %s",
audmux_port_string((ptcr >> 12) & 0x7)); audmux_port_string((ptcr >> 12) & 0x7));
else else
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"RxClk input"); "RxClk input");
} }
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += scnprintf(buf + ret, PAGE_SIZE - ret,
"\nData received from %s\n", "\nData received from %s\n",
audmux_port_string((pdcr >> 13) & 0x7)); audmux_port_string((pdcr >> 13) & 0x7));

View File

@ -91,7 +91,7 @@ config SND_SST_ATOM_HIFI2_PLATFORM_PCI
config SND_SST_ATOM_HIFI2_PLATFORM_ACPI config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms" tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
default ACPI default ACPI
depends on X86 && ACPI depends on X86 && ACPI && PCI
select SND_SST_IPC_ACPI select SND_SST_IPC_ACPI
select SND_SST_ATOM_HIFI2_PLATFORM select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SOC_ACPI_INTEL_MATCH select SND_SOC_ACPI_INTEL_MATCH

View File

@ -399,7 +399,13 @@ static int sst_media_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) 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)); memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
return 0; return 0;
} }

View File

@ -192,7 +192,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
.stream_name = "Loopback", .stream_name = "Loopback",
.cpu_dai_name = "Loopback Pin", .cpu_dai_name = "Loopback Pin",
.platform_name = "haswell-pcm-audio", .platform_name = "haswell-pcm-audio",
.dynamic = 0, .dynamic = 1,
.codec_name = "snd-soc-dummy", .codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai", .codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},

View File

@ -55,39 +55,6 @@ enum {
GLK_DPCM_AUDIO_HDMI3_PB, 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[] = { static const struct snd_kcontrol_new geminilake_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Headset Mic"), 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("HDMI1", NULL),
SND_SOC_DAPM_SPK("HDMI2", NULL), SND_SOC_DAPM_SPK("HDMI2", NULL),
SND_SOC_DAPM_SPK("HDMI3", 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[] = { static const struct snd_soc_dapm_route geminilake_map[] = {
/* HP jack connectors - unknown if we have jack detection */ /* HP jack connectors - unknown if we have jack detection */
{ "Headphone Jack", NULL, "Platform Clock" },
{ "Headphone Jack", NULL, "HPOL" }, { "Headphone Jack", NULL, "HPOL" },
{ "Headphone Jack", NULL, "HPOR" }, { "Headphone Jack", NULL, "HPOR" },
@ -117,7 +80,6 @@ static const struct snd_soc_dapm_route geminilake_map[] = {
{ "Spk", NULL, "Speaker" }, { "Spk", NULL, "Speaker" },
/* other jacks */ /* other jacks */
{ "Headset Mic", NULL, "Platform Clock" },
{ "IN1P", NULL, "Headset Mic" }, { "IN1P", NULL, "Headset Mic" },
/* digital mics */ /* digital mics */
@ -177,6 +139,13 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
struct snd_soc_jack *jack; struct snd_soc_jack *jack;
int ret; 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 */ /* Configure sysclk for codec */
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN); RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);

View File

@ -146,7 +146,7 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = {
.stream_name = "Loopback", .stream_name = "Loopback",
.cpu_dai_name = "Loopback Pin", .cpu_dai_name = "Loopback Pin",
.platform_name = "haswell-pcm-audio", .platform_name = "haswell-pcm-audio",
.dynamic = 0, .dynamic = 1,
.codec_name = "snd-soc-dummy", .codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai", .codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},

View File

@ -336,9 +336,6 @@ static int skl_suspend(struct device *dev)
skl->skl_sst->fw_loaded = false; 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; return 0;
} }
@ -350,10 +347,6 @@ static int skl_resume(struct device *dev)
struct hdac_ext_link *hlink = NULL; struct hdac_ext_link *hlink = NULL;
int ret; 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 * resume only when we are not in suspend active, otherwise need to
* restore the device * restore the device
@ -446,8 +439,10 @@ static int skl_free(struct hdac_bus *bus)
snd_hdac_ext_bus_exit(bus); snd_hdac_ext_bus_exit(bus);
cancel_work_sync(&skl->probe_work); 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); snd_hdac_i915_exit(bus);
}
return 0; return 0;
} }
@ -814,7 +809,7 @@ static void skl_probe_work(struct work_struct *work)
err = skl_platform_register(bus->dev); err = skl_platform_register(bus->dev);
if (err < 0) { if (err < 0) {
dev_err(bus->dev, "platform register failed: %d\n", err); dev_err(bus->dev, "platform register failed: %d\n", err);
return; goto out_err;
} }
err = skl_machine_device_register(skl); err = skl_machine_device_register(skl);

View File

@ -570,10 +570,10 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
prtd->audio_client = q6asm_audio_client_alloc(dev, prtd->audio_client = q6asm_audio_client_alloc(dev,
(q6asm_cb)compress_event_handler, (q6asm_cb)compress_event_handler,
prtd, stream_id, LEGACY_PCM_MODE); prtd, stream_id, LEGACY_PCM_MODE);
if (!prtd->audio_client) { if (IS_ERR(prtd->audio_client)) {
dev_err(dev, "Could not allocate memory\n"); dev_err(dev, "Could not allocate memory\n");
kfree(prtd); ret = PTR_ERR(prtd->audio_client);
return -ENOMEM; goto free_prtd;
} }
size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE *
@ -582,7 +582,7 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
&prtd->dma_buffer); &prtd->dma_buffer);
if (ret) { if (ret) {
dev_err(dev, "Cannot allocate buffer(s)\n"); dev_err(dev, "Cannot allocate buffer(s)\n");
return ret; goto free_client;
} }
if (pdata->sid < 0) if (pdata->sid < 0)
@ -595,6 +595,13 @@ static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
runtime->private_data = prtd; runtime->private_data = prtd;
return 0; 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) 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) { for_each_child_of_node(dev->of_node, node) {
ret = of_property_read_u32(node, "reg", &id); 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); dev_err(dev, "valid dai id not found:%d\n", ret);
continue; continue;
} }

View File

@ -158,17 +158,24 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
return ret; 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) static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_component *component; 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_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); struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
int i, rval; struct snd_jack *jack;
int rval;
if (!pdata->jack_setup) { if (!pdata->jack_setup) {
struct snd_jack *jack;
rval = snd_soc_card_jack_new(card, "Headset Jack", rval = snd_soc_card_jack_new(card, "Headset Jack",
SND_JACK_HEADSET | SND_JACK_HEADSET |
SND_JACK_HEADPHONE | SND_JACK_HEADPHONE |
@ -190,16 +197,22 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
pdata->jack_setup = true; pdata->jack_setup = true;
} }
for (i = 0 ; i < dai_link->num_codecs; i++) { switch (cpu_dai->id) {
struct snd_soc_dai *dai = rtd->codec_dais[i]; case PRIMARY_MI2S_RX:
jack = pdata->jack.jack;
component = codec_dai->component;
component = dai->component; jack->private_data = component;
rval = snd_soc_component_set_jack( jack->private_free = sdm845_jack_free;
component, &pdata->jack, NULL); rval = snd_soc_component_set_jack(component,
&pdata->jack, NULL);
if (rval != 0 && rval != -ENOTSUPP) { if (rval != 0 && rval != -ENOTSUPP) {
dev_warn(card->dev, "Failed to set jack: %d\n", rval); dev_warn(card->dev, "Failed to set jack: %d\n", rval);
return rval; return rval;
} }
break;
default:
break;
} }
return 0; return 0;

View File

@ -202,7 +202,7 @@ static int camelot_prepare(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id]; 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); (u32)runtime->dma_addr, runtime->dma_bytes);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {

View File

@ -742,7 +742,7 @@ static struct snd_soc_component *soc_find_component(
if (of_node) { if (of_node) {
if (component->dev->of_node == of_node) if (component->dev->of_node == of_node)
return component; return component;
} else if (strcmp(component->name, name) == 0) { } else if (name && strcmp(component->name, name) == 0) {
return component; 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 * this function should be removed in the future
*/ */
/* convert Legacy platform link */ /* convert Legacy platform link */
if (!platform) { if (!platform || dai_link->legacy_platform) {
platform = devm_kzalloc(card->dev, platform = devm_kzalloc(card->dev,
sizeof(struct snd_soc_dai_link_component), sizeof(struct snd_soc_dai_link_component),
GFP_KERNEL); GFP_KERNEL);
if (!platform) if (!platform)
return -ENOMEM; return -ENOMEM;
dai_link->platform = platform; dai_link->platform = platform;
platform->name = dai_link->platform_name; dai_link->legacy_platform = 1;
platform->of_node = dai_link->platform_of_node; platform->name = dai_link->platform_name;
platform->dai_name = NULL; platform->of_node = dai_link->platform_of_node;
platform->dai_name = NULL;
} }
/* if there's no platform we match on the empty platform */ /* 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); link->name);
return -EINVAL; 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 * CPU device may be specified by either name or OF node, but
* can be left unspecified, and will be matched based on DAI * 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); link->name);
return -EINVAL; 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 * At least one of CPU DAI name or CPU device name/node must be
* specified * specified
@ -2739,15 +2758,18 @@ int snd_soc_register_card(struct snd_soc_card *card)
if (!card->name || !card->dev) if (!card->name || !card->dev)
return -EINVAL; return -EINVAL;
mutex_lock(&client_mutex);
for_each_card_prelinks(card, i, link) { for_each_card_prelinks(card, i, link) {
ret = soc_init_dai_link(card, link); ret = soc_init_dai_link(card, link);
if (ret) { if (ret) {
dev_err(card->dev, "ASoC: failed to init link %s\n", dev_err(card->dev, "ASoC: failed to init link %s\n",
link->name); link->name);
mutex_unlock(&client_mutex);
return ret; return ret;
} }
} }
mutex_unlock(&client_mutex);
dev_set_drvdata(card->dev, card); dev_set_drvdata(card->dev, card);

View File

@ -2019,19 +2019,19 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
out = is_connected_output_ep(w, NULL, NULL); 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->name, w->power ? "On" : "Off",
w->force ? " (forced)" : "", in, out); w->force ? " (forced)" : "", in, out);
if (w->reg >= 0) 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", " - R%d(0x%x) mask 0x%x",
w->reg, w->reg, w->mask << w->shift); 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) 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->sname,
w->active ? "active" : "inactive"); w->active ? "active" : "inactive");
@ -2044,7 +2044,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
if (!p->connect) if (!p->connect)
continue; continue;
ret += snprintf(buf + ret, PAGE_SIZE - ret, ret += scnprintf(buf + ret, PAGE_SIZE - ret,
" %s \"%s\" \"%s\"\n", " %s \"%s\" \"%s\"\n",
(rdir == SND_SOC_DAPM_DIR_IN) ? "in" : "out", (rdir == SND_SOC_DAPM_DIR_IN) ? "in" : "out",
p->name ? p->name : "static", p->name ? p->name : "static",

View File

@ -108,7 +108,7 @@ struct davinci_mcasp {
/* Used for comstraint setting on the second stream */ /* Used for comstraint setting on the second stream */
u32 channels; u32 channels;
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM
struct davinci_mcasp_context context; struct davinci_mcasp_context context;
#endif #endif
@ -1486,74 +1486,6 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
return 0; 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_RATES SNDRV_PCM_RATE_8000_192000
#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ #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", .name = "davinci-mcasp.0",
.probe = davinci_mcasp_dai_probe, .probe = davinci_mcasp_dai_probe,
.suspend = davinci_mcasp_suspend,
.resume = davinci_mcasp_resume,
.playback = { .playback = {
.channels_min = 1, .channels_min = 1,
.channels_max = 32 * 16, .channels_max = 32 * 16,
@ -1976,7 +1906,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
} }
mcasp->num_serializer = pdata->num_serializer; mcasp->num_serializer = pdata->num_serializer;
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM
mcasp->context.xrsr_regs = devm_kcalloc(&pdev->dev, mcasp->context.xrsr_regs = devm_kcalloc(&pdev->dev,
mcasp->num_serializer, sizeof(u32), mcasp->num_serializer, sizeof(u32),
GFP_KERNEL); GFP_KERNEL);
@ -2196,11 +2126,73 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
return 0; 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 = { static struct platform_driver davinci_mcasp_driver = {
.probe = davinci_mcasp_probe, .probe = davinci_mcasp_probe,
.remove = davinci_mcasp_remove, .remove = davinci_mcasp_remove,
.driver = { .driver = {
.name = "davinci-mcasp", .name = "davinci-mcasp",
.pm = &davinci_mcasp_pm_ops,
.of_match_table = mcasp_dt_ids, .of_match_table = mcasp_dt_ids,
}, },
}; };

View File

@ -1,5 +1,5 @@
config SND_SOC_XILINX_I2S config SND_SOC_XILINX_I2S
tristate "Audio support for the the Xilinx I2S" tristate "Audio support for the Xilinx I2S"
help help
Select this option to enable Xilinx I2S Audio. This enables Select this option to enable Xilinx I2S Audio. This enables
I2S playback and capture using xilinx soft IP. In transmitter I2S playback and capture using xilinx soft IP. In transmitter

View File

@ -1,12 +1,11 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* //
* Xilinx ASoC I2S audio support // Xilinx ASoC I2S audio support
* //
* Copyright (C) 2018 Xilinx, Inc. // Copyright (C) 2018 Xilinx, Inc.
* //
* Author: Praveen Vuppala <praveenv@xilinx.com> // Author: Praveen Vuppala <praveenv@xilinx.com>
* Author: Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com> // Author: Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com>
*/
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>

View File

@ -768,7 +768,7 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
* REG1: PLL binary search enable, soft mute enable. * REG1: PLL binary search enable, soft mute enable.
*/ */
CM6206_REG1_PLLBIN_EN | CM6206_REG1_PLLBIN_EN |
CM6206_REG1_SOFT_MUTE_EN | CM6206_REG1_SOFT_MUTE_EN,
/* /*
* REG2: enable output drivers, * REG2: enable output drivers,
* select front channels to the headphone output, * select front channels to the headphone output,
@ -1492,6 +1492,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
return SNDRV_PCM_FMTBIT_DSD_U32_BE; return SNDRV_PCM_FMTBIT_DSD_U32_BE;
break; break;
case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */
case USB_ID(0x152a, 0x85de): /* SMSL D1 DAC */ case USB_ID(0x152a, 0x85de): /* SMSL D1 DAC */
case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */
case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */