1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the people's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 #include <aw-alsa-lib/pcm_config.h>
34 #include <aw-alsa-lib/pcm_plugin.h>
35 
36 #define SND_PCM_HW_CONFIG(name, device) \
37 { \
38     .card_name  = #name,  \
39     .device_num = device, \
40 }
41 
42 #define DEFINE_SND_PCM_HW_CONFIG(name, device) \
43     const snd_pcm_hw_config_t snd_##name##_hw_config = \
44                 SND_PCM_HW_CONFIG(name, device);
45 
46 static DEFINE_SND_PCM_HW_CONFIG(audiocodec, 0);
47 static DEFINE_SND_PCM_HW_CONFIG(snddaudio0, 0);
48 static DEFINE_SND_PCM_HW_CONFIG(snddaudio1, 0);
49 static DEFINE_SND_PCM_HW_CONFIG(snddaudio2, 0);
50 static DEFINE_SND_PCM_HW_CONFIG(snddaudio3, 0);
51 static DEFINE_SND_PCM_HW_CONFIG(snddmic, 0);
52 static DEFINE_SND_PCM_HW_CONFIG(sndspdif, 0);
53 
54 static const snd_pcm_softvol_config_t snd_pcm_softvol_config1 = {
55     .type       = "softvol",
56     .slave = {
57         .pcm        = "PlaybackDmix",
58     },
59     .control = {
60         .control_name   = "Soft Volume Control1",
61         .card_name  = "audiocodec",
62     },
63     .min_dB         = -51.0,
64     .max_dB         = 0.0,
65     .resolution     = 256,
66 };
67 
68 static const snd_pcm_softvol_config_t snd_pcm_softvol_config2 = {
69     .type       = "softvol",
70     .slave = {
71         .pcm        = "PlaybackDmix",
72     },
73     .control = {
74         .control_name   = "Soft Volume Control2",
75         .card_name  = "audiocodec",
76     },
77     .min_dB         = -51.0,
78     .max_dB         = 0.0,
79     .resolution     = 100,
80 };
81 
82 static const snd_pcm_dsnoop_config_t snd_pcm_dsnoop_config = {
83     .type       = "dsnoop",
84     .ipc_key    = 1111,
85     .slave = {
86         .pcm        = "audiocodec",
87         .format     = SND_PCM_FORMAT_S16_LE,
88         .rate       = 16000,
89         .channels   = 4,
90         .period_size    = 2048,
91         .periods    = 8,
92     },
93 };
94 
95 static const snd_pcm_dmix_config_t snd_pcm_dmix_config = {
96     .type       = "dmix",
97     .ipc_key    = 2222,
98     .slave = {
99         .pcm        = "audiocodec",
100         .format     = SND_PCM_FORMAT_S16_LE,
101         .rate       = 48000,
102         .channels   = 2,
103         .period_size    = 1024,
104         .periods    = 8,
105     },
106 };
107 
108 
109 #define DEFINE_SND_PCM_RATE_CONFIG(name, formats, rates, converters) \
110     const snd_pcm_rate_config_t snd_##name##_rate_config = { \
111         .type       = "rate", \
112         .slave = { \
113             .pcm        = #name, \
114             .format     = formats, \
115             .rate       = rates, \
116         }, \
117         .converter  = #converters, \
118     }
119 
120 static DEFINE_SND_PCM_RATE_CONFIG(audiocodec, SND_PCM_FORMAT_S16_LE, 48000, speexrate);
121 
122 static const snd_pcm_asym_config_t snd_pcm_asym_config = {
123     .type       = "asym",
124     .playback_pcm   = "PlaybackPlug",
125     .capture_pcm    = "CaptureDsnoop",
126 };
127 
128 static const snd_pcm_route_config_t snd_pcm_route_config = {
129     .type = "route",
130     .slave = {
131         .pcm = "audiocodec",
132         .channels = 1,
133     },
134     .ttable = {
135         {0, 0, 0.5},
136         {1, 0, 0.5},
137         TTABLE_CONFIG_END
138     },
139 };
140 
141 static const snd_pcm_plug_config_t snd_pcm_plug_config = {
142     .type           = "plug",
143     .slave          = {
144         .pcm        = "PlaybackDmix",
145         .format         = SND_PCM_FORMAT_S16_LE,
146         .channels       = 2,
147         .rate           = 48000,
148     },
149     .rate_converter = "speexrate",
150     .route_policy   = "default",
151     .ttable         = {
152         TTABLE_CONFIG_END
153     },
154 };
155 
156 #ifdef CONFIG_AW_ALSA_PLUGINS_SONA_AUDIOAEF
157 static const snd_pcm_sona_audioaef_config_t snd_pcm_sona_audioaef_config = {
158     .type = "sona_audioaef",
159     .slave = {
160         .pcm = "hw:audiocodec",
161     },
162     .config_name = "sona_audioaef_example",
163     .config_file = NULL,
164     .max_frames = 0,
165     .runtime_config = 0,
166 };
167 #endif
168 
169 static const snd_pcm_file_config_t snd_pcm_file_pb_config = {
170     .type       = "file",
171     .slave      = {
172         .pcm        = "PlaybackDmix",
173     },
174     .format     = "raw",
175     .mode       = "adb",
176     .port       = 20190,
177 };
178 
179 static const snd_pcm_file_config_t snd_pcm_file_cap_config = {
180     .type       = "file",
181     .slave      = {
182         .pcm        = "CaptureDsnoop",
183     },
184     .format     = "raw",
185     .mode       = "adb",
186     .port       = 20191,
187 };
188 
189 const snd_pcm_config_t snd_pcm_global_configs[] = {
190     SND_PCM_CONFIG("CaptureDsnoop", "dsnoop", &snd_pcm_dsnoop_config),
191     SND_PCM_CONFIG("PlaybackDmix", "dmix", &snd_pcm_dmix_config),
192     SND_PCM_CONFIG("Playbackrate", "rate", &snd_audiocodec_rate_config),
193     SND_PCM_CONFIG("audiocodec", "hw", &snd_audiocodec_hw_config),
194         SND_PCM_CONFIG("snddaudio0", "hw", &snd_snddaudio0_hw_config),
195         SND_PCM_CONFIG("snddaudio1", "hw", &snd_snddaudio1_hw_config),
196         SND_PCM_CONFIG("snddaudio2", "hw", &snd_snddaudio2_hw_config),
197         SND_PCM_CONFIG("snddaudio3", "hw", &snd_snddaudio3_hw_config),
198         SND_PCM_CONFIG("snddmic", "hw", &snd_snddmic_hw_config),
199         SND_PCM_CONFIG("sndspdif", "hw", &snd_sndspdif_hw_config),
200     /* SND_PCM_CONFIG("default", "hw", &snd_pcm_asym_config), */
201     SND_PCM_CONFIG("default", "asym", &snd_pcm_asym_config), //pcm.!default
202     SND_PCM_CONFIG("ctl.!default", "hw", &snd_audiocodec_hw_config), //ctl.!default
203     SND_PCM_CONFIG("PlaybackSoftVol1", "softvol", &snd_pcm_softvol_config1),
204     SND_PCM_CONFIG("PlaybackSoftVol2", "softvol", &snd_pcm_softvol_config2),
205     SND_PCM_CONFIG("PlaybackRoute", "route", &snd_pcm_route_config),
206     SND_PCM_CONFIG("PlaybackPlug", "plug", &snd_pcm_plug_config),
207 #ifdef CONFIG_AW_ALSA_PLUGINS_SONA_AUDIOAEF
208     SND_PCM_CONFIG("PlaybackSona", "sona_audioaef", &snd_pcm_sona_audioaef_config),
209 #endif
210     SND_PCM_CONFIG("PlaybackFile", "file", &snd_pcm_file_pb_config),
211     SND_PCM_CONFIG("CaptureFile", "file", &snd_pcm_file_cap_config),
212 };
213 
214 REGISTER_SND_PCM_GLOBAL_CONFIGS(snd_pcm_global_configs);
215