diff --git a/btfmcodec/btfm_codec_interface.c b/btfmcodec/btfm_codec_interface.c index b23b624225..e6d3d379ba 100644 --- a/btfmcodec/btfm_codec_interface.c +++ b/btfmcodec/btfm_codec_interface.c @@ -4,6 +4,8 @@ */ #include +#include +#include #include "btfm_codec.h" #include "btfm_codec_interface.h" #include "btfm_codec_pkt.h" @@ -676,6 +678,40 @@ static struct snd_soc_dai_ops btfmcodec_dai_ops = { .get_channel_map = btfmcodec_dai_get_channel_map, }; +static int btfmcodec_adsp_ssr_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct btfmcodec_data *btfmcodec = container_of(nb, + struct btfmcodec_data, notifier.nb); + struct btfmcodec_char_device *btfmcodec_dev = btfmcodec->btfmcodec_dev; + struct btm_adsp_state_ind state_ind; + + switch (action) { + case QCOM_SSR_BEFORE_SHUTDOWN: { + BTFMCODEC_WARN("LPASS SSR triggered"); + break; + } case QCOM_SSR_AFTER_SHUTDOWN: { + BTFMCODEC_WARN("LPASS SSR Completed"); + break; + } case QCOM_SSR_BEFORE_POWERUP: { + BTFMCODEC_WARN("LPASS booted up after SSR"); + break; + } case QCOM_SSR_AFTER_POWERUP: { + BTFMCODEC_WARN("LPASS booted up completely"); + state_ind.opcode = BTM_BTFMCODEC_ADSP_STATE_IND; + state_ind.len = BTM_ADSP_STATE_IND_LEN; + state_ind.action = (uint32_t)action; + btfmcodec_dev_enqueue_pkt(btfmcodec_dev, &state_ind, + (state_ind.len + + BTM_HEADER_LEN)); + break; + } default: + BTFMCODEC_WARN("unhandled action id %lu", action); + break; + } + return 0; +} + int btfm_register_codec(struct hwep_data *hwep_info) { struct btfmcodec_data *btfmcodec; @@ -687,6 +723,16 @@ int btfm_register_codec(struct hwep_data *hwep_info) btfmcodec = btfm_get_btfmcodec(); btfmcodec_dev = btfmcodec->btfmcodec_dev; dev = &btfmcodec->dev; + + btfmcodec->notifier.nb.notifier_call = btfmcodec_adsp_ssr_notify; + btfmcodec->notifier.notifier = qcom_register_ssr_notifier("lpass", + &btfmcodec->notifier.nb); + if (IS_ERR(btfmcodec->notifier.notifier)) { + ret = PTR_ERR(btfmcodec->notifier.notifier); + BTFMCODEC_ERR("Failed to register SSR notification: %d\n", ret); + return ret; + } + btfmcodec_dai_info = kzalloc((sizeof(struct snd_soc_dai_driver) * hwep_info->num_dai), GFP_KERNEL); if (!btfmcodec_dai_info) { BTFMCODEC_ERR("failed to allocate memory"); diff --git a/btfmcodec/include/btfm_codec.h b/btfmcodec/include/btfm_codec.h index 2f05639a78..88c7117997 100644 --- a/btfmcodec/include/btfm_codec.h +++ b/btfmcodec/include/btfm_codec.h @@ -86,12 +86,18 @@ struct btfmcodec_char_device { void *btfmcodec; }; +struct adsp_notifier { + void *notifier; + struct notifier_block nb; +}; + struct btfmcodec_data { struct device dev; struct btfmcodec_state_machine states; struct btfmcodec_char_device *btfmcodec_dev; struct hwep_data *hwep_info; struct list_head config_head; + struct adsp_notifier notifier; }; struct btfmcodec_data *btfm_get_btfmcodec(void); diff --git a/btfmcodec/include/btfm_codec_pkt.h b/btfmcodec/include/btfm_codec_pkt.h index 12f604bc60..cc75c2e357 100644 --- a/btfmcodec/include/btfm_codec_pkt.h +++ b/btfmcodec/include/btfm_codec_pkt.h @@ -40,6 +40,7 @@ struct btm_ctrl_pkt { #define BTM_BTFMCODEC_CTRL_MASTER_SHUTDOWN_RSP 0x50000005 #define BTM_BTFMCODEC_BEARER_SWITCH_IND 0x58000001 #define BTM_BTFMCODEC_TRANSPORT_SWITCH_FAILED_IND 0x58000002 +#define BTM_BTFMCODEC_ADSP_STATE_IND 0x58000003 #define BTM_BTFMCODEC_CTRL_LOG_LVL_IND 0x58000004 #define BTM_MASTER_CONFIG_REQ_LEN 13 @@ -51,6 +52,7 @@ struct btm_ctrl_pkt { #define BTM_PREPARE_AUDIO_BEARER_SWITCH_REQ_LEN 1 #define BTM_BEARER_SWITCH_IND_LEN 1 #define BTM_LOG_LVL_IND_LEN 1 +#define BTM_ADSP_STATE_IND_LEN 4 enum rx_status { /* Waiting for response */ @@ -94,6 +96,13 @@ struct btm_master_shutdown_req { uint32_t len; uint8_t stream_id; }__attribute__((packed)); + +struct btm_adsp_state_ind { + btm_opcode opcode; + uint32_t len; + uint32_t action; +} __attribute__((packed)); + int btfmcodec_dev_enqueue_pkt(struct btfmcodec_char_device *, void *, int); bool btfmcodec_is_valid_cache_avb(struct btfmcodec_data *); #endif /* __LINUX_BTFM_CODEC_PKT_H*/