diff --git a/sound/soc/codecs/es7210.c b/sound/soc/codecs/es7210.c index 39006a636..11a36e32a 100644 --- a/sound/soc/codecs/es7210.c +++ b/sound/soc/codecs/es7210.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "es7210.h" @@ -46,8 +47,11 @@ #define MIC_CHN_2 2 #define ES7210_TDM_ENABLE ENABLE -#define ES7210_CHANNELS_MAX MIC_CHN_2 +//#define ES7210_CHANNELS_MAX MIC_CHN_8 +static int ADC_DEV_MAXNUM = 1; +static int ES7210_CHANNELS_MAX = 1; +#if 0 #if ES7210_CHANNELS_MAX == MIC_CHN_2 #define ADC_DEV_MAXNUM 1 #endif @@ -72,6 +76,7 @@ #if ES7210_CHANNELS_MAX == MIC_CHN_16 #define ADC_DEV_MAXNUM 4 #endif +#endif #define ES7210_TDM_1LRCK_DSPA 0 #define ES7210_TDM_1LRCK_DSPB 1 @@ -83,7 +88,7 @@ #define ES7210_TDM_NLRCK_LJ 7 #define ES7210_NORMAL_I2S 8 -#define ES7210_WORK_MODE ES7210_NORMAL_I2S +#define ES7210_WORK_MODE ES7210_TDM_1LRCK_DSPB #define ES7210_I2C_BUS_NUM 1 @@ -100,26 +105,16 @@ #define RATIO_128 0x01 #define RATIO_64 0x41 /* mclk from bclk pin */ -#define ES7210_MCLK_LRCK_RATIO RATIO_64 +#define ES7210_MCLK_LRCK_RATIO RATIO_256 // mclk=sclk. mclk/lrck = sclk / lrck = 16bit*4slot=RATIO_64. 32bit*4slot=16bit*8slot=RATIO_128 32bit*8slot=RATIO_256 -struct i2c_client *i2c_clt1[ADC_DEV_MAXNUM]; +struct i2c_client *i2c_clt1[4] = {0}; struct es7210_priv *resume_es7210 = NULL; -/* codec private data */ -struct es7210_priv { - struct regmap *regmap; - struct i2c_client *i2c_client; - unsigned int dmic_enable; - unsigned int sysclk; - struct clk *mclk; - struct snd_pcm_hw_constraint_list *sysclk_constraints; - unsigned int tdm_mode; - struct delayed_work pcm_pop_work; -}; -struct snd_soc_component *tron_codec1[ADC_DEV_MAXNUM]; +struct snd_soc_component *tron_codec1[4]; int es7210_init_reg = 0; +int es7210_hw_param_reg = 0; static int es7210_codec_num = 0; static const struct regmap_config es7210_regmap_config = { @@ -162,9 +157,6 @@ static const struct es7210_reg_config es7210_tdm_reg_fmt_cfg[] = { }; static const struct es7210_reg_config es7210_tdm_reg_common_cfg2[] = { { 0x40, 0xC3 }, - { 0x14, 0x3C }, - { 0x15, 0x3C }, - { 0x17, 0x00 }, { 0x41, 0x70 }, { 0x42, 0x70 }, { 0x43, 0x1E }, @@ -286,12 +278,185 @@ static int es7210_set_dai_fmt(struct snd_soc_dai *codec_dai, { return 0; } +static void es7210_tdm_init_ratio(struct es7210_priv *priv) +{ + int cnt, channel, width; + + channel = ES7210_CHANNELS_MAX; + + switch(priv->tdm_mode) { + case ES7210_TDM_1LRCK_DSPB: + switch(priv->pcm_format) { + case SNDRV_PCM_FORMAT_S16_LE: + width = 16; + break; + case SNDRV_PCM_FORMAT_S32_LE: + width = 32; + } + break; + case ES7210_NORMAL_I2S: + width = 32; + if (channel > 2) // i2s 8ch has 2 channels in actual. + channel = 2; + break; + default: + break; + } + + priv->sclk_lrck_ratio = channel * width ; + + switch(priv->sclk_lrck_ratio * priv->mclk_sclk_ratio) { + case 64: + priv->mclk_lrck_ratio = RATIO_64; + break; + case 128: + priv->mclk_lrck_ratio = RATIO_128; + break; + case 256: + priv->mclk_lrck_ratio = RATIO_256; + break; + case 768: + priv->mclk_lrck_ratio = RATIO_768; + break; + default: + pr_err("%s Unable to calculate proper mclk_lrck_ratio with sclk_lrck_ratio=%d!\n", __func__, priv->sclk_lrck_ratio); + break; + } + + switch (priv->tdm_mode) { + case ES7210_TDM_1LRCK_DSPA: + case ES7210_TDM_1LRCK_DSPB: + case ES7210_TDM_1LRCK_I2S: + case ES7210_TDM_1LRCK_LJ: + case ES7210_NORMAL_I2S: + /* + * to set internal mclk + * here, we assume that cpu/soc always provides + * 256FS i2s clock + * to es7210. + * dll bypassed, use clock doubler to get double + * frequency for + * internal modem which need + * 512FS clock. the clk divider ratio is 1. + * user must modify the setting of register0x02 + * according to FS + * ratio provided by CPU/SOC. + */ + + for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { + es7210_write(ES7210_MCLK_CTL_REG02, + priv->mclk_lrck_ratio, i2c_clt1[cnt]); + } + // es7210_multi_chips_write(ES7210_MCLK_CTL_REG02, + // 0xc1); + break; + case ES7210_TDM_NLRCK_DSPA: + case ES7210_TDM_NLRCK_DSPB: + case ES7210_TDM_NLRCK_I2S: + case ES7210_TDM_NLRCK_LJ: + /* + * Here to set TDM format for DSP-A with + * multiple LRCK TDM mode + */ + channel = ES7210_CHANNELS_MAX; + /* + * Set the microphone numbers in array + */ + switch (channel) { + case 2: + /* ES7210_CHANNELS_MAX=2 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x10); + break; + case 4: + /* ES7210_CHANNELS_MAX=4 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x20); + break; + case 6: + /* ES7210_CHANNELS_MAX=6 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x30); + break; + case 8: + /* ES7210_CHANNELS_MAX=8 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x40); + break; + case 10: + /* ES7210_CHANNELS_MAX=10 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x50); + break; + case 12: + /* ES7210_CHANNELS_MAX=12 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x60); + break; + case 14: + /* ES7210_CHANNELS_MAX=14 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x70); + break; + case 16: + /* ES7210_CHANNELS_MAX=16 */ + es7210_multi_chips_write( + ES7210_MODE_CFG_REG08, 0x80); + break; + default: + break; + } + /* + * to set internal mclk + * here, we assume that cpu/soc always provides + * 256FS i2s clock + * to es7210 and there is four + * es7210 devices in tdm link. so the + * internal FS in es7210 + * is only FS/4; + * dll bypassed, clock doubler bypassed. the clk + * divider ratio is + * 2. so the clock of internal + * modem equals to (256FS / (FS/4) / 2) * FS + * = 512FS + * user must modify the setting of register0x02 + * according to FS + * ratio provided by CPU/SOC. + */ + + es7210_multi_chips_write(ES7210_MCLK_CTL_REG02, + priv->mclk_lrck_ratio);// NFS MODE:RATIO_768 ,12.288M/48K(16K 6 CH),12.288M/64K(16K 8 CH) + break; + default: + /* + * to set internal mclk for normal mode + * here, we assume that cpu/soc always provides + * 256FS i2s clock + * to es7210. + * dll bypassed, use clock doubler to get double + * frequency for + * internal modem which need + * 512FS clock. the clk divider ratio is 1. + * user must modify the setting of register0x02 + * according to FS + * ratio provided by CPU/SOC. + */ + for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { + es7210_write(ES7210_MCLK_CTL_REG02, + priv->mclk_lrck_ratio, i2c_clt1[cnt]); + } + + break; + } + return; +} + /* * to initialize es7210 for tdm mode */ static void es7210_tdm_init_codec(u8 mode) { - int cnt, channel, i; + int cnt, i; for (cnt = 0; cnt < sizeof(es7210_tdm_reg_common_cfg1) / @@ -302,9 +467,7 @@ static void es7210_tdm_init_codec(u8 mode) es7210_tdm_reg_common_cfg1[cnt].reg_v); } if(DOUBLESPEED) - es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x16); - else - es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x14); + es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0x02, 0x02); switch (mode) { case ES7210_TDM_1LRCK_DSPA: @@ -324,7 +487,7 @@ static void es7210_tdm_init_codec(u8 mode) */ for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { es7210_write(ES7210_SDP_CFG1_REG11, - 0x83, i2c_clt1[cnt]); + 0x73, i2c_clt1[cnt]); es7210_write(ES7210_SDP_CFG2_REG12, 0x01, i2c_clt1[cnt]); } @@ -385,7 +548,7 @@ static void es7210_tdm_init_codec(u8 mode) */ for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { es7210_write(ES7210_SDP_CFG1_REG11, - 0x83, i2c_clt1[cnt]); + 0x73, i2c_clt1[cnt]); } for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { if (cnt == 0) { @@ -491,134 +654,7 @@ static void es7210_tdm_init_codec(u8 mode) es7210_tdm_reg_common_cfg2[cnt].reg_addr, es7210_tdm_reg_common_cfg2[cnt].reg_v); } - es7210_multi_chips_write(0x4, 0x00); - es7210_multi_chips_write(0x5, 0x40); - switch (mode) { - case ES7210_TDM_1LRCK_DSPA: - case ES7210_TDM_1LRCK_DSPB: - case ES7210_TDM_1LRCK_I2S: - case ES7210_TDM_1LRCK_LJ: - case ES7210_NORMAL_I2S: - /* - * to set internal mclk - * here, we assume that cpu/soc always provides - * 256FS i2s clock - * to es7210. - * dll bypassed, use clock doubler to get double - * frequency for - * internal modem which need - * 512FS clock. the clk divider ratio is 1. - * user must modify the setting of register0x02 - * according to FS - * ratio provided by CPU/SOC. - */ - - for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { - es7210_write(ES7210_MCLK_CTL_REG02, - ES7210_MCLK_LRCK_RATIO, i2c_clt1[cnt]); - } - // es7210_multi_chips_write(ES7210_MCLK_CTL_REG02, - // 0xc1); - break; - case ES7210_TDM_NLRCK_DSPA: - case ES7210_TDM_NLRCK_DSPB: - case ES7210_TDM_NLRCK_I2S: - case ES7210_TDM_NLRCK_LJ: - /* - * Here to set TDM format for DSP-A with - * multiple LRCK TDM mode - */ - channel = ES7210_CHANNELS_MAX; - /* - * Set the microphone numbers in array - */ - switch (channel) { - case 2: - /* ES7210_CHANNELS_MAX=2 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x10); - break; - case 4: - /* ES7210_CHANNELS_MAX=4 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x20); - break; - case 6: - /* ES7210_CHANNELS_MAX=6 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x30); - break; - case 8: - /* ES7210_CHANNELS_MAX=8 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x40); - break; - case 10: - /* ES7210_CHANNELS_MAX=10 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x50); - break; - case 12: - /* ES7210_CHANNELS_MAX=12 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x60); - break; - case 14: - /* ES7210_CHANNELS_MAX=14 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x70); - break; - case 16: - /* ES7210_CHANNELS_MAX=16 */ - es7210_multi_chips_write( - ES7210_MODE_CFG_REG08, 0x80); - break; - default: - break; - } - /* - * to set internal mclk - * here, we assume that cpu/soc always provides - * 256FS i2s clock - * to es7210 and there is four - * es7210 devices in tdm link. so the - * internal FS in es7210 - * is only FS/4; - * dll bypassed, clock doubler bypassed. the clk - * divider ratio is - * 2. so the clock of internal - * modem equals to (256FS / (FS/4) / 2) * FS - * = 512FS - * user must modify the setting of register0x02 - * according to FS - * ratio provided by CPU/SOC. - */ - - es7210_multi_chips_write(ES7210_MCLK_CTL_REG02, - ES7210_MCLK_LRCK_RATIO);// NFS MODE:RATIO_768 ,12.288M/48K(16K 6 CH),12.288M/64K(16K 8 CH) - break; - default: - /* - * to set internal mclk for normal mode - * here, we assume that cpu/soc always provides - * 256FS i2s clock - * to es7210. - * dll bypassed, use clock doubler to get double - * frequency for - * internal modem which need - * 512FS clock. the clk divider ratio is 1. - * user must modify the setting of register0x02 - * according to FS - * ratio provided by CPU/SOC. - */ - for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { - es7210_write(ES7210_MCLK_CTL_REG02, - ES7210_MCLK_LRCK_RATIO, i2c_clt1[cnt]); - } - - break; - } for (cnt = 0; cnt < sizeof(es7210_tdm_reg_common_cfg3) / sizeof(es7210_tdm_reg_common_cfg3[0]); @@ -651,52 +687,53 @@ static void es7210_tdm_init_codec(u8 mode) } if (i == 1) { /* set second es7210 PGA GAIN */ - es7210_write(ES7210_MIC1_GAIN_REG43, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC1_GAIN_REG43, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC2_GAIN_REG44, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC2_GAIN_REG44, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC3_GAIN_REG45, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC3_GAIN_REG45, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC4_GAIN_REG46, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC4_GAIN_REG46, ES7210_MIC_GAIN, i2c_clt1[i]); } if (i == 2) { /* set third es7210 PGA GAIN */ - es7210_write(ES7210_MIC1_GAIN_REG43, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC1_GAIN_REG43, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC2_GAIN_REG44, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC2_GAIN_REG44, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC3_GAIN_REG45, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC3_GAIN_REG45, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC4_GAIN_REG46, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC4_GAIN_REG46, ES7210_MIC_GAIN, i2c_clt1[i]); } if (i == 3) { /* set third es7210 PGA GAIN */ - es7210_write(ES7210_MIC1_GAIN_REG43, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC1_GAIN_REG43, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC2_GAIN_REG44, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC2_GAIN_REG44, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC3_GAIN_REG45, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC3_GAIN_REG45, ES7210_MIC_GAIN, i2c_clt1[i]); - es7210_write(ES7210_MIC4_GAIN_REG46, ES7210_AEC_GAIN, + es7210_write(ES7210_MIC4_GAIN_REG46, ES7210_MIC_GAIN, i2c_clt1[i]); } } } static void es7210_unmute(void) { - printk("enter into %s\n", __func__); es7210_multi_chips_update_bits(ES7210_ADC34_MUTE_REG14, 0x03, 0x00); es7210_multi_chips_update_bits(ES7210_ADC12_MUTE_REG15, 0x03, 0x00); + es7210_multi_chips_update_bits(ES7210_MIC1_GAIN_REG43, 0x1f, ES7210_MIC_GAIN); + es7210_multi_chips_update_bits(ES7210_MIC2_GAIN_REG44, 0x1f, ES7210_MIC_GAIN); + es7210_multi_chips_update_bits(ES7210_MIC3_GAIN_REG45, 0x1f, ES7210_MIC_GAIN); + es7210_multi_chips_update_bits(ES7210_MIC4_GAIN_REG46, 0x1f, ES7210_MIC_GAIN); } static void pcm_pop_work_events(struct work_struct *work) { - printk("enter into %s\n", __func__); es7210_unmute(); - es7210_init_reg = 1; } static int es7210_pcm_startup(struct snd_pcm_substream *substream, @@ -706,6 +743,7 @@ static int es7210_pcm_startup(struct snd_pcm_substream *substream, struct es7210_priv *es7210 = snd_soc_component_get_drvdata(component); if (es7210_init_reg == 0) { + es7210_init_reg = 1; schedule_delayed_work(&es7210->pcm_pop_work, msecs_to_jiffies(100)); } return 0; @@ -714,13 +752,22 @@ static int es7210_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 es7210_priv *priv = snd_soc_component_get_drvdata(component); int i; + if (es7210_hw_param_reg == 1 && params_format(params) == priv->pcm_format) { + return 0; + } + + es7210_hw_param_reg = 1; + priv->pcm_format = params_format(params); + es7210_tdm_init_ratio(priv); + es7210_multi_chips_update_bits(ES7210_RESET_CTL_REG00, 0x30, 0x30); for (i = 0; i < ADC_DEV_MAXNUM; i++) { /* set es7210 bit size */ - switch (params_format(params)) { + switch (priv->pcm_format) { case SNDRV_PCM_FORMAT_S16_LE: es7210_update_bits(0x11, 0xE0, 0x60, i2c_clt1[i]); @@ -753,6 +800,7 @@ static int es7210_pcm_hw_params(struct snd_pcm_substream *substream, default: break; } + return 0; } @@ -767,7 +815,7 @@ static struct snd_soc_dai_ops es7210_ops = { .set_fmt = es7210_set_dai_fmt, .set_sysclk = es7210_set_dai_sysclk, }; -#if ES7210_CHANNELS_MAX > 0 + static struct snd_soc_dai_driver es7210_dai0 = { .name = "ES7210 ADC 0", .capture = { @@ -779,8 +827,8 @@ static struct snd_soc_dai_driver es7210_dai0 = { }, .ops = &es7210_ops, }; -#endif -#if ES7210_CHANNELS_MAX > 4 + + static struct snd_soc_dai_driver es7210_dai1 = { .name = "ES7210 4CH ADC 1", .capture = { @@ -792,8 +840,7 @@ static struct snd_soc_dai_driver es7210_dai1 = { }, .ops = &es7210_ops, }; -#endif -#if ES7210_CHANNELS_MAX > 8 + static struct snd_soc_dai_driver es7210_dai2 = { .name = "ES7210 4CH ADC 2", .capture = { @@ -805,8 +852,7 @@ static struct snd_soc_dai_driver es7210_dai2 = { }, .ops = &es7210_ops, }; -#endif -#if ES7210_CHANNELS_MAX > 12 + static struct snd_soc_dai_driver es7210_dai3 = { .name = "ES7210 4CH ADC 3", .capture = { @@ -818,89 +864,191 @@ static struct snd_soc_dai_driver es7210_dai3 = { }, .ops = &es7210_ops, }; -#endif + static struct snd_soc_dai_driver *es7210_dai[] = { -#if ES7210_CHANNELS_MAX > 0 &es7210_dai0, -#endif -#if ES7210_CHANNELS_MAX > 4 &es7210_dai1, -#endif -#if ES7210_CHANNELS_MAX > 8 &es7210_dai2, -#endif -#if ES7210_CHANNELS_MAX > 12 &es7210_dai3, -#endif }; +#ifdef CONFIG_PM_SLEEP static int es7210_suspend(struct snd_soc_component *component) { int i = 0; - - printk("es7210_suspend enter\n"); + struct es7210_priv *priv = snd_soc_component_get_drvdata(component); for (i = 0; i < ADC_DEV_MAXNUM; i++) { - if (i == 1) { - es7210_write(0x06, 0x05, i2c_clt1[i]); - es7210_write(0x05, 0x1B, i2c_clt1[i]); - es7210_write(0x06, 0x5C, i2c_clt1[i]); - es7210_write(0x07, 0x3F, i2c_clt1[i]); - es7210_write(0x08, 0x4B, i2c_clt1[i]); - es7210_write(0x09, 0x9F, i2c_clt1[i]); - - } else { - /*turn off mic3/4 */ - - es7210_write(0x4C, 0xFF, i2c_clt1[i]); - es7210_write(0x0B, 0xD0, i2c_clt1[i]); - es7210_write(0x40, 0x80, i2c_clt1[i]); - es7210_write(0x01, 0x34, i2c_clt1[i]); - es7210_write(0x06, 0x07, i2c_clt1[i]); - /*turn off mic 1/2/3/4 */ - /* - es7210_write(0x4B, 0xFF, i2c_clt1[i]); - es7210_write(0x4C, 0xFF, i2c_clt1[i]); - es7210_write(0x0B, 0xD0, i2c_clt1[i]); - es7210_write(0x40, 0x80, i2c_clt1[i]); - es7210_write(0x01, 0x7F, i2c_clt1[i]); - es7210_write(0x06, 0x07, i2c_clt1[i]); - */ - } + es7210_read(ES7210_RESET_CTL_REG00, &priv->suspend_reg00[i], i2c_clt1[i]); + es7210_read(ES7210_CLK_ON_OFF_REG01, &priv->suspend_reg01[i], i2c_clt1[i]); + es7210_read(ES7210_MCLK_CTL_REG02, &priv->suspend_reg02[i], i2c_clt1[i]); + es7210_read(ES7210_MST_CLK_CTL_REG03, &priv->suspend_reg03[i], i2c_clt1[i]); + es7210_read(ES7210_MST_LRCDIVH_REG04, &priv->suspend_reg04[i], i2c_clt1[i]); + es7210_read(ES7210_MST_LRCDIVL_REG05, &priv->suspend_reg05[i], i2c_clt1[i]); + es7210_read(ES7210_DIGITAL_PDN_REG06, &priv->suspend_reg06[i], i2c_clt1[i]); + es7210_read(ES7210_ADC_OSR_REG07, &priv->suspend_reg07[i], i2c_clt1[i]); + es7210_read(ES7210_MODE_CFG_REG08, &priv->suspend_reg08[i], i2c_clt1[i]); + es7210_read(ES7210_TCT0_CHPINI_REG09, &priv->suspend_reg09[i], i2c_clt1[i]); + es7210_read(ES7210_TCT1_CHPINI_REG0A, &priv->suspend_reg0A[i], i2c_clt1[i]); + es7210_read(ES7210_CHIP_STA_REG0B, &priv->suspend_reg0B[i], i2c_clt1[i]); + es7210_read(ES7210_IRQ_CTL_REG0C, &priv->suspend_reg0C[i], i2c_clt1[i]); + es7210_read(ES7210_MISC_CTL_REG0D, &priv->suspend_reg0D[i], i2c_clt1[i]); + es7210_read(ES7210_DMIC_CTL_REG10, &priv->suspend_reg10[i], i2c_clt1[i]); + es7210_read(ES7210_SDP_CFG1_REG11, &priv->suspend_reg11[i], i2c_clt1[i]); + es7210_read(ES7210_SDP_CFG2_REG12, &priv->suspend_reg12[i], i2c_clt1[i]); + es7210_read(ES7210_ADC_AUTOMUTE_REG13, &priv->suspend_reg13[i], i2c_clt1[i]); + es7210_read(ES7210_ADC34_MUTE_REG14, &priv->suspend_reg14[i], i2c_clt1[i]); + es7210_read(ES7210_ADC12_MUTE_REG15, &priv->suspend_reg15[i], i2c_clt1[i]); + es7210_read(ES7210_ALC_SEL_REG16, &priv->suspend_reg16[i], i2c_clt1[i]); + es7210_read(ES7210_ALC_COM_CFG1_REG17, &priv->suspend_reg17[i], i2c_clt1[i]); + es7210_read(ES7210_ALC34_LVL_REG18, &priv->suspend_reg18[i], i2c_clt1[i]); + es7210_read(ES7210_ALC12_LVL_REG19, &priv->suspend_reg19[i], i2c_clt1[i]); + es7210_read(ES7210_ALC_COM_CFG2_REG1A, &priv->suspend_reg1A[i], i2c_clt1[i]); + es7210_read(ES7210_ALC4_MAX_GAIN_REG1B, &priv->suspend_reg1B[i], i2c_clt1[i]); + es7210_read(ES7210_ALC3_MAX_GAIN_REG1C, &priv->suspend_reg1C[i], i2c_clt1[i]); + es7210_read(ES7210_ALC2_MAX_GAIN_REG1D, &priv->suspend_reg1D[i], i2c_clt1[i]); + es7210_read(ES7210_ALC1_MAX_GAIN_REG1E, &priv->suspend_reg1E[i], i2c_clt1[i]); + es7210_read(ES7210_ADC34_HPF2_REG20, &priv->suspend_reg20[i], i2c_clt1[i]); + es7210_read(ES7210_ADC34_HPF1_REG21, &priv->suspend_reg21[i], i2c_clt1[i]); + es7210_read(ES7210_ADC12_HPF2_REG22, &priv->suspend_reg22[i], i2c_clt1[i]); + es7210_read(ES7210_ADC12_HPF1_REG23, &priv->suspend_reg23[i], i2c_clt1[i]); + es7210_read(ES7210_ANALOG_SYS_REG40, &priv->suspend_reg40[i], i2c_clt1[i]); + es7210_read(ES7210_MICBIAS12_REG41, &priv->suspend_reg41[i], i2c_clt1[i]); + es7210_read(ES7210_MICBIAS34_REG42, &priv->suspend_reg42[i], i2c_clt1[i]); + es7210_read(ES7210_MIC1_GAIN_REG43, &priv->suspend_reg43[i], i2c_clt1[i]); + es7210_read(ES7210_MIC2_GAIN_REG44, &priv->suspend_reg44[i], i2c_clt1[i]); + es7210_read(ES7210_MIC3_GAIN_REG45, &priv->suspend_reg45[i], i2c_clt1[i]); + es7210_read(ES7210_MIC4_GAIN_REG46, &priv->suspend_reg46[i], i2c_clt1[i]); + es7210_read(ES7210_MIC1_LP_REG47, &priv->suspend_reg47[i], i2c_clt1[i]); + es7210_read(ES7210_MIC2_LP_REG48, &priv->suspend_reg48[i], i2c_clt1[i]); + es7210_read(ES7210_MIC3_LP_REG49, &priv->suspend_reg49[i], i2c_clt1[i]); + es7210_read(ES7210_MIC4_LP_REG4A, &priv->suspend_reg4A[i], i2c_clt1[i]); + es7210_read(ES7210_MIC12_PDN_REG4B, &priv->suspend_reg4B[i], i2c_clt1[i]); + es7210_read(ES7210_MIC34_PDN_REG4C, &priv->suspend_reg4C[i], i2c_clt1[i]); } es7210_init_reg = 0; + + /* power down the controller */ + if (priv->pvdd) + regulator_disable(priv->pvdd); + if (priv->dvdd) + regulator_disable(priv->dvdd); + if (priv->avdd) + regulator_disable(priv->avdd); + if (priv->mvdd) + regulator_disable(priv->mvdd); + return 0; } static int es7210_resume(struct snd_soc_component *component) { - es7210_tdm_init_codec(resume_es7210->tdm_mode); - return 0; + int ret = 0, i = 0; + struct es7210_priv *priv = snd_soc_component_get_drvdata(component); + + /* power up the controller */ + if (priv->mvdd) + ret |= regulator_enable(priv->mvdd); + if (priv->avdd) + ret |= regulator_enable(priv->avdd); + if (priv->dvdd) + ret |= regulator_enable(priv->dvdd); + if (priv->pvdd) + ret |= regulator_enable(priv->pvdd); + if (ret) { + pr_err("Failed to enable VDD regulator: %d\n", ret); + return ret; + } + mdelay(10); // es7210 need 10ms setup time after power up. + + for (i = 0; i < ADC_DEV_MAXNUM; i++) { + es7210_write(ES7210_RESET_CTL_REG00, priv->suspend_reg00[i], i2c_clt1[i]); + es7210_write(ES7210_CLK_ON_OFF_REG01, priv->suspend_reg01[i], i2c_clt1[i]); + es7210_write(ES7210_MCLK_CTL_REG02, priv->suspend_reg02[i], i2c_clt1[i]); + es7210_write(ES7210_MST_CLK_CTL_REG03, priv->suspend_reg03[i], i2c_clt1[i]); + es7210_write(ES7210_MST_LRCDIVH_REG04, priv->suspend_reg04[i], i2c_clt1[i]); + es7210_write(ES7210_MST_LRCDIVL_REG05, priv->suspend_reg05[i], i2c_clt1[i]); + es7210_write(ES7210_DIGITAL_PDN_REG06, priv->suspend_reg06[i], i2c_clt1[i]); + es7210_write(ES7210_ADC_OSR_REG07, priv->suspend_reg07[i], i2c_clt1[i]); + es7210_write(ES7210_MODE_CFG_REG08, priv->suspend_reg08[i], i2c_clt1[i]); + es7210_write(ES7210_TCT0_CHPINI_REG09, priv->suspend_reg09[i], i2c_clt1[i]); + es7210_write(ES7210_TCT1_CHPINI_REG0A, priv->suspend_reg0A[i], i2c_clt1[i]); + es7210_write(ES7210_CHIP_STA_REG0B, priv->suspend_reg0B[i], i2c_clt1[i]); + es7210_write(ES7210_IRQ_CTL_REG0C, priv->suspend_reg0C[i], i2c_clt1[i]); + es7210_write(ES7210_MISC_CTL_REG0D, priv->suspend_reg0D[i], i2c_clt1[i]); + es7210_write(ES7210_DMIC_CTL_REG10, priv->suspend_reg10[i], i2c_clt1[i]); + es7210_write(ES7210_SDP_CFG1_REG11, priv->suspend_reg11[i], i2c_clt1[i]); + es7210_write(ES7210_SDP_CFG2_REG12, priv->suspend_reg12[i], i2c_clt1[i]); + es7210_write(ES7210_ADC_AUTOMUTE_REG13, priv->suspend_reg13[i], i2c_clt1[i]); + es7210_write(ES7210_ADC34_MUTE_REG14, priv->suspend_reg14[i], i2c_clt1[i]); + es7210_write(ES7210_ADC12_MUTE_REG15, priv->suspend_reg15[i], i2c_clt1[i]); + es7210_write(ES7210_ALC_SEL_REG16, priv->suspend_reg16[i], i2c_clt1[i]); + es7210_write(ES7210_ALC_COM_CFG1_REG17, priv->suspend_reg17[i], i2c_clt1[i]); + es7210_write(ES7210_ALC34_LVL_REG18, priv->suspend_reg18[i], i2c_clt1[i]); + es7210_write(ES7210_ALC12_LVL_REG19, priv->suspend_reg19[i], i2c_clt1[i]); + es7210_write(ES7210_ALC_COM_CFG2_REG1A, priv->suspend_reg1A[i], i2c_clt1[i]); + es7210_write(ES7210_ALC4_MAX_GAIN_REG1B, priv->suspend_reg1B[i], i2c_clt1[i]); + es7210_write(ES7210_ALC3_MAX_GAIN_REG1C, priv->suspend_reg1C[i], i2c_clt1[i]); + es7210_write(ES7210_ALC2_MAX_GAIN_REG1D, priv->suspend_reg1D[i], i2c_clt1[i]); + es7210_write(ES7210_ALC1_MAX_GAIN_REG1E, priv->suspend_reg1E[i], i2c_clt1[i]); + es7210_write(ES7210_ADC34_HPF2_REG20, priv->suspend_reg20[i], i2c_clt1[i]); + es7210_write(ES7210_ADC34_HPF1_REG21, priv->suspend_reg21[i], i2c_clt1[i]); + es7210_write(ES7210_ADC12_HPF2_REG22, priv->suspend_reg22[i], i2c_clt1[i]); + es7210_write(ES7210_ADC12_HPF1_REG23, priv->suspend_reg23[i], i2c_clt1[i]); + es7210_write(ES7210_ANALOG_SYS_REG40, priv->suspend_reg40[i], i2c_clt1[i]); + es7210_write(ES7210_MICBIAS12_REG41, priv->suspend_reg41[i], i2c_clt1[i]); + es7210_write(ES7210_MICBIAS34_REG42, priv->suspend_reg42[i], i2c_clt1[i]); + es7210_write(ES7210_MIC1_GAIN_REG43, priv->suspend_reg43[i], i2c_clt1[i]); + es7210_write(ES7210_MIC2_GAIN_REG44, priv->suspend_reg44[i], i2c_clt1[i]); + es7210_write(ES7210_MIC3_GAIN_REG45, priv->suspend_reg45[i], i2c_clt1[i]); + es7210_write(ES7210_MIC4_GAIN_REG46, priv->suspend_reg46[i], i2c_clt1[i]); + es7210_write(ES7210_MIC1_LP_REG47, priv->suspend_reg47[i], i2c_clt1[i]); + es7210_write(ES7210_MIC2_LP_REG48, priv->suspend_reg48[i], i2c_clt1[i]); + es7210_write(ES7210_MIC3_LP_REG49, priv->suspend_reg49[i], i2c_clt1[i]); + es7210_write(ES7210_MIC4_LP_REG4A, priv->suspend_reg4A[i], i2c_clt1[i]); + es7210_write(ES7210_MIC12_PDN_REG4B, priv->suspend_reg4B[i], i2c_clt1[i]); + es7210_write(ES7210_MIC34_PDN_REG4C, priv->suspend_reg4C[i], i2c_clt1[i]); + } + + return ret; } +#endif static int es7210_probe(struct snd_soc_component *component) { struct es7210_priv *es7210 = snd_soc_component_get_drvdata(component); - u8 val, val1; + u8 val, val1, cnt; int ret = 0; resume_es7210 = es7210; - if (ret < 0) { - dev_err(component->dev, "Failed to set cache I/O: %d\n", ret); + /* power up the controller */ + if (es7210->mvdd) + ret |= regulator_enable(es7210->mvdd); + if (es7210->avdd) + ret |= regulator_enable(es7210->avdd); + if (es7210->dvdd) + ret |= regulator_enable(es7210->dvdd); + if (es7210->pvdd) + ret |= regulator_enable(es7210->pvdd); + if (ret) { + pr_err("Failed to enable VDD regulator: %d\n", ret); return ret; } tron_codec1[es7210_codec_num++] = component; + INIT_DELAYED_WORK(&es7210->pcm_pop_work, pcm_pop_work_events); - /* es7210 chip id */ - ret = es7210_read(0x3D, &val, i2c_clt1[0]); - ret = es7210_read(0x3E, &val1, i2c_clt1[0]); - if (ret < 0) { - pr_err("%s: read chipid failed %d\n", __func__, ret); - goto exit_i2c_check_id_failed; - } + for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) { + /* es7210 chip id */ + ret = es7210_read(0x3D, &val, i2c_clt1[cnt]); + ret = es7210_read(0x3E, &val1, i2c_clt1[cnt]); + if (ret < 0) { + pr_err("%s: read chipid failed %d\n", __func__, ret); + goto exit_i2c_check_id_failed; + } + } es7210_tdm_init_codec(es7210->tdm_mode); @@ -908,7 +1056,20 @@ exit_i2c_check_id_failed: return 0; } +static void es7210_remove(struct snd_soc_component *component) +{ + struct es7210_priv *es7210 = snd_soc_component_get_drvdata(component); + /* power down the controller */ + if (es7210->pvdd) + regulator_disable(es7210->pvdd); + if (es7210->dvdd) + regulator_disable(es7210->dvdd); + if (es7210->avdd) + regulator_disable(es7210->avdd); + if (es7210->mvdd) + regulator_disable(es7210->mvdd); +} static int es7210_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) @@ -930,7 +1091,6 @@ static int es7210_set_bias_level(struct snd_soc_component *component, static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 300, 0); -#if ES7210_CHANNELS_MAX > 0 static int es7210_micboost1_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1061,12 +1221,11 @@ static int es7210_adc4_mute_get(struct snd_kcontrol *kcontrol, return 0; } -#endif - -#if ES7210_CHANNELS_MAX > 4 static int es7210_micboost5_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(0x43, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[1]); return 0; } @@ -1075,6 +1234,8 @@ static int es7210_micboost5_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(0x43, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = val; return 0; @@ -1082,6 +1243,8 @@ static int es7210_micboost5_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost6_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(0x44, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[1]); return 0; } @@ -1090,6 +1253,8 @@ static int es7210_micboost6_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(0x44, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = val; return 0; @@ -1097,6 +1262,8 @@ static int es7210_micboost6_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost7_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(0x45, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[1]); return 0; } @@ -1105,6 +1272,8 @@ static int es7210_micboost7_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(0x45, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = val; return 0; @@ -1112,6 +1281,8 @@ static int es7210_micboost7_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost8_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(0x46, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[1]); return 0; } @@ -1120,6 +1291,8 @@ static int es7210_micboost8_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(0x46, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = val; return 0; @@ -1127,8 +1300,10 @@ static int es7210_micboost8_setting_get(struct snd_kcontrol *kcontrol, static int es7210_adc5_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(ES7210_ADC12_MUTE_REG15, 0x01, - ucontrol->value.integer.value[0]&0x01, i2c_clt1[1]); + ucontrol->value.integer.value[0]&0x01, i2c_clt1[1]); return 0; } @@ -1136,6 +1311,8 @@ static int es7210_adc5_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(ES7210_ADC12_MUTE_REG15, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = val & 0x01; return 0; @@ -1144,6 +1321,8 @@ static int es7210_adc5_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc6_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(ES7210_ADC12_MUTE_REG15, 0x02, (ucontrol->value.integer.value[0] & 0x01) << 1, i2c_clt1[1]); return 0; @@ -1153,6 +1332,8 @@ static int es7210_adc6_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(ES7210_ADC12_MUTE_REG15, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = (val & 0x02) >> 1; return 0; @@ -1161,6 +1342,8 @@ static int es7210_adc6_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc7_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(ES7210_ADC34_MUTE_REG14, 0x01, ucontrol->value.integer.value[0]&0x01, i2c_clt1[1]); return 0; @@ -1170,6 +1353,8 @@ static int es7210_adc7_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(ES7210_ADC34_MUTE_REG14, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = val & 0x01; return 0; @@ -1177,6 +1362,8 @@ static int es7210_adc7_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc8_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[1] == NULL) + return 0; es7210_update_bits(ES7210_ADC34_MUTE_REG14, 0x02, (ucontrol->value.integer.value[0] & 0x01) << 1, i2c_clt1[1]); return 0; @@ -1186,16 +1373,18 @@ static int es7210_adc8_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[1] == NULL) + return 0; es7210_read(ES7210_ADC34_MUTE_REG14, &val, i2c_clt1[1]); ucontrol->value.integer.value[0] = (val & 0x02) >> 1; return 0; } -#endif -#if ES7210_CHANNELS_MAX > 8 static int es7210_micboost9_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(0x43, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[2]); return 0; } @@ -1204,6 +1393,8 @@ static int es7210_micboost9_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(0x43, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = val; return 0; @@ -1211,6 +1402,8 @@ static int es7210_micboost9_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost10_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(0x44, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[2]); return 0; } @@ -1219,6 +1412,8 @@ static int es7210_micboost10_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(0x44, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = val; return 0; @@ -1226,6 +1421,8 @@ static int es7210_micboost10_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost11_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(0x45, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[2]); return 0; } @@ -1234,6 +1431,8 @@ static int es7210_micboost11_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(0x45, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = val; return 0; @@ -1241,6 +1440,8 @@ static int es7210_micboost11_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost12_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(0x46, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[2]); return 0; } @@ -1249,6 +1450,8 @@ static int es7210_micboost12_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(0x46, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = val; return 0; @@ -1256,8 +1459,10 @@ static int es7210_micboost12_setting_get(struct snd_kcontrol *kcontrol, static int es7210_adc9_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(ES7210_ADC12_MUTE_REG15, 0x01, - ucontrol->value.integer.value[0]&0x01, i2c_clt1[2]); + ucontrol->value.integer.value[0]&0x01, i2c_clt1[2]); return 0; } @@ -1265,6 +1470,8 @@ static int es7210_adc9_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(ES7210_ADC12_MUTE_REG15, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = val & 0x01; return 0; @@ -1273,6 +1480,8 @@ static int es7210_adc9_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc10_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(ES7210_ADC12_MUTE_REG15, 0x02, (ucontrol->value.integer.value[0] & 0x01) << 1, i2c_clt1[2]); return 0; @@ -1282,6 +1491,8 @@ static int es7210_adc10_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(ES7210_ADC12_MUTE_REG15, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = (val & 0x02) >> 1; return 0; @@ -1290,6 +1501,8 @@ static int es7210_adc10_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc11_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(ES7210_ADC34_MUTE_REG14, 0x01, ucontrol->value.integer.value[0]&0x01, i2c_clt1[2]); return 0; @@ -1299,6 +1512,8 @@ static int es7210_adc11_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(ES7210_ADC34_MUTE_REG14, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = val & 0x01; return 0; @@ -1306,6 +1521,8 @@ static int es7210_adc11_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc12_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[2] == NULL) + return 0; es7210_update_bits(ES7210_ADC34_MUTE_REG14, 0x02, (ucontrol->value.integer.value[0] & 0x01) << 1, i2c_clt1[2]); return 0; @@ -1315,16 +1532,18 @@ static int es7210_adc12_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[2] == NULL) + return 0; es7210_read(ES7210_ADC34_MUTE_REG14, &val, i2c_clt1[2]); ucontrol->value.integer.value[0] = (val & 0x02) >> 1; return 0; } -#endif -#if ES7210_CHANNELS_MAX > 12 static int es7210_micboost13_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(0x43, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[3]); return 0; } @@ -1333,6 +1552,8 @@ static int es7210_micboost13_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(0x43, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = val; return 0; @@ -1340,6 +1561,8 @@ static int es7210_micboost13_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost14_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(0x44, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[3]); return 0; } @@ -1348,6 +1571,8 @@ static int es7210_micboost14_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(0x44, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = val; return 0; @@ -1355,6 +1580,8 @@ static int es7210_micboost14_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost15_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(0x45, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[3]); return 0; } @@ -1363,6 +1590,8 @@ static int es7210_micboost15_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(0x45, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = val; return 0; @@ -1370,6 +1599,8 @@ static int es7210_micboost15_setting_get(struct snd_kcontrol *kcontrol, static int es7210_micboost16_setting_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(0x46, 0x0F, ucontrol->value.integer.value[0], i2c_clt1[3]); return 0; } @@ -1378,6 +1609,8 @@ static int es7210_micboost16_setting_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(0x46, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = val; return 0; @@ -1385,8 +1618,10 @@ static int es7210_micboost16_setting_get(struct snd_kcontrol *kcontrol, static int es7210_adc13_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(ES7210_ADC12_MUTE_REG15, 0x01, - ucontrol->value.integer.value[0]&0x01, i2c_clt1[3]); + ucontrol->value.integer.value[0]&0x01, i2c_clt1[3]); return 0; } @@ -1394,6 +1629,8 @@ static int es7210_adc13_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(ES7210_ADC12_MUTE_REG15, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = val & 0x01; return 0; @@ -1402,6 +1639,8 @@ static int es7210_adc13_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc14_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(ES7210_ADC12_MUTE_REG15, 0x02, (ucontrol->value.integer.value[0] & 0x01) << 1, i2c_clt1[3]); return 0; @@ -1411,6 +1650,8 @@ static int es7210_adc14_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(ES7210_ADC12_MUTE_REG15, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = (val & 0x02) >> 1; return 0; @@ -1419,6 +1660,8 @@ static int es7210_adc14_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc15_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(ES7210_ADC34_MUTE_REG14, 0x01, ucontrol->value.integer.value[0]&0x01, i2c_clt1[3]); return 0; @@ -1428,6 +1671,8 @@ static int es7210_adc15_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(ES7210_ADC34_MUTE_REG14, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = val & 0x01; return 0; @@ -1435,6 +1680,8 @@ static int es7210_adc15_mute_get(struct snd_kcontrol *kcontrol, static int es7210_adc16_mute_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + if (i2c_clt1[3] == NULL) + return 0; es7210_update_bits(ES7210_ADC34_MUTE_REG14, 0x02, (ucontrol->value.integer.value[0] & 0x01) << 1, i2c_clt1[3]); return 0; @@ -1444,14 +1691,14 @@ static int es7210_adc16_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { u8 val; + if (i2c_clt1[3] == NULL) + return 0; es7210_read(ES7210_ADC34_MUTE_REG14, &val, i2c_clt1[3]); ucontrol->value.integer.value[0] = (val & 0x02) >> 1; return 0; } -#endif static const struct snd_kcontrol_new es7210_snd_controls[] = { -#if ES7210_CHANNELS_MAX > 0 SOC_SINGLE_EXT_TLV("PGA1_setting", 0x43, 0, 0x0E, 0, es7210_micboost1_setting_get, es7210_micboost1_setting_set, @@ -1476,8 +1723,6 @@ static const struct snd_kcontrol_new es7210_snd_controls[] = { es7210_adc3_mute_get, es7210_adc3_mute_set), SOC_SINGLE_EXT("ADC4_MUTE", ES7210_ADC34_MUTE_REG14, 1, 1, 0, es7210_adc4_mute_get, es7210_adc4_mute_set), -#endif -#if ES7210_CHANNELS_MAX > 4 SOC_SINGLE_EXT_TLV("PGA5_setting", 0x43, 0, 0x0E, 0, es7210_micboost5_setting_get, es7210_micboost5_setting_set, @@ -1502,9 +1747,6 @@ static const struct snd_kcontrol_new es7210_snd_controls[] = { es7210_adc7_mute_get, es7210_adc7_mute_set), SOC_SINGLE_EXT("ADC8_MUTE", ES7210_ADC34_MUTE_REG14, 1, 1, 0, es7210_adc8_mute_get, es7210_adc8_mute_set), - -#endif -#if ES7210_CHANNELS_MAX > 8 SOC_SINGLE_EXT_TLV("PGA9_setting", 0x43, 0, 0x0E, 0, es7210_micboost9_setting_get, es7210_micboost9_setting_set, @@ -1529,9 +1771,6 @@ static const struct snd_kcontrol_new es7210_snd_controls[] = { es7210_adc11_mute_get, es7210_adc11_mute_set), SOC_SINGLE_EXT("ADC12_MUTE", ES7210_ADC34_MUTE_REG14, 1, 1, 0, es7210_adc12_mute_get, es7210_adc12_mute_set), - -#endif -#if ES7210_CHANNELS_MAX > 12 SOC_SINGLE_EXT_TLV("PGA13_setting", 0x43, 0, 0x0E, 0, es7210_micboost13_setting_get, es7210_micboost13_setting_set, @@ -1556,15 +1795,16 @@ static const struct snd_kcontrol_new es7210_snd_controls[] = { es7210_adc15_mute_get, es7210_adc15_mute_set), SOC_SINGLE_EXT("ADC16_MUTE", ES7210_ADC34_MUTE_REG14, 1, 1, 0, es7210_adc16_mute_get, es7210_adc16_mute_set), - -#endif - }; static struct snd_soc_component_driver soc_codec_dev_es7210 = { + .name = "es7210", .probe = es7210_probe, + .remove = es7210_remove, +#ifdef CONFIG_PM_SLEEP .suspend = es7210_suspend, .resume = es7210_resume, +#endif .set_bias_level = es7210_set_bias_level, .controls = es7210_snd_controls, .num_controls = ARRAY_SIZE(es7210_snd_controls), @@ -1608,9 +1848,17 @@ static ssize_t es7210_store(struct device *dev, struct device_attribute *attr, c static ssize_t es7210_show(struct device *dev, struct device_attribute *attr, char *buf) { + u8 value, i; + struct es7210_priv *es7210 = dev_get_drvdata(dev); + printk("echo flag|reg|val > es7210\n"); printk("eg read star address=0x06,count 0x10:echo 0610 >es7210\n"); printk("eg write star address=0x90,value=0x3c,count=4:echo 4903c >es7210\n"); + + for (i = 0; i < 0x4d; i++) { + es7210_read(i, &value, es7210->i2c_client); + printk("reg[0x%x]=0x%x\n", i, value); + } return 0; } @@ -1634,6 +1882,8 @@ static int es7210_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *i2c_id) { struct es7210_priv *es7210; + struct device_node *np = i2c_client->dev.of_node; + const char* property; int ret; es7210 = devm_kzalloc(&i2c_client->dev, sizeof(struct es7210_priv), @@ -1641,7 +1891,6 @@ static int es7210_i2c_probe(struct i2c_client *i2c_client, if (es7210 == NULL) return -ENOMEM; es7210->i2c_client = i2c_client; - es7210->tdm_mode = ES7210_WORK_MODE; //to set tdm mode or normal mode property = of_get_property(np, "work-mode", NULL); if (property) { @@ -1726,41 +1975,19 @@ static int es7210_i2c_probe(struct i2c_client *i2c_client, static const struct i2c_device_id es7210_i2c_id[] = { -#if ES7210_CHANNELS_MAX > 0 { "MicArray_0", 0 },//es7210_0 -#endif - -#if ES7210_CHANNELS_MAX > 4 { "MicArray_1", 1 },//es7210_1 -#endif - -#if ES7210_CHANNELS_MAX > 8 { "MicArray_2", 2 },//es7210_2 -#endif - -#if ES7210_CHANNELS_MAX > 12 { "MicArray_3", 3 },//es7210_3 -#endif { } }; MODULE_DEVICE_TABLE(i2c_client, es7210_i2c_id); static const struct of_device_id es7210_dt_ids[] = { -#if ES7210_CHANNELS_MAX > 0 { .compatible = "MicArray_0", },//es7210_0 -#endif - -#if ES7210_CHANNELS_MAX > 4 { .compatible = "MicArray_1", },//es7210_1 -#endif - -#if ES7210_CHANNELS_MAX > 8 { .compatible = "MicArray_2", },//es7210_2 -#endif - -#if ES7210_CHANNELS_MAX > 12 { .compatible = "MicArray_3", },//es7210_3 -#endif {} }; MODULE_DEVICE_TABLE(of, es7210_dt_ids); diff --git a/sound/soc/codecs/es7210.h b/sound/soc/codecs/es7210.h index c3b89fd4d..4b6dabb7f 100644 --- a/sound/soc/codecs/es7210.h +++ b/sound/soc/codecs/es7210.h @@ -69,5 +69,72 @@ #define ES7210_MIC4_LP_REG4A 0x4A #define ES7210_MIC12_PDN_REG4B 0x4B #define ES7210_MIC34_PDN_REG4C 0x4C - + +/* codec private data */ +struct es7210_priv { + struct regmap *regmap; + struct i2c_client *i2c_client; + unsigned int dmic_enable; + unsigned int sysclk; + struct clk *mclk; + struct snd_pcm_hw_constraint_list *sysclk_constraints; + struct regulator *mvdd; + struct regulator *avdd; + struct regulator *dvdd; + struct regulator *pvdd; + unsigned int tdm_mode; + struct delayed_work pcm_pop_work; + int mclk_lrck_ratio; + int pcm_format; + int mclk_sclk_ratio; // mclk_sclk_ratio=1 is when mclk hardwired to sclk. + int sclk_lrck_ratio; + + u8 suspend_reg00[4]; + u8 suspend_reg01[4]; + u8 suspend_reg02[4]; + u8 suspend_reg03[4]; + u8 suspend_reg04[4]; + u8 suspend_reg05[4]; + u8 suspend_reg06[4]; + u8 suspend_reg07[4]; + u8 suspend_reg08[4]; + u8 suspend_reg09[4]; + u8 suspend_reg0A[4]; + u8 suspend_reg0B[4]; + u8 suspend_reg0C[4]; + u8 suspend_reg0D[4]; + u8 suspend_reg10[4]; + u8 suspend_reg11[4]; + u8 suspend_reg12[4]; + u8 suspend_reg13[4]; + u8 suspend_reg14[4]; + u8 suspend_reg15[4]; + u8 suspend_reg16[4]; + u8 suspend_reg17[4]; + u8 suspend_reg18[4]; + u8 suspend_reg19[4]; + u8 suspend_reg1A[4]; + u8 suspend_reg1B[4]; + u8 suspend_reg1C[4]; + u8 suspend_reg1D[4]; + u8 suspend_reg1E[4]; + u8 suspend_reg20[4]; + u8 suspend_reg21[4]; + u8 suspend_reg22[4]; + u8 suspend_reg23[4]; + u8 suspend_reg40[4]; + u8 suspend_reg41[4]; + u8 suspend_reg42[4]; + u8 suspend_reg43[4]; + u8 suspend_reg44[4]; + u8 suspend_reg45[4]; + u8 suspend_reg46[4]; + u8 suspend_reg47[4]; + u8 suspend_reg48[4]; + u8 suspend_reg49[4]; + u8 suspend_reg4A[4]; + u8 suspend_reg4B[4]; + u8 suspend_reg4C[4]; +}; + #endif /* _ES7210_H_ */ diff --git a/sound/soc/codecs/es8156.c b/sound/soc/codecs/es8156.c index ee164b526..02aa14ac2 100644 --- a/sound/soc/codecs/es8156.c +++ b/sound/soc/codecs/es8156.c @@ -30,12 +30,14 @@ #include #include #include +#include #include "es8156.h" #define INVALID_GPIO -1 #define GPIO_LOW 0 #define GPIO_HIGH 1 #define es8156_DEF_VOL 0xBF +#define ES8156_VOL_MAX 0xBF /* * If your system doesn't have MCLK, define this to 0 or the * driver will crash. @@ -63,6 +65,9 @@ struct es8156_priv { unsigned int sysclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; struct clk *mclk; + struct regulator *avdd; + struct regulator *dvdd; + struct regulator *pvdd; int debounce_time; int hp_det_invert; struct delayed_work work; @@ -74,6 +79,39 @@ struct es8156_priv { bool spk_active_level; int pwr_count; + u32 mclk_sclk_ratio; + + u32 suspend_reg_00; + u32 suspend_reg_01; + u32 suspend_reg_02; + u32 suspend_reg_03; + u32 suspend_reg_04; + u32 suspend_reg_05; + u32 suspend_reg_06; + u32 suspend_reg_07; + u32 suspend_reg_08; + u32 suspend_reg_09; + u32 suspend_reg_0A; + u32 suspend_reg_0B; + u32 suspend_reg_0C; + u32 suspend_reg_0D; + u32 suspend_reg_10; + u32 suspend_reg_11; + u32 suspend_reg_12; + u32 suspend_reg_13; + u32 suspend_reg_14; + u32 suspend_reg_15; + u32 suspend_reg_16; + u32 suspend_reg_17; + u32 suspend_reg_18; + u32 suspend_reg_19; + u32 suspend_reg_1A; + u32 suspend_reg_20; + u32 suspend_reg_21; + u32 suspend_reg_22; + u32 suspend_reg_23; + u32 suspend_reg_24; + u32 suspend_reg_25; }; /* @@ -114,11 +152,8 @@ static const struct snd_kcontrol_new es8156_snd_controls[] = { SOC_DOUBLE("ALC Maximum Minimum Volume",ES8156_ALC_CONFIG3_REG17, 4,0,15,0), /* DAC Digital controls */ - /* 255 is too loudy on LicheeConsole4A, so we limit it - * TODO: move it into devicetree or module param? - */ SOC_SINGLE_TLV("DAC Playback Volume", ES8156_VOLUME_CONTROL_REG14, - 0, 170, 0, dac_vol_tlv), + 0, ES8156_VOL_MAX, 0, dac_vol_tlv), SOC_SINGLE("HP Switch",ES8156_ANALOG_SYS3_REG22,3,1,0), @@ -126,7 +161,7 @@ static const struct snd_kcontrol_new es8156_snd_controls[] = { static const struct snd_soc_dapm_widget es8156_dapm_widgets[] = { - SND_SOC_DAPM_AIF_OUT("SDOUT", "I2S Capture", 0, + SND_SOC_DAPM_AIF_OUT("AIFSDOUT", "I2S Capture", 0, ES8156_P2S_CONTROL_REG0D, 2, 0), SND_SOC_DAPM_AIF_IN("SDIN", "I2S Playback", 0, @@ -146,6 +181,158 @@ static const struct snd_soc_dapm_widget es8156_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("ROUT"), }; +/*************** parameter define ***************/ +#define STATEconfirm 0x0C +#define NORMAL_I2S 0x00 +#define NORMAL_LJ 0x01 +#define NORMAL_DSPA 0x03 +#define NORMAL_DSPB 0x07 +#define Format_Len24 0x00 +#define Format_Len20 0x01 +#define Format_Len18 0x02 +#define Format_Len16 0x03 +#define Format_Len32 0x04 + +#define VDDA_3V3 0x00 +#define VDDA_1V8 0x01 +#define MCLK_PIN 0x00 +#define SCLK_PIN 0x01 + +/**************************************************/ +#define MSMode_MasterSelOn 0 // SlaveMode:0, MasterMode:1 +static unsigned int Ratio = 64; // Ratio = MCLK/LRCK on board +#define Format NORMAL_I2S +#define Format_Len Format_Len16 // data format +#define SCLK_DIV 8 // SCLK_DIV = MCLK/SCLK +#define SCLK_INV 0 +static unsigned int MCLK_SOURCE; // select MCLK source, MCLK_PIN or SCLK_PIN +#define EQ7bandOn 0 +#define VDDA_VOLTAGE VDDA_3V3 +#define DAC_Volume 191 // DAC digital gain +#define DACHPModeOn 0 // disable:0, enable:1 + +/**************************************************/ + +static int es8156_init_regs(struct snd_soc_component *codec) +{ + //struct es8156_priv *priv = snd_soc_component_get_drvdata(codec); + pr_debug("%s\n", __func__); + + snd_soc_component_write(codec,0x02,(MCLK_SOURCE<<7) + (SCLK_INV<<4) + (EQ7bandOn<<3) + 0x04 + MSMode_MasterSelOn); + snd_soc_component_write(codec,0x19,0x20); + + if(DACHPModeOn == 0) // output from PA + { + snd_soc_component_write(codec,0x20,0x2A); + snd_soc_component_write(codec,0x21,0x3C); + snd_soc_component_write(codec,0x22,0x02); + snd_soc_component_write(codec,0x24,0x07); + snd_soc_component_write(codec,0x23,0x40 + (0x30*VDDA_VOLTAGE)); + } + if(DACHPModeOn == 1) // output from headphone + { + snd_soc_component_write(codec,0x20,0x16); + snd_soc_component_write(codec,0x21,0x3F); + snd_soc_component_write(codec,0x22,0x0A); + snd_soc_component_write(codec,0x24,0x01); + snd_soc_component_write(codec,0x23,0xCA + (0x30*VDDA_VOLTAGE)); + } + snd_soc_component_write(codec,0x0A,0x01); + snd_soc_component_write(codec,0x0B,0x01); + //snd_soc_component_write(codec,0x11,NORMAL_I2S + (Format_Len<<4)); + + if(Ratio == 1536) // Ratio=MCLK/LRCK=1536; 12M288/8K; 24M576/16K + { + snd_soc_component_write(codec,0x01,0x26 - (0x03*EQ7bandOn)); // 1536 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 1536 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x06); // LRCK H + snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/1536 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 + } + if(Ratio == 1024) // Ratio=MCLK/LRCK=1024; 12M288/12K; 24M576/24K + { + snd_soc_component_write(codec,0x01,0x24 - (0x02*EQ7bandOn)); // 256 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 256 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x04); // LRCK H + snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/256 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 + } + if(Ratio == 768) // Ratio=MCLK/LRCK=768; 12M288/16K; 24M576/32K + { + snd_soc_component_write(codec,0x01,0x23 + (0x40*EQ7bandOn)); // 768 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 768 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x03); // LRCK H + snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/768 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 + } + if(Ratio == 512) // Ratio=MCLK/LRCK=512; 12M288/24K; 24M576/48K + { + snd_soc_component_write(codec,0x01,0xC0 + 0x22 - (0x01*EQ7bandOn)); // 512 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 512 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x02); // LRCK H + snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/512 + snd_soc_component_write(codec,0x05,SCLK_DIV); //BCLK=MCLK/4 + } + if(Ratio == 400) // Ratio=MCLK/LRCK=400; 19M2/48K + { // DVDD must be 3.3V + snd_soc_component_write(codec,0x01,0x21 + (0x40*EQ7bandOn)); // 384 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 400 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x10,0x64); // 400 OSR + snd_soc_component_write(codec,0x03,0x01); // LRCK H + snd_soc_component_write(codec,0x04,0x90); // LRCK=MCLK/400 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 + } + if(Ratio == 384) // Ratio=MCLK/LRCK=384; 12M288/32K; 6M144/16K + { + snd_soc_component_write(codec,0x01,0x63 + (0x40*EQ7bandOn)); // 384 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 384 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x01); // LRCK H + snd_soc_component_write(codec,0x04,0x80); // LRCK=MCLK/384 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 + } + if(Ratio == 256) // Ratio=MCLK/LRCK=256; 12M288/48K + { + snd_soc_component_write(codec,0x01,0x21 + (0x40*EQ7bandOn)); // 256 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 256 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x01); // LRCK H + snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/256 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 + } + if(Ratio == 128) // Ratio=MCLK/LRCK=128; 6M144/48K + { + snd_soc_component_write(codec,0x01,0x61 + (0x40*EQ7bandOn)); // 128 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x00); // 128 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x00); // LRCK H + snd_soc_component_write(codec,0x04,0x80); // LRCK=MCLK/128 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 + } + if(Ratio == 64) // Ratio=MCLK/LRCK=64; 3M072/48K + { + snd_soc_component_write(codec,0x01,0xE1); // 64 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x09,0x02); // 64 Ratio(MCLK/LRCK) + snd_soc_component_write(codec,0x03,0x00); // LRCK H + snd_soc_component_write(codec,0x04,0x40); // LRCK=MCLK/64 + snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/2 + } + + snd_soc_component_write(codec,0x0D,0x14); + snd_soc_component_write(codec,0x18,0x00); + snd_soc_component_write(codec,0x08,0x3F); + snd_soc_component_write(codec,0x00,0x02); + snd_soc_component_write(codec,0x00,0x03); + snd_soc_component_write(codec,0x25,0x20); + + return 0; +} + +static int es8156_init_sequence(struct snd_soc_component *codec) +{ + es8156_init_regs(codec); + snd_soc_component_write(codec, ES8156_VOLUME_CONTROL_REG14, DAC_Volume); + + return 0; +} + static const struct snd_soc_dapm_route es8156_dapm_routes[] = { {"SDOUT TRISTATE",NULL,"SDIN"}, {"SDOUT",NULL,"SDOUT TRISTATE"}, @@ -164,150 +351,6 @@ static const struct snd_soc_dapm_route es8156_dapm_routes[] = { { "ROUT", NULL, "DACR" }, }; -/*************** parameter define ***************/ -#define STATEconfirm 0x0C -#define NORMAL_I2S 0x00 -#define NORMAL_LJ 0x01 -#define NORMAL_DSPA 0x03 -#define NORMAL_DSPB 0x07 -#define Format_Len24 0x00 -#define Format_Len20 0x01 -#define Format_Len18 0x02 -#define Format_Len16 0x03 -#define Format_Len32 0x04 - -#define VDDA_3V3 0x00 -#define VDDA_1V8 0x01 -#define MCLK_PIN 0x00 -#define SCLK_PIN 0x01 - -/**************************************************/ -#define MSMode_MasterSelOn 0 // SlaveMode:0, MasterMode:1 -#define Ratio 64 // Ratio = MCLK/LRCK on board -#define Format NORMAL_I2S -#define Format_Len Format_Len16 // data format -#define SCLK_DIV 8 // SCLK_DIV = MCLK/SCLK -#define SCLK_INV 0 -#define MCLK_SOURCE SCLK_PIN // select MCLK source, MCLK_PIN or SCLK_PIN -#define EQ7bandOn 0 -#define VDDA_VOLTAGE VDDA_3V3 -#define DAC_Volume 170 // DAC digital gain -#define DACHPModeOn 0 // disable:0, enable:1 - -/**************************************************/ - -static int es8156_init_sequence(struct snd_soc_component *codec) -{ - pr_debug("%s\n", __func__); - - snd_soc_component_write(codec,0x02,(MCLK_SOURCE<<7) + (SCLK_INV<<4) + (EQ7bandOn<<3) + 0x04 + MSMode_MasterSelOn); - snd_soc_component_write(codec,0x19,0x20); - - if(DACHPModeOn == 0) // output from PA - { - snd_soc_component_write(codec,0x20,0x2A); - snd_soc_component_write(codec,0x21,0x3C); - snd_soc_component_write(codec,0x22,0x02); - snd_soc_component_write(codec,0x24,0x07); - snd_soc_component_write(codec,0x23,0x40 + (0x30*VDDA_VOLTAGE)); - } - if(DACHPModeOn == 1) // output from headphone - { - snd_soc_component_write(codec,0x20,0x16); - snd_soc_component_write(codec,0x21,0x3F); - snd_soc_component_write(codec,0x22,0x0A); - snd_soc_component_write(codec,0x24,0x01); - snd_soc_component_write(codec,0x23,0xCA + (0x30*VDDA_VOLTAGE)); - } - snd_soc_component_write(codec,0x0A,0x01); - snd_soc_component_write(codec,0x0B,0x01); - //snd_soc_component_write(codec,0x11,NORMAL_I2S + (Format_Len<<4)); - snd_soc_component_write(codec,0x14,DAC_Volume); - if(Ratio == 1536) // Ratio=MCLK/LRCK=1536; 12M288/8K; 24M576/16K - { - snd_soc_component_write(codec,0x01,0x26 - (0x03*EQ7bandOn)); // 1536 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 1536 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x06); // LRCK H - snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/1536 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 - } - if(Ratio == 1024) // Ratio=MCLK/LRCK=1024; 12M288/12K; 24M576/24K - { - snd_soc_component_write(codec,0x01,0x24 - (0x02*EQ7bandOn)); // 256 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 256 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x04); // LRCK H - snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/256 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 - } - if(Ratio == 768) // Ratio=MCLK/LRCK=768; 12M288/16K; 24M576/32K - { - snd_soc_component_write(codec,0x01,0x23 + (0x40*EQ7bandOn)); // 768 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 768 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x03); // LRCK H - snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/768 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 - } - if(Ratio == 512) // Ratio=MCLK/LRCK=512; 12M288/24K; 24M576/48K - { - snd_soc_component_write(codec,0x01,0xC0 + 0x22 - (0x01*EQ7bandOn)); // 512 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 512 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x02); // LRCK H - snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/512 - snd_soc_component_write(codec,0x05,SCLK_DIV); //BCLK=MCLK/4 - } - if(Ratio == 400) // Ratio=MCLK/LRCK=400; 19M2/48K - { // DVDD must be 3.3V - snd_soc_component_write(codec,0x01,0x21 + (0x40*EQ7bandOn)); // 384 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 400 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x10,0x64); // 400 OSR - snd_soc_component_write(codec,0x03,0x01); // LRCK H - snd_soc_component_write(codec,0x04,0x90); // LRCK=MCLK/400 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 - } - if(Ratio == 384) // Ratio=MCLK/LRCK=384; 12M288/32K; 6M144/16K - { - snd_soc_component_write(codec,0x01,0x63 + (0x40*EQ7bandOn)); // 384 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 384 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x01); // LRCK H - snd_soc_component_write(codec,0x04,0x80); // LRCK=MCLK/384 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 - } - if(Ratio == 256) // Ratio=MCLK/LRCK=256; 12M288/48K - { - snd_soc_component_write(codec,0x01,0x21 + (0x40*EQ7bandOn)); // 256 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 256 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x01); // LRCK H - snd_soc_component_write(codec,0x04,0x00); // LRCK=MCLK/256 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 - } - if(Ratio == 128) // Ratio=MCLK/LRCK=128; 6M144/48K - { - snd_soc_component_write(codec,0x01,0x61 + (0x40*EQ7bandOn)); // 128 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x00); // 128 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x00); // LRCK H - snd_soc_component_write(codec,0x04,0x80); // LRCK=MCLK/128 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/4 - } - if(Ratio == 64) // Ratio=MCLK/LRCK=64; 3M072/48K - { - snd_soc_component_write(codec,0x01,0xE1); // 64 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x09,0x02); // 64 Ratio(MCLK/LRCK) - snd_soc_component_write(codec,0x03,0x00); // LRCK H - snd_soc_component_write(codec,0x04,0x40); // LRCK=MCLK/64 - snd_soc_component_write(codec,0x05,SCLK_DIV); // BCLK=MCLK/2 - } - - snd_soc_component_write(codec,0x0D,0x14); - snd_soc_component_write(codec,0x18,0x00); - snd_soc_component_write(codec,0x08,0x3F); - snd_soc_component_write(codec,0x00,0x02); - snd_soc_component_write(codec,0x00,0x03); - snd_soc_component_write(codec,0x25,0x20); - - return 0; -} - - static int es8156_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { @@ -395,8 +438,8 @@ static int es8156_pcm_hw_params(struct snd_pcm_substream *substream, static int es8156_set_bias_level(struct snd_soc_component *codec, enum snd_soc_bias_level level) { - int ret; - struct es8156_priv *priv = snd_soc_component_get_drvdata(codec); + //int ret, i; + //struct es8156_priv *priv = snd_soc_component_get_drvdata(codec); switch (level) { @@ -407,6 +450,7 @@ static int es8156_set_bias_level(struct snd_soc_component *codec, break; case SND_SOC_BIAS_STANDBY: +#if 0 /* *open i2s clock */ @@ -415,7 +459,7 @@ static int es8156_set_bias_level(struct snd_soc_component *codec, if (!IS_ERR(priv->mclk)) { ret = clk_prepare_enable(priv->mclk); - es8156_init_sequence(codec); + es8156_init_regs(codec); if (ret) { dev_err(codec->dev, @@ -425,26 +469,27 @@ static int es8156_set_bias_level(struct snd_soc_component *codec, } } } +#endif break; case SND_SOC_BIAS_OFF: - snd_soc_component_write(codec,0x14,0x00); - snd_soc_component_write(codec,0x19,0x02); - snd_soc_component_write(codec,0x22,0x02); - snd_soc_component_write(codec,0x25,0x81); - snd_soc_component_write(codec,0x18,0x01); - snd_soc_component_write(codec,0x09,0x02); - snd_soc_component_write(codec,0x09,0x01); - snd_soc_component_write(codec,0x08,0x00); - mdelay(500); - snd_soc_component_write(codec,0x25,0x87); +#if 0 + //snd_soc_component_write(codec,0x14,0x00); + snd_soc_component_write(codec,0x19,0x02); + snd_soc_component_write(codec,0x22,0x02); + snd_soc_component_write(codec,0x25,0x81); + snd_soc_component_write(codec,0x18,0x01); + snd_soc_component_write(codec,0x09,0x02); + snd_soc_component_write(codec,0x09,0x01); + snd_soc_component_write(codec,0x08,0x00); + mdelay(500); + snd_soc_component_write(codec,0x25,0x87); /* *close i2s clock */ - if (!IS_ERR(priv->mclk)) { - pr_info("%s codec_uninit_sequence\n", __func__); + if (!IS_ERR(priv->mclk)) clk_disable_unprepare(priv->mclk); - } +#endif break; } return 0; @@ -475,7 +520,7 @@ static struct snd_soc_dai_driver es8156_dai = { .ops = &es8156_ops, }; - +#ifdef CONFIG_PM_SLEEP static int es8156_suspend(struct snd_soc_component *codec) { struct es8156_priv *priv = snd_soc_component_get_drvdata(codec); @@ -483,7 +528,38 @@ static int es8156_suspend(struct snd_soc_component *codec) pr_debug("Entered: %s\n", __func__); es8156_set_bias_level(codec, SND_SOC_BIAS_OFF); - printk("es8156_suspend\n"); + priv->suspend_reg_00 = snd_soc_component_read(codec, ES8156_RESET_REG00); + priv->suspend_reg_01 = snd_soc_component_read(codec, ES8156_MAINCLOCK_CTL_REG01); + priv->suspend_reg_02 = snd_soc_component_read(codec, ES8156_SCLK_MODE_REG02); + priv->suspend_reg_03 = snd_soc_component_read(codec, ES8156_LRCLK_DIV_H_REG03); + priv->suspend_reg_04 = snd_soc_component_read(codec, ES8156_LRCLK_DIV_L_REG04); + priv->suspend_reg_05 = snd_soc_component_read(codec, ES8156_SCLK_DIV_REG05); + priv->suspend_reg_06 = snd_soc_component_read(codec, ES8156_NFS_CONFIG_REG06); + priv->suspend_reg_07 = snd_soc_component_read(codec, ES8156_MISC_CONTROL1_REG07); + priv->suspend_reg_08 = snd_soc_component_read(codec, ES8156_CLOCK_ON_OFF_REG08); + priv->suspend_reg_09 = snd_soc_component_read(codec, ES8156_MISC_CONTROL2_REG09); + priv->suspend_reg_0A = snd_soc_component_read(codec, ES8156_TIME_CONTROL1_REG0A); + priv->suspend_reg_0B = snd_soc_component_read(codec, ES8156_TIME_CONTROL2_REG0B); + priv->suspend_reg_0C = snd_soc_component_read(codec, ES8156_CHIP_STATUS_REG0C); + priv->suspend_reg_0D = snd_soc_component_read(codec, ES8156_P2S_CONTROL_REG0D); + priv->suspend_reg_10 = snd_soc_component_read(codec, ES8156_DAC_OSR_COUNTER_REG10); + priv->suspend_reg_11 = snd_soc_component_read(codec, ES8156_DAC_SDP_REG11); + priv->suspend_reg_12 = snd_soc_component_read(codec, ES8156_AUTOMUTE_SET_REG12); + priv->suspend_reg_13 = snd_soc_component_read(codec, ES8156_DAC_MUTE_REG13); + priv->suspend_reg_14 = snd_soc_component_read(codec, ES8156_VOLUME_CONTROL_REG14); + priv->suspend_reg_15 = snd_soc_component_read(codec, ES8156_ALC_CONFIG1_REG15); + priv->suspend_reg_16 = snd_soc_component_read(codec, ES8156_ALC_CONFIG2_REG16); + priv->suspend_reg_17 = snd_soc_component_read(codec, ES8156_ALC_CONFIG3_REG17); + priv->suspend_reg_18 = snd_soc_component_read(codec, ES8156_MISC_CONTROL3_REG18); + priv->suspend_reg_19 = snd_soc_component_read(codec, ES8156_EQ_CONTROL1_REG19); + priv->suspend_reg_1A = snd_soc_component_read(codec, ES8156_EQ_CONTROL2_REG1A); + priv->suspend_reg_20 = snd_soc_component_read(codec, ES8156_ANALOG_SYS1_REG20); + priv->suspend_reg_21 = snd_soc_component_read(codec, ES8156_ANALOG_SYS2_REG21); + priv->suspend_reg_22 = snd_soc_component_read(codec, ES8156_ANALOG_SYS3_REG22); + priv->suspend_reg_23 = snd_soc_component_read(codec, ES8156_ANALOG_SYS4_REG23); + priv->suspend_reg_24 = snd_soc_component_read(codec, ES8156_ANALOG_LP_REG24); + priv->suspend_reg_25 = snd_soc_component_read(codec, ES8156_ANALOG_SYS5_REG25); + return 0; } @@ -527,6 +603,7 @@ static int es8156_resume(struct snd_soc_component *codec) return 0; } +#endif #ifdef HP_DET_FUNTION static irqreturn_t es8156_irq_handler(int irq, void *data) @@ -589,12 +666,23 @@ static void hp_work(struct work_struct *work) static int es8156_probe(struct snd_soc_component *codec) { -#if MCLK struct es8156_priv *es8156 = snd_soc_component_get_drvdata(codec); -#endif int ret = 0; es8156_codec = codec; + + /* power up the controller */ + if (es8156->avdd) + ret |= regulator_enable(es8156->avdd); + if (es8156->dvdd) + ret |= regulator_enable(es8156->dvdd); + if (es8156->pvdd) + ret |= regulator_enable(es8156->pvdd); + if (ret) { + pr_err("Failed to enable VDD regulator: %d\n", ret); + return ret; + } + #if MCLK es8156->mclk = devm_clk_get(codec->dev, "mclk"); if (PTR_ERR(es8156->mclk) == -EPROBE_DEFER) @@ -608,7 +696,16 @@ static int es8156_probe(struct snd_soc_component *codec) static void es8156_remove(struct snd_soc_component *codec) { + struct es8156_priv *es8156 = snd_soc_component_get_drvdata(codec); + es8156_set_bias_level(codec, SND_SOC_BIAS_OFF); + /* power down the controller */ + if (es8156->pvdd) + regulator_disable(es8156->pvdd); + if (es8156->dvdd) + regulator_disable(es8156->dvdd); + if (es8156->avdd) + regulator_disable(es8156->avdd); } const struct regmap_config es8156_regmap_config = { @@ -621,10 +718,13 @@ const struct regmap_config es8156_regmap_config = { }; static struct snd_soc_component_driver soc_codec_dev_es8156 = { + .name = "es8156", .probe = es8156_probe, .remove = es8156_remove, +#ifdef CONFIG_PM_SLEEP .suspend = es8156_suspend, .resume = es8156_resume, +#endif .set_bias_level = es8156_set_bias_level, .controls = es8156_snd_controls, .num_controls = ARRAY_SIZE(es8156_snd_controls), @@ -670,10 +770,10 @@ static int es8156_i2c_probe(struct i2c_client *i2c, { struct es8156_priv *es8156; int ret = -1; + struct device_node *np = i2c->dev.of_node; #ifdef HP_DET_FUNTION int hp_irq; enum of_gpio_flags flags; - struct device_node *np = i2c->dev.of_node; #endif es8156 = devm_kzalloc(&i2c->dev, sizeof(*es8156), GFP_KERNEL); if (!es8156) @@ -692,6 +792,37 @@ static int es8156_i2c_probe(struct i2c_client *i2c, return ret; } + es8156->avdd = devm_regulator_get(&i2c->dev, "AVDD"); + if (IS_ERR(es8156->avdd)) { + ret = PTR_ERR(es8156->avdd); + dev_warn(&i2c->dev, "Failed to get AVDD regulator: %d\n", ret); + es8156->avdd = NULL; + } + es8156->dvdd = devm_regulator_get(&i2c->dev, "DVDD"); + if (IS_ERR(es8156->dvdd)) { + ret = PTR_ERR(es8156->dvdd); + dev_warn(&i2c->dev, "Failed to get DVDD regulator: %d\n", ret); + es8156->dvdd = NULL; + } + es8156->pvdd = devm_regulator_get(&i2c->dev, "PVDD"); + if (IS_ERR(es8156->pvdd)) { + ret = PTR_ERR(es8156->pvdd); + dev_warn(&i2c->dev, "Failed to get PVDD regulator: %d\n", ret); + es8156->pvdd = NULL; + } + + if (of_property_read_u32(np, "mclk-sclk-ratio", &es8156->mclk_sclk_ratio) != 0) { + es8156->mclk_sclk_ratio = 1; + } + + Ratio *= es8156->mclk_sclk_ratio; + + if (es8156->mclk_sclk_ratio == 1) { + MCLK_SOURCE = SCLK_PIN; + } else { + MCLK_SOURCE = MCLK_PIN; + } + i2c_set_clientdata(i2c, es8156); #ifdef HP_DET_FUNTION es8156->spk_ctl_gpio = of_get_named_gpio_flags(np,