// SPDX-License-Identifier: GPL-2.0-only
/*
* es8389.c -- ES8389 ALSA SoC Audio Codec
*
* Copyright Everest Semiconductor Co., Ltd
*
* Authors: Michael Zhang (zhangyi@everest-semi.com)
*
* 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.
*/
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/soc.h>
#include "es8389.h"
/* codec private data */
struct es8389_private {
struct regmap *regmap;
struct clk *mclk;
unsigned int sysclk;
int mastermode;
u8 mclk_src;
enum snd_soc_bias_level bias_level;
};
static bool es8389_volatile_register(struct device *dev,
unsigned int reg)
{
if ((reg <= 0 xff))
return true ;
else
return false ;
}
static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9550 , 50 , 0 );
static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -9550 , 50 , 0 );
static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, 0 , 300 , 0 );
static const DECLARE_TLV_DB_SCALE(mix_vol_tlv, -9500 , 100 , 0 );
static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -3200 , 200 , 0 );
static const DECLARE_TLV_DB_SCALE(alc_max_level, -3200 , 200 , 0 );
static int es8389_dmic_set(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val;
bool changed1, changed2;
val = ucontrol->value.integer.value[0 ];
if (val > 1 )
return -EINVAL;
if (val) {
regmap_update_bits_check(es8389->regmap, ES8389_DMIC_EN, 0 xC0, 0 xC0, &changed1);
regmap_update_bits_check(es8389->regmap, ES8389_ADC_MODE, 0 x03, 0 x03, &changed2);
} else {
regmap_update_bits_check(es8389->regmap, ES8389_DMIC_EN, 0 xC0, 0 x00, &changed1);
regmap_update_bits_check(es8389->regmap, ES8389_ADC_MODE, 0 x03, 0 x00, &changed2);
}
if (changed1 & changed2)
return snd_soc_dapm_mux_update_power(dapm, kcontrol, val, e, NULL);
else
return 0 ;
}
static const char *const alc[] = {
"ALC OFF" ,
"ADCR ALC ON" ,
"ADCL ALC ON" ,
"ADCL & ADCL ALC ON" ,
};
static const char *const ramprate[] = {
"0.125db/1 LRCK" ,
"0.125db/4 LRCK" ,
"0.125db/8 LRCK" ,
"0.125db/16 LRCK" ,
"0.125db/32 LRCK" ,
"0.125db/64 LRCK" ,
"0.125db/128 LRCK" ,
"0.125db/256 LRCK" ,
"0.125db/512 LRCK" ,
"0.125db/1024 LRCK" ,
"0.125db/2048 LRCK" ,
"0.125db/4096 LRCK" ,
"0.125db/8192 LRCK" ,
"0.125db/16384 LRCK" ,
"0.125db/32768 LRCK" ,
"0.125db/65536 LRCK" ,
};
static const char *const winsize[] = {
"2 LRCK" ,
"4 LRCK" ,
"8 LRCK" ,
"16 LRCK" ,
"32 LRCK" ,
"64 LRCK" ,
"128 LRCK" ,
"256 LRCK" ,
"512 LRCK" ,
"1024 LRCK" ,
"2048 LRCK" ,
"4096 LRCK" ,
"8192 LRCK" ,
"16384 LRCK" ,
"32768 LRCK" ,
"65536 LRCK" ,
};
static const struct soc_enum alc_enable =
SOC_ENUM_SINGLE(ES8389_ALC_ON, 5 , 4 , alc);
static const struct soc_enum alc_ramprate =
SOC_ENUM_SINGLE(ES8389_ALC_CTL, 4 , 16 , ramprate);
static const struct soc_enum alc_winsize =
SOC_ENUM_SINGLE(ES8389_ALC_CTL, 0 , 16 , winsize);
static const char *const es8389_outl_mux_txt[] = {
"Normal" ,
"DAC2 channel to DAC1 channel" ,
};
static const char *const es8389_outr_mux_txt[] = {
"Normal" ,
"DAC1 channel to DAC2 channel" ,
};
static const char *const es8389_dmic_mux_txt[] = {
"AMIC" ,
"DMIC" ,
};
static const char *const es8389_pga1_texts[] = {
"DifferentialL" , "Line 1P" , "Line 2P"
};
static const char *const es8389_pga2_texts[] = {
"DifferentialR" , "Line 2N" , "Line 1N"
};
static const unsigned int es8389_pga_values[] = {
1 , 5 , 6
};
static const struct soc_enum es8389_outl_mux_enum =
SOC_ENUM_SINGLE(ES8389_DAC_MIX, 5 ,
ARRAY_SIZE(es8389_outl_mux_txt), es8389_outl_mux_txt);
static const struct snd_kcontrol_new es8389_outl_mux_controls =
SOC_DAPM_ENUM("OUTL MUX" , es8389_outl_mux_enum);
static const struct soc_enum es8389_outr_mux_enum =
SOC_ENUM_SINGLE(ES8389_DAC_MIX, 4 ,
ARRAY_SIZE(es8389_outr_mux_txt), es8389_outr_mux_txt);
static const struct snd_kcontrol_new es8389_outr_mux_controls =
SOC_DAPM_ENUM("OUTR MUX" , es8389_outr_mux_enum);
static SOC_ENUM_SINGLE_DECL(
es8389_dmic_mux_enum, ES8389_DMIC_EN, 6 , es8389_dmic_mux_txt);
static const struct soc_enum es8389_pgal_enum =
SOC_VALUE_ENUM_SINGLE(ES8389_MIC1_GAIN, 4 , 7 ,
ARRAY_SIZE(es8389_pga1_texts), es8389_pga1_texts,
es8389_pga_values);
static const struct soc_enum es8389_pgar_enum =
SOC_VALUE_ENUM_SINGLE(ES8389_MIC2_GAIN, 4 , 7 ,
ARRAY_SIZE(es8389_pga2_texts), es8389_pga2_texts,
es8389_pga_values);
static const struct snd_kcontrol_new es8389_dmic_mux_controls =
SOC_DAPM_ENUM_EXT("ADC MUX" , es8389_dmic_mux_enum,
snd_soc_dapm_get_enum_double, es8389_dmic_set);
static const struct snd_kcontrol_new es8389_left_mixer_controls[] = {
SOC_DAPM_SINGLE("DACR DACL Mixer" , ES8389_DAC_MIX, 3 , 1 , 0 ),
};
static const struct snd_kcontrol_new es8389_right_mixer_controls[] = {
SOC_DAPM_SINGLE("DACL DACR Mixer" , ES8389_DAC_MIX, 2 , 1 , 0 ),
};
static const struct snd_kcontrol_new es8389_leftadc_mixer_controls[] = {
SOC_DAPM_SINGLE("ADCL DACL Mixer" , ES8389_DAC_MIX, 1 , 1 , 0 ),
};
static const struct snd_kcontrol_new es8389_rightadc_mixer_controls[] = {
SOC_DAPM_SINGLE("ADCR DACR Mixer" , ES8389_DAC_MIX, 0 , 1 , 0 ),
};
static const struct snd_kcontrol_new es8389_adc_mixer_controls[] = {
SOC_DAPM_SINGLE("DACL ADCL Mixer" , ES8389_ADC_RESET, 7 , 1 , 0 ),
SOC_DAPM_SINGLE("DACR ADCR Mixer" , ES8389_ADC_RESET, 6 , 1 , 0 ),
};
static const struct snd_kcontrol_new es8389_snd_controls[] = {
SOC_SINGLE_TLV("ADCL Capture Volume" , ES8389_ADCL_VOL, 0 , 0 xFF, 0 , adc_vol_tlv),
SOC_SINGLE_TLV("ADCR Capture Volume" , ES8389_ADCR_VOL, 0 , 0 xFF, 0 , adc_vol_tlv),
SOC_SINGLE_TLV("ADCL PGA Volume" , ES8389_MIC1_GAIN, 0 , 0 x0E, 0 , pga_vol_tlv),
SOC_SINGLE_TLV("ADCR PGA Volume" , ES8389_MIC2_GAIN, 0 , 0 x0E, 0 , pga_vol_tlv),
SOC_ENUM("PGAL Select" , es8389_pgal_enum),
SOC_ENUM("PGAR Select" , es8389_pgar_enum),
SOC_ENUM("ALC Capture Switch" , alc_enable),
SOC_SINGLE_TLV("ALC Capture Target Level" , ES8389_ALC_TARGET,
0 , 0 x0f, 0 , alc_target_tlv),
SOC_SINGLE_TLV("ALC Capture Max Gain" , ES8389_ALC_GAIN,
0 , 0 x0f, 0 , alc_max_level),
SOC_ENUM("ADC Ramp Rate" , alc_ramprate),
SOC_ENUM("ALC Capture Winsize" , alc_winsize),
SOC_DOUBLE("ADC OSR Volume ON Switch" , ES8389_ADC_MUTE, 6 , 7 , 1 , 0 ),
SOC_SINGLE_TLV("ADC OSR Volume" , ES8389_OSR_VOL, 0 , 0 xFF, 0 , adc_vol_tlv),
SOC_DOUBLE("ADC OUTPUT Invert Switch" , ES8389_ADC_HPF2, 5 , 6 , 1 , 0 ),
SOC_SINGLE_TLV("DACL Playback Volume" , ES8389_DACL_VOL, 0 , 0 xFF, 0 , dac_vol_tlv),
SOC_SINGLE_TLV("DACR Playback Volume" , ES8389_DACR_VOL, 0 , 0 xFF, 0 , dac_vol_tlv),
SOC_DOUBLE("DAC OUTPUT Invert Switch" , ES8389_DAC_INV, 5 , 6 , 1 , 0 ),
SOC_SINGLE_TLV("ADC2DAC Mixer Volume" , ES8389_MIX_VOL, 0 , 0 x7F, 0 , mix_vol_tlv),
};
static const struct snd_soc_dapm_widget es8389_dapm_widgets[] = {
/*Input Side*/
SND_SOC_DAPM_INPUT("INPUT1" ),
SND_SOC_DAPM_INPUT("INPUT2" ),
SND_SOC_DAPM_INPUT("DMIC" ),
SND_SOC_DAPM_PGA("PGAL" , SND_SOC_NOPM, 4 , 0 , NULL, 0 ),
SND_SOC_DAPM_PGA("PGAR" , SND_SOC_NOPM, 4 , 0 , NULL, 0 ),
/*ADCs*/
SND_SOC_DAPM_ADC("ADCL" , NULL, SND_SOC_NOPM, 0 , 0 ),
SND_SOC_DAPM_ADC("ADCR" , NULL, SND_SOC_NOPM, 0 , 0 ),
/* Audio Interface */
SND_SOC_DAPM_AIF_OUT("I2S OUT" , "I2S Capture" , 0 , SND_SOC_NOPM, 0 , 0 ),
SND_SOC_DAPM_AIF_IN("I2S IN" , "I2S Playback" , 0 , SND_SOC_NOPM, 0 , 0 ),
/*DACs*/
SND_SOC_DAPM_DAC("DACL" , NULL, SND_SOC_NOPM, 0 , 0 ),
SND_SOC_DAPM_DAC("DACR" , NULL, SND_SOC_NOPM, 0 , 0 ),
/*Output Side*/
SND_SOC_DAPM_OUTPUT("HPOL" ),
SND_SOC_DAPM_OUTPUT("HPOR" ),
/* Digital Interface */
SND_SOC_DAPM_PGA("IF DAC" , SND_SOC_NOPM, 0 , 0 , NULL, 0 ),
SND_SOC_DAPM_PGA("IF DACL1" , SND_SOC_NOPM, 0 , 0 , NULL, 0 ),
SND_SOC_DAPM_PGA("IF DACR1" , SND_SOC_NOPM, 0 , 0 , NULL, 0 ),
SND_SOC_DAPM_PGA("IF DACL2" , SND_SOC_NOPM, 0 , 0 , NULL, 0 ),
SND_SOC_DAPM_PGA("IF DACR2" , SND_SOC_NOPM, 0 , 0 , NULL, 0 ),
SND_SOC_DAPM_PGA("IF DACL3" , SND_SOC_NOPM, 0 , 0 , NULL, 0 ),
SND_SOC_DAPM_PGA("IF DACR3" , SND_SOC_NOPM, 0 , 0 , NULL, 0 ),
/* Digital Interface Select */
SND_SOC_DAPM_MIXER("IF DACL Mixer" , SND_SOC_NOPM, 0 , 0 ,
&es8389_left_mixer_controls[0 ],
ARRAY_SIZE(es8389_left_mixer_controls)),
SND_SOC_DAPM_MIXER("IF DACR Mixer" , SND_SOC_NOPM, 0 , 0 ,
&es8389_right_mixer_controls[0 ],
ARRAY_SIZE(es8389_right_mixer_controls)),
SND_SOC_DAPM_MIXER("IF ADCDACL Mixer" , SND_SOC_NOPM, 0 , 0 ,
&es8389_leftadc_mixer_controls[0 ],
ARRAY_SIZE(es8389_leftadc_mixer_controls)),
SND_SOC_DAPM_MIXER("IF ADCDACR Mixer" , SND_SOC_NOPM, 0 , 0 ,
&es8389_rightadc_mixer_controls[0 ],
ARRAY_SIZE(es8389_rightadc_mixer_controls)),
SND_SOC_DAPM_MIXER("ADC Mixer" , SND_SOC_NOPM, 0 , 0 ,
&es8389_adc_mixer_controls[0 ],
ARRAY_SIZE(es8389_adc_mixer_controls)),
SND_SOC_DAPM_MUX("ADC MUX" , SND_SOC_NOPM, 0 , 0 , &es8389_dmic_mux_controls),
SND_SOC_DAPM_MUX("OUTL MUX" , SND_SOC_NOPM, 0 , 0 , &es8389_outl_mux_controls),
SND_SOC_DAPM_MUX("OUTR MUX" , SND_SOC_NOPM, 0 , 0 , &es8389_outr_mux_controls),
};
static const struct snd_soc_dapm_route es8389_dapm_routes[] = {
{"PGAL" , NULL, "INPUT1" },
{"PGAR" , NULL, "INPUT2" },
{"ADCL" , NULL, "PGAL" },
{"ADCR" , NULL, "PGAR" },
{"ADC Mixer" , "DACL ADCL Mixer" , "DACL" },
{"ADC Mixer" , "DACR ADCR Mixer" , "DACR" },
{"ADC Mixer" , NULL, "ADCL" },
{"ADC Mixer" , NULL, "ADCR" },
{"ADC MUX" , "AMIC" , "ADC Mixer" },
{"ADC MUX" , "DMIC" , "DMIC" },
{"I2S OUT" , NULL, "ADC MUX" },
{"DACL" , NULL, "I2S IN" },
{"DACR" , NULL, "I2S IN" },
{"IF DACL1" , NULL, "DACL" },
{"IF DACR1" , NULL, "DACR" },
{"IF DACL2" , NULL, "DACL" },
{"IF DACR2" , NULL, "DACR" },
{"IF DACL3" , NULL, "DACL" },
{"IF DACR3" , NULL, "DACR" },
{"IF DACL Mixer" , NULL, "IF DACL2" },
{"IF DACL Mixer" , "DACR DACL Mixer" , "IF DACR1" },
{"IF DACR Mixer" , NULL, "IF DACR2" },
{"IF DACR Mixer" , "DACL DACR Mixer" , "IF DACL1" },
{"IF ADCDACL Mixer" , NULL, "IF DACL Mixer" },
{"IF ADCDACL Mixer" , "ADCL DACL Mixer" , "IF DACL3" },
{"IF ADCDACR Mixer" , NULL, "IF DACR Mixer" },
{"IF ADCDACR Mixer" , "ADCR DACR Mixer" , "IF DACR3" },
{"OUTL MUX" , "Normal" , "IF ADCDACL Mixer" },
{"OUTL MUX" , "DAC2 channel to DAC1 channel" , "IF ADCDACR Mixer" },
{"OUTR MUX" , "Normal" , "IF ADCDACR Mixer" },
{"OUTR MUX" , "DAC1 channel to DAC2 channel" , "IF ADCDACL Mixer" },
{"HPOL" , NULL, "OUTL MUX" },
{"HPOR" , NULL, "OUTR MUX" },
};
struct _coeff_div {
u16 fs;
u32 mclk;
u32 rate;
u8 Reg0x04;
u8 Reg0x05;
u8 Reg0x06;
u8 Reg0x07;
u8 Reg0x08;
u8 Reg0x09;
u8 Reg0x0A;
u8 Reg0x0F;
u8 Reg0x11;
u8 Reg0x21;
u8 Reg0x22;
u8 Reg0x26;
u8 Reg0x30;
u8 Reg0x41;
u8 Reg0x42;
u8 Reg0x43;
u8 Reg0xF0;
u8 Reg0xF1;
u8 Reg0x16;
u8 Reg0x18;
u8 Reg0x19;
};
/* codec hifi mclk clock divider coefficients */
static const struct _coeff_div coeff_div[] = {
{32 , 256000 , 8000 , 0 x00, 0 x57, 0 x84, 0 xD0, 0 x03, 0 xC1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{36 , 288000 , 8000 , 0 x00, 0 x55, 0 x84, 0 xD0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x23, 0 x8F, 0 xB7, 0 xC0, 0 x1F, 0 x8F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{48 , 384000 , 8000 , 0 x02, 0 x5F, 0 x04, 0 xC0, 0 x03, 0 xC1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{64 , 512000 , 8000 , 0 x00, 0 x4D, 0 x24, 0 xC0, 0 x03, 0 xD1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{72 , 576000 , 8000 , 0 x00, 0 x45, 0 x24, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 x00, 0 x00, 0 x23, 0 x8F, 0 xB7, 0 xC0, 0 x1F, 0 x8F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{96 , 768000 , 8000 , 0 x02, 0 x57, 0 x84, 0 xD0, 0 x03, 0 xC1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{128 , 1024000 , 8000 , 0 x00, 0 x45, 0 x04, 0 xD0, 0 x03, 0 xC1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{192 , 1536000 , 8000 , 0 x02, 0 x4D, 0 x24, 0 xC0, 0 x03, 0 xD1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{256 , 2048000 , 8000 , 0 x01, 0 x45, 0 x04, 0 xD0, 0 x03, 0 xC1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{288 , 2304000 , 8000 , 0 x01, 0 x51, 0 x00, 0 xC0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x23, 0 x8F, 0 xB7, 0 xC0, 0 x1F, 0 x8F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{384 , 3072000 , 8000 , 0 x02, 0 x45, 0 x04, 0 xD0, 0 x03, 0 xC1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{512 , 4096000 , 8000 , 0 x00, 0 x41, 0 x04, 0 xE0, 0 x00, 0 xD1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{768 , 6144000 , 8000 , 0 x05, 0 x45, 0 x04, 0 xD0, 0 x03, 0 xC1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{1024 , 8192000 , 8000 , 0 x01, 0 x41, 0 x06, 0 xE0, 0 x00, 0 xD1, 0 xB0, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{1536 , 12288000 , 8000 , 0 x02, 0 x41, 0 x04, 0 xE0, 0 x00, 0 xD1, 0 xB0, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{1625 , 13000000 , 8000 , 0 x40, 0 x6E, 0 x05, 0 xC8, 0 x01, 0 xC2, 0 x90, 0 x40, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{2048 , 16384000 , 8000 , 0 x03, 0 x44, 0 x01, 0 xC0, 0 x00, 0 xD2, 0 x80, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{2304 , 18432000 , 8000 , 0 x11, 0 x45, 0 x25, 0 xF0, 0 x00, 0 xD1, 0 xB0, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{3072 , 24576000 , 8000 , 0 x05, 0 x44, 0 x01, 0 xC0, 0 x00, 0 xD2, 0 x80, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{32 , 512000 , 16000 , 0 x00, 0 x55, 0 x84, 0 xD0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{36 , 576000 , 16000 , 0 x00, 0 x55, 0 x84, 0 xD0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x23, 0 x8F, 0 xB7, 0 xC0, 0 x1F, 0 x8F, 0 x01, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{48 , 768000 , 16000 , 0 x02, 0 x57, 0 x04, 0 xC0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{50 , 800000 , 16000 , 0 x00, 0 x7E, 0 x01, 0 xD9, 0 x00, 0 xC2, 0 x80, 0 x00, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 xC7, 0 x95, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{64 , 1024000 , 16000 , 0 x00, 0 x45, 0 x24, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{72 , 1152000 , 16000 , 0 x00, 0 x45, 0 x24, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 x00, 0 x00, 0 x23, 0 x8F, 0 xB7, 0 xC0, 0 x1F, 0 x8F, 0 x01, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{96 , 1536000 , 16000 , 0 x02, 0 x55, 0 x84, 0 xD0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{128 , 2048000 , 16000 , 0 x00, 0 x51, 0 x04, 0 xD0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{144 , 2304000 , 16000 , 0 x00, 0 x51, 0 x00, 0 xC0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x23, 0 x8F, 0 xB7, 0 xC0, 0 x1F, 0 x8F, 0 x01, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{192 , 3072000 , 16000 , 0 x02, 0 x65, 0 x25, 0 xE0, 0 x00, 0 xE1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{256 , 4096000 , 16000 , 0 x00, 0 x41, 0 x04, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{300 , 4800000 , 16000 , 0 x02, 0 x66, 0 x01, 0 xD9, 0 x00, 0 xC2, 0 x80, 0 x00, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 xC7, 0 x95, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{384 , 6144000 , 16000 , 0 x02, 0 x51, 0 x04, 0 xD0, 0 x01, 0 xC1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{512 , 8192000 , 16000 , 0 x01, 0 x41, 0 x04, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{750 , 12000000 , 16000 , 0 x0E, 0 x7E, 0 x01, 0 xC9, 0 x00, 0 xC2, 0 x80, 0 x40, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 xC7, 0 x95, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{768 , 12288000 , 16000 , 0 x02, 0 x41, 0 x04, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{1024 , 16384000 , 16000 , 0 x03, 0 x41, 0 x04, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{1152 , 18432000 , 16000 , 0 x08, 0 x51, 0 x04, 0 xD0, 0 x01, 0 xC1, 0 x90, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{1200 , 19200000 , 16000 , 0 x0B, 0 x66, 0 x01, 0 xD9, 0 x00, 0 xC2, 0 x80, 0 x40, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 xC7, 0 x95, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{1500 , 24000000 , 16000 , 0 x0E, 0 x26, 0 x01, 0 xD9, 0 x00, 0 xC2, 0 x80, 0 xC0, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 xC7, 0 x95, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{1536 , 24576000 , 16000 , 0 x05, 0 x41, 0 x04, 0 xC0, 0 x01, 0 xD1, 0 x90, 0 xC0, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 xFF, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{1625 , 26000000 , 16000 , 0 x40, 0 x6E, 0 x05, 0 xC8, 0 x01, 0 xC2, 0 x90, 0 xC0, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x12, 0 x31, 0 x0E},
{800 , 19200000 , 24000 , 0 x07, 0 x66, 0 x01, 0 xD9, 0 x00, 0 xC2, 0 x80, 0 x40, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 xC7, 0 x95, 0 x00, 0 x12, 0 x00, 0 x1A, 0 x49, 0 x14},
{600 , 19200000 , 32000 , 0 x05, 0 x46, 0 x01, 0 xD8, 0 x10, 0 xD2, 0 x80, 0 x40, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x23, 0 x61, 0 x1B},
{32 , 1411200 , 44100 , 0 x00, 0 x45, 0 xA4, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{64 , 2822400 , 44100 , 0 x00, 0 x51, 0 x00, 0 xC0, 0 x10, 0 xC1, 0 x80, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{128 , 5644800 , 44100 , 0 x00, 0 x41, 0 x04, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{256 , 11289600 , 44100 , 0 x01, 0 x41, 0 x04, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{512 , 22579200 , 44100 , 0 x03, 0 x41, 0 x04, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 xC0, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{32 , 1536000 , 48000 , 0 x00, 0 x45, 0 xA4, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{48 , 2304000 , 48000 , 0 x02, 0 x55, 0 x04, 0 xC0, 0 x10, 0 xC1, 0 x80, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{50 , 2400000 , 48000 , 0 x00, 0 x76, 0 x01, 0 xC8, 0 x10, 0 xC2, 0 x80, 0 x00, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{64 , 3072000 , 48000 , 0 x00, 0 x51, 0 x04, 0 xC0, 0 x10, 0 xC1, 0 x80, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{100 , 4800000 , 48000 , 0 x00, 0 x46, 0 x01, 0 xD8, 0 x10, 0 xD2, 0 x80, 0 x00, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{125 , 6000000 , 48000 , 0 x04, 0 x6E, 0 x05, 0 xC8, 0 x10, 0 xC2, 0 x80, 0 x00, 0 x01, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{128 , 6144000 , 48000 , 0 x00, 0 x41, 0 x04, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x00, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{200 , 9600000 , 48000 , 0 x01, 0 x46, 0 x01, 0 xD8, 0 x10, 0 xD2, 0 x80, 0 x00, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{250 , 12000000 , 48000 , 0 x04, 0 x76, 0 x01, 0 xC8, 0 x10, 0 xC2, 0 x80, 0 x40, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{256 , 12288000 , 48000 , 0 x01, 0 x41, 0 x04, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{384 , 18432000 , 48000 , 0 x02, 0 x41, 0 x04, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x40, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{400 , 19200000 , 48000 , 0 x03, 0 x46, 0 x01, 0 xD8, 0 x10, 0 xD2, 0 x80, 0 x40, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{500 , 24000000 , 48000 , 0 x04, 0 x46, 0 x01, 0 xD8, 0 x10, 0 xD2, 0 x80, 0 xC0, 0 x00, 0 x18, 0 x95, 0 xD0, 0 xC0, 0 x63, 0 x95, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{512 , 24576000 , 48000 , 0 x03, 0 x41, 0 x04, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 xC0, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{800 , 38400000 , 48000 , 0 x18, 0 x45, 0 x04, 0 xC0, 0 x10, 0 xC1, 0 x80, 0 xC0, 0 x00, 0 x1F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x00, 0 x12, 0 x00, 0 x35, 0 x91, 0 x28},
{128 , 11289600 , 88200 , 0 x00, 0 x50, 0 x00, 0 xC0, 0 x10, 0 xC1, 0 x80, 0 x40, 0 x00, 0 x9F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x80, 0 x12, 0 xC0, 0 x32, 0 x89, 0 x25},
{64 , 6144000 , 96000 , 0 x00, 0 x41, 0 x00, 0 xD0, 0 x10, 0 xD1, 0 x80, 0 x00, 0 x00, 0 x9F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x80, 0 x12, 0 xC0, 0 x35, 0 x91, 0 x28},
{128 , 12288000 , 96000 , 0 x00, 0 x50, 0 x00, 0 xC0, 0 x10, 0 xC1, 0 x80, 0 xC0, 0 x00, 0 x9F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x80, 0 x12, 0 xC0, 0 x35, 0 x91, 0 x28},
{256 , 24576000 , 96000 , 0 x00, 0 x40, 0 x00, 0 xC0, 0 x10, 0 xC1, 0 x80, 0 xC0, 0 x00, 0 x9F, 0 x7F, 0 xBF, 0 xC0, 0 x7F, 0 x7F, 0 x80, 0 x12, 0 xC0, 0 x35, 0 x91, 0 x28},
{128 , 24576000 , 192000 , 0 x00, 0 x50, 0 x00, 0 xC0, 0 x18, 0 xC1, 0 x81, 0 xC0, 0 x00, 0 x8F, 0 x7F, 0 xEF, 0 xC0, 0 x3F, 0 x7F, 0 x80, 0 x12, 0 xC0, 0 x3F, 0 xF9, 0 x3F},
{50 , 400000 , 8000 , 0 x00, 0 x75, 0 x05, 0 xC8, 0 x01, 0 xC1, 0 x90, 0 x10, 0 x00, 0 x18, 0 xC7, 0 xD0, 0 xC0, 0 x8F, 0 xC7, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{600 , 4800000 , 8000 , 0 x05, 0 x65, 0 x25, 0 xF9, 0 x00, 0 xD1, 0 x90, 0 x10, 0 x00, 0 x18, 0 xC7, 0 xD0, 0 xC0, 0 x8F, 0 xC7, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{1500 , 12000000 , 8000 , 0 x0E, 0 x25, 0 x25, 0 xE8, 0 x00, 0 xD1, 0 x90, 0 x40, 0 x00, 0 x31, 0 xC7, 0 xC5, 0 x00, 0 x8F, 0 xC7, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{2400 , 19200000 , 8000 , 0 x0B, 0 x01, 0 x00, 0 xD0, 0 x00, 0 xD1, 0 x80, 0 x90, 0 x00, 0 x31, 0 xC7, 0 xC5, 0 x00, 0 xC7, 0 xC7, 0 x00, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{3000 , 24000000 , 8000 , 0 x0E, 0 x24, 0 x05, 0 xD0, 0 x00, 0 xC2, 0 x80, 0 xC0, 0 x00, 0 x31, 0 xC7, 0 xC5, 0 x00, 0 x8F, 0 xC7, 0 x01, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
{3250 , 26000000 , 8000 , 0 x40, 0 x05, 0 xA4, 0 xC0, 0 x00, 0 xD1, 0 x80, 0 xD0, 0 x00, 0 x31, 0 xC7, 0 xC5, 0 x00, 0 xC7, 0 xC7, 0 x00, 0 x12, 0 x00, 0 x09, 0 x19, 0 x07},
};
static inline int get_coeff(int mclk, int rate)
{
int i;
for (i = 0 ; i < ARRAY_SIZE(coeff_div); i++) {
if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
return i;
}
return -EINVAL;
}
/*
* if PLL not be used, use internal clk1 for mclk,otherwise, use internal clk2 for PLL source.
*/
static int es8389_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_component *component = dai->component;
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
es8389->sysclk = freq;
return 0 ;
}
static int es8389_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{
struct snd_soc_component *component = dai->component;
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
regmap_update_bits(es8389->regmap, ES8389_PTDM_SLOT,
ES8389_TDM_SLOT, (slots << ES8389_TDM_SHIFT));
regmap_update_bits(es8389->regmap, ES8389_DAC_RAMP,
ES8389_TDM_SLOT, (slots << ES8389_TDM_SHIFT));
return 0 ;
}
static int es8389_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_component *component = dai->component;
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
u8 state = 0 ;
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
case SND_SOC_DAIFMT_CBC_CFP:
regmap_update_bits(es8389->regmap, ES8389_MASTER_MODE,
ES8389_MASTER_MODE_EN, ES8389_MASTER_MODE_EN);
es8389->mastermode = 1 ;
break ;
case SND_SOC_DAIFMT_CBC_CFC:
es8389->mastermode = 0 ;
break ;
default :
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
state |= ES8389_DAIFMT_I2S;
break ;
case SND_SOC_DAIFMT_RIGHT_J:
dev_err(component->dev, "component driver does not support right justified\n" );
return -EINVAL;
case SND_SOC_DAIFMT_LEFT_J:
state |= ES8389_DAIFMT_LEFT_J;
break ;
case SND_SOC_DAIFMT_DSP_A:
state |= ES8389_DAIFMT_DSP_A;
break ;
case SND_SOC_DAIFMT_DSP_B:
state |= ES8389_DAIFMT_DSP_B;
break ;
default :
break ;
}
regmap_update_bits(es8389->regmap, ES8389_ADC_FORMAT_MUTE, ES8389_DAIFMT_MASK, state);
regmap_update_bits(es8389->regmap, ES8389_DAC_FORMAT_MUTE, ES8389_DAIFMT_MASK, state);
return 0 ;
}
static int es8389_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
int coeff;
u8 state = 0 ;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
state |= ES8389_S16_LE;
break ;
case SNDRV_PCM_FORMAT_S20_3LE:
state |= ES8389_S20_3_LE;
break ;
case SNDRV_PCM_FORMAT_S18_3LE:
state |= ES8389_S18_LE;
break ;
case SNDRV_PCM_FORMAT_S24_LE:
state |= ES8389_S24_LE;
break ;
case SNDRV_PCM_FORMAT_S32_LE:
state |= ES8389_S32_LE;
break ;
default :
return -EINVAL;
}
regmap_update_bits(es8389->regmap, ES8389_ADC_FORMAT_MUTE, ES8389_DATA_LEN_MASK, state);
regmap_update_bits(es8389->regmap, ES8389_DAC_FORMAT_MUTE, ES8389_DATA_LEN_MASK, state);
if (es8389->mclk_src == ES8389_SCLK_PIN) {
regmap_update_bits(es8389->regmap, ES8389_MASTER_CLK,
ES8389_MCLK_SOURCE, es8389->mclk_src);
es8389->sysclk = params_channels(params) * params_width(params) * params_rate(params);
}
coeff = get_coeff(es8389->sysclk, params_rate(params));
if (coeff >= 0 ) {
regmap_write(es8389->regmap, ES8389_CLK_DIV1, coeff_div[coeff].Reg0x04);
regmap_write(es8389->regmap, ES8389_CLK_MUL, coeff_div[coeff].Reg0x05);
regmap_write(es8389->regmap, ES8389_CLK_MUX1, coeff_div[coeff].Reg0x06);
regmap_write(es8389->regmap, ES8389_CLK_MUX2, coeff_div[coeff].Reg0x07);
regmap_write(es8389->regmap, ES8389_CLK_CTL1, coeff_div[coeff].Reg0x08);
regmap_write(es8389->regmap, ES8389_CLK_CTL2, coeff_div[coeff].Reg0x09);
regmap_write(es8389->regmap, ES8389_CLK_CTL3, coeff_div[coeff].Reg0x0A);
regmap_update_bits(es8389->regmap, ES8389_OSC_CLK,
0 xC0, coeff_div[coeff].Reg0x0F);
regmap_write(es8389->regmap, ES8389_CLK_DIV2, coeff_div[coeff].Reg0x11);
regmap_write(es8389->regmap, ES8389_ADC_OSR, coeff_div[coeff].Reg0x21);
regmap_write(es8389->regmap, ES8389_ADC_DSP, coeff_div[coeff].Reg0x22);
regmap_write(es8389->regmap, ES8389_OSR_VOL, coeff_div[coeff].Reg0x26);
regmap_update_bits(es8389->regmap, ES8389_SYSTEM30,
0 xC0, coeff_div[coeff].Reg0x30);
regmap_write(es8389->regmap, ES8389_DAC_DSM_OSR, coeff_div[coeff].Reg0x41);
regmap_write(es8389->regmap, ES8389_DAC_DSP_OSR, coeff_div[coeff].Reg0x42);
regmap_update_bits(es8389->regmap, ES8389_DAC_MISC,
0 x81, coeff_div[coeff].Reg0x43);
regmap_update_bits(es8389->regmap, ES8389_CHIP_MISC,
0 x72, coeff_div[coeff].Reg0xF0);
regmap_write(es8389->regmap, ES8389_CSM_STATE1, coeff_div[coeff].Reg0xF1);
regmap_write(es8389->regmap, ES8389_SYSTEM16, coeff_div[coeff].Reg0x16);
regmap_write(es8389->regmap, ES8389_SYSTEM18, coeff_div[coeff].Reg0x18);
regmap_write(es8389->regmap, ES8389_SYSTEM19, coeff_div[coeff].Reg0x19);
} else {
dev_warn(component->dev, "Clock coefficients do not match" );
}
return 0 ;
}
static int es8389_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
int ret;
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
switch (level) {
case SND_SOC_BIAS_ON:
ret = clk_prepare_enable(es8389->mclk);
if (ret)
return ret;
regmap_update_bits(es8389->regmap, ES8389_HPSW, 0 x20, 0 x20);
regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0 xD9);
regmap_write(es8389->regmap, ES8389_ADC_EN, 0 x8F);
regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0 xE4);
regmap_write(es8389->regmap, ES8389_RESET, 0 x01);
regmap_write(es8389->regmap, ES8389_CLK_OFF1, 0 xC3);
regmap_update_bits(es8389->regmap, ES8389_ADC_HPF1, 0 x0f, 0 x0a);
regmap_update_bits(es8389->regmap, ES8389_ADC_HPF2, 0 x0f, 0 x0a);
usleep_range(70000 , 72000 );
regmap_write(es8389->regmap, ES8389_DAC_RESET, 0 X00);
break ;
case SND_SOC_BIAS_PREPARE:
break ;
case SND_SOC_BIAS_STANDBY:
regmap_update_bits(es8389->regmap, ES8389_ADC_HPF1, 0 x0f, 0 x04);
regmap_update_bits(es8389->regmap, ES8389_ADC_HPF2, 0 x0f, 0 x04);
regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0 xD4);
usleep_range(70000 , 72000 );
regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0 x59);
regmap_write(es8389->regmap, ES8389_ADC_EN, 0 x00);
regmap_write(es8389->regmap, ES8389_CLK_OFF1, 0 x00);
regmap_write(es8389->regmap, ES8389_RESET, 0 x3E);
regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0 x80, 0 x80);
usleep_range(8000 , 8500 );
regmap_update_bits(es8389->regmap, ES8389_DAC_INV, 0 x80, 0 x00);
clk_disable_unprepare(es8389->mclk);
break ;
case SND_SOC_BIAS_OFF:
break ;
}
return 0 ;
}
static int es8389_mute(struct snd_soc_dai *dai, int mute, int direction)
{
struct snd_soc_component *component = dai->component;
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
if (mute) {
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
regmap_update_bits(es8389->regmap, ES8389_DAC_FORMAT_MUTE,
0 x03, 0 x03);
} else {
regmap_update_bits(es8389->regmap, ES8389_ADC_FORMAT_MUTE,
0 x03, 0 x03);
}
} else {
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
regmap_update_bits(es8389->regmap, ES8389_DAC_FORMAT_MUTE,
0 x03, 0 x00);
} else {
regmap_update_bits(es8389->regmap, ES8389_ADC_FORMAT_MUTE,
0 x03, 0 x00);
}
}
return 0 ;
}
#define es8389_RATES SNDRV_PCM_RATE_8000_96000
#define es8389_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
static const struct snd_soc_dai_ops es8389_ops = {
.hw_params = es8389_pcm_hw_params,
.set_fmt = es8389_set_dai_fmt,
.set_sysclk = es8389_set_dai_sysclk,
.set_tdm_slot = es8389_set_tdm_slot,
.mute_stream = es8389_mute,
};
static struct snd_soc_dai_driver es8389_dai = {
.name = "ES8389 HiFi" ,
.playback = {
.stream_name = "Playback" ,
.channels_min = 1 ,
.channels_max = 2 ,
.rates = es8389_RATES,
.formats = es8389_FORMATS,
},
.capture = {
.stream_name = "Capture" ,
.channels_min = 1 ,
.channels_max = 2 ,
.rates = es8389_RATES,
.formats = es8389_FORMATS,
},
.ops = &es8389_ops,
.symmetric_rate = 1 ,
};
static void es8389_init(struct snd_soc_component *component)
{
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
regmap_write(es8389->regmap, ES8389_ISO_CTL, 0 x00);
regmap_write(es8389->regmap, ES8389_RESET, 0 x7E);
regmap_write(es8389->regmap, ES8389_ISO_CTL, 0 x38);
regmap_write(es8389->regmap, ES8389_ADC_HPF1, 0 x64);
regmap_write(es8389->regmap, ES8389_ADC_HPF2, 0 x04);
regmap_write(es8389->regmap, ES8389_DAC_INV, 0 x03);
regmap_write(es8389->regmap, ES8389_VMID, 0 x2A);
regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0 xC9);
regmap_write(es8389->regmap, ES8389_ANA_VSEL, 0 x4F);
regmap_write(es8389->regmap, ES8389_ANA_CTL2, 0 x06);
regmap_write(es8389->regmap, ES8389_LOW_POWER1, 0 x00);
regmap_write(es8389->regmap, ES8389_DMIC_EN, 0 x16);
regmap_write(es8389->regmap, ES8389_PGA_SW, 0 xAA);
regmap_write(es8389->regmap, ES8389_MOD_SW1, 0 x66);
regmap_write(es8389->regmap, ES8389_MOD_SW2, 0 x99);
regmap_write(es8389->regmap, ES8389_ADC_MODE, (0 x00 | ES8389_TDM_MODE));
regmap_update_bits(es8389->regmap, ES8389_DMIC_EN, 0 xC0, 0 x00);
regmap_update_bits(es8389->regmap, ES8389_ADC_MODE, 0 x03, 0 x00);
regmap_update_bits(es8389->regmap, ES8389_MIC1_GAIN,
ES8389_MIC_SEL_MASK, ES8389_MIC_DEFAULT);
regmap_update_bits(es8389->regmap, ES8389_MIC2_GAIN,
ES8389_MIC_SEL_MASK, ES8389_MIC_DEFAULT);
regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0 xC4);
regmap_write(es8389->regmap, ES8389_MASTER_MODE, 0 x08);
regmap_write(es8389->regmap, ES8389_CSM_STATE1, 0 x00);
regmap_write(es8389->regmap, ES8389_SYSTEM12, 0 x01);
regmap_write(es8389->regmap, ES8389_SYSTEM13, 0 x01);
regmap_write(es8389->regmap, ES8389_SYSTEM14, 0 x01);
regmap_write(es8389->regmap, ES8389_SYSTEM15, 0 x01);
regmap_write(es8389->regmap, ES8389_SYSTEM16, 0 x35);
regmap_write(es8389->regmap, ES8389_SYSTEM17, 0 x09);
regmap_write(es8389->regmap, ES8389_SYSTEM18, 0 x91);
regmap_write(es8389->regmap, ES8389_SYSTEM19, 0 x28);
regmap_write(es8389->regmap, ES8389_SYSTEM1A, 0 x01);
regmap_write(es8389->regmap, ES8389_SYSTEM1B, 0 x01);
regmap_write(es8389->regmap, ES8389_SYSTEM1C, 0 x11);
regmap_write(es8389->regmap, ES8389_CHIP_MISC, 0 x13);
regmap_write(es8389->regmap, ES8389_MASTER_CLK, 0 x00);
regmap_write(es8389->regmap, ES8389_CLK_DIV1, 0 x00);
regmap_write(es8389->regmap, ES8389_CLK_MUL, 0 x10);
regmap_write(es8389->regmap, ES8389_CLK_MUX1, 0 x00);
regmap_write(es8389->regmap, ES8389_CLK_MUX2, 0 xC0);
regmap_write(es8389->regmap, ES8389_CLK_CTL1, 0 x00);
regmap_write(es8389->regmap, ES8389_CLK_CTL2, 0 xC0);
regmap_write(es8389->regmap, ES8389_CLK_CTL3, 0 x80);
regmap_write(es8389->regmap, ES8389_SCLK_DIV, 0 x04);
regmap_write(es8389->regmap, ES8389_LRCK_DIV1, 0 x01);
regmap_write(es8389->regmap, ES8389_LRCK_DIV2, 0 x00);
regmap_write(es8389->regmap, ES8389_OSC_CLK, 0 x00);
regmap_write(es8389->regmap, ES8389_ADC_OSR, 0 x1F);
regmap_write(es8389->regmap, ES8389_ADC_DSP, 0 x7F);
regmap_write(es8389->regmap, ES8389_ADC_MUTE, 0 xC0);
regmap_write(es8389->regmap, ES8389_SYSTEM30, 0 xF4);
regmap_write(es8389->regmap, ES8389_DAC_DSM_OSR, 0 x7F);
regmap_write(es8389->regmap, ES8389_DAC_DSP_OSR, 0 x7F);
regmap_write(es8389->regmap, ES8389_DAC_MISC, 0 x10);
regmap_write(es8389->regmap, ES8389_DAC_RAMP, 0 x0F);
regmap_write(es8389->regmap, ES8389_SYSTEM4C, 0 xC0);
regmap_write(es8389->regmap, ES8389_RESET, 0 x00);
regmap_write(es8389->regmap, ES8389_CLK_OFF1, 0 xC1);
regmap_write(es8389->regmap, ES8389_RESET, 0 x01);
regmap_write(es8389->regmap, ES8389_DAC_RESET, 0 x02);
regmap_update_bits(es8389->regmap, ES8389_ADC_FORMAT_MUTE, 0 x03, 0 x03);
regmap_update_bits(es8389->regmap, ES8389_DAC_FORMAT_MUTE, 0 x03, 0 x03);
}
static int es8389_suspend(struct snd_soc_component *component)
{
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
es8389_set_bias_level(component, SND_SOC_BIAS_STANDBY);
regcache_cache_only(es8389->regmap, true );
regcache_mark_dirty(es8389->regmap);
return 0 ;
}
static int es8389_resume(struct snd_soc_component *component)
{
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
unsigned int regv;
regcache_cache_only(es8389->regmap, false );
regcache_cache_bypass(es8389->regmap, true );
regmap_read(es8389->regmap, ES8389_RESET, ®v);
regcache_cache_bypass(es8389->regmap, false );
if (regv == 0 xff)
es8389_init(component);
else
es8389_set_bias_level(component, SND_SOC_BIAS_ON);
regcache_sync(es8389->regmap);
return 0 ;
}
static int es8389_probe(struct snd_soc_component *component)
{
int ret;
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
ret = device_property_read_u8(component->dev, "everest,mclk-src" , &es8389->mclk_src);
if (ret != 0 ) {
dev_dbg(component->dev, "mclk-src return %d" , ret);
es8389->mclk_src = ES8389_MCLK_SOURCE;
}
es8389->mclk = devm_clk_get(component->dev, "mclk" );
if (IS_ERR(es8389->mclk))
return dev_err_probe(component->dev, PTR_ERR(es8389->mclk),
"ES8389 is unable to get mclk\n" );
if (!es8389->mclk)
dev_err(component->dev, "%s, assuming static mclk\n" , __func__);
ret = clk_prepare_enable(es8389->mclk);
if (ret) {
dev_err(component->dev, "%s, unable to enable mclk\n" , __func__);
return ret;
}
es8389_init(component);
es8389_set_bias_level(component, SND_SOC_BIAS_STANDBY);
return 0 ;
}
static void es8389_remove(struct snd_soc_component *component)
{
struct es8389_private *es8389 = snd_soc_component_get_drvdata(component);
regmap_write(es8389->regmap, ES8389_MASTER_MODE, 0 x28);
regmap_write(es8389->regmap, ES8389_HPSW, 0 x00);
regmap_write(es8389->regmap, ES8389_VMID, 0 x00);
regmap_write(es8389->regmap, ES8389_RESET, 0 x00);
regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0 xCC);
usleep_range(500000 , 550000 );//500MS
regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0 x00);
regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0 x08);
regmap_write(es8389->regmap, ES8389_ISO_CTL, 0 xC1);
regmap_write(es8389->regmap, ES8389_PULL_DOWN, 0 x00);
}
static const struct snd_soc_component_driver soc_codec_dev_es8389 = {
.probe = es8389_probe,
.remove = es8389_remove,
.suspend = es8389_suspend,
.resume = es8389_resume,
.set_bias_level = es8389_set_bias_level,
.controls = es8389_snd_controls,
.num_controls = ARRAY_SIZE(es8389_snd_controls),
.dapm_widgets = es8389_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(es8389_dapm_widgets),
.dapm_routes = es8389_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(es8389_dapm_routes),
.idle_bias_on = 1 ,
.use_pmdown_time = 1 ,
};
static const struct regmap_config es8389_regmap = {
.reg_bits = 8 ,
.val_bits = 8 ,
.max_register = ES8389_MAX_REGISTER,
.volatile_reg = es8389_volatile_register,
.cache_type = REGCACHE_MAPLE,
};
static void es8389_i2c_shutdown(struct i2c_client *i2c)
{
struct es8389_private *es8389;
es8389 = i2c_get_clientdata(i2c);
regmap_write(es8389->regmap, ES8389_MASTER_MODE, 0 x28);
regmap_write(es8389->regmap, ES8389_HPSW, 0 x00);
regmap_write(es8389->regmap, ES8389_VMID, 0 x00);
regmap_write(es8389->regmap, ES8389_RESET, 0 x00);
regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0 xCC);
usleep_range(500000 , 550000 );//500MS
regmap_write(es8389->regmap, ES8389_CSM_JUMP, 0 x00);
regmap_write(es8389->regmap, ES8389_ANA_CTL1, 0 x08);
regmap_write(es8389->regmap, ES8389_ISO_CTL, 0 xC1);
regmap_write(es8389->regmap, ES8389_PULL_DOWN, 0 x00);
}
static int es8389_i2c_probe(struct i2c_client *i2c_client)
{
struct es8389_private *es8389;
int ret;
es8389 = devm_kzalloc(&i2c_client->dev, sizeof (*es8389), GFP_KERNEL);
if (es8389 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c_client, es8389);
es8389->regmap = devm_regmap_init_i2c(i2c_client, &es8389_regmap);
if (IS_ERR(es8389->regmap))
return dev_err_probe(&i2c_client->dev, PTR_ERR(es8389->regmap),
"regmap_init() failed\n" );
ret = devm_snd_soc_register_component(&i2c_client->dev,
&soc_codec_dev_es8389,
&es8389_dai,
1 );
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id es8389_if_dt_ids[] = {
{ .compatible = "everest,es8389" , },
{ }
};
MODULE_DEVICE_TABLE(of, es8389_if_dt_ids);
#endif
static const struct i2c_device_id es8389_i2c_id[] = {
{"es8389" },
{ }
};
MODULE_DEVICE_TABLE(i2c, es8389_i2c_id);
static struct i2c_driver es8389_i2c_driver = {
.driver = {
.name = "es8389" ,
.of_match_table = of_match_ptr(es8389_if_dt_ids),
},
.shutdown = es8389_i2c_shutdown,
.probe = es8389_i2c_probe,
.id_table = es8389_i2c_id,
};
module_i2c_driver(es8389_i2c_driver);
MODULE_DESCRIPTION("ASoC es8389 driver" );
MODULE_AUTHOR("Michael Zhang <zhangyi@everest-semi.com>" );
MODULE_LICENSE("GPL" );
Messung V0.5 in Prozent C=94 H=92 G=92