mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Use the SoundWire link number and device unique ID as the firmware file qualifier suffix on CS35L56 B0 if .bin files are not found with the older suffix. Some changes in wm_adsp needed to support this have been included in this patch because they are trivial. The allows future products with CS35L56 B0 silicon to use the same firmware file naming as CS35L57 and cs35L63, while retaining backward compatibility for firmware that has already been published with the old naming scheme. The old suffix is searched first, partly because there are already many files using that naming scheme, but also because they are a smaller subset of all the possible fallback name options offered by wm_adsp so we know that it will either find the qualified files or fail. All the firmware files already published have the wmfw qualified with only the ACPI SSID and the bin files qualified with both SSID and the suffix. Originally, the firmware file names indicated which amplifier instance they were for by appending the ALSA prefix string. This is the standard ASoC way of distinguishing different instances of the same device. However, on SoundWire systems the SoundWire physical unique address is available as a unique identifier for each amp, and this address is hardwired by the address pin on the amp. The firmware files are specific for each physical amp so they must be applied to that amp. Using the ALSA prefix for the filename qualifier means that to name a firmware file it must be determined what prefix string the machine driver will assign to each device and then use that to name the firmware file correctly. This is straightforward in traditional ASoC systems where the machine driver is specific to a particular piece of hardware. But on SoundWire the machine driver is generic and can handle a very wide range of hardware. It is more difficult to determine exactly what the prefix will be on any particular production device, and more prone to mistakes. Also, when the machine driver switches to generating this automatically from SDCA properties in ACPI, there is an additional layer of complexity in determining the mapping. This uncertainty is unnecessary because the firmware is built for a specific amp. with known address, so we can use that directly instead of introducing a redundant intermediate alias. This ensures the firmware is applied to the amp it was intended for. There are already many published firmware for CS35L56 B0 silicon so this first looks for the original name suffix, to keep backward compatibility. If this doesn't find .bin files it will switch to using the new name suffix so that future products using CS35L56 B0 can start to use the new suffix. Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Link: https://patch.msgid.link/20250612121428.1667-3-rf@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
74 lines
2.1 KiB
C
74 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Driver for Cirrus Logic CS35L56 smart amp
|
|
*
|
|
* Copyright (C) 2023 Cirrus Logic, Inc. and
|
|
* Cirrus Logic International Semiconductor Ltd.
|
|
*/
|
|
|
|
#ifndef CS35L56_H
|
|
#define CS35L56_H
|
|
|
|
#include <linux/completion.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/workqueue.h>
|
|
#include <sound/cs35l56.h>
|
|
#include "wm_adsp.h"
|
|
|
|
#define CS35L56_SDW_GEN_INT_STAT_1 0xc0
|
|
#define CS35L56_SDW_GEN_INT_MASK_1 0xc1
|
|
#define CS35L56_SDW_INT_MASK_CODEC_IRQ BIT(0)
|
|
|
|
#define CS35L56_SDW_INVALID_BUS_SCALE 0xf
|
|
|
|
#define CS35L56_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
|
|
#define CS35L56_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE \
|
|
| SNDRV_PCM_FMTBIT_S32_LE)
|
|
|
|
#define CS35L56_RATES (SNDRV_PCM_RATE_48000)
|
|
|
|
struct sdw_slave;
|
|
|
|
struct cs35l56_private {
|
|
struct wm_adsp dsp; /* must be first member */
|
|
struct cs35l56_base base;
|
|
struct work_struct dsp_work;
|
|
struct workqueue_struct *dsp_wq;
|
|
struct snd_soc_component *component;
|
|
struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES];
|
|
struct sdw_slave *sdw_peripheral;
|
|
const char *fallback_fw_suffix;
|
|
struct work_struct sdw_irq_work;
|
|
bool sdw_irq_no_unmask;
|
|
bool soft_resetting;
|
|
bool sdw_attached;
|
|
struct completion init_completion;
|
|
|
|
int speaker_id;
|
|
u32 rx_mask;
|
|
u32 tx_mask;
|
|
u8 asp_slot_width;
|
|
u8 asp_slot_count;
|
|
bool tdm_mode;
|
|
bool sysclk_set;
|
|
u8 old_sdw_clock_scale;
|
|
u8 sdw_link_num;
|
|
u8 sdw_unique_id;
|
|
};
|
|
|
|
extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi;
|
|
|
|
int cs35l56_system_suspend(struct device *dev);
|
|
int cs35l56_system_suspend_late(struct device *dev);
|
|
int cs35l56_system_suspend_no_irq(struct device *dev);
|
|
int cs35l56_system_resume_no_irq(struct device *dev);
|
|
int cs35l56_system_resume_early(struct device *dev);
|
|
int cs35l56_system_resume(struct device *dev);
|
|
irqreturn_t cs35l56_irq(int irq, void *data);
|
|
int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq);
|
|
int cs35l56_common_probe(struct cs35l56_private *cs35l56);
|
|
int cs35l56_init(struct cs35l56_private *cs35l56);
|
|
void cs35l56_remove(struct cs35l56_private *cs35l56);
|
|
|
|
#endif /* ifndef CS35L56_H */
|