kernel_samsung_a34x-permissive/sound/soc/mediatek/common_int/mtk-auddrv-afe.c
2024-04-28 15:49:01 +02:00

292 lines
7 KiB
C
Executable file

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
* Author: Michael Hsiao <michael.hsiao@mediatek.com>
*/
/*****************************************************************************
*
* Filename:
* ---------
* mtk-auddrv-afe.c
*
* Project:
* --------
* MT6797 Audio Driver Afe Register setting
*
* Description:
* ------------
* Audio register
*
* Author:
* -------
* Chipeng Chang
*
*----------------------------------------------------------------------------
*
*
*****************************************************************************
*/
/*****************************************************************************
* C O M P I L E R F L A G S
*****************************************************************************/
/*****************************************************************************
* E X T E R N A L R E F E R E N C E S
*****************************************************************************/
#include "mtk-auddrv-common.h"
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/types.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#endif
/*****************************************************************************
* D A T A T Y P E S
*****************************************************************************/
/*****************************************************************************
* FUNCTION IMPLEMENTATION
*****************************************************************************/
/*****************************************************************************
* FUNCTION
* Auddrv_Reg_map
*
* DESCRIPTION
* Auddrv_Reg_map
*
*****************************************************************************
*/
/*
* global variable control
*/
#ifndef CONFIG_FPGA_EARLY_PORTING
static DEFINE_SPINLOCK(clksys_set_reg_lock);
#endif
static const unsigned int SramCaptureOffSet = (16 * 1024);
static const struct regmap_config mtk_afe_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = AFE_MAXLENGTH,
.cache_type = REGCACHE_NONE,
.fast_io = true,
};
/* address for ioremap audio hardware register */
void *AFE_BASE_ADDRESS;
void *AFE_SRAM_ADDRESS;
void *AFE_TOP_ADDRESS;
void *APMIXEDSYS_ADDRESS;
void *CLKSYS_ADDRESS;
struct regmap *pregmap;
int Auddrv_Reg_map(struct device *pdev)
{
int ret = 0;
#ifdef CONFIG_OF
struct device_node *audio_sram_node = NULL;
audio_sram_node =
of_find_compatible_node(NULL, NULL, "mediatek,audio_sram");
pr_debug("%s\n", __func__);
if (!pdev->of_node)
pr_warn("%s invalid of_node\n", __func__);
if (audio_sram_node == NULL)
pr_warn("%s invalid audio_sram_node\n", __func__);
/* mapping AFE reg*/
AFE_BASE_ADDRESS = of_iomap(pdev->of_node, 0);
if (AFE_BASE_ADDRESS == NULL) {
pr_err("AFE_BASE_ADDRESS=0x%p\n", AFE_BASE_ADDRESS);
return -ENODEV;
}
AFE_SRAM_ADDRESS = of_iomap(audio_sram_node, 0);
if (AFE_SRAM_ADDRESS == NULL) {
pr_err("AFE_SRAM_ADDRESS=0x%p\n", AFE_SRAM_ADDRESS);
return -ENODEV;
}
pregmap = devm_regmap_init_mmio(pdev, AFE_BASE_ADDRESS,
&mtk_afe_regmap_config);
if (IS_ERR(pregmap)) {
pr_err("devm_regmap_init_mmio error\n");
return -ENODEV;
}
#else
AFE_BASE_ADDRESS = ioremap_nocache(AUDIO_HW_PHYSICAL_BASE, 0x1000);
AFE_SRAM_ADDRESS = ioremap_nocache(AFE_INTERNAL_SRAM_PHY_BASE,
AFE_INTERNAL_SRAM_SIZE);
#endif
/* temp for hardawre code set 0x1000629c = 0xd */
AFE_TOP_ADDRESS = ioremap_nocache(AUDIO_POWER_TOP, 0x1000);
APMIXEDSYS_ADDRESS = ioremap_nocache(APMIXEDSYS_BASE, 0x1000);
CLKSYS_ADDRESS = ioremap_nocache(AUDIO_CLKCFG_PHYSICAL_BASE, 0x1000);
return ret;
}
unsigned int Get_Afe_Sram_Length(void)
{
return AFE_INTERNAL_SRAM_SIZE;
}
dma_addr_t Get_Afe_Sram_Phys_Addr(void)
{
return (dma_addr_t)AFE_INTERNAL_SRAM_PHY_BASE;
}
dma_addr_t Get_Afe_Sram_Capture_Phys_Addr(void)
{
return (dma_addr_t)(AFE_INTERNAL_SRAM_PHY_BASE + SramCaptureOffSet);
}
void *Get_Afe_SramBase_Pointer()
{
return AFE_SRAM_ADDRESS;
}
void *Get_Afe_SramCaptureBase_Pointer()
{
char *CaptureSramPointer =
(char *)(AFE_SRAM_ADDRESS) + SramCaptureOffSet;
return (void *)CaptureSramPointer;
}
void *Get_Afe_Powertop_Pointer()
{
return AFE_TOP_ADDRESS;
}
/* function to access apmixed sys */
unsigned int GetApmixedCfg(unsigned int offset)
{
long address = (long)((char *)APMIXEDSYS_ADDRESS + offset);
unsigned int *value;
value = (unsigned int *)(address);
return *value;
}
void SetApmixedCfg(unsigned int offset, unsigned int value, unsigned int mask)
{
long address = (long)((char *)APMIXEDSYS_ADDRESS + offset);
unsigned int *AFE_Register = (unsigned int *)address;
unsigned int val_tmp;
val_tmp = GetApmixedCfg(offset);
val_tmp &= (~mask);
val_tmp |= (value & mask);
#ifdef _REG_SYNC_WRITE
mt_reg_sync_writel(val_tmp, AFE_Register);
#else
AFE_Register++;
#endif
}
/* function to access clksys */
unsigned int clksys_get_reg(unsigned int offset)
{
#ifndef CONFIG_FPGA_EARLY_PORTING
long address = (long)((char *)CLKSYS_ADDRESS + offset);
unsigned int *value;
if (CLKSYS_ADDRESS == NULL) {
pr_warn("%s(), CLKSYS_ADDRESS is null\n", __func__);
return 0;
}
value = (unsigned int *)(address);
#if defined(AUD_DEBUG_LOG)
pr_debug("%s(), offset = %x, address = %lx, value = 0x%x\n", __func__,
offset, address, *value);
#endif
return *value;
#else
return 0;
#endif
}
void clksys_set_reg(unsigned int offset, unsigned int value, unsigned int mask)
{
#ifndef CONFIG_FPGA_EARLY_PORTING
long address = (long)((char *)CLKSYS_ADDRESS + offset);
unsigned int *val_addr = (unsigned int *)address;
unsigned int val_tmp;
unsigned long flags = 0;
if (CLKSYS_ADDRESS == NULL) {
pr_warn("%s(), CLKSYS_ADDRESS is null\n", __func__);
return;
}
#if defined(AUD_DEBUG_LOG)
pr_debug("%s(), offset = %x, value = %x, mask = %x\n", __func__, offset,
value, mask);
#endif
spin_lock_irqsave(&clksys_set_reg_lock, flags);
val_tmp = clksys_get_reg(offset);
val_tmp &= (~mask);
val_tmp |= (value & mask);
#ifdef _REG_SYNC_WRITE
mt_reg_sync_writel(val_tmp, val_addr);
#else
val_addr++;
#endif
spin_unlock_irqrestore(&clksys_set_reg_lock, flags);
#endif
}
void Afe_Set_Reg_Val(unsigned int offset, unsigned int value)
{
int ret = 0;
ret = regmap_write(pregmap, offset, value);
if (ret) {
pr_debug("%s(), ret = %d, offset = 0x%x, value = 0x%x\n",
__func__, ret, offset, value);
}
}
EXPORT_SYMBOL(Afe_Set_Reg_Val);
void Afe_Set_Reg(unsigned int offset, unsigned int value, unsigned int mask)
{
int ret = 0;
ret = regmap_update_bits(pregmap, offset, mask, value);
if (ret) {
pr_warn("%s ret = %d offset = 0x%x value = 0x%x mask = 0x%x\n",
__func__, ret, offset, value, mask);
}
}
EXPORT_SYMBOL(Afe_Set_Reg);
unsigned int Afe_Get_Reg(unsigned int offset)
{
unsigned int value = 0;
int ret;
ret = regmap_read(pregmap, offset, &value);
if (ret)
pr_warn("%s ret = %d value = 0x%x mask = 0x%x\n", __func__, ret,
offset, value);
return value;
}
EXPORT_SYMBOL(Afe_Get_Reg);