mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-linus' into for-next
Taking the 5.5 devel branch back into the main devel branch. A USB-audio fix needs to be adjusted to adapt the changes that have been formerly applied for stop_sync. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
commit
a032ff0e80
|
@ -1150,6 +1150,7 @@ struct snd_soc_pcm_runtime {
|
|||
unsigned int num_codecs;
|
||||
|
||||
struct delayed_work delayed_work;
|
||||
void (*close_delayed_work_func)(struct snd_soc_pcm_runtime *rtd);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_dpcm_root;
|
||||
#endif
|
||||
|
|
|
@ -740,6 +740,10 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
|
||||
runtime->boundary *= 2;
|
||||
|
||||
/* clear the buffer for avoiding possible kernel info leaks */
|
||||
if (runtime->dma_area && !substream->ops->copy_user)
|
||||
memset(runtime->dma_area, 0, runtime->dma_bytes);
|
||||
|
||||
snd_pcm_timer_resolution_change(substream);
|
||||
snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
|
||||
|
||||
|
|
|
@ -120,10 +120,8 @@ void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
|
|||
snd_hdac_stream_updateb(azx_dev, SD_CTL,
|
||||
SD_CTL_DMA_START | SD_INT_MASK, 0);
|
||||
snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
|
||||
if (azx_dev->stripe) {
|
||||
if (azx_dev->stripe)
|
||||
snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
|
||||
azx_dev->stripe = 0;
|
||||
}
|
||||
azx_dev->running = false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_stream_clear);
|
||||
|
|
|
@ -835,7 +835,7 @@ static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
|
|||
return -EAGAIN; /* give a chance to retry */
|
||||
}
|
||||
|
||||
dev_WARN(chip->card->dev,
|
||||
dev_err(chip->card->dev,
|
||||
"azx_get_response timeout, switching to single_cmd mode: last cmd=0x%08x\n",
|
||||
bus->last_cmd[addr]);
|
||||
chip->single_cmd = 1;
|
||||
|
|
|
@ -1809,13 +1809,14 @@ struct scp_msg {
|
|||
|
||||
static void dspio_clear_response_queue(struct hda_codec *codec)
|
||||
{
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
|
||||
unsigned int dummy = 0;
|
||||
int status = -1;
|
||||
int status;
|
||||
|
||||
/* clear all from the response queue */
|
||||
do {
|
||||
status = dspio_read(codec, &dummy);
|
||||
} while (status == 0);
|
||||
} while (status == 0 && time_before(jiffies, timeout));
|
||||
}
|
||||
|
||||
static int dspio_get_response_data(struct hda_codec *codec)
|
||||
|
@ -7588,12 +7589,14 @@ static void ca0132_process_dsp_response(struct hda_codec *codec,
|
|||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
codec_dbg(codec, "ca0132_process_dsp_response\n");
|
||||
snd_hda_power_up_pm(codec);
|
||||
if (spec->wait_scp) {
|
||||
if (dspio_get_response_data(codec) >= 0)
|
||||
spec->wait_scp = 0;
|
||||
}
|
||||
|
||||
dspio_clear_response_queue(codec);
|
||||
snd_hda_power_down_pm(codec);
|
||||
}
|
||||
|
||||
static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
|
||||
|
@ -7604,11 +7607,10 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
|
|||
/* Delay enabling the HP amp, to let the mic-detection
|
||||
* state machine run.
|
||||
*/
|
||||
cancel_delayed_work(&spec->unsol_hp_work);
|
||||
schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
|
||||
tbl = snd_hda_jack_tbl_get(codec, cb->nid);
|
||||
if (tbl)
|
||||
tbl->block_report = 1;
|
||||
schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
|
||||
}
|
||||
|
||||
static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
|
||||
|
@ -8454,12 +8456,25 @@ static void ca0132_reboot_notify(struct hda_codec *codec)
|
|||
codec->patch_ops.free(codec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ca0132_suspend(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
cancel_delayed_work_sync(&spec->unsol_hp_work);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct hda_codec_ops ca0132_patch_ops = {
|
||||
.build_controls = ca0132_build_controls,
|
||||
.build_pcms = ca0132_build_pcms,
|
||||
.init = ca0132_init,
|
||||
.free = ca0132_free,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ca0132_suspend,
|
||||
#endif
|
||||
.reboot_notify = ca0132_reboot_notify,
|
||||
};
|
||||
|
||||
|
|
|
@ -2021,6 +2021,8 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
|
|||
per_cvt->assigned = 0;
|
||||
hinfo->nid = 0;
|
||||
|
||||
azx_stream(get_azx_dev(substream))->stripe = 0;
|
||||
|
||||
mutex_lock(&spec->pcm_lock);
|
||||
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
|
||||
clear_bit(pcm_idx, &spec->pcm_in_use);
|
||||
|
|
|
@ -7643,11 +7643,6 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
|||
{0x1a, 0x90a70130},
|
||||
{0x1b, 0x90170110},
|
||||
{0x21, 0x03211020}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
|
||||
{0x12, 0xb7a60130},
|
||||
{0x13, 0xb8a61140},
|
||||
{0x16, 0x90170110},
|
||||
{0x21, 0x04211020}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
|
||||
{0x12, 0x90a60130},
|
||||
{0x14, 0x90170110},
|
||||
|
@ -7841,6 +7836,9 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
|
|||
SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
{0x19, 0x40000000},
|
||||
{0x1a, 0x40000000}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
|
||||
{0x19, 0x40000000},
|
||||
{0x1a, 0x40000000}),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -96,14 +96,19 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int da7219_clk_enable(struct snd_pcm_substream *substream,
|
||||
int wclk_rate, int bclk_rate)
|
||||
static int da7219_clk_enable(struct snd_pcm_substream *substream)
|
||||
{
|
||||
int ret = 0;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
|
||||
clk_set_rate(da7219_dai_wclk, wclk_rate);
|
||||
clk_set_rate(da7219_dai_bclk, bclk_rate);
|
||||
/*
|
||||
* Set wclk to 48000 because the rate constraint of this driver is
|
||||
* 48000. ADAU7002 spec: "The ADAU7002 requires a BCLK rate that is
|
||||
* minimum of 64x the LRCLK sample rate." DA7219 is the only clk
|
||||
* source so for all codecs we have to limit bclk to 64X lrclk.
|
||||
*/
|
||||
clk_set_rate(da7219_dai_wclk, 48000);
|
||||
clk_set_rate(da7219_dai_bclk, 48000 * 64);
|
||||
ret = clk_prepare_enable(da7219_dai_bclk);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "can't enable master clock %d\n", ret);
|
||||
|
@ -156,7 +161,7 @@ static int cz_da7219_play_startup(struct snd_pcm_substream *substream)
|
|||
&constraints_rates);
|
||||
|
||||
machine->play_i2s_instance = I2S_SP_INSTANCE;
|
||||
return 0;
|
||||
return da7219_clk_enable(substream);
|
||||
}
|
||||
|
||||
static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
|
||||
|
@ -178,7 +183,7 @@ static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
|
|||
|
||||
machine->cap_i2s_instance = I2S_SP_INSTANCE;
|
||||
machine->capture_channel = CAP_CHANNEL1;
|
||||
return 0;
|
||||
return da7219_clk_enable(substream);
|
||||
}
|
||||
|
||||
static int cz_max_startup(struct snd_pcm_substream *substream)
|
||||
|
@ -199,7 +204,7 @@ static int cz_max_startup(struct snd_pcm_substream *substream)
|
|||
&constraints_rates);
|
||||
|
||||
machine->play_i2s_instance = I2S_BT_INSTANCE;
|
||||
return 0;
|
||||
return da7219_clk_enable(substream);
|
||||
}
|
||||
|
||||
static int cz_dmic0_startup(struct snd_pcm_substream *substream)
|
||||
|
@ -220,7 +225,7 @@ static int cz_dmic0_startup(struct snd_pcm_substream *substream)
|
|||
&constraints_rates);
|
||||
|
||||
machine->cap_i2s_instance = I2S_BT_INSTANCE;
|
||||
return 0;
|
||||
return da7219_clk_enable(substream);
|
||||
}
|
||||
|
||||
static int cz_dmic1_startup(struct snd_pcm_substream *substream)
|
||||
|
@ -242,25 +247,7 @@ static int cz_dmic1_startup(struct snd_pcm_substream *substream)
|
|||
|
||||
machine->cap_i2s_instance = I2S_SP_INSTANCE;
|
||||
machine->capture_channel = CAP_CHANNEL0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cz_da7219_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
int wclk, bclk;
|
||||
|
||||
wclk = params_rate(params);
|
||||
bclk = wclk * params_channels(params) *
|
||||
snd_pcm_format_width(params_format(params));
|
||||
/* ADAU7002 spec: "The ADAU7002 requires a BCLK rate
|
||||
* that is minimum of 64x the LRCLK sample rate."
|
||||
* DA7219 is the only clk source so for all codecs
|
||||
* we have to limit bclk to 64X lrclk.
|
||||
*/
|
||||
if (bclk < (wclk * 64))
|
||||
bclk = wclk * 64;
|
||||
return da7219_clk_enable(substream, wclk, bclk);
|
||||
return da7219_clk_enable(substream);
|
||||
}
|
||||
|
||||
static void cz_da7219_shutdown(struct snd_pcm_substream *substream)
|
||||
|
@ -271,31 +258,26 @@ static void cz_da7219_shutdown(struct snd_pcm_substream *substream)
|
|||
static const struct snd_soc_ops cz_da7219_play_ops = {
|
||||
.startup = cz_da7219_play_startup,
|
||||
.shutdown = cz_da7219_shutdown,
|
||||
.hw_params = cz_da7219_params,
|
||||
};
|
||||
|
||||
static const struct snd_soc_ops cz_da7219_cap_ops = {
|
||||
.startup = cz_da7219_cap_startup,
|
||||
.shutdown = cz_da7219_shutdown,
|
||||
.hw_params = cz_da7219_params,
|
||||
};
|
||||
|
||||
static const struct snd_soc_ops cz_max_play_ops = {
|
||||
.startup = cz_max_startup,
|
||||
.shutdown = cz_da7219_shutdown,
|
||||
.hw_params = cz_da7219_params,
|
||||
};
|
||||
|
||||
static const struct snd_soc_ops cz_dmic0_cap_ops = {
|
||||
.startup = cz_dmic0_startup,
|
||||
.shutdown = cz_da7219_shutdown,
|
||||
.hw_params = cz_da7219_params,
|
||||
};
|
||||
|
||||
static const struct snd_soc_ops cz_dmic1_cap_ops = {
|
||||
.startup = cz_dmic1_startup,
|
||||
.shutdown = cz_da7219_shutdown,
|
||||
.hw_params = cz_da7219_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEF(designware1,
|
||||
|
|
|
@ -2103,26 +2103,40 @@ static void max98090_pll_det_disable_work(struct work_struct *work)
|
|||
M98090_IULK_MASK, 0);
|
||||
}
|
||||
|
||||
static void max98090_pll_work(struct work_struct *work)
|
||||
static void max98090_pll_work(struct max98090_priv *max98090)
|
||||
{
|
||||
struct max98090_priv *max98090 =
|
||||
container_of(work, struct max98090_priv, pll_work);
|
||||
struct snd_soc_component *component = max98090->component;
|
||||
unsigned int pll;
|
||||
int i;
|
||||
|
||||
if (!snd_soc_component_is_active(component))
|
||||
return;
|
||||
|
||||
dev_info_ratelimited(component->dev, "PLL unlocked\n");
|
||||
|
||||
/*
|
||||
* As the datasheet suggested, the maximum PLL lock time should be
|
||||
* 7 msec. The workaround resets the codec softly by toggling SHDN
|
||||
* off and on if PLL failed to lock for 10 msec. Notably, there is
|
||||
* no suggested hold time for SHDN off.
|
||||
*/
|
||||
|
||||
/* Toggle shutdown OFF then ON */
|
||||
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
|
||||
M98090_SHDNN_MASK, 0);
|
||||
msleep(10);
|
||||
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
|
||||
M98090_SHDNN_MASK, M98090_SHDNN_MASK);
|
||||
|
||||
/* Give PLL time to lock */
|
||||
msleep(10);
|
||||
for (i = 0; i < 10; ++i) {
|
||||
/* Give PLL time to lock */
|
||||
usleep_range(1000, 1200);
|
||||
|
||||
/* Check lock status */
|
||||
pll = snd_soc_component_read32(
|
||||
component, M98090_REG_DEVICE_STATUS);
|
||||
if (!(pll & M98090_ULK_MASK))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void max98090_jack_work(struct work_struct *work)
|
||||
|
@ -2259,7 +2273,7 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
|
|||
|
||||
if (active & M98090_ULK_MASK) {
|
||||
dev_dbg(component->dev, "M98090_ULK_MASK\n");
|
||||
schedule_work(&max98090->pll_work);
|
||||
max98090_pll_work(max98090);
|
||||
}
|
||||
|
||||
if (active & M98090_JDET_MASK) {
|
||||
|
@ -2422,7 +2436,6 @@ static int max98090_probe(struct snd_soc_component *component)
|
|||
max98090_pll_det_enable_work);
|
||||
INIT_WORK(&max98090->pll_det_disable_work,
|
||||
max98090_pll_det_disable_work);
|
||||
INIT_WORK(&max98090->pll_work, max98090_pll_work);
|
||||
|
||||
/* Enable jack detection */
|
||||
snd_soc_component_write(component, M98090_REG_JACK_DETECT,
|
||||
|
@ -2475,7 +2488,6 @@ static void max98090_remove(struct snd_soc_component *component)
|
|||
cancel_delayed_work_sync(&max98090->jack_work);
|
||||
cancel_delayed_work_sync(&max98090->pll_det_enable_work);
|
||||
cancel_work_sync(&max98090->pll_det_disable_work);
|
||||
cancel_work_sync(&max98090->pll_work);
|
||||
max98090->component = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1530,7 +1530,6 @@ struct max98090_priv {
|
|||
struct delayed_work jack_work;
|
||||
struct delayed_work pll_det_enable_work;
|
||||
struct work_struct pll_det_disable_work;
|
||||
struct work_struct pll_work;
|
||||
struct snd_soc_jack *jack;
|
||||
unsigned int dai_fmt;
|
||||
int tdm_slots;
|
||||
|
|
|
@ -9,9 +9,25 @@
|
|||
#ifndef __RT5677_SPI_H__
|
||||
#define __RT5677_SPI_H__
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_RT5677_SPI)
|
||||
int rt5677_spi_read(u32 addr, void *rxbuf, size_t len);
|
||||
int rt5677_spi_write(u32 addr, const void *txbuf, size_t len);
|
||||
int rt5677_spi_write_firmware(u32 addr, const struct firmware *fw);
|
||||
void rt5677_spi_hotword_detected(void);
|
||||
#else
|
||||
static inline int rt5677_spi_read(u32 addr, void *rxbuf, size_t len)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int rt5677_spi_write(u32 addr, const void *txbuf, size_t len)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int rt5677_spi_write_firmware(u32 addr, const struct firmware *fw)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline void rt5677_spi_hotword_detected(void){}
|
||||
#endif
|
||||
|
||||
#endif /* __RT5677_SPI_H__ */
|
||||
|
|
|
@ -73,6 +73,7 @@ struct rt5682_priv {
|
|||
static const struct reg_sequence patch_list[] = {
|
||||
{RT5682_HP_IMP_SENS_CTRL_19, 0x1000},
|
||||
{RT5682_DAC_ADC_DIG_VOL1, 0xa020},
|
||||
{RT5682_I2C_CTRL, 0x000f},
|
||||
};
|
||||
|
||||
static const struct reg_default rt5682_reg[] = {
|
||||
|
@ -2474,6 +2475,7 @@ static void rt5682_calibrate(struct rt5682_priv *rt5682)
|
|||
mutex_lock(&rt5682->calibrate_mutex);
|
||||
|
||||
rt5682_reset(rt5682->regmap);
|
||||
regmap_write(rt5682->regmap, RT5682_I2C_CTRL, 0x000f);
|
||||
regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0xa2af);
|
||||
usleep_range(15000, 20000);
|
||||
regmap_write(rt5682->regmap, RT5682_PWR_ANLG_1, 0xf2af);
|
||||
|
|
|
@ -1806,6 +1806,12 @@ static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
|
|||
|
||||
switch (clk_id) {
|
||||
case WM8904_CLK_AUTO:
|
||||
/* We don't have any rate constraints, so just ignore the
|
||||
* request to disable constraining.
|
||||
*/
|
||||
if (!freq)
|
||||
return 0;
|
||||
|
||||
mclk_freq = clk_get_rate(priv->mclk);
|
||||
/* enable FLL if a different sysclk is desired */
|
||||
if (mclk_freq != freq) {
|
||||
|
|
|
@ -2788,7 +2788,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
|
|||
|
||||
if (target % Fref == 0) {
|
||||
fll_div->theta = 0;
|
||||
fll_div->lambda = 0;
|
||||
fll_div->lambda = 1;
|
||||
} else {
|
||||
gcd_fll = gcd(target, fratio * Fref);
|
||||
|
||||
|
@ -2858,7 +2858,7 @@ static int wm8962_set_fll(struct snd_soc_component *component, int fll_id, int s
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fll_div.theta || fll_div.lambda)
|
||||
if (fll_div.theta)
|
||||
fll1 |= WM8962_FLL_FRAC;
|
||||
|
||||
/* Stop the FLL while we reconfigure */
|
||||
|
|
|
@ -371,6 +371,7 @@ static int simple_for_each_link(struct asoc_simple_priv *priv,
|
|||
do {
|
||||
struct asoc_simple_data adata;
|
||||
struct device_node *codec;
|
||||
struct device_node *plat;
|
||||
struct device_node *np;
|
||||
int num = of_get_child_count(node);
|
||||
|
||||
|
@ -381,6 +382,9 @@ static int simple_for_each_link(struct asoc_simple_priv *priv,
|
|||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
/* get platform */
|
||||
plat = of_get_child_by_name(node, is_top ?
|
||||
PREFIX "plat" : "plat");
|
||||
|
||||
/* get convert-xxx property */
|
||||
memset(&adata, 0, sizeof(adata));
|
||||
|
@ -389,6 +393,8 @@ static int simple_for_each_link(struct asoc_simple_priv *priv,
|
|||
|
||||
/* loop for all CPU/Codec node */
|
||||
for_each_child_of_node(node, np) {
|
||||
if (plat == np)
|
||||
continue;
|
||||
/*
|
||||
* It is DPCM
|
||||
* if it has many CPUs,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pm_qos.h>
|
||||
|
|
|
@ -707,13 +707,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
|||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{
|
||||
/* Teclast X89 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
|
||||
},
|
||||
.driver_data = (void *)(BYT_RT5640_IN3_MAP |
|
||||
BYT_RT5640_MCLK_EN |
|
||||
BYT_RT5640_SSP0_AIF1),
|
||||
BYT_RT5640_JD_SRC_JD1_IN4P |
|
||||
BYT_RT5640_OVCD_TH_2000UA |
|
||||
BYT_RT5640_OVCD_SF_1P0 |
|
||||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{ /* Toshiba Satellite Click Mini L9W-B */
|
||||
.matches = {
|
||||
|
|
|
@ -9,45 +9,52 @@
|
|||
#include <sound/soc-acpi.h>
|
||||
#include <sound/soc-acpi-intel-match.h>
|
||||
|
||||
static struct snd_soc_acpi_codecs cml_codecs = {
|
||||
static struct snd_soc_acpi_codecs rt1011_spk_codecs = {
|
||||
.num_codecs = 1,
|
||||
.codecs = {"10EC5682"}
|
||||
.codecs = {"10EC1011"}
|
||||
};
|
||||
|
||||
static struct snd_soc_acpi_codecs cml_spk_codecs = {
|
||||
static struct snd_soc_acpi_codecs max98357a_spk_codecs = {
|
||||
.num_codecs = 1,
|
||||
.codecs = {"MX98357A"}
|
||||
};
|
||||
|
||||
/*
|
||||
* The order of the three entries with .id = "10EC5682" matters
|
||||
* here, because DSDT tables expose an ACPI HID for the MAX98357A
|
||||
* speaker amplifier which is not populated on the board.
|
||||
*/
|
||||
struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = {
|
||||
{
|
||||
.id = "DLGS7219",
|
||||
.drv_name = "cml_da7219_max98357a",
|
||||
.quirk_data = &cml_spk_codecs,
|
||||
.sof_fw_filename = "sof-cml.ri",
|
||||
.sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
|
||||
},
|
||||
{
|
||||
.id = "MX98357A",
|
||||
.drv_name = "sof_rt5682",
|
||||
.quirk_data = &cml_codecs,
|
||||
.sof_fw_filename = "sof-cml.ri",
|
||||
.sof_tplg_filename = "sof-cml-rt5682-max98357a.tplg",
|
||||
},
|
||||
{
|
||||
.id = "10EC1011",
|
||||
.id = "10EC5682",
|
||||
.drv_name = "cml_rt1011_rt5682",
|
||||
.quirk_data = &cml_codecs,
|
||||
.machine_quirk = snd_soc_acpi_codec_list,
|
||||
.quirk_data = &rt1011_spk_codecs,
|
||||
.sof_fw_filename = "sof-cml.ri",
|
||||
.sof_tplg_filename = "sof-cml-rt1011-rt5682.tplg",
|
||||
},
|
||||
{
|
||||
.id = "10EC5682",
|
||||
.drv_name = "sof_rt5682",
|
||||
.machine_quirk = snd_soc_acpi_codec_list,
|
||||
.quirk_data = &max98357a_spk_codecs,
|
||||
.sof_fw_filename = "sof-cml.ri",
|
||||
.sof_tplg_filename = "sof-cml-rt5682-max98357a.tplg",
|
||||
},
|
||||
{
|
||||
.id = "10EC5682",
|
||||
.drv_name = "sof_rt5682",
|
||||
.sof_fw_filename = "sof-cml.ri",
|
||||
.sof_tplg_filename = "sof-cml-rt5682.tplg",
|
||||
},
|
||||
|
||||
{
|
||||
.id = "DLGS7219",
|
||||
.drv_name = "cml_da7219_max98357a",
|
||||
.machine_quirk = snd_soc_acpi_codec_list,
|
||||
.quirk_data = &max98357a_spk_codecs,
|
||||
.sof_fw_filename = "sof-cml.ri",
|
||||
.sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
|
||||
},
|
||||
{},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines);
|
||||
|
|
|
@ -214,10 +214,8 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
|
|||
* This is to ensure there are no pops or clicks in between any music tracks
|
||||
* due to DAPM power cycling.
|
||||
*/
|
||||
static void close_delayed_work(struct work_struct *work)
|
||||
static void close_delayed_work(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd =
|
||||
container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
|
||||
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
|
||||
|
@ -929,7 +927,7 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
|
|||
}
|
||||
|
||||
/* DAPM dai link stream work */
|
||||
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
|
||||
rtd->close_delayed_work_func = close_delayed_work;
|
||||
|
||||
rtd->compr = compr;
|
||||
compr->private_data = rtd;
|
||||
|
|
|
@ -419,7 +419,8 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
|
|||
|
||||
list_del(&rtd->list);
|
||||
|
||||
flush_delayed_work(&rtd->delayed_work);
|
||||
if (delayed_work_pending(&rtd->delayed_work))
|
||||
flush_delayed_work(&rtd->delayed_work);
|
||||
snd_soc_pcm_component_free(rtd);
|
||||
|
||||
/*
|
||||
|
@ -435,6 +436,15 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
|
|||
device_unregister(rtd->dev);
|
||||
}
|
||||
|
||||
static void close_delayed_work(struct work_struct *work) {
|
||||
struct snd_soc_pcm_runtime *rtd =
|
||||
container_of(work, struct snd_soc_pcm_runtime,
|
||||
delayed_work.work);
|
||||
|
||||
if (rtd->close_delayed_work_func)
|
||||
rtd->close_delayed_work_func(rtd);
|
||||
}
|
||||
|
||||
static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
|
||||
struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
|
||||
{
|
||||
|
@ -470,6 +480,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
|
|||
|
||||
rtd->dev = dev;
|
||||
dev_set_drvdata(dev, rtd);
|
||||
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
|
||||
|
||||
/*
|
||||
* for rtd->codec_dais
|
||||
|
|
|
@ -637,10 +637,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
|
|||
* This is to ensure there are no pops or clicks in between any music tracks
|
||||
* due to DAPM power cycling.
|
||||
*/
|
||||
static void close_delayed_work(struct work_struct *work)
|
||||
static void close_delayed_work(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd =
|
||||
container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dais[0];
|
||||
|
||||
mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
|
||||
|
@ -660,7 +658,7 @@ static void close_delayed_work(struct work_struct *work)
|
|||
mutex_unlock(&rtd->card->pcm_mutex);
|
||||
}
|
||||
|
||||
static void codec2codec_close_delayed_work(struct work_struct *work)
|
||||
static void codec2codec_close_delayed_work(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
/*
|
||||
* Currently nothing to do for c2c links
|
||||
|
@ -2974,10 +2972,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
|
|||
|
||||
/* DAPM dai link stream work */
|
||||
if (rtd->dai_link->params)
|
||||
INIT_DELAYED_WORK(&rtd->delayed_work,
|
||||
codec2codec_close_delayed_work);
|
||||
rtd->close_delayed_work_func = codec2codec_close_delayed_work;
|
||||
else
|
||||
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
|
||||
rtd->close_delayed_work_func = close_delayed_work;
|
||||
|
||||
pcm->nonatomic = rtd->dai_link->nonatomic;
|
||||
rtd->pcm = pcm;
|
||||
|
|
|
@ -1933,11 +1933,13 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
|
|||
ret = soc_tplg_dai_link_load(tplg, link, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(tplg->comp->dev, "ASoC: FE link loading failed\n");
|
||||
kfree(link->name);
|
||||
kfree(link->stream_name);
|
||||
kfree(link->cpus->dai_name);
|
||||
kfree(link);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = snd_soc_add_dai_link(tplg->comp->card, link);
|
||||
if (ret < 0) {
|
||||
dev_err(tplg->comp->dev, "ASoC: adding FE link failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
link->dobj.index = tplg->index;
|
||||
|
@ -1945,8 +1947,13 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
|
|||
link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
|
||||
list_add(&link->dobj.list, &tplg->comp->dobj_list);
|
||||
|
||||
snd_soc_add_dai_link(tplg->comp->card, link);
|
||||
return 0;
|
||||
err:
|
||||
kfree(link->name);
|
||||
kfree(link->stream_name);
|
||||
kfree(link->cpus->dai_name);
|
||||
kfree(link);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* create a FE DAI and DAI link from the PCM object */
|
||||
|
@ -2039,6 +2046,7 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
|
|||
int size;
|
||||
int i;
|
||||
bool abi_match;
|
||||
int ret;
|
||||
|
||||
count = le32_to_cpu(hdr->count);
|
||||
|
||||
|
@ -2080,7 +2088,12 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
|
|||
}
|
||||
|
||||
/* create the FE DAIs and DAI links */
|
||||
soc_tplg_pcm_create(tplg, _pcm);
|
||||
ret = soc_tplg_pcm_create(tplg, _pcm);
|
||||
if (ret < 0) {
|
||||
if (!abi_match)
|
||||
kfree(_pcm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* offset by version-specific struct size and
|
||||
* real priv data size
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
#define DRAM_OFFSET 0x100000
|
||||
#define DRAM_SIZE (160 * 1024)
|
||||
#define SHIM_OFFSET 0x140000
|
||||
#define SHIM_SIZE 0x100
|
||||
#define SHIM_SIZE_BYT 0x100
|
||||
#define SHIM_SIZE_CHT 0x118
|
||||
#define MBOX_OFFSET 0x144000
|
||||
#define MBOX_SIZE 0x1000
|
||||
#define EXCEPT_OFFSET 0x800
|
||||
|
@ -75,7 +76,7 @@ static const struct snd_sof_debugfs_map byt_debugfs[] = {
|
|||
SOF_DEBUGFS_ACCESS_D0_ONLY},
|
||||
{"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
|
||||
SOF_DEBUGFS_ACCESS_D0_ONLY},
|
||||
{"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE,
|
||||
{"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
|
||||
SOF_DEBUGFS_ACCESS_ALWAYS},
|
||||
};
|
||||
|
||||
|
@ -102,7 +103,7 @@ static const struct snd_sof_debugfs_map cht_debugfs[] = {
|
|||
SOF_DEBUGFS_ACCESS_D0_ONLY},
|
||||
{"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
|
||||
SOF_DEBUGFS_ACCESS_D0_ONLY},
|
||||
{"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE,
|
||||
{"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
|
||||
SOF_DEBUGFS_ACCESS_ALWAYS},
|
||||
};
|
||||
|
||||
|
@ -145,33 +146,33 @@ static void byt_dump(struct snd_sof_dev *sdev, u32 flags)
|
|||
struct sof_ipc_dsp_oops_xtensa xoops;
|
||||
struct sof_ipc_panic_info panic_info;
|
||||
u32 stack[BYT_STACK_DUMP_SIZE];
|
||||
u32 status, panic, imrd, imrx;
|
||||
u64 status, panic, imrd, imrx;
|
||||
|
||||
/* now try generic SOF status messages */
|
||||
status = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCD);
|
||||
panic = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCX);
|
||||
status = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD);
|
||||
panic = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX);
|
||||
byt_get_registers(sdev, &xoops, &panic_info, stack,
|
||||
BYT_STACK_DUMP_SIZE);
|
||||
snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
|
||||
BYT_STACK_DUMP_SIZE);
|
||||
|
||||
/* provide some context for firmware debug */
|
||||
imrx = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IMRX);
|
||||
imrd = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IMRD);
|
||||
imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX);
|
||||
imrd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRD);
|
||||
dev_err(sdev->dev,
|
||||
"error: ipc host -> DSP: pending %s complete %s raw 0x%8.8x\n",
|
||||
"error: ipc host -> DSP: pending %s complete %s raw 0x%llx\n",
|
||||
(panic & SHIM_IPCX_BUSY) ? "yes" : "no",
|
||||
(panic & SHIM_IPCX_DONE) ? "yes" : "no", panic);
|
||||
dev_err(sdev->dev,
|
||||
"error: mask host: pending %s complete %s raw 0x%8.8x\n",
|
||||
"error: mask host: pending %s complete %s raw 0x%llx\n",
|
||||
(imrx & SHIM_IMRX_BUSY) ? "yes" : "no",
|
||||
(imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx);
|
||||
dev_err(sdev->dev,
|
||||
"error: ipc DSP -> host: pending %s complete %s raw 0x%8.8x\n",
|
||||
"error: ipc DSP -> host: pending %s complete %s raw 0x%llx\n",
|
||||
(status & SHIM_IPCD_BUSY) ? "yes" : "no",
|
||||
(status & SHIM_IPCD_DONE) ? "yes" : "no", status);
|
||||
dev_err(sdev->dev,
|
||||
"error: mask DSP: pending %s complete %s raw 0x%8.8x\n",
|
||||
"error: mask DSP: pending %s complete %s raw 0x%llx\n",
|
||||
(imrd & SHIM_IMRD_BUSY) ? "yes" : "no",
|
||||
(imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd);
|
||||
|
||||
|
|
|
@ -50,8 +50,7 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset)
|
|||
|
||||
while (ext_hdr->hdr.cmd == SOF_IPC_FW_READY) {
|
||||
/* read in ext structure */
|
||||
offset += sizeof(*ext_hdr);
|
||||
snd_sof_dsp_block_read(sdev, bar, offset,
|
||||
snd_sof_dsp_block_read(sdev, bar, offset + sizeof(*ext_hdr),
|
||||
(void *)((u8 *)ext_data + sizeof(*ext_hdr)),
|
||||
ext_hdr->hdr.size - sizeof(*ext_hdr));
|
||||
|
||||
|
@ -61,11 +60,15 @@ int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset)
|
|||
/* process structure data */
|
||||
switch (ext_hdr->type) {
|
||||
case SOF_IPC_EXT_DMA_BUFFER:
|
||||
ret = 0;
|
||||
break;
|
||||
case SOF_IPC_EXT_WINDOW:
|
||||
ret = get_ext_windows(sdev, ext_hdr);
|
||||
break;
|
||||
default:
|
||||
dev_warn(sdev->dev, "warning: unknown ext header type %d size 0x%x\n",
|
||||
ext_hdr->type, ext_hdr->hdr.size);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -3132,7 +3132,9 @@ static int sof_link_unload(struct snd_soc_component *scomp,
|
|||
case SOF_DAI_INTEL_SSP:
|
||||
case SOF_DAI_INTEL_DMIC:
|
||||
case SOF_DAI_INTEL_ALH:
|
||||
/* no resource needs to be released for SSP, DMIC and ALH */
|
||||
case SOF_DAI_IMX_SAI:
|
||||
case SOF_DAI_IMX_ESAI:
|
||||
/* no resource needs to be released for all cases above */
|
||||
break;
|
||||
case SOF_DAI_INTEL_HDA:
|
||||
ret = sof_link_hda_unload(sdev, link);
|
||||
|
|
|
@ -145,6 +145,7 @@ struct snd_usb_substream {
|
|||
struct snd_usb_endpoint *sync_endpoint;
|
||||
unsigned long flags;
|
||||
bool need_setup_ep; /* (re)configure EP at prepare? */
|
||||
bool need_setup_fmt; /* (re)configure fmt after resume? */
|
||||
unsigned int speed; /* USB_SPEED_XXX */
|
||||
|
||||
u64 formats; /* format bitmasks (all or'ed) */
|
||||
|
|
|
@ -523,11 +523,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
|
|||
if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
|
||||
return -EINVAL;
|
||||
|
||||
if (fmt == subs->cur_audiofmt)
|
||||
if (fmt == subs->cur_audiofmt && !subs->need_setup_fmt)
|
||||
return 0;
|
||||
|
||||
/* close the old interface */
|
||||
if (subs->interface >= 0 && subs->interface != fmt->iface) {
|
||||
if (subs->interface >= 0 && (subs->interface != fmt->iface || subs->need_setup_fmt)) {
|
||||
if (!subs->stream->chip->keep_iface) {
|
||||
err = usb_set_interface(subs->dev, subs->interface, 0);
|
||||
if (err < 0) {
|
||||
|
@ -541,6 +541,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
|
|||
subs->altset_idx = 0;
|
||||
}
|
||||
|
||||
if (subs->need_setup_fmt)
|
||||
subs->need_setup_fmt = false;
|
||||
|
||||
/* set interface */
|
||||
if (iface->cur_altsetting != alts) {
|
||||
err = snd_usb_select_mode_quirk(subs, fmt);
|
||||
|
@ -1734,6 +1737,13 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
|
|||
subs->data_endpoint->retire_data_urb = retire_playback_urb;
|
||||
subs->running = 0;
|
||||
return 0;
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
if (subs->stream->chip->setup_fmt_after_resume_quirk) {
|
||||
stop_endpoints(subs);
|
||||
subs->need_setup_fmt = true;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
@ -1766,6 +1776,13 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
|
|||
subs->data_endpoint->retire_data_urb = retire_capture_urb;
|
||||
subs->running = 1;
|
||||
return 0;
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
if (subs->stream->chip->setup_fmt_after_resume_quirk) {
|
||||
stop_endpoints(subs);
|
||||
subs->need_setup_fmt = true;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
|
|
@ -3466,7 +3466,8 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
|
|||
.vendor_name = "Dell",
|
||||
.product_name = "WD19 Dock",
|
||||
.profile_name = "Dell-WD15-Dock",
|
||||
.ifnum = QUIRK_NO_INTERFACE
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_SETUP_FMT_AFTER_RESUME
|
||||
}
|
||||
},
|
||||
/* MOTU Microbook II */
|
||||
|
|
|
@ -508,6 +508,16 @@ static int create_standard_mixer_quirk(struct snd_usb_audio *chip,
|
|||
return snd_usb_create_mixer(chip, quirk->ifnum, 0);
|
||||
}
|
||||
|
||||
|
||||
static int setup_fmt_after_resume_quirk(struct snd_usb_audio *chip,
|
||||
struct usb_interface *iface,
|
||||
struct usb_driver *driver,
|
||||
const struct snd_usb_audio_quirk *quirk)
|
||||
{
|
||||
chip->setup_fmt_after_resume_quirk = 1;
|
||||
return 1; /* Continue with creating streams and mixer */
|
||||
}
|
||||
|
||||
/*
|
||||
* audio-interface quirks
|
||||
*
|
||||
|
@ -546,6 +556,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
|
|||
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
|
||||
[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
|
||||
[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
|
||||
[QUIRK_SETUP_FMT_AFTER_RESUME] = setup_fmt_after_resume_quirk,
|
||||
};
|
||||
|
||||
if (quirk->type < QUIRK_TYPE_COUNT) {
|
||||
|
|
|
@ -33,7 +33,7 @@ struct snd_usb_audio {
|
|||
wait_queue_head_t shutdown_wait;
|
||||
unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
|
||||
unsigned int tx_length_quirk:1; /* Put length specifier in transfers */
|
||||
|
||||
unsigned int setup_fmt_after_resume_quirk:1; /* setup the format to interface after resume */
|
||||
int num_interfaces;
|
||||
int num_suspended_intf;
|
||||
int sample_rate_read_error;
|
||||
|
@ -98,6 +98,7 @@ enum quirk_type {
|
|||
QUIRK_AUDIO_EDIROL_UAXX,
|
||||
QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
QUIRK_AUDIO_STANDARD_MIXER,
|
||||
QUIRK_SETUP_FMT_AFTER_RESUME,
|
||||
|
||||
QUIRK_TYPE_COUNT
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue