/*
* Copyright (C) 2015 MediaTek Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.
* If not, see .
*/
/****************************************************************************
*
* Filename:
* ---------
* mt_soc_spkprotect_common.c
*
* Project:
* --------
* Audio Driver Kernel Function
*
* Description:
* ------------
* Audio playback
*
* Author:
* -------
* Chipeng Chang
*
*---------------------------------------------------------------------------
*
*
******************************************************************************
*/
#include "mtk-auddrv-scp-spkprotect-common.h"
#include
#include
#include
#include
#ifdef CONFIG_SND_SOC_MTK_SCP_SMARTPA
#include "audio_ipi_client_spkprotect.h"
#include
#include
#include
#endif
static struct aud_spk_message mAud_Spk_Message;
static struct audio_resv_dram_t resv_dram_spkprotect;
static struct spk_dump_ops *mspk_dump_op;
void init_spkscp_reserved_dram(void)
{
/*speaker protection*/
resv_dram_spkprotect.phy_addr =
(char *)scp_get_reserve_mem_phys(SPK_PROTECT_MEM_ID);
resv_dram_spkprotect.vir_addr =
(char *)scp_get_reserve_mem_virt(SPK_PROTECT_MEM_ID);
resv_dram_spkprotect.size =
(uint32_t)scp_get_reserve_mem_size(SPK_PROTECT_MEM_ID);
pr_info("resv_dram: pa %p, va %p, sz 0x%x\n",
resv_dram_spkprotect.phy_addr, resv_dram_spkprotect.vir_addr,
resv_dram_spkprotect.size);
if (audio_ipi_check_scp_status()) {
AUDIO_ASSERT(resv_dram_spkprotect.phy_addr != NULL);
AUDIO_ASSERT(resv_dram_spkprotect.vir_addr != NULL);
AUDIO_ASSERT(resv_dram_spkprotect.size > 0);
}
}
struct audio_resv_dram_t *get_reserved_dram_spkprotect(void)
{
return &resv_dram_spkprotect;
}
char *get_resv_dram_spkprotect_vir_addr(char *resv_dram_phy_addr)
{
uint32_t offset = 0;
offset = resv_dram_phy_addr - resv_dram_spkprotect.phy_addr;
return resv_dram_spkprotect.vir_addr + offset;
}
void spkproc_service_set_spk_dump_message(struct spk_dump_ops *ops)
{
pr_debug("%s\n ", __func__);
if (ops != NULL) {
mspk_dump_op = ops;
mspk_dump_op->spk_dump_callback(NULL);
}
}
void spkproc_service_ipicmd_received(struct ipi_msg_t *ipi_msg)
{
switch (ipi_msg->msg_id) {
case SPK_PROTECT_IRQDL:
mAud_Spk_Message.msg_id = ipi_msg->msg_id;
mAud_Spk_Message.param1 = ipi_msg->param1;
mAud_Spk_Message.param2 = ipi_msg->param2;
mAud_Spk_Message.payload = ipi_msg->payload;
AudDrv_DSP_IRQ_handler((void *)&mAud_Spk_Message);
break;
case SPK_PROTECT_PCMDUMP_OK:
if (mspk_dump_op->spk_dump_callback != NULL)
mspk_dump_op->spk_dump_callback(ipi_msg);
break;
default:
break;
}
}
void spkproc_service_ipicmd_send(uint8_t data_type, uint8_t ack_type,
uint16_t msg_id, uint32_t param1,
uint32_t param2, char *payload)
{
struct ipi_msg_t ipi_msg;
int send_result = 0;
int retry_count;
const int k_max_try_count = 200; /* maximum wait 20ms */
memset((void *)&ipi_msg, 0, sizeof(struct ipi_msg_t));
for (retry_count = 0; retry_count < k_max_try_count; retry_count++) {
if (ack_type == AUDIO_IPI_MSG_DIRECT_SEND)
send_result = audio_send_ipi_msg(
&ipi_msg, TASK_SCENE_SPEAKER_PROTECTION,
AUDIO_IPI_LAYER_KERNEL_TO_SCP_ATOMIC, data_type,
ack_type, msg_id, param1, param2,
(char *)payload);
else
send_result = audio_send_ipi_msg(
&ipi_msg, TASK_SCENE_SPEAKER_PROTECTION,
AUDIO_IPI_LAYER_KERNEL_TO_SCP, data_type,
ack_type, msg_id, param1, param2,
(char *)payload);
if (send_result == 0)
break;
udelay(100);
}
if (send_result < 0) {
pr_err("%s(), scp_ipi send fail\n", __func__);
return;
}
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MediaTek SpkPotect");