1 // SPDX-License-Identifier: GPL-2.0
3 // Analog Devices ADAU7118 8 channel PDM-to-I2S/TDM Converter driver
5 // Copyright 2019 Analog Devices Inc.
7 #include <linux/bitfield.h>
8 #include <linux/module.h>
9 #include <linux/regmap.h>
10 #include <linux/regulator/consumer.h>
11 #include <sound/pcm_params.h>
12 #include <sound/soc.h>
16 #define ADAU7118_DEC_RATIO_MASK GENMASK(1, 0)
17 #define ADAU7118_DEC_RATIO(x) FIELD_PREP(ADAU7118_DEC_RATIO_MASK, x)
18 #define ADAU7118_CLK_MAP_MASK GENMASK(7, 4)
19 #define ADAU7118_SLOT_WIDTH_MASK GENMASK(5, 4)
20 #define ADAU7118_SLOT_WIDTH(x) FIELD_PREP(ADAU7118_SLOT_WIDTH_MASK, x)
21 #define ADAU7118_TRISTATE_MASK BIT(6)
22 #define ADAU7118_TRISTATE(x) FIELD_PREP(ADAU7118_TRISTATE_MASK, x)
23 #define ADAU7118_DATA_FMT_MASK GENMASK(3, 1)
24 #define ADAU7118_DATA_FMT(x) FIELD_PREP(ADAU7118_DATA_FMT_MASK, x)
25 #define ADAU7118_SAI_MODE_MASK BIT(0)
26 #define ADAU7118_SAI_MODE(x) FIELD_PREP(ADAU7118_SAI_MODE_MASK, x)
27 #define ADAU7118_LRCLK_BCLK_POL_MASK GENMASK(1, 0)
28 #define ADAU7118_LRCLK_BCLK_POL(x) \
29 FIELD_PREP(ADAU7118_LRCLK_BCLK_POL_MASK, x)
30 #define ADAU7118_SPT_SLOT_MASK GENMASK(7, 4)
31 #define ADAU7118_SPT_SLOT(x) FIELD_PREP(ADAU7118_SPT_SLOT_MASK, x)
32 #define ADAU7118_FULL_SOFT_R_MASK BIT(1)
33 #define ADAU7118_FULL_SOFT_R(x) FIELD_PREP(ADAU7118_FULL_SOFT_R_MASK, x)
35 struct adau7118_data
{
38 struct regulator
*iovdd
;
39 struct regulator
*dvdd
;
47 static const struct snd_kcontrol_new adau7118_dapm_pdm_control
[4] = {
48 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES
, 0, 1, 0),
49 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES
, 1, 1, 0),
50 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES
, 2, 1, 0),
51 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES
, 3, 1, 0),
54 static const struct snd_soc_dapm_widget adau7118_widgets_sw
[] = {
55 /* Input Enable Switches */
56 SND_SOC_DAPM_SWITCH("PDM0", SND_SOC_NOPM
, 0, 0,
57 &adau7118_dapm_pdm_control
[0]),
58 SND_SOC_DAPM_SWITCH("PDM1", SND_SOC_NOPM
, 0, 0,
59 &adau7118_dapm_pdm_control
[1]),
60 SND_SOC_DAPM_SWITCH("PDM2", SND_SOC_NOPM
, 0, 0,
61 &adau7118_dapm_pdm_control
[2]),
62 SND_SOC_DAPM_SWITCH("PDM3", SND_SOC_NOPM
, 0, 0,
63 &adau7118_dapm_pdm_control
[3]),
66 SND_SOC_DAPM_SUPPLY("PDM_CLK0", ADAU7118_REG_ENABLES
, 4, 0, NULL
, 0),
67 SND_SOC_DAPM_SUPPLY("PDM_CLK1", ADAU7118_REG_ENABLES
, 5, 0, NULL
, 0),
70 SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, ADAU7118_REG_SPT_CX(0),
72 SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 0, ADAU7118_REG_SPT_CX(1),
74 SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 0, ADAU7118_REG_SPT_CX(2),
76 SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 0, ADAU7118_REG_SPT_CX(3),
78 SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 0, ADAU7118_REG_SPT_CX(4),
80 SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 0, ADAU7118_REG_SPT_CX(5),
82 SND_SOC_DAPM_AIF_OUT("AIF1TX7", "Capture", 0, ADAU7118_REG_SPT_CX(6),
84 SND_SOC_DAPM_AIF_OUT("AIF1TX8", "Capture", 0, ADAU7118_REG_SPT_CX(7),
88 static const struct snd_soc_dapm_route adau7118_routes_sw
[] = {
89 { "PDM0", "Capture Switch", "PDM_DAT0" },
90 { "PDM1", "Capture Switch", "PDM_DAT1" },
91 { "PDM2", "Capture Switch", "PDM_DAT2" },
92 { "PDM3", "Capture Switch", "PDM_DAT3" },
93 { "AIF1TX1", NULL
, "PDM0" },
94 { "AIF1TX2", NULL
, "PDM0" },
95 { "AIF1TX3", NULL
, "PDM1" },
96 { "AIF1TX4", NULL
, "PDM1" },
97 { "AIF1TX5", NULL
, "PDM2" },
98 { "AIF1TX6", NULL
, "PDM2" },
99 { "AIF1TX7", NULL
, "PDM3" },
100 { "AIF1TX8", NULL
, "PDM3" },
101 { "Capture", NULL
, "PDM_CLK0" },
102 { "Capture", NULL
, "PDM_CLK1" },
105 static const struct snd_soc_dapm_widget adau7118_widgets_hw
[] = {
106 SND_SOC_DAPM_AIF_OUT("AIF1TX", "Capture", 0, SND_SOC_NOPM
, 0, 0),
109 static const struct snd_soc_dapm_route adau7118_routes_hw
[] = {
110 { "AIF1TX", NULL
, "PDM_DAT0" },
111 { "AIF1TX", NULL
, "PDM_DAT1" },
112 { "AIF1TX", NULL
, "PDM_DAT2" },
113 { "AIF1TX", NULL
, "PDM_DAT3" },
116 static const struct snd_soc_dapm_widget adau7118_widgets
[] = {
117 SND_SOC_DAPM_INPUT("PDM_DAT0"),
118 SND_SOC_DAPM_INPUT("PDM_DAT1"),
119 SND_SOC_DAPM_INPUT("PDM_DAT2"),
120 SND_SOC_DAPM_INPUT("PDM_DAT3"),
123 static int adau7118_set_channel_map(struct snd_soc_dai
*dai
,
124 unsigned int tx_num
, unsigned int *tx_slot
,
125 unsigned int rx_num
, unsigned int *rx_slot
)
127 struct adau7118_data
*st
=
128 snd_soc_component_get_drvdata(dai
->component
);
131 dev_dbg(st
->dev
, "Set channel map, %d", tx_num
);
133 for (chan
= 0; chan
< tx_num
; chan
++) {
134 ret
= snd_soc_component_update_bits(dai
->component
,
135 ADAU7118_REG_SPT_CX(chan
),
136 ADAU7118_SPT_SLOT_MASK
,
137 ADAU7118_SPT_SLOT(tx_slot
[chan
]));
145 static int adau7118_set_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
147 struct adau7118_data
*st
=
148 snd_soc_component_get_drvdata(dai
->component
);
152 dev_dbg(st
->dev
, "Set format, fmt:%d\n", fmt
);
154 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
155 case SND_SOC_DAIFMT_I2S
:
156 ret
= snd_soc_component_update_bits(dai
->component
,
157 ADAU7118_REG_SPT_CTRL1
,
158 ADAU7118_DATA_FMT_MASK
,
159 ADAU7118_DATA_FMT(0));
161 case SND_SOC_DAIFMT_LEFT_J
:
162 ret
= snd_soc_component_update_bits(dai
->component
,
163 ADAU7118_REG_SPT_CTRL1
,
164 ADAU7118_DATA_FMT_MASK
,
165 ADAU7118_DATA_FMT(1));
167 case SND_SOC_DAIFMT_RIGHT_J
:
171 dev_err(st
->dev
, "Invalid format %d",
172 fmt
& SND_SOC_DAIFMT_FORMAT_MASK
);
179 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
180 case SND_SOC_DAIFMT_NB_NF
:
181 regval
= ADAU7118_LRCLK_BCLK_POL(0);
183 case SND_SOC_DAIFMT_NB_IF
:
184 regval
= ADAU7118_LRCLK_BCLK_POL(2);
186 case SND_SOC_DAIFMT_IB_NF
:
187 regval
= ADAU7118_LRCLK_BCLK_POL(1);
189 case SND_SOC_DAIFMT_IB_IF
:
190 regval
= ADAU7118_LRCLK_BCLK_POL(3);
193 dev_err(st
->dev
, "Invalid Inv mask %d",
194 fmt
& SND_SOC_DAIFMT_INV_MASK
);
198 ret
= snd_soc_component_update_bits(dai
->component
,
199 ADAU7118_REG_SPT_CTRL2
,
200 ADAU7118_LRCLK_BCLK_POL_MASK
,
208 static int adau7118_set_tristate(struct snd_soc_dai
*dai
, int tristate
)
210 struct adau7118_data
*st
=
211 snd_soc_component_get_drvdata(dai
->component
);
214 dev_dbg(st
->dev
, "Set tristate, %d\n", tristate
);
216 ret
= snd_soc_component_update_bits(dai
->component
,
217 ADAU7118_REG_SPT_CTRL1
,
218 ADAU7118_TRISTATE_MASK
,
219 ADAU7118_TRISTATE(tristate
));
226 static int adau7118_set_tdm_slot(struct snd_soc_dai
*dai
, unsigned int tx_mask
,
227 unsigned int rx_mask
, int slots
,
230 struct adau7118_data
*st
=
231 snd_soc_component_get_drvdata(dai
->component
);
235 dev_dbg(st
->dev
, "Set tdm, slots:%d width:%d\n", slots
, slot_width
);
237 switch (slot_width
) {
239 regval
= ADAU7118_SLOT_WIDTH(0);
242 regval
= ADAU7118_SLOT_WIDTH(2);
245 regval
= ADAU7118_SLOT_WIDTH(1);
248 dev_err(st
->dev
, "Invalid slot width:%d\n", slot_width
);
252 ret
= snd_soc_component_update_bits(dai
->component
,
253 ADAU7118_REG_SPT_CTRL1
,
254 ADAU7118_SLOT_WIDTH_MASK
, regval
);
258 st
->slot_width
= slot_width
;
264 static int adau7118_hw_params(struct snd_pcm_substream
*substream
,
265 struct snd_pcm_hw_params
*params
,
266 struct snd_soc_dai
*dai
)
268 struct adau7118_data
*st
=
269 snd_soc_component_get_drvdata(dai
->component
);
270 u32 data_width
= params_width(params
), slots_width
;
275 /* set stereo mode */
276 ret
= snd_soc_component_update_bits(dai
->component
,
277 ADAU7118_REG_SPT_CTRL1
,
278 ADAU7118_SAI_MODE_MASK
,
279 ADAU7118_SAI_MODE(0));
285 slots_width
= st
->slot_width
;
288 if (data_width
> slots_width
) {
289 dev_err(st
->dev
, "Invalid data_width:%d, slots_width:%d",
290 data_width
, slots_width
);
295 switch (slots_width
- data_width
) {
297 /* delay bclck by 8 */
298 regval
= ADAU7118_DATA_FMT(2);
301 /* delay bclck by 12 */
302 regval
= ADAU7118_DATA_FMT(3);
305 /* delay bclck by 16 */
306 regval
= ADAU7118_DATA_FMT(4);
310 "Cannot set right_j setting, slot_w:%d, data_w:%d\n",
311 slots_width
, data_width
);
315 ret
= snd_soc_component_update_bits(dai
->component
,
316 ADAU7118_REG_SPT_CTRL1
,
317 ADAU7118_DATA_FMT_MASK
,
326 static int adau7118_set_bias_level(struct snd_soc_component
*component
,
327 enum snd_soc_bias_level level
)
329 struct adau7118_data
*st
= snd_soc_component_get_drvdata(component
);
332 dev_dbg(st
->dev
, "Set bias level %d\n", level
);
335 case SND_SOC_BIAS_ON
:
336 case SND_SOC_BIAS_PREPARE
:
339 case SND_SOC_BIAS_STANDBY
:
340 if (snd_soc_component_get_bias_level(component
) ==
343 ret
= regulator_enable(st
->iovdd
);
347 /* there's no timing constraints before enabling dvdd */
348 ret
= regulator_enable(st
->dvdd
);
350 regulator_disable(st
->iovdd
);
357 regcache_cache_only(st
->map
, false);
359 ret
= snd_soc_component_cache_sync(component
);
362 case SND_SOC_BIAS_OFF
:
364 ret
= regulator_disable(st
->dvdd
);
368 ret
= regulator_disable(st
->iovdd
);
376 regcache_mark_dirty(st
->map
);
377 regcache_cache_only(st
->map
, true);
385 static int adau7118_component_probe(struct snd_soc_component
*component
)
387 struct adau7118_data
*st
= snd_soc_component_get_drvdata(component
);
388 struct snd_soc_dapm_context
*dapm
=
389 snd_soc_component_get_dapm(component
);
393 ret
= snd_soc_dapm_new_controls(dapm
, adau7118_widgets_hw
,
394 ARRAY_SIZE(adau7118_widgets_hw
));
398 ret
= snd_soc_dapm_add_routes(dapm
, adau7118_routes_hw
,
399 ARRAY_SIZE(adau7118_routes_hw
));
401 snd_soc_component_init_regmap(component
, st
->map
);
402 ret
= snd_soc_dapm_new_controls(dapm
, adau7118_widgets_sw
,
403 ARRAY_SIZE(adau7118_widgets_sw
));
407 ret
= snd_soc_dapm_add_routes(dapm
, adau7118_routes_sw
,
408 ARRAY_SIZE(adau7118_routes_sw
));
414 static const struct snd_soc_dai_ops adau7118_ops
= {
415 .hw_params
= adau7118_hw_params
,
416 .set_channel_map
= adau7118_set_channel_map
,
417 .set_fmt
= adau7118_set_fmt
,
418 .set_tdm_slot
= adau7118_set_tdm_slot
,
419 .set_tristate
= adau7118_set_tristate
,
422 static struct snd_soc_dai_driver adau7118_dai
= {
423 .name
= "adau7118-hifi-capture",
425 .stream_name
= "Capture",
428 .formats
= SNDRV_PCM_FMTBIT_S16_LE
| SNDRV_PCM_FMTBIT_S20_3LE
|
429 SNDRV_PCM_FMTBIT_S20_LE
| SNDRV_PCM_FMTBIT_S24_LE
|
430 SNDRV_PCM_FMTBIT_S24_3LE
,
431 .rates
= SNDRV_PCM_RATE_CONTINUOUS
,
438 static const struct snd_soc_component_driver adau7118_component_driver
= {
439 .probe
= adau7118_component_probe
,
440 .set_bias_level
= adau7118_set_bias_level
,
441 .dapm_widgets
= adau7118_widgets
,
442 .num_dapm_widgets
= ARRAY_SIZE(adau7118_widgets
),
443 .use_pmdown_time
= 1,
445 .non_legacy_dai_naming
= 1,
448 static void adau7118_regulator_disable(void *data
)
450 struct adau7118_data
*st
= data
;
453 * If we fail to disable DVDD, don't bother in trying IOVDD. We
454 * actually don't want to be left in the situation where DVDD
455 * is enabled and IOVDD is disabled.
457 ret
= regulator_disable(st
->dvdd
);
461 regulator_disable(st
->iovdd
);
464 static int adau7118_regulator_setup(struct adau7118_data
*st
)
466 st
->iovdd
= devm_regulator_get(st
->dev
, "iovdd");
467 if (IS_ERR(st
->iovdd
)) {
468 dev_err(st
->dev
, "Could not get iovdd: %ld\n",
470 return PTR_ERR(st
->iovdd
);
473 st
->dvdd
= devm_regulator_get(st
->dev
, "dvdd");
474 if (IS_ERR(st
->dvdd
)) {
475 dev_err(st
->dev
, "Could not get dvdd: %ld\n",
477 return PTR_ERR(st
->dvdd
);
479 /* just assume the device is in reset */
481 regcache_mark_dirty(st
->map
);
482 regcache_cache_only(st
->map
, true);
485 return devm_add_action_or_reset(st
->dev
, adau7118_regulator_disable
,
489 static int adau7118_parset_dt(const struct adau7118_data
*st
)
494 u32 clk_map
[4], regval
;
499 ret
= device_property_read_u32(st
->dev
, "adi,decimation-ratio",
504 regval
= ADAU7118_DEC_RATIO(0);
507 regval
= ADAU7118_DEC_RATIO(1);
510 regval
= ADAU7118_DEC_RATIO(2);
513 dev_err(st
->dev
, "Invalid dec ratio: %u", dec_ratio
);
517 ret
= regmap_update_bits(st
->map
,
518 ADAU7118_REG_DEC_RATIO_CLK_MAP
,
519 ADAU7118_DEC_RATIO_MASK
, regval
);
524 ret
= device_property_read_u32_array(st
->dev
, "adi,pdm-clk-map",
525 clk_map
, ARRAY_SIZE(clk_map
));
530 for (pdm
= 0; pdm
< ARRAY_SIZE(clk_map
); pdm
++)
531 _clk_map
|= (clk_map
[pdm
] << (pdm
+ 4));
533 ret
= regmap_update_bits(st
->map
,
534 ADAU7118_REG_DEC_RATIO_CLK_MAP
,
535 ADAU7118_CLK_MAP_MASK
, _clk_map
);
543 int adau7118_probe(struct device
*dev
, struct regmap
*map
, bool hw_mode
)
545 struct adau7118_data
*st
;
548 st
= devm_kzalloc(dev
, sizeof(*st
), GFP_KERNEL
);
553 st
->hw_mode
= hw_mode
;
554 dev_set_drvdata(dev
, st
);
558 adau7118_dai
.ops
= &adau7118_ops
;
560 * Perform a full soft reset. This will set all register's
561 * with their reset values.
563 ret
= regmap_update_bits(map
, ADAU7118_REG_RESET
,
564 ADAU7118_FULL_SOFT_R_MASK
,
565 ADAU7118_FULL_SOFT_R(1));
570 ret
= adau7118_parset_dt(st
);
574 ret
= adau7118_regulator_setup(st
);
578 return devm_snd_soc_register_component(dev
,
579 &adau7118_component_driver
,
582 EXPORT_SYMBOL_GPL(adau7118_probe
);
584 MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
585 MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver");
586 MODULE_LICENSE("GPL");