mirror of
https://github.com/torvalds/linux.git
synced 2026-09-12 20:53:03 +02:00
ASoC: tegra: Simplify error handling
bui duc phuc <phucduc.bui@gmail.com> says: This series contains a few small cleanups for the Tegra ASoC drivers. - Use dev_err_probe() for regmap initialization failures. - Return the original error from snd_soc_add_component_controls(). - Use devm_clk_get_optional() for the optional sync_input clock. Overall, this simplifies the error paths and makes the code more consistent. Link: https://patch.msgid.link/20260715051115.17385-1-phucduc.bui@gmail.com
This commit is contained in:
commit
4fe01a156e
|
|
@ -21,6 +21,7 @@ properties:
|
|||
- qcom,sc8280xp-lpass-rx-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,eliza-lpass-rx-macro
|
||||
- qcom,kaanapali-lpass-rx-macro
|
||||
- qcom,sm8650-lpass-rx-macro
|
||||
- qcom,sm8750-lpass-rx-macro
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ properties:
|
|||
- qcom,sc8280xp-lpass-tx-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,eliza-lpass-tx-macro
|
||||
- qcom,kaanapali-lpass-tx-macro
|
||||
- qcom,sm8650-lpass-tx-macro
|
||||
- qcom,sm8750-lpass-tx-macro
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ properties:
|
|||
- qcom,sc8280xp-lpass-va-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,eliza-lpass-va-macro
|
||||
- qcom,glymur-lpass-va-macro
|
||||
- qcom,kaanapali-lpass-va-macro
|
||||
- qcom,sm8650-lpass-va-macro
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ properties:
|
|||
- qcom,sc8280xp-lpass-wsa-macro
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,eliza-lpass-wsa-macro
|
||||
- qcom,glymur-lpass-wsa-macro
|
||||
- qcom,kaanapali-lpass-wsa-macro
|
||||
- qcom,sm8650-lpass-wsa-macro
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ properties:
|
|||
- const: qcom,sdm845-sndcard
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,eliza-sndcard
|
||||
- qcom,kaanapali-sndcard
|
||||
- qcom,sm8550-sndcard
|
||||
- qcom,sm8650-sndcard
|
||||
|
|
|
|||
|
|
@ -44,6 +44,18 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "83W5"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TUF Gaming A14 FA401EA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vivobook 18 M1807GA"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,17 @@ config SND_SOC_AMD_ACP_COMMON
|
|||
|
||||
config SND_SOC_ACPI_AMD_MATCH
|
||||
tristate
|
||||
select SND_SOC_ACPI_AMD_SDCA_QUIRKS if SND_SOC_SDCA
|
||||
select SND_SOC_ACPI if ACPI
|
||||
|
||||
config SND_SOC_ACPI_AMD_SDCA_QUIRKS
|
||||
tristate
|
||||
depends on ACPI
|
||||
bool "AMD ACPI SDCA quirks"
|
||||
depends on SND_SOC_ACPI_AMD_MATCH
|
||||
depends on SND_SOC_SDCA
|
||||
depends on SND_SOC_ACPI_AMD_MATCH = m || SND_SOC_SDCA = y
|
||||
default y
|
||||
help
|
||||
Enable SDCA quirk support for AMD ACPI match tables.
|
||||
This is compiled into the snd-soc-acpi-amd-match module.
|
||||
|
||||
if SND_SOC_AMD_ACP_COMMON
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ snd-acp-mach-y := acp-mach-common.o
|
|||
snd-acp-legacy-mach-y := acp-legacy-mach.o acp3x-es83xx/acp3x-es83xx.o
|
||||
snd-acp-sof-mach-y := acp-sof-mach.o
|
||||
snd-soc-acpi-amd-match-y := amd-acp63-acpi-match.o amd-acp70-acpi-match.o
|
||||
snd-soc-acpi-amd-match-$(CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS) += soc-acpi-amd-sdca-quirks.o
|
||||
snd-acp-sdw-mach-y := acp-sdw-mach-common.o
|
||||
snd-acp-sdw-sof-mach-y += acp-sdw-sof-mach.o
|
||||
snd-acp-sdw-legacy-mach-y += acp-sdw-legacy-mach.o
|
||||
snd-soc-acpi-amd-sdca-quirks-y += soc-acpi-amd-sdca-quirks.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o
|
||||
obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o
|
||||
|
|
@ -41,7 +41,6 @@ obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o
|
|||
obj-$(CONFIG_SND_AMD_ASOC_ACP63) += snd-acp63.o
|
||||
obj-$(CONFIG_SND_AMD_ASOC_ACP70) += snd-acp70.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS) += snd-soc-acpi-amd-sdca-quirks.o
|
||||
obj-$(CONFIG_SND_AMD_SOUNDWIRE_ACPI) += snd-amd-sdw-acpi.o
|
||||
obj-$(CONFIG_SND_SOC_AMD_MACH_COMMON) += snd-acp-mach.o
|
||||
obj-$(CONFIG_SND_SOC_AMD_LEGACY_MACH) += snd-acp-legacy-mach.o
|
||||
|
|
|
|||
|
|
@ -553,6 +553,46 @@ static const struct snd_soc_acpi_link_adr acp70_rt722_l0_rt1320_l1[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device tas2783_2_adr[] = {
|
||||
{
|
||||
/* left */
|
||||
.adr = 0x00003c0102000001ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_l_endpoint,
|
||||
.name_prefix = "tas2783-1",
|
||||
},
|
||||
{
|
||||
/* right */
|
||||
.adr = 0x00003d0102000001ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_l_endpoint,
|
||||
.name_prefix = "tas2783-2",
|
||||
},
|
||||
{
|
||||
/* left */
|
||||
.adr = 0x0000390102000001ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_r_endpoint,
|
||||
.name_prefix = "tas2783-3",
|
||||
},
|
||||
{
|
||||
/* right */
|
||||
.adr = 0x00003a0102000001ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_r_endpoint,
|
||||
.name_prefix = "tas2783-4",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr acp70_tas2783_2[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
.num_adr = ARRAY_SIZE(tas2783_2_adr),
|
||||
.adr_d = tas2783_2_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1320_0_single_adr[] = {
|
||||
{
|
||||
.adr = 0x000030025D132001ull,
|
||||
|
|
@ -659,6 +699,11 @@ static const struct snd_soc_acpi_link_adr acp70_rt721_only[] = {
|
|||
};
|
||||
|
||||
struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = {
|
||||
{
|
||||
.link_mask = BIT(0),
|
||||
.links = acp70_tas2783_2,
|
||||
.drv_name = "amd_sdw",
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(1),
|
||||
.links = acp70_rt1320_l0_rt722_l1,
|
||||
|
|
@ -775,5 +820,5 @@ MODULE_DESCRIPTION("AMD ACP7.0 & ACP7.1 tables and support for ACPI enumeration"
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_ACPI_AMD_SDCA_QUIRKS)
|
||||
MODULE_IMPORT_NS("SND_SOC_ACPI_AMD_SDCA_QUIRKS");
|
||||
MODULE_IMPORT_NS("SND_SOC_SDCA");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -35,8 +35,4 @@ bool snd_soc_acpi_amd_sdca_is_device_rt712_vb(void *arg)
|
|||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_NS(snd_soc_acpi_amd_sdca_is_device_rt712_vb, "SND_SOC_ACPI_AMD_SDCA_QUIRKS");
|
||||
|
||||
MODULE_DESCRIPTION("ASoC ACPI AMD SDCA quirks");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS("SND_SOC_SDCA");
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
|
|||
if (sdw_dma_irq_flag)
|
||||
return IRQ_WAKE_THREAD;
|
||||
|
||||
if (irq_flag | wake_irq_flag)
|
||||
if (irq_flag || wake_irq_flag)
|
||||
return IRQ_HANDLED;
|
||||
else
|
||||
return IRQ_NONE;
|
||||
|
|
@ -602,7 +602,7 @@ static int snd_acp63_probe(struct pci_dev *pci,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = pci_request_regions(pci, "AMD ACP6.2 audio");
|
||||
ret = pci_request_regions(pci, "AMD ACP6.3 audio");
|
||||
if (ret < 0) {
|
||||
dev_err(&pci->dev, "pci_request_regions failed\n");
|
||||
goto disable_pci;
|
||||
|
|
@ -693,8 +693,37 @@ static int snd_acp_runtime_resume(struct device *dev)
|
|||
return acp_hw_runtime_resume(dev);
|
||||
}
|
||||
|
||||
static void acp_disable_msi_on_resume(struct pci_dev *pdev)
|
||||
{
|
||||
u16 control;
|
||||
|
||||
if (!pdev->msi_cap)
|
||||
return;
|
||||
|
||||
pci_read_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, &control);
|
||||
if (control & PCI_MSI_FLAGS_ENABLE) {
|
||||
dev_warn(&pdev->dev,
|
||||
"ACP: MSI unexpectedly enabled after resume (flags=0x%04x), disabling\n",
|
||||
control);
|
||||
control &= ~PCI_MSI_FLAGS_ENABLE;
|
||||
pci_write_config_word(pdev, pdev->msi_cap + PCI_MSI_FLAGS, control);
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_acp_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
/*
|
||||
* BIOS/firmware may re-enable MSI in PCI config space during
|
||||
* system resume even though this driver only uses legacy INTx
|
||||
* interrupts. If MSI is left enabled with stale address/data
|
||||
* registers, the device will write interrupts to a bogus address
|
||||
* causing IOMMU IO_PAGE_FAULT and interrupt delivery failure.
|
||||
* Explicitly clear the MSI Enable bit before reinitializing
|
||||
* the ACP hardware.
|
||||
*/
|
||||
acp_disable_msi_on_resume(pdev);
|
||||
return acp_hw_resume(dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -521,6 +521,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "Vector A16 HX A8WHG"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vector A16 HX A8WIG"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
|
|
|
|||
|
|
@ -315,6 +315,7 @@ irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data)
|
|||
#define CS42L43_JACK_ABSENT 0x0
|
||||
|
||||
#define CS42L43_JACK_OPTICAL (SND_JACK_MECHANICAL | SND_JACK_AVOUT)
|
||||
#define CS42L43_JACK_MICROPHONE (SND_JACK_MECHANICAL | SND_JACK_MICROPHONE)
|
||||
#define CS42L43_JACK_HEADPHONE (SND_JACK_MECHANICAL | SND_JACK_HEADPHONE)
|
||||
#define CS42L43_JACK_HEADSET (SND_JACK_MECHANICAL | SND_JACK_HEADSET)
|
||||
#define CS42L43_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
|
||||
|
|
@ -860,7 +861,7 @@ static const struct cs42l43_jack_override_mode {
|
|||
.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
|
||||
.mic_ctrl = (0x3 << CS42L43_JACK_STEREO_CONFIG_SHIFT) |
|
||||
CS42L43_HS1_BIAS_EN_MASK | CS42L43_HS2_BIAS_EN_MASK,
|
||||
.report = CS42L43_JACK_LINEIN,
|
||||
.report = CS42L43_JACK_MICROPHONE,
|
||||
},
|
||||
[CS42L43_JACK_RAW_OPTICAL] = {
|
||||
.hsdet_mode = CS42L43_JACK_3_POLE_SWITCHES,
|
||||
|
|
|
|||
|
|
@ -1843,6 +1843,15 @@ static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)
|
|||
}
|
||||
}
|
||||
|
||||
static void rt712_sdca_reset(struct rt712_sdca_priv *rt712)
|
||||
{
|
||||
rt712_sdca_index_update_bits(rt712, RT712_VENDOR_REG,
|
||||
RT712_PARA_VERB_CTL, RT712_HIDDEN_REG_SW_RESET,
|
||||
RT712_HIDDEN_REG_SW_RESET);
|
||||
rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
|
||||
RT712_HDA_LEGACY_RESET_CTL, 0x1, 0x1);
|
||||
}
|
||||
|
||||
int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
{
|
||||
struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev);
|
||||
|
|
@ -1870,6 +1879,8 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
|||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
||||
rt712_sdca_reset(rt712);
|
||||
|
||||
rt712_sdca_index_read(rt712, RT712_VENDOR_REG, RT712_JD_PRODUCT_NUM, &val);
|
||||
rt712->hw_id = (val & 0xf000) >> 12;
|
||||
rt712->version_id = (val & 0x0f00) >> 8;
|
||||
|
|
|
|||
|
|
@ -675,11 +675,12 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
|
|||
if (tas2562->sdz_gpio == NULL) {
|
||||
tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(tas2562->sdz_gpio))
|
||||
if (IS_ERR(tas2562->sdz_gpio)) {
|
||||
if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
tas2562->sdz_gpio = NULL;
|
||||
tas2562->sdz_gpio = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (tas2562->model_id == TAS2110)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
|
@ -1100,13 +1101,42 @@ static int tasdevice_load_block_kernel(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tasdevice_fw_strnlen(const struct firmware *fmw, int offset)
|
||||
{
|
||||
const u8 *start;
|
||||
const u8 *nul;
|
||||
size_t remaining;
|
||||
size_t len;
|
||||
|
||||
if (offset < 0 || offset >= fmw->size)
|
||||
return -EINVAL;
|
||||
|
||||
start = fmw->data + offset;
|
||||
remaining = fmw->size - offset;
|
||||
nul = memchr(start, '\0', remaining);
|
||||
if (!nul)
|
||||
return -EINVAL;
|
||||
|
||||
len = nul - start;
|
||||
if (len > INT_MAX)
|
||||
return -EOVERFLOW;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int fw_parse_variable_hdr(struct tasdevice_priv
|
||||
*tas_priv, struct tasdevice_dspfw_hdr *fw_hdr,
|
||||
const struct firmware *fmw, int offset)
|
||||
{
|
||||
const unsigned char *buf = fmw->data;
|
||||
int len = strlen((char *)&buf[offset]);
|
||||
int len;
|
||||
|
||||
len = tasdevice_fw_strnlen(fmw, offset);
|
||||
if (len < 0) {
|
||||
dev_err(tas_priv->dev, "%s: Description error\n", __func__);
|
||||
offset = len;
|
||||
goto out;
|
||||
}
|
||||
len++;
|
||||
|
||||
if (offset + len + 8 > fmw->size) {
|
||||
|
|
@ -1238,7 +1268,12 @@ static int fw_parse_data(struct tasdevice_fw *tas_fmw,
|
|||
memcpy(img_data->name, &data[offset], 64);
|
||||
offset += 64;
|
||||
|
||||
n = strlen((char *)&data[offset]);
|
||||
n = tasdevice_fw_strnlen(fmw, offset);
|
||||
if (n < 0) {
|
||||
dev_err(tas_fmw->dev, "%s: Description error\n", __func__);
|
||||
offset = n;
|
||||
goto out;
|
||||
}
|
||||
n++;
|
||||
if (offset + n + 2 > fmw->size) {
|
||||
dev_err(tas_fmw->dev, "%s: Description error\n", __func__);
|
||||
|
|
@ -1309,7 +1344,12 @@ static int fw_parse_program_data(struct tasdevice_priv *tas_priv,
|
|||
}
|
||||
offset += 64;
|
||||
|
||||
n = strlen((char *)&buf[offset]);
|
||||
n = tasdevice_fw_strnlen(fmw, offset);
|
||||
if (n < 0) {
|
||||
dev_err(tas_priv->dev, "Description err\n");
|
||||
offset = n;
|
||||
goto out;
|
||||
}
|
||||
/* skip '\0' and 5 unused bytes */
|
||||
n += 6;
|
||||
if (offset + n > fmw->size) {
|
||||
|
|
@ -1372,7 +1412,12 @@ static int fw_parse_configuration_data(
|
|||
memcpy(config->name, &data[offset], 64);
|
||||
offset += 64;
|
||||
|
||||
n = strlen((char *)&data[offset]);
|
||||
n = tasdevice_fw_strnlen(fmw, offset);
|
||||
if (n < 0) {
|
||||
dev_err(tas_priv->dev, "Description err\n");
|
||||
offset = n;
|
||||
goto out;
|
||||
}
|
||||
n += 15;
|
||||
if (offset + n > fmw->size) {
|
||||
dev_err(tas_priv->dev, "Description err\n");
|
||||
|
|
@ -2134,7 +2179,8 @@ static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv,
|
|||
{
|
||||
struct tasdevice_calibration *calibration;
|
||||
unsigned char *data = (unsigned char *)fmw->data;
|
||||
unsigned int i, n;
|
||||
unsigned int i;
|
||||
int n;
|
||||
|
||||
if (offset + 2 > fmw->size) {
|
||||
dev_err(tas_priv->dev, "%s: Calibrations error\n", __func__);
|
||||
|
|
@ -2166,7 +2212,12 @@ static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv,
|
|||
calibration = &(tas_fmw->calibrations[i]);
|
||||
offset += 64;
|
||||
|
||||
n = strlen((char *)&data[offset]);
|
||||
n = tasdevice_fw_strnlen(fmw, offset);
|
||||
if (n < 0) {
|
||||
dev_err(tas_priv->dev, "Description err\n");
|
||||
offset = n;
|
||||
goto out;
|
||||
}
|
||||
/* skip '\0' and 2 unused bytes */
|
||||
n += 3;
|
||||
if (offset + n > fmw->size) {
|
||||
|
|
|
|||
|
|
@ -808,6 +808,8 @@ static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
|
|||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
unsigned int ofs = sai->soc_data->reg_offset;
|
||||
int adir = tx ? RX : TX;
|
||||
int dir = tx ? TX : RX;
|
||||
|
||||
/* Clear xMR to avoid channel swap with mclk_with_tere enabled case */
|
||||
regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0);
|
||||
|
|
@ -815,10 +817,29 @@ static int fsl_sai_hw_free(struct snd_pcm_substream *substream,
|
|||
regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
|
||||
FSL_SAI_CR3_TRCE_MASK, 0);
|
||||
|
||||
if (!sai->is_consumer_mode[tx] &&
|
||||
sai->mclk_streams & BIT(substream->stream)) {
|
||||
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
|
||||
sai->mclk_streams &= ~BIT(substream->stream);
|
||||
if (!sai->is_consumer_mode[tx]) {
|
||||
bool adir_active = !!(sai->mclk_streams & BIT(!substream->stream));
|
||||
/*
|
||||
* If opposite stream provides clocks for synchronous mode and
|
||||
* it is inactive, Clear BYP and BCI
|
||||
*/
|
||||
if (fsl_sai_dir_is_synced(sai, adir) && !adir_active)
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR2(!tx, ofs),
|
||||
FSL_SAI_CR2_BCI | FSL_SAI_CR2_BYP, 0);
|
||||
/*
|
||||
* Clear BYP and BCI of current stream if either of:
|
||||
* 1. current stream doesn't provide clocks for synchronous mode
|
||||
* 2. current stream provides clocks for synchronous mode but no
|
||||
* more stream is active.
|
||||
*/
|
||||
if (!fsl_sai_dir_is_synced(sai, dir) || !adir_active)
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
|
||||
FSL_SAI_CR2_BCI | FSL_SAI_CR2_BYP, 0);
|
||||
|
||||
if (sai->mclk_streams & BIT(substream->stream)) {
|
||||
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
|
||||
sai->mclk_streams &= ~BIT(substream->stream);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -496,11 +496,15 @@ static void imx_aif_shutdown(struct snd_pcm_substream *substream)
|
|||
struct snd_soc_dai *codec_dai;
|
||||
int i;
|
||||
|
||||
for_each_rtd_cpu_dais(rtd, i, cpu_dai)
|
||||
snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
|
||||
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
|
||||
if (!snd_soc_dai_active(cpu_dai))
|
||||
snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
|
||||
}
|
||||
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai)
|
||||
snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||
if (!snd_soc_dai_active(codec_dai))
|
||||
snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops imx_aif_ops = {
|
||||
|
|
|
|||
|
|
@ -855,6 +855,7 @@ static const struct snd_pci_quirk sof_sdw_ssid_quirk_table[] = {
|
|||
SND_PCI_QUIRK(0x17aa, 0x2348, "Lenovo P16", SOC_SDW_CODEC_MIC),
|
||||
SND_PCI_QUIRK(0x17aa, 0x2349, "Lenovo P1", SOC_SDW_CODEC_MIC),
|
||||
SND_PCI_QUIRK(0x17aa, 0x3821, "Lenovo 0x3821", SOC_SDW_SIDECAR_AMPS),
|
||||
SND_PCI_QUIRK(0x17aa, 0x383c, "Lenovo 0x383c", SOC_SDW_SIDECAR_AMPS),
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
|
||||
#define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
|
||||
#define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
|
||||
#define AIU_RST_SOFT_958_FAST BIT(2)
|
||||
|
||||
#define AIU_FIFO_SPDIF_BLOCK 8
|
||||
|
||||
|
|
@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
snd_soc_component_write(component, AIU_RST_SOFT,
|
||||
AIU_RST_SOFT_958_FAST);
|
||||
fifo_spdif_dcu_enable(component, true);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
snd_soc_component_write(component, AIU_RST_SOFT,
|
||||
AIU_RST_SOFT_958_FAST);
|
||||
fifo_spdif_dcu_enable(component, false);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id snd_sc8280xp_dt_match[] = {
|
||||
{.compatible = "qcom,eliza-sndcard", "eliza"},
|
||||
{.compatible = "qcom,kaanapali-sndcard", "kaanapali"},
|
||||
{.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
|
||||
{.compatible = "qcom,qcs615-sndcard", "qcs615"},
|
||||
|
|
|
|||
|
|
@ -2237,6 +2237,7 @@ static const struct sun4i_codec_quirks sun50i_h616_codec_quirks = {
|
|||
.reg_dac_fifoc = REG_FIELD(SUN50I_H616_CODEC_DAC_FIFOC, 0, 31),
|
||||
.reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA,
|
||||
.has_reset = true,
|
||||
.playback_only = true,
|
||||
.dma_max_burst = SUN4I_DMA_MAX_BURST,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -167,10 +167,9 @@ static int tegra20_das_probe(struct platform_device *pdev)
|
|||
|
||||
das->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
|
||||
&tegra20_das_regmap_config);
|
||||
if (IS_ERR(das->regmap)) {
|
||||
dev_err(&pdev->dev, "regmap init failed\n");
|
||||
return PTR_ERR(das->regmap);
|
||||
}
|
||||
if (IS_ERR(das->regmap))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(das->regmap),
|
||||
"regmap init failed\n");
|
||||
|
||||
tegra20_das_connect_dap_to_dac(das, TEGRA20_DAS_DAP_ID_1,
|
||||
TEGRA20_DAS_DAP_SEL_DAC1);
|
||||
|
|
|
|||
|
|
@ -496,16 +496,12 @@ static struct snd_kcontrol_new tegra264_adx_controls[] = {
|
|||
static int tegra210_adx_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct tegra210_adx *adx = snd_soc_component_get_drvdata(component);
|
||||
int err = 0;
|
||||
|
||||
if (adx->soc_data->num_controls) {
|
||||
err = snd_soc_add_component_controls(component, adx->soc_data->controls,
|
||||
adx->soc_data->num_controls);
|
||||
if (err)
|
||||
dev_err(component->dev, "can't add ADX controls, err: %d\n", err);
|
||||
}
|
||||
if (adx->soc_data->num_controls)
|
||||
return snd_soc_add_component_controls(component, adx->soc_data->controls,
|
||||
adx->soc_data->num_controls);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver tegra210_adx_cmpnt = {
|
||||
|
|
|
|||
|
|
@ -504,16 +504,12 @@ static struct snd_kcontrol_new tegra264_amx_controls[] = {
|
|||
static int tegra210_amx_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct tegra210_amx *amx = snd_soc_component_get_drvdata(component);
|
||||
int err = 0;
|
||||
|
||||
if (amx->soc_data->num_controls) {
|
||||
err = snd_soc_add_component_controls(component, amx->soc_data->controls,
|
||||
amx->soc_data->num_controls);
|
||||
if (err)
|
||||
dev_err(component->dev, "can't add AMX controls, err: %d\n", err);
|
||||
}
|
||||
if (amx->soc_data->num_controls)
|
||||
return snd_soc_add_component_controls(component, amx->soc_data->controls,
|
||||
amx->soc_data->num_controls);
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver tegra210_amx_cmpnt = {
|
||||
|
|
|
|||
|
|
@ -1078,13 +1078,13 @@ static int tegra210_i2s_probe(struct platform_device *pdev)
|
|||
"can't retrieve I2S bit clock\n");
|
||||
|
||||
/*
|
||||
* Not an error, as this clock is needed only when some other I/O
|
||||
* requires input clock from current I2S instance, which is
|
||||
* configurable from DT.
|
||||
* This clock is optional and is only needed when another I/O uses
|
||||
* the current I2S instance as its input clock, as configured in DT.
|
||||
*/
|
||||
i2s->clk_sync_input = devm_clk_get(dev, "sync_input");
|
||||
i2s->clk_sync_input = devm_clk_get_optional(dev, "sync_input");
|
||||
if (IS_ERR(i2s->clk_sync_input))
|
||||
dev_dbg(dev, "can't retrieve I2S sync input clock\n");
|
||||
return dev_err_probe(dev, PTR_ERR(i2s->clk_sync_input),
|
||||
"can't retrieve I2S sync input clock\n");
|
||||
|
||||
regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(regs))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user