1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * rk730.c -- RK730 ALSA SoC Audio driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2022 Rockchip Electronics Co.,Ltd
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/moduleparam.h>
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/init.h>
12*4882a593Smuzhiyun #include <linux/delay.h>
13*4882a593Smuzhiyun #include <linux/pm.h>
14*4882a593Smuzhiyun #include <linux/i2c.h>
15*4882a593Smuzhiyun #include <linux/regmap.h>
16*4882a593Smuzhiyun #include <linux/clk.h>
17*4882a593Smuzhiyun #include <sound/core.h>
18*4882a593Smuzhiyun #include <sound/pcm.h>
19*4882a593Smuzhiyun #include <sound/pcm_params.h>
20*4882a593Smuzhiyun #include <sound/soc.h>
21*4882a593Smuzhiyun #include <sound/tlv.h>
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #include "rk730.h"
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun enum rk730_mix_mode {
26*4882a593Smuzhiyun RK730_MIX_MODE_1_PATH,
27*4882a593Smuzhiyun RK730_MIX_MODE_2_PATHS,
28*4882a593Smuzhiyun RK730_MIX_MODE_3_PATHS,
29*4882a593Smuzhiyun };
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun enum rk730_chop_freq {
32*4882a593Smuzhiyun RK730_CHOP_FREQ_NONE,
33*4882a593Smuzhiyun RK730_CHOP_FREQ_200KHZ,
34*4882a593Smuzhiyun RK730_CHOP_FREQ_400KHZ,
35*4882a593Smuzhiyun RK730_CHOP_FREQ_800KHZ,
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun struct rk730_priv {
39*4882a593Smuzhiyun struct regmap *regmap;
40*4882a593Smuzhiyun struct clk *mclk;
41*4882a593Smuzhiyun atomic_t mix_mode;
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* ADC Digital Volume */
45*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(adc_dig_tlv, -95625, 375, 0);
46*4882a593Smuzhiyun /* DAC Digital Volume */
47*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -95625, 375, 0);
48*4882a593Smuzhiyun /* D2S Volume */
49*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(d2s_tlv, -1800, 300, 0);
50*4882a593Smuzhiyun /* ADC Volume */
51*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 300, 0);
52*4882a593Smuzhiyun /* MUX Volume */
53*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(mux_tlv, -600, 600, 0);
54*4882a593Smuzhiyun /* MIX Buf Volume */
55*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(mix_buf_tlv, -1800, 300, 0);
56*4882a593Smuzhiyun /* HP Volume */
57*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(hp_tlv, 0, 300, 0);
58*4882a593Smuzhiyun /* LINEOUT Volume */
59*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(lineout_tlv, 0, 300, 0);
60*4882a593Smuzhiyun /* MIC Boost Volume */
61*4882a593Smuzhiyun static const DECLARE_TLV_DB_RANGE(micboost_tlv,
62*4882a593Smuzhiyun 0, 2, TLV_DB_SCALE_ITEM(0, 600, 0),
63*4882a593Smuzhiyun 3, 4, TLV_DB_SCALE_ITEM(2400, 1200, 0),
64*4882a593Smuzhiyun 5, 7, TLV_DB_SCALE_ITEM(4200, 600, 0),
65*4882a593Smuzhiyun 8, 8, TLV_DB_SCALE_ITEM(-300, 0, 0),
66*4882a593Smuzhiyun 16, 16, TLV_DB_SCALE_ITEM(-600, 0, 0),
67*4882a593Smuzhiyun 24, 24, TLV_DB_SCALE_ITEM(-900, 0, 0)
68*4882a593Smuzhiyun );
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun static const char * const mux_out_l_text[] = { "DIFF", "MIC1N", "MIC2N" };
71*4882a593Smuzhiyun static const char * const mux_out_r_text[] = { "DIFF", "MIC2P", "MIC1P" };
72*4882a593Smuzhiyun static const char * const mux_input_l_text[] = { "DIFF", "VINP1", "VINN1" };
73*4882a593Smuzhiyun static const char * const mux_input_r_text[] = { "DIFF", "VINP2", "VINN2" };
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(mux_out_l_enum, RK730_MUXER_0, 2, mux_out_l_text);
76*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(mux_out_r_enum, RK730_MUXER_0, 6, mux_out_r_text);
77*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(mux_input_l_enum, RK730_ADC_PGA_BLOCK_0,
78*4882a593Smuzhiyun 4, mux_input_l_text);
79*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(mux_input_r_enum, RK730_ADC_PGA_BLOCK_1,
80*4882a593Smuzhiyun 4, mux_input_r_text);
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun static const struct snd_kcontrol_new mux_out_l =
83*4882a593Smuzhiyun SOC_DAPM_ENUM("Left Out Mux", mux_out_l_enum);
84*4882a593Smuzhiyun static const struct snd_kcontrol_new mux_out_r =
85*4882a593Smuzhiyun SOC_DAPM_ENUM("Right Out Mux", mux_out_r_enum);
86*4882a593Smuzhiyun static const struct snd_kcontrol_new mux_input_l =
87*4882a593Smuzhiyun SOC_DAPM_ENUM("Left Input Mux", mux_input_l_enum);
88*4882a593Smuzhiyun static const struct snd_kcontrol_new mux_input_r =
89*4882a593Smuzhiyun SOC_DAPM_ENUM("Right Input Mux", mux_input_r_enum);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun static const struct snd_kcontrol_new mix_ctls[] = {
92*4882a593Smuzhiyun SOC_DAPM_SINGLE("Left Out Mux Switch", RK730_MUXER_0, 0, 1, 1),
93*4882a593Smuzhiyun SOC_DAPM_SINGLE("Right Out Mux Switch", RK730_MUXER_0, 4, 1, 1),
94*4882a593Smuzhiyun };
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun static const char * const adc_hpf_cutoff_text[] = {
97*4882a593Smuzhiyun "3.79Hz", "60Hz", "243Hz", "493Hz",
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun static const char * const dac_hpf_cutoff_text[] = {
101*4882a593Smuzhiyun "80Hz", "100Hz", "120Hz", "140Hz",
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(adc_hpf_cutoff_enum, RK730_DADC_HPF,
105*4882a593Smuzhiyun 4, adc_hpf_cutoff_text);
106*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(dac_hpf_cutoff_enum, RK730_DDAC_MUTE_MIXCTL,
107*4882a593Smuzhiyun 5, dac_hpf_cutoff_text);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun static const char * const chop_freq_text[] = {
110*4882a593Smuzhiyun "Disabled", "200kHz", "400kHz", "800kHz",
111*4882a593Smuzhiyun };
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(dac_ref_buf_chop_freq_enum, RK730_HK_TOP_1,
114*4882a593Smuzhiyun 6, chop_freq_text);
115*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(mic_chop_freq_enum, RK730_MIC_BOOST_3,
116*4882a593Smuzhiyun 6, chop_freq_text);
117*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(adc_pga_chop_freq_enum, RK730_ADC_PGA_BLOCK_1,
118*4882a593Smuzhiyun 6, chop_freq_text);
119*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(mux_out_chop_freq_enum, RK730_MUXER_1,
120*4882a593Smuzhiyun 0, chop_freq_text);
121*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(mix_chop_freq_enum, RK730_MIXER_2,
122*4882a593Smuzhiyun 6, chop_freq_text);
123*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(hp_lo_chop_freq_enum, RK730_HP_1,
124*4882a593Smuzhiyun 5, chop_freq_text);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun static const char * const micbias_volt_text[] = {
127*4882a593Smuzhiyun "2.0v", "2.2v", "2.5v", "2.8v",
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun static const char * const charge_pump_volt_text[] = {
131*4882a593Smuzhiyun "2.1v", "2.3v", "2.5v", "2.7v",
132*4882a593Smuzhiyun };
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(micbias_volt_enum, RK730_MIC_BIAS,
135*4882a593Smuzhiyun 2, micbias_volt_text);
136*4882a593Smuzhiyun static SOC_ENUM_SINGLE_DECL(charge_pump_volt_enum, RK730_CHARGE_PUMP,
137*4882a593Smuzhiyun 1, charge_pump_volt_text);
138*4882a593Smuzhiyun
rk730_adc_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)139*4882a593Smuzhiyun static int rk730_adc_vol_get(struct snd_kcontrol *kcontrol,
140*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
143*4882a593Smuzhiyun struct soc_mixer_control *mc =
144*4882a593Smuzhiyun (struct soc_mixer_control *)kcontrol->private_value;
145*4882a593Smuzhiyun unsigned int val = snd_soc_component_read(component, mc->reg);
146*4882a593Smuzhiyun unsigned int sign = snd_soc_component_read(component, RK730_DADC_SR_ACL);
147*4882a593Smuzhiyun unsigned int mask = (1 << fls(mc->max)) - 1;
148*4882a593Smuzhiyun unsigned int shift = mc->shift;
149*4882a593Smuzhiyun int mid = mc->max / 2;
150*4882a593Smuzhiyun int uv;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun uv = (val >> shift) & mask;
153*4882a593Smuzhiyun sign &= RK730_DADC_SR_ACL_VOLL_POL_MASK;
154*4882a593Smuzhiyun if (sign)
155*4882a593Smuzhiyun uv = mid + uv;
156*4882a593Smuzhiyun else
157*4882a593Smuzhiyun uv = mid - uv;
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun ucontrol->value.integer.value[0] = uv;
160*4882a593Smuzhiyun ucontrol->value.integer.value[1] = uv;
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun return 0;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
rk730_adc_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)165*4882a593Smuzhiyun static int rk730_adc_vol_put(struct snd_kcontrol *kcontrol,
166*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
169*4882a593Smuzhiyun struct soc_mixer_control *mc =
170*4882a593Smuzhiyun (struct soc_mixer_control *)kcontrol->private_value;
171*4882a593Smuzhiyun unsigned int reg = mc->reg;
172*4882a593Smuzhiyun unsigned int rreg = mc->rreg;
173*4882a593Smuzhiyun unsigned int shift = mc->shift;
174*4882a593Smuzhiyun unsigned int mask = (1 << fls(mc->max)) - 1;
175*4882a593Smuzhiyun unsigned int val, val_mask, sign, sign_mask;
176*4882a593Smuzhiyun int uv = ucontrol->value.integer.value[0];
177*4882a593Smuzhiyun int min = mc->min;
178*4882a593Smuzhiyun int mid = mc->max / 2;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun sign_mask = RK730_DADC_SR_ACL_VOLL_POL_MASK | RK730_DADC_SR_ACL_VOLR_POL_MASK;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun if (uv > mid) {
183*4882a593Smuzhiyun sign = RK730_DADC_SR_ACL_VOLL_POS | RK730_DADC_SR_ACL_VOLR_POS;
184*4882a593Smuzhiyun uv = uv - mid;
185*4882a593Smuzhiyun } else {
186*4882a593Smuzhiyun sign = RK730_DADC_SR_ACL_VOLL_NEG | RK730_DADC_SR_ACL_VOLR_NEG;
187*4882a593Smuzhiyun uv = mid - uv;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun val = ((uv + min) & mask);
191*4882a593Smuzhiyun val_mask = mask << shift;
192*4882a593Smuzhiyun val = val << shift;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun snd_soc_component_update_bits(component, reg, val_mask, val);
195*4882a593Smuzhiyun snd_soc_component_update_bits(component, rreg, val_mask, val);
196*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DADC_SR_ACL, sign_mask, sign);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun return 1;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
rk730_dac_vol_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)201*4882a593Smuzhiyun static int rk730_dac_vol_get(struct snd_kcontrol *kcontrol,
202*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
205*4882a593Smuzhiyun struct soc_mixer_control *mc =
206*4882a593Smuzhiyun (struct soc_mixer_control *)kcontrol->private_value;
207*4882a593Smuzhiyun unsigned int val = snd_soc_component_read(component, mc->reg);
208*4882a593Smuzhiyun unsigned int sign = snd_soc_component_read(component, RK730_DDAC_SR_LMT);
209*4882a593Smuzhiyun unsigned int mask = (1 << fls(mc->max)) - 1;
210*4882a593Smuzhiyun unsigned int shift = mc->shift;
211*4882a593Smuzhiyun int mid = mc->max / 2;
212*4882a593Smuzhiyun int uv;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun uv = (val >> shift) & mask;
215*4882a593Smuzhiyun sign &= RK730_DDAC_SR_LMT_VOLL_POL_MASK;
216*4882a593Smuzhiyun if (sign)
217*4882a593Smuzhiyun uv = mid + uv;
218*4882a593Smuzhiyun else
219*4882a593Smuzhiyun uv = mid - uv;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun ucontrol->value.integer.value[0] = uv;
222*4882a593Smuzhiyun ucontrol->value.integer.value[1] = uv;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun return 0;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
rk730_dac_vol_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)227*4882a593Smuzhiyun static int rk730_dac_vol_put(struct snd_kcontrol *kcontrol,
228*4882a593Smuzhiyun struct snd_ctl_elem_value *ucontrol)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
231*4882a593Smuzhiyun struct soc_mixer_control *mc =
232*4882a593Smuzhiyun (struct soc_mixer_control *)kcontrol->private_value;
233*4882a593Smuzhiyun unsigned int reg = mc->reg;
234*4882a593Smuzhiyun unsigned int rreg = mc->rreg;
235*4882a593Smuzhiyun unsigned int shift = mc->shift;
236*4882a593Smuzhiyun unsigned int mask = (1 << fls(mc->max)) - 1;
237*4882a593Smuzhiyun unsigned int val, val_mask, sign, sign_mask;
238*4882a593Smuzhiyun int uv = ucontrol->value.integer.value[0];
239*4882a593Smuzhiyun int min = mc->min;
240*4882a593Smuzhiyun int mid = mc->max / 2;
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun sign_mask = RK730_DDAC_SR_LMT_VOLL_POL_MASK | RK730_DDAC_SR_LMT_VOLR_POL_MASK;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun if (uv > mid) {
245*4882a593Smuzhiyun sign = RK730_DDAC_SR_LMT_VOLL_POS | RK730_DDAC_SR_LMT_VOLR_POS;
246*4882a593Smuzhiyun uv = uv - mid;
247*4882a593Smuzhiyun } else {
248*4882a593Smuzhiyun sign = RK730_DDAC_SR_LMT_VOLL_NEG | RK730_DDAC_SR_LMT_VOLR_NEG;
249*4882a593Smuzhiyun uv = mid - uv;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun val = ((uv + min) & mask);
253*4882a593Smuzhiyun val_mask = mask << shift;
254*4882a593Smuzhiyun val = val << shift;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun snd_soc_component_update_bits(component, reg, val_mask, val);
257*4882a593Smuzhiyun snd_soc_component_update_bits(component, rreg, val_mask, val);
258*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT, sign_mask, sign);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun return 1;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
rk730_cp_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)263*4882a593Smuzhiyun static int rk730_cp_event(struct snd_soc_dapm_widget *w,
264*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun if (SND_SOC_DAPM_EVENT_ON(event))
267*4882a593Smuzhiyun usleep_range(5000, 5100);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun return 0;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun
rk730_pll_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)272*4882a593Smuzhiyun static int rk730_pll_event(struct snd_soc_dapm_widget *w,
273*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun if (SND_SOC_DAPM_EVENT_ON(event))
278*4882a593Smuzhiyun snd_soc_component_write(component, RK730_SYSPLL_0, 0x00);
279*4882a593Smuzhiyun else
280*4882a593Smuzhiyun snd_soc_component_write(component, RK730_SYSPLL_0, 0xff);
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun return 0;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
rk730_adc_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)285*4882a593Smuzhiyun static int rk730_adc_event(struct snd_soc_dapm_widget *w,
286*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun if (SND_SOC_DAPM_EVENT_ON(event)) {
291*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_ADC_0,
292*4882a593Smuzhiyun RK730_ADC_0_DEM_EN_MASK,
293*4882a593Smuzhiyun RK730_ADC_0_DEM_EN);
294*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
295*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK |
296*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK |
297*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK |
298*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK,
299*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_CKE_EN |
300*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_CKE_EN |
301*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_EN |
302*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_EN);
303*4882a593Smuzhiyun usleep_range(20000, 21000);
304*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD,
305*4882a593Smuzhiyun RK730_DI2S_TXCR_3_TXCMD_TXS_MASK,
306*4882a593Smuzhiyun RK730_DI2S_TXCR_3_TXCMD_TXS_EN);
307*4882a593Smuzhiyun } else {
308*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD,
309*4882a593Smuzhiyun RK730_DI2S_TXCR_3_TXCMD_TXS_MASK,
310*4882a593Smuzhiyun RK730_DI2S_TXCR_3_TXCMD_TXS_DIS);
311*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_ADC_0,
312*4882a593Smuzhiyun RK730_ADC_0_DEM_EN_MASK,
313*4882a593Smuzhiyun RK730_ADC_0_DEM_DIS);
314*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
315*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK |
316*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK |
317*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK |
318*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK,
319*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_CKE_DIS |
320*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_CKE_DIS |
321*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_ADC_DIS |
322*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2STX_DIS);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun return 0;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
rk730_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)328*4882a593Smuzhiyun static int rk730_dac_event(struct snd_soc_dapm_widget *w,
329*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun if (SND_SOC_DAPM_EVENT_ON(event)) {
334*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
335*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK |
336*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK |
337*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK |
338*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK,
339*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_CKE_EN |
340*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_EN |
341*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_EN |
342*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_EN);
343*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD,
344*4882a593Smuzhiyun RK730_DI2S_RXCMD_TSD_RXS_MASK,
345*4882a593Smuzhiyun RK730_DI2S_RXCMD_TSD_RXS_EN);
346*4882a593Smuzhiyun } else {
347*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD,
348*4882a593Smuzhiyun RK730_DI2S_RXCMD_TSD_RXS_MASK,
349*4882a593Smuzhiyun RK730_DI2S_RXCMD_TSD_RXS_DIS);
350*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
351*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK |
352*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK |
353*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK |
354*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK,
355*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_CKE_DIS |
356*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_DIS |
357*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_DAC_DIS |
358*4882a593Smuzhiyun RK730_DTOP_DIGEN_CLKE_I2SRX_DIS);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun return 0;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
rk730_mux_out_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)364*4882a593Smuzhiyun static int rk730_mux_out_event(struct snd_soc_dapm_widget *w,
365*4882a593Smuzhiyun struct snd_kcontrol *kcontrol, int event)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
368*4882a593Smuzhiyun struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
369*4882a593Smuzhiyun unsigned int val;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun if (SND_SOC_DAPM_EVENT_ON(event))
372*4882a593Smuzhiyun val = atomic_inc_return(&rk730->mix_mode);
373*4882a593Smuzhiyun else
374*4882a593Smuzhiyun val = atomic_dec_return(&rk730->mix_mode);
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_MIXER_2,
377*4882a593Smuzhiyun RK730_MIXER_2_MIX_R_MODE_MASK |
378*4882a593Smuzhiyun RK730_MIXER_2_MIX_L_MODE_MASK,
379*4882a593Smuzhiyun RK730_MIXER_2_MIX_R_MODE(val) |
380*4882a593Smuzhiyun RK730_MIXER_2_MIX_L_MODE(val));
381*4882a593Smuzhiyun return 0;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun static const struct snd_kcontrol_new rk730_snd_controls[] = {
385*4882a593Smuzhiyun SOC_DOUBLE_R_TLV("ADC Volume", RK730_ADC_PGA_BLOCK_0, RK730_ADC_PGA_BLOCK_1,
386*4882a593Smuzhiyun 1, 0x7, 1, adc_tlv),
387*4882a593Smuzhiyun SOC_DOUBLE_R_TLV("D2S Volume", RK730_DAC_1, RK730_DAC_2,
388*4882a593Smuzhiyun 1, 0x6, 1, d2s_tlv),
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun SOC_DOUBLE_R_TLV("MIC1 Boost Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1,
391*4882a593Smuzhiyun 1, 0x18, 0, micboost_tlv),
392*4882a593Smuzhiyun SOC_DOUBLE_R_TLV("MIC2 Boost Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3,
393*4882a593Smuzhiyun 1, 0x18, 0, micboost_tlv),
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun SOC_DOUBLE_TLV("Out Mux Volume", RK730_MUXER_0, 1, 5, 0x1, 0, mux_tlv),
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun SOC_SINGLE_TLV("Left Out Mux -> Left Out Mixer Volume",
398*4882a593Smuzhiyun RK730_MIXER_0, 1, 0x6, 1, mix_buf_tlv),
399*4882a593Smuzhiyun SOC_SINGLE_TLV("Left Out Mux -> Right Out Mixer Volume",
400*4882a593Smuzhiyun RK730_MIXER_0, 5, 0x6, 1, mix_buf_tlv),
401*4882a593Smuzhiyun SOC_SINGLE_TLV("Right Out Mux -> Left Out Mixer Volume",
402*4882a593Smuzhiyun RK730_MIXER_1, 1, 0x6, 1, mix_buf_tlv),
403*4882a593Smuzhiyun SOC_SINGLE_TLV("Right Out Mux -> Right Out Mixer Volume",
404*4882a593Smuzhiyun RK730_MIXER_1, 5, 0x6, 1, mix_buf_tlv),
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun SOC_SINGLE_TLV("HP Volume", RK730_HP_0, 6, 0x3, 0, hp_tlv),
407*4882a593Smuzhiyun SOC_SINGLE_TLV("Line Out Volume", RK730_LINEOUT_1, 2, 0x3, 0, lineout_tlv),
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun SOC_DOUBLE_R_EXT_TLV("ADC Digital Volume",
410*4882a593Smuzhiyun RK730_DADC_VOLL, RK730_DADC_VOLR, 0, 0x1fe, 0,
411*4882a593Smuzhiyun rk730_adc_vol_get,
412*4882a593Smuzhiyun rk730_adc_vol_put,
413*4882a593Smuzhiyun adc_dig_tlv),
414*4882a593Smuzhiyun SOC_DOUBLE_R_EXT_TLV("DAC Digital Volume",
415*4882a593Smuzhiyun RK730_DDAC_VOLL, RK730_DDAC_VOLR, 0, 0x1fe, 0,
416*4882a593Smuzhiyun rk730_dac_vol_get,
417*4882a593Smuzhiyun rk730_dac_vol_put,
418*4882a593Smuzhiyun dac_dig_tlv),
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun SOC_ENUM("ADC HPF Cutoff", adc_hpf_cutoff_enum),
421*4882a593Smuzhiyun SOC_ENUM("DAC HPF Cutoff", dac_hpf_cutoff_enum),
422*4882a593Smuzhiyun SOC_ENUM("DAC Ref Buf Chop Freq", dac_ref_buf_chop_freq_enum),
423*4882a593Smuzhiyun SOC_ENUM("MIC Chop Freq", mic_chop_freq_enum),
424*4882a593Smuzhiyun SOC_ENUM("ADC PGA Chop Freq", adc_pga_chop_freq_enum),
425*4882a593Smuzhiyun SOC_ENUM("Out Mux Chop Freq", mux_out_chop_freq_enum),
426*4882a593Smuzhiyun SOC_ENUM("Mixer Chop Freq", mix_chop_freq_enum),
427*4882a593Smuzhiyun SOC_ENUM("HP / Lineout Chop Freq", hp_lo_chop_freq_enum),
428*4882a593Smuzhiyun SOC_ENUM("Mic Bias Volt", micbias_volt_enum),
429*4882a593Smuzhiyun SOC_ENUM("Charge Pump Volt", charge_pump_volt_enum),
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun SOC_SINGLE("ADCL HPF Switch", RK730_DADC_HPF, 7, 1, 0),
432*4882a593Smuzhiyun SOC_SINGLE("ADCR HPF Switch", RK730_DADC_HPF, 6, 1, 0),
433*4882a593Smuzhiyun SOC_SINGLE("DAC HPF Switch", RK730_DDAC_MUTE_MIXCTL, 7, 1, 0),
434*4882a593Smuzhiyun SOC_SINGLE("ADC Volume Bypass Switch", RK730_DTOP_VUCTL, 7, 1, 0),
435*4882a593Smuzhiyun SOC_SINGLE("DAC Volume Bypass Switch", RK730_DTOP_VUCTL, 6, 1, 0),
436*4882a593Smuzhiyun SOC_SINGLE("ADC Fade Switch", RK730_DTOP_VUCTL, 5, 1, 0),
437*4882a593Smuzhiyun SOC_SINGLE("DAC Fade Switch", RK730_DTOP_VUCTL, 4, 1, 0),
438*4882a593Smuzhiyun SOC_SINGLE("ADC Zero Crossing Switch", RK730_DTOP_VUCTL, 1, 1, 0),
439*4882a593Smuzhiyun SOC_SINGLE("DAC Zero Crossing Switch", RK730_DTOP_VUCTL, 0, 1, 0),
440*4882a593Smuzhiyun SOC_SINGLE("MIC1N / MIC2P Exchanged Switch", RK730_MIC_BOOST_2, 7, 1, 0),
441*4882a593Smuzhiyun };
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun static const struct snd_soc_dapm_widget rk730_dapm_widgets[] = {
444*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("ANA LDO", 0, RK730_LDO, 7, 0, NULL, 0),
445*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("OSC CLK", 1, RK730_HK_TOP_2, 4, 0, NULL, 0),
446*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("VAG BUF", 1, RK730_HK_TOP_2, 2, 1, NULL, 0),
447*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("ADC BUF", 1, RK730_HK_TOP_2, 1, 1, NULL, 0),
448*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("DAC BUF", 1, RK730_HK_TOP_2, 0, 1, NULL, 0),
449*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("MICBIAS", 1, RK730_MIC_BIAS, 0, 1, NULL, 0),
450*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RK730_CHARGE_PUMP, 0, 0,
451*4882a593Smuzhiyun rk730_cp_event, SND_SOC_DAPM_POST_PMU),
452*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("PLL", 2, SND_SOC_NOPM, 0, 0, rk730_pll_event,
453*4882a593Smuzhiyun SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("DAC Bias", 2, RK730_DAC_0, 2, 1, NULL, 0),
456*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("HP Bias", 2, RK730_HP_0, 5, 1, NULL, 0),
457*4882a593Smuzhiyun SND_SOC_DAPM_SUPPLY_S("Line Out Bias", 2, RK730_LINEOUT_1, 7, 1, NULL, 0),
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun SND_SOC_DAPM_ADC_E("ADCL", "HiFi Capture", RK730_ADC_0, 0, 1,
460*4882a593Smuzhiyun rk730_adc_event,
461*4882a593Smuzhiyun SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
462*4882a593Smuzhiyun SND_SOC_DAPM_ADC_E("ADCR", "HiFi Capture", RK730_ADC_0, 1, 1,
463*4882a593Smuzhiyun rk730_adc_event,
464*4882a593Smuzhiyun SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun SND_SOC_DAPM_DAC_E("DACL", "HiFi Playback", RK730_DAC_0, 0, 1,
467*4882a593Smuzhiyun rk730_dac_event,
468*4882a593Smuzhiyun SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
469*4882a593Smuzhiyun SND_SOC_DAPM_DAC_E("DACR", "HiFi Playback", RK730_DAC_0, 1, 1,
470*4882a593Smuzhiyun rk730_dac_event,
471*4882a593Smuzhiyun SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun SND_SOC_DAPM_PGA("ADCL PGA", RK730_ADC_PGA_BLOCK_0, 0, 1, NULL, 0),
474*4882a593Smuzhiyun SND_SOC_DAPM_PGA("ADCR PGA", RK730_ADC_PGA_BLOCK_1, 0, 1, NULL, 0),
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun SND_SOC_DAPM_PGA("D2SL", RK730_DAC_1, 0, 1, NULL, 0),
477*4882a593Smuzhiyun SND_SOC_DAPM_PGA("D2SR", RK730_DAC_2, 0, 1, NULL, 0),
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun SND_SOC_DAPM_PGA("MIC1P", RK730_MIC_BOOST_0, 0, 1, NULL, 0),
480*4882a593Smuzhiyun SND_SOC_DAPM_PGA("MIC1N", RK730_MIC_BOOST_1, 0, 1, NULL, 0),
481*4882a593Smuzhiyun SND_SOC_DAPM_PGA("MIC2P", RK730_MIC_BOOST_2, 0, 1, NULL, 0),
482*4882a593Smuzhiyun SND_SOC_DAPM_PGA("MIC2N", RK730_MIC_BOOST_3, 0, 1, NULL, 0),
483*4882a593Smuzhiyun SND_SOC_DAPM_PGA("DIFFL", SND_SOC_NOPM, 0, 0, NULL, 0),
484*4882a593Smuzhiyun SND_SOC_DAPM_PGA("DIFFR", SND_SOC_NOPM, 0, 0, NULL, 0),
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun SND_SOC_DAPM_PGA("HP Out", RK730_HP_0, 2, 1, NULL, 0),
487*4882a593Smuzhiyun SND_SOC_DAPM_PGA("HP Out Stage", RK730_HP_0, 3, 1, NULL, 0),
488*4882a593Smuzhiyun SND_SOC_DAPM_PGA("Line Out", RK730_LINEOUT_0, 2, 1, NULL, 0),
489*4882a593Smuzhiyun SND_SOC_DAPM_PGA("Line Out Stage", RK730_LINEOUT_0, 3, 1, NULL, 0),
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun SND_SOC_DAPM_MUX_E("Left Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_l,
492*4882a593Smuzhiyun rk730_mux_out_event,
493*4882a593Smuzhiyun SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
494*4882a593Smuzhiyun SND_SOC_DAPM_MUX_E("Right Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_r,
495*4882a593Smuzhiyun rk730_mux_out_event,
496*4882a593Smuzhiyun SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_l),
499*4882a593Smuzhiyun SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_r),
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun SND_SOC_DAPM_MIXER("Left Out Mixer", RK730_MIXER_2, 0, 1,
502*4882a593Smuzhiyun mix_ctls, ARRAY_SIZE(mix_ctls)),
503*4882a593Smuzhiyun SND_SOC_DAPM_MIXER("Right Out Mixer", RK730_MIXER_2, 3, 1,
504*4882a593Smuzhiyun mix_ctls, ARRAY_SIZE(mix_ctls)),
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun SND_SOC_DAPM_OUTPUT("HPL"),
507*4882a593Smuzhiyun SND_SOC_DAPM_OUTPUT("HPR"),
508*4882a593Smuzhiyun SND_SOC_DAPM_OUTPUT("LINEOUTL"),
509*4882a593Smuzhiyun SND_SOC_DAPM_OUTPUT("LINEOUTR"),
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun SND_SOC_DAPM_INPUT("MIC1"),
512*4882a593Smuzhiyun SND_SOC_DAPM_INPUT("MIC2"),
513*4882a593Smuzhiyun };
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun static const struct snd_soc_dapm_route rk730_dapm_routes[] = {
516*4882a593Smuzhiyun { "DACL", NULL, "ANA LDO" },
517*4882a593Smuzhiyun { "DACR", NULL, "ANA LDO" },
518*4882a593Smuzhiyun { "DACL", NULL, "OSC CLK" },
519*4882a593Smuzhiyun { "DACR", NULL, "OSC CLK" },
520*4882a593Smuzhiyun { "DACL", NULL, "VAG BUF" },
521*4882a593Smuzhiyun { "DACR", NULL, "VAG BUF" },
522*4882a593Smuzhiyun { "DACL", NULL, "DAC BUF" },
523*4882a593Smuzhiyun { "DACR", NULL, "DAC BUF" },
524*4882a593Smuzhiyun { "DACL", NULL, "PLL" },
525*4882a593Smuzhiyun { "DACR", NULL, "PLL" },
526*4882a593Smuzhiyun { "DACL", NULL, "DAC Bias" },
527*4882a593Smuzhiyun { "DACR", NULL, "DAC Bias" },
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun { "D2SL", NULL, "DACL" },
530*4882a593Smuzhiyun { "D2SR", NULL, "DACR" },
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun { "Left Out Mixer", NULL, "D2SL" },
533*4882a593Smuzhiyun { "Left Out Mixer", "Left Out Mux Switch", "Left Out Mux" },
534*4882a593Smuzhiyun { "Left Out Mixer", "Right Out Mux Switch", "Right Out Mux" },
535*4882a593Smuzhiyun { "Right Out Mixer", NULL, "D2SR" },
536*4882a593Smuzhiyun { "Right Out Mixer", "Left Out Mux Switch", "Left Out Mux" },
537*4882a593Smuzhiyun { "Right Out Mixer", "Right Out Mux Switch", "Right Out Mux" },
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun { "Left Out Mux", "DIFF", "DIFFL" },
540*4882a593Smuzhiyun { "Left Out Mux", "MIC1N", "MIC1N" },
541*4882a593Smuzhiyun { "Left Out Mux", "MIC2N", "MIC2N" },
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun { "Right Out Mux", "DIFF", "DIFFR" },
544*4882a593Smuzhiyun { "Right Out Mux", "MIC1P", "MIC1P" },
545*4882a593Smuzhiyun { "Right Out Mux", "MIC2P", "MIC2P" },
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun { "HP Out", NULL, "HP Bias" },
548*4882a593Smuzhiyun { "HP Out", NULL, "HP Bias" },
549*4882a593Smuzhiyun { "Line Out", NULL, "Line Out Bias" },
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun { "HP Out", NULL, "Left Out Mixer" },
552*4882a593Smuzhiyun { "HP Out", NULL, "Right Out Mixer" },
553*4882a593Smuzhiyun { "Line Out", NULL, "Left Out Mixer" },
554*4882a593Smuzhiyun { "Line Out", NULL, "Right Out Mixer" },
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun { "HP Out Stage", NULL, "HP Out" },
557*4882a593Smuzhiyun { "Line Out Stage", NULL, "Line Out" },
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun { "HPL", NULL, "HP Out Stage" },
560*4882a593Smuzhiyun { "HPR", NULL, "HP Out Stage" },
561*4882a593Smuzhiyun { "HPL", NULL, "Charge Pump" },
562*4882a593Smuzhiyun { "HPR", NULL, "Charge Pump" },
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun { "LINEOUTL", NULL, "Line Out Stage" },
565*4882a593Smuzhiyun { "LINEOUTR", NULL, "Line Out Stage" },
566*4882a593Smuzhiyun { "LINEOUTL", NULL, "Charge Pump" },
567*4882a593Smuzhiyun { "LINEOUTR", NULL, "Charge Pump" },
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun { "ADCL", NULL, "ANA LDO" },
570*4882a593Smuzhiyun { "ADCR", NULL, "ANA LDO" },
571*4882a593Smuzhiyun { "ADCL", NULL, "OSC CLK" },
572*4882a593Smuzhiyun { "ADCR", NULL, "OSC CLK" },
573*4882a593Smuzhiyun { "ADCL", NULL, "ADC BUF" },
574*4882a593Smuzhiyun { "ADCR", NULL, "ADC BUF" },
575*4882a593Smuzhiyun { "ADCL", NULL, "VAG BUF" },
576*4882a593Smuzhiyun { "ADCR", NULL, "VAG BUF" },
577*4882a593Smuzhiyun { "ADCL", NULL, "PLL" },
578*4882a593Smuzhiyun { "ADCR", NULL, "PLL" },
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun { "ADCL", NULL, "ADCL PGA" },
581*4882a593Smuzhiyun { "ADCR", NULL, "ADCR PGA" },
582*4882a593Smuzhiyun { "ADCL PGA", NULL, "Left Input Mux" },
583*4882a593Smuzhiyun { "ADCR PGA", NULL, "Right Input Mux" },
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun { "Left Input Mux", "DIFF", "DIFFL" },
586*4882a593Smuzhiyun { "Left Input Mux", "VINP1", "MIC1P" },
587*4882a593Smuzhiyun { "Left Input Mux", "VINN1", "MIC1N" },
588*4882a593Smuzhiyun { "Right Input Mux", "DIFF", "DIFFR" },
589*4882a593Smuzhiyun { "Right Input Mux", "VINP2", "MIC2P" },
590*4882a593Smuzhiyun { "Right Input Mux", "VINN2", "MIC2N" },
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun { "DIFFL", NULL, "MIC1P" },
593*4882a593Smuzhiyun { "DIFFL", NULL, "MIC1N" },
594*4882a593Smuzhiyun { "DIFFR", NULL, "MIC2P" },
595*4882a593Smuzhiyun { "DIFFR", NULL, "MIC2N" },
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun { "MIC1P", NULL, "MIC1" },
598*4882a593Smuzhiyun { "MIC1N", NULL, "MIC1" },
599*4882a593Smuzhiyun { "MIC2P", NULL, "MIC2" },
600*4882a593Smuzhiyun { "MIC2N", NULL, "MIC2" },
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun { "MIC1", NULL, "MICBIAS" },
603*4882a593Smuzhiyun { "MIC2", NULL, "MICBIAS" },
604*4882a593Smuzhiyun };
605*4882a593Smuzhiyun
samplerate_to_bit(unsigned int samplerate)606*4882a593Smuzhiyun static unsigned int samplerate_to_bit(unsigned int samplerate)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun switch (samplerate) {
609*4882a593Smuzhiyun case 8000:
610*4882a593Smuzhiyun case 11025:
611*4882a593Smuzhiyun case 12000:
612*4882a593Smuzhiyun return 0;
613*4882a593Smuzhiyun case 16000:
614*4882a593Smuzhiyun case 22050:
615*4882a593Smuzhiyun case 24000:
616*4882a593Smuzhiyun return 1;
617*4882a593Smuzhiyun case 32000:
618*4882a593Smuzhiyun case 44100:
619*4882a593Smuzhiyun case 48000:
620*4882a593Smuzhiyun return 2;
621*4882a593Smuzhiyun case 64000:
622*4882a593Smuzhiyun case 88200:
623*4882a593Smuzhiyun case 96000:
624*4882a593Smuzhiyun return 3;
625*4882a593Smuzhiyun case 128000:
626*4882a593Smuzhiyun case 176400:
627*4882a593Smuzhiyun case 192000:
628*4882a593Smuzhiyun return 4;
629*4882a593Smuzhiyun default:
630*4882a593Smuzhiyun return 2;
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun
rk730_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)634*4882a593Smuzhiyun static int rk730_dai_hw_params(struct snd_pcm_substream *substream,
635*4882a593Smuzhiyun struct snd_pcm_hw_params *params,
636*4882a593Smuzhiyun struct snd_soc_dai *dai)
637*4882a593Smuzhiyun {
638*4882a593Smuzhiyun struct snd_soc_component *component = dai->component;
639*4882a593Smuzhiyun unsigned int width, rate;
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun width = min(params_width(params), 24);
642*4882a593Smuzhiyun rate = samplerate_to_bit(params_rate(params));
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
645*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_RXCR_2,
646*4882a593Smuzhiyun RK730_DI2S_XCR2_VDW_MASK,
647*4882a593Smuzhiyun RK730_DI2S_XCR2_VDW(width));
648*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT,
649*4882a593Smuzhiyun RK730_DDAC_SR_LMT_SRT_MASK,
650*4882a593Smuzhiyun RK730_DDAC_SR_LMT_SRT(rate));
651*4882a593Smuzhiyun } else {
652*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_TXCR_2,
653*4882a593Smuzhiyun RK730_DI2S_XCR2_VDW_MASK,
654*4882a593Smuzhiyun RK730_DI2S_XCR2_VDW(width));
655*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DADC_SR_ACL,
656*4882a593Smuzhiyun RK730_DADC_SR_ACL_SRT_MASK,
657*4882a593Smuzhiyun RK730_DADC_SR_ACL_SRT(rate));
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun return 0;
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun
rk730_dai_set_fmt(struct snd_soc_dai * codec_dai,unsigned int fmt)663*4882a593Smuzhiyun static int rk730_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
664*4882a593Smuzhiyun {
665*4882a593Smuzhiyun struct snd_soc_component *component = codec_dai->component;
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
668*4882a593Smuzhiyun case SND_SOC_DAIFMT_CBS_CFS:
669*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_CKM,
670*4882a593Smuzhiyun RK730_DI2S_CKM_MST_MASK,
671*4882a593Smuzhiyun RK730_DI2S_CKM_MST_SLAVE);
672*4882a593Smuzhiyun break;
673*4882a593Smuzhiyun case SND_SOC_DAIFMT_CBM_CFM:
674*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DI2S_CKM,
675*4882a593Smuzhiyun RK730_DI2S_CKM_MST_MASK,
676*4882a593Smuzhiyun RK730_DI2S_CKM_MST_MASTER);
677*4882a593Smuzhiyun break;
678*4882a593Smuzhiyun default:
679*4882a593Smuzhiyun return -EINVAL;
680*4882a593Smuzhiyun }
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun return 0;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun
rk730_dai_mute(struct snd_soc_dai * codec_dai,int mute,int direction)685*4882a593Smuzhiyun static int rk730_dai_mute(struct snd_soc_dai *codec_dai, int mute, int direction)
686*4882a593Smuzhiyun {
687*4882a593Smuzhiyun struct snd_soc_component *component = codec_dai->component;
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun if (mute)
690*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL,
691*4882a593Smuzhiyun RK730_DDAC_MUTE_MIXCTL_MUTE_MASK,
692*4882a593Smuzhiyun RK730_DDAC_MUTE_MIXCTL_MUTE);
693*4882a593Smuzhiyun else
694*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL,
695*4882a593Smuzhiyun RK730_DDAC_MUTE_MIXCTL_MUTE_MASK,
696*4882a593Smuzhiyun RK730_DDAC_MUTE_MIXCTL_UNMUTE);
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun return 0;
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun
rk730_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)701*4882a593Smuzhiyun static int rk730_set_bias_level(struct snd_soc_component *component,
702*4882a593Smuzhiyun enum snd_soc_bias_level level)
703*4882a593Smuzhiyun {
704*4882a593Smuzhiyun struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun switch (level) {
707*4882a593Smuzhiyun case SND_SOC_BIAS_ON:
708*4882a593Smuzhiyun break;
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun case SND_SOC_BIAS_PREPARE:
711*4882a593Smuzhiyun /*
712*4882a593Smuzhiyun * SND_SOC_BIAS_PREPARE is called while preparing for a
713*4882a593Smuzhiyun * transition to ON or away from ON. If current bias_level
714*4882a593Smuzhiyun * is SND_SOC_BIAS_ON, then it is preparing for a transition
715*4882a593Smuzhiyun * away from ON. Disable the clock in that case, otherwise
716*4882a593Smuzhiyun * enable it.
717*4882a593Smuzhiyun */
718*4882a593Smuzhiyun if (!IS_ERR(rk730->mclk)) {
719*4882a593Smuzhiyun if (snd_soc_component_get_bias_level(component) ==
720*4882a593Smuzhiyun SND_SOC_BIAS_ON)
721*4882a593Smuzhiyun clk_disable_unprepare(rk730->mclk);
722*4882a593Smuzhiyun else
723*4882a593Smuzhiyun clk_prepare_enable(rk730->mclk);
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun break;
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun case SND_SOC_BIAS_STANDBY:
728*4882a593Smuzhiyun if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
729*4882a593Smuzhiyun regcache_sync(rk730->regmap);
730*4882a593Smuzhiyun break;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun case SND_SOC_BIAS_OFF:
733*4882a593Smuzhiyun regcache_mark_dirty(rk730->regmap);
734*4882a593Smuzhiyun break;
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun return 0;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun #define RK730_RATES SNDRV_PCM_RATE_8000_192000
740*4882a593Smuzhiyun #define RK730_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
741*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_S32_LE)
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun static const struct snd_soc_dai_ops rk730_dai_ops = {
744*4882a593Smuzhiyun .set_fmt = rk730_dai_set_fmt,
745*4882a593Smuzhiyun .hw_params = rk730_dai_hw_params,
746*4882a593Smuzhiyun .mute_stream = rk730_dai_mute,
747*4882a593Smuzhiyun .no_capture_mute = 1,
748*4882a593Smuzhiyun };
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun static struct snd_soc_dai_driver rk730_dai = {
751*4882a593Smuzhiyun .name = "HiFi",
752*4882a593Smuzhiyun .playback = {
753*4882a593Smuzhiyun .stream_name = "HiFi Playback",
754*4882a593Smuzhiyun .channels_min = 1,
755*4882a593Smuzhiyun .channels_max = 2,
756*4882a593Smuzhiyun .rates = RK730_RATES,
757*4882a593Smuzhiyun .formats = RK730_FORMATS,
758*4882a593Smuzhiyun },
759*4882a593Smuzhiyun .capture = {
760*4882a593Smuzhiyun .stream_name = "HiFi Capture",
761*4882a593Smuzhiyun .channels_min = 1,
762*4882a593Smuzhiyun .channels_max = 2,
763*4882a593Smuzhiyun .rates = RK730_RATES,
764*4882a593Smuzhiyun .formats = RK730_FORMATS,
765*4882a593Smuzhiyun },
766*4882a593Smuzhiyun .ops = &rk730_dai_ops,
767*4882a593Smuzhiyun };
768*4882a593Smuzhiyun
rk730_reset(struct snd_soc_component * component)769*4882a593Smuzhiyun static int rk730_reset(struct snd_soc_component *component)
770*4882a593Smuzhiyun {
771*4882a593Smuzhiyun struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
772*4882a593Smuzhiyun
773*4882a593Smuzhiyun clk_prepare_enable(rk730->mclk);
774*4882a593Smuzhiyun snd_soc_component_write(component, RK730_DTOP_LPT_SRST, 0x40);
775*4882a593Smuzhiyun udelay(10);
776*4882a593Smuzhiyun /* WA: Initial micbias default, ADC stopped with micbias(>2.5v) */
777*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_MIC_BIAS,
778*4882a593Smuzhiyun RK730_MIC_BIAS_VOLT_MASK,
779*4882a593Smuzhiyun RK730_MIC_BIAS_VOLT_2_2V);
780*4882a593Smuzhiyun /* PF: Use the maximum bias current for better performance */
781*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_HK_TOP_1,
782*4882a593Smuzhiyun RK730_HK_TOP_1_IBIAS_STD_SEL_MASK |
783*4882a593Smuzhiyun RK730_HK_TOP_1_IBIAS_GAIN_SEL_MASK,
784*4882a593Smuzhiyun RK730_HK_TOP_1_IBIAS_STD_SEL_27_5UA |
785*4882a593Smuzhiyun RK730_HK_TOP_1_IBIAS_GAIN_SEL_200);
786*4882a593Smuzhiyun /* PF: Use the chop 400kHz for better ADC noise performance */
787*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_MIC_BOOST_3,
788*4882a593Smuzhiyun RK730_MIC_BOOST_3_MIC_CHOP_MASK,
789*4882a593Smuzhiyun RK730_MIC_BOOST_3_MIC_CHOP(RK730_CHOP_FREQ_400KHZ));
790*4882a593Smuzhiyun snd_soc_component_update_bits(component, RK730_ADC_PGA_BLOCK_1,
791*4882a593Smuzhiyun RK730_ADC_PGA_BLOCK_1_PGA_CHOP_MASK,
792*4882a593Smuzhiyun RK730_ADC_PGA_BLOCK_1_PGA_CHOP(RK730_CHOP_FREQ_400KHZ));
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun clk_disable_unprepare(rk730->mclk);
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun return 0;
797*4882a593Smuzhiyun }
798*4882a593Smuzhiyun
rk730_probe(struct snd_soc_component * component)799*4882a593Smuzhiyun static int rk730_probe(struct snd_soc_component *component)
800*4882a593Smuzhiyun {
801*4882a593Smuzhiyun struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
802*4882a593Smuzhiyun int ret = 0;
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun regcache_mark_dirty(rk730->regmap);
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun /* initialize private data */
807*4882a593Smuzhiyun atomic_set(&rk730->mix_mode, RK730_MIX_MODE_1_PATH);
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun ret = snd_soc_component_read(component, RK730_HK_TOP_0);
810*4882a593Smuzhiyun if (ret < 0) {
811*4882a593Smuzhiyun dev_err(component->dev, "Failed to read register: %d\n", ret);
812*4882a593Smuzhiyun return ret;
813*4882a593Smuzhiyun }
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun rk730_reset(component);
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun return ret;
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun static const struct snd_soc_component_driver rk730_component_driver = {
821*4882a593Smuzhiyun .probe = rk730_probe,
822*4882a593Smuzhiyun .set_bias_level = rk730_set_bias_level,
823*4882a593Smuzhiyun .controls = rk730_snd_controls,
824*4882a593Smuzhiyun .num_controls = ARRAY_SIZE(rk730_snd_controls),
825*4882a593Smuzhiyun .dapm_widgets = rk730_dapm_widgets,
826*4882a593Smuzhiyun .num_dapm_widgets = ARRAY_SIZE(rk730_dapm_widgets),
827*4882a593Smuzhiyun .dapm_routes = rk730_dapm_routes,
828*4882a593Smuzhiyun .num_dapm_routes = ARRAY_SIZE(rk730_dapm_routes),
829*4882a593Smuzhiyun .suspend_bias_off = 1,
830*4882a593Smuzhiyun .idle_bias_on = 1,
831*4882a593Smuzhiyun .use_pmdown_time = 1,
832*4882a593Smuzhiyun .endianness = 1,
833*4882a593Smuzhiyun .non_legacy_dai_naming = 1,
834*4882a593Smuzhiyun };
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun static const struct reg_default rk730_reg_defaults[] = {
837*4882a593Smuzhiyun { 0x00, 0x40 },
838*4882a593Smuzhiyun { 0x02, 0x17 },
839*4882a593Smuzhiyun { 0x05, 0x03 },
840*4882a593Smuzhiyun { 0x06, 0x22 },
841*4882a593Smuzhiyun { 0x07, 0x02 },
842*4882a593Smuzhiyun { 0x08, 0x07 },
843*4882a593Smuzhiyun { 0x09, 0x01 },
844*4882a593Smuzhiyun { 0x0a, 0x01 },
845*4882a593Smuzhiyun { 0x0b, 0x01 },
846*4882a593Smuzhiyun { 0x0c, 0x01 },
847*4882a593Smuzhiyun { 0x0d, 0x01 },
848*4882a593Smuzhiyun { 0x0e, 0x01 },
849*4882a593Smuzhiyun { 0x0f, 0x07 },
850*4882a593Smuzhiyun { 0x10, 0x07 },
851*4882a593Smuzhiyun { 0x11, 0xff },
852*4882a593Smuzhiyun { 0x12, 0x07 },
853*4882a593Smuzhiyun { 0x13, 0x54 },
854*4882a593Smuzhiyun { 0x14, 0x04 },
855*4882a593Smuzhiyun { 0x15, 0x23 },
856*4882a593Smuzhiyun { 0x16, 0x35 },
857*4882a593Smuzhiyun { 0x17, 0x67 },
858*4882a593Smuzhiyun { 0x18, 0x1e },
859*4882a593Smuzhiyun { 0x19, 0xc0 },
860*4882a593Smuzhiyun { 0x1a, 0x13 },
861*4882a593Smuzhiyun { 0x1b, 0x04 },
862*4882a593Smuzhiyun { 0x1c, 0x20 },
863*4882a593Smuzhiyun { 0x1f, 0x90 },
864*4882a593Smuzhiyun { 0x20, 0x11 },
865*4882a593Smuzhiyun { 0x21, 0x09 },
866*4882a593Smuzhiyun { 0x22, 0x33 },
867*4882a593Smuzhiyun { 0x24, 0x11 },
868*4882a593Smuzhiyun { 0x25, 0x11 },
869*4882a593Smuzhiyun { 0x26, 0x09 },
870*4882a593Smuzhiyun { 0x27, 0x02 },
871*4882a593Smuzhiyun { 0x28, 0x2c },
872*4882a593Smuzhiyun { 0x2a, 0x0c },
873*4882a593Smuzhiyun { 0x2b, 0x80 },
874*4882a593Smuzhiyun { 0x40, 0x03 },
875*4882a593Smuzhiyun { 0x42, 0x20 },
876*4882a593Smuzhiyun { 0x47, 0xe6 },
877*4882a593Smuzhiyun { 0x48, 0xd0 },
878*4882a593Smuzhiyun { 0x49, 0x17 },
879*4882a593Smuzhiyun { 0x4a, 0x26 },
880*4882a593Smuzhiyun { 0x4b, 0x01 },
881*4882a593Smuzhiyun { 0x4c, 0x05 },
882*4882a593Smuzhiyun { 0x4d, 0x0e },
883*4882a593Smuzhiyun { 0x4e, 0x09 },
884*4882a593Smuzhiyun { 0x4f, 0x02 },
885*4882a593Smuzhiyun { 0x5b, 0xe6 },
886*4882a593Smuzhiyun { 0x5c, 0xd0 },
887*4882a593Smuzhiyun { 0x5d, 0x17 },
888*4882a593Smuzhiyun { 0x5e, 0x26 },
889*4882a593Smuzhiyun { 0x5f, 0x01 },
890*4882a593Smuzhiyun { 0x60, 0x05 },
891*4882a593Smuzhiyun { 0x61, 0x0e },
892*4882a593Smuzhiyun { 0x62, 0x09 },
893*4882a593Smuzhiyun { 0x63, 0x20 },
894*4882a593Smuzhiyun { 0x66, 0x01 },
895*4882a593Smuzhiyun { 0x69, 0x17 },
896*4882a593Smuzhiyun { 0x6c, 0x17 },
897*4882a593Smuzhiyun };
898*4882a593Smuzhiyun
rk730_volatile_register(struct device * dev,unsigned int reg)899*4882a593Smuzhiyun static bool rk730_volatile_register(struct device *dev, unsigned int reg)
900*4882a593Smuzhiyun {
901*4882a593Smuzhiyun switch (reg) {
902*4882a593Smuzhiyun case RK730_DTOP_LPT_SRST:
903*4882a593Smuzhiyun return true;
904*4882a593Smuzhiyun default:
905*4882a593Smuzhiyun return false;
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun }
908*4882a593Smuzhiyun
909*4882a593Smuzhiyun static const struct regmap_config rk730_regmap = {
910*4882a593Smuzhiyun .reg_bits = 8,
911*4882a593Smuzhiyun .val_bits = 8,
912*4882a593Smuzhiyun .volatile_reg = rk730_volatile_register,
913*4882a593Smuzhiyun .max_register = RK730_DAC_ATTN,
914*4882a593Smuzhiyun .reg_defaults = rk730_reg_defaults,
915*4882a593Smuzhiyun .num_reg_defaults = ARRAY_SIZE(rk730_reg_defaults),
916*4882a593Smuzhiyun .cache_type = REGCACHE_RBTREE,
917*4882a593Smuzhiyun };
918*4882a593Smuzhiyun
rk730_i2c_probe(struct i2c_client * i2c,const struct i2c_device_id * id)919*4882a593Smuzhiyun static int rk730_i2c_probe(struct i2c_client *i2c,
920*4882a593Smuzhiyun const struct i2c_device_id *id)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun struct rk730_priv *rk730;
923*4882a593Smuzhiyun int ret;
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun rk730 = devm_kzalloc(&i2c->dev, sizeof(struct rk730_priv), GFP_KERNEL);
926*4882a593Smuzhiyun if (!rk730)
927*4882a593Smuzhiyun return -ENOMEM;
928*4882a593Smuzhiyun
929*4882a593Smuzhiyun rk730->regmap = devm_regmap_init_i2c(i2c, &rk730_regmap);
930*4882a593Smuzhiyun if (IS_ERR(rk730->regmap))
931*4882a593Smuzhiyun return PTR_ERR(rk730->regmap);
932*4882a593Smuzhiyun
933*4882a593Smuzhiyun rk730->mclk = devm_clk_get(&i2c->dev, "mclk");
934*4882a593Smuzhiyun if (IS_ERR(rk730->mclk))
935*4882a593Smuzhiyun return PTR_ERR(rk730->mclk);
936*4882a593Smuzhiyun
937*4882a593Smuzhiyun i2c_set_clientdata(i2c, rk730);
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun ret = devm_snd_soc_register_component(&i2c->dev,
940*4882a593Smuzhiyun &rk730_component_driver, &rk730_dai, 1);
941*4882a593Smuzhiyun return ret;
942*4882a593Smuzhiyun }
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun static const struct i2c_device_id rk730_i2c_id[] = {
945*4882a593Smuzhiyun { "rk730", 0 },
946*4882a593Smuzhiyun { }
947*4882a593Smuzhiyun };
948*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, rk730_i2c_id);
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun #if defined(CONFIG_OF)
951*4882a593Smuzhiyun static const struct of_device_id rk730_of_match[] = {
952*4882a593Smuzhiyun { .compatible = "rockchip,rk730" },
953*4882a593Smuzhiyun { }
954*4882a593Smuzhiyun };
955*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rk730_of_match);
956*4882a593Smuzhiyun #endif
957*4882a593Smuzhiyun
958*4882a593Smuzhiyun static struct i2c_driver rk730_i2c_driver = {
959*4882a593Smuzhiyun .driver = {
960*4882a593Smuzhiyun .name = "rk730",
961*4882a593Smuzhiyun .of_match_table = of_match_ptr(rk730_of_match),
962*4882a593Smuzhiyun },
963*4882a593Smuzhiyun .probe = rk730_i2c_probe,
964*4882a593Smuzhiyun .id_table = rk730_i2c_id,
965*4882a593Smuzhiyun };
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun module_i2c_driver(rk730_i2c_driver);
968*4882a593Smuzhiyun
969*4882a593Smuzhiyun MODULE_DESCRIPTION("ASoC RK730 driver");
970*4882a593Smuzhiyun MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
971*4882a593Smuzhiyun MODULE_LICENSE("GPL");
972