253 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// MediaTek ALSA SoC Audio Misc Control4//5// Copyright (c) 2022 MediaTek Inc.6// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>7 8#include <linux/delay.h>9#include <linux/dma-mapping.h>10#include <linux/io.h>11#include <linux/regmap.h>12#include <sound/soc.h>13 14#include "../common/mtk-afe-fe-dai.h"15#include "../common/mtk-afe-platform-driver.h"16#include "mt8186-afe-common.h"17 18static const char * const mt8186_sgen_mode_str[] = {19 "I0I1", "I2", "I3I4", "I5I6",20 "I7I8", "I9I22", "I10I11", "I12I13",21 "I14I21", "I15I16", "I17I18", "I19I20",22 "I23I24", "I25I26", "I27I28", "I33",23 "I34I35", "I36I37", "I38I39", "I40I41",24 "I42I43", "I44I45", "I46I47", "I48I49",25 "I56I57", "I58I59", "I60I61", "I62I63",26 "O0O1", "O2", "O3O4", "O5O6",27 "O7O8", "O9O10", "O11", "O12",28 "O13O14", "O15O16", "O17O18", "O19O20",29 "O21O22", "O23O24", "O25", "O28O29",30 "O34", "O35", "O32O33", "O36O37",31 "O38O39", "O30O31", "O40O41", "O42O43",32 "O44O45", "O46O47", "O48O49", "O50O51",33 "O58O59", "O60O61", "O62O63", "O64O65",34 "O66O67", "O68O69", "O26O27", "OFF",35};36 37static const int mt8186_sgen_mode_idx[] = {38 0, 2, 4, 6,39 8, 22, 10, 12,40 14, -1, 18, 20,41 24, 26, 28, 33,42 34, 36, 38, 40,43 42, 44, 46, 48,44 56, 58, 60, 62,45 128, 130, 132, 134,46 135, 138, 139, 140,47 142, 144, 166, 148,48 150, 152, 153, 156,49 162, 163, 160, 164,50 166, -1, 168, 170,51 172, 174, 176, 178,52 186, 188, 190, 192,53 194, 196, -1, -1,54};55 56static const char * const mt8186_sgen_rate_str[] = {57 "8K", "11K", "12K", "16K",58 "22K", "24K", "32K", "44K",59 "48K", "88k", "96k", "176k",60 "192k"61};62 63static const int mt8186_sgen_rate_idx[] = {64 0, 1, 2, 4,65 5, 6, 8, 9,66 10, 11, 12, 13,67 1468};69 70/* this order must match reg bit amp_div_ch1/2 */71static const char * const mt8186_sgen_amp_str[] = {72 "1/128", "1/64", "1/32", "1/16", "1/8", "1/4", "1/2", "1" };73 74static int mt8186_sgen_get(struct snd_kcontrol *kcontrol,75 struct snd_ctl_elem_value *ucontrol)76{77 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);78 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);79 struct mt8186_afe_private *afe_priv = afe->platform_priv;80 81 ucontrol->value.integer.value[0] = afe_priv->sgen_mode;82 83 return 0;84}85 86static int mt8186_sgen_set(struct snd_kcontrol *kcontrol,87 struct snd_ctl_elem_value *ucontrol)88{89 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);90 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);91 struct mt8186_afe_private *afe_priv = afe->platform_priv;92 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;93 int mode;94 int mode_idx;95 96 if (ucontrol->value.enumerated.item[0] >= e->items)97 return -EINVAL;98 99 mode = ucontrol->value.integer.value[0];100 mode_idx = mt8186_sgen_mode_idx[mode];101 102 dev_dbg(afe->dev, "%s(), mode %d, mode_idx %d\n",103 __func__, mode, mode_idx);104 105 if (mode == afe_priv->sgen_mode)106 return 0;107 108 if (mode_idx >= 0) {109 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,110 INNER_LOOP_BACK_MODE_MASK_SFT,111 mode_idx << INNER_LOOP_BACK_MODE_SFT);112 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,113 DAC_EN_MASK_SFT, BIT(DAC_EN_SFT));114 } else {115 /* disable sgen */116 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,117 DAC_EN_MASK_SFT, 0);118 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,119 INNER_LOOP_BACK_MODE_MASK_SFT,120 0x3f << INNER_LOOP_BACK_MODE_SFT);121 }122 123 afe_priv->sgen_mode = mode;124 125 return 1;126}127 128static int mt8186_sgen_rate_get(struct snd_kcontrol *kcontrol,129 struct snd_ctl_elem_value *ucontrol)130{131 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);132 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);133 struct mt8186_afe_private *afe_priv = afe->platform_priv;134 135 ucontrol->value.integer.value[0] = afe_priv->sgen_rate;136 137 return 0;138}139 140static int mt8186_sgen_rate_set(struct snd_kcontrol *kcontrol,141 struct snd_ctl_elem_value *ucontrol)142{143 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);144 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);145 struct mt8186_afe_private *afe_priv = afe->platform_priv;146 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;147 int rate;148 149 if (ucontrol->value.enumerated.item[0] >= e->items)150 return -EINVAL;151 152 rate = ucontrol->value.integer.value[0];153 154 dev_dbg(afe->dev, "%s(), rate %d\n", __func__, rate);155 156 if (rate == afe_priv->sgen_rate)157 return 0;158 159 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,160 SINE_MODE_CH1_MASK_SFT,161 mt8186_sgen_rate_idx[rate] << SINE_MODE_CH1_SFT);162 163 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,164 SINE_MODE_CH2_MASK_SFT,165 mt8186_sgen_rate_idx[rate] << SINE_MODE_CH2_SFT);166 167 afe_priv->sgen_rate = rate;168 169 return 1;170}171 172static int mt8186_sgen_amplitude_get(struct snd_kcontrol *kcontrol,173 struct snd_ctl_elem_value *ucontrol)174{175 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);176 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);177 struct mt8186_afe_private *afe_priv = afe->platform_priv;178 179 ucontrol->value.integer.value[0] = afe_priv->sgen_amplitude;180 return 0;181}182 183static int mt8186_sgen_amplitude_set(struct snd_kcontrol *kcontrol,184 struct snd_ctl_elem_value *ucontrol)185{186 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);187 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);188 struct mt8186_afe_private *afe_priv = afe->platform_priv;189 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;190 int amplitude;191 192 if (ucontrol->value.enumerated.item[0] >= e->items)193 return -EINVAL;194 195 amplitude = ucontrol->value.integer.value[0];196 if (amplitude > AMP_DIV_CH1_MASK) {197 dev_err(afe->dev, "%s(), amplitude %d invalid\n",198 __func__, amplitude);199 return -EINVAL;200 }201 202 dev_dbg(afe->dev, "%s(), amplitude %d\n", __func__, amplitude);203 204 if (amplitude == afe_priv->sgen_amplitude)205 return 0;206 207 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,208 AMP_DIV_CH1_MASK_SFT,209 amplitude << AMP_DIV_CH1_SFT);210 regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,211 AMP_DIV_CH2_MASK_SFT,212 amplitude << AMP_DIV_CH2_SFT);213 214 afe_priv->sgen_amplitude = amplitude;215 216 return 1;217}218 219static const struct soc_enum mt8186_afe_sgen_enum[] = {220 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_mode_str),221 mt8186_sgen_mode_str),222 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_rate_str),223 mt8186_sgen_rate_str),224 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_amp_str),225 mt8186_sgen_amp_str),226};227 228static const struct snd_kcontrol_new mt8186_afe_sgen_controls[] = {229 SOC_ENUM_EXT("Audio_SineGen_Switch", mt8186_afe_sgen_enum[0],230 mt8186_sgen_get, mt8186_sgen_set),231 SOC_ENUM_EXT("Audio_SineGen_SampleRate", mt8186_afe_sgen_enum[1],232 mt8186_sgen_rate_get, mt8186_sgen_rate_set),233 SOC_ENUM_EXT("Audio_SineGen_Amplitude", mt8186_afe_sgen_enum[2],234 mt8186_sgen_amplitude_get, mt8186_sgen_amplitude_set),235 SOC_SINGLE("Audio_SineGen_Mute_Ch1", AFE_SINEGEN_CON0,236 MUTE_SW_CH1_MASK_SFT, MUTE_SW_CH1_MASK, 0),237 SOC_SINGLE("Audio_SineGen_Mute_Ch2", AFE_SINEGEN_CON0,238 MUTE_SW_CH2_MASK_SFT, MUTE_SW_CH2_MASK, 0),239 SOC_SINGLE("Audio_SineGen_Freq_Div_Ch1", AFE_SINEGEN_CON0,240 FREQ_DIV_CH1_SFT, FREQ_DIV_CH1_MASK, 0),241 SOC_SINGLE("Audio_SineGen_Freq_Div_Ch2", AFE_SINEGEN_CON0,242 FREQ_DIV_CH2_SFT, FREQ_DIV_CH2_MASK, 0),243};244 245int mt8186_add_misc_control(struct snd_soc_component *component)246{247 snd_soc_add_component_controls(component,248 mt8186_afe_sgen_controls,249 ARRAY_SIZE(mt8186_afe_sgen_controls));250 251 return 0;252}253