1b97391a6SBinbin Zhou // SPDX-License-Identifier: GPL-2.0-only 2b97391a6SBinbin Zhou // 3b97391a6SBinbin Zhou // es8323.c -- es8323 ALSA SoC audio driver 4b97391a6SBinbin Zhou // 5b97391a6SBinbin Zhou // Copyright 2024 Rockchip Electronics Co. Ltd. 6b97391a6SBinbin Zhou // Copyright 2024 Everest Semiconductor Co.,Ltd. 7b97391a6SBinbin Zhou // Copyright 2024 Loongson Technology Co.,Ltd. 8b97391a6SBinbin Zhou // 9b97391a6SBinbin Zhou // Author: Mark Brown <broonie@kernel.org> 10b97391a6SBinbin Zhou // Jianqun Xu <jay.xu@rock-chips.com> 11b97391a6SBinbin Zhou // Nickey Yang <nickey.yang@rock-chips.com> 12b97391a6SBinbin Zhou // Further cleanup and restructuring by: 13b97391a6SBinbin Zhou // Binbin Zhou <zhoubinbin@loongson.cn> 14b97391a6SBinbin Zhou 15b97391a6SBinbin Zhou #include <linux/module.h> 16b97391a6SBinbin Zhou #include <linux/acpi.h> 17b97391a6SBinbin Zhou #include <linux/clk.h> 18b97391a6SBinbin Zhou #include <linux/delay.h> 19b97391a6SBinbin Zhou #include <linux/i2c.h> 20b97391a6SBinbin Zhou #include <linux/mod_devicetable.h> 21b97391a6SBinbin Zhou #include <linux/regmap.h> 22b97391a6SBinbin Zhou #include <sound/pcm.h> 23b97391a6SBinbin Zhou #include <sound/pcm_params.h> 24b97391a6SBinbin Zhou #include <sound/soc.h> 25b97391a6SBinbin Zhou #include <sound/soc-dapm.h> 26b97391a6SBinbin Zhou #include <sound/tlv.h> 27b97391a6SBinbin Zhou 28b97391a6SBinbin Zhou #include "es8323.h" 29b97391a6SBinbin Zhou 30b97391a6SBinbin Zhou struct es8323_priv { 31b97391a6SBinbin Zhou unsigned int sysclk; 32b97391a6SBinbin Zhou struct clk *mclk; 33b97391a6SBinbin Zhou struct regmap *regmap; 34b97391a6SBinbin Zhou struct snd_pcm_hw_constraint_list *sysclk_constraints; 35b97391a6SBinbin Zhou struct snd_soc_component *component; 36b97391a6SBinbin Zhou }; 37b97391a6SBinbin Zhou 38b97391a6SBinbin Zhou /* es8323 register cache */ 39b97391a6SBinbin Zhou static const struct reg_default es8323_reg_defaults[] = { 40b97391a6SBinbin Zhou { ES8323_CONTROL1, 0x06 }, 41b97391a6SBinbin Zhou { ES8323_CONTROL2, 0x1c }, 42b97391a6SBinbin Zhou { ES8323_CHIPPOWER, 0xc3 }, 43b97391a6SBinbin Zhou { ES8323_ADCPOWER, 0xfc }, 44b97391a6SBinbin Zhou { ES8323_DACPOWER, 0xc0 }, 45b97391a6SBinbin Zhou { ES8323_CHIPLOPOW1, 0x00 }, 46b97391a6SBinbin Zhou { ES8323_CHIPLOPOW2, 0x00 }, 47b97391a6SBinbin Zhou { ES8323_ANAVOLMANAG, 0x7c }, 48b97391a6SBinbin Zhou { ES8323_MASTERMODE, 0x80 }, 49b97391a6SBinbin Zhou { ES8323_ADCCONTROL1, 0x00 }, 50b97391a6SBinbin Zhou { ES8323_ADCCONTROL2, 0x00 }, 51b97391a6SBinbin Zhou { ES8323_ADCCONTROL3, 0x06 }, 52b97391a6SBinbin Zhou { ES8323_ADCCONTROL4, 0x00 }, 53b97391a6SBinbin Zhou { ES8323_ADCCONTROL5, 0x06 }, 54b97391a6SBinbin Zhou { ES8323_ADCCONTROL6, 0x30 }, 55b97391a6SBinbin Zhou { ES8323_ADC_MUTE, 0x30 }, 56b97391a6SBinbin Zhou { ES8323_LADC_VOL, 0xc0 }, 57b97391a6SBinbin Zhou { ES8323_RADC_VOL, 0xc0 }, 58b97391a6SBinbin Zhou { ES8323_ADCCONTROL10, 0x38 }, 59b97391a6SBinbin Zhou { ES8323_ADCCONTROL11, 0xb0 }, 60b97391a6SBinbin Zhou { ES8323_ADCCONTROL12, 0x32 }, 61b97391a6SBinbin Zhou { ES8323_ADCCONTROL13, 0x06 }, 62b97391a6SBinbin Zhou { ES8323_ADCCONTROL14, 0x00 }, 63b97391a6SBinbin Zhou { ES8323_DACCONTROL1, 0x00 }, 64b97391a6SBinbin Zhou { ES8323_DACCONTROL2, 0x06 }, 65b97391a6SBinbin Zhou { ES8323_DAC_MUTE, 0x30 }, 66b97391a6SBinbin Zhou { ES8323_LDAC_VOL, 0xc0 }, 67b97391a6SBinbin Zhou { ES8323_RDAC_VOL, 0xc0 }, 68b97391a6SBinbin Zhou { ES8323_DACCONTROL6, 0x08 }, 69b97391a6SBinbin Zhou { ES8323_DACCONTROL7, 0x06 }, 70b97391a6SBinbin Zhou { ES8323_DACCONTROL8, 0x1f }, 71b97391a6SBinbin Zhou { ES8323_DACCONTROL9, 0xf7 }, 72b97391a6SBinbin Zhou { ES8323_DACCONTROL10, 0xfd }, 73b97391a6SBinbin Zhou { ES8323_DACCONTROL11, 0xff }, 74b97391a6SBinbin Zhou { ES8323_DACCONTROL12, 0x1f }, 75b97391a6SBinbin Zhou { ES8323_DACCONTROL13, 0xf7 }, 76b97391a6SBinbin Zhou { ES8323_DACCONTROL14, 0xfd }, 77b97391a6SBinbin Zhou { ES8323_DACCONTROL15, 0xff }, 78b97391a6SBinbin Zhou { ES8323_DACCONTROL16, 0x00 }, 79b97391a6SBinbin Zhou { ES8323_DACCONTROL17, 0x38 }, 80b97391a6SBinbin Zhou { ES8323_DACCONTROL18, 0x38 }, 81b97391a6SBinbin Zhou { ES8323_DACCONTROL19, 0x38 }, 82b97391a6SBinbin Zhou { ES8323_DACCONTROL20, 0x38 }, 83b97391a6SBinbin Zhou { ES8323_DACCONTROL21, 0x38 }, 84b97391a6SBinbin Zhou { ES8323_DACCONTROL22, 0x38 }, 85b97391a6SBinbin Zhou { ES8323_DACCONTROL23, 0x00 }, 86b97391a6SBinbin Zhou { ES8323_LOUT1_VOL, 0x00 }, 87b97391a6SBinbin Zhou { ES8323_ROUT1_VOL, 0x00 }, 88b97391a6SBinbin Zhou }; 89b97391a6SBinbin Zhou 90b97391a6SBinbin Zhou static const char *const es8323_stereo_3d_texts[] = { "No 3D ", "Level 1", "Level 2", "Level 3", 91b97391a6SBinbin Zhou "Level 4", "Level 5", "Level 6", "Level 7" }; 92b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_stereo_3d_enum, ES8323_DACCONTROL7, 2, es8323_stereo_3d_texts); 93b97391a6SBinbin Zhou 94b97391a6SBinbin Zhou static const char *const es8323_alc_func_texts[] = { "Off", "Right", "Left", "Stereo" }; 95b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_alc_function_enum, 96b97391a6SBinbin Zhou ES8323_ADCCONTROL10, 6, es8323_alc_func_texts); 97b97391a6SBinbin Zhou 98b97391a6SBinbin Zhou static const char *const es8323_ng_type_texts[] = { "Constant PGA Gain", "Mute ADC Output" }; 99b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_alc_ng_type_enum, ES8323_ADCCONTROL14, 1, es8323_ng_type_texts); 100b97391a6SBinbin Zhou 101b97391a6SBinbin Zhou static const char *const es8323_deemph_texts[] = { "None", "32Khz", "44.1Khz", "48Khz" }; 102b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_playback_deemphasis_enum, 103b97391a6SBinbin Zhou ES8323_DACCONTROL6, 6, es8323_deemph_texts); 104b97391a6SBinbin Zhou 105b97391a6SBinbin Zhou static const char *const es8323_adcpol_texts[] = { "Normal", "L Invert", 106b97391a6SBinbin Zhou "R Invert", "L + R Invert" }; 107b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_capture_polarity_enum, 108b97391a6SBinbin Zhou ES8323_ADCCONTROL6, 6, es8323_adcpol_texts); 109b97391a6SBinbin Zhou 110b97391a6SBinbin Zhou static const DECLARE_TLV_DB_SCALE(es8323_adc_tlv, -9600, 50, 1); 111b97391a6SBinbin Zhou static const DECLARE_TLV_DB_SCALE(es8323_dac_tlv, -9600, 50, 1); 112b97391a6SBinbin Zhou static const DECLARE_TLV_DB_SCALE(es8323_out_tlv, -4500, 150, 0); 113b97391a6SBinbin Zhou static const DECLARE_TLV_DB_SCALE(es8323_bypass_tlv, 0, 300, 0); 114b97391a6SBinbin Zhou static const DECLARE_TLV_DB_SCALE(es8323_bypass_tlv2, -15, 300, 0); 115b97391a6SBinbin Zhou 116b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_snd_controls[] = { 117b97391a6SBinbin Zhou SOC_ENUM("3D Mode", es8323_stereo_3d_enum), 118b97391a6SBinbin Zhou SOC_ENUM("ALC Capture Function", es8323_alc_function_enum), 119b97391a6SBinbin Zhou SOC_ENUM("ALC Capture NG Type", es8323_alc_ng_type_enum), 120b97391a6SBinbin Zhou SOC_ENUM("Playback De-emphasis", es8323_playback_deemphasis_enum), 121b97391a6SBinbin Zhou SOC_ENUM("Capture Polarity", es8323_capture_polarity_enum), 122b97391a6SBinbin Zhou SOC_SINGLE("ALC Capture ZC Switch", ES8323_ADCCONTROL13, 6, 1, 0), 123b97391a6SBinbin Zhou SOC_SINGLE("ALC Capture Decay Time", ES8323_ADCCONTROL12, 4, 15, 0), 124b97391a6SBinbin Zhou SOC_SINGLE("ALC Capture Attack Time", ES8323_ADCCONTROL12, 0, 15, 0), 125b97391a6SBinbin Zhou SOC_SINGLE("ALC Capture NG Threshold", ES8323_ADCCONTROL14, 3, 31, 0), 126b97391a6SBinbin Zhou SOC_SINGLE("ALC Capture NG Switch", ES8323_ADCCONTROL14, 0, 1, 0), 127b97391a6SBinbin Zhou SOC_SINGLE("ZC Timeout Switch", ES8323_ADCCONTROL13, 6, 1, 0), 128b97391a6SBinbin Zhou SOC_SINGLE("Capture Mute Switch", ES8323_ADC_MUTE, 2, 1, 0), 129b97391a6SBinbin Zhou SOC_SINGLE_TLV("Left Channel Capture Volume", ES8323_ADCCONTROL1, 4, 8, 130b97391a6SBinbin Zhou 0, es8323_bypass_tlv), 131b97391a6SBinbin Zhou SOC_SINGLE_TLV("Right Channel Capture Volume", ES8323_ADCCONTROL1, 0, 132b97391a6SBinbin Zhou 8, 0, es8323_bypass_tlv), 133b97391a6SBinbin Zhou SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", ES8323_DACCONTROL17, 3, 134b97391a6SBinbin Zhou 7, 1, es8323_bypass_tlv2), 135b97391a6SBinbin Zhou SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", ES8323_DACCONTROL20, 136b97391a6SBinbin Zhou 3, 7, 1, es8323_bypass_tlv2), 137b97391a6SBinbin Zhou SOC_DOUBLE_R_TLV("PCM Volume", ES8323_LDAC_VOL, ES8323_RDAC_VOL, 138b97391a6SBinbin Zhou 0, 192, 1, es8323_dac_tlv), 139b97391a6SBinbin Zhou SOC_DOUBLE_R_TLV("Capture Digital Volume", ES8323_LADC_VOL, 140b97391a6SBinbin Zhou ES8323_RADC_VOL, 0, 192, 1, es8323_adc_tlv), 141b97391a6SBinbin Zhou SOC_DOUBLE_R_TLV("Output 1 Playback Volume", ES8323_LOUT1_VOL, 142b97391a6SBinbin Zhou ES8323_ROUT1_VOL, 0, 33, 0, es8323_out_tlv), 143b97391a6SBinbin Zhou SOC_DOUBLE_R_TLV("Output 2 Playback Volume", ES8323_LOUT2_VOL, 144b97391a6SBinbin Zhou ES8323_ROUT2_VOL, 0, 33, 0, es8323_out_tlv), 145b97391a6SBinbin Zhou }; 146b97391a6SBinbin Zhou 147b97391a6SBinbin Zhou /* Left DAC Route */ 148b97391a6SBinbin Zhou static const char *const es8323_pga_sell[] = { "Line 1L", "Line 2L", "NC", "DifferentialL" }; 149b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_left_dac_enum, ES8323_ADCCONTROL2, 6, es8323_pga_sell); 150b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_left_dac_mux_controls = 151b97391a6SBinbin Zhou SOC_DAPM_ENUM("Left DAC Route", es8323_left_dac_enum); 152b97391a6SBinbin Zhou 153b97391a6SBinbin Zhou /* Right DAC Route */ 154b97391a6SBinbin Zhou static const char *const es8323_pga_selr[] = { "Line 1R", "Line 2R", "NC", "DifferentialR" }; 155b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_right_dac_enum, ES8323_ADCCONTROL2, 4, es8323_pga_selr); 156b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_right_dac_mux_controls = 157b97391a6SBinbin Zhou SOC_DAPM_ENUM("Right DAC Route", es8323_right_dac_enum); 158b97391a6SBinbin Zhou 159b97391a6SBinbin Zhou /* Left Line Mux */ 160b97391a6SBinbin Zhou static const char *const es8323_lin_sell[] = { "Line 1L", "Line 2L", "NC", "MicL" }; 161b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_llin_enum, ES8323_DACCONTROL16, 3, es8323_lin_sell); 162b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_left_line_controls = 163b97391a6SBinbin Zhou SOC_DAPM_ENUM("LLIN Mux", es8323_llin_enum); 164b97391a6SBinbin Zhou 165b97391a6SBinbin Zhou /* Right Line Mux */ 166b97391a6SBinbin Zhou static const char *const es8323_lin_selr[] = { "Line 1R", "Line 2R", "NC", "MicR" }; 167b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_rlin_enum, ES8323_DACCONTROL16, 0, es8323_lin_selr); 168b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_right_line_controls = 169b97391a6SBinbin Zhou SOC_DAPM_ENUM("RLIN Mux", es8323_rlin_enum); 170b97391a6SBinbin Zhou 171b97391a6SBinbin Zhou /* Differential Mux */ 172b97391a6SBinbin Zhou static const char *const es8323_diffmux_sel[] = { "Line 1", "Line 2" }; 173b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_diffmux_enum, ES8323_ADCCONTROL3, 7, es8323_diffmux_sel); 174b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_diffmux_controls = 175b97391a6SBinbin Zhou SOC_DAPM_ENUM("Route2", es8323_diffmux_enum); 176b97391a6SBinbin Zhou 177b97391a6SBinbin Zhou /* Mono ADC Mux */ 178b97391a6SBinbin Zhou static const char *const es8323_mono_adc_mux[] = { "Stereo", "Mono (Left)", "Mono (Right)" }; 179b97391a6SBinbin Zhou static SOC_ENUM_SINGLE_DECL(es8323_mono_adc_mux_enum, ES8323_ADCCONTROL3, 3, es8323_mono_adc_mux); 180b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_mono_adc_mux_controls = 181b97391a6SBinbin Zhou SOC_DAPM_ENUM("Mono Mux", es8323_mono_adc_mux_enum); 182b97391a6SBinbin Zhou 183b97391a6SBinbin Zhou /* Left Mixer */ 184b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_left_mixer_controls[] = { 185b97391a6SBinbin Zhou SOC_DAPM_SINGLE("Left Playback Switch", SND_SOC_NOPM, 7, 1, 1), 186b97391a6SBinbin Zhou SOC_DAPM_SINGLE("Left Bypass Switch", ES8323_DACCONTROL17, 6, 1, 0), 187b97391a6SBinbin Zhou }; 188b97391a6SBinbin Zhou 189b97391a6SBinbin Zhou /* Right Mixer */ 190b97391a6SBinbin Zhou static const struct snd_kcontrol_new es8323_right_mixer_controls[] = { 191b97391a6SBinbin Zhou SOC_DAPM_SINGLE("Right Playback Switch", SND_SOC_NOPM, 6, 1, 1), 192b97391a6SBinbin Zhou SOC_DAPM_SINGLE("Right Bypass Switch", ES8323_DACCONTROL20, 6, 1, 0), 193b97391a6SBinbin Zhou }; 194b97391a6SBinbin Zhou 195b97391a6SBinbin Zhou static const struct snd_soc_dapm_widget es8323_dapm_widgets[] = { 196b97391a6SBinbin Zhou SND_SOC_DAPM_INPUT("LINPUT1"), 197b97391a6SBinbin Zhou SND_SOC_DAPM_INPUT("LINPUT2"), 198b97391a6SBinbin Zhou SND_SOC_DAPM_INPUT("RINPUT1"), 199b97391a6SBinbin Zhou SND_SOC_DAPM_INPUT("RINPUT2"), 200b97391a6SBinbin Zhou 201b97391a6SBinbin Zhou SND_SOC_DAPM_MICBIAS("Mic Bias", SND_SOC_NOPM, 3, 1), 202b97391a6SBinbin Zhou 203b97391a6SBinbin Zhou /* Muxes */ 204b97391a6SBinbin Zhou SND_SOC_DAPM_MUX("Left PGA Mux", SND_SOC_NOPM, 0, 0, &es8323_left_dac_mux_controls), 205b97391a6SBinbin Zhou SND_SOC_DAPM_MUX("Right PGA Mux", SND_SOC_NOPM, 0, 0, &es8323_right_dac_mux_controls), 206b97391a6SBinbin Zhou SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, &es8323_diffmux_controls), 207b97391a6SBinbin Zhou SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, &es8323_mono_adc_mux_controls), 208b97391a6SBinbin Zhou SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, &es8323_mono_adc_mux_controls), 209b97391a6SBinbin Zhou SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, &es8323_left_line_controls), 210b97391a6SBinbin Zhou SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, &es8323_right_line_controls), 211b97391a6SBinbin Zhou 212b97391a6SBinbin Zhou SND_SOC_DAPM_ADC("Right ADC", "Right Capture", SND_SOC_NOPM, 4, 1), 213b97391a6SBinbin Zhou SND_SOC_DAPM_ADC("Left ADC", "Left Capture", SND_SOC_NOPM, 5, 1), 214b97391a6SBinbin Zhou SND_SOC_DAPM_DAC("Right DAC", "Right Playback", SND_SOC_NOPM, 6, 1), 215b97391a6SBinbin Zhou SND_SOC_DAPM_DAC("Left DAC", "Left Playback", SND_SOC_NOPM, 7, 1), 216b97391a6SBinbin Zhou 217b97391a6SBinbin Zhou SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, 218b97391a6SBinbin Zhou &es8323_left_mixer_controls[0], 219b97391a6SBinbin Zhou ARRAY_SIZE(es8323_left_mixer_controls)), 220b97391a6SBinbin Zhou SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, 221b97391a6SBinbin Zhou &es8323_right_mixer_controls[0], 222b97391a6SBinbin Zhou ARRAY_SIZE(es8323_right_mixer_controls)), 223b97391a6SBinbin Zhou 224b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("Right ADC Power", SND_SOC_NOPM, 6, 1, NULL, 0), 225b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("Left ADC Power", SND_SOC_NOPM, 7, 1, NULL, 0), 226b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("Right Out 2", SND_SOC_NOPM, 2, 0, NULL, 0), 227b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("Left Out 2", SND_SOC_NOPM, 3, 0, NULL, 0), 228b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("Right Out 1", SND_SOC_NOPM, 4, 0, NULL, 0), 229b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("Left Out 1", SND_SOC_NOPM, 5, 0, NULL, 0), 230b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("LAMP", ES8323_ADCCONTROL1, 4, 0, NULL, 0), 231b97391a6SBinbin Zhou SND_SOC_DAPM_PGA("RAMP", ES8323_ADCCONTROL1, 0, 0, NULL, 0), 232b97391a6SBinbin Zhou 233b97391a6SBinbin Zhou SND_SOC_DAPM_OUTPUT("LOUT1"), 234b97391a6SBinbin Zhou SND_SOC_DAPM_OUTPUT("ROUT1"), 235b97391a6SBinbin Zhou SND_SOC_DAPM_OUTPUT("LOUT2"), 236b97391a6SBinbin Zhou SND_SOC_DAPM_OUTPUT("ROUT2"), 237b97391a6SBinbin Zhou SND_SOC_DAPM_OUTPUT("VREF"), 238b97391a6SBinbin Zhou }; 239b97391a6SBinbin Zhou 240b97391a6SBinbin Zhou static const struct snd_soc_dapm_route es8323_dapm_routes[] = { 241b97391a6SBinbin Zhou /*12.22*/ 242b97391a6SBinbin Zhou {"Left PGA Mux", "Line 1L", "LINPUT1"}, 243b97391a6SBinbin Zhou {"Left PGA Mux", "Line 2L", "LINPUT2"}, 244b97391a6SBinbin Zhou {"Left PGA Mux", "DifferentialL", "Differential Mux"}, 245b97391a6SBinbin Zhou 246b97391a6SBinbin Zhou {"Right PGA Mux", "Line 1R", "RINPUT1"}, 247b97391a6SBinbin Zhou {"Right PGA Mux", "Line 2R", "RINPUT2"}, 248b97391a6SBinbin Zhou {"Right PGA Mux", "DifferentialR", "Differential Mux"}, 249b97391a6SBinbin Zhou 250b97391a6SBinbin Zhou {"Differential Mux", "Line 1", "LINPUT1"}, 251b97391a6SBinbin Zhou {"Differential Mux", "Line 1", "RINPUT1"}, 252b97391a6SBinbin Zhou {"Differential Mux", "Line 2", "LINPUT2"}, 253b97391a6SBinbin Zhou {"Differential Mux", "Line 2", "RINPUT2"}, 254b97391a6SBinbin Zhou 255b97391a6SBinbin Zhou {"Left ADC Mux", "Stereo", "Right PGA Mux"}, 256b97391a6SBinbin Zhou {"Left ADC Mux", "Stereo", "Left PGA Mux"}, 257b97391a6SBinbin Zhou {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"}, 258b97391a6SBinbin Zhou 259b97391a6SBinbin Zhou {"Right ADC Mux", "Stereo", "Left PGA Mux"}, 260b97391a6SBinbin Zhou {"Right ADC Mux", "Stereo", "Right PGA Mux"}, 261b97391a6SBinbin Zhou {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"}, 262b97391a6SBinbin Zhou 263b97391a6SBinbin Zhou {"Left ADC Power", NULL, "Left ADC Mux"}, 264b97391a6SBinbin Zhou {"Right ADC Power", NULL, "Right ADC Mux"}, 265b97391a6SBinbin Zhou {"Left ADC", NULL, "Left ADC Power"}, 266b97391a6SBinbin Zhou {"Right ADC", NULL, "Right ADC Power"}, 267b97391a6SBinbin Zhou 268b97391a6SBinbin Zhou {"Left Line Mux", "Line 1L", "LINPUT1"}, 269b97391a6SBinbin Zhou {"Left Line Mux", "Line 2L", "LINPUT2"}, 270b97391a6SBinbin Zhou {"Left Line Mux", "MicL", "Left PGA Mux"}, 271b97391a6SBinbin Zhou 272b97391a6SBinbin Zhou {"Right Line Mux", "Line 1R", "RINPUT1"}, 273b97391a6SBinbin Zhou {"Right Line Mux", "Line 2R", "RINPUT2"}, 274b97391a6SBinbin Zhou {"Right Line Mux", "MicR", "Right PGA Mux"}, 275b97391a6SBinbin Zhou 276b97391a6SBinbin Zhou {"Left Mixer", "Left Playback Switch", "Left DAC"}, 277b97391a6SBinbin Zhou {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, 278b97391a6SBinbin Zhou 279b97391a6SBinbin Zhou {"Right Mixer", "Right Playback Switch", "Right DAC"}, 280b97391a6SBinbin Zhou {"Right Mixer", "Right Bypass Switch", "Right Line Mux"}, 281b97391a6SBinbin Zhou 282b97391a6SBinbin Zhou {"Left Out 1", NULL, "Left Mixer"}, 283b97391a6SBinbin Zhou {"LOUT1", NULL, "Left Out 1"}, 284b97391a6SBinbin Zhou {"Right Out 1", NULL, "Right Mixer"}, 285b97391a6SBinbin Zhou {"ROUT1", NULL, "Right Out 1"}, 286b97391a6SBinbin Zhou 287b97391a6SBinbin Zhou {"Left Out 2", NULL, "Left Mixer"}, 288b97391a6SBinbin Zhou {"LOUT2", NULL, "Left Out 2"}, 289b97391a6SBinbin Zhou {"Right Out 2", NULL, "Right Mixer"}, 290b97391a6SBinbin Zhou {"ROUT2", NULL, "Right Out 2"}, 291b97391a6SBinbin Zhou }; 292b97391a6SBinbin Zhou 293b97391a6SBinbin Zhou struct coeff_div { 294b97391a6SBinbin Zhou u32 mclk; 295b97391a6SBinbin Zhou u32 rate; 296b97391a6SBinbin Zhou u16 fs; 297b97391a6SBinbin Zhou u8 sr:4; 298b97391a6SBinbin Zhou u8 usb:1; 299b97391a6SBinbin Zhou }; 300b97391a6SBinbin Zhou 301b97391a6SBinbin Zhou /* codec hifi mclk clock divider coefficients */ 302b97391a6SBinbin Zhou static const struct coeff_div es8323_coeff_div[] = { 303b97391a6SBinbin Zhou /* 8k */ 304b97391a6SBinbin Zhou {12288000, 8000, 1536, 0xa, 0x0}, 305b97391a6SBinbin Zhou {11289600, 8000, 1408, 0x9, 0x0}, 306b97391a6SBinbin Zhou {18432000, 8000, 2304, 0xc, 0x0}, 307b97391a6SBinbin Zhou {16934400, 8000, 2112, 0xb, 0x0}, 308b97391a6SBinbin Zhou {12000000, 8000, 1500, 0xb, 0x1}, 309b97391a6SBinbin Zhou 310b97391a6SBinbin Zhou /* 11.025k */ 311b97391a6SBinbin Zhou {11289600, 11025, 1024, 0x7, 0x0}, 312b97391a6SBinbin Zhou {16934400, 11025, 1536, 0xa, 0x0}, 313b97391a6SBinbin Zhou {12000000, 11025, 1088, 0x9, 0x1}, 314b97391a6SBinbin Zhou 315b97391a6SBinbin Zhou /* 16k */ 316b97391a6SBinbin Zhou {12288000, 16000, 768, 0x6, 0x0}, 317b97391a6SBinbin Zhou {18432000, 16000, 1152, 0x8, 0x0}, 318b97391a6SBinbin Zhou {12000000, 16000, 750, 0x7, 0x1}, 319b97391a6SBinbin Zhou 320b97391a6SBinbin Zhou /* 22.05k */ 321b97391a6SBinbin Zhou {11289600, 22050, 512, 0x4, 0x0}, 322b97391a6SBinbin Zhou {16934400, 22050, 768, 0x6, 0x0}, 323b97391a6SBinbin Zhou {12000000, 22050, 544, 0x6, 0x1}, 324b97391a6SBinbin Zhou 325b97391a6SBinbin Zhou /* 32k */ 326b97391a6SBinbin Zhou {12288000, 32000, 384, 0x3, 0x0}, 327b97391a6SBinbin Zhou {18432000, 32000, 576, 0x5, 0x0}, 328b97391a6SBinbin Zhou {12000000, 32000, 375, 0x4, 0x1}, 329b97391a6SBinbin Zhou 330b97391a6SBinbin Zhou /* 44.1k */ 331b97391a6SBinbin Zhou {11289600, 44100, 256, 0x2, 0x0}, 332b97391a6SBinbin Zhou {16934400, 44100, 384, 0x3, 0x0}, 333b97391a6SBinbin Zhou {12000000, 44100, 272, 0x3, 0x1}, 334b97391a6SBinbin Zhou 335b97391a6SBinbin Zhou /* 48k */ 336b97391a6SBinbin Zhou {12288000, 48000, 256, 0x2, 0x0}, 337b97391a6SBinbin Zhou {18432000, 48000, 384, 0x3, 0x0}, 338b97391a6SBinbin Zhou {12000000, 48000, 250, 0x2, 0x1}, 339b97391a6SBinbin Zhou 340b97391a6SBinbin Zhou /* 88.2k */ 341b97391a6SBinbin Zhou {11289600, 88200, 128, 0x0, 0x0}, 342b97391a6SBinbin Zhou {16934400, 88200, 192, 0x1, 0x0}, 343b97391a6SBinbin Zhou {12000000, 88200, 136, 0x1, 0x1}, 344b97391a6SBinbin Zhou 345b97391a6SBinbin Zhou /* 96k */ 346b97391a6SBinbin Zhou {12288000, 96000, 128, 0x0, 0x0}, 347b97391a6SBinbin Zhou {18432000, 96000, 192, 0x1, 0x0}, 348b97391a6SBinbin Zhou {12000000, 96000, 125, 0x0, 0x1}, 349b97391a6SBinbin Zhou }; 350b97391a6SBinbin Zhou 351b97391a6SBinbin Zhou static unsigned int rates_12288[] = { 352b97391a6SBinbin Zhou 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000, 353b97391a6SBinbin Zhou }; 354b97391a6SBinbin Zhou 355b97391a6SBinbin Zhou static struct snd_pcm_hw_constraint_list constraints_12288 = { 356b97391a6SBinbin Zhou .count = ARRAY_SIZE(rates_12288), 357b97391a6SBinbin Zhou .list = rates_12288, 358b97391a6SBinbin Zhou }; 359b97391a6SBinbin Zhou 360b97391a6SBinbin Zhou static unsigned int rates_112896[] = { 361b97391a6SBinbin Zhou 8000, 11025, 22050, 44100, 362b97391a6SBinbin Zhou }; 363b97391a6SBinbin Zhou 364b97391a6SBinbin Zhou static struct snd_pcm_hw_constraint_list constraints_112896 = { 365b97391a6SBinbin Zhou .count = ARRAY_SIZE(rates_112896), 366b97391a6SBinbin Zhou .list = rates_112896, 367b97391a6SBinbin Zhou }; 368b97391a6SBinbin Zhou 369b97391a6SBinbin Zhou static unsigned int rates_12[] = { 370b97391a6SBinbin Zhou 8000, 11025, 12000, 16000, 22050, 24000, 371b97391a6SBinbin Zhou 32000, 44100, 48000, 48000, 88235, 96000, 372b97391a6SBinbin Zhou }; 373b97391a6SBinbin Zhou 374b97391a6SBinbin Zhou static struct snd_pcm_hw_constraint_list constraints_12 = { 375b97391a6SBinbin Zhou .count = ARRAY_SIZE(rates_12), 376b97391a6SBinbin Zhou .list = rates_12, 377b97391a6SBinbin Zhou }; 378b97391a6SBinbin Zhou 379b97391a6SBinbin Zhou static inline int get_coeff(int mclk, int rate) 380b97391a6SBinbin Zhou { 381b97391a6SBinbin Zhou int i; 382b97391a6SBinbin Zhou 383b97391a6SBinbin Zhou for (i = 0; i < ARRAY_SIZE(es8323_coeff_div); i++) { 384b97391a6SBinbin Zhou if (es8323_coeff_div[i].rate == rate && 385b97391a6SBinbin Zhou es8323_coeff_div[i].mclk == mclk) 386b97391a6SBinbin Zhou return i; 387b97391a6SBinbin Zhou } 388b97391a6SBinbin Zhou 389b97391a6SBinbin Zhou return -EINVAL; 390b97391a6SBinbin Zhou } 391b97391a6SBinbin Zhou 392b97391a6SBinbin Zhou static int es8323_set_dai_sysclk(struct snd_soc_dai *codec_dai, 393b97391a6SBinbin Zhou int clk_id, unsigned int freq, int dir) 394b97391a6SBinbin Zhou { 395b97391a6SBinbin Zhou struct snd_soc_component *component = codec_dai->component; 396b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 397b97391a6SBinbin Zhou 398b97391a6SBinbin Zhou switch (freq) { 399b97391a6SBinbin Zhou case 11289600: 400b97391a6SBinbin Zhou case 18432000: 401b97391a6SBinbin Zhou case 22579200: 402b97391a6SBinbin Zhou case 36864000: 403b97391a6SBinbin Zhou es8323->sysclk_constraints = &constraints_112896; 404b97391a6SBinbin Zhou break; 405b97391a6SBinbin Zhou case 12288000: 406b97391a6SBinbin Zhou case 16934400: 407b97391a6SBinbin Zhou case 24576000: 408b97391a6SBinbin Zhou case 33868800: 409b97391a6SBinbin Zhou es8323->sysclk_constraints = &constraints_12288; 410b97391a6SBinbin Zhou break; 411b97391a6SBinbin Zhou case 12000000: 412b97391a6SBinbin Zhou case 24000000: 413b97391a6SBinbin Zhou es8323->sysclk_constraints = &constraints_12; 414b97391a6SBinbin Zhou break; 415b97391a6SBinbin Zhou default: 416b97391a6SBinbin Zhou return -EINVAL; 417b97391a6SBinbin Zhou } 418b97391a6SBinbin Zhou 419b97391a6SBinbin Zhou es8323->sysclk = freq; 420b97391a6SBinbin Zhou return 0; 421b97391a6SBinbin Zhou } 422b97391a6SBinbin Zhou 423b97391a6SBinbin Zhou static int es8323_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 424b97391a6SBinbin Zhou { 425b97391a6SBinbin Zhou struct snd_soc_component *component = codec_dai->component; 426b97391a6SBinbin Zhou u8 iface = snd_soc_component_read(component, ES8323_MASTERMODE); 427b97391a6SBinbin Zhou u8 adciface = snd_soc_component_read(component, ES8323_ADC_IFACE); 428b97391a6SBinbin Zhou u8 daciface = snd_soc_component_read(component, ES8323_DAC_IFACE); 429b97391a6SBinbin Zhou 430b97391a6SBinbin Zhou switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 431b97391a6SBinbin Zhou case SND_SOC_DAIFMT_BC_FP: 432b97391a6SBinbin Zhou iface |= 0x80; 433b97391a6SBinbin Zhou break; 434b97391a6SBinbin Zhou case SND_SOC_DAIFMT_BC_FC: 435b97391a6SBinbin Zhou iface &= 0x7f; 436b97391a6SBinbin Zhou break; 437b97391a6SBinbin Zhou default: 438b97391a6SBinbin Zhou return -EINVAL; 439b97391a6SBinbin Zhou } 440b97391a6SBinbin Zhou 441b97391a6SBinbin Zhou /* interface format */ 442b97391a6SBinbin Zhou switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 443b97391a6SBinbin Zhou case SND_SOC_DAIFMT_I2S: 444b97391a6SBinbin Zhou adciface &= 0xfc; 445b97391a6SBinbin Zhou daciface &= 0xf8; 446b97391a6SBinbin Zhou break; 447b97391a6SBinbin Zhou case SND_SOC_DAIFMT_LEFT_J: 448b97391a6SBinbin Zhou adciface &= 0xfd; 449b97391a6SBinbin Zhou daciface &= 0xf9; 450b97391a6SBinbin Zhou break; 451b97391a6SBinbin Zhou case SND_SOC_DAIFMT_RIGHT_J: 452b97391a6SBinbin Zhou adciface &= 0xfe; 453b97391a6SBinbin Zhou daciface &= 0xfa; 454b97391a6SBinbin Zhou break; 455b97391a6SBinbin Zhou case SND_SOC_DAIFMT_DSP_A: 456b97391a6SBinbin Zhou case SND_SOC_DAIFMT_DSP_B: 457b97391a6SBinbin Zhou adciface &= 0xff; 458b97391a6SBinbin Zhou daciface &= 0xfb; 459b97391a6SBinbin Zhou break; 460b97391a6SBinbin Zhou default: 461b97391a6SBinbin Zhou return -EINVAL; 462b97391a6SBinbin Zhou } 463b97391a6SBinbin Zhou 464b97391a6SBinbin Zhou /* clock inversion */ 465b97391a6SBinbin Zhou switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 466b97391a6SBinbin Zhou case SND_SOC_DAIFMT_NB_NF: 467b97391a6SBinbin Zhou iface &= 0xdf; 468b97391a6SBinbin Zhou adciface &= 0xdf; 469b97391a6SBinbin Zhou daciface &= 0xbf; 470b97391a6SBinbin Zhou break; 471b97391a6SBinbin Zhou case SND_SOC_DAIFMT_IB_IF: 472b97391a6SBinbin Zhou iface |= 0x20; 473b97391a6SBinbin Zhou adciface |= 0x20; 474b97391a6SBinbin Zhou daciface |= 0x40; 475b97391a6SBinbin Zhou break; 476b97391a6SBinbin Zhou case SND_SOC_DAIFMT_IB_NF: 477b97391a6SBinbin Zhou iface |= 0x20; 478b97391a6SBinbin Zhou adciface &= 0xdf; 479b97391a6SBinbin Zhou daciface &= 0xbf; 480b97391a6SBinbin Zhou break; 481b97391a6SBinbin Zhou case SND_SOC_DAIFMT_NB_IF: 482b97391a6SBinbin Zhou iface &= 0xdf; 483b97391a6SBinbin Zhou adciface |= 0x20; 484b97391a6SBinbin Zhou daciface |= 0x40; 485b97391a6SBinbin Zhou break; 486b97391a6SBinbin Zhou default: 487b97391a6SBinbin Zhou return -EINVAL; 488b97391a6SBinbin Zhou } 489b97391a6SBinbin Zhou 490b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_MASTERMODE, iface); 491b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ADC_IFACE, adciface); 492b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DAC_IFACE, daciface); 493b97391a6SBinbin Zhou 494b97391a6SBinbin Zhou return 0; 495b97391a6SBinbin Zhou } 496b97391a6SBinbin Zhou 497b97391a6SBinbin Zhou static int es8323_pcm_startup(struct snd_pcm_substream *substream, 498b97391a6SBinbin Zhou struct snd_soc_dai *dai) 499b97391a6SBinbin Zhou { 500b97391a6SBinbin Zhou struct snd_soc_component *component = dai->component; 501b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 502b97391a6SBinbin Zhou 503b97391a6SBinbin Zhou if (es8323->sysclk) { 504b97391a6SBinbin Zhou snd_pcm_hw_constraint_list(substream->runtime, 0, 505b97391a6SBinbin Zhou SNDRV_PCM_HW_PARAM_RATE, 506b97391a6SBinbin Zhou es8323->sysclk_constraints); 507b97391a6SBinbin Zhou } 508b97391a6SBinbin Zhou 509b97391a6SBinbin Zhou return 0; 510b97391a6SBinbin Zhou } 511b97391a6SBinbin Zhou 512b97391a6SBinbin Zhou static int es8323_pcm_hw_params(struct snd_pcm_substream *substream, 513b97391a6SBinbin Zhou struct snd_pcm_hw_params *params, 514b97391a6SBinbin Zhou struct snd_soc_dai *dai) 515b97391a6SBinbin Zhou { 516b97391a6SBinbin Zhou struct snd_soc_component *component = dai->component; 517b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 518b97391a6SBinbin Zhou u16 srate = snd_soc_component_read(component, ES8323_MASTERMODE) & 0x80; 519b97391a6SBinbin Zhou u16 adciface = snd_soc_component_read(component, ES8323_ADC_IFACE) & 0xe3; 520b97391a6SBinbin Zhou u16 daciface = snd_soc_component_read(component, ES8323_DAC_IFACE) & 0xc7; 521b97391a6SBinbin Zhou int coeff; 522b97391a6SBinbin Zhou 523b97391a6SBinbin Zhou coeff = get_coeff(es8323->sysclk, params_rate(params)); 524b97391a6SBinbin Zhou if (coeff < 0) { 525b97391a6SBinbin Zhou coeff = get_coeff(es8323->sysclk / 2, params_rate(params)); 526b97391a6SBinbin Zhou srate |= 0x40; 527b97391a6SBinbin Zhou } 528b97391a6SBinbin Zhou 529b97391a6SBinbin Zhou if (coeff < 0) { 530b97391a6SBinbin Zhou dev_err(component->dev, 531b97391a6SBinbin Zhou "Unable to configure sample rate %dHz with %dHz MCLK\n", 532b97391a6SBinbin Zhou params_rate(params), es8323->sysclk); 533b97391a6SBinbin Zhou return coeff; 534b97391a6SBinbin Zhou } 535b97391a6SBinbin Zhou 536b97391a6SBinbin Zhou /* bit size */ 537b97391a6SBinbin Zhou switch (params_format(params)) { 538b97391a6SBinbin Zhou case SNDRV_PCM_FORMAT_S16_LE: 539b97391a6SBinbin Zhou adciface |= 0xc; 540b97391a6SBinbin Zhou daciface |= 0x18; 541b97391a6SBinbin Zhou break; 542b97391a6SBinbin Zhou case SNDRV_PCM_FORMAT_S20_3LE: 543b97391a6SBinbin Zhou adciface |= 0x4; 544b97391a6SBinbin Zhou daciface |= 0x8; 545b97391a6SBinbin Zhou break; 546b97391a6SBinbin Zhou case SNDRV_PCM_FORMAT_S24_LE: 547b97391a6SBinbin Zhou break; 548b97391a6SBinbin Zhou case SNDRV_PCM_FORMAT_S32_LE: 549b97391a6SBinbin Zhou adciface |= 0x10; 550b97391a6SBinbin Zhou daciface |= 0x20; 551b97391a6SBinbin Zhou break; 552b97391a6SBinbin Zhou } 553b97391a6SBinbin Zhou 554b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DAC_IFACE, daciface); 555b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ADC_IFACE, adciface); 556b97391a6SBinbin Zhou 557b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_MASTERMODE, srate); 558b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ADCCONTROL5, 559b97391a6SBinbin Zhou es8323_coeff_div[coeff].sr | 560b97391a6SBinbin Zhou (es8323_coeff_div[coeff].usb) << 4); 561b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DACCONTROL2, 562b97391a6SBinbin Zhou es8323_coeff_div[coeff].sr | 563b97391a6SBinbin Zhou (es8323_coeff_div[coeff].usb) << 4); 564b97391a6SBinbin Zhou 565b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DACPOWER, 0x3c); 566b97391a6SBinbin Zhou 567b97391a6SBinbin Zhou return 0; 568b97391a6SBinbin Zhou } 569b97391a6SBinbin Zhou 570b97391a6SBinbin Zhou static int es8323_mute_stream(struct snd_soc_dai *dai, int mute, int stream) 571b97391a6SBinbin Zhou { 572b97391a6SBinbin Zhou struct snd_soc_component *component = dai->component; 573b97391a6SBinbin Zhou u32 val = mute ? 0x6 : 0x2; 574b97391a6SBinbin Zhou 575b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DAC_MUTE, val); 576b97391a6SBinbin Zhou 577b97391a6SBinbin Zhou return 0; 578b97391a6SBinbin Zhou } 579b97391a6SBinbin Zhou 580b97391a6SBinbin Zhou static const struct snd_soc_dai_ops es8323_ops = { 581b97391a6SBinbin Zhou .startup = es8323_pcm_startup, 582b97391a6SBinbin Zhou .hw_params = es8323_pcm_hw_params, 583b97391a6SBinbin Zhou .set_fmt = es8323_set_dai_fmt, 584b97391a6SBinbin Zhou .set_sysclk = es8323_set_dai_sysclk, 585b97391a6SBinbin Zhou .mute_stream = es8323_mute_stream, 586b97391a6SBinbin Zhou }; 587b97391a6SBinbin Zhou 588b97391a6SBinbin Zhou #define ES8323_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 589b97391a6SBinbin Zhou SNDRV_PCM_FMTBIT_S24_LE) 590b97391a6SBinbin Zhou 591b97391a6SBinbin Zhou static struct snd_soc_dai_driver es8323_dai = { 592b97391a6SBinbin Zhou .name = "ES8323 HiFi", 593b97391a6SBinbin Zhou .playback = { 594b97391a6SBinbin Zhou .stream_name = "Playback", 595b97391a6SBinbin Zhou .channels_min = 1, 596b97391a6SBinbin Zhou .channels_max = 2, 597b97391a6SBinbin Zhou .rates = SNDRV_PCM_RATE_8000_96000, 598b97391a6SBinbin Zhou .formats = ES8323_FORMATS, 599b97391a6SBinbin Zhou }, 600b97391a6SBinbin Zhou .capture = { 601b97391a6SBinbin Zhou .stream_name = "Capture", 602b97391a6SBinbin Zhou .channels_min = 1, 603b97391a6SBinbin Zhou .channels_max = 2, 604b97391a6SBinbin Zhou .rates = SNDRV_PCM_RATE_8000_96000, 605b97391a6SBinbin Zhou .formats = ES8323_FORMATS, 606b97391a6SBinbin Zhou }, 607b97391a6SBinbin Zhou .ops = &es8323_ops, 608b97391a6SBinbin Zhou .symmetric_rate = 1, 609b97391a6SBinbin Zhou }; 610b97391a6SBinbin Zhou 611b97391a6SBinbin Zhou static int es8323_probe(struct snd_soc_component *component) 612b97391a6SBinbin Zhou { 613b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 614b97391a6SBinbin Zhou int ret; 615b97391a6SBinbin Zhou 616b97391a6SBinbin Zhou es8323->component = component; 617b97391a6SBinbin Zhou 618b97391a6SBinbin Zhou es8323->mclk = devm_clk_get_optional(component->dev, "mclk"); 619b97391a6SBinbin Zhou if (IS_ERR(es8323->mclk)) { 620b97391a6SBinbin Zhou dev_err(component->dev, "unable to get mclk\n"); 621b97391a6SBinbin Zhou return PTR_ERR(es8323->mclk); 622b97391a6SBinbin Zhou } 623b97391a6SBinbin Zhou 624b97391a6SBinbin Zhou if (!es8323->mclk) 625b97391a6SBinbin Zhou dev_warn(component->dev, "assuming static mclk\n"); 626b97391a6SBinbin Zhou 627b97391a6SBinbin Zhou ret = clk_prepare_enable(es8323->mclk); 628b97391a6SBinbin Zhou if (ret) { 629b97391a6SBinbin Zhou dev_err(component->dev, "unable to enable mclk\n"); 630b97391a6SBinbin Zhou return ret; 631b97391a6SBinbin Zhou } 632b97391a6SBinbin Zhou 633b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CONTROL2, 0x60); 634b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPPOWER, 0x00); 635b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DACCONTROL17, 0xB8); 636b97391a6SBinbin Zhou 637b97391a6SBinbin Zhou return 0; 638b97391a6SBinbin Zhou } 639b97391a6SBinbin Zhou 640b97391a6SBinbin Zhou static int es8323_set_bias_level(struct snd_soc_component *component, 641b97391a6SBinbin Zhou enum snd_soc_bias_level level) 642b97391a6SBinbin Zhou { 643b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 644b97391a6SBinbin Zhou int ret; 645b97391a6SBinbin Zhou 646b97391a6SBinbin Zhou switch (level) { 647b97391a6SBinbin Zhou case SND_SOC_BIAS_ON: 648b97391a6SBinbin Zhou ret = clk_prepare_enable(es8323->mclk); 649b97391a6SBinbin Zhou if (ret) 650b97391a6SBinbin Zhou return ret; 651b97391a6SBinbin Zhou 652b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPPOWER, 0xf0); 653b97391a6SBinbin Zhou usleep_range(18000, 20000); 654b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DACPOWER, 0x3c); 655b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ANAVOLMANAG, 0x7c); 656b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPLOPOW1, 0x00); 657b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPLOPOW2, 0x00); 658b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPPOWER, 0x00); 659b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ADCPOWER, 0x09); 660b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ADCCONTROL14, 0x00); 661b97391a6SBinbin Zhou break; 662b97391a6SBinbin Zhou case SND_SOC_BIAS_PREPARE: 663b97391a6SBinbin Zhou break; 664b97391a6SBinbin Zhou case SND_SOC_BIAS_STANDBY: 665b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ANAVOLMANAG, 0x7c); 666b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPLOPOW1, 0x00); 667b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPLOPOW2, 0x00); 668b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPPOWER, 0x00); 669b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ADCPOWER, 0x59); 670b97391a6SBinbin Zhou break; 671b97391a6SBinbin Zhou case SND_SOC_BIAS_OFF: 672b97391a6SBinbin Zhou clk_disable_unprepare(es8323->mclk); 673b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ADCPOWER, 0xff); 674b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_DACPOWER, 0xC0); 675b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPLOPOW1, 0xff); 676b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPLOPOW2, 0xff); 677b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_CHIPPOWER, 0xff); 678b97391a6SBinbin Zhou snd_soc_component_write(component, ES8323_ANAVOLMANAG, 0x7b); 679b97391a6SBinbin Zhou break; 680b97391a6SBinbin Zhou } 681b97391a6SBinbin Zhou 682b97391a6SBinbin Zhou return 0; 683b97391a6SBinbin Zhou } 684b97391a6SBinbin Zhou 685b97391a6SBinbin Zhou static void es8323_remove(struct snd_soc_component *component) 686b97391a6SBinbin Zhou { 687b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 688b97391a6SBinbin Zhou 689b97391a6SBinbin Zhou clk_disable_unprepare(es8323->mclk); 690b97391a6SBinbin Zhou es8323_set_bias_level(component, SND_SOC_BIAS_OFF); 691b97391a6SBinbin Zhou } 692b97391a6SBinbin Zhou 693b97391a6SBinbin Zhou static int es8323_suspend(struct snd_soc_component *component) 694b97391a6SBinbin Zhou { 695b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 696b97391a6SBinbin Zhou 697b97391a6SBinbin Zhou regcache_cache_only(es8323->regmap, true); 698b97391a6SBinbin Zhou regcache_mark_dirty(es8323->regmap); 699b97391a6SBinbin Zhou 700b97391a6SBinbin Zhou return 0; 701b97391a6SBinbin Zhou } 702b97391a6SBinbin Zhou 703b97391a6SBinbin Zhou static int es8323_resume(struct snd_soc_component *component) 704b97391a6SBinbin Zhou { 705b97391a6SBinbin Zhou struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component); 706b97391a6SBinbin Zhou 707b97391a6SBinbin Zhou regcache_cache_only(es8323->regmap, false); 708b97391a6SBinbin Zhou regcache_sync(es8323->regmap); 709b97391a6SBinbin Zhou 710b97391a6SBinbin Zhou return 0; 711b97391a6SBinbin Zhou } 712b97391a6SBinbin Zhou 713b97391a6SBinbin Zhou static const struct snd_soc_component_driver soc_component_dev_es8323 = { 714b97391a6SBinbin Zhou .probe = es8323_probe, 715b97391a6SBinbin Zhou .remove = es8323_remove, 716b97391a6SBinbin Zhou .suspend = es8323_suspend, 717b97391a6SBinbin Zhou .resume = es8323_resume, 718b97391a6SBinbin Zhou .set_bias_level = es8323_set_bias_level, 719b97391a6SBinbin Zhou .controls = es8323_snd_controls, 720b97391a6SBinbin Zhou .num_controls = ARRAY_SIZE(es8323_snd_controls), 721b97391a6SBinbin Zhou .dapm_widgets = es8323_dapm_widgets, 722b97391a6SBinbin Zhou .num_dapm_widgets = ARRAY_SIZE(es8323_dapm_widgets), 723b97391a6SBinbin Zhou .dapm_routes = es8323_dapm_routes, 724b97391a6SBinbin Zhou .num_dapm_routes = ARRAY_SIZE(es8323_dapm_routes), 725b97391a6SBinbin Zhou .use_pmdown_time = 1, 726b97391a6SBinbin Zhou .endianness = 1, 727b97391a6SBinbin Zhou }; 728b97391a6SBinbin Zhou 729b97391a6SBinbin Zhou static const struct regmap_config es8323_regmap = { 730b97391a6SBinbin Zhou .reg_bits = 8, 731b97391a6SBinbin Zhou .val_bits = 8, 732b97391a6SBinbin Zhou .use_single_read = true, 733b97391a6SBinbin Zhou .use_single_write = true, 734b97391a6SBinbin Zhou .max_register = 0x53, 735b97391a6SBinbin Zhou .reg_defaults = es8323_reg_defaults, 736b97391a6SBinbin Zhou .num_reg_defaults = ARRAY_SIZE(es8323_reg_defaults), 737b97391a6SBinbin Zhou .cache_type = REGCACHE_MAPLE, 738b97391a6SBinbin Zhou }; 739b97391a6SBinbin Zhou 740b97391a6SBinbin Zhou static int es8323_i2c_probe(struct i2c_client *i2c_client) 741b97391a6SBinbin Zhou { 742b97391a6SBinbin Zhou struct es8323_priv *es8323; 743b97391a6SBinbin Zhou struct device *dev = &i2c_client->dev; 744b97391a6SBinbin Zhou 745b97391a6SBinbin Zhou es8323 = devm_kzalloc(dev, sizeof(*es8323), GFP_KERNEL); 746*c1789209STang Bin if (!es8323) 747b97391a6SBinbin Zhou return -ENOMEM; 748b97391a6SBinbin Zhou 749b97391a6SBinbin Zhou i2c_set_clientdata(i2c_client, es8323); 750b97391a6SBinbin Zhou 751b97391a6SBinbin Zhou es8323->regmap = devm_regmap_init_i2c(i2c_client, &es8323_regmap); 752b97391a6SBinbin Zhou if (IS_ERR(es8323->regmap)) 753b97391a6SBinbin Zhou return PTR_ERR(es8323->regmap); 754b97391a6SBinbin Zhou 755b97391a6SBinbin Zhou return devm_snd_soc_register_component(dev, 756b97391a6SBinbin Zhou &soc_component_dev_es8323, 757b97391a6SBinbin Zhou &es8323_dai, 1); 758b97391a6SBinbin Zhou } 759b97391a6SBinbin Zhou 760b97391a6SBinbin Zhou static const struct i2c_device_id es8323_i2c_id[] = { 761b97391a6SBinbin Zhou { "es8323", 0 }, 762b97391a6SBinbin Zhou { } 763b97391a6SBinbin Zhou }; 764b97391a6SBinbin Zhou MODULE_DEVICE_TABLE(i2c, es8323_i2c_id); 765b97391a6SBinbin Zhou 766b97391a6SBinbin Zhou static const struct acpi_device_id es8323_acpi_match[] = { 767b97391a6SBinbin Zhou { "ESSX8323", 0 }, 768b97391a6SBinbin Zhou { } 769b97391a6SBinbin Zhou }; 770b97391a6SBinbin Zhou MODULE_DEVICE_TABLE(acpi, es8323_acpi_match); 771b97391a6SBinbin Zhou 772b97391a6SBinbin Zhou static const struct of_device_id es8323_of_match[] = { 773b97391a6SBinbin Zhou { .compatible = "everest,es8323" }, 774b97391a6SBinbin Zhou { } 775b97391a6SBinbin Zhou }; 776b97391a6SBinbin Zhou MODULE_DEVICE_TABLE(of, es8323_of_match); 777b97391a6SBinbin Zhou 778b97391a6SBinbin Zhou static struct i2c_driver es8323_i2c_driver = { 779b97391a6SBinbin Zhou .driver = { 780b97391a6SBinbin Zhou .name = "ES8323", 781b97391a6SBinbin Zhou .acpi_match_table = es8323_acpi_match, 782b97391a6SBinbin Zhou .of_match_table = es8323_of_match, 783b97391a6SBinbin Zhou }, 784b97391a6SBinbin Zhou .probe = es8323_i2c_probe, 785b97391a6SBinbin Zhou .id_table = es8323_i2c_id, 786b97391a6SBinbin Zhou }; 787b97391a6SBinbin Zhou module_i2c_driver(es8323_i2c_driver); 788b97391a6SBinbin Zhou 789b97391a6SBinbin Zhou MODULE_DESCRIPTION("Everest Semi ES8323 ALSA SoC Codec Driver"); 790b97391a6SBinbin Zhou MODULE_AUTHOR("Mark Brown <broonie@kernel.org>"); 791b97391a6SBinbin Zhou MODULE_AUTHOR("Binbin Zhou <zhoubinbin@loongson.cn>"); 792b97391a6SBinbin Zhou MODULE_LICENSE("GPL"); 793