summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/ti,tas2552.yaml13
-rw-r--r--include/sound/sdca_interrupts.h5
-rw-r--r--sound/soc/amd/acp/acp-sdw-legacy-mach.c24
-rw-r--r--sound/soc/codecs/nau8325.c9
-rw-r--r--sound/soc/intel/avs/board_selection.c9
-rw-r--r--sound/soc/sdca/sdca_class.c34
-rw-r--r--sound/soc/sdca/sdca_class_function.c17
-rw-r--r--sound/soc/sdca/sdca_interrupts.c92
-rw-r--r--sound/soc/sof/intel/hda-pcm.c14
-rw-r--r--sound/soc/sof/intel/hda.c10
-rw-r--r--sound/soc/stm/stm32_sai_sub.c3
11 files changed, 184 insertions, 46 deletions
diff --git a/Documentation/devicetree/bindings/sound/ti,tas2552.yaml b/Documentation/devicetree/bindings/sound/ti,tas2552.yaml
index 10369aa5f0a8..85e3ebd2acd8 100644
--- a/Documentation/devicetree/bindings/sound/ti,tas2552.yaml
+++ b/Documentation/devicetree/bindings/sound/ti,tas2552.yaml
@@ -12,8 +12,8 @@ maintainers:
- Baojun Xu <baojun.xu@ti.com>
description: >
- The TAS2552 can receive its reference clock via MCLK, BCLK, IVCLKIN pin or
- use the internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL,
+ The TAS2552 can receive its reference clock via MCLK, BCLK, IVCLKIN pin or
+ use the internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL,
the PDM reference clock is also selectable: PLL, IVCLKIN, BCLK or MCLK.
For system integration the dt-bindings/sound/tas2552.h header file provides
@@ -34,6 +34,9 @@ properties:
maxItems: 1
description: gpio pin to enable/disable the device
+ '#sound-dai-cells':
+ const: 0
+
required:
- compatible
- reg
@@ -41,7 +44,10 @@ required:
- iovdd-supply
- avdd-supply
-additionalProperties: false
+allOf:
+ - $ref: dai-common.yaml#
+
+unevaluatedProperties: false
examples:
- |
@@ -54,6 +60,7 @@ examples:
audio-codec@41 {
compatible = "ti,tas2552";
reg = <0x41>;
+ #sound-dai-cells = <0>;
vbat-supply = <&reg_vbat>;
iovdd-supply = <&reg_iovdd>;
avdd-supply = <&reg_avdd>;
diff --git a/include/sound/sdca_interrupts.h b/include/sound/sdca_interrupts.h
index 9bcb5d8fd592..a515cc3df097 100644
--- a/include/sound/sdca_interrupts.h
+++ b/include/sound/sdca_interrupts.h
@@ -69,6 +69,8 @@ struct sdca_interrupt_info {
int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *interrupt_info,
int sdca_irq, const char *name, irq_handler_t handler,
void *data);
+void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *interrupt_info,
+ int sdca_irq, const char *name, void *data);
int sdca_irq_data_populate(struct device *dev, struct regmap *function_regmap,
struct snd_soc_component *component,
struct sdca_function_data *function,
@@ -81,6 +83,9 @@ int sdca_irq_populate_early(struct device *dev, struct regmap *function_regmap,
int sdca_irq_populate(struct sdca_function_data *function,
struct snd_soc_component *component,
struct sdca_interrupt_info *info);
+void sdca_irq_cleanup(struct device *dev,
+ struct sdca_function_data *function,
+ struct sdca_interrupt_info *info);
struct sdca_interrupt_info *sdca_irq_allocate(struct device *dev,
struct regmap *regmap, int irq);
diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
index 24e99d8d36ab..0f21e5f64531 100644
--- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
@@ -99,17 +99,33 @@ static const struct dmi_system_id soc_sdw_quirk_table[] = {
.callback = soc_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YW"),
+ DMI_MATCH(DMI_PRODUCT_SKU, "21YW"),
},
- .driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
+ .driver_data = (void *)((ASOC_SDW_CODEC_SPKR) | (ASOC_SDW_ACP_DMIC)),
},
{
.callback = soc_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YX"),
+ DMI_MATCH(DMI_PRODUCT_SKU, "21YX"),
},
- .driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
+ .driver_data = (void *)((ASOC_SDW_CODEC_SPKR) | (ASOC_SDW_ACP_DMIC)),
+ },
+ {
+ .callback = soc_sdw_quirk_cb,
+ .matches = { /* Lenovo P16s G5 AMD */
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_SKU, "21XG"),
+ },
+ .driver_data = (void *)(ASOC_SDW_ACP_DMIC),
+ },
+ {
+ .callback = soc_sdw_quirk_cb,
+ .matches = { /* Lenovo P16s G5 AMD */
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_SKU, "21XH"),
+ },
+ .driver_data = (void *)(ASOC_SDW_ACP_DMIC),
},
{
.callback = soc_sdw_quirk_cb,
diff --git a/sound/soc/codecs/nau8325.c b/sound/soc/codecs/nau8325.c
index e651263a9812..58ef5c493835 100644
--- a/sound/soc/codecs/nau8325.c
+++ b/sound/soc/codecs/nau8325.c
@@ -142,7 +142,7 @@ static bool nau8325_readable_reg(struct device *dev, unsigned int reg)
static bool nau8325_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
- case NAU8325_R00_HARDWARE_RST:
+ case NAU8325_R00_HARDWARE_RST ... NAU8325_R01_SOFTWARE_RST:
case NAU8325_R03_CLK_CTRL ... NAU8325_R06_INT_CLR_STATUS:
case NAU8325_R09_IRQOUT ... NAU8325_R13_DAC_VOLUME:
case NAU8325_R29_DAC_CTRL1 ... NAU8325_R2A_DAC_CTRL2:
@@ -670,6 +670,12 @@ static void nau8325_reset_chip(struct regmap *regmap)
regmap_write(regmap, NAU8325_R00_HARDWARE_RST, 0x0000);
}
+static void nau8325_software_reset(struct regmap *regmap)
+{
+ regmap_write(regmap, NAU8325_R01_SOFTWARE_RST, 0x0000);
+ regmap_write(regmap, NAU8325_R01_SOFTWARE_RST, 0x0000);
+}
+
static void nau8325_init_regs(struct nau8325 *nau8325)
{
struct regmap *regmap = nau8325->regmap;
@@ -856,6 +862,7 @@ static int nau8325_i2c_probe(struct i2c_client *i2c)
nau8325_print_device_properties(nau8325);
nau8325_reset_chip(nau8325->regmap);
+ nau8325_software_reset(nau8325->regmap);
ret = regmap_read(nau8325->regmap, NAU8325_R02_DEVICE_ID, &value);
if (ret) {
dev_dbg(dev, "Failed to read device id (%d)", ret);
diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c
index 8a46285181fa..dd0e7cd5a7dd 100644
--- a/sound/soc/intel/avs/board_selection.c
+++ b/sound/soc/intel/avs/board_selection.c
@@ -520,7 +520,8 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev)
if (num_elems > max_ssps) {
dev_err(adev->dev, "board supports only %d SSP, %d specified\n",
max_ssps, num_elems);
- return -EINVAL;
+ ret = -EINVAL;
+ goto exit;
}
for (ssp_port = 0; ssp_port < num_elems; ssp_port++) {
@@ -528,11 +529,13 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev)
for_each_set_bit(tdm_slot, &tdm_slots, 16) {
ret = avs_register_i2s_test_board(adev, ssp_port, tdm_slot);
if (ret)
- return ret;
+ goto exit;
}
}
- return 0;
+exit:
+ kfree(array);
+ return ret;
}
static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)
diff --git a/sound/soc/sdca/sdca_class.c b/sound/soc/sdca/sdca_class.c
index 7af4e5d1b347..6e9b66f71801 100644
--- a/sound/soc/sdca/sdca_class.c
+++ b/sound/soc/sdca/sdca_class.c
@@ -137,6 +137,13 @@ static const struct regmap_config class_dev_regmap_config = {
.unlock = class_regmap_unlock,
};
+static void class_remove_functions(void *data)
+{
+ struct sdca_class_drv *drv = data;
+
+ sdca_dev_unregister_functions(drv->sdw);
+}
+
static void class_boot_work(struct work_struct *work)
{
struct sdca_class_drv *drv = container_of(work,
@@ -157,6 +164,11 @@ static void class_boot_work(struct work_struct *work)
if (ret)
goto err;
+ /* Ensure function drivers are removed before the IRQ is destroyed */
+ ret = devm_add_action_or_reset(drv->dev, class_remove_functions, drv);
+ if (ret)
+ goto err;
+
dev_dbg(drv->dev, "boot work complete\n");
pm_runtime_mark_last_busy(drv->dev);
@@ -168,15 +180,6 @@ err:
pm_runtime_put_sync(drv->dev);
}
-static void class_dev_remove(void *data)
-{
- struct sdca_class_drv *drv = data;
-
- cancel_work_sync(&drv->boot_work);
-
- sdca_dev_unregister_functions(drv->sdw);
-}
-
static int class_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id)
{
struct device *dev = &sdw->dev;
@@ -230,15 +233,19 @@ static int class_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id
if (ret)
return ret;
- ret = devm_add_action_or_reset(dev, class_dev_remove, drv);
- if (ret)
- return ret;
-
queue_work(system_long_wq, &drv->boot_work);
return 0;
}
+static void class_sdw_remove(struct sdw_slave *sdw)
+{
+ struct device *dev = &sdw->dev;
+ struct sdca_class_drv *drv = dev_get_drvdata(dev);
+
+ cancel_work_sync(&drv->boot_work);
+}
+
static int class_suspend(struct device *dev)
{
struct sdca_class_drv *drv = dev_get_drvdata(dev);
@@ -330,6 +337,7 @@ static struct sdw_driver class_sdw_driver = {
},
.probe = class_sdw_probe,
+ .remove = class_sdw_remove,
.id_table = class_sdw_id,
.ops = &class_sdw_ops,
};
diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c
index c3eb3c23a7db..31fc08d51307 100644
--- a/sound/soc/sdca/sdca_class_function.c
+++ b/sound/soc/sdca/sdca_class_function.c
@@ -198,6 +198,14 @@ static int class_function_component_probe(struct snd_soc_component *component)
return sdca_irq_populate(drv->function, component, core->irq_info);
}
+static void class_function_component_remove(struct snd_soc_component *component)
+{
+ struct class_function_drv *drv = snd_soc_component_get_drvdata(component);
+ struct sdca_class_drv *core = drv->core;
+
+ sdca_irq_cleanup(component->dev, drv->function, core->irq_info);
+}
+
static int class_function_set_jack(struct snd_soc_component *component,
struct snd_soc_jack *jack, void *d)
{
@@ -209,6 +217,7 @@ static int class_function_set_jack(struct snd_soc_component *component,
static const struct snd_soc_component_driver class_function_component_drv = {
.probe = class_function_component_probe,
+ .remove = class_function_component_remove,
.endianness = 1,
};
@@ -408,6 +417,13 @@ static int class_function_probe(struct auxiliary_device *auxdev,
return 0;
}
+static void class_function_remove(struct auxiliary_device *auxdev)
+{
+ struct class_function_drv *drv = auxiliary_get_drvdata(auxdev);
+
+ sdca_irq_cleanup(drv->dev, drv->function, drv->core->irq_info);
+}
+
static int class_function_runtime_suspend(struct device *dev)
{
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
@@ -560,6 +576,7 @@ static struct auxiliary_driver class_function_drv = {
},
.probe = class_function_probe,
+ .remove = class_function_remove,
.id_table = class_function_id_table
};
module_auxiliary_driver(class_function_drv);
diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c
index 95b1ab4ba1b0..3d7eb1996724 100644
--- a/sound/soc/sdca/sdca_interrupts.c
+++ b/sound/soc/sdca/sdca_interrupts.c
@@ -117,9 +117,7 @@ static irqreturn_t function_status_handler(int irq, void *data)
status = val;
for_each_set_bit(mask, &status, BITS_PER_BYTE) {
- mask = 1 << mask;
-
- switch (mask) {
+ switch (BIT(mask)) {
case SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION:
//FIXME: Add init writes
break;
@@ -140,7 +138,7 @@ static irqreturn_t function_status_handler(int irq, void *data)
}
}
- ret = regmap_write(interrupt->function_regmap, reg, val);
+ ret = regmap_write(interrupt->function_regmap, reg, val & 0x7F);
if (ret < 0) {
dev_err(dev, "failed to clear function status: %d\n", ret);
goto error;
@@ -252,8 +250,7 @@ static int sdca_irq_request_locked(struct device *dev,
if (irq < 0)
return irq;
- ret = devm_request_threaded_irq(dev, irq, NULL, handler,
- IRQF_ONESHOT, name, data);
+ ret = request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, name, data);
if (ret)
return ret;
@@ -264,6 +261,22 @@ static int sdca_irq_request_locked(struct device *dev,
return 0;
}
+static void sdca_irq_free_locked(struct device *dev, struct sdca_interrupt_info *info,
+ int sdca_irq, const char *name, void *data)
+{
+ int irq;
+
+ irq = regmap_irq_get_virq(info->irq_data, sdca_irq);
+ if (irq < 0)
+ return;
+
+ free_irq(irq, data);
+
+ info->irqs[sdca_irq].irq = 0;
+
+ dev_dbg(dev, "freed irq %d for %s\n", irq, name);
+}
+
/**
* sdca_irq_request - request an individual SDCA interrupt
* @dev: Pointer to the struct device against which things should be allocated.
@@ -303,6 +316,30 @@ int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *info,
EXPORT_SYMBOL_NS_GPL(sdca_irq_request, "SND_SOC_SDCA");
/**
+ * sdca_irq_free - free an individual SDCA interrupt
+ * @dev: Pointer to the struct device.
+ * @info: Pointer to the interrupt information structure.
+ * @sdca_irq: SDCA interrupt position.
+ * @name: Name to be given to the IRQ.
+ * @data: Private data pointer that will be passed to the handler.
+ *
+ * Typically this is handled internally by sdca_irq_cleanup, however if
+ * a device requires custom IRQ handling this can be called manually before
+ * calling sdca_irq_cleanup, which will then skip that IRQ whilst processing.
+ */
+void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *info,
+ int sdca_irq, const char *name, void *data)
+{
+ if (sdca_irq < 0 || sdca_irq >= SDCA_MAX_INTERRUPTS)
+ return;
+
+ guard(mutex)(&info->irq_lock);
+
+ sdca_irq_free_locked(dev, info, sdca_irq, name, data);
+}
+EXPORT_SYMBOL_NS_GPL(sdca_irq_free, "SND_SOC_SDCA");
+
+/**
* sdca_irq_data_populate - Populate common interrupt data
* @dev: Pointer to the Function device.
* @regmap: Pointer to the Function regmap.
@@ -328,8 +365,8 @@ int sdca_irq_data_populate(struct device *dev, struct regmap *regmap,
if (!dev)
return -ENODEV;
- name = devm_kasprintf(dev, GFP_KERNEL, "%s %s %s", function->desc->name,
- entity->label, control->label);
+ name = kasprintf(GFP_KERNEL, "%s %s %s", function->desc->name,
+ entity->label, control->label);
if (!name)
return -ENOMEM;
@@ -517,6 +554,35 @@ int sdca_irq_populate(struct sdca_function_data *function,
EXPORT_SYMBOL_NS_GPL(sdca_irq_populate, "SND_SOC_SDCA");
/**
+ * sdca_irq_cleanup - Free all the individual IRQs for an SDCA Function
+ * @dev: Device pointer against which the sdca_interrupt_info was allocated.
+ * @function: Pointer to the SDCA Function.
+ * @info: Pointer to the SDCA interrupt info for this device.
+ *
+ * Typically this would be called from the driver for a single SDCA Function.
+ */
+void sdca_irq_cleanup(struct device *dev,
+ struct sdca_function_data *function,
+ struct sdca_interrupt_info *info)
+{
+ int i;
+
+ guard(mutex)(&info->irq_lock);
+
+ for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
+ struct sdca_interrupt *interrupt = &info->irqs[i];
+
+ if (interrupt->function != function || !interrupt->irq)
+ continue;
+
+ sdca_irq_free_locked(dev, info, i, interrupt->name, interrupt);
+
+ kfree(interrupt->name);
+ }
+}
+EXPORT_SYMBOL_NS_GPL(sdca_irq_cleanup, "SND_SOC_SDCA");
+
+/**
* sdca_irq_allocate - allocate an SDCA interrupt structure for a device
* @sdev: Device pointer against which things should be allocated.
* @regmap: regmap to be used for accessing the SDCA IRQ registers.
@@ -564,13 +630,12 @@ EXPORT_SYMBOL_NS_GPL(sdca_irq_allocate, "SND_SOC_SDCA");
static void irq_enable_flags(struct sdca_function_data *function,
struct sdca_interrupt_info *info, bool early)
{
- struct sdca_interrupt *interrupt;
int i;
for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
- interrupt = &info->irqs[i];
+ struct sdca_interrupt *interrupt = &info->irqs[i];
- if (!interrupt || interrupt->function != function)
+ if (!interrupt->irq || interrupt->function != function)
continue;
switch (SDCA_CTL_TYPE(interrupt->entity->type,
@@ -623,13 +688,12 @@ EXPORT_SYMBOL_NS_GPL(sdca_irq_enable, "SND_SOC_SDCA");
void sdca_irq_disable(struct sdca_function_data *function,
struct sdca_interrupt_info *info)
{
- struct sdca_interrupt *interrupt;
int i;
for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
- interrupt = &info->irqs[i];
+ struct sdca_interrupt *interrupt = &info->irqs[i];
- if (!interrupt || interrupt->function != function)
+ if (!interrupt->irq || interrupt->function != function)
continue;
disable_irq(interrupt->irq);
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index da6c1e7263cd..16a364072821 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -219,6 +219,7 @@ EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
+ const struct sof_intel_dsp_desc *chip_info = get_chip_info(sdev->pdata);
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_component *scomp = sdev->component;
@@ -268,8 +269,17 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
return -ENODEV;
}
- /* minimum as per HDA spec */
- snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
+ /*
+ * Set period size constraint to ensure BDLE buffer length and
+ * start address alignment requirements are met. Align to 128
+ * bytes for newer Intel platforms, with older ones using 4 byte alignment.
+ */
+ if (chip_info->hw_ip_version >= SOF_INTEL_ACE_4_0)
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
+ else
+ snd_pcm_hw_constraint_step(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
/* avoid circular buffer wrap in middle of period */
snd_pcm_hw_constraint_integer(substream->runtime,
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index edb80c2fa770..b3d61d973ce4 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -1133,8 +1133,7 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
-static bool is_endpoint_present(struct sdw_slave *sdw_device,
- struct asoc_sdw_codec_info *dai_info, int dai_type)
+static bool is_endpoint_present(struct sdw_slave *sdw_device, int dai_type)
{
int i;
@@ -1145,7 +1144,7 @@ static bool is_endpoint_present(struct sdw_slave *sdw_device,
}
for (i = 0; i < sdw_device->sdca_data.num_functions; i++) {
- if (dai_type == dai_info->dais[i].dai_type)
+ if (dai_type == asoc_sdw_get_dai_type(sdw_device->sdca_data.function[i].type))
return true;
}
dev_dbg(&sdw_device->dev, "Endpoint DAI type %d not found\n", dai_type);
@@ -1202,11 +1201,10 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev,
}
for (j = 0; j < codec_info_list[i].dai_num; j++) {
/* Check if the endpoint is present by the SDCA DisCo table */
- if (!is_endpoint_present(sdw_device, &codec_info_list[i],
- codec_info_list[i].dais[j].dai_type))
+ if (!is_endpoint_present(sdw_device, codec_info_list[i].dais[j].dai_type))
continue;
- endpoints[ep_index].num = ep_index;
+ endpoints[ep_index].num = j;
if (codec_info_list[i].dais[j].dai_type == SOC_SDW_DAI_TYPE_AMP) {
/* Assume all amp are aggregated */
endpoints[ep_index].aggregated = 1;
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 450e1585edee..3e82fa90e719 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -802,6 +802,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
break;
/* Left justified */
case SND_SOC_DAIFMT_MSB:
+ cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
break;
/* Right justified */
@@ -809,9 +810,11 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
break;
case SND_SOC_DAIFMT_DSP_A:
+ cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF;
break;
case SND_SOC_DAIFMT_DSP_B:
+ cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL;
break;
default: