| 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* |
| 3 | * es8389.c -- ES8389 ALSA SoC Audio Codec |
| 4 | * |
| 5 | * Copyright Everest Semiconductor Co., Ltd |
| 6 | * |
| 7 | * Authors: Michael Zhang (zhangyi@everest-semi.com) |
| 8 | * |
| 9 | * This program is free software; you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU General Public License version 2 as |
| 11 | * published by the Free Software Foundation. |
| 12 | */ |
| 13 | |
| 14 | #include <linux/clk.h> |
| 15 | #include <linux/module.h> |
| 16 | #include <linux/kernel.h> |
| 17 | #include <linux/delay.h> |
| 18 | #include <linux/i2c.h> |
| 19 | #include <linux/regmap.h> |
| 20 | #include <sound/core.h> |
| 21 | #include <sound/pcm.h> |
| 22 | #include <sound/pcm_params.h> |
| 23 | #include <sound/tlv.h> |
| 24 | #include <sound/soc.h> |
| 25 | |
| 26 | #include "es8389.h" |
| 27 | |
| 28 | |
| 29 | /* codec private data */ |
| 30 | |
| 31 | struct es8389_private { |
| 32 | struct regmap *regmap; |
| 33 | struct clk *mclk; |
| 34 | unsigned int sysclk; |
| 35 | int mastermode; |
| 36 | |
| 37 | u8 mclk_src; |
| 38 | enum snd_soc_bias_level bias_level; |
| 39 | }; |
| 40 | |
| 41 | static bool es8389_volatile_register(struct device *dev, |
| 42 | unsigned int reg) |
| 43 | { |
| 44 | if ((reg <= 0xff)) |
| 45 | return true; |
| 46 | else |
| 47 | return false; |
| 48 | } |
| 49 | |
| 50 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9550, 50, 0); |
| 51 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -9550, 50, 0); |
| 52 | static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, 0, 300, 0); |
| 53 | static const DECLARE_TLV_DB_SCALE(mix_vol_tlv, -9500, 100, 0); |
| 54 | static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -3200, 200, 0); |
| 55 | static const DECLARE_TLV_DB_SCALE(alc_max_level, -3200, 200, 0); |
| 56 | |
| 57 | static int es8389_dmic_set(struct snd_kcontrol *kcontrol, |
| 58 | struct snd_ctl_elem_value *ucontrol) |
| 59 | { |
| 60 | struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol); |
| 61 | struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); |
| 62 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 63 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
| 64 | unsigned int val; |
| 65 | bool changed1, changed2; |
| 66 | |
| 67 | val = ucontrol->value.integer.value[0]; |
| 68 | if (val > 1) |
| 69 | return -EINVAL; |
| 70 | |
| 71 | if (val) { |
| 72 | regmap_update_bits_check(map: es8389->regmap, ES8389_DMIC_EN, mask: 0xC0, val: 0xC0, change: &changed1); |
| 73 | regmap_update_bits_check(map: es8389->regmap, ES8389_ADC_MODE, mask: 0x03, val: 0x03, change: &changed2); |
| 74 | } else { |
| 75 | regmap_update_bits_check(map: es8389->regmap, ES8389_DMIC_EN, mask: 0xC0, val: 0x00, change: &changed1); |
| 76 | regmap_update_bits_check(map: es8389->regmap, ES8389_ADC_MODE, mask: 0x03, val: 0x00, change: &changed2); |
| 77 | } |
| 78 | |
| 79 | if (changed1 & changed2) |
| 80 | return snd_soc_dapm_mux_update_power(dapm, kcontrol, mux: val, e, NULL); |
| 81 | else |
| 82 | return 0; |
| 83 | } |
| 84 | |
| 85 | static const char *const alc[] = { |
| 86 | "ALC OFF" , |
| 87 | "ADCR ALC ON" , |
| 88 | "ADCL ALC ON" , |
| 89 | "ADCL & ADCL ALC ON" , |
| 90 | }; |
| 91 | |
| 92 | static const char *const ramprate[] = { |
| 93 | "0.125db/1 LRCK" , |
| 94 | "0.125db/4 LRCK" , |
| 95 | "0.125db/8 LRCK" , |
| 96 | "0.125db/16 LRCK" , |
| 97 | "0.125db/32 LRCK" , |
| 98 | "0.125db/64 LRCK" , |
| 99 | "0.125db/128 LRCK" , |
| 100 | "0.125db/256 LRCK" , |
| 101 | "0.125db/512 LRCK" , |
| 102 | "0.125db/1024 LRCK" , |
| 103 | "0.125db/2048 LRCK" , |
| 104 | "0.125db/4096 LRCK" , |
| 105 | "0.125db/8192 LRCK" , |
| 106 | "0.125db/16384 LRCK" , |
| 107 | "0.125db/32768 LRCK" , |
| 108 | "0.125db/65536 LRCK" , |
| 109 | }; |
| 110 | |
| 111 | static const char *const winsize[] = { |
| 112 | "2 LRCK" , |
| 113 | "4 LRCK" , |
| 114 | "8 LRCK" , |
| 115 | "16 LRCK" , |
| 116 | "32 LRCK" , |
| 117 | "64 LRCK" , |
| 118 | "128 LRCK" , |
| 119 | "256 LRCK" , |
| 120 | "512 LRCK" , |
| 121 | "1024 LRCK" , |
| 122 | "2048 LRCK" , |
| 123 | "4096 LRCK" , |
| 124 | "8192 LRCK" , |
| 125 | "16384 LRCK" , |
| 126 | "32768 LRCK" , |
| 127 | "65536 LRCK" , |
| 128 | }; |
| 129 | |
| 130 | static const struct soc_enum alc_enable = |
| 131 | SOC_ENUM_SINGLE(ES8389_ALC_ON, 5, 4, alc); |
| 132 | static const struct soc_enum alc_ramprate = |
| 133 | SOC_ENUM_SINGLE(ES8389_ALC_CTL, 4, 16, ramprate); |
| 134 | static const struct soc_enum alc_winsize = |
| 135 | SOC_ENUM_SINGLE(ES8389_ALC_CTL, 0, 16, winsize); |
| 136 | |
| 137 | static const char *const es8389_outl_mux_txt[] = { |
| 138 | "Normal" , |
| 139 | "DAC2 channel to DAC1 channel" , |
| 140 | }; |
| 141 | |
| 142 | static const char *const es8389_outr_mux_txt[] = { |
| 143 | "Normal" , |
| 144 | "DAC1 channel to DAC2 channel" , |
| 145 | }; |
| 146 | |
| 147 | static const char *const es8389_dmic_mux_txt[] = { |
| 148 | "AMIC" , |
| 149 | "DMIC" , |
| 150 | }; |
| 151 | |
| 152 | static const char *const es8389_pga1_texts[] = { |
| 153 | "DifferentialL" , "Line 1P" , "Line 2P" |
| 154 | }; |
| 155 | |
| 156 | static const char *const es8389_pga2_texts[] = { |
| 157 | "DifferentialR" , "Line 2N" , "Line 1N" |
| 158 | }; |
| 159 | |
| 160 | static const unsigned int es8389_pga_values[] = { |
| 161 | 1, 5, 6 |
| 162 | }; |
| 163 | |
| 164 | static const struct soc_enum es8389_outl_mux_enum = |
| 165 | SOC_ENUM_SINGLE(ES8389_DAC_MIX, 5, |
| 166 | ARRAY_SIZE(es8389_outl_mux_txt), es8389_outl_mux_txt); |
| 167 | |
| 168 | static const struct snd_kcontrol_new es8389_outl_mux_controls = |
| 169 | SOC_DAPM_ENUM("OUTL MUX" , es8389_outl_mux_enum); |
| 170 | |
| 171 | static const struct soc_enum es8389_outr_mux_enum = |
| 172 | SOC_ENUM_SINGLE(ES8389_DAC_MIX, 4, |
| 173 | ARRAY_SIZE(es8389_outr_mux_txt), es8389_outr_mux_txt); |
| 174 | |
| 175 | static const struct snd_kcontrol_new es8389_outr_mux_controls = |
| 176 | SOC_DAPM_ENUM("OUTR MUX" , es8389_outr_mux_enum); |
| 177 | |
| 178 | static SOC_ENUM_SINGLE_DECL( |
| 179 | es8389_dmic_mux_enum, ES8389_DMIC_EN, 6, es8389_dmic_mux_txt); |
| 180 | |
| 181 | static const struct soc_enum es8389_pgal_enum = |
| 182 | SOC_VALUE_ENUM_SINGLE(ES8389_MIC1_GAIN, 4, 7, |
| 183 | ARRAY_SIZE(es8389_pga1_texts), es8389_pga1_texts, |
| 184 | es8389_pga_values); |
| 185 | |
| 186 | static const struct soc_enum es8389_pgar_enum = |
| 187 | SOC_VALUE_ENUM_SINGLE(ES8389_MIC2_GAIN, 4, 7, |
| 188 | ARRAY_SIZE(es8389_pga2_texts), es8389_pga2_texts, |
| 189 | es8389_pga_values); |
| 190 | |
| 191 | static const struct snd_kcontrol_new es8389_dmic_mux_controls = |
| 192 | SOC_DAPM_ENUM_EXT("ADC MUX" , es8389_dmic_mux_enum, |
| 193 | snd_soc_dapm_get_enum_double, es8389_dmic_set); |
| 194 | |
| 195 | static const struct snd_kcontrol_new es8389_left_mixer_controls[] = { |
| 196 | SOC_DAPM_SINGLE("DACR DACL Mixer" , ES8389_DAC_MIX, 3, 1, 0), |
| 197 | }; |
| 198 | |
| 199 | static const struct snd_kcontrol_new es8389_right_mixer_controls[] = { |
| 200 | SOC_DAPM_SINGLE("DACL DACR Mixer" , ES8389_DAC_MIX, 2, 1, 0), |
| 201 | }; |
| 202 | |
| 203 | static const struct snd_kcontrol_new es8389_leftadc_mixer_controls[] = { |
| 204 | SOC_DAPM_SINGLE("ADCL DACL Mixer" , ES8389_DAC_MIX, 1, 1, 0), |
| 205 | }; |
| 206 | |
| 207 | static const struct snd_kcontrol_new es8389_rightadc_mixer_controls[] = { |
| 208 | SOC_DAPM_SINGLE("ADCR DACR Mixer" , ES8389_DAC_MIX, 0, 1, 0), |
| 209 | }; |
| 210 | |
| 211 | static const struct snd_kcontrol_new es8389_adc_mixer_controls[] = { |
| 212 | SOC_DAPM_SINGLE("DACL ADCL Mixer" , ES8389_ADC_RESET, 7, 1, 0), |
| 213 | SOC_DAPM_SINGLE("DACR ADCR Mixer" , ES8389_ADC_RESET, 6, 1, 0), |
| 214 | }; |
| 215 | |
| 216 | static const struct snd_kcontrol_new es8389_snd_controls[] = { |
| 217 | SOC_SINGLE_TLV("ADCL Capture Volume" , ES8389_ADCL_VOL, 0, 0xFF, 0, adc_vol_tlv), |
| 218 | SOC_SINGLE_TLV("ADCR Capture Volume" , ES8389_ADCR_VOL, 0, 0xFF, 0, adc_vol_tlv), |
| 219 | SOC_SINGLE_TLV("ADCL PGA Volume" , ES8389_MIC1_GAIN, 0, 0x0E, 0, pga_vol_tlv), |
| 220 | SOC_SINGLE_TLV("ADCR PGA Volume" , ES8389_MIC2_GAIN, 0, 0x0E, 0, pga_vol_tlv), |
| 221 | |
| 222 | SOC_ENUM("PGAL Select" , es8389_pgal_enum), |
| 223 | SOC_ENUM("PGAR Select" , es8389_pgar_enum), |
| 224 | SOC_ENUM("ALC Capture Switch" , alc_enable), |
| 225 | SOC_SINGLE_TLV("ALC Capture Target Level" , ES8389_ALC_TARGET, |
| 226 | 0, 0x0f, 0, alc_target_tlv), |
| 227 | SOC_SINGLE_TLV("ALC Capture Max Gain" , ES8389_ALC_GAIN, |
| 228 | 0, 0x0f, 0, alc_max_level), |
| 229 | SOC_ENUM("ADC Ramp Rate" , alc_ramprate), |
| 230 | SOC_ENUM("ALC Capture Winsize" , alc_winsize), |
| 231 | SOC_DOUBLE("ADC OSR Volume ON Switch" , ES8389_ADC_MUTE, 6, 7, 1, 0), |
| 232 | SOC_SINGLE_TLV("ADC OSR Volume" , ES8389_OSR_VOL, 0, 0xFF, 0, adc_vol_tlv), |
| 233 | SOC_DOUBLE("ADC OUTPUT Invert Switch" , ES8389_ADC_HPF2, 5, 6, 1, 0), |
| 234 | |
| 235 | SOC_SINGLE_TLV("DACL Playback Volume" , ES8389_DACL_VOL, 0, 0xFF, 0, dac_vol_tlv), |
| 236 | SOC_SINGLE_TLV("DACR Playback Volume" , ES8389_DACR_VOL, 0, 0xFF, 0, dac_vol_tlv), |
| 237 | SOC_DOUBLE("DAC OUTPUT Invert Switch" , ES8389_DAC_INV, 5, 6, 1, 0), |
| 238 | SOC_SINGLE_TLV("ADC2DAC Mixer Volume" , ES8389_MIX_VOL, 0, 0x7F, 0, mix_vol_tlv), |
| 239 | }; |
| 240 | |
| 241 | static const struct snd_soc_dapm_widget es8389_dapm_widgets[] = { |
| 242 | /*Input Side*/ |
| 243 | SND_SOC_DAPM_INPUT("INPUT1" ), |
| 244 | SND_SOC_DAPM_INPUT("INPUT2" ), |
| 245 | SND_SOC_DAPM_INPUT("DMIC" ), |
| 246 | SND_SOC_DAPM_PGA("PGAL" , SND_SOC_NOPM, 4, 0, NULL, 0), |
| 247 | SND_SOC_DAPM_PGA("PGAR" , SND_SOC_NOPM, 4, 0, NULL, 0), |
| 248 | |
| 249 | /*ADCs*/ |
| 250 | SND_SOC_DAPM_ADC("ADCL" , NULL, SND_SOC_NOPM, 0, 0), |
| 251 | SND_SOC_DAPM_ADC("ADCR" , NULL, SND_SOC_NOPM, 0, 0), |
| 252 | |
| 253 | /* Audio Interface */ |
| 254 | SND_SOC_DAPM_AIF_OUT("I2S OUT" , "I2S Capture" , 0, SND_SOC_NOPM, 0, 0), |
| 255 | SND_SOC_DAPM_AIF_IN("I2S IN" , "I2S Playback" , 0, SND_SOC_NOPM, 0, 0), |
| 256 | |
| 257 | /*DACs*/ |
| 258 | SND_SOC_DAPM_DAC("DACL" , NULL, SND_SOC_NOPM, 0, 0), |
| 259 | SND_SOC_DAPM_DAC("DACR" , NULL, SND_SOC_NOPM, 0, 0), |
| 260 | |
| 261 | /*Output Side*/ |
| 262 | SND_SOC_DAPM_OUTPUT("HPOL" ), |
| 263 | SND_SOC_DAPM_OUTPUT("HPOR" ), |
| 264 | |
| 265 | /* Digital Interface */ |
| 266 | SND_SOC_DAPM_PGA("IF DAC" , SND_SOC_NOPM, 0, 0, NULL, 0), |
| 267 | SND_SOC_DAPM_PGA("IF DACL1" , SND_SOC_NOPM, 0, 0, NULL, 0), |
| 268 | SND_SOC_DAPM_PGA("IF DACR1" , SND_SOC_NOPM, 0, 0, NULL, 0), |
| 269 | SND_SOC_DAPM_PGA("IF DACL2" , SND_SOC_NOPM, 0, 0, NULL, 0), |
| 270 | SND_SOC_DAPM_PGA("IF DACR2" , SND_SOC_NOPM, 0, 0, NULL, 0), |
| 271 | SND_SOC_DAPM_PGA("IF DACL3" , SND_SOC_NOPM, 0, 0, NULL, 0), |
| 272 | SND_SOC_DAPM_PGA("IF DACR3" , SND_SOC_NOPM, 0, 0, NULL, 0), |
| 273 | |
| 274 | /* Digital Interface Select */ |
| 275 | SND_SOC_DAPM_MIXER("IF DACL Mixer" , SND_SOC_NOPM, 0, 0, |
| 276 | &es8389_left_mixer_controls[0], |
| 277 | ARRAY_SIZE(es8389_left_mixer_controls)), |
| 278 | SND_SOC_DAPM_MIXER("IF DACR Mixer" , SND_SOC_NOPM, 0, 0, |
| 279 | &es8389_right_mixer_controls[0], |
| 280 | ARRAY_SIZE(es8389_right_mixer_controls)), |
| 281 | SND_SOC_DAPM_MIXER("IF ADCDACL Mixer" , SND_SOC_NOPM, 0, 0, |
| 282 | &es8389_leftadc_mixer_controls[0], |
| 283 | ARRAY_SIZE(es8389_leftadc_mixer_controls)), |
| 284 | SND_SOC_DAPM_MIXER("IF ADCDACR Mixer" , SND_SOC_NOPM, 0, 0, |
| 285 | &es8389_rightadc_mixer_controls[0], |
| 286 | ARRAY_SIZE(es8389_rightadc_mixer_controls)), |
| 287 | |
| 288 | SND_SOC_DAPM_MIXER("ADC Mixer" , SND_SOC_NOPM, 0, 0, |
| 289 | &es8389_adc_mixer_controls[0], |
| 290 | ARRAY_SIZE(es8389_adc_mixer_controls)), |
| 291 | SND_SOC_DAPM_MUX("ADC MUX" , SND_SOC_NOPM, 0, 0, &es8389_dmic_mux_controls), |
| 292 | |
| 293 | SND_SOC_DAPM_MUX("OUTL MUX" , SND_SOC_NOPM, 0, 0, &es8389_outl_mux_controls), |
| 294 | SND_SOC_DAPM_MUX("OUTR MUX" , SND_SOC_NOPM, 0, 0, &es8389_outr_mux_controls), |
| 295 | }; |
| 296 | |
| 297 | |
| 298 | static const struct snd_soc_dapm_route es8389_dapm_routes[] = { |
| 299 | {"PGAL" , NULL, "INPUT1" }, |
| 300 | {"PGAR" , NULL, "INPUT2" }, |
| 301 | |
| 302 | {"ADCL" , NULL, "PGAL" }, |
| 303 | {"ADCR" , NULL, "PGAR" }, |
| 304 | |
| 305 | {"ADC Mixer" , "DACL ADCL Mixer" , "DACL" }, |
| 306 | {"ADC Mixer" , "DACR ADCR Mixer" , "DACR" }, |
| 307 | {"ADC Mixer" , NULL, "ADCL" }, |
| 308 | {"ADC Mixer" , NULL, "ADCR" }, |
| 309 | |
| 310 | {"ADC MUX" , "AMIC" , "ADC Mixer" }, |
| 311 | {"ADC MUX" , "DMIC" , "DMIC" }, |
| 312 | |
| 313 | {"I2S OUT" , NULL, "ADC MUX" }, |
| 314 | |
| 315 | {"DACL" , NULL, "I2S IN" }, |
| 316 | {"DACR" , NULL, "I2S IN" }, |
| 317 | |
| 318 | {"IF DACL1" , NULL, "DACL" }, |
| 319 | {"IF DACR1" , NULL, "DACR" }, |
| 320 | {"IF DACL2" , NULL, "DACL" }, |
| 321 | {"IF DACR2" , NULL, "DACR" }, |
| 322 | {"IF DACL3" , NULL, "DACL" }, |
| 323 | {"IF DACR3" , NULL, "DACR" }, |
| 324 | |
| 325 | {"IF DACL Mixer" , NULL, "IF DACL2" }, |
| 326 | {"IF DACL Mixer" , "DACR DACL Mixer" , "IF DACR1" }, |
| 327 | {"IF DACR Mixer" , NULL, "IF DACR2" }, |
| 328 | {"IF DACR Mixer" , "DACL DACR Mixer" , "IF DACL1" }, |
| 329 | |
| 330 | {"IF ADCDACL Mixer" , NULL, "IF DACL Mixer" }, |
| 331 | {"IF ADCDACL Mixer" , "ADCL DACL Mixer" , "IF DACL3" }, |
| 332 | {"IF ADCDACR Mixer" , NULL, "IF DACR Mixer" }, |
| 333 | {"IF ADCDACR Mixer" , "ADCR DACR Mixer" , "IF DACR3" }, |
| 334 | |
| 335 | {"OUTL MUX" , "Normal" , "IF ADCDACL Mixer" }, |
| 336 | {"OUTL MUX" , "DAC2 channel to DAC1 channel" , "IF ADCDACR Mixer" }, |
| 337 | {"OUTR MUX" , "Normal" , "IF ADCDACR Mixer" }, |
| 338 | {"OUTR MUX" , "DAC1 channel to DAC2 channel" , "IF ADCDACL Mixer" }, |
| 339 | |
| 340 | {"HPOL" , NULL, "OUTL MUX" }, |
| 341 | {"HPOR" , NULL, "OUTR MUX" }, |
| 342 | |
| 343 | }; |
| 344 | |
| 345 | struct _coeff_div { |
| 346 | u16 fs; |
| 347 | u32 mclk; |
| 348 | u32 rate; |
| 349 | u8 Reg0x04; |
| 350 | u8 Reg0x05; |
| 351 | u8 Reg0x06; |
| 352 | u8 Reg0x07; |
| 353 | u8 Reg0x08; |
| 354 | u8 Reg0x09; |
| 355 | u8 Reg0x0A; |
| 356 | u8 Reg0x0F; |
| 357 | u8 Reg0x11; |
| 358 | u8 Reg0x21; |
| 359 | u8 Reg0x22; |
| 360 | u8 Reg0x26; |
| 361 | u8 Reg0x30; |
| 362 | u8 Reg0x41; |
| 363 | u8 Reg0x42; |
| 364 | u8 Reg0x43; |
| 365 | u8 Reg0xF0; |
| 366 | u8 Reg0xF1; |
| 367 | u8 Reg0x16; |
| 368 | u8 Reg0x18; |
| 369 | u8 Reg0x19; |
| 370 | }; |
| 371 | |
| 372 | /* codec hifi mclk clock divider coefficients */ |
| 373 | static const struct _coeff_div coeff_div[] = { |
| 374 | {32, 256000, 8000, 0x00, 0x57, 0x84, 0xD0, 0x03, 0xC1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 375 | {36, 288000, 8000, 0x00, 0x55, 0x84, 0xD0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x23, 0x8F, 0xB7, 0xC0, 0x1F, 0x8F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 376 | {48, 384000, 8000, 0x02, 0x5F, 0x04, 0xC0, 0x03, 0xC1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 377 | {64, 512000, 8000, 0x00, 0x4D, 0x24, 0xC0, 0x03, 0xD1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 378 | {72, 576000, 8000, 0x00, 0x45, 0x24, 0xC0, 0x01, 0xD1, 0x90, 0x00, 0x00, 0x23, 0x8F, 0xB7, 0xC0, 0x1F, 0x8F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 379 | {96, 768000, 8000, 0x02, 0x57, 0x84, 0xD0, 0x03, 0xC1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 380 | {128, 1024000, 8000, 0x00, 0x45, 0x04, 0xD0, 0x03, 0xC1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 381 | {192, 1536000, 8000, 0x02, 0x4D, 0x24, 0xC0, 0x03, 0xD1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 382 | {256, 2048000, 8000, 0x01, 0x45, 0x04, 0xD0, 0x03, 0xC1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 383 | {288, 2304000, 8000, 0x01, 0x51, 0x00, 0xC0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x23, 0x8F, 0xB7, 0xC0, 0x1F, 0x8F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 384 | {384, 3072000, 8000, 0x02, 0x45, 0x04, 0xD0, 0x03, 0xC1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 385 | {512, 4096000, 8000, 0x00, 0x41, 0x04, 0xE0, 0x00, 0xD1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 386 | {768, 6144000, 8000, 0x05, 0x45, 0x04, 0xD0, 0x03, 0xC1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 387 | {1024, 8192000, 8000, 0x01, 0x41, 0x06, 0xE0, 0x00, 0xD1, 0xB0, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 388 | {1536, 12288000, 8000, 0x02, 0x41, 0x04, 0xE0, 0x00, 0xD1, 0xB0, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 389 | {1625, 13000000, 8000, 0x40, 0x6E, 0x05, 0xC8, 0x01, 0xC2, 0x90, 0x40, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 390 | {2048, 16384000, 8000, 0x03, 0x44, 0x01, 0xC0, 0x00, 0xD2, 0x80, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 391 | {2304, 18432000, 8000, 0x11, 0x45, 0x25, 0xF0, 0x00, 0xD1, 0xB0, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 392 | {3072, 24576000, 8000, 0x05, 0x44, 0x01, 0xC0, 0x00, 0xD2, 0x80, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 393 | {32, 512000, 16000, 0x00, 0x55, 0x84, 0xD0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 394 | {36, 576000, 16000, 0x00, 0x55, 0x84, 0xD0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x23, 0x8F, 0xB7, 0xC0, 0x1F, 0x8F, 0x01, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 395 | {48, 768000, 16000, 0x02, 0x57, 0x04, 0xC0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 396 | {50, 800000, 16000, 0x00, 0x7E, 0x01, 0xD9, 0x00, 0xC2, 0x80, 0x00, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0xC7, 0x95, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 397 | {64, 1024000, 16000, 0x00, 0x45, 0x24, 0xC0, 0x01, 0xD1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 398 | {72, 1152000, 16000, 0x00, 0x45, 0x24, 0xC0, 0x01, 0xD1, 0x90, 0x00, 0x00, 0x23, 0x8F, 0xB7, 0xC0, 0x1F, 0x8F, 0x01, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 399 | {96, 1536000, 16000, 0x02, 0x55, 0x84, 0xD0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 400 | {128, 2048000, 16000, 0x00, 0x51, 0x04, 0xD0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 401 | {144, 2304000, 16000, 0x00, 0x51, 0x00, 0xC0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x23, 0x8F, 0xB7, 0xC0, 0x1F, 0x8F, 0x01, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 402 | {192, 3072000, 16000, 0x02, 0x65, 0x25, 0xE0, 0x00, 0xE1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 403 | {256, 4096000, 16000, 0x00, 0x41, 0x04, 0xC0, 0x01, 0xD1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 404 | {300, 4800000, 16000, 0x02, 0x66, 0x01, 0xD9, 0x00, 0xC2, 0x80, 0x00, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0xC7, 0x95, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 405 | {384, 6144000, 16000, 0x02, 0x51, 0x04, 0xD0, 0x01, 0xC1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 406 | {512, 8192000, 16000, 0x01, 0x41, 0x04, 0xC0, 0x01, 0xD1, 0x90, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 407 | {750, 12000000, 16000, 0x0E, 0x7E, 0x01, 0xC9, 0x00, 0xC2, 0x80, 0x40, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0xC7, 0x95, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 408 | {768, 12288000, 16000, 0x02, 0x41, 0x04, 0xC0, 0x01, 0xD1, 0x90, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 409 | {1024, 16384000, 16000, 0x03, 0x41, 0x04, 0xC0, 0x01, 0xD1, 0x90, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 410 | {1152, 18432000, 16000, 0x08, 0x51, 0x04, 0xD0, 0x01, 0xC1, 0x90, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 411 | {1200, 19200000, 16000, 0x0B, 0x66, 0x01, 0xD9, 0x00, 0xC2, 0x80, 0x40, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0xC7, 0x95, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 412 | {1500, 24000000, 16000, 0x0E, 0x26, 0x01, 0xD9, 0x00, 0xC2, 0x80, 0xC0, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0xC7, 0x95, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 413 | {1536, 24576000, 16000, 0x05, 0x41, 0x04, 0xC0, 0x01, 0xD1, 0x90, 0xC0, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0xFF, 0x7F, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 414 | {1625, 26000000, 16000, 0x40, 0x6E, 0x05, 0xC8, 0x01, 0xC2, 0x90, 0xC0, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x12, 0x31, 0x0E}, |
| 415 | {800, 19200000, 24000, 0x07, 0x66, 0x01, 0xD9, 0x00, 0xC2, 0x80, 0x40, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0xC7, 0x95, 0x00, 0x12, 0x00, 0x1A, 0x49, 0x14}, |
| 416 | {600, 19200000, 32000, 0x05, 0x46, 0x01, 0xD8, 0x10, 0xD2, 0x80, 0x40, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x23, 0x61, 0x1B}, |
| 417 | {32, 1411200, 44100, 0x00, 0x45, 0xA4, 0xD0, 0x10, 0xD1, 0x80, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 418 | {64, 2822400, 44100, 0x00, 0x51, 0x00, 0xC0, 0x10, 0xC1, 0x80, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 419 | {128, 5644800, 44100, 0x00, 0x41, 0x04, 0xD0, 0x10, 0xD1, 0x80, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 420 | {256, 11289600, 44100, 0x01, 0x41, 0x04, 0xD0, 0x10, 0xD1, 0x80, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 421 | {512, 22579200, 44100, 0x03, 0x41, 0x04, 0xD0, 0x10, 0xD1, 0x80, 0xC0, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 422 | {32, 1536000, 48000, 0x00, 0x45, 0xA4, 0xD0, 0x10, 0xD1, 0x80, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 423 | {48, 2304000, 48000, 0x02, 0x55, 0x04, 0xC0, 0x10, 0xC1, 0x80, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 424 | {50, 2400000, 48000, 0x00, 0x76, 0x01, 0xC8, 0x10, 0xC2, 0x80, 0x00, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 425 | {64, 3072000, 48000, 0x00, 0x51, 0x04, 0xC0, 0x10, 0xC1, 0x80, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 426 | {100, 4800000, 48000, 0x00, 0x46, 0x01, 0xD8, 0x10, 0xD2, 0x80, 0x00, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 427 | {125, 6000000, 48000, 0x04, 0x6E, 0x05, 0xC8, 0x10, 0xC2, 0x80, 0x00, 0x01, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 428 | {128, 6144000, 48000, 0x00, 0x41, 0x04, 0xD0, 0x10, 0xD1, 0x80, 0x00, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 429 | {200, 9600000, 48000, 0x01, 0x46, 0x01, 0xD8, 0x10, 0xD2, 0x80, 0x00, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 430 | {250, 12000000, 48000, 0x04, 0x76, 0x01, 0xC8, 0x10, 0xC2, 0x80, 0x40, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 431 | {256, 12288000, 48000, 0x01, 0x41, 0x04, 0xD0, 0x10, 0xD1, 0x80, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 432 | {384, 18432000, 48000, 0x02, 0x41, 0x04, 0xD0, 0x10, 0xD1, 0x80, 0x40, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 433 | {400, 19200000, 48000, 0x03, 0x46, 0x01, 0xD8, 0x10, 0xD2, 0x80, 0x40, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 434 | {500, 24000000, 48000, 0x04, 0x46, 0x01, 0xD8, 0x10, 0xD2, 0x80, 0xC0, 0x00, 0x18, 0x95, 0xD0, 0xC0, 0x63, 0x95, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 435 | {512, 24576000, 48000, 0x03, 0x41, 0x04, 0xD0, 0x10, 0xD1, 0x80, 0xC0, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 436 | {800, 38400000, 48000, 0x18, 0x45, 0x04, 0xC0, 0x10, 0xC1, 0x80, 0xC0, 0x00, 0x1F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x12, 0x00, 0x35, 0x91, 0x28}, |
| 437 | {128, 11289600, 88200, 0x00, 0x50, 0x00, 0xC0, 0x10, 0xC1, 0x80, 0x40, 0x00, 0x9F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x80, 0x12, 0xC0, 0x32, 0x89, 0x25}, |
| 438 | {64, 6144000, 96000, 0x00, 0x41, 0x00, 0xD0, 0x10, 0xD1, 0x80, 0x00, 0x00, 0x9F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x80, 0x12, 0xC0, 0x35, 0x91, 0x28}, |
| 439 | {128, 12288000, 96000, 0x00, 0x50, 0x00, 0xC0, 0x10, 0xC1, 0x80, 0xC0, 0x00, 0x9F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x80, 0x12, 0xC0, 0x35, 0x91, 0x28}, |
| 440 | {256, 24576000, 96000, 0x00, 0x40, 0x00, 0xC0, 0x10, 0xC1, 0x80, 0xC0, 0x00, 0x9F, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x80, 0x12, 0xC0, 0x35, 0x91, 0x28}, |
| 441 | {128, 24576000, 192000, 0x00, 0x50, 0x00, 0xC0, 0x18, 0xC1, 0x81, 0xC0, 0x00, 0x8F, 0x7F, 0xEF, 0xC0, 0x3F, 0x7F, 0x80, 0x12, 0xC0, 0x3F, 0xF9, 0x3F}, |
| 442 | |
| 443 | {50, 400000, 8000, 0x00, 0x75, 0x05, 0xC8, 0x01, 0xC1, 0x90, 0x10, 0x00, 0x18, 0xC7, 0xD0, 0xC0, 0x8F, 0xC7, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 444 | {600, 4800000, 8000, 0x05, 0x65, 0x25, 0xF9, 0x00, 0xD1, 0x90, 0x10, 0x00, 0x18, 0xC7, 0xD0, 0xC0, 0x8F, 0xC7, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 445 | {1500, 12000000, 8000, 0x0E, 0x25, 0x25, 0xE8, 0x00, 0xD1, 0x90, 0x40, 0x00, 0x31, 0xC7, 0xC5, 0x00, 0x8F, 0xC7, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 446 | {2400, 19200000, 8000, 0x0B, 0x01, 0x00, 0xD0, 0x00, 0xD1, 0x80, 0x90, 0x00, 0x31, 0xC7, 0xC5, 0x00, 0xC7, 0xC7, 0x00, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 447 | {3000, 24000000, 8000, 0x0E, 0x24, 0x05, 0xD0, 0x00, 0xC2, 0x80, 0xC0, 0x00, 0x31, 0xC7, 0xC5, 0x00, 0x8F, 0xC7, 0x01, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 448 | {3250, 26000000, 8000, 0x40, 0x05, 0xA4, 0xC0, 0x00, 0xD1, 0x80, 0xD0, 0x00, 0x31, 0xC7, 0xC5, 0x00, 0xC7, 0xC7, 0x00, 0x12, 0x00, 0x09, 0x19, 0x07}, |
| 449 | }; |
| 450 | |
| 451 | static inline int get_coeff(int mclk, int rate) |
| 452 | { |
| 453 | int i; |
| 454 | |
| 455 | for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { |
| 456 | if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) |
| 457 | return i; |
| 458 | } |
| 459 | return -EINVAL; |
| 460 | } |
| 461 | |
| 462 | /* |
| 463 | * if PLL not be used, use internal clk1 for mclk,otherwise, use internal clk2 for PLL source. |
| 464 | */ |
| 465 | static int es8389_set_dai_sysclk(struct snd_soc_dai *dai, |
| 466 | int clk_id, unsigned int freq, int dir) |
| 467 | { |
| 468 | struct snd_soc_component *component = dai->component; |
| 469 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 470 | |
| 471 | es8389->sysclk = freq; |
| 472 | |
| 473 | return 0; |
| 474 | } |
| 475 | |
| 476 | static int es8389_set_tdm_slot(struct snd_soc_dai *dai, |
| 477 | unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) |
| 478 | { |
| 479 | struct snd_soc_component *component = dai->component; |
| 480 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 481 | |
| 482 | regmap_update_bits(map: es8389->regmap, ES8389_PTDM_SLOT, |
| 483 | ES8389_TDM_SLOT, val: (slots << ES8389_TDM_SHIFT)); |
| 484 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_RAMP, |
| 485 | ES8389_TDM_SLOT, val: (slots << ES8389_TDM_SHIFT)); |
| 486 | |
| 487 | return 0; |
| 488 | } |
| 489 | |
| 490 | static int es8389_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
| 491 | { |
| 492 | struct snd_soc_component *component = dai->component; |
| 493 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 494 | u8 state = 0; |
| 495 | |
| 496 | switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { |
| 497 | case SND_SOC_DAIFMT_CBC_CFP: |
| 498 | regmap_update_bits(map: es8389->regmap, ES8389_MASTER_MODE, |
| 499 | ES8389_MASTER_MODE_EN, ES8389_MASTER_MODE_EN); |
| 500 | es8389->mastermode = 1; |
| 501 | break; |
| 502 | case SND_SOC_DAIFMT_CBC_CFC: |
| 503 | es8389->mastermode = 0; |
| 504 | break; |
| 505 | default: |
| 506 | return -EINVAL; |
| 507 | } |
| 508 | |
| 509 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 510 | case SND_SOC_DAIFMT_I2S: |
| 511 | state |= ES8389_DAIFMT_I2S; |
| 512 | break; |
| 513 | case SND_SOC_DAIFMT_RIGHT_J: |
| 514 | dev_err(component->dev, "component driver does not support right justified\n" ); |
| 515 | return -EINVAL; |
| 516 | case SND_SOC_DAIFMT_LEFT_J: |
| 517 | state |= ES8389_DAIFMT_LEFT_J; |
| 518 | break; |
| 519 | case SND_SOC_DAIFMT_DSP_A: |
| 520 | state |= ES8389_DAIFMT_DSP_A; |
| 521 | break; |
| 522 | case SND_SOC_DAIFMT_DSP_B: |
| 523 | state |= ES8389_DAIFMT_DSP_B; |
| 524 | break; |
| 525 | default: |
| 526 | break; |
| 527 | } |
| 528 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_FORMAT_MUTE, ES8389_DAIFMT_MASK, val: state); |
| 529 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_FORMAT_MUTE, ES8389_DAIFMT_MASK, val: state); |
| 530 | |
| 531 | return 0; |
| 532 | } |
| 533 | |
| 534 | static int es8389_pcm_hw_params(struct snd_pcm_substream *substream, |
| 535 | struct snd_pcm_hw_params *params, |
| 536 | struct snd_soc_dai *dai) |
| 537 | { |
| 538 | struct snd_soc_component *component = dai->component; |
| 539 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 540 | int coeff; |
| 541 | u8 state = 0; |
| 542 | |
| 543 | switch (params_format(p: params)) { |
| 544 | case SNDRV_PCM_FORMAT_S16_LE: |
| 545 | state |= ES8389_S16_LE; |
| 546 | break; |
| 547 | case SNDRV_PCM_FORMAT_S20_3LE: |
| 548 | state |= ES8389_S20_3_LE; |
| 549 | break; |
| 550 | case SNDRV_PCM_FORMAT_S18_3LE: |
| 551 | state |= ES8389_S18_LE; |
| 552 | break; |
| 553 | case SNDRV_PCM_FORMAT_S24_LE: |
| 554 | state |= ES8389_S24_LE; |
| 555 | break; |
| 556 | case SNDRV_PCM_FORMAT_S32_LE: |
| 557 | state |= ES8389_S32_LE; |
| 558 | break; |
| 559 | default: |
| 560 | return -EINVAL; |
| 561 | } |
| 562 | |
| 563 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_FORMAT_MUTE, ES8389_DATA_LEN_MASK, val: state); |
| 564 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_FORMAT_MUTE, ES8389_DATA_LEN_MASK, val: state); |
| 565 | |
| 566 | if (es8389->mclk_src == ES8389_SCLK_PIN) { |
| 567 | regmap_update_bits(map: es8389->regmap, ES8389_MASTER_CLK, |
| 568 | ES8389_MCLK_SOURCE, val: es8389->mclk_src); |
| 569 | es8389->sysclk = params_channels(p: params) * params_width(p: params) * params_rate(p: params); |
| 570 | } |
| 571 | |
| 572 | coeff = get_coeff(mclk: es8389->sysclk, rate: params_rate(p: params)); |
| 573 | if (coeff >= 0) { |
| 574 | regmap_write(map: es8389->regmap, ES8389_CLK_DIV1, val: coeff_div[coeff].Reg0x04); |
| 575 | regmap_write(map: es8389->regmap, ES8389_CLK_MUL, val: coeff_div[coeff].Reg0x05); |
| 576 | regmap_write(map: es8389->regmap, ES8389_CLK_MUX1, val: coeff_div[coeff].Reg0x06); |
| 577 | regmap_write(map: es8389->regmap, ES8389_CLK_MUX2, val: coeff_div[coeff].Reg0x07); |
| 578 | regmap_write(map: es8389->regmap, ES8389_CLK_CTL1, val: coeff_div[coeff].Reg0x08); |
| 579 | regmap_write(map: es8389->regmap, ES8389_CLK_CTL2, val: coeff_div[coeff].Reg0x09); |
| 580 | regmap_write(map: es8389->regmap, ES8389_CLK_CTL3, val: coeff_div[coeff].Reg0x0A); |
| 581 | regmap_update_bits(map: es8389->regmap, ES8389_OSC_CLK, |
| 582 | mask: 0xC0, val: coeff_div[coeff].Reg0x0F); |
| 583 | regmap_write(map: es8389->regmap, ES8389_CLK_DIV2, val: coeff_div[coeff].Reg0x11); |
| 584 | regmap_write(map: es8389->regmap, ES8389_ADC_OSR, val: coeff_div[coeff].Reg0x21); |
| 585 | regmap_write(map: es8389->regmap, ES8389_ADC_DSP, val: coeff_div[coeff].Reg0x22); |
| 586 | regmap_write(map: es8389->regmap, ES8389_OSR_VOL, val: coeff_div[coeff].Reg0x26); |
| 587 | regmap_update_bits(map: es8389->regmap, ES8389_SYSTEM30, |
| 588 | mask: 0xC0, val: coeff_div[coeff].Reg0x30); |
| 589 | regmap_write(map: es8389->regmap, ES8389_DAC_DSM_OSR, val: coeff_div[coeff].Reg0x41); |
| 590 | regmap_write(map: es8389->regmap, ES8389_DAC_DSP_OSR, val: coeff_div[coeff].Reg0x42); |
| 591 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_MISC, |
| 592 | mask: 0x81, val: coeff_div[coeff].Reg0x43); |
| 593 | regmap_update_bits(map: es8389->regmap, ES8389_CHIP_MISC, |
| 594 | mask: 0x72, val: coeff_div[coeff].Reg0xF0); |
| 595 | regmap_write(map: es8389->regmap, ES8389_CSM_STATE1, val: coeff_div[coeff].Reg0xF1); |
| 596 | regmap_write(map: es8389->regmap, ES8389_SYSTEM16, val: coeff_div[coeff].Reg0x16); |
| 597 | regmap_write(map: es8389->regmap, ES8389_SYSTEM18, val: coeff_div[coeff].Reg0x18); |
| 598 | regmap_write(map: es8389->regmap, ES8389_SYSTEM19, val: coeff_div[coeff].Reg0x19); |
| 599 | } else { |
| 600 | dev_warn(component->dev, "Clock coefficients do not match" ); |
| 601 | } |
| 602 | |
| 603 | return 0; |
| 604 | } |
| 605 | |
| 606 | static int es8389_set_bias_level(struct snd_soc_component *component, |
| 607 | enum snd_soc_bias_level level) |
| 608 | { |
| 609 | int ret; |
| 610 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 611 | |
| 612 | switch (level) { |
| 613 | case SND_SOC_BIAS_ON: |
| 614 | ret = clk_prepare_enable(clk: es8389->mclk); |
| 615 | if (ret) |
| 616 | return ret; |
| 617 | |
| 618 | regmap_update_bits(map: es8389->regmap, ES8389_HPSW, mask: 0x20, val: 0x20); |
| 619 | regmap_write(map: es8389->regmap, ES8389_ANA_CTL1, val: 0xD9); |
| 620 | regmap_write(map: es8389->regmap, ES8389_ADC_EN, val: 0x8F); |
| 621 | regmap_write(map: es8389->regmap, ES8389_CSM_JUMP, val: 0xE4); |
| 622 | regmap_write(map: es8389->regmap, ES8389_RESET, val: 0x01); |
| 623 | regmap_write(map: es8389->regmap, ES8389_CLK_OFF1, val: 0xC3); |
| 624 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_HPF1, mask: 0x0f, val: 0x0a); |
| 625 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_HPF2, mask: 0x0f, val: 0x0a); |
| 626 | usleep_range(min: 70000, max: 72000); |
| 627 | regmap_write(map: es8389->regmap, ES8389_DAC_RESET, val: 0X00); |
| 628 | break; |
| 629 | case SND_SOC_BIAS_PREPARE: |
| 630 | break; |
| 631 | case SND_SOC_BIAS_STANDBY: |
| 632 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_HPF1, mask: 0x0f, val: 0x04); |
| 633 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_HPF2, mask: 0x0f, val: 0x04); |
| 634 | regmap_write(map: es8389->regmap, ES8389_CSM_JUMP, val: 0xD4); |
| 635 | usleep_range(min: 70000, max: 72000); |
| 636 | regmap_write(map: es8389->regmap, ES8389_ANA_CTL1, val: 0x59); |
| 637 | regmap_write(map: es8389->regmap, ES8389_ADC_EN, val: 0x00); |
| 638 | regmap_write(map: es8389->regmap, ES8389_CLK_OFF1, val: 0x00); |
| 639 | regmap_write(map: es8389->regmap, ES8389_RESET, val: 0x3E); |
| 640 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_INV, mask: 0x80, val: 0x80); |
| 641 | usleep_range(min: 8000, max: 8500); |
| 642 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_INV, mask: 0x80, val: 0x00); |
| 643 | |
| 644 | clk_disable_unprepare(clk: es8389->mclk); |
| 645 | break; |
| 646 | case SND_SOC_BIAS_OFF: |
| 647 | break; |
| 648 | } |
| 649 | return 0; |
| 650 | } |
| 651 | |
| 652 | |
| 653 | |
| 654 | static int es8389_mute(struct snd_soc_dai *dai, int mute, int direction) |
| 655 | { |
| 656 | struct snd_soc_component *component = dai->component; |
| 657 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 658 | |
| 659 | if (mute) { |
| 660 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) { |
| 661 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_FORMAT_MUTE, |
| 662 | mask: 0x03, val: 0x03); |
| 663 | } else { |
| 664 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_FORMAT_MUTE, |
| 665 | mask: 0x03, val: 0x03); |
| 666 | } |
| 667 | } else { |
| 668 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) { |
| 669 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_FORMAT_MUTE, |
| 670 | mask: 0x03, val: 0x00); |
| 671 | } else { |
| 672 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_FORMAT_MUTE, |
| 673 | mask: 0x03, val: 0x00); |
| 674 | } |
| 675 | } |
| 676 | |
| 677 | return 0; |
| 678 | } |
| 679 | |
| 680 | #define es8389_RATES SNDRV_PCM_RATE_8000_96000 |
| 681 | |
| 682 | #define es8389_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 683 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) |
| 684 | |
| 685 | static const struct snd_soc_dai_ops es8389_ops = { |
| 686 | .hw_params = es8389_pcm_hw_params, |
| 687 | .set_fmt = es8389_set_dai_fmt, |
| 688 | .set_sysclk = es8389_set_dai_sysclk, |
| 689 | .set_tdm_slot = es8389_set_tdm_slot, |
| 690 | .mute_stream = es8389_mute, |
| 691 | }; |
| 692 | |
| 693 | static struct snd_soc_dai_driver es8389_dai = { |
| 694 | .name = "ES8389 HiFi" , |
| 695 | .playback = { |
| 696 | .stream_name = "Playback" , |
| 697 | .channels_min = 1, |
| 698 | .channels_max = 2, |
| 699 | .rates = es8389_RATES, |
| 700 | .formats = es8389_FORMATS, |
| 701 | }, |
| 702 | .capture = { |
| 703 | .stream_name = "Capture" , |
| 704 | .channels_min = 1, |
| 705 | .channels_max = 2, |
| 706 | .rates = es8389_RATES, |
| 707 | .formats = es8389_FORMATS, |
| 708 | }, |
| 709 | .ops = &es8389_ops, |
| 710 | .symmetric_rate = 1, |
| 711 | }; |
| 712 | |
| 713 | static void es8389_init(struct snd_soc_component *component) |
| 714 | { |
| 715 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 716 | |
| 717 | regmap_write(map: es8389->regmap, ES8389_ISO_CTL, val: 0x00); |
| 718 | regmap_write(map: es8389->regmap, ES8389_RESET, val: 0x7E); |
| 719 | regmap_write(map: es8389->regmap, ES8389_ISO_CTL, val: 0x38); |
| 720 | regmap_write(map: es8389->regmap, ES8389_ADC_HPF1, val: 0x64); |
| 721 | regmap_write(map: es8389->regmap, ES8389_ADC_HPF2, val: 0x04); |
| 722 | regmap_write(map: es8389->regmap, ES8389_DAC_INV, val: 0x03); |
| 723 | |
| 724 | regmap_write(map: es8389->regmap, ES8389_VMID, val: 0x2A); |
| 725 | regmap_write(map: es8389->regmap, ES8389_ANA_CTL1, val: 0xC9); |
| 726 | regmap_write(map: es8389->regmap, ES8389_ANA_VSEL, val: 0x4F); |
| 727 | regmap_write(map: es8389->regmap, ES8389_ANA_CTL2, val: 0x06); |
| 728 | regmap_write(map: es8389->regmap, ES8389_LOW_POWER1, val: 0x00); |
| 729 | regmap_write(map: es8389->regmap, ES8389_DMIC_EN, val: 0x16); |
| 730 | |
| 731 | regmap_write(map: es8389->regmap, ES8389_PGA_SW, val: 0xAA); |
| 732 | regmap_write(map: es8389->regmap, ES8389_MOD_SW1, val: 0x66); |
| 733 | regmap_write(map: es8389->regmap, ES8389_MOD_SW2, val: 0x99); |
| 734 | regmap_write(map: es8389->regmap, ES8389_ADC_MODE, val: (0x00 | ES8389_TDM_MODE)); |
| 735 | regmap_update_bits(map: es8389->regmap, ES8389_DMIC_EN, mask: 0xC0, val: 0x00); |
| 736 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_MODE, mask: 0x03, val: 0x00); |
| 737 | |
| 738 | regmap_update_bits(map: es8389->regmap, ES8389_MIC1_GAIN, |
| 739 | ES8389_MIC_SEL_MASK, ES8389_MIC_DEFAULT); |
| 740 | regmap_update_bits(map: es8389->regmap, ES8389_MIC2_GAIN, |
| 741 | ES8389_MIC_SEL_MASK, ES8389_MIC_DEFAULT); |
| 742 | regmap_write(map: es8389->regmap, ES8389_CSM_JUMP, val: 0xC4); |
| 743 | regmap_write(map: es8389->regmap, ES8389_MASTER_MODE, val: 0x08); |
| 744 | regmap_write(map: es8389->regmap, ES8389_CSM_STATE1, val: 0x00); |
| 745 | regmap_write(map: es8389->regmap, ES8389_SYSTEM12, val: 0x01); |
| 746 | regmap_write(map: es8389->regmap, ES8389_SYSTEM13, val: 0x01); |
| 747 | regmap_write(map: es8389->regmap, ES8389_SYSTEM14, val: 0x01); |
| 748 | regmap_write(map: es8389->regmap, ES8389_SYSTEM15, val: 0x01); |
| 749 | regmap_write(map: es8389->regmap, ES8389_SYSTEM16, val: 0x35); |
| 750 | regmap_write(map: es8389->regmap, ES8389_SYSTEM17, val: 0x09); |
| 751 | regmap_write(map: es8389->regmap, ES8389_SYSTEM18, val: 0x91); |
| 752 | regmap_write(map: es8389->regmap, ES8389_SYSTEM19, val: 0x28); |
| 753 | regmap_write(map: es8389->regmap, ES8389_SYSTEM1A, val: 0x01); |
| 754 | regmap_write(map: es8389->regmap, ES8389_SYSTEM1B, val: 0x01); |
| 755 | regmap_write(map: es8389->regmap, ES8389_SYSTEM1C, val: 0x11); |
| 756 | |
| 757 | regmap_write(map: es8389->regmap, ES8389_CHIP_MISC, val: 0x13); |
| 758 | regmap_write(map: es8389->regmap, ES8389_MASTER_CLK, val: 0x00); |
| 759 | regmap_write(map: es8389->regmap, ES8389_CLK_DIV1, val: 0x00); |
| 760 | regmap_write(map: es8389->regmap, ES8389_CLK_MUL, val: 0x10); |
| 761 | regmap_write(map: es8389->regmap, ES8389_CLK_MUX1, val: 0x00); |
| 762 | regmap_write(map: es8389->regmap, ES8389_CLK_MUX2, val: 0xC0); |
| 763 | regmap_write(map: es8389->regmap, ES8389_CLK_CTL1, val: 0x00); |
| 764 | regmap_write(map: es8389->regmap, ES8389_CLK_CTL2, val: 0xC0); |
| 765 | regmap_write(map: es8389->regmap, ES8389_CLK_CTL3, val: 0x80); |
| 766 | regmap_write(map: es8389->regmap, ES8389_SCLK_DIV, val: 0x04); |
| 767 | regmap_write(map: es8389->regmap, ES8389_LRCK_DIV1, val: 0x01); |
| 768 | regmap_write(map: es8389->regmap, ES8389_LRCK_DIV2, val: 0x00); |
| 769 | regmap_write(map: es8389->regmap, ES8389_OSC_CLK, val: 0x00); |
| 770 | regmap_write(map: es8389->regmap, ES8389_ADC_OSR, val: 0x1F); |
| 771 | regmap_write(map: es8389->regmap, ES8389_ADC_DSP, val: 0x7F); |
| 772 | regmap_write(map: es8389->regmap, ES8389_ADC_MUTE, val: 0xC0); |
| 773 | regmap_write(map: es8389->regmap, ES8389_SYSTEM30, val: 0xF4); |
| 774 | regmap_write(map: es8389->regmap, ES8389_DAC_DSM_OSR, val: 0x7F); |
| 775 | regmap_write(map: es8389->regmap, ES8389_DAC_DSP_OSR, val: 0x7F); |
| 776 | regmap_write(map: es8389->regmap, ES8389_DAC_MISC, val: 0x10); |
| 777 | regmap_write(map: es8389->regmap, ES8389_DAC_RAMP, val: 0x0F); |
| 778 | regmap_write(map: es8389->regmap, ES8389_SYSTEM4C, val: 0xC0); |
| 779 | regmap_write(map: es8389->regmap, ES8389_RESET, val: 0x00); |
| 780 | regmap_write(map: es8389->regmap, ES8389_CLK_OFF1, val: 0xC1); |
| 781 | regmap_write(map: es8389->regmap, ES8389_RESET, val: 0x01); |
| 782 | regmap_write(map: es8389->regmap, ES8389_DAC_RESET, val: 0x02); |
| 783 | |
| 784 | regmap_update_bits(map: es8389->regmap, ES8389_ADC_FORMAT_MUTE, mask: 0x03, val: 0x03); |
| 785 | regmap_update_bits(map: es8389->regmap, ES8389_DAC_FORMAT_MUTE, mask: 0x03, val: 0x03); |
| 786 | } |
| 787 | |
| 788 | static int es8389_suspend(struct snd_soc_component *component) |
| 789 | { |
| 790 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 791 | |
| 792 | es8389_set_bias_level(component, level: SND_SOC_BIAS_STANDBY); |
| 793 | regcache_cache_only(map: es8389->regmap, enable: true); |
| 794 | regcache_mark_dirty(map: es8389->regmap); |
| 795 | |
| 796 | return 0; |
| 797 | } |
| 798 | |
| 799 | static int es8389_resume(struct snd_soc_component *component) |
| 800 | { |
| 801 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 802 | unsigned int regv; |
| 803 | |
| 804 | regcache_cache_only(map: es8389->regmap, enable: false); |
| 805 | regcache_cache_bypass(map: es8389->regmap, enable: true); |
| 806 | regmap_read(map: es8389->regmap, ES8389_RESET, val: ®v); |
| 807 | regcache_cache_bypass(map: es8389->regmap, enable: false); |
| 808 | |
| 809 | if (regv == 0xff) |
| 810 | es8389_init(component); |
| 811 | else |
| 812 | es8389_set_bias_level(component, level: SND_SOC_BIAS_ON); |
| 813 | |
| 814 | regcache_sync(map: es8389->regmap); |
| 815 | |
| 816 | return 0; |
| 817 | } |
| 818 | |
| 819 | static int es8389_probe(struct snd_soc_component *component) |
| 820 | { |
| 821 | int ret; |
| 822 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 823 | |
| 824 | ret = device_property_read_u8(dev: component->dev, propname: "everest,mclk-src" , val: &es8389->mclk_src); |
| 825 | if (ret != 0) { |
| 826 | dev_dbg(component->dev, "mclk-src return %d" , ret); |
| 827 | es8389->mclk_src = ES8389_MCLK_SOURCE; |
| 828 | } |
| 829 | |
| 830 | es8389->mclk = devm_clk_get(dev: component->dev, id: "mclk" ); |
| 831 | if (IS_ERR(ptr: es8389->mclk)) |
| 832 | return dev_err_probe(dev: component->dev, err: PTR_ERR(ptr: es8389->mclk), |
| 833 | fmt: "ES8389 is unable to get mclk\n" ); |
| 834 | |
| 835 | if (!es8389->mclk) |
| 836 | dev_err(component->dev, "%s, assuming static mclk\n" , __func__); |
| 837 | |
| 838 | ret = clk_prepare_enable(clk: es8389->mclk); |
| 839 | if (ret) { |
| 840 | dev_err(component->dev, "%s, unable to enable mclk\n" , __func__); |
| 841 | return ret; |
| 842 | } |
| 843 | |
| 844 | es8389_init(component); |
| 845 | es8389_set_bias_level(component, level: SND_SOC_BIAS_STANDBY); |
| 846 | |
| 847 | return 0; |
| 848 | } |
| 849 | |
| 850 | static void es8389_remove(struct snd_soc_component *component) |
| 851 | { |
| 852 | struct es8389_private *es8389 = snd_soc_component_get_drvdata(c: component); |
| 853 | |
| 854 | regmap_write(map: es8389->regmap, ES8389_MASTER_MODE, val: 0x28); |
| 855 | regmap_write(map: es8389->regmap, ES8389_HPSW, val: 0x00); |
| 856 | regmap_write(map: es8389->regmap, ES8389_VMID, val: 0x00); |
| 857 | regmap_write(map: es8389->regmap, ES8389_RESET, val: 0x00); |
| 858 | regmap_write(map: es8389->regmap, ES8389_CSM_JUMP, val: 0xCC); |
| 859 | usleep_range(min: 500000, max: 550000);//500MS |
| 860 | regmap_write(map: es8389->regmap, ES8389_CSM_JUMP, val: 0x00); |
| 861 | regmap_write(map: es8389->regmap, ES8389_ANA_CTL1, val: 0x08); |
| 862 | regmap_write(map: es8389->regmap, ES8389_ISO_CTL, val: 0xC1); |
| 863 | regmap_write(map: es8389->regmap, ES8389_PULL_DOWN, val: 0x00); |
| 864 | |
| 865 | } |
| 866 | |
| 867 | static const struct snd_soc_component_driver soc_codec_dev_es8389 = { |
| 868 | .probe = es8389_probe, |
| 869 | .remove = es8389_remove, |
| 870 | .suspend = es8389_suspend, |
| 871 | .resume = es8389_resume, |
| 872 | .set_bias_level = es8389_set_bias_level, |
| 873 | |
| 874 | .controls = es8389_snd_controls, |
| 875 | .num_controls = ARRAY_SIZE(es8389_snd_controls), |
| 876 | .dapm_widgets = es8389_dapm_widgets, |
| 877 | .num_dapm_widgets = ARRAY_SIZE(es8389_dapm_widgets), |
| 878 | .dapm_routes = es8389_dapm_routes, |
| 879 | .num_dapm_routes = ARRAY_SIZE(es8389_dapm_routes), |
| 880 | .idle_bias_on = 1, |
| 881 | .use_pmdown_time = 1, |
| 882 | }; |
| 883 | |
| 884 | static const struct regmap_config es8389_regmap = { |
| 885 | .reg_bits = 8, |
| 886 | .val_bits = 8, |
| 887 | |
| 888 | .max_register = ES8389_MAX_REGISTER, |
| 889 | |
| 890 | .volatile_reg = es8389_volatile_register, |
| 891 | .cache_type = REGCACHE_MAPLE, |
| 892 | }; |
| 893 | |
| 894 | static void es8389_i2c_shutdown(struct i2c_client *i2c) |
| 895 | { |
| 896 | struct es8389_private *es8389; |
| 897 | |
| 898 | es8389 = i2c_get_clientdata(client: i2c); |
| 899 | |
| 900 | regmap_write(map: es8389->regmap, ES8389_MASTER_MODE, val: 0x28); |
| 901 | regmap_write(map: es8389->regmap, ES8389_HPSW, val: 0x00); |
| 902 | regmap_write(map: es8389->regmap, ES8389_VMID, val: 0x00); |
| 903 | regmap_write(map: es8389->regmap, ES8389_RESET, val: 0x00); |
| 904 | regmap_write(map: es8389->regmap, ES8389_CSM_JUMP, val: 0xCC); |
| 905 | usleep_range(min: 500000, max: 550000);//500MS |
| 906 | regmap_write(map: es8389->regmap, ES8389_CSM_JUMP, val: 0x00); |
| 907 | regmap_write(map: es8389->regmap, ES8389_ANA_CTL1, val: 0x08); |
| 908 | regmap_write(map: es8389->regmap, ES8389_ISO_CTL, val: 0xC1); |
| 909 | regmap_write(map: es8389->regmap, ES8389_PULL_DOWN, val: 0x00); |
| 910 | } |
| 911 | |
| 912 | static int es8389_i2c_probe(struct i2c_client *i2c_client) |
| 913 | { |
| 914 | struct es8389_private *es8389; |
| 915 | int ret; |
| 916 | |
| 917 | es8389 = devm_kzalloc(dev: &i2c_client->dev, size: sizeof(*es8389), GFP_KERNEL); |
| 918 | if (es8389 == NULL) |
| 919 | return -ENOMEM; |
| 920 | |
| 921 | i2c_set_clientdata(client: i2c_client, data: es8389); |
| 922 | es8389->regmap = devm_regmap_init_i2c(i2c_client, &es8389_regmap); |
| 923 | if (IS_ERR(ptr: es8389->regmap)) |
| 924 | return dev_err_probe(dev: &i2c_client->dev, err: PTR_ERR(ptr: es8389->regmap), |
| 925 | fmt: "regmap_init() failed\n" ); |
| 926 | |
| 927 | ret = devm_snd_soc_register_component(dev: &i2c_client->dev, |
| 928 | component_driver: &soc_codec_dev_es8389, |
| 929 | dai_drv: &es8389_dai, |
| 930 | num_dai: 1); |
| 931 | |
| 932 | return ret; |
| 933 | } |
| 934 | |
| 935 | #ifdef CONFIG_OF |
| 936 | static const struct of_device_id es8389_if_dt_ids[] = { |
| 937 | { .compatible = "everest,es8389" , }, |
| 938 | { } |
| 939 | }; |
| 940 | MODULE_DEVICE_TABLE(of, es8389_if_dt_ids); |
| 941 | #endif |
| 942 | |
| 943 | static const struct i2c_device_id es8389_i2c_id[] = { |
| 944 | {"es8389" }, |
| 945 | { } |
| 946 | }; |
| 947 | MODULE_DEVICE_TABLE(i2c, es8389_i2c_id); |
| 948 | |
| 949 | static struct i2c_driver es8389_i2c_driver = { |
| 950 | .driver = { |
| 951 | .name = "es8389" , |
| 952 | .of_match_table = of_match_ptr(es8389_if_dt_ids), |
| 953 | }, |
| 954 | .shutdown = es8389_i2c_shutdown, |
| 955 | .probe = es8389_i2c_probe, |
| 956 | .id_table = es8389_i2c_id, |
| 957 | }; |
| 958 | module_i2c_driver(es8389_i2c_driver); |
| 959 | |
| 960 | MODULE_DESCRIPTION("ASoC es8389 driver" ); |
| 961 | MODULE_AUTHOR("Michael Zhang <zhangyi@everest-semi.com>" ); |
| 962 | MODULE_LICENSE("GPL" ); |
| 963 | |