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