#include "rt5645.h"
#define RT5645_DEVICE_ID 0x6308
++ +#define RT5650_DEVICE_ID 0x6419
#define RT5645_PR_RANGE_BASE (0xff + 1)
#define RT5645_PR_SPACING 0x100
};
#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list)
++ +static const struct reg_default rt5650_init_list[] = {
++ + {0xf6, 0x0100},
++ +};
++ +
static const struct reg_default rt5645_reg[] = {
{ 0x00, 0x0000 },
{ 0x01, 0xc8c8 },
{ 0x2a, 0x5656 },
{ 0x2b, 0x5454 },
{ 0x2c, 0xaaa0 },
++ + { 0x2d, 0x0000 },
{ 0x2f, 0x1002 },
{ 0x31, 0x5000 },
{ 0x32, 0x0000 },
{ 0xdb, 0x0003 },
{ 0xdc, 0x0049 },
{ 0xdd, 0x001b },
++ + { 0xdf, 0x0008 },
++ + { 0xe0, 0x4000 },
{ 0xe6, 0x8000 },
{ 0xe7, 0x0200 },
{ 0xec, 0xb300 },
case RT5645_IRQ_CTRL3:
case RT5645_INT_IRQ_ST:
case RT5645_IL_CMD:
++ + case RT5650_4BTN_IL_CMD1:
case RT5645_VENDOR_ID:
case RT5645_VENDOR_ID1:
case RT5645_VENDOR_ID2:
case RT5645_STO_DAC_MIXER:
case RT5645_MONO_DAC_MIXER:
case RT5645_DIG_MIXER:
++ + case RT5650_A_DAC_SOUR:
case RT5645_DIG_INF1_DATA:
case RT5645_PDM_OUT_CTRL:
case RT5645_REC_L1_MIXER:
case RT5645_IL_CMD:
case RT5645_IL_CMD2:
case RT5645_IL_CMD3:
++ + case RT5650_4BTN_IL_CMD1:
++ + case RT5650_4BTN_IL_CMD2:
case RT5645_DRC1_HL_CTRL1:
case RT5645_DRC2_HL_CTRL1:
case RT5645_ADC_MONO_HP_CTRL1:
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
int idx = -EINVAL;
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
unsigned int val;
--- val = snd_soc_read(source->codec, RT5645_GLB_CLK);
+++ val = snd_soc_read(codec, RT5645_GLB_CLK);
val &= RT5645_SCLK_SRC_MASK;
if (val == RT5645_SCLK_SRC_PLL1)
return 1;
static int is_using_asrc(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
unsigned int reg, shift, val;
switch (source->shift) {
return 0;
}
--- val = (snd_soc_read(source->codec, reg) >> shift) & 0xf;
+++ val = (snd_soc_read(codec, reg) >> shift) & 0xf;
switch (val) {
case 1:
case 2:
static const struct snd_kcontrol_new rt5645_if1_adc_in_mux =
SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum);
++ +/* MX-2d [3] [2] */
++ +static const char * const rt5650_a_dac1_src[] = {
++ + "DAC1", "Stereo DAC Mixer"
++ +};
++ +
++ +static SOC_ENUM_SINGLE_DECL(
++ + rt5650_a_dac1_l_enum, RT5650_A_DAC_SOUR,
++ + RT5650_A_DAC1_L_IN_SFT, rt5650_a_dac1_src);
++ +
++ +static const struct snd_kcontrol_new rt5650_a_dac1_l_mux =
++ + SOC_DAPM_ENUM("A DAC1 L source", rt5650_a_dac1_l_enum);
++ +
++ +static SOC_ENUM_SINGLE_DECL(
++ + rt5650_a_dac1_r_enum, RT5650_A_DAC_SOUR,
++ + RT5650_A_DAC1_R_IN_SFT, rt5650_a_dac1_src);
++ +
++ +static const struct snd_kcontrol_new rt5650_a_dac1_r_mux =
++ + SOC_DAPM_ENUM("A DAC1 R source", rt5650_a_dac1_r_enum);
++ +
++ +/* MX-2d [1] [0] */
++ +static const char * const rt5650_a_dac2_src[] = {
++ + "Stereo DAC Mixer", "Mono DAC Mixer"
++ +};
++ +
++ +static SOC_ENUM_SINGLE_DECL(
++ + rt5650_a_dac2_l_enum, RT5650_A_DAC_SOUR,
++ + RT5650_A_DAC2_L_IN_SFT, rt5650_a_dac2_src);
++ +
++ +static const struct snd_kcontrol_new rt5650_a_dac2_l_mux =
++ + SOC_DAPM_ENUM("A DAC2 L source", rt5650_a_dac2_l_enum);
++ +
++ +static SOC_ENUM_SINGLE_DECL(
++ + rt5650_a_dac2_r_enum, RT5650_A_DAC_SOUR,
++ + RT5650_A_DAC2_R_IN_SFT, rt5650_a_dac2_src);
++ +
++ +static const struct snd_kcontrol_new rt5650_a_dac2_r_mux =
++ + SOC_DAPM_ENUM("A DAC2 R source", rt5650_a_dac2_r_enum);
++ +
/* MX-2F [13:12] */
static const char * const rt5645_if2_adc_in_src[] = {
"IF_ADC1", "IF_ADC2", "VAD_ADC"
static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
hp_amp_power(codec, 1);
/* headphone unmute sequence */
-- - snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK |
-- - RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK,
-- - (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
-- - (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
-- - (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
++ + if (rt5645->codec_type == CODEC_TYPE_RT5650) {
++ + snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
++ + } else {
++ + snd_soc_update_bits(codec, RT5645_DEPOP_M3,
++ + RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
++ + RT5645_CP_FQ3_MASK,
++ + (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
++ + (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
++ + (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
++ + }
regmap_write(rt5645->regmap,
RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00);
snd_soc_update_bits(codec, RT5645_DEPOP_M1,
case SND_SOC_DAPM_PRE_PMD:
/* headphone mute sequence */
-- - snd_soc_update_bits(codec, RT5645_DEPOP_M3,
-- - RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
-- - RT5645_CP_FQ3_MASK,
-- - (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
-- - (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
-- - (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
++ + if (rt5645->codec_type == CODEC_TYPE_RT5650) {
++ + snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
++ + } else {
++ + snd_soc_update_bits(codec, RT5645_DEPOP_M3,
++ + RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
++ + RT5645_CP_FQ3_MASK,
++ + (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
++ + (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
++ + (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
++ + }
regmap_write(rt5645->regmap,
RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00);
snd_soc_update_bits(codec, RT5645_DEPOP_M1,
static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
SND_SOC_DAPM_OUTPUT("SPOR"),
};
++ +static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = {
++ + SND_SOC_DAPM_MUX("A DAC1 L Mux", SND_SOC_NOPM,
++ + 0, 0, &rt5650_a_dac1_l_mux),
++ + SND_SOC_DAPM_MUX("A DAC1 R Mux", SND_SOC_NOPM,
++ + 0, 0, &rt5650_a_dac1_r_mux),
++ + SND_SOC_DAPM_MUX("A DAC2 L Mux", SND_SOC_NOPM,
++ + 0, 0, &rt5650_a_dac2_l_mux),
++ + SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM,
++ + 0, 0, &rt5650_a_dac2_r_mux),
++ +};
++ +
static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
{ "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
{ "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc },
{ "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
{ "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
-- - { "DAC L1", NULL, "Stereo DAC MIXL" },
{ "DAC L1", NULL, "PLL1", is_sys_clk_from_pll },
-- - { "DAC R1", NULL, "Stereo DAC MIXR" },
{ "DAC R1", NULL, "PLL1", is_sys_clk_from_pll },
-- - { "DAC L2", NULL, "Mono DAC MIXL" },
{ "DAC L2", NULL, "PLL1", is_sys_clk_from_pll },
-- - { "DAC R2", NULL, "Mono DAC MIXR" },
{ "DAC R2", NULL, "PLL1", is_sys_clk_from_pll },
{ "SPK MIXL", "BST1 Switch", "BST1" },
{ "SPOR", NULL, "SPK amp" },
};
++ +static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = {
++ + { "A DAC1 L Mux", "DAC1", "DAC1 MIXL"},
++ + { "A DAC1 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
++ + { "A DAC1 R Mux", "DAC1", "DAC1 MIXR"},
++ + { "A DAC1 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
++ +
++ + { "A DAC2 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
++ + { "A DAC2 L Mux", "Mono DAC Mixer", "Mono DAC MIXL"},
++ + { "A DAC2 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
++ + { "A DAC2 R Mux", "Mono DAC Mixer", "Mono DAC MIXR"},
++ +
++ + { "DAC L1", NULL, "A DAC1 L Mux" },
++ + { "DAC R1", NULL, "A DAC1 R Mux" },
++ + { "DAC L2", NULL, "A DAC2 L Mux" },
++ + { "DAC R2", NULL, "A DAC2 R Mux" },
++ +};
++ +
++ +static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = {
++ + { "DAC L1", NULL, "Stereo DAC MIXL" },
++ + { "DAC R1", NULL, "Stereo DAC MIXR" },
++ + { "DAC L2", NULL, "Mono DAC MIXL" },
++ + { "DAC R2", NULL, "Mono DAC MIXR" },
++ +};
++ +
static int rt5645_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
rt5645->codec = codec;
++ + switch (rt5645->codec_type) {
++ + case CODEC_TYPE_RT5645:
++ + snd_soc_dapm_add_routes(&codec->dapm,
++ + rt5645_specific_dapm_routes,
++ + ARRAY_SIZE(rt5645_specific_dapm_routes));
++ + break;
++ + case CODEC_TYPE_RT5650:
++ + snd_soc_dapm_new_controls(&codec->dapm,
++ + rt5650_specific_dapm_widgets,
++ + ARRAY_SIZE(rt5650_specific_dapm_widgets));
++ + snd_soc_dapm_add_routes(&codec->dapm,
++ + rt5650_specific_dapm_routes,
++ + ARRAY_SIZE(rt5650_specific_dapm_routes));
++ + break;
++ + }
++ +
rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200);
static const struct i2c_device_id rt5645_i2c_id[] = {
{ "rt5645", 0 },
++ + { "rt5650", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
}
regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val);
-- - if (val != RT5645_DEVICE_ID) {
++ +
++ + switch (val) {
++ + case RT5645_DEVICE_ID:
++ + rt5645->codec_type = CODEC_TYPE_RT5645;
++ + break;
++ + case RT5650_DEVICE_ID:
++ + rt5645->codec_type = CODEC_TYPE_RT5650;
++ + break;
++ + default:
dev_err(&i2c->dev,
-- - "Device with ID register %x is not rt5645\n", val);
++ + "Device with ID register %x is not rt5645 or rt5650\n",
++ + val);
return -ENODEV;
}
if (ret != 0)
dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
++ + if (rt5645->codec_type == CODEC_TYPE_RT5650) {
++ + ret = regmap_register_patch(rt5645->regmap, rt5650_init_list,
++ + ARRAY_SIZE(rt5650_init_list));
++ + if (ret != 0)
++ + dev_warn(&i2c->dev, "Apply rt5650 patch failed: %d\n",
++ + ret);
++ + }
++ +
if (rt5645->pdata.in2_diff)
regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL,
RT5645_IN_DF2, RT5645_IN_DF2);
static bool activity;
int ret;
+++ if (!IS_ENABLED(CONFIG_SND_SOC_RT5677_SPI))
+++ return -ENXIO;
+++
if (on && !activity) {
activity = true;
static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
--- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
--- struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+++ struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
ucontrol->value.integer.value[0] = rt5677->dsp_vad_en;
static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
--- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
--- struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+++ struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
+++ struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0];
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
int idx = rl6231_calc_dmic_clk(rt5677->sysclk);
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
--- struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(source->codec);
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
+++ struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
unsigned int val;
regmap_read(rt5677->regmap, RT5677_GLB_CLK1, &val);
return 0;
}
- struct snd_soc_codec *codec = source->codec;
++ static int is_using_asrc(struct snd_soc_dapm_widget *source,
++ struct snd_soc_dapm_widget *sink)
++ {
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
++ struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
++ unsigned int reg, shift, val;
++
++ if (source->reg == RT5677_ASRC_1) {
++ switch (source->shift) {
++ case 12:
++ reg = RT5677_ASRC_4;
++ shift = 0;
++ break;
++ case 13:
++ reg = RT5677_ASRC_4;
++ shift = 4;
++ break;
++ case 14:
++ reg = RT5677_ASRC_4;
++ shift = 8;
++ break;
++ case 15:
++ reg = RT5677_ASRC_4;
++ shift = 12;
++ break;
++ default:
++ return 0;
++ }
++ } else {
++ switch (source->shift) {
++ case 0:
++ reg = RT5677_ASRC_6;
++ shift = 8;
++ break;
++ case 1:
++ reg = RT5677_ASRC_6;
++ shift = 12;
++ break;
++ case 2:
++ reg = RT5677_ASRC_5;
++ shift = 0;
++ break;
++ case 3:
++ reg = RT5677_ASRC_5;
++ shift = 4;
++ break;
++ case 4:
++ reg = RT5677_ASRC_5;
++ shift = 8;
++ break;
++ case 5:
++ reg = RT5677_ASRC_5;
++ shift = 12;
++ break;
++ case 12:
++ reg = RT5677_ASRC_3;
++ shift = 0;
++ break;
++ case 13:
++ reg = RT5677_ASRC_3;
++ shift = 4;
++ break;
++ case 14:
++ reg = RT5677_ASRC_3;
++ shift = 12;
++ break;
++ default:
++ return 0;
++ }
++ }
++
++ regmap_read(rt5677->regmap, reg, &val);
++ val = (val >> shift) & 0xf;
++
++ switch (val) {
++ case 1 ... 6:
++ return 1;
++ default:
++ return 0;
++ }
++
++ }
++
++ static int can_use_asrc(struct snd_soc_dapm_widget *source,
++ struct snd_soc_dapm_widget *sink)
++ {
++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
++ struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
++
++ if (rt5677->sysclk > rt5677->lrck[RT5677_AIF1] * 384)
++ return 1;
++
++ return 0;
++ }
++
/* Digital Mixer */
static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = {
SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER,
static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
switch (event) {
static int rt5677_bst2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
switch (event) {
static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
switch (event) {
--- case SND_SOC_DAPM_POST_PMU:
+++ case SND_SOC_DAPM_PRE_PMU:
regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x2);
+++ break;
+++
+++ case SND_SOC_DAPM_POST_PMU:
regmap_update_bits(rt5677->regmap, RT5677_PLL1_CTRL2, 0x2, 0x0);
break;
+++
default:
return 0;
}
static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
switch (event) {
--- case SND_SOC_DAPM_POST_PMU:
+++ case SND_SOC_DAPM_PRE_PMU:
regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x2);
+++ break;
+++
+++ case SND_SOC_DAPM_POST_PMU:
regmap_update_bits(rt5677->regmap, RT5677_PLL2_CTRL2, 0x2, 0x0);
break;
+++
default:
return 0;
}
static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
switch (event) {
static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
unsigned int value;
static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
unsigned int value;
static int rt5677_vref_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
--- struct snd_soc_codec *codec = w->codec;
+++ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
switch (event) {
static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL1", RT5677_PWR_ANLG2, RT5677_PWR_PLL1_BIT,
--- 0, rt5677_set_pll1_event, SND_SOC_DAPM_POST_PMU),
+++ 0, rt5677_set_pll1_event, SND_SOC_DAPM_PRE_PMU |
+++ SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("PLL2", RT5677_PWR_ANLG2, RT5677_PWR_PLL2_BIT,
--- 0, rt5677_set_pll2_event, SND_SOC_DAPM_POST_PMU),
+++ 0, rt5677_set_pll2_event, SND_SOC_DAPM_PRE_PMU |
+++ SND_SOC_DAPM_POST_PMU),
++
++ /* ASRC */
++ SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5677_ASRC_1, 0, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5677_ASRC_1, 1, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5677_ASRC_1, 2, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5677_ASRC_1, 3, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("DAC MONO2 L ASRC", 1, RT5677_ASRC_2, 13, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DAC MONO2 R ASRC", 1, RT5677_ASRC_2, 12, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DAC MONO3 L ASRC", 1, RT5677_ASRC_1, 15, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DAC MONO3 R ASRC", 1, RT5677_ASRC_1, 14, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DAC MONO4 L ASRC", 1, RT5677_ASRC_1, 13, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DAC MONO4 R ASRC", 1, RT5677_ASRC_1, 12, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5677_ASRC_2, 11, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DMIC STO2 ASRC", 1, RT5677_ASRC_2, 10, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DMIC STO3 ASRC", 1, RT5677_ASRC_2, 9, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DMIC STO4 ASRC", 1, RT5677_ASRC_2, 8, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5677_ASRC_2, 7, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5677_ASRC_2, 6, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5677_ASRC_2, 5, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("ADC STO2 ASRC", 1, RT5677_ASRC_2, 4, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("ADC STO3 ASRC", 1, RT5677_ASRC_2, 3, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("ADC STO4 ASRC", 1, RT5677_ASRC_2, 2, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5677_ASRC_2, 1, 0, NULL,
++ 0),
++ SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5677_ASRC_2, 0, 0, NULL,
++ 0),
/* Input Side */
/* micbias */
/* DAC Mixer */
SND_SOC_DAPM_SUPPLY("dac stereo1 filter", RT5677_PWR_DIG2,
RT5677_PWR_DAC_S1F_BIT, 0, NULL, 0),
-- SND_SOC_DAPM_SUPPLY("dac mono left filter", RT5677_PWR_DIG2,
++ SND_SOC_DAPM_SUPPLY("dac mono2 left filter", RT5677_PWR_DIG2,
RT5677_PWR_DAC_M2F_L_BIT, 0, NULL, 0),
-- SND_SOC_DAPM_SUPPLY("dac mono right filter", RT5677_PWR_DIG2,
++ SND_SOC_DAPM_SUPPLY("dac mono2 right filter", RT5677_PWR_DIG2,
RT5677_PWR_DAC_M2F_R_BIT, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("dac mono3 left filter", RT5677_PWR_DIG2,
++ RT5677_PWR_DAC_M3F_L_BIT, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("dac mono3 right filter", RT5677_PWR_DIG2,
++ RT5677_PWR_DAC_M3F_R_BIT, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("dac mono4 left filter", RT5677_PWR_DIG2,
++ RT5677_PWR_DAC_M4F_L_BIT, 0, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("dac mono4 right filter", RT5677_PWR_DIG2,
++ RT5677_PWR_DAC_M4F_R_BIT, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
rt5677_sto1_dac_l_mix, ARRAY_SIZE(rt5677_sto1_dac_l_mix)),
};
static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
++ { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc },
++ { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc },
++ { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", can_use_asrc },
++ { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", can_use_asrc },
++ { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc },
++ { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc },
++ { "I2S1", NULL, "I2S1 ASRC", can_use_asrc},
++ { "I2S2", NULL, "I2S2 ASRC", can_use_asrc},
++ { "I2S3", NULL, "I2S3 ASRC", can_use_asrc},
++ { "I2S4", NULL, "I2S4 ASRC", can_use_asrc},
++
++ { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc },
++ { "dac mono2 left filter", NULL, "DAC MONO2 L ASRC", is_using_asrc },
++ { "dac mono2 right filter", NULL, "DAC MONO2 R ASRC", is_using_asrc },
++ { "dac mono3 left filter", NULL, "DAC MONO3 L ASRC", is_using_asrc },
++ { "dac mono3 right filter", NULL, "DAC MONO3 R ASRC", is_using_asrc },
++ { "dac mono4 left filter", NULL, "DAC MONO4 L ASRC", is_using_asrc },
++ { "dac mono4 right filter", NULL, "DAC MONO4 R ASRC", is_using_asrc },
++ { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
++ { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc },
++ { "adc stereo3 filter", NULL, "ADC STO3 ASRC", is_using_asrc },
++ { "adc stereo4 filter", NULL, "ADC STO4 ASRC", is_using_asrc },
++ { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc },
++ { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc },
++
{ "DMIC1", NULL, "DMIC L1" },
{ "DMIC1", NULL, "DMIC R1" },
{ "DMIC2", NULL, "DMIC L2" },
{ "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
{ "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" },
-- { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
--
{ "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
{ "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" },
{ "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "Stereo2 ADC MIXL", NULL, "Stereo2 ADC LR Mux" },
{ "Stereo2 ADC MIXL", NULL, "adc stereo2 filter" },
-- { "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll },
--
{ "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
{ "Stereo2 ADC MIXR", NULL, "adc stereo2 filter" },
{ "adc stereo2 filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "Stereo3 ADC MIXL", NULL, "Sto3 ADC MIXL" },
{ "Stereo3 ADC MIXL", NULL, "adc stereo3 filter" },
-- { "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll },
--
{ "Stereo3 ADC MIXR", NULL, "Sto3 ADC MIXR" },
{ "Stereo3 ADC MIXR", NULL, "adc stereo3 filter" },
{ "adc stereo3 filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "Stereo4 ADC MIXL", NULL, "Sto4 ADC MIXL" },
{ "Stereo4 ADC MIXL", NULL, "adc stereo4 filter" },
-- { "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll },
--
{ "Stereo4 ADC MIXR", NULL, "Sto4 ADC MIXR" },
{ "Stereo4 ADC MIXR", NULL, "adc stereo4 filter" },
{ "adc stereo4 filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "DAC1 MIXL", "Stereo ADC Switch", "ADDA1 Mux" },
{ "DAC1 MIXL", "DAC1 Switch", "DAC1 Mux" },
-- { "DAC1 MIXL", NULL, "dac stereo1 filter" },
{ "DAC1 MIXR", "Stereo ADC Switch", "ADDA1 Mux" },
{ "DAC1 MIXR", "DAC1 Switch", "DAC1 Mux" },
-- { "DAC1 MIXR", NULL, "dac stereo1 filter" },
{ "DAC1 FS", NULL, "DAC1 MIXL" },
{ "DAC1 FS", NULL, "DAC1 MIXR" },
{ "Stereo DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" },
{ "Stereo DAC MIXR", "DAC1 L Switch", "DAC1 MIXL" },
{ "Stereo DAC MIXR", NULL, "dac stereo1 filter" },
++ { "dac stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "Mono DAC MIXL", "ST L Switch", "Sidetone Mux" },
{ "Mono DAC MIXL", "DAC1 L Switch", "DAC1 MIXL" },
{ "Mono DAC MIXL", "DAC2 L Switch", "DAC2 L Mux" },
{ "Mono DAC MIXL", "DAC2 R Switch", "DAC2 R Mux" },
-- { "Mono DAC MIXL", NULL, "dac mono left filter" },
++ { "Mono DAC MIXL", NULL, "dac mono2 left filter" },
++ { "dac mono2 left filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "Mono DAC MIXR", "ST R Switch", "Sidetone Mux" },
{ "Mono DAC MIXR", "DAC1 R Switch", "DAC1 MIXR" },
{ "Mono DAC MIXR", "DAC2 R Switch", "DAC2 R Mux" },
{ "Mono DAC MIXR", "DAC2 L Switch", "DAC2 L Mux" },
-- { "Mono DAC MIXR", NULL, "dac mono right filter" },
++ { "Mono DAC MIXR", NULL, "dac mono2 right filter" },
++ { "dac mono2 right filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "DD1 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
{ "DD1 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" },
{ "DD1 MIXL", "DAC3 L Switch", "DAC3 L Mux" },
{ "DD1 MIXL", "DAC3 R Switch", "DAC3 R Mux" },
++ { "DD1 MIXL", NULL, "dac mono3 left filter" },
++ { "dac mono3 left filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "DD1 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
{ "DD1 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" },
{ "DD1 MIXR", "DAC3 L Switch", "DAC3 L Mux" },
{ "DD1 MIXR", "DAC3 R Switch", "DAC3 R Mux" },
++ { "DD1 MIXR", NULL, "dac mono3 right filter" },
++ { "dac mono3 right filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "DD2 MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
{ "DD2 MIXL", "Mono DAC Mix L Switch", "Mono DAC MIXL" },
{ "DD2 MIXL", "DAC4 L Switch", "DAC4 L Mux" },
{ "DD2 MIXL", "DAC4 R Switch", "DAC4 R Mux" },
++ { "DD2 MIXL", NULL, "dac mono4 left filter" },
++ { "dac mono4 left filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "DD2 MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
{ "DD2 MIXR", "Mono DAC Mix R Switch", "Mono DAC MIXR" },
{ "DD2 MIXR", "DAC4 L Switch", "DAC4 L Mux" },
{ "DD2 MIXR", "DAC4 R Switch", "DAC4 R Mux" },
++ { "DD2 MIXR", NULL, "dac mono4 right filter" },
++ { "dac mono4 right filter", NULL, "PLL1", is_sys_clk_from_pll },
{ "Stereo DAC MIX", NULL, "Stereo DAC MIXL" },
{ "Stereo DAC MIX", NULL, "Stereo DAC MIXR" },
{ "DAC3 SRC Mux", "DD MIX2L", "DD2 MIXL" },
{ "DAC 1", NULL, "DAC12 SRC Mux" },
-- { "DAC 1", NULL, "PLL1", is_sys_clk_from_pll },
{ "DAC 2", NULL, "DAC12 SRC Mux" },
-- { "DAC 2", NULL, "PLL1", is_sys_clk_from_pll },
{ "DAC 3", NULL, "DAC3 SRC Mux" },
-- { "DAC 3", NULL, "PLL1", is_sys_clk_from_pll },
{ "PDM1 L Mux", "STO1 DAC MIX", "Stereo DAC MIXL" },
{ "PDM1 L Mux", "MONO DAC MIX", "Mono DAC MIXL" },
unsigned int rx_mask, int slots, int slot_width)
{
struct snd_soc_codec *codec = dai->codec;
-- unsigned int val = 0;
++ struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
++ unsigned int val = 0, slot_width_25 = 0;
if (rx_mask || tx_mask)
val |= (1 << 12);
case 20:
val |= (1 << 8);
break;
++ case 25:
++ slot_width_25 = 0x8080;
case 24:
val |= (2 << 8);
break;
switch (dai->id) {
case RT5677_AIF1:
-- snd_soc_update_bits(codec, RT5677_TDM1_CTRL1, 0x1f00, val);
++ regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL1, 0x1f00,
++ val);
++ regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x8000,
++ slot_width_25);
break;
case RT5677_AIF2:
-- snd_soc_update_bits(codec, RT5677_TDM2_CTRL1, 0x1f00, val);
++ regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL1, 0x1f00,
++ val);
++ regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x80,
++ slot_width_25);
break;
default:
break;
RT5677_GPIO5_DIR_OUT);
}
++ if (rt5677->pdata.micbias1_vdd_3v3)
++ regmap_update_bits(rt5677->regmap, RT5677_MICBIAS,
++ RT5677_MICBIAS1_CTRL_VDD_MASK,
++ RT5677_MICBIAS1_CTRL_VDD_3_3V);
++
rt5677_init_gpio(i2c);
rt5677_init_irq(i2c);