Commit f850a2b1 authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-fix-v6.1-rc2' of...

Merge tag 'asoc-fix-v6.1-rc2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v6.1

Quite a few fixes here, a lot driver specific, plus some new quirks.
There was a bit of a mess with the runtime PM handling due to some
confusion in the API there which resulted in a number of commits and
reverts but that should all be stable now.
parents 50895a55 e9441675
...@@ -177,6 +177,7 @@ void asoc_simple_convert_fixup(struct asoc_simple_data *data, ...@@ -177,6 +177,7 @@ void asoc_simple_convert_fixup(struct asoc_simple_data *data,
struct snd_pcm_hw_params *params); struct snd_pcm_hw_params *params);
void asoc_simple_parse_convert(struct device_node *np, char *prefix, void asoc_simple_parse_convert(struct device_node *np, char *prefix,
struct asoc_simple_data *data); struct asoc_simple_data *data);
bool asoc_simple_is_convert_required(const struct asoc_simple_data *data);
int asoc_simple_parse_routing(struct snd_soc_card *card, int asoc_simple_parse_routing(struct snd_soc_card *card,
char *prefix); char *prefix);
......
...@@ -45,6 +45,27 @@ static struct snd_soc_card acp6x_card = { ...@@ -45,6 +45,27 @@ static struct snd_soc_card acp6x_card = {
}; };
static const struct dmi_system_id yc_acp_quirk_table[] = { static const struct dmi_system_id yc_acp_quirk_table[] = {
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D1"),
}
},
{ {
.driver_data = &acp6x_card, .driver_data = &acp6x_card,
.matches = { .matches = {
......
...@@ -1629,6 +1629,7 @@ config SND_SOC_TFA989X ...@@ -1629,6 +1629,7 @@ config SND_SOC_TFA989X
config SND_SOC_TLV320ADC3XXX config SND_SOC_TLV320ADC3XXX
tristate "Texas Instruments TLV320ADC3001/3101 audio ADC" tristate "Texas Instruments TLV320ADC3001/3101 audio ADC"
depends on I2C depends on I2C
depends on GPIOLIB
help help
Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101 Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
ADCs. ADCs.
......
...@@ -177,7 +177,7 @@ ...@@ -177,7 +177,7 @@
#define CX2072X_PLBK_DRC_PARM_LEN 9 #define CX2072X_PLBK_DRC_PARM_LEN 9
#define CX2072X_CLASSD_AMP_LEN 6 #define CX2072X_CLASSD_AMP_LEN 6
/* DAI interfae type */ /* DAI interface type */
#define CX2072X_DAI_HIFI 1 #define CX2072X_DAI_HIFI 1
#define CX2072X_DAI_DSP 2 #define CX2072X_DAI_DSP 2
#define CX2072X_DAI_DSP_PWM 3 /* 4 ch, including mic and AEC */ #define CX2072X_DAI_DSP_PWM 3 /* 4 ch, including mic and AEC */
......
...@@ -136,14 +136,17 @@ enum { ...@@ -136,14 +136,17 @@ enum {
#define REG_CGR3_GO1L_OFFSET 0 #define REG_CGR3_GO1L_OFFSET 0
#define REG_CGR3_GO1L_MASK (0x1f << REG_CGR3_GO1L_OFFSET) #define REG_CGR3_GO1L_MASK (0x1f << REG_CGR3_GO1L_OFFSET)
#define REG_CGR10_GIL_OFFSET 0
#define REG_CGR10_GIR_OFFSET 4
struct jz_icdc { struct jz_icdc {
struct regmap *regmap; struct regmap *regmap;
void __iomem *base; void __iomem *base;
struct clk *clk; struct clk *clk;
}; };
static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv, 0, 150, 0);
static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
static const struct snd_kcontrol_new jz4725b_codec_controls[] = { static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
SOC_DOUBLE_TLV("Master Playback Volume", SOC_DOUBLE_TLV("Master Playback Volume",
...@@ -151,11 +154,11 @@ static const struct snd_kcontrol_new jz4725b_codec_controls[] = { ...@@ -151,11 +154,11 @@ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
REG_CGR1_GODL_OFFSET, REG_CGR1_GODL_OFFSET,
REG_CGR1_GODR_OFFSET, REG_CGR1_GODR_OFFSET,
0xf, 1, jz4725b_dac_tlv), 0xf, 1, jz4725b_dac_tlv),
SOC_DOUBLE_R_TLV("Master Capture Volume", SOC_DOUBLE_TLV("Master Capture Volume",
JZ4725B_CODEC_REG_CGR3, JZ4725B_CODEC_REG_CGR10,
JZ4725B_CODEC_REG_CGR2, REG_CGR10_GIL_OFFSET,
REG_CGR2_GO1R_OFFSET, REG_CGR10_GIR_OFFSET,
0x1f, 1, jz4725b_line_tlv), 0xf, 0, jz4725b_adc_tlv),
SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1, SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1,
REG_CR1_DAC_MUTE_OFFSET, 1, 1), REG_CR1_DAC_MUTE_OFFSET, 1, 1),
...@@ -180,7 +183,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum, ...@@ -180,7 +183,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
jz4725b_codec_adc_src_texts, jz4725b_codec_adc_src_texts,
jz4725b_codec_adc_src_values); jz4725b_codec_adc_src_values);
static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl = static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
SOC_DAPM_ENUM("Route", jz4725b_codec_adc_src_enum); SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = { static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1, SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1,
...@@ -225,7 +228,7 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = { ...@@ -225,7 +228,7 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_DAPM_ADC("ADC", "Capture",
JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1), JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
SND_SOC_DAPM_MUX("ADC Source", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
&jz4725b_codec_adc_src_ctrl), &jz4725b_codec_adc_src_ctrl),
/* Mixer */ /* Mixer */
...@@ -236,7 +239,8 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = { ...@@ -236,7 +239,8 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1, SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
REG_CR1_DACSEL_OFFSET, 0, NULL, 0), REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Line In", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1, SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
REG_CR1_HP_DIS_OFFSET, 1, NULL, 0), REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
...@@ -283,11 +287,11 @@ static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = { ...@@ -283,11 +287,11 @@ static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
{"Mixer", NULL, "DAC to Mixer"}, {"Mixer", NULL, "DAC to Mixer"},
{"Mixer to ADC", NULL, "Mixer"}, {"Mixer to ADC", NULL, "Mixer"},
{"ADC Source", "Mixer", "Mixer to ADC"}, {"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
{"ADC Source", "Line In", "Line In"}, {"ADC Source Capture Route", "Line In", "Line In"},
{"ADC Source", "Mic 1", "Mic 1"}, {"ADC Source Capture Route", "Mic 1", "Mic 1"},
{"ADC Source", "Mic 2", "Mic 2"}, {"ADC Source Capture Route", "Mic 2", "Mic 2"},
{"ADC", NULL, "ADC Source"}, {"ADC", NULL, "ADC Source Capture Route"},
{"Out Stage", NULL, "Mixer"}, {"Out Stage", NULL, "Mixer"},
{"HP Out", NULL, "Out Stage"}, {"HP Out", NULL, "Out Stage"},
......
...@@ -503,14 +503,14 @@ static int mt6660_i2c_probe(struct i2c_client *client) ...@@ -503,14 +503,14 @@ static int mt6660_i2c_probe(struct i2c_client *client)
dev_err(chip->dev, "read chip revision fail\n"); dev_err(chip->dev, "read chip revision fail\n");
goto probe_fail; goto probe_fail;
} }
pm_runtime_set_active(chip->dev);
pm_runtime_enable(chip->dev);
ret = devm_snd_soc_register_component(chip->dev, ret = devm_snd_soc_register_component(chip->dev,
&mt6660_component_driver, &mt6660_component_driver,
&mt6660_codec_dai, 1); &mt6660_codec_dai, 1);
if (!ret) { if (ret)
pm_runtime_set_active(chip->dev); pm_runtime_disable(chip->dev);
pm_runtime_enable(chip->dev);
}
return ret; return ret;
......
...@@ -391,18 +391,18 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -391,18 +391,18 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots, int slot_width) unsigned int rx_mask, int slots, int slot_width)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
unsigned int val = 0, rx_slotnum; unsigned int cn = 0, cl = 0, rx_slotnum;
int ret = 0, first_bit; int ret = 0, first_bit;
switch (slots) { switch (slots) {
case 4: case 4:
val |= RT1019_I2S_TX_4CH; cn = RT1019_I2S_TX_4CH;
break; break;
case 6: case 6:
val |= RT1019_I2S_TX_6CH; cn = RT1019_I2S_TX_6CH;
break; break;
case 8: case 8:
val |= RT1019_I2S_TX_8CH; cn = RT1019_I2S_TX_8CH;
break; break;
case 2: case 2:
break; break;
...@@ -412,16 +412,16 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -412,16 +412,16 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
switch (slot_width) { switch (slot_width) {
case 20: case 20:
val |= RT1019_I2S_DL_20; cl = RT1019_TDM_CL_20;
break; break;
case 24: case 24:
val |= RT1019_I2S_DL_24; cl = RT1019_TDM_CL_24;
break; break;
case 32: case 32:
val |= RT1019_I2S_DL_32; cl = RT1019_TDM_CL_32;
break; break;
case 8: case 8:
val |= RT1019_I2S_DL_8; cl = RT1019_TDM_CL_8;
break; break;
case 16: case 16:
break; break;
...@@ -470,8 +470,10 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -470,8 +470,10 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
goto _set_tdm_err_; goto _set_tdm_err_;
} }
snd_soc_component_update_bits(component, RT1019_TDM_1,
RT1019_TDM_CL_MASK, cl);
snd_soc_component_update_bits(component, RT1019_TDM_2, snd_soc_component_update_bits(component, RT1019_TDM_2,
RT1019_I2S_CH_TX_MASK | RT1019_I2S_DF_MASK, val); RT1019_I2S_CH_TX_MASK, cn);
_set_tdm_err_: _set_tdm_err_:
return ret; return ret;
......
...@@ -95,6 +95,12 @@ ...@@ -95,6 +95,12 @@
#define RT1019_TDM_BCLK_MASK (0x1 << 6) #define RT1019_TDM_BCLK_MASK (0x1 << 6)
#define RT1019_TDM_BCLK_NORM (0x0 << 6) #define RT1019_TDM_BCLK_NORM (0x0 << 6)
#define RT1019_TDM_BCLK_INV (0x1 << 6) #define RT1019_TDM_BCLK_INV (0x1 << 6)
#define RT1019_TDM_CL_MASK (0x7)
#define RT1019_TDM_CL_8 (0x4)
#define RT1019_TDM_CL_32 (0x3)
#define RT1019_TDM_CL_24 (0x2)
#define RT1019_TDM_CL_20 (0x1)
#define RT1019_TDM_CL_16 (0x0)
/* 0x0401 TDM Control-2 */ /* 0x0401 TDM Control-2 */
#define RT1019_I2S_CH_TX_MASK (0x3 << 6) #define RT1019_I2S_CH_TX_MASK (0x3 << 6)
......
...@@ -50,6 +50,7 @@ static bool rt1308_volatile_register(struct device *dev, unsigned int reg) ...@@ -50,6 +50,7 @@ static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
case 0x3008: case 0x3008:
case 0x300a: case 0x300a:
case 0xc000: case 0xc000:
case 0xc710:
case 0xc860 ... 0xc863: case 0xc860 ... 0xc863:
case 0xc870 ... 0xc873: case 0xc870 ... 0xc873:
return true; return true;
...@@ -200,6 +201,7 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave) ...@@ -200,6 +201,7 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
{ {
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev); struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
int ret = 0; int ret = 0;
unsigned int tmp;
if (rt1308->hw_init) if (rt1308->hw_init)
return 0; return 0;
...@@ -231,6 +233,10 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave) ...@@ -231,6 +233,10 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
/* sw reset */ /* sw reset */
regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0); regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0);
regmap_read(rt1308->regmap, 0xc710, &tmp);
rt1308->hw_ver = tmp;
dev_dbg(dev, "%s, hw_ver=0x%x\n", __func__, rt1308->hw_ver);
/* initial settings */ /* initial settings */
regmap_write(rt1308->regmap, 0xc103, 0xc0); regmap_write(rt1308->regmap, 0xc103, 0xc0);
regmap_write(rt1308->regmap, 0xc030, 0x17); regmap_write(rt1308->regmap, 0xc030, 0x17);
...@@ -246,8 +252,14 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave) ...@@ -246,8 +252,14 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
regmap_write(rt1308->regmap, 0xc062, 0x05); regmap_write(rt1308->regmap, 0xc062, 0x05);
regmap_write(rt1308->regmap, 0xc171, 0x07); regmap_write(rt1308->regmap, 0xc171, 0x07);
regmap_write(rt1308->regmap, 0xc173, 0x0d); regmap_write(rt1308->regmap, 0xc173, 0x0d);
if (rt1308->hw_ver == RT1308_VER_C) {
regmap_write(rt1308->regmap, 0xc311, 0x7f); regmap_write(rt1308->regmap, 0xc311, 0x7f);
regmap_write(rt1308->regmap, 0xc900, 0x90); regmap_write(rt1308->regmap, 0xc300, 0x09);
} else {
regmap_write(rt1308->regmap, 0xc311, 0x4f);
regmap_write(rt1308->regmap, 0xc300, 0x0b);
}
regmap_write(rt1308->regmap, 0xc900, 0x5a);
regmap_write(rt1308->regmap, 0xc1a0, 0x84); regmap_write(rt1308->regmap, 0xc1a0, 0x84);
regmap_write(rt1308->regmap, 0xc1a1, 0x01); regmap_write(rt1308->regmap, 0xc1a1, 0x01);
regmap_write(rt1308->regmap, 0xc360, 0x78); regmap_write(rt1308->regmap, 0xc360, 0x78);
...@@ -257,7 +269,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave) ...@@ -257,7 +269,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
regmap_write(rt1308->regmap, 0xc070, 0x00); regmap_write(rt1308->regmap, 0xc070, 0x00);
regmap_write(rt1308->regmap, 0xc100, 0xd7); regmap_write(rt1308->regmap, 0xc100, 0xd7);
regmap_write(rt1308->regmap, 0xc101, 0xd7); regmap_write(rt1308->regmap, 0xc101, 0xd7);
regmap_write(rt1308->regmap, 0xc300, 0x09);
if (rt1308->first_hw_init) { if (rt1308->first_hw_init) {
regcache_cache_bypass(rt1308->regmap, false); regcache_cache_bypass(rt1308->regmap, false);
......
...@@ -139,10 +139,12 @@ static const struct reg_default rt1308_reg_defaults[] = { ...@@ -139,10 +139,12 @@ static const struct reg_default rt1308_reg_defaults[] = {
{ 0x3005, 0x23 }, { 0x3005, 0x23 },
{ 0x3008, 0x02 }, { 0x3008, 0x02 },
{ 0x300a, 0x00 }, { 0x300a, 0x00 },
{ 0xc000 | (RT1308_DATA_PATH << 4), 0x00 },
{ 0xc003 | (RT1308_DAC_SET << 4), 0x00 }, { 0xc003 | (RT1308_DAC_SET << 4), 0x00 },
{ 0xc000 | (RT1308_POWER << 4), 0x00 }, { 0xc000 | (RT1308_POWER << 4), 0x00 },
{ 0xc001 | (RT1308_POWER << 4), 0x00 }, { 0xc001 | (RT1308_POWER << 4), 0x00 },
{ 0xc002 | (RT1308_POWER << 4), 0x00 }, { 0xc002 | (RT1308_POWER << 4), 0x00 },
{ 0xc000 | (RT1308_POWER_STATUS << 4), 0x00 },
}; };
#define RT1308_SDW_OFFSET 0xc000 #define RT1308_SDW_OFFSET 0xc000
...@@ -163,6 +165,7 @@ struct rt1308_sdw_priv { ...@@ -163,6 +165,7 @@ struct rt1308_sdw_priv {
bool first_hw_init; bool first_hw_init;
int rx_mask; int rx_mask;
int slots; int slots;
int hw_ver;
}; };
struct sdw_stream_data { struct sdw_stream_data {
......
...@@ -286,4 +286,9 @@ enum { ...@@ -286,4 +286,9 @@ enum {
RT1308_AIFS RT1308_AIFS
}; };
enum rt1308_hw_ver {
RT1308_VER_C = 2,
RT1308_VER_D
};
#endif /* end of _RT1308_H_ */ #endif /* end of _RT1308_H_ */
...@@ -1981,7 +1981,7 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -1981,7 +1981,7 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots, int slot_width) unsigned int rx_mask, int slots, int slot_width)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
unsigned int cl, val = 0; unsigned int cl, val = 0, tx_slotnum;
if (tx_mask || rx_mask) if (tx_mask || rx_mask)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
...@@ -1990,6 +1990,16 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -1990,6 +1990,16 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0); RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0);
/* Tx slot configuration */
tx_slotnum = hweight_long(tx_mask);
if (tx_slotnum) {
if (tx_slotnum > slots) {
dev_err(component->dev, "Invalid or oversized Tx slots.\n");
return -EINVAL;
}
val |= (tx_slotnum - 1) << RT5682S_TDM_ADC_DL_SFT;
}
switch (slots) { switch (slots) {
case 4: case 4:
val |= RT5682S_TDM_TX_CH_4; val |= RT5682S_TDM_TX_CH_4;
...@@ -2010,7 +2020,8 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -2010,7 +2020,8 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
} }
snd_soc_component_update_bits(component, RT5682S_TDM_CTRL, snd_soc_component_update_bits(component, RT5682S_TDM_CTRL,
RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK, val); RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK |
RT5682S_TDM_ADC_DL_MASK, val);
switch (slot_width) { switch (slot_width) {
case 8: case 8:
......
...@@ -899,6 +899,7 @@ ...@@ -899,6 +899,7 @@
#define RT5682S_TDM_RX_CH_8 (0x3 << 8) #define RT5682S_TDM_RX_CH_8 (0x3 << 8)
#define RT5682S_TDM_ADC_LCA_MASK (0x7 << 4) #define RT5682S_TDM_ADC_LCA_MASK (0x7 << 4)
#define RT5682S_TDM_ADC_LCA_SFT 4 #define RT5682S_TDM_ADC_LCA_SFT 4
#define RT5682S_TDM_ADC_DL_MASK (0x3 << 0)
#define RT5682S_TDM_ADC_DL_SFT 0 #define RT5682S_TDM_ADC_DL_SFT 0
/* TDM control 2 (0x007a) */ /* TDM control 2 (0x007a) */
......
...@@ -1449,7 +1449,7 @@ static struct i2c_driver adc3xxx_i2c_driver = { ...@@ -1449,7 +1449,7 @@ static struct i2c_driver adc3xxx_i2c_driver = {
.of_match_table = tlv320adc3xxx_of_match, .of_match_table = tlv320adc3xxx_of_match,
}, },
.probe_new = adc3xxx_i2c_probe, .probe_new = adc3xxx_i2c_probe,
.remove = adc3xxx_i2c_remove, .remove = __exit_p(adc3xxx_i2c_remove),
.id_table = adc3xxx_i2c_id, .id_table = adc3xxx_i2c_id,
}; };
......
...@@ -2099,6 +2099,9 @@ static int wm5102_probe(struct platform_device *pdev) ...@@ -2099,6 +2099,9 @@ static int wm5102_probe(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, wm5102_digital_vu[i], regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
WM5102_DIG_VU, WM5102_DIG_VU); WM5102_DIG_VU, WM5102_DIG_VU);
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
"ADSP2 Compressed IRQ", wm5102_adsp2_irq, "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
wm5102); wm5102);
...@@ -2131,9 +2134,6 @@ static int wm5102_probe(struct platform_device *pdev) ...@@ -2131,9 +2134,6 @@ static int wm5102_probe(struct platform_device *pdev)
goto err_spk_irqs; goto err_spk_irqs;
} }
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
return ret; return ret;
err_spk_irqs: err_spk_irqs:
...@@ -2142,6 +2142,7 @@ static int wm5102_probe(struct platform_device *pdev) ...@@ -2142,6 +2142,7 @@ static int wm5102_probe(struct platform_device *pdev)
arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0); arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102); arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102);
err_jack_codec_dev: err_jack_codec_dev:
pm_runtime_disable(&pdev->dev);
arizona_jack_codec_dev_remove(&wm5102->core); arizona_jack_codec_dev_remove(&wm5102->core);
return ret; return ret;
......
...@@ -2457,6 +2457,9 @@ static int wm5110_probe(struct platform_device *pdev) ...@@ -2457,6 +2457,9 @@ static int wm5110_probe(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, wm5110_digital_vu[i], regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
WM5110_DIG_VU, WM5110_DIG_VU); WM5110_DIG_VU, WM5110_DIG_VU);
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
"ADSP2 Compressed IRQ", wm5110_adsp2_irq, "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
wm5110); wm5110);
...@@ -2489,9 +2492,6 @@ static int wm5110_probe(struct platform_device *pdev) ...@@ -2489,9 +2492,6 @@ static int wm5110_probe(struct platform_device *pdev)
goto err_spk_irqs; goto err_spk_irqs;
} }
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
return ret; return ret;
err_spk_irqs: err_spk_irqs:
...@@ -2500,6 +2500,7 @@ static int wm5110_probe(struct platform_device *pdev) ...@@ -2500,6 +2500,7 @@ static int wm5110_probe(struct platform_device *pdev)
arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0); arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5110); arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5110);
err_jack_codec_dev: err_jack_codec_dev:
pm_runtime_disable(&pdev->dev);
arizona_jack_codec_dev_remove(&wm5110->core); arizona_jack_codec_dev_remove(&wm5110->core);
return ret; return ret;
......
...@@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5, ...@@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
4, 1, 0, inmix_tlv), 4, 1, 0, inmix_tlv),
}; };
static int tp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
int ret, reg, val, mask;
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
ret = pm_runtime_resume_and_get(component->dev);
if (ret < 0) {
dev_err(component->dev, "Failed to resume device: %d\n", ret);
return ret;
}
reg = WM8962_ADDITIONAL_CONTROL_4;
if (!strcmp(w->name, "TEMP_HP")) {
mask = WM8962_TEMP_ENA_HP_MASK;
val = WM8962_TEMP_ENA_HP;
} else if (!strcmp(w->name, "TEMP_SPK")) {
mask = WM8962_TEMP_ENA_SPK_MASK;
val = WM8962_TEMP_ENA_SPK;
} else {
pm_runtime_put(component->dev);
return -EINVAL;
}
switch (event) {
case SND_SOC_DAPM_POST_PMD:
val = 0;
fallthrough;
case SND_SOC_DAPM_POST_PMU:
ret = snd_soc_component_update_bits(component, reg, mask, val);
break;
default:
WARN(1, "Invalid event %d\n", event);
pm_runtime_put(component->dev);
return -EINVAL;
}
pm_runtime_put(component->dev);
return 0;
}
static int cp_event(struct snd_soc_dapm_widget *w, static int cp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
{ {
...@@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), ...@@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT, SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
WM8962_DSP2_ENA_SHIFT, 0, dsp2_event, WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event,
SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0), SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event,
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
inpgal, ARRAY_SIZE(inpgal)), inpgal, ARRAY_SIZE(inpgal)),
...@@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c) ...@@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c)
if (ret < 0) if (ret < 0)
goto err_pm_runtime; goto err_pm_runtime;
regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
WM8962_TEMP_ENA_HP_MASK, 0);
regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
WM8962_TEMP_ENA_SPK_MASK, 0);
regcache_cache_only(wm8962->regmap, true); regcache_cache_only(wm8962->regmap, true);
/* The drivers should power up as needed */ /* The drivers should power up as needed */
......
...@@ -1161,6 +1161,9 @@ static int wm8997_probe(struct platform_device *pdev) ...@@ -1161,6 +1161,9 @@ static int wm8997_probe(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, wm8997_digital_vu[i], regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
WM8997_DIG_VU, WM8997_DIG_VU); WM8997_DIG_VU, WM8997_DIG_VU);
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
arizona_init_common(arizona); arizona_init_common(arizona);
ret = arizona_init_vol_limit(arizona); ret = arizona_init_vol_limit(arizona);
...@@ -1179,14 +1182,12 @@ static int wm8997_probe(struct platform_device *pdev) ...@@ -1179,14 +1182,12 @@ static int wm8997_probe(struct platform_device *pdev)
goto err_spk_irqs; goto err_spk_irqs;
} }
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
return ret; return ret;
err_spk_irqs: err_spk_irqs:
arizona_free_spk_irqs(arizona); arizona_free_spk_irqs(arizona);
err_jack_codec_dev: err_jack_codec_dev:
pm_runtime_disable(&pdev->dev);
arizona_jack_codec_dev_remove(&wm8997->core); arizona_jack_codec_dev_remove(&wm8997->core);
return ret; return ret;
......
...@@ -417,7 +417,7 @@ static inline bool parse_as_dpcm_link(struct asoc_simple_priv *priv, ...@@ -417,7 +417,7 @@ static inline bool parse_as_dpcm_link(struct asoc_simple_priv *priv,
* or has convert-xxx property * or has convert-xxx property
*/ */
if ((of_get_child_count(codec_port) > 1) || if ((of_get_child_count(codec_port) > 1) ||
(adata->convert_rate || adata->convert_channels)) asoc_simple_is_convert_required(adata))
return true; return true;
return false; return false;
......
...@@ -85,6 +85,21 @@ void asoc_simple_parse_convert(struct device_node *np, ...@@ -85,6 +85,21 @@ void asoc_simple_parse_convert(struct device_node *np,
} }
EXPORT_SYMBOL_GPL(asoc_simple_parse_convert); EXPORT_SYMBOL_GPL(asoc_simple_parse_convert);
/**
* asoc_simple_is_convert_required() - Query if HW param conversion was requested
* @data: Link data.
*
* Returns true if any HW param conversion was requested for this DAI link with
* any "convert-xxx" properties.
*/
bool asoc_simple_is_convert_required(const struct asoc_simple_data *data)
{
return data->convert_rate ||
data->convert_channels ||
data->convert_sample_format;
}
EXPORT_SYMBOL_GPL(asoc_simple_is_convert_required);
int asoc_simple_parse_daifmt(struct device *dev, int asoc_simple_parse_daifmt(struct device *dev,
struct device_node *node, struct device_node *node,
struct device_node *codec, struct device_node *codec,
......
...@@ -393,8 +393,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv, ...@@ -393,8 +393,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
* or has convert-xxx property * or has convert-xxx property
*/ */
if (dpcm_selectable && if (dpcm_selectable &&
(num > 2 || (num > 2 || asoc_simple_is_convert_required(&adata))) {
adata.convert_rate || adata.convert_channels)) {
/* /*
* np * np
* |1(CPU)|0(Codec) li->cpu * |1(CPU)|0(Codec) li->cpu
......
...@@ -223,6 +223,18 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { ...@@ -223,6 +223,18 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
SOF_RT5682_SSP_AMP(2) | SOF_RT5682_SSP_AMP(2) |
SOF_RT5682_NUM_HDMIDEV(4)), SOF_RT5682_NUM_HDMIDEV(4)),
}, },
{
.callback = sof_rt5682_quirk_cb,
.matches = {
DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
},
.driver_data = (void *)(SOF_RT5682_MCLK_EN |
SOF_RT5682_SSP_CODEC(2) |
SOF_SPEAKER_AMP_PRESENT |
SOF_RT5682_SSP_AMP(0) |
SOF_RT5682_NUM_HDMIDEV(4)
),
},
{} {}
}; };
......
...@@ -202,6 +202,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { ...@@ -202,6 +202,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
SOF_SDW_PCH_DMIC | SOF_SDW_PCH_DMIC |
RT711_JD1), RT711_JD1),
}, },
{
/* NUC15 LAPBC710 skews */
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
SOF_SDW_PCH_DMIC |
RT711_JD1),
},
/* TigerLake-SDCA devices */ /* TigerLake-SDCA devices */
{ {
.callback = sof_sdw_quirk_cb, .callback = sof_sdw_quirk_cb,
......
...@@ -689,11 +689,6 @@ static void load_codec_module(struct hda_codec *codec) ...@@ -689,11 +689,6 @@ static void load_codec_module(struct hda_codec *codec)
#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */ #endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
static void skl_codec_device_exit(struct device *dev)
{
snd_hdac_device_exit(dev_to_hdac_dev(dev));
}
static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr) static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr)
{ {
struct hda_codec *codec; struct hda_codec *codec;
...@@ -706,12 +701,11 @@ static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr) ...@@ -706,12 +701,11 @@ static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr)
} }
codec->core.type = HDA_DEV_ASOC; codec->core.type = HDA_DEV_ASOC;
codec->core.dev.release = skl_codec_device_exit;
ret = snd_hdac_device_register(&codec->core); ret = snd_hdac_device_register(&codec->core);
if (ret) { if (ret) {
dev_err(bus->dev, "failed to register hdac device\n"); dev_err(bus->dev, "failed to register hdac device\n");
snd_hdac_device_exit(&codec->core); put_device(&codec->core.dev);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
......
...@@ -187,6 +187,7 @@ config SND_SOC_SC8280XP ...@@ -187,6 +187,7 @@ config SND_SOC_SC8280XP
config SND_SOC_SC7180 config SND_SOC_SC7180
tristate "SoC Machine driver for SC7180 boards" tristate "SoC Machine driver for SC7180 boards"
depends on I2C && GPIOLIB depends on I2C && GPIOLIB
depends on SOUNDWIRE || SOUNDWIRE=n
select SND_SOC_QCOM_COMMON select SND_SOC_QCOM_COMMON
select SND_SOC_LPASS_SC7180 select SND_SOC_LPASS_SC7180
select SND_SOC_MAX98357A select SND_SOC_MAX98357A
......
...@@ -782,10 +782,20 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg) ...@@ -782,10 +782,20 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
return true; return true;
if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v)) if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
return true; return true;
if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
return true;
if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
return true;
for (i = 0; i < v->hdmi_rdma_channels; ++i) { for (i = 0; i < v->hdmi_rdma_channels; ++i) {
if (reg == LPAIF_HDMI_RDMACURR_REG(v, i)) if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
return true; return true;
if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
return true;
if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
return true;
if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
return true;
} }
return false; return false;
} }
......
...@@ -1213,9 +1213,11 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd, ...@@ -1213,9 +1213,11 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
int i; int i;
for_each_rtd_components(rtd, i, component) { for_each_rtd_components(rtd, i, component) {
int ret = pm_runtime_resume_and_get(component->dev); int ret = pm_runtime_get_sync(component->dev);
if (ret < 0 && ret != -EACCES) if (ret < 0 && ret != -EACCES) {
pm_runtime_put_noidle(component->dev);
return soc_component_ret(component, ret); return soc_component_ret(component, ret);
}
/* mark stream if succeeded */ /* mark stream if succeeded */
soc_component_mark_push(component, stream, pm); soc_component_mark_push(component, stream, pm);
} }
......
...@@ -109,11 +109,6 @@ EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC); ...@@ -109,11 +109,6 @@ EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC);
#define is_generic_config(x) 0 #define is_generic_config(x) 0
#endif #endif
static void hda_codec_device_exit(struct device *dev)
{
snd_hdac_device_exit(dev_to_hdac_dev(dev));
}
static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, int type) static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, int type)
{ {
struct hda_codec *codec; struct hda_codec *codec;
...@@ -126,12 +121,11 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i ...@@ -126,12 +121,11 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i
} }
codec->core.type = type; codec->core.type = type;
codec->core.dev.release = hda_codec_device_exit;
ret = snd_hdac_device_register(&codec->core); ret = snd_hdac_device_register(&codec->core);
if (ret) { if (ret) {
dev_err(bus->dev, "failed to register hdac device\n"); dev_err(bus->dev, "failed to register hdac device\n");
snd_hdac_device_exit(&codec->core); put_device(&codec->core.dev);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
......
...@@ -38,7 +38,7 @@ static const struct sof_dev_desc mtl_desc = { ...@@ -38,7 +38,7 @@ static const struct sof_dev_desc mtl_desc = {
[SOF_INTEL_IPC4] = "intel/sof-ace-tplg", [SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
}, },
.default_fw_filename = { .default_fw_filename = {
[SOF_INTEL_IPC4] = "dsp_basefw.bin", [SOF_INTEL_IPC4] = "sof-mtl.ri",
}, },
.nocodec_tplg_filename = "sof-mtl-nocodec.tplg", .nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
.ops = &sof_mtl_ops, .ops = &sof_mtl_ops,
......
...@@ -159,6 +159,34 @@ static const struct sof_dev_desc adl_desc = { ...@@ -159,6 +159,34 @@ static const struct sof_dev_desc adl_desc = {
.ops_init = sof_tgl_ops_init, .ops_init = sof_tgl_ops_init,
}; };
static const struct sof_dev_desc adl_n_desc = {
.machines = snd_soc_acpi_intel_adl_machines,
.alt_machines = snd_soc_acpi_intel_adl_sdw_machines,
.use_acpi_target_states = true,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = -1,
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &tgl_chip_info,
.ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
.ipc_default = SOF_IPC,
.default_fw_path = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/adl-n",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
},
.default_fw_filename = {
[SOF_IPC] = "sof-adl-n.ri",
[SOF_INTEL_IPC4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
.ops = &sof_tgl_ops,
.ops_init = sof_tgl_ops_init,
};
static const struct sof_dev_desc rpls_desc = { static const struct sof_dev_desc rpls_desc = {
.machines = snd_soc_acpi_intel_rpl_machines, .machines = snd_soc_acpi_intel_rpl_machines,
.alt_machines = snd_soc_acpi_intel_rpl_sdw_machines, .alt_machines = snd_soc_acpi_intel_rpl_sdw_machines,
...@@ -246,7 +274,7 @@ static const struct pci_device_id sof_pci_ids[] = { ...@@ -246,7 +274,7 @@ static const struct pci_device_id sof_pci_ids[] = {
{ PCI_DEVICE(0x8086, 0x51cf), /* RPL-PX */ { PCI_DEVICE(0x8086, 0x51cf), /* RPL-PX */
.driver_data = (unsigned long)&rpl_desc}, .driver_data = (unsigned long)&rpl_desc},
{ PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */ { PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */
.driver_data = (unsigned long)&adl_desc}, .driver_data = (unsigned long)&adl_n_desc},
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(pci, sof_pci_ids); MODULE_DEVICE_TABLE(pci, sof_pci_ids);
......
...@@ -108,6 +108,7 @@ struct sof_mtrace_core_data { ...@@ -108,6 +108,7 @@ struct sof_mtrace_core_data {
int id; int id;
u32 slot_offset; u32 slot_offset;
void *log_buffer; void *log_buffer;
struct mutex buffer_lock; /* for log_buffer alloc/free */
u32 host_read_ptr; u32 host_read_ptr;
u32 dsp_write_ptr; u32 dsp_write_ptr;
/* pos update IPC arrived before the slot offset is known, queried */ /* pos update IPC arrived before the slot offset is known, queried */
...@@ -128,14 +129,22 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file) ...@@ -128,14 +129,22 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file)
struct sof_mtrace_core_data *core_data = inode->i_private; struct sof_mtrace_core_data *core_data = inode->i_private;
int ret; int ret;
mutex_lock(&core_data->buffer_lock);
if (core_data->log_buffer) {
ret = -EBUSY;
goto out;
}
ret = debugfs_file_get(file->f_path.dentry); ret = debugfs_file_get(file->f_path.dentry);
if (unlikely(ret)) if (unlikely(ret))
return ret; goto out;
core_data->log_buffer = kmalloc(SOF_MTRACE_SLOT_SIZE, GFP_KERNEL); core_data->log_buffer = kmalloc(SOF_MTRACE_SLOT_SIZE, GFP_KERNEL);
if (!core_data->log_buffer) { if (!core_data->log_buffer) {
debugfs_file_put(file->f_path.dentry); debugfs_file_put(file->f_path.dentry);
return -ENOMEM; ret = -ENOMEM;
goto out;
} }
ret = simple_open(inode, file); ret = simple_open(inode, file);
...@@ -144,6 +153,9 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file) ...@@ -144,6 +153,9 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file)
debugfs_file_put(file->f_path.dentry); debugfs_file_put(file->f_path.dentry);
} }
out:
mutex_unlock(&core_data->buffer_lock);
return ret; return ret;
} }
...@@ -280,7 +292,10 @@ static int sof_ipc4_mtrace_dfs_release(struct inode *inode, struct file *file) ...@@ -280,7 +292,10 @@ static int sof_ipc4_mtrace_dfs_release(struct inode *inode, struct file *file)
debugfs_file_put(file->f_path.dentry); debugfs_file_put(file->f_path.dentry);
mutex_lock(&core_data->buffer_lock);
kfree(core_data->log_buffer); kfree(core_data->log_buffer);
core_data->log_buffer = NULL;
mutex_unlock(&core_data->buffer_lock);
return 0; return 0;
} }
...@@ -563,6 +578,7 @@ static int ipc4_mtrace_init(struct snd_sof_dev *sdev) ...@@ -563,6 +578,7 @@ static int ipc4_mtrace_init(struct snd_sof_dev *sdev)
struct sof_mtrace_core_data *core_data = &priv->cores[i]; struct sof_mtrace_core_data *core_data = &priv->cores[i];
init_waitqueue_head(&core_data->trace_sleep); init_waitqueue_head(&core_data->trace_sleep);
mutex_init(&core_data->buffer_lock);
core_data->sdev = sdev; core_data->sdev = sdev;
core_data->id = i; core_data->id = i;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment