Thanks Krzysztof for doing this. On 8/21/25 3:16 PM, Krzysztof Kozlowski wrote: > Speaker Protection is capability of ADSP to adjust the gain during > playback to different speakers and their temperature. This allows good > playback without blowing the speakers up. > > Implement parsing MODULE_ID_SPEAKER_PROTECTION from Audioreach topology > and sending it as command to the ADSP. > > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx> > --- > sound/soc/qcom/qdsp6/audioreach.c | 13 +++++++++++++ > sound/soc/qcom/qdsp6/audioreach.h | 11 +++++++++++ > 2 files changed, 24 insertions(+) > > diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c > index f4c53e84b4dc..b7f1fc835dc2 100644 > --- a/sound/soc/qcom/qdsp6/audioreach.c > +++ b/sound/soc/qcom/qdsp6/audioreach.c > @@ -1250,6 +1250,15 @@ static int audioreach_gain_set(struct q6apm_graph *graph, struct audioreach_modu > return rc; > } > > +static int audioreach_speaker_protection(struct q6apm_graph *graph, > + struct audioreach_module *module, > + uint32_t operation_mode) > +{ > + return audioreach_send_u32_param(graph, module, PARAM_ID_SP_OP_MODE, > + operation_mode); > +} > + > + > int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_module *module, > struct audioreach_module_config *cfg) > { > @@ -1299,6 +1308,10 @@ int audioreach_set_media_format(struct q6apm_graph *graph, struct audioreach_mod > case MODULE_ID_GAPLESS: > rc = audioreach_gapless_set_media_format(graph, module, cfg); > break; > + case MODULE_ID_SPEAKER_PROTECTION: > + rc = audioreach_speaker_protection(graph, module, > + PARAM_ID_SP_OP_MODE_CALIBRATION); Are we leaving this in calibration mode forever? When does the mode change? > + break; > default: > rc = 0; > } > diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h > index 790fba96e34d..0ad566e45e09 100644 > --- a/sound/soc/qcom/qdsp6/audioreach.h > +++ b/sound/soc/qcom/qdsp6/audioreach.h > @@ -31,6 +31,7 @@ struct q6apm_graph; > #define MODULE_ID_MP3_DECODE 0x0700103B > #define MODULE_ID_GAPLESS 0x0700104D > #define MODULE_ID_DISPLAY_PORT_SINK 0x07001069 > +#define MODULE_ID_SPEAKER_PROTECTION 0x070010E2 > > #define APM_CMD_GET_SPF_STATE 0x01001021 > #define APM_CMD_RSP_GET_SPF_STATE 0x02001007 > @@ -542,6 +543,16 @@ struct data_logging_config { > uint32_t mode; > } __packed; > > +/* Speaker Protection */ > +#define PARAM_ID_SP_OP_MODE 0x080011e9 Are we missing #define PARAM_ID_SP_OP_MODE_NORMAL 0 ? > +#define PARAM_ID_SP_OP_MODE_CALIBRATION 1 > +#define PARAM_ID_SP_OP_MODE_FACTORY_TEST 2 > +#define PARAM_ID_SP_OP_MODE_VALIDATION 3 > + > +struct param_id_sp_op_mode { > + uint32_t operation_mode; > +} __packed; > + > #define PARAM_ID_SAL_OUTPUT_CFG 0x08001016 > struct param_id_sal_output_config { > uint32_t bits_per_sample;