1 // SPDX-License-Identifier: GPL-2.0-only
3 // Copyright(c) 2020 Intel Corporation. All rights reserved.
5 #include <linux/device.h>
6 #include <linux/kernel.h>
8 #include <sound/pcm_params.h>
10 #include <sound/soc-dai.h>
11 #include <sound/soc-dapm.h>
12 #include <uapi/sound/asound.h>
13 #include "../../codecs/rt1011.h"
14 #include "sof_realtek_common.h"
17 * Current only 2-amp configuration is supported for rt1011
19 static const struct snd_soc_dapm_route rt1011_dapm_routes
[] = {
21 { "Left Spk", NULL
, "Left SPO" },
22 { "Right Spk", NULL
, "Right SPO" },
26 * Make sure device's Unique ID follows this configuration:
31 * 0: Woofer left, 1: Woofer right
32 * 2: Tweeter left, 3: Tweeter right
34 static struct snd_soc_codec_conf rt1011_codec_confs
[] = {
36 .dlc
= COMP_CODEC_CONF(RT1011_DEV0_NAME
),
37 .name_prefix
= "Left",
40 .dlc
= COMP_CODEC_CONF(RT1011_DEV1_NAME
),
41 .name_prefix
= "Right",
45 static struct snd_soc_dai_link_component rt1011_dai_link_components
[] = {
47 .name
= RT1011_DEV0_NAME
,
48 .dai_name
= RT1011_CODEC_DAI
,
51 .name
= RT1011_DEV1_NAME
,
52 .dai_name
= RT1011_CODEC_DAI
,
59 } rt1011_tdm_mask
[] = {
60 {.tx
= 0x4, .rx
= 0x1},
61 {.tx
= 0x8, .rx
= 0x2},
64 static int rt1011_hw_params(struct snd_pcm_substream
*substream
,
65 struct snd_pcm_hw_params
*params
)
67 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
68 struct snd_soc_dai
*codec_dai
;
69 int srate
, i
, ret
= 0;
71 srate
= params_rate(params
);
73 for_each_rtd_codec_dais(rtd
, i
, codec_dai
) {
74 /* 100 Fs to drive 24 bit data */
75 ret
= snd_soc_dai_set_pll(codec_dai
, 0, RT1011_PLL1_S_BCLK
,
76 100 * srate
, 256 * srate
);
78 dev_err(codec_dai
->dev
, "fail to set pll, ret %d\n",
83 ret
= snd_soc_dai_set_sysclk(codec_dai
, RT1011_FS_SYS_PRE_S_PLL1
,
84 256 * srate
, SND_SOC_CLOCK_IN
);
86 dev_err(codec_dai
->dev
, "fail to set sysclk, ret %d\n",
91 if (i
>= ARRAY_SIZE(rt1011_tdm_mask
)) {
92 dev_err(codec_dai
->dev
, "invalid codec index %d\n",
97 ret
= snd_soc_dai_set_tdm_slot(codec_dai
, rt1011_tdm_mask
[i
].tx
,
98 rt1011_tdm_mask
[i
].rx
, 4,
99 params_width(params
));
101 dev_err(codec_dai
->dev
, "fail to set tdm slot, ret %d\n",
110 static const struct snd_soc_ops rt1011_ops
= {
111 .hw_params
= rt1011_hw_params
,
114 static int rt1011_init(struct snd_soc_pcm_runtime
*rtd
)
116 struct snd_soc_card
*card
= rtd
->card
;
119 ret
= snd_soc_dapm_add_routes(&card
->dapm
, rt1011_dapm_routes
,
120 ARRAY_SIZE(rt1011_dapm_routes
));
122 dev_err(rtd
->dev
, "Speaker map addition failed: %d\n", ret
);
126 void sof_rt1011_dai_link(struct snd_soc_dai_link
*link
)
128 link
->codecs
= rt1011_dai_link_components
;
129 link
->num_codecs
= ARRAY_SIZE(rt1011_dai_link_components
);
130 link
->init
= rt1011_init
;
131 link
->ops
= &rt1011_ops
;
134 void sof_rt1011_codec_conf(struct snd_soc_card
*card
)
136 card
->codec_conf
= rt1011_codec_confs
;
137 card
->num_configs
= ARRAY_SIZE(rt1011_codec_confs
);