Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/codecs/ad193x.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* AD193X Audio Codec driver supporting AD1936/7/8/9
4
*
5
* Copyright 2010 Analog Devices Inc.
6
*/
7
8
#include <linux/module.h>
9
#include <linux/kernel.h>
10
#include <linux/device.h>
11
#include <linux/regmap.h>
12
#include <linux/slab.h>
13
#include <sound/core.h>
14
#include <sound/pcm.h>
15
#include <sound/pcm_params.h>
16
#include <sound/initval.h>
17
#include <sound/soc.h>
18
#include <sound/tlv.h>
19
20
#include "ad193x.h"
21
22
/* codec private data */
23
struct ad193x_priv {
24
struct regmap *regmap;
25
enum ad193x_type type;
26
int sysclk;
27
};
28
29
/*
30
* AD193X volume/mute/de-emphasis etc. controls
31
*/
32
static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
33
34
static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1,
35
ad193x_deemp);
36
37
static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
38
39
static const unsigned int ad193x_sb[] = {32};
40
41
static struct snd_pcm_hw_constraint_list constr = {
42
.list = ad193x_sb,
43
.count = ARRAY_SIZE(ad193x_sb),
44
};
45
46
static const struct snd_kcontrol_new ad193x_snd_controls[] = {
47
/* DAC volume control */
48
SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL,
49
AD193X_DAC_R1_VOL, 0, 0xFF, 1, adau193x_tlv),
50
SOC_DOUBLE_R_TLV("DAC2 Volume", AD193X_DAC_L2_VOL,
51
AD193X_DAC_R2_VOL, 0, 0xFF, 1, adau193x_tlv),
52
SOC_DOUBLE_R_TLV("DAC3 Volume", AD193X_DAC_L3_VOL,
53
AD193X_DAC_R3_VOL, 0, 0xFF, 1, adau193x_tlv),
54
SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
55
AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
56
57
/* DAC switch control */
58
SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE,
59
AD193X_DACR1_MUTE, 1, 1),
60
SOC_DOUBLE("DAC2 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL2_MUTE,
61
AD193X_DACR2_MUTE, 1, 1),
62
SOC_DOUBLE("DAC3 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL3_MUTE,
63
AD193X_DACR3_MUTE, 1, 1),
64
SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE,
65
AD193X_DACR4_MUTE, 1, 1),
66
67
/* DAC de-emphasis */
68
SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
69
};
70
71
static const struct snd_kcontrol_new ad193x_adc_snd_controls[] = {
72
/* ADC switch control */
73
SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
74
AD193X_ADCR1_MUTE, 1, 1),
75
SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
76
AD193X_ADCR2_MUTE, 1, 1),
77
78
/* ADC high-pass filter */
79
SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0,
80
AD193X_ADC_HIGHPASS_FILTER, 1, 0),
81
};
82
83
static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
84
SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
85
SND_SOC_DAPM_PGA("DAC Output", AD193X_DAC_CTRL0, 0, 1, NULL, 0),
86
SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
87
SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
88
SND_SOC_DAPM_VMID("VMID"),
89
SND_SOC_DAPM_OUTPUT("DAC1OUT"),
90
SND_SOC_DAPM_OUTPUT("DAC2OUT"),
91
SND_SOC_DAPM_OUTPUT("DAC3OUT"),
92
SND_SOC_DAPM_OUTPUT("DAC4OUT"),
93
};
94
95
static const struct snd_soc_dapm_widget ad193x_adc_widgets[] = {
96
SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
97
SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
98
SND_SOC_DAPM_INPUT("ADC1IN"),
99
SND_SOC_DAPM_INPUT("ADC2IN"),
100
};
101
102
static int ad193x_check_pll(struct snd_soc_dapm_widget *source,
103
struct snd_soc_dapm_widget *sink)
104
{
105
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
106
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
107
108
return !!ad193x->sysclk;
109
}
110
111
static const struct snd_soc_dapm_route audio_paths[] = {
112
{ "DAC", NULL, "SYSCLK" },
113
{ "DAC Output", NULL, "DAC" },
114
{ "DAC Output", NULL, "VMID" },
115
{ "DAC1OUT", NULL, "DAC Output" },
116
{ "DAC2OUT", NULL, "DAC Output" },
117
{ "DAC3OUT", NULL, "DAC Output" },
118
{ "DAC4OUT", NULL, "DAC Output" },
119
{ "SYSCLK", NULL, "PLL_PWR", &ad193x_check_pll },
120
};
121
122
static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = {
123
{ "ADC", NULL, "SYSCLK" },
124
{ "ADC", NULL, "ADC_PWR" },
125
{ "ADC", NULL, "ADC1IN" },
126
{ "ADC", NULL, "ADC2IN" },
127
};
128
129
static inline bool ad193x_has_adc(const struct ad193x_priv *ad193x)
130
{
131
switch (ad193x->type) {
132
case AD1933:
133
case AD1934:
134
return false;
135
default:
136
break;
137
}
138
139
return true;
140
}
141
142
/*
143
* DAI ops entries
144
*/
145
146
static int ad193x_mute(struct snd_soc_dai *dai, int mute, int direction)
147
{
148
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
149
150
if (mute)
151
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
152
AD193X_DAC_MASTER_MUTE,
153
AD193X_DAC_MASTER_MUTE);
154
else
155
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
156
AD193X_DAC_MASTER_MUTE, 0);
157
158
return 0;
159
}
160
161
static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
162
unsigned int rx_mask, int slots, int width)
163
{
164
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(dai->component);
165
unsigned int channels;
166
167
switch (slots) {
168
case 2:
169
channels = AD193X_2_CHANNELS;
170
break;
171
case 4:
172
channels = AD193X_4_CHANNELS;
173
break;
174
case 8:
175
channels = AD193X_8_CHANNELS;
176
break;
177
case 16:
178
channels = AD193X_16_CHANNELS;
179
break;
180
default:
181
return -EINVAL;
182
}
183
184
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
185
AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
186
if (ad193x_has_adc(ad193x))
187
regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
188
AD193X_ADC_CHAN_MASK,
189
channels << AD193X_ADC_CHAN_SHFT);
190
191
return 0;
192
}
193
194
static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
195
unsigned int fmt)
196
{
197
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component);
198
unsigned int adc_serfmt = 0;
199
unsigned int dac_serfmt = 0;
200
unsigned int adc_fmt = 0;
201
unsigned int dac_fmt = 0;
202
203
/* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
204
* with TDM), ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) and DAC I2S mode
205
* (SND_SOC_DAIFMT_I2S)
206
*/
207
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
208
case SND_SOC_DAIFMT_I2S:
209
adc_serfmt |= AD193X_ADC_SERFMT_TDM;
210
dac_serfmt |= AD193X_DAC_SERFMT_STEREO;
211
break;
212
case SND_SOC_DAIFMT_DSP_A:
213
adc_serfmt |= AD193X_ADC_SERFMT_AUX;
214
dac_serfmt |= AD193X_DAC_SERFMT_TDM;
215
break;
216
default:
217
if (ad193x_has_adc(ad193x))
218
return -EINVAL;
219
}
220
221
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
222
case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
223
break;
224
case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
225
adc_fmt |= AD193X_ADC_LEFT_HIGH;
226
dac_fmt |= AD193X_DAC_LEFT_HIGH;
227
break;
228
case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
229
adc_fmt |= AD193X_ADC_BCLK_INV;
230
dac_fmt |= AD193X_DAC_BCLK_INV;
231
break;
232
case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
233
adc_fmt |= AD193X_ADC_LEFT_HIGH;
234
adc_fmt |= AD193X_ADC_BCLK_INV;
235
dac_fmt |= AD193X_DAC_LEFT_HIGH;
236
dac_fmt |= AD193X_DAC_BCLK_INV;
237
break;
238
default:
239
return -EINVAL;
240
}
241
242
/* For DSP_*, LRCLK's polarity must be inverted */
243
if (fmt & SND_SOC_DAIFMT_DSP_A)
244
dac_fmt ^= AD193X_DAC_LEFT_HIGH;
245
246
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
247
case SND_SOC_DAIFMT_CBP_CFP:
248
adc_fmt |= AD193X_ADC_LCR_MASTER;
249
adc_fmt |= AD193X_ADC_BCLK_MASTER;
250
dac_fmt |= AD193X_DAC_LCR_MASTER;
251
dac_fmt |= AD193X_DAC_BCLK_MASTER;
252
break;
253
case SND_SOC_DAIFMT_CBC_CFP:
254
adc_fmt |= AD193X_ADC_LCR_MASTER;
255
dac_fmt |= AD193X_DAC_LCR_MASTER;
256
break;
257
case SND_SOC_DAIFMT_CBP_CFC:
258
adc_fmt |= AD193X_ADC_BCLK_MASTER;
259
dac_fmt |= AD193X_DAC_BCLK_MASTER;
260
break;
261
case SND_SOC_DAIFMT_CBC_CFC:
262
break;
263
default:
264
return -EINVAL;
265
}
266
267
if (ad193x_has_adc(ad193x)) {
268
regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
269
AD193X_ADC_SERFMT_MASK, adc_serfmt);
270
regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
271
AD193X_ADC_FMT_MASK, adc_fmt);
272
}
273
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0,
274
AD193X_DAC_SERFMT_MASK, dac_serfmt);
275
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
276
AD193X_DAC_FMT_MASK, dac_fmt);
277
278
return 0;
279
}
280
281
static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
282
int clk_id, unsigned int freq, int dir)
283
{
284
struct snd_soc_component *component = codec_dai->component;
285
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
286
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
287
288
if (clk_id == AD193X_SYSCLK_MCLK) {
289
/* MCLK must be 512 x fs */
290
if (dir == SND_SOC_CLOCK_OUT || freq != 24576000)
291
return -EINVAL;
292
293
regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL1,
294
AD193X_PLL_SRC_MASK,
295
AD193X_PLL_DAC_SRC_MCLK |
296
AD193X_PLL_CLK_SRC_MCLK);
297
298
snd_soc_dapm_sync(dapm);
299
return 0;
300
}
301
switch (freq) {
302
case 12288000:
303
case 18432000:
304
case 24576000:
305
case 36864000:
306
ad193x->sysclk = freq;
307
return 0;
308
}
309
return -EINVAL;
310
}
311
312
static int ad193x_hw_params(struct snd_pcm_substream *substream,
313
struct snd_pcm_hw_params *params,
314
struct snd_soc_dai *dai)
315
{
316
int word_len = 0, master_rate = 0;
317
struct snd_soc_component *component = dai->component;
318
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
319
bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
320
u8 dacc0;
321
322
dev_dbg(dai->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
323
__func__, params_rate(params), params_format(params),
324
params_width(params), params_channels(params));
325
326
327
/* bit size */
328
switch (params_width(params)) {
329
case 16:
330
word_len = 3;
331
break;
332
case 20:
333
word_len = 1;
334
break;
335
case 24:
336
case 32:
337
word_len = 0;
338
break;
339
}
340
341
switch (ad193x->sysclk) {
342
case 12288000:
343
master_rate = AD193X_PLL_INPUT_256;
344
break;
345
case 18432000:
346
master_rate = AD193X_PLL_INPUT_384;
347
break;
348
case 24576000:
349
master_rate = AD193X_PLL_INPUT_512;
350
break;
351
case 36864000:
352
master_rate = AD193X_PLL_INPUT_768;
353
break;
354
}
355
356
if (is_playback) {
357
switch (params_rate(params)) {
358
case 48000:
359
dacc0 = AD193X_DAC_SR_48;
360
break;
361
case 96000:
362
dacc0 = AD193X_DAC_SR_96;
363
break;
364
case 192000:
365
dacc0 = AD193X_DAC_SR_192;
366
break;
367
default:
368
dev_err(dai->dev, "invalid sampling rate: %d\n", params_rate(params));
369
return -EINVAL;
370
}
371
372
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0, AD193X_DAC_SR_MASK, dacc0);
373
}
374
375
regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0,
376
AD193X_PLL_INPUT_MASK, master_rate);
377
378
regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2,
379
AD193X_DAC_WORD_LEN_MASK,
380
word_len << AD193X_DAC_WORD_LEN_SHFT);
381
382
if (ad193x_has_adc(ad193x))
383
regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
384
AD193X_ADC_WORD_LEN_MASK, word_len);
385
386
return 0;
387
}
388
389
static int ad193x_startup(struct snd_pcm_substream *substream,
390
struct snd_soc_dai *dai)
391
{
392
return snd_pcm_hw_constraint_list(substream->runtime, 0,
393
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
394
&constr);
395
}
396
397
static const struct snd_soc_dai_ops ad193x_dai_ops = {
398
.startup = ad193x_startup,
399
.hw_params = ad193x_hw_params,
400
.mute_stream = ad193x_mute,
401
.set_tdm_slot = ad193x_set_tdm_slot,
402
.set_sysclk = ad193x_set_dai_sysclk,
403
.set_fmt = ad193x_set_dai_fmt,
404
.no_capture_mute = 1,
405
};
406
407
/* codec DAI instance */
408
static struct snd_soc_dai_driver ad193x_dai = {
409
.name = "ad193x-hifi",
410
.playback = {
411
.stream_name = "Playback",
412
.channels_min = 2,
413
.channels_max = 8,
414
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
415
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
416
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
417
},
418
.capture = {
419
.stream_name = "Capture",
420
.channels_min = 2,
421
.channels_max = 4,
422
.rates = SNDRV_PCM_RATE_48000,
423
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
424
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
425
},
426
.ops = &ad193x_dai_ops,
427
};
428
429
/* codec DAI instance for DAC only */
430
static struct snd_soc_dai_driver ad193x_no_adc_dai = {
431
.name = "ad193x-hifi",
432
.playback = {
433
.stream_name = "Playback",
434
.channels_min = 2,
435
.channels_max = 8,
436
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
437
.formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
438
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
439
},
440
.ops = &ad193x_dai_ops,
441
};
442
443
/* codec register values to set after reset */
444
static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
445
{
446
static const struct reg_sequence reg_init[] = {
447
{ 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */
448
{ 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */
449
{ 2, 0x40 }, /* DAC_CTRL0: TDM mode */
450
{ 3, 0x00 }, /* DAC_CTRL1: reset */
451
{ 4, 0x1A }, /* DAC_CTRL2: 48kHz de-emphasis, unmute dac */
452
{ 5, 0x00 }, /* DAC_CHNL_MUTE: unmute DAC channels */
453
{ 6, 0x00 }, /* DAC_L1_VOL: no attenuation */
454
{ 7, 0x00 }, /* DAC_R1_VOL: no attenuation */
455
{ 8, 0x00 }, /* DAC_L2_VOL: no attenuation */
456
{ 9, 0x00 }, /* DAC_R2_VOL: no attenuation */
457
{ 10, 0x00 }, /* DAC_L3_VOL: no attenuation */
458
{ 11, 0x00 }, /* DAC_R3_VOL: no attenuation */
459
{ 12, 0x00 }, /* DAC_L4_VOL: no attenuation */
460
{ 13, 0x00 }, /* DAC_R4_VOL: no attenuation */
461
};
462
static const struct reg_sequence reg_adc_init[] = {
463
{ 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */
464
{ 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */
465
{ 16, 0x00 }, /* ADC_CTRL2: reset */
466
};
467
468
regmap_multi_reg_write(ad193x->regmap, reg_init, ARRAY_SIZE(reg_init));
469
470
if (ad193x_has_adc(ad193x)) {
471
regmap_multi_reg_write(ad193x->regmap, reg_adc_init,
472
ARRAY_SIZE(reg_adc_init));
473
}
474
}
475
476
static int ad193x_component_probe(struct snd_soc_component *component)
477
{
478
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
479
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
480
int num, ret;
481
482
/* default setting for ad193x */
483
ad193x_reg_default_init(ad193x);
484
485
/* adc only */
486
if (ad193x_has_adc(ad193x)) {
487
/* add adc controls */
488
num = ARRAY_SIZE(ad193x_adc_snd_controls);
489
ret = snd_soc_add_component_controls(component,
490
ad193x_adc_snd_controls,
491
num);
492
if (ret)
493
return ret;
494
495
/* add adc widgets */
496
num = ARRAY_SIZE(ad193x_adc_widgets);
497
ret = snd_soc_dapm_new_controls(dapm,
498
ad193x_adc_widgets,
499
num);
500
if (ret)
501
return ret;
502
503
/* add adc routes */
504
num = ARRAY_SIZE(ad193x_adc_audio_paths);
505
ret = snd_soc_dapm_add_routes(dapm,
506
ad193x_adc_audio_paths,
507
num);
508
if (ret)
509
return ret;
510
}
511
512
return 0;
513
}
514
515
static const struct snd_soc_component_driver soc_component_dev_ad193x = {
516
.probe = ad193x_component_probe,
517
.controls = ad193x_snd_controls,
518
.num_controls = ARRAY_SIZE(ad193x_snd_controls),
519
.dapm_widgets = ad193x_dapm_widgets,
520
.num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets),
521
.dapm_routes = audio_paths,
522
.num_dapm_routes = ARRAY_SIZE(audio_paths),
523
.idle_bias_on = 1,
524
.use_pmdown_time = 1,
525
.endianness = 1,
526
};
527
528
const struct regmap_config ad193x_regmap_config = {
529
.max_register = AD193X_NUM_REGS - 1,
530
};
531
EXPORT_SYMBOL_GPL(ad193x_regmap_config);
532
533
int ad193x_probe(struct device *dev, struct regmap *regmap,
534
enum ad193x_type type)
535
{
536
struct ad193x_priv *ad193x;
537
538
if (IS_ERR(regmap))
539
return PTR_ERR(regmap);
540
541
ad193x = devm_kzalloc(dev, sizeof(*ad193x), GFP_KERNEL);
542
if (ad193x == NULL)
543
return -ENOMEM;
544
545
ad193x->regmap = regmap;
546
ad193x->type = type;
547
548
dev_set_drvdata(dev, ad193x);
549
550
if (ad193x_has_adc(ad193x))
551
return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
552
&ad193x_dai, 1);
553
return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x,
554
&ad193x_no_adc_dai, 1);
555
}
556
EXPORT_SYMBOL_GPL(ad193x_probe);
557
558
MODULE_DESCRIPTION("ASoC ad193x driver");
559
MODULE_AUTHOR("Barry Song <[email protected]>");
560
MODULE_LICENSE("GPL");
561
562