blob: 1ecacf8677b289246f7adbaa1526cfdd87281090 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022 MediaTek Inc.
* Author: yiwen chiou<yiwen.chiou@mediatek.com
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include "../common/mtk-afe-fe-dai.h"
#include "../common/mtk-base-afe.h"
#include "mt6983-afe-cm.h"
#include "mt6983-afe-common.h"
static int mtk_convert_cm_rate(unsigned int rate)
{
switch (rate) {
case MTK_AFE_RATE_8K:
case MTK_AFE_RATE_11K:
case MTK_AFE_RATE_12K:
case MTK_AFE_RATE_384K:
case MTK_AFE_RATE_16K:
case MTK_AFE_RATE_22K:
case MTK_AFE_RATE_24K:
case MTK_AFE_RATE_32K:
case MTK_AFE_RATE_44K:
case MTK_AFE_RATE_48K:
case MTK_AFE_RATE_88K:
case MTK_AFE_RATE_96K:
case MTK_AFE_RATE_176K:
case MTK_AFE_RATE_192K:
return rate;
case MTK_AFE_RATE_352K:
case MTK_AFE_RATE_260K:
default:
return 0;
}
return 0;
}
static int mtk_convert_cm_ch(unsigned int ch)
{
return ch - 1;
}
int mtk_set_cm(struct mtk_base_afe *afe, int id, unsigned int rate,
unsigned int update, bool swap, unsigned int ch)
{
int cm_reg = 0;
int cm_rate_mask = 0;
int cm_update_mask = 0;
int cm_swap_mask = 0;
int cm_ch_mask = 0;
int cm_rate_shift = 0;
int cm_update_shift = 0;
int cm_swap_shift = 0;
int cm_ch_shift = 0;
pr_info("%s()-0, CM%d, rate %d, update %d, swap %d, ch %d\n",
__func__, id+1, rate, update, swap, ch);
cm_rate_mask = AFE_CM_1X_EN_SEL_FS_MASK;
cm_rate_shift = AFE_CM_1X_EN_SEL_FS;
cm_update_mask = AFE_CM_UPDATE_CNT_MASK;
cm_update_shift = AFE_CM_UPDATE_CNT;
cm_swap_mask = AFE_CM_BYTE_SWAP_MASK;
cm_swap_shift = AFE_CM_BYTE_SWAP;
cm_ch_mask = AFE_CM_CH_NUM_MASK;
cm_ch_shift = AFE_CM_CH_NUM;
switch (id) {
case CM1:
cm_reg = AFE_CM1_CON0;
break;
case CM2:
cm_reg = AFE_CM2_CON0;
break;
default:
pr_info("%s(), CM%d not found\n", __func__, id+1);
return 0;
}
/* update cnt */
mtk_regmap_update_bits(afe->regmap, cm_reg,
cm_update_mask, update, cm_update_shift);
/* rate */
rate = mtk_convert_cm_rate(rate);
mtk_regmap_update_bits(afe->regmap, cm_reg,
cm_rate_mask, rate, cm_rate_shift);
/* ch num */
ch = mtk_convert_cm_ch(ch);
mtk_regmap_update_bits(afe->regmap, cm_reg,
cm_ch_mask, ch, cm_ch_shift);
/* swap */
mtk_regmap_update_bits(afe->regmap, cm_reg,
cm_swap_mask, swap, cm_swap_shift);
pr_info("%s()-1, CM%d, rate %d, update %d, swap %d, ch %d\n",
__func__, id+1, rate, update, swap, ch);
return 0;
}
EXPORT_SYMBOL_GPL(mtk_set_cm);
mtk_enable_cm_bypass(struct mtk_base_afe *afe, int id, bool en1, bool en2)
{
int cm_reg = 0;
int cm_on1_mask = 0, cm_on2_mask = 0;
int cm_on1_shift = 0, cm_on2_shift = 0;
pr_info("%s, CM%d, en %d/%d\n", __func__, id+1, en1, en2);
switch (id) {
case CM1:
cm_reg = AFE_CM1_CON0;
cm_on1_mask = AFE_CM1_VUL8_BYPASS_CM_MASK;
cm_on1_shift = AFE_CM1_VUL8_BYPASS_CM;
cm_on2_mask = AFE_CM1_VUL9_BYPASS_CM_MASK;
cm_on2_shift = AFE_CM1_VUL9_BYPASS_CM;
break;
case CM2:
cm_reg = AFE_CM2_CON0;
cm_on1_mask = -1;
cm_on1_shift = -1;
cm_on2_mask = AFE_CM2_AWB2_TINY_BYPASS_CM_MASK;
cm_on2_shift = AFE_CM2_AWB2_TINY_BYPASS_CM;
break;
default:
pr_info("%s(), CM%d not found\n", __func__, id+1);
return 0;
}
if (cm_on1_shift > 0)
mtk_regmap_update_bits(afe->regmap, cm_reg, cm_on1_mask,
en1, cm_on1_shift);
mtk_regmap_update_bits(afe->regmap, cm_reg, cm_on2_mask,
en2, cm_on2_shift);
return 0;
}
EXPORT_SYMBOL_GPL(mtk_enable_cm_bypass);
int mtk_enable_cm(struct mtk_base_afe *afe, int id, bool en)
{
int cm_reg = 0;
int cm_on_mask = 0;
int cm_on_shift = 0;
cm_on_mask = AFE_CM_ON_MASK;
cm_on_shift = AFE_CM_ON;
switch (id) {
case CM1:
cm_reg = AFE_CM1_CON0;
break;
case CM2:
cm_reg = AFE_CM2_CON0;
break;
default:
dev_info(afe->dev, "%s(), CM%d not found\n",
__func__, id+1);
return 0;
}
mtk_regmap_update_bits(afe->regmap, cm_reg, cm_on_mask,
en, cm_on_shift);
return 0;
}
EXPORT_SYMBOL_GPL(mtk_enable_cm);
MODULE_DESCRIPTION("Mediatek afe cm");
MODULE_AUTHOR("yiwen chiou<yiwen.chiou@mediatek.com>");
MODULE_LICENSE("GPL v2");