Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/codecs/adav80x.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* ADAV80X Audio Codec driver supporting ADAV801, ADAV803
4
*
5
* Copyright 2011 Analog Devices Inc.
6
* Author: Yi Li <[email protected]>
7
* Author: Lars-Peter Clausen <[email protected]>
8
*/
9
10
#include <linux/module.h>
11
#include <linux/kernel.h>
12
#include <linux/regmap.h>
13
#include <linux/slab.h>
14
15
#include <sound/pcm.h>
16
#include <sound/pcm_params.h>
17
#include <sound/soc.h>
18
#include <sound/tlv.h>
19
20
#include "adav80x.h"
21
22
#define ADAV80X_PLAYBACK_CTRL 0x04
23
#define ADAV80X_AUX_IN_CTRL 0x05
24
#define ADAV80X_REC_CTRL 0x06
25
#define ADAV80X_AUX_OUT_CTRL 0x07
26
#define ADAV80X_DPATH_CTRL1 0x62
27
#define ADAV80X_DPATH_CTRL2 0x63
28
#define ADAV80X_DAC_CTRL1 0x64
29
#define ADAV80X_DAC_CTRL2 0x65
30
#define ADAV80X_DAC_CTRL3 0x66
31
#define ADAV80X_DAC_L_VOL 0x68
32
#define ADAV80X_DAC_R_VOL 0x69
33
#define ADAV80X_PGA_L_VOL 0x6c
34
#define ADAV80X_PGA_R_VOL 0x6d
35
#define ADAV80X_ADC_CTRL1 0x6e
36
#define ADAV80X_ADC_CTRL2 0x6f
37
#define ADAV80X_ADC_L_VOL 0x70
38
#define ADAV80X_ADC_R_VOL 0x71
39
#define ADAV80X_PLL_CTRL1 0x74
40
#define ADAV80X_PLL_CTRL2 0x75
41
#define ADAV80X_ICLK_CTRL1 0x76
42
#define ADAV80X_ICLK_CTRL2 0x77
43
#define ADAV80X_PLL_CLK_SRC 0x78
44
#define ADAV80X_PLL_OUTE 0x7a
45
46
#define ADAV80X_PLL_CLK_SRC_PLL_XIN(pll) 0x00
47
#define ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll) (0x40 << (pll))
48
#define ADAV80X_PLL_CLK_SRC_PLL_MASK(pll) (0x40 << (pll))
49
50
#define ADAV80X_ICLK_CTRL1_DAC_SRC(src) ((src) << 5)
51
#define ADAV80X_ICLK_CTRL1_ADC_SRC(src) ((src) << 2)
52
#define ADAV80X_ICLK_CTRL1_ICLK2_SRC(src) (src)
53
#define ADAV80X_ICLK_CTRL2_ICLK1_SRC(src) ((src) << 3)
54
55
#define ADAV80X_PLL_CTRL1_PLLDIV 0x10
56
#define ADAV80X_PLL_CTRL1_PLLPD(pll) (0x04 << (pll))
57
#define ADAV80X_PLL_CTRL1_XTLPD 0x02
58
59
#define ADAV80X_PLL_CTRL2_FIELD(pll, x) ((x) << ((pll) * 4))
60
61
#define ADAV80X_PLL_CTRL2_FS_48(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x00)
62
#define ADAV80X_PLL_CTRL2_FS_32(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x08)
63
#define ADAV80X_PLL_CTRL2_FS_44(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0c)
64
65
#define ADAV80X_PLL_CTRL2_SEL(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x02)
66
#define ADAV80X_PLL_CTRL2_DOUB(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x01)
67
#define ADAV80X_PLL_CTRL2_PLL_MASK(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0f)
68
69
#define ADAV80X_ADC_CTRL1_MODULATOR_MASK 0x80
70
#define ADAV80X_ADC_CTRL1_MODULATOR_128FS 0x00
71
#define ADAV80X_ADC_CTRL1_MODULATOR_64FS 0x80
72
73
#define ADAV80X_DAC_CTRL1_PD 0x80
74
75
#define ADAV80X_DAC_CTRL2_DIV1 0x00
76
#define ADAV80X_DAC_CTRL2_DIV1_5 0x10
77
#define ADAV80X_DAC_CTRL2_DIV2 0x20
78
#define ADAV80X_DAC_CTRL2_DIV3 0x30
79
#define ADAV80X_DAC_CTRL2_DIV_MASK 0x30
80
81
#define ADAV80X_DAC_CTRL2_INTERPOL_256FS 0x00
82
#define ADAV80X_DAC_CTRL2_INTERPOL_128FS 0x40
83
#define ADAV80X_DAC_CTRL2_INTERPOL_64FS 0x80
84
#define ADAV80X_DAC_CTRL2_INTERPOL_MASK 0xc0
85
86
#define ADAV80X_DAC_CTRL2_DEEMPH_NONE 0x00
87
#define ADAV80X_DAC_CTRL2_DEEMPH_44 0x01
88
#define ADAV80X_DAC_CTRL2_DEEMPH_32 0x02
89
#define ADAV80X_DAC_CTRL2_DEEMPH_48 0x03
90
#define ADAV80X_DAC_CTRL2_DEEMPH_MASK 0x01
91
92
#define ADAV80X_CAPTURE_MODE_MASTER 0x20
93
#define ADAV80X_CAPTURE_WORD_LEN24 0x00
94
#define ADAV80X_CAPTURE_WORD_LEN20 0x04
95
#define ADAV80X_CAPTRUE_WORD_LEN18 0x08
96
#define ADAV80X_CAPTURE_WORD_LEN16 0x0c
97
#define ADAV80X_CAPTURE_WORD_LEN_MASK 0x0c
98
99
#define ADAV80X_CAPTURE_MODE_LEFT_J 0x00
100
#define ADAV80X_CAPTURE_MODE_I2S 0x01
101
#define ADAV80X_CAPTURE_MODE_RIGHT_J 0x03
102
#define ADAV80X_CAPTURE_MODE_MASK 0x03
103
104
#define ADAV80X_PLAYBACK_MODE_MASTER 0x10
105
#define ADAV80X_PLAYBACK_MODE_LEFT_J 0x00
106
#define ADAV80X_PLAYBACK_MODE_I2S 0x01
107
#define ADAV80X_PLAYBACK_MODE_RIGHT_J_24 0x04
108
#define ADAV80X_PLAYBACK_MODE_RIGHT_J_20 0x05
109
#define ADAV80X_PLAYBACK_MODE_RIGHT_J_18 0x06
110
#define ADAV80X_PLAYBACK_MODE_RIGHT_J_16 0x07
111
#define ADAV80X_PLAYBACK_MODE_MASK 0x07
112
113
#define ADAV80X_PLL_OUTE_SYSCLKPD(x) BIT(2 - (x))
114
115
static const struct reg_default adav80x_reg_defaults[] = {
116
{ ADAV80X_PLAYBACK_CTRL, 0x01 },
117
{ ADAV80X_AUX_IN_CTRL, 0x01 },
118
{ ADAV80X_REC_CTRL, 0x02 },
119
{ ADAV80X_AUX_OUT_CTRL, 0x01 },
120
{ ADAV80X_DPATH_CTRL1, 0xc0 },
121
{ ADAV80X_DPATH_CTRL2, 0x11 },
122
{ ADAV80X_DAC_CTRL1, 0x00 },
123
{ ADAV80X_DAC_CTRL2, 0x00 },
124
{ ADAV80X_DAC_CTRL3, 0x00 },
125
{ ADAV80X_DAC_L_VOL, 0xff },
126
{ ADAV80X_DAC_R_VOL, 0xff },
127
{ ADAV80X_PGA_L_VOL, 0x00 },
128
{ ADAV80X_PGA_R_VOL, 0x00 },
129
{ ADAV80X_ADC_CTRL1, 0x00 },
130
{ ADAV80X_ADC_CTRL2, 0x00 },
131
{ ADAV80X_ADC_L_VOL, 0xff },
132
{ ADAV80X_ADC_R_VOL, 0xff },
133
{ ADAV80X_PLL_CTRL1, 0x00 },
134
{ ADAV80X_PLL_CTRL2, 0x00 },
135
{ ADAV80X_ICLK_CTRL1, 0x00 },
136
{ ADAV80X_ICLK_CTRL2, 0x00 },
137
{ ADAV80X_PLL_CLK_SRC, 0x00 },
138
{ ADAV80X_PLL_OUTE, 0x00 },
139
};
140
141
struct adav80x {
142
struct regmap *regmap;
143
144
enum adav80x_clk_src clk_src;
145
unsigned int sysclk;
146
enum adav80x_pll_src pll_src;
147
148
unsigned int dai_fmt[2];
149
unsigned int rate;
150
bool deemph;
151
bool sysclk_pd[3];
152
};
153
154
static const char *adav80x_mux_text[] = {
155
"ADC",
156
"Playback",
157
"Aux Playback",
158
};
159
160
static const unsigned int adav80x_mux_values[] = {
161
0, 2, 3,
162
};
163
164
#define ADAV80X_MUX_ENUM_DECL(name, reg, shift) \
165
SOC_VALUE_ENUM_DOUBLE_DECL(name, reg, shift, 7, \
166
ARRAY_SIZE(adav80x_mux_text), adav80x_mux_text, \
167
adav80x_mux_values)
168
169
static ADAV80X_MUX_ENUM_DECL(adav80x_aux_capture_enum, ADAV80X_DPATH_CTRL1, 0);
170
static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3);
171
static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3);
172
173
static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl =
174
SOC_DAPM_ENUM("Route", adav80x_aux_capture_enum);
175
static const struct snd_kcontrol_new adav80x_capture_mux_ctrl =
176
SOC_DAPM_ENUM("Route", adav80x_capture_enum);
177
static const struct snd_kcontrol_new adav80x_dac_mux_ctrl =
178
SOC_DAPM_ENUM("Route", adav80x_dac_enum);
179
180
#define ADAV80X_MUX(name, ctrl) \
181
SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
182
183
static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = {
184
SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1),
185
SND_SOC_DAPM_ADC("ADC", NULL, ADAV80X_ADC_CTRL1, 5, 1),
186
187
SND_SOC_DAPM_PGA("Right PGA", ADAV80X_ADC_CTRL1, 0, 1, NULL, 0),
188
SND_SOC_DAPM_PGA("Left PGA", ADAV80X_ADC_CTRL1, 1, 1, NULL, 0),
189
190
SND_SOC_DAPM_AIF_OUT("AIFOUT", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
191
SND_SOC_DAPM_AIF_IN("AIFIN", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
192
193
SND_SOC_DAPM_AIF_OUT("AIFAUXOUT", "Aux Capture", 0, SND_SOC_NOPM, 0, 0),
194
SND_SOC_DAPM_AIF_IN("AIFAUXIN", "Aux Playback", 0, SND_SOC_NOPM, 0, 0),
195
196
ADAV80X_MUX("Aux Capture Select", &adav80x_aux_capture_mux_ctrl),
197
ADAV80X_MUX("Capture Select", &adav80x_capture_mux_ctrl),
198
ADAV80X_MUX("DAC Select", &adav80x_dac_mux_ctrl),
199
200
SND_SOC_DAPM_INPUT("VINR"),
201
SND_SOC_DAPM_INPUT("VINL"),
202
SND_SOC_DAPM_OUTPUT("VOUTR"),
203
SND_SOC_DAPM_OUTPUT("VOUTL"),
204
205
SND_SOC_DAPM_SUPPLY("SYSCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
206
SND_SOC_DAPM_SUPPLY("PLL1", ADAV80X_PLL_CTRL1, 2, 1, NULL, 0),
207
SND_SOC_DAPM_SUPPLY("PLL2", ADAV80X_PLL_CTRL1, 3, 1, NULL, 0),
208
SND_SOC_DAPM_SUPPLY("OSC", ADAV80X_PLL_CTRL1, 1, 1, NULL, 0),
209
};
210
211
static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
212
struct snd_soc_dapm_widget *sink)
213
{
214
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
215
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
216
const char *clk;
217
218
switch (adav80x->clk_src) {
219
case ADAV80X_CLK_PLL1:
220
clk = "PLL1";
221
break;
222
case ADAV80X_CLK_PLL2:
223
clk = "PLL2";
224
break;
225
case ADAV80X_CLK_XTAL:
226
clk = "OSC";
227
break;
228
default:
229
return 0;
230
}
231
232
return snd_soc_dapm_widget_name_cmp(source, clk) == 0;
233
}
234
235
static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,
236
struct snd_soc_dapm_widget *sink)
237
{
238
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
239
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
240
241
return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;
242
}
243
244
245
static const struct snd_soc_dapm_route adav80x_dapm_routes[] = {
246
{ "DAC Select", "ADC", "ADC" },
247
{ "DAC Select", "Playback", "AIFIN" },
248
{ "DAC Select", "Aux Playback", "AIFAUXIN" },
249
{ "DAC", NULL, "DAC Select" },
250
251
{ "Capture Select", "ADC", "ADC" },
252
{ "Capture Select", "Playback", "AIFIN" },
253
{ "Capture Select", "Aux Playback", "AIFAUXIN" },
254
{ "AIFOUT", NULL, "Capture Select" },
255
256
{ "Aux Capture Select", "ADC", "ADC" },
257
{ "Aux Capture Select", "Playback", "AIFIN" },
258
{ "Aux Capture Select", "Aux Playback", "AIFAUXIN" },
259
{ "AIFAUXOUT", NULL, "Aux Capture Select" },
260
261
{ "VOUTR", NULL, "DAC" },
262
{ "VOUTL", NULL, "DAC" },
263
264
{ "Left PGA", NULL, "VINL" },
265
{ "Right PGA", NULL, "VINR" },
266
{ "ADC", NULL, "Left PGA" },
267
{ "ADC", NULL, "Right PGA" },
268
269
{ "SYSCLK", NULL, "PLL1", adav80x_dapm_sysclk_check },
270
{ "SYSCLK", NULL, "PLL2", adav80x_dapm_sysclk_check },
271
{ "SYSCLK", NULL, "OSC", adav80x_dapm_sysclk_check },
272
{ "PLL1", NULL, "OSC", adav80x_dapm_pll_check },
273
{ "PLL2", NULL, "OSC", adav80x_dapm_pll_check },
274
275
{ "ADC", NULL, "SYSCLK" },
276
{ "DAC", NULL, "SYSCLK" },
277
{ "AIFOUT", NULL, "SYSCLK" },
278
{ "AIFAUXOUT", NULL, "SYSCLK" },
279
{ "AIFIN", NULL, "SYSCLK" },
280
{ "AIFAUXIN", NULL, "SYSCLK" },
281
};
282
283
static int adav80x_set_deemph(struct snd_soc_component *component)
284
{
285
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
286
unsigned int val;
287
288
if (adav80x->deemph) {
289
switch (adav80x->rate) {
290
case 32000:
291
val = ADAV80X_DAC_CTRL2_DEEMPH_32;
292
break;
293
case 44100:
294
val = ADAV80X_DAC_CTRL2_DEEMPH_44;
295
break;
296
case 48000:
297
case 64000:
298
case 88200:
299
case 96000:
300
val = ADAV80X_DAC_CTRL2_DEEMPH_48;
301
break;
302
default:
303
val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
304
break;
305
}
306
} else {
307
val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
308
}
309
310
return regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2,
311
ADAV80X_DAC_CTRL2_DEEMPH_MASK, val);
312
}
313
314
static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
315
struct snd_ctl_elem_value *ucontrol)
316
{
317
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
318
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
319
unsigned int deemph = ucontrol->value.integer.value[0];
320
321
if (deemph > 1)
322
return -EINVAL;
323
324
adav80x->deemph = deemph;
325
326
return adav80x_set_deemph(component);
327
}
328
329
static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
330
struct snd_ctl_elem_value *ucontrol)
331
{
332
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
333
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
334
335
ucontrol->value.integer.value[0] = adav80x->deemph;
336
return 0;
337
};
338
339
static const DECLARE_TLV_DB_SCALE(adav80x_inpga_tlv, 0, 50, 0);
340
static const DECLARE_TLV_DB_MINMAX(adav80x_digital_tlv, -9563, 0);
341
342
static const struct snd_kcontrol_new adav80x_controls[] = {
343
SOC_DOUBLE_R_TLV("Master Playback Volume", ADAV80X_DAC_L_VOL,
344
ADAV80X_DAC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
345
SOC_DOUBLE_R_TLV("Master Capture Volume", ADAV80X_ADC_L_VOL,
346
ADAV80X_ADC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
347
348
SOC_DOUBLE_R_TLV("PGA Capture Volume", ADAV80X_PGA_L_VOL,
349
ADAV80X_PGA_R_VOL, 0, 0x30, 0, adav80x_inpga_tlv),
350
351
SOC_DOUBLE("Master Playback Switch", ADAV80X_DAC_CTRL1, 0, 1, 1, 0),
352
SOC_DOUBLE("Master Capture Switch", ADAV80X_ADC_CTRL1, 2, 3, 1, 1),
353
354
SOC_SINGLE("ADC High Pass Filter Switch", ADAV80X_ADC_CTRL1, 6, 1, 0),
355
356
SOC_SINGLE_BOOL_EXT("Playback De-emphasis Switch", 0,
357
adav80x_get_deemph, adav80x_put_deemph),
358
};
359
360
static unsigned int adav80x_port_ctrl_regs[2][2] = {
361
{ ADAV80X_REC_CTRL, ADAV80X_PLAYBACK_CTRL, },
362
{ ADAV80X_AUX_OUT_CTRL, ADAV80X_AUX_IN_CTRL },
363
};
364
365
static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
366
{
367
struct snd_soc_component *component = dai->component;
368
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
369
unsigned int capture = 0x00;
370
unsigned int playback = 0x00;
371
372
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
373
case SND_SOC_DAIFMT_CBP_CFP:
374
capture |= ADAV80X_CAPTURE_MODE_MASTER;
375
playback |= ADAV80X_PLAYBACK_MODE_MASTER;
376
break;
377
case SND_SOC_DAIFMT_CBC_CFC:
378
break;
379
default:
380
return -EINVAL;
381
}
382
383
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
384
case SND_SOC_DAIFMT_I2S:
385
capture |= ADAV80X_CAPTURE_MODE_I2S;
386
playback |= ADAV80X_PLAYBACK_MODE_I2S;
387
break;
388
case SND_SOC_DAIFMT_LEFT_J:
389
capture |= ADAV80X_CAPTURE_MODE_LEFT_J;
390
playback |= ADAV80X_PLAYBACK_MODE_LEFT_J;
391
break;
392
case SND_SOC_DAIFMT_RIGHT_J:
393
capture |= ADAV80X_CAPTURE_MODE_RIGHT_J;
394
playback |= ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
395
break;
396
default:
397
return -EINVAL;
398
}
399
400
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
401
case SND_SOC_DAIFMT_NB_NF:
402
break;
403
default:
404
return -EINVAL;
405
}
406
407
regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0],
408
ADAV80X_CAPTURE_MODE_MASK | ADAV80X_CAPTURE_MODE_MASTER,
409
capture);
410
regmap_write(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1],
411
playback);
412
413
adav80x->dai_fmt[dai->id] = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
414
415
return 0;
416
}
417
418
static int adav80x_set_adc_clock(struct snd_soc_component *component,
419
unsigned int sample_rate)
420
{
421
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
422
unsigned int val;
423
424
if (sample_rate <= 48000)
425
val = ADAV80X_ADC_CTRL1_MODULATOR_128FS;
426
else
427
val = ADAV80X_ADC_CTRL1_MODULATOR_64FS;
428
429
regmap_update_bits(adav80x->regmap, ADAV80X_ADC_CTRL1,
430
ADAV80X_ADC_CTRL1_MODULATOR_MASK, val);
431
432
return 0;
433
}
434
435
static int adav80x_set_dac_clock(struct snd_soc_component *component,
436
unsigned int sample_rate)
437
{
438
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
439
unsigned int val;
440
441
if (sample_rate <= 48000)
442
val = ADAV80X_DAC_CTRL2_DIV1 | ADAV80X_DAC_CTRL2_INTERPOL_256FS;
443
else
444
val = ADAV80X_DAC_CTRL2_DIV2 | ADAV80X_DAC_CTRL2_INTERPOL_128FS;
445
446
regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2,
447
ADAV80X_DAC_CTRL2_DIV_MASK | ADAV80X_DAC_CTRL2_INTERPOL_MASK,
448
val);
449
450
return 0;
451
}
452
453
static int adav80x_set_capture_pcm_format(struct snd_soc_component *component,
454
struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
455
{
456
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
457
unsigned int val;
458
459
switch (params_width(params)) {
460
case 16:
461
val = ADAV80X_CAPTURE_WORD_LEN16;
462
break;
463
case 18:
464
val = ADAV80X_CAPTRUE_WORD_LEN18;
465
break;
466
case 20:
467
val = ADAV80X_CAPTURE_WORD_LEN20;
468
break;
469
case 24:
470
val = ADAV80X_CAPTURE_WORD_LEN24;
471
break;
472
default:
473
return -EINVAL;
474
}
475
476
regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0],
477
ADAV80X_CAPTURE_WORD_LEN_MASK, val);
478
479
return 0;
480
}
481
482
static int adav80x_set_playback_pcm_format(struct snd_soc_component *component,
483
struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)
484
{
485
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
486
unsigned int val;
487
488
if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
489
return 0;
490
491
switch (params_width(params)) {
492
case 16:
493
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;
494
break;
495
case 18:
496
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;
497
break;
498
case 20:
499
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;
500
break;
501
case 24:
502
val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
503
break;
504
default:
505
return -EINVAL;
506
}
507
508
regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1],
509
ADAV80X_PLAYBACK_MODE_MASK, val);
510
511
return 0;
512
}
513
514
static int adav80x_hw_params(struct snd_pcm_substream *substream,
515
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
516
{
517
struct snd_soc_component *component = dai->component;
518
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
519
unsigned int rate = params_rate(params);
520
521
if (rate * 256 != adav80x->sysclk)
522
return -EINVAL;
523
524
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
525
adav80x_set_playback_pcm_format(component, dai, params);
526
adav80x_set_dac_clock(component, rate);
527
} else {
528
adav80x_set_capture_pcm_format(component, dai, params);
529
adav80x_set_adc_clock(component, rate);
530
}
531
adav80x->rate = rate;
532
adav80x_set_deemph(component);
533
534
return 0;
535
}
536
537
static int adav80x_set_sysclk(struct snd_soc_component *component,
538
int clk_id, int source,
539
unsigned int freq, int dir)
540
{
541
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
542
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
543
544
if (dir == SND_SOC_CLOCK_IN) {
545
switch (clk_id) {
546
case ADAV80X_CLK_XIN:
547
case ADAV80X_CLK_XTAL:
548
case ADAV80X_CLK_MCLKI:
549
case ADAV80X_CLK_PLL1:
550
case ADAV80X_CLK_PLL2:
551
break;
552
default:
553
return -EINVAL;
554
}
555
556
adav80x->sysclk = freq;
557
558
if (adav80x->clk_src != clk_id) {
559
unsigned int iclk_ctrl1, iclk_ctrl2;
560
561
adav80x->clk_src = clk_id;
562
if (clk_id == ADAV80X_CLK_XTAL)
563
clk_id = ADAV80X_CLK_XIN;
564
565
iclk_ctrl1 = ADAV80X_ICLK_CTRL1_DAC_SRC(clk_id) |
566
ADAV80X_ICLK_CTRL1_ADC_SRC(clk_id) |
567
ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id);
568
iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id);
569
570
regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL1,
571
iclk_ctrl1);
572
regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2,
573
iclk_ctrl2);
574
575
snd_soc_dapm_sync(dapm);
576
}
577
} else {
578
unsigned int mask;
579
580
switch (clk_id) {
581
case ADAV80X_CLK_SYSCLK1:
582
case ADAV80X_CLK_SYSCLK2:
583
case ADAV80X_CLK_SYSCLK3:
584
break;
585
default:
586
return -EINVAL;
587
}
588
589
clk_id -= ADAV80X_CLK_SYSCLK1;
590
mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id);
591
592
if (freq == 0) {
593
regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE,
594
mask, mask);
595
adav80x->sysclk_pd[clk_id] = true;
596
} else {
597
regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE,
598
mask, 0);
599
adav80x->sysclk_pd[clk_id] = false;
600
}
601
602
snd_soc_dapm_mutex_lock(dapm);
603
604
if (adav80x->sysclk_pd[0])
605
snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1");
606
else
607
snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1");
608
609
if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
610
snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2");
611
else
612
snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2");
613
614
snd_soc_dapm_sync_unlocked(dapm);
615
616
snd_soc_dapm_mutex_unlock(dapm);
617
}
618
619
return 0;
620
}
621
622
static int adav80x_set_pll(struct snd_soc_component *component, int pll_id,
623
int source, unsigned int freq_in, unsigned int freq_out)
624
{
625
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
626
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
627
unsigned int pll_ctrl1 = 0;
628
unsigned int pll_ctrl2 = 0;
629
unsigned int pll_src;
630
631
switch (source) {
632
case ADAV80X_PLL_SRC_XTAL:
633
case ADAV80X_PLL_SRC_XIN:
634
case ADAV80X_PLL_SRC_MCLKI:
635
break;
636
default:
637
return -EINVAL;
638
}
639
640
if (!freq_out)
641
return 0;
642
643
switch (freq_in) {
644
case 27000000:
645
break;
646
case 54000000:
647
if (source == ADAV80X_PLL_SRC_XIN) {
648
pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV;
649
break;
650
}
651
fallthrough;
652
default:
653
return -EINVAL;
654
}
655
656
if (freq_out > 12288000) {
657
pll_ctrl2 |= ADAV80X_PLL_CTRL2_DOUB(pll_id);
658
freq_out /= 2;
659
}
660
661
/* freq_out = sample_rate * 256 */
662
switch (freq_out) {
663
case 8192000:
664
pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_32(pll_id);
665
break;
666
case 11289600:
667
pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_44(pll_id);
668
break;
669
case 12288000:
670
pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_48(pll_id);
671
break;
672
default:
673
return -EINVAL;
674
}
675
676
regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL1,
677
ADAV80X_PLL_CTRL1_PLLDIV, pll_ctrl1);
678
regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL2,
679
ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2);
680
681
if (source != adav80x->pll_src) {
682
if (source == ADAV80X_PLL_SRC_MCLKI)
683
pll_src = ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll_id);
684
else
685
pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id);
686
687
regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CLK_SRC,
688
ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src);
689
690
adav80x->pll_src = source;
691
692
snd_soc_dapm_sync(dapm);
693
}
694
695
return 0;
696
}
697
698
static int adav80x_set_bias_level(struct snd_soc_component *component,
699
enum snd_soc_bias_level level)
700
{
701
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
702
unsigned int mask = ADAV80X_DAC_CTRL1_PD;
703
704
switch (level) {
705
case SND_SOC_BIAS_ON:
706
break;
707
case SND_SOC_BIAS_PREPARE:
708
break;
709
case SND_SOC_BIAS_STANDBY:
710
regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask,
711
0x00);
712
break;
713
case SND_SOC_BIAS_OFF:
714
regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask,
715
mask);
716
break;
717
}
718
719
return 0;
720
}
721
722
/* Enforce the same sample rate on all audio interfaces */
723
static int adav80x_dai_startup(struct snd_pcm_substream *substream,
724
struct snd_soc_dai *dai)
725
{
726
struct snd_soc_component *component = dai->component;
727
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
728
729
if (!snd_soc_component_active(component) || !adav80x->rate)
730
return 0;
731
732
return snd_pcm_hw_constraint_single(substream->runtime,
733
SNDRV_PCM_HW_PARAM_RATE, adav80x->rate);
734
}
735
736
static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
737
struct snd_soc_dai *dai)
738
{
739
struct snd_soc_component *component = dai->component;
740
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
741
742
if (!snd_soc_component_active(component))
743
adav80x->rate = 0;
744
}
745
746
static const struct snd_soc_dai_ops adav80x_dai_ops = {
747
.set_fmt = adav80x_set_dai_fmt,
748
.hw_params = adav80x_hw_params,
749
.startup = adav80x_dai_startup,
750
.shutdown = adav80x_dai_shutdown,
751
};
752
753
#define ADAV80X_PLAYBACK_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
754
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | \
755
SNDRV_PCM_RATE_96000)
756
757
#define ADAV80X_CAPTURE_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
758
759
#define ADAV80X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
760
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
761
762
static struct snd_soc_dai_driver adav80x_dais[] = {
763
{
764
.name = "adav80x-hifi",
765
.id = 0,
766
.playback = {
767
.stream_name = "HiFi Playback",
768
.channels_min = 2,
769
.channels_max = 2,
770
.rates = ADAV80X_PLAYBACK_RATES,
771
.formats = ADAV80X_FORMATS,
772
},
773
.capture = {
774
.stream_name = "HiFi Capture",
775
.channels_min = 2,
776
.channels_max = 2,
777
.rates = ADAV80X_CAPTURE_RATES,
778
.formats = ADAV80X_FORMATS,
779
},
780
.ops = &adav80x_dai_ops,
781
},
782
{
783
.name = "adav80x-aux",
784
.id = 1,
785
.playback = {
786
.stream_name = "Aux Playback",
787
.channels_min = 2,
788
.channels_max = 2,
789
.rates = ADAV80X_PLAYBACK_RATES,
790
.formats = ADAV80X_FORMATS,
791
},
792
.capture = {
793
.stream_name = "Aux Capture",
794
.channels_min = 2,
795
.channels_max = 2,
796
.rates = ADAV80X_CAPTURE_RATES,
797
.formats = ADAV80X_FORMATS,
798
},
799
.ops = &adav80x_dai_ops,
800
},
801
};
802
803
static int adav80x_probe(struct snd_soc_component *component)
804
{
805
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
806
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
807
808
/* Force PLLs on for SYSCLK output */
809
snd_soc_dapm_force_enable_pin(dapm, "PLL1");
810
snd_soc_dapm_force_enable_pin(dapm, "PLL2");
811
812
/* Power down S/PDIF receiver, since it is currently not supported */
813
regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20);
814
/* Disable DAC zero flag */
815
regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6);
816
817
return 0;
818
}
819
820
static int adav80x_resume(struct snd_soc_component *component)
821
{
822
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
823
824
regcache_sync(adav80x->regmap);
825
826
return 0;
827
}
828
829
static const struct snd_soc_component_driver adav80x_component_driver = {
830
.probe = adav80x_probe,
831
.resume = adav80x_resume,
832
.set_bias_level = adav80x_set_bias_level,
833
.set_pll = adav80x_set_pll,
834
.set_sysclk = adav80x_set_sysclk,
835
.controls = adav80x_controls,
836
.num_controls = ARRAY_SIZE(adav80x_controls),
837
.dapm_widgets = adav80x_dapm_widgets,
838
.num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets),
839
.dapm_routes = adav80x_dapm_routes,
840
.num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
841
.suspend_bias_off = 1,
842
.idle_bias_on = 1,
843
.use_pmdown_time = 1,
844
.endianness = 1,
845
};
846
847
int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
848
{
849
struct adav80x *adav80x;
850
851
if (IS_ERR(regmap))
852
return PTR_ERR(regmap);
853
854
adav80x = devm_kzalloc(dev, sizeof(*adav80x), GFP_KERNEL);
855
if (!adav80x)
856
return -ENOMEM;
857
858
dev_set_drvdata(dev, adav80x);
859
adav80x->regmap = regmap;
860
861
return devm_snd_soc_register_component(dev, &adav80x_component_driver,
862
adav80x_dais, ARRAY_SIZE(adav80x_dais));
863
}
864
EXPORT_SYMBOL_GPL(adav80x_bus_probe);
865
866
const struct regmap_config adav80x_regmap_config = {
867
.val_bits = 8,
868
.pad_bits = 1,
869
.reg_bits = 7,
870
871
.max_register = ADAV80X_PLL_OUTE,
872
873
.cache_type = REGCACHE_MAPLE,
874
.reg_defaults = adav80x_reg_defaults,
875
.num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),
876
};
877
EXPORT_SYMBOL_GPL(adav80x_regmap_config);
878
879
MODULE_DESCRIPTION("ASoC ADAV80x driver");
880
MODULE_AUTHOR("Lars-Peter Clausen <[email protected]>");
881
MODULE_AUTHOR("Yi Li <[email protected]>>");
882
MODULE_LICENSE("GPL");
883
884