mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
ASoC: cs35l56: Add control to read CAL_SET_STATUS
Create an ALSA control to read the value of the firmware CAL_SET_STATUS control. This reports whether the firmware is using a calibration blob or the default calibration from the .bin file. The firmware only reports a valid value in this register while audio is actually playing and the internal PLL is locked to the audio clock. Otherwise it returns a status of "unknown". Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Link: https://patch.msgid.link/20251111130850.513969-2-rf@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
committed by
Mark Brown
parent
772ada5028
commit
69f3474a01
@@ -16,6 +16,8 @@
|
||||
#include <linux/spi/spi.h>
|
||||
#include <sound/cs-amp-lib.h>
|
||||
|
||||
struct snd_ctl_elem_value;
|
||||
|
||||
#define CS35L56_DEVID 0x0000000
|
||||
#define CS35L56_REVID 0x0000004
|
||||
#define CS35L56_RELID 0x000000C
|
||||
@@ -268,6 +270,10 @@
|
||||
#define CS35L56_CAL_STATUS_SUCCESS 1
|
||||
#define CS35L56_CAL_STATUS_OUT_OF_RANGE 3
|
||||
|
||||
#define CS35L56_CAL_SET_STATUS_UNKNOWN 0
|
||||
#define CS35L56_CAL_SET_STATUS_DEFAULT 1
|
||||
#define CS35L56_CAL_SET_STATUS_SET 2
|
||||
|
||||
#define CS35L56_CONTROL_PORT_READY_US 2200
|
||||
#define CS35L56_HALO_STATE_POLL_US 1000
|
||||
#define CS35L56_HALO_STATE_TIMEOUT_US 250000
|
||||
@@ -363,6 +369,7 @@ extern const struct regmap_config cs35l63_regmap_i2c;
|
||||
extern const struct regmap_config cs35l63_regmap_sdw;
|
||||
|
||||
extern const struct cirrus_amp_cal_controls cs35l56_calibration_controls;
|
||||
extern const char * const cs35l56_cal_set_status_text[3];
|
||||
|
||||
extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
|
||||
extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
|
||||
@@ -396,6 +403,8 @@ ssize_t cs35l56_cal_data_debugfs_write(struct cs35l56_base *cs35l56_base,
|
||||
void cs35l56_create_cal_debugfs(struct cs35l56_base *cs35l56_base,
|
||||
const struct cs35l56_cal_debugfs_fops *fops);
|
||||
void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base);
|
||||
int cs35l56_cal_set_status_get(struct cs35l56_base *cs35l56_base,
|
||||
struct snd_ctl_elem_value *uvalue);
|
||||
int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
|
||||
bool *fw_missing, unsigned int *fw_version);
|
||||
void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
|
||||
|
||||
@@ -1262,6 +1262,54 @@ void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs35l56_remove_cal_debugfs, "SND_SOC_CS35L56_SHARED");
|
||||
|
||||
const char * const cs35l56_cal_set_status_text[] = {
|
||||
"Unknown", "Default", "Set",
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(cs35l56_cal_set_status_text, "SND_SOC_CS35L56_SHARED");
|
||||
|
||||
int cs35l56_cal_set_status_get(struct cs35l56_base *cs35l56_base,
|
||||
struct snd_ctl_elem_value *uvalue)
|
||||
{
|
||||
struct cs_dsp *dsp = cs35l56_base->dsp;
|
||||
__be32 cal_set_status_be;
|
||||
int alg_id;
|
||||
int ret;
|
||||
|
||||
switch (cs35l56_base->type) {
|
||||
case 0x54:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
alg_id = 0x9f210;
|
||||
break;
|
||||
default:
|
||||
alg_id = 0xbf210;
|
||||
break;
|
||||
}
|
||||
|
||||
scoped_guard(mutex, &dsp->pwr_lock) {
|
||||
ret = cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(dsp,
|
||||
"CAL_SET_STATUS",
|
||||
WMFW_ADSP2_YM, alg_id),
|
||||
0, &cal_set_status_be,
|
||||
sizeof(cal_set_status_be));
|
||||
}
|
||||
if (ret) {
|
||||
uvalue->value.enumerated.item[0] = CS35L56_CAL_SET_STATUS_UNKNOWN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (be32_to_cpu(cal_set_status_be)) {
|
||||
case CS35L56_CAL_SET_STATUS_DEFAULT:
|
||||
case CS35L56_CAL_SET_STATUS_SET:
|
||||
uvalue->value.enumerated.item[0] = be32_to_cpu(cal_set_status_be);
|
||||
return 0;
|
||||
default:
|
||||
uvalue->value.enumerated.item[0] = CS35L56_CAL_SET_STATUS_UNKNOWN;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs35l56_cal_set_status_get, "SND_SOC_CS35L56_SHARED");
|
||||
|
||||
int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
|
||||
bool *fw_missing, unsigned int *fw_version)
|
||||
{
|
||||
|
||||
@@ -66,6 +66,18 @@ static int cs35l56_dspwait_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
|
||||
static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cs35l56_cal_set_status_enum, SND_SOC_NOPM, 0,
|
||||
cs35l56_cal_set_status_text);
|
||||
|
||||
static int cs35l56_cal_set_status_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return cs35l56_cal_set_status_get(&cs35l56->base, ucontrol);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new cs35l56_controls[] = {
|
||||
SOC_SINGLE_EXT("Speaker Switch",
|
||||
CS35L56_MAIN_RENDER_USER_MUTE, 0, 1, 1,
|
||||
@@ -83,6 +95,8 @@ static const struct snd_kcontrol_new cs35l56_controls[] = {
|
||||
SOC_SINGLE_EXT("Posture Number", CS35L56_MAIN_POSTURE_NUMBER,
|
||||
0, 255, 0,
|
||||
cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw),
|
||||
SOC_ENUM_EXT("CAL_SET_STATUS", cs35l56_cal_set_status_enum,
|
||||
cs35l56_cal_set_status_ctl_get, NULL),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new cs35l63_controls[] = {
|
||||
@@ -102,6 +116,8 @@ static const struct snd_kcontrol_new cs35l63_controls[] = {
|
||||
SOC_SINGLE_EXT("Posture Number", CS35L63_MAIN_POSTURE_NUMBER,
|
||||
0, 255, 0,
|
||||
cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw),
|
||||
SOC_ENUM_EXT("CAL_SET_STATUS", cs35l56_cal_set_status_enum,
|
||||
cs35l56_cal_set_status_ctl_get, NULL),
|
||||
};
|
||||
|
||||
static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx1_enum,
|
||||
|
||||
Reference in New Issue
Block a user