forked from Minki/linux
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. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmNZkkEACgkQJNaLcl1U h9DvZAf7B9cYxTWPVFDridvJWjWG6SfdQ3dcnINYjbuF42mCLJf+2zBA0AvER7yl gHn0gjdag7l+ssnLBG17R4nlQb/r9VfFiuxuVzwr4iyAfL5YsynmOIJFmPt1TaiF KAZlBG+kLC41ke389rgsIuFnY0vvWWhnank/pJplBZBkCtDz0+RO9YbTK0gVQbIU LBB7ajP7mROLaTsVbyWTQpoWcFZ0clC7yiBx+bTtLYVhopJuvqztQlxEYyqaGteq 94jBMLza/+aDOwdVjqq4lHf/HjXEggDbYeSWpV7S9FKwVa44aGWrJoih5HweFD6R 9/+AqjWrqz23XJeDQfojzxrtt9m7cA== =wGg1 -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
f850a2b156
@ -177,6 +177,7 @@ void asoc_simple_convert_fixup(struct asoc_simple_data *data,
|
||||
struct snd_pcm_hw_params *params);
|
||||
void asoc_simple_parse_convert(struct device_node *np, char *prefix,
|
||||
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,
|
||||
char *prefix);
|
||||
|
@ -45,6 +45,27 @@ static struct snd_soc_card acp6x_card = {
|
||||
};
|
||||
|
||||
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,
|
||||
.matches = {
|
||||
|
@ -1629,6 +1629,7 @@ config SND_SOC_TFA989X
|
||||
config SND_SOC_TLV320ADC3XXX
|
||||
tristate "Texas Instruments TLV320ADC3001/3101 audio ADC"
|
||||
depends on I2C
|
||||
depends on GPIOLIB
|
||||
help
|
||||
Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
|
||||
ADCs.
|
||||
|
@ -177,7 +177,7 @@
|
||||
#define CX2072X_PLBK_DRC_PARM_LEN 9
|
||||
#define CX2072X_CLASSD_AMP_LEN 6
|
||||
|
||||
/* DAI interfae type */
|
||||
/* DAI interface type */
|
||||
#define CX2072X_DAI_HIFI 1
|
||||
#define CX2072X_DAI_DSP 2
|
||||
#define CX2072X_DAI_DSP_PWM 3 /* 4 ch, including mic and AEC */
|
||||
|
@ -136,14 +136,17 @@ enum {
|
||||
#define REG_CGR3_GO1L_OFFSET 0
|
||||
#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 regmap *regmap;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0);
|
||||
static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600);
|
||||
static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv, 0, 150, 0);
|
||||
static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
|
||||
|
||||
static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
|
||||
SOC_DOUBLE_TLV("Master Playback Volume",
|
||||
@ -151,11 +154,11 @@ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
|
||||
REG_CGR1_GODL_OFFSET,
|
||||
REG_CGR1_GODR_OFFSET,
|
||||
0xf, 1, jz4725b_dac_tlv),
|
||||
SOC_DOUBLE_R_TLV("Master Capture Volume",
|
||||
JZ4725B_CODEC_REG_CGR3,
|
||||
JZ4725B_CODEC_REG_CGR2,
|
||||
REG_CGR2_GO1R_OFFSET,
|
||||
0x1f, 1, jz4725b_line_tlv),
|
||||
SOC_DOUBLE_TLV("Master Capture Volume",
|
||||
JZ4725B_CODEC_REG_CGR10,
|
||||
REG_CGR10_GIL_OFFSET,
|
||||
REG_CGR10_GIR_OFFSET,
|
||||
0xf, 0, jz4725b_adc_tlv),
|
||||
|
||||
SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1,
|
||||
REG_CR1_DAC_MUTE_OFFSET, 1, 1),
|
||||
@ -180,7 +183,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
|
||||
jz4725b_codec_adc_src_texts,
|
||||
jz4725b_codec_adc_src_values);
|
||||
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[] = {
|
||||
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[] = {
|
||||
SND_SOC_DAPM_ADC("ADC", "Capture",
|
||||
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),
|
||||
|
||||
/* Mixer */
|
||||
@ -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,
|
||||
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,
|
||||
REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
|
||||
|
||||
@ -283,11 +287,11 @@ static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
|
||||
{"Mixer", NULL, "DAC to Mixer"},
|
||||
|
||||
{"Mixer to ADC", NULL, "Mixer"},
|
||||
{"ADC Source", "Mixer", "Mixer to ADC"},
|
||||
{"ADC Source", "Line In", "Line In"},
|
||||
{"ADC Source", "Mic 1", "Mic 1"},
|
||||
{"ADC Source", "Mic 2", "Mic 2"},
|
||||
{"ADC", NULL, "ADC Source"},
|
||||
{"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
|
||||
{"ADC Source Capture Route", "Line In", "Line In"},
|
||||
{"ADC Source Capture Route", "Mic 1", "Mic 1"},
|
||||
{"ADC Source Capture Route", "Mic 2", "Mic 2"},
|
||||
{"ADC", NULL, "ADC Source Capture Route"},
|
||||
|
||||
{"Out Stage", NULL, "Mixer"},
|
||||
{"HP Out", NULL, "Out Stage"},
|
||||
|
@ -503,14 +503,14 @@ static int mt6660_i2c_probe(struct i2c_client *client)
|
||||
dev_err(chip->dev, "read chip revision fail\n");
|
||||
goto probe_fail;
|
||||
}
|
||||
pm_runtime_set_active(chip->dev);
|
||||
pm_runtime_enable(chip->dev);
|
||||
|
||||
ret = devm_snd_soc_register_component(chip->dev,
|
||||
&mt6660_component_driver,
|
||||
&mt6660_codec_dai, 1);
|
||||
if (!ret) {
|
||||
pm_runtime_set_active(chip->dev);
|
||||
pm_runtime_enable(chip->dev);
|
||||
}
|
||||
if (ret)
|
||||
pm_runtime_disable(chip->dev);
|
||||
|
||||
return ret;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
switch (slots) {
|
||||
case 4:
|
||||
val |= RT1019_I2S_TX_4CH;
|
||||
cn = RT1019_I2S_TX_4CH;
|
||||
break;
|
||||
case 6:
|
||||
val |= RT1019_I2S_TX_6CH;
|
||||
cn = RT1019_I2S_TX_6CH;
|
||||
break;
|
||||
case 8:
|
||||
val |= RT1019_I2S_TX_8CH;
|
||||
cn = RT1019_I2S_TX_8CH;
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
@ -412,16 +412,16 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
||||
|
||||
switch (slot_width) {
|
||||
case 20:
|
||||
val |= RT1019_I2S_DL_20;
|
||||
cl = RT1019_TDM_CL_20;
|
||||
break;
|
||||
case 24:
|
||||
val |= RT1019_I2S_DL_24;
|
||||
cl = RT1019_TDM_CL_24;
|
||||
break;
|
||||
case 32:
|
||||
val |= RT1019_I2S_DL_32;
|
||||
cl = RT1019_TDM_CL_32;
|
||||
break;
|
||||
case 8:
|
||||
val |= RT1019_I2S_DL_8;
|
||||
cl = RT1019_TDM_CL_8;
|
||||
break;
|
||||
case 16:
|
||||
break;
|
||||
@ -470,8 +470,10 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
||||
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,
|
||||
RT1019_I2S_CH_TX_MASK | RT1019_I2S_DF_MASK, val);
|
||||
RT1019_I2S_CH_TX_MASK, cn);
|
||||
|
||||
_set_tdm_err_:
|
||||
return ret;
|
||||
|
@ -95,6 +95,12 @@
|
||||
#define RT1019_TDM_BCLK_MASK (0x1 << 6)
|
||||
#define RT1019_TDM_BCLK_NORM (0x0 << 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 */
|
||||
#define RT1019_I2S_CH_TX_MASK (0x3 << 6)
|
||||
|
@ -50,6 +50,7 @@ static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
|
||||
case 0x3008:
|
||||
case 0x300a:
|
||||
case 0xc000:
|
||||
case 0xc710:
|
||||
case 0xc860 ... 0xc863:
|
||||
case 0xc870 ... 0xc873:
|
||||
return true;
|
||||
@ -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);
|
||||
int ret = 0;
|
||||
unsigned int tmp;
|
||||
|
||||
if (rt1308->hw_init)
|
||||
return 0;
|
||||
@ -231,6 +233,10 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
/* sw reset */
|
||||
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 */
|
||||
regmap_write(rt1308->regmap, 0xc103, 0xc0);
|
||||
regmap_write(rt1308->regmap, 0xc030, 0x17);
|
||||
@ -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, 0xc171, 0x07);
|
||||
regmap_write(rt1308->regmap, 0xc173, 0x0d);
|
||||
regmap_write(rt1308->regmap, 0xc311, 0x7f);
|
||||
regmap_write(rt1308->regmap, 0xc900, 0x90);
|
||||
if (rt1308->hw_ver == RT1308_VER_C) {
|
||||
regmap_write(rt1308->regmap, 0xc311, 0x7f);
|
||||
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, 0xc1a1, 0x01);
|
||||
regmap_write(rt1308->regmap, 0xc360, 0x78);
|
||||
@ -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, 0xc100, 0xd7);
|
||||
regmap_write(rt1308->regmap, 0xc101, 0xd7);
|
||||
regmap_write(rt1308->regmap, 0xc300, 0x09);
|
||||
|
||||
if (rt1308->first_hw_init) {
|
||||
regcache_cache_bypass(rt1308->regmap, false);
|
||||
|
@ -139,10 +139,12 @@ static const struct reg_default rt1308_reg_defaults[] = {
|
||||
{ 0x3005, 0x23 },
|
||||
{ 0x3008, 0x02 },
|
||||
{ 0x300a, 0x00 },
|
||||
{ 0xc000 | (RT1308_DATA_PATH << 4), 0x00 },
|
||||
{ 0xc003 | (RT1308_DAC_SET << 4), 0x00 },
|
||||
{ 0xc000 | (RT1308_POWER << 4), 0x00 },
|
||||
{ 0xc001 | (RT1308_POWER << 4), 0x00 },
|
||||
{ 0xc002 | (RT1308_POWER << 4), 0x00 },
|
||||
{ 0xc000 | (RT1308_POWER_STATUS << 4), 0x00 },
|
||||
};
|
||||
|
||||
#define RT1308_SDW_OFFSET 0xc000
|
||||
@ -163,6 +165,7 @@ struct rt1308_sdw_priv {
|
||||
bool first_hw_init;
|
||||
int rx_mask;
|
||||
int slots;
|
||||
int hw_ver;
|
||||
};
|
||||
|
||||
struct sdw_stream_data {
|
||||
|
@ -286,4 +286,9 @@ enum {
|
||||
RT1308_AIFS
|
||||
};
|
||||
|
||||
enum rt1308_hw_ver {
|
||||
RT1308_VER_C = 2,
|
||||
RT1308_VER_D
|
||||
};
|
||||
|
||||
#endif /* end of _RT1308_H_ */
|
||||
|
@ -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)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
unsigned int cl, val = 0;
|
||||
unsigned int cl, val = 0, tx_slotnum;
|
||||
|
||||
if (tx_mask || rx_mask)
|
||||
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,
|
||||
snd_soc_component_update_bits(component,
|
||||
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) {
|
||||
case 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,
|
||||
}
|
||||
|
||||
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) {
|
||||
case 8:
|
||||
|
@ -899,6 +899,7 @@
|
||||
#define RT5682S_TDM_RX_CH_8 (0x3 << 8)
|
||||
#define RT5682S_TDM_ADC_LCA_MASK (0x7 << 4)
|
||||
#define RT5682S_TDM_ADC_LCA_SFT 4
|
||||
#define RT5682S_TDM_ADC_DL_MASK (0x3 << 0)
|
||||
#define RT5682S_TDM_ADC_DL_SFT 0
|
||||
|
||||
/* TDM control 2 (0x007a) */
|
||||
|
@ -1449,7 +1449,7 @@ static struct i2c_driver adc3xxx_i2c_driver = {
|
||||
.of_match_table = tlv320adc3xxx_of_match,
|
||||
},
|
||||
.probe_new = adc3xxx_i2c_probe,
|
||||
.remove = adc3xxx_i2c_remove,
|
||||
.remove = __exit_p(adc3xxx_i2c_remove),
|
||||
.id_table = adc3xxx_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -2099,6 +2099,9 @@ static int wm5102_probe(struct platform_device *pdev)
|
||||
regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
|
||||
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,
|
||||
"ADSP2 Compressed IRQ", wm5102_adsp2_irq,
|
||||
wm5102);
|
||||
@ -2131,9 +2134,6 @@ static int wm5102_probe(struct platform_device *pdev)
|
||||
goto err_spk_irqs;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_idle(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
|
||||
err_spk_irqs:
|
||||
@ -2142,6 +2142,7 @@ err_dsp_irq:
|
||||
arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
|
||||
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102);
|
||||
err_jack_codec_dev:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
arizona_jack_codec_dev_remove(&wm5102->core);
|
||||
|
||||
return ret;
|
||||
|
@ -2457,6 +2457,9 @@ static int wm5110_probe(struct platform_device *pdev)
|
||||
regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
|
||||
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,
|
||||
"ADSP2 Compressed IRQ", wm5110_adsp2_irq,
|
||||
wm5110);
|
||||
@ -2489,9 +2492,6 @@ static int wm5110_probe(struct platform_device *pdev)
|
||||
goto err_spk_irqs;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_idle(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
|
||||
err_spk_irqs:
|
||||
@ -2500,6 +2500,7 @@ err_dsp_irq:
|
||||
arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
|
||||
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5110);
|
||||
err_jack_codec_dev:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
arizona_jack_codec_dev_remove(&wm5110->core);
|
||||
|
||||
return ret;
|
||||
|
@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
|
||||
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,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
@ -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,
|
||||
WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
|
||||
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_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event,
|
||||
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,
|
||||
inpgal, ARRAY_SIZE(inpgal)),
|
||||
@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c)
|
||||
if (ret < 0)
|
||||
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);
|
||||
|
||||
/* The drivers should power up as needed */
|
||||
|
@ -1161,6 +1161,9 @@ static int wm8997_probe(struct platform_device *pdev)
|
||||
regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
|
||||
WM8997_DIG_VU, WM8997_DIG_VU);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_idle(&pdev->dev);
|
||||
|
||||
arizona_init_common(arizona);
|
||||
|
||||
ret = arizona_init_vol_limit(arizona);
|
||||
@ -1179,14 +1182,12 @@ static int wm8997_probe(struct platform_device *pdev)
|
||||
goto err_spk_irqs;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_idle(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
|
||||
err_spk_irqs:
|
||||
arizona_free_spk_irqs(arizona);
|
||||
err_jack_codec_dev:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
arizona_jack_codec_dev_remove(&wm8997->core);
|
||||
|
||||
return ret;
|
||||
|
@ -417,7 +417,7 @@ static inline bool parse_as_dpcm_link(struct asoc_simple_priv *priv,
|
||||
* or has convert-xxx property
|
||||
*/
|
||||
if ((of_get_child_count(codec_port) > 1) ||
|
||||
(adata->convert_rate || adata->convert_channels))
|
||||
asoc_simple_is_convert_required(adata))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -85,6 +85,21 @@ void asoc_simple_parse_convert(struct device_node *np,
|
||||
}
|
||||
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,
|
||||
struct device_node *node,
|
||||
struct device_node *codec,
|
||||
|
@ -393,8 +393,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
|
||||
* or has convert-xxx property
|
||||
*/
|
||||
if (dpcm_selectable &&
|
||||
(num > 2 ||
|
||||
adata.convert_rate || adata.convert_channels)) {
|
||||
(num > 2 || asoc_simple_is_convert_required(&adata))) {
|
||||
/*
|
||||
* np
|
||||
* |1(CPU)|0(Codec) li->cpu
|
||||
|
@ -223,6 +223,18 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
|
||||
SOF_RT5682_SSP_AMP(2) |
|
||||
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[] = {
|
||||
SOF_SDW_PCH_DMIC |
|
||||
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 */
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
|
@ -689,11 +689,6 @@ static void load_codec_module(struct hda_codec *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)
|
||||
{
|
||||
struct hda_codec *codec;
|
||||
@ -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.dev.release = skl_codec_device_exit;
|
||||
|
||||
ret = snd_hdac_device_register(&codec->core);
|
||||
if (ret) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,7 @@ config SND_SOC_SC8280XP
|
||||
config SND_SOC_SC7180
|
||||
tristate "SoC Machine driver for SC7180 boards"
|
||||
depends on I2C && GPIOLIB
|
||||
depends on SOUNDWIRE || SOUNDWIRE=n
|
||||
select SND_SOC_QCOM_COMMON
|
||||
select SND_SOC_LPASS_SC7180
|
||||
select SND_SOC_MAX98357A
|
||||
|
@ -782,10 +782,20 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
|
||||
return true;
|
||||
if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
|
||||
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) {
|
||||
if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
|
||||
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;
|
||||
}
|
||||
|
@ -1213,9 +1213,11 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
|
||||
int i;
|
||||
|
||||
for_each_rtd_components(rtd, i, component) {
|
||||
int ret = pm_runtime_resume_and_get(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
int ret = pm_runtime_get_sync(component->dev);
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
pm_runtime_put_noidle(component->dev);
|
||||
return soc_component_ret(component, ret);
|
||||
}
|
||||
/* mark stream if succeeded */
|
||||
soc_component_mark_push(component, stream, pm);
|
||||
}
|
||||
|
@ -109,11 +109,6 @@ EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC);
|
||||
#define is_generic_config(x) 0
|
||||
#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)
|
||||
{
|
||||
struct hda_codec *codec;
|
||||
@ -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.dev.release = hda_codec_device_exit;
|
||||
|
||||
ret = snd_hdac_device_register(&codec->core);
|
||||
if (ret) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ static const struct sof_dev_desc mtl_desc = {
|
||||
[SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
|
||||
},
|
||||
.default_fw_filename = {
|
||||
[SOF_INTEL_IPC4] = "dsp_basefw.bin",
|
||||
[SOF_INTEL_IPC4] = "sof-mtl.ri",
|
||||
},
|
||||
.nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
|
||||
.ops = &sof_mtl_ops,
|
||||
|
@ -159,6 +159,34 @@ static const struct sof_dev_desc adl_desc = {
|
||||
.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 = {
|
||||
.machines = snd_soc_acpi_intel_rpl_machines,
|
||||
.alt_machines = snd_soc_acpi_intel_rpl_sdw_machines,
|
||||
@ -246,7 +274,7 @@ static const struct pci_device_id sof_pci_ids[] = {
|
||||
{ PCI_DEVICE(0x8086, 0x51cf), /* RPL-PX */
|
||||
.driver_data = (unsigned long)&rpl_desc},
|
||||
{ PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */
|
||||
.driver_data = (unsigned long)&adl_desc},
|
||||
.driver_data = (unsigned long)&adl_n_desc},
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, sof_pci_ids);
|
||||
|
@ -108,6 +108,7 @@ struct sof_mtrace_core_data {
|
||||
int id;
|
||||
u32 slot_offset;
|
||||
void *log_buffer;
|
||||
struct mutex buffer_lock; /* for log_buffer alloc/free */
|
||||
u32 host_read_ptr;
|
||||
u32 dsp_write_ptr;
|
||||
/* 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)
|
||||
struct sof_mtrace_core_data *core_data = inode->i_private;
|
||||
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);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
core_data->log_buffer = kmalloc(SOF_MTRACE_SLOT_SIZE, GFP_KERNEL);
|
||||
if (!core_data->log_buffer) {
|
||||
debugfs_file_put(file->f_path.dentry);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = simple_open(inode, 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);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&core_data->buffer_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -280,7 +292,10 @@ static int sof_ipc4_mtrace_dfs_release(struct inode *inode, struct file *file)
|
||||
|
||||
debugfs_file_put(file->f_path.dentry);
|
||||
|
||||
mutex_lock(&core_data->buffer_lock);
|
||||
kfree(core_data->log_buffer);
|
||||
core_data->log_buffer = NULL;
|
||||
mutex_unlock(&core_data->buffer_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -563,6 +578,7 @@ static int ipc4_mtrace_init(struct snd_sof_dev *sdev)
|
||||
struct sof_mtrace_core_data *core_data = &priv->cores[i];
|
||||
|
||||
init_waitqueue_head(&core_data->trace_sleep);
|
||||
mutex_init(&core_data->buffer_lock);
|
||||
core_data->sdev = sdev;
|
||||
core_data->id = i;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user