1111
1212#define DRV_NAME "q6voice-dai"
1313
14+ static enum q6voice_path_type q6voice_get_path (unsigned int dai_id )
15+ {
16+ switch (dai_id ) {
17+ case CS_VOICE :
18+ return Q6VOICE_PATH_VOICE ;
19+ case VOICEMMODE1 :
20+ return Q6VOICE_PATH_VOICEMMODE1 ;
21+ }
22+
23+ return Q6VOICE_PATH_COUNT ;
24+ }
25+
1426static int q6voice_dai_startup (struct snd_pcm_substream * substream ,
1527 struct snd_soc_dai * dai )
1628{
1729 struct q6voice * v = snd_soc_dai_get_drvdata (dai );
30+ enum q6voice_path_type path = q6voice_get_path (dai -> driver -> id );
1831
19- return q6voice_start (v , Q6VOICE_PATH_VOICE , substream -> stream );
32+ if (path == Q6VOICE_PATH_COUNT ) {
33+ dev_err (dai -> dev , "Invalid DAI ID %u\n" , dai -> driver -> id );
34+ return - EINVAL ;
35+ }
36+
37+ return q6voice_start (v , path , substream -> stream );
2038}
2139
2240static void q6voice_dai_shutdown (struct snd_pcm_substream * substream ,
2341 struct snd_soc_dai * dai )
2442{
2543 struct q6voice * v = snd_soc_dai_get_drvdata (dai );
44+ enum q6voice_path_type path = q6voice_get_path (dai -> driver -> id );
45+
46+ if (path == Q6VOICE_PATH_COUNT ) {
47+ dev_err (dai -> dev , "Invalid DAI ID %u\n" , dai -> driver -> id );
48+ return ;
49+ }
2650
27- q6voice_stop (v , Q6VOICE_PATH_VOICE , substream -> stream );
51+ q6voice_stop (v , path , substream -> stream );
2852}
2953
3054static struct snd_soc_dai_ops q6voice_dai_ops = {
@@ -57,6 +81,29 @@ static struct snd_soc_dai_driver q6voice_dais[] = {
5781 },
5882 .ops = & q6voice_dai_ops ,
5983 },
84+ {
85+ .id = VOICEMMODE1 ,
86+ .name = "VOICEMMODE1" ,
87+ .playback = {
88+ .stream_name = "VOICEMMODE1 Playback" ,
89+ .formats = SNDRV_PCM_FMTBIT_S16_LE ,
90+ .rates = SNDRV_PCM_RATE_8000 ,
91+ .rate_min = 8000 ,
92+ .rate_max = 8000 ,
93+ .channels_min = 1 ,
94+ .channels_max = 1 ,
95+ },
96+ .capture = {
97+ .stream_name = "VOICEMMODE1 Capture" ,
98+ .formats = SNDRV_PCM_FMTBIT_S16_LE ,
99+ .rates = SNDRV_PCM_RATE_8000 ,
100+ .rate_min = 8000 ,
101+ .rate_max = 8000 ,
102+ .channels_min = 1 ,
103+ .channels_max = 1 ,
104+ },
105+ .ops = & q6voice_dai_ops ,
106+ },
60107};
61108
62109/* FIXME: Use codec2codec instead */
@@ -77,83 +124,141 @@ static int q6voice_dai_open(struct snd_soc_component *component,
77124 return 0 ;
78125}
79126
80- static int q6voice_get_mixer (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
127+ static int q6voice_get_mixer (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol , bool capture )
81128{
82129 struct snd_soc_dapm_context * dapm = snd_soc_dapm_kcontrol_dapm (kcontrol );
83130 struct snd_soc_component * c = snd_soc_dapm_to_component (dapm );
84131 struct soc_mixer_control * mc =
85132 (struct soc_mixer_control * )kcontrol -> private_value ;
86133 struct q6voice * v = snd_soc_component_get_drvdata (c );
87- bool capture = !!mc -> shift ;
134+ enum q6voice_path_type path = q6voice_get_path (mc -> shift );
135+
136+ if (path == Q6VOICE_PATH_COUNT ) {
137+ dev_err (c -> dev , "Invalid DAI ID %u\n" , mc -> shift );
138+ return - EINVAL ;
139+ }
88140
89141 ucontrol -> value .integer .value [0 ] =
90- q6voice_get_port (v , Q6VOICE_PATH_VOICE , capture ) == mc -> reg ;
142+ q6voice_get_port (v , path , capture ) == mc -> reg ;
91143 return 0 ;
92144}
93145
94- static int q6voice_put_mixer (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
146+ static int q6voice_put_mixer (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol , bool capture )
95147{
96148 struct snd_soc_dapm_context * dapm = snd_soc_dapm_kcontrol_dapm (kcontrol );
97149 struct snd_soc_component * c = snd_soc_dapm_to_component (dapm );
98150 struct soc_mixer_control * mc =
99151 (struct soc_mixer_control * )kcontrol -> private_value ;
100152 struct q6voice * v = snd_soc_component_get_drvdata (c );
101153 bool val = !!ucontrol -> value .integer .value [0 ];
102- bool capture = !!mc -> shift ;
154+ enum q6voice_path_type path = q6voice_get_path (mc -> shift );
155+
156+ if (path == Q6VOICE_PATH_COUNT ) {
157+ dev_err (c -> dev , "Invalid DAI ID %u\n" , mc -> shift );
158+ return - EINVAL ;
159+ }
103160
104161 if (val )
105- q6voice_set_port (v , Q6VOICE_PATH_VOICE , capture , mc -> reg );
106- else if (q6voice_get_port (v , Q6VOICE_PATH_VOICE , capture ) == mc -> reg )
107- q6voice_set_port (v , Q6VOICE_PATH_VOICE , capture , 0 );
162+ q6voice_set_port (v , path , capture , mc -> reg );
163+ else if (q6voice_get_port (v , path , capture ) == mc -> reg )
164+ q6voice_set_port (v , path , capture , 0 );
108165
109166 snd_soc_dapm_mixer_update_power (dapm , kcontrol , val , NULL );
110167 return 1 ;
111168}
112169
113- static const struct snd_kcontrol_new voice_tx_mixer_controls [] = {
114- SOC_SINGLE_EXT ("PRI_MI2S_TX" , PRIMARY_MI2S_TX , 1 , 1 , 0 ,
115- q6voice_get_mixer , q6voice_put_mixer ),
116- SOC_SINGLE_EXT ("SEC_MI2S_TX" , SECONDARY_MI2S_TX , 1 , 1 , 0 ,
117- q6voice_get_mixer , q6voice_put_mixer ),
118- SOC_SINGLE_EXT ("TERT_MI2S_TX" , TERTIARY_MI2S_TX , 1 , 1 , 0 ,
119- q6voice_get_mixer , q6voice_put_mixer ),
120- SOC_SINGLE_EXT ("QUAT_MI2S_TX" , QUATERNARY_MI2S_TX , 1 , 1 , 0 ,
121- q6voice_get_mixer , q6voice_put_mixer ),
122- SOC_SINGLE_EXT ("QUIN_MI2S_TX" , QUINARY_MI2S_TX , 1 , 1 , 0 ,
123- q6voice_get_mixer , q6voice_put_mixer ),
170+ static int q6voice_get_mixer_capture (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
171+ {
172+ return q6voice_get_mixer (kcontrol , ucontrol , true);
173+ }
174+
175+ static int q6voice_get_mixer_playback (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
176+ {
177+ return q6voice_get_mixer (kcontrol , ucontrol , false);
178+ }
179+
180+ static int q6voice_put_mixer_capture (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
181+ {
182+ return q6voice_put_mixer (kcontrol , ucontrol , true);
183+ }
184+
185+ static int q6voice_put_mixer_playback (struct snd_kcontrol * kcontrol , struct snd_ctl_elem_value * ucontrol )
186+ {
187+ return q6voice_put_mixer (kcontrol , ucontrol , false);
188+ }
189+
190+ static const struct snd_kcontrol_new cs_voice_tx_mixer_controls [] = {
191+ SOC_SINGLE_EXT ("PRI_MI2S_TX" , PRIMARY_MI2S_TX , CS_VOICE , 1 , 0 ,
192+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
193+ SOC_SINGLE_EXT ("SEC_MI2S_TX" , SECONDARY_MI2S_TX , CS_VOICE , 1 , 0 ,
194+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
195+ SOC_SINGLE_EXT ("TERT_MI2S_TX" , TERTIARY_MI2S_TX , CS_VOICE , 1 , 0 ,
196+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
197+ SOC_SINGLE_EXT ("QUAT_MI2S_TX" , QUATERNARY_MI2S_TX , CS_VOICE , 1 , 0 ,
198+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
199+ SOC_SINGLE_EXT ("QUIN_MI2S_TX" , QUINARY_MI2S_TX , CS_VOICE , 1 , 0 ,
200+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
201+ };
202+
203+ static const struct snd_kcontrol_new voicemmode1_tx_mixer_controls [] = {
204+ SOC_SINGLE_EXT ("PRI_MI2S_TX" , PRIMARY_MI2S_TX , VOICEMMODE1 , 1 , 0 ,
205+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
206+ SOC_SINGLE_EXT ("SEC_MI2S_TX" , SECONDARY_MI2S_TX , VOICEMMODE1 , 1 , 0 ,
207+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
208+ SOC_SINGLE_EXT ("TERT_MI2S_TX" , TERTIARY_MI2S_TX , VOICEMMODE1 , 1 , 0 ,
209+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
210+ SOC_SINGLE_EXT ("QUAT_MI2S_TX" , QUATERNARY_MI2S_TX , VOICEMMODE1 , 1 , 0 ,
211+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
212+ SOC_SINGLE_EXT ("QUIN_MI2S_TX" , QUINARY_MI2S_TX , VOICEMMODE1 , 1 , 0 ,
213+ q6voice_get_mixer_capture , q6voice_put_mixer_capture ),
124214};
125215
126216static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls [] = {
127- SOC_SINGLE_EXT ("CS-Voice" , PRIMARY_MI2S_RX , 0 , 1 , 0 ,
128- q6voice_get_mixer , q6voice_put_mixer )
217+ SOC_SINGLE_EXT ("CS-Voice" , PRIMARY_MI2S_RX , CS_VOICE , 1 , 0 ,
218+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
219+ SOC_SINGLE_EXT ("VoiceMMode1" , PRIMARY_MI2S_RX , VOICEMMODE1 , 1 , 0 ,
220+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
129221};
130222
131223static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls [] = {
132- SOC_SINGLE_EXT ("CS-Voice" , SECONDARY_MI2S_RX , 0 , 1 , 0 ,
133- q6voice_get_mixer , q6voice_put_mixer )
224+ SOC_SINGLE_EXT ("CS-Voice" , SECONDARY_MI2S_RX , CS_VOICE , 1 , 0 ,
225+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
226+ SOC_SINGLE_EXT ("VoiceMMode1" , SECONDARY_MI2S_RX , VOICEMMODE1 , 1 , 0 ,
227+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
134228};
135229
136230static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls [] = {
137- SOC_SINGLE_EXT ("CS-Voice" , TERTIARY_MI2S_RX , 0 , 1 , 0 ,
138- q6voice_get_mixer , q6voice_put_mixer )
231+ SOC_SINGLE_EXT ("CS-Voice" , TERTIARY_MI2S_RX , CS_VOICE , 1 , 0 ,
232+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
233+ SOC_SINGLE_EXT ("VoiceMMode1" , TERTIARY_MI2S_RX , VOICEMMODE1 , 1 , 0 ,
234+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
139235};
140236
141237static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls [] = {
142- SOC_SINGLE_EXT ("CS-Voice" , QUATERNARY_MI2S_RX , 0 , 1 , 0 ,
143- q6voice_get_mixer , q6voice_put_mixer )
238+ SOC_SINGLE_EXT ("CS-Voice" , QUATERNARY_MI2S_RX , CS_VOICE , 1 , 0 ,
239+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
240+ SOC_SINGLE_EXT ("VoiceMMode1" , QUATERNARY_MI2S_RX , VOICEMMODE1 , 1 , 0 ,
241+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
144242};
145243
146244static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls [] = {
147- SOC_SINGLE_EXT ("CS-Voice" , QUINARY_MI2S_RX , 0 , 1 , 0 ,
148- q6voice_get_mixer , q6voice_put_mixer )
245+ SOC_SINGLE_EXT ("CS-Voice" , QUINARY_MI2S_RX , CS_VOICE , 1 , 0 ,
246+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
247+ SOC_SINGLE_EXT ("VoiceMMode1" , QUINARY_MI2S_RX , VOICEMMODE1 , 1 , 0 ,
248+ q6voice_get_mixer_playback , q6voice_put_mixer_playback ),
149249};
150250
151251static const struct snd_soc_dapm_widget q6voice_dapm_widgets [] = {
152252 SND_SOC_DAPM_AIF_IN ("CS-VOICE_DL1" , "CS-VOICE Playback" , 0 , SND_SOC_NOPM , 0 , 0 ),
153253 SND_SOC_DAPM_AIF_OUT ("CS-VOICE_UL1" , "CS-VOICE Capture" , 0 , SND_SOC_NOPM , 0 , 0 ),
154254 SND_SOC_DAPM_MIXER ("CS-Voice Capture Mixer" , SND_SOC_NOPM , 0 , 0 ,
155- voice_tx_mixer_controls ,
156- ARRAY_SIZE (voice_tx_mixer_controls )),
255+ cs_voice_tx_mixer_controls ,
256+ ARRAY_SIZE (cs_voice_tx_mixer_controls )),
257+ SND_SOC_DAPM_AIF_IN ("VOICEMMODE1_DL1" , "VOICEMMODE1 Playback" , 0 , SND_SOC_NOPM , 0 , 0 ),
258+ SND_SOC_DAPM_AIF_OUT ("VOICEMMODE1_UL1" , "VOICEMMODE1 Capture" , 0 , SND_SOC_NOPM , 0 , 0 ),
259+ SND_SOC_DAPM_MIXER ("VoiceMMode1 Capture Mixer" , SND_SOC_NOPM , 0 , 0 ,
260+ voicemmode1_tx_mixer_controls ,
261+ ARRAY_SIZE (voicemmode1_tx_mixer_controls )),
157262 SND_SOC_DAPM_MIXER ("PRI_MI2S_RX Voice Mixer" , SND_SOC_NOPM , 0 , 0 ,
158263 primary_mi2s_rx_mixer_controls ,
159264 ARRAY_SIZE (primary_mi2s_rx_mixer_controls )),
@@ -178,12 +283,24 @@ static const struct snd_soc_dapm_route q6voice_dapm_routes[] = {
178283 { "CS-Voice Capture Mixer" , "QUAT_MI2S_TX" , "QUAT_MI2S_TX" },
179284 { "CS-Voice Capture Mixer" , "QUIN_MI2S_TX" , "QUIN_MI2S_TX" },
180285 { "CS-VOICE_UL1" , NULL , "CS-Voice Capture Mixer" },
286+ { "VoiceMMode1 Capture Mixer" , "PRI_MI2S_TX" , "PRI_MI2S_TX" },
287+ { "VoiceMMode1 Capture Mixer" , "SEC_MI2S_TX" , "SEC_MI2S_TX" },
288+ { "VoiceMMode1 Capture Mixer" , "TERT_MI2S_TX" , "TERT_MI2S_TX" },
289+ { "VoiceMMode1 Capture Mixer" , "QUAT_MI2S_TX" , "QUAT_MI2S_TX" },
290+ { "VoiceMMode1 Capture Mixer" , "QUIN_MI2S_TX" , "QUIN_MI2S_TX" },
291+ { "VOICEMMODE1_UL1" , NULL , "VoiceMMode1 Capture Mixer" },
181292
182293 { "PRI_MI2S_RX Voice Mixer" , "CS-Voice" , "CS-VOICE_DL1" },
183294 { "SEC_MI2S_RX Voice Mixer" , "CS-Voice" , "CS-VOICE_DL1" },
184295 { "TERT_MI2S_RX Voice Mixer" , "CS-Voice" , "CS-VOICE_DL1" },
185296 { "QUAT_MI2S_RX Voice Mixer" , "CS-Voice" , "CS-VOICE_DL1" },
186297 { "QUIN_MI2S_RX Voice Mixer" , "CS-Voice" , "CS-VOICE_DL1" },
298+ { "PRI_MI2S_RX Voice Mixer" , "VoiceMMode1" , "VOICEMMODE1_DL1" },
299+ { "SEC_MI2S_RX Voice Mixer" , "VoiceMMode1" , "VOICEMMODE1_DL1" },
300+ { "TERT_MI2S_RX Voice Mixer" , "VoiceMMode1" , "VOICEMMODE1_DL1" },
301+ { "QUAT_MI2S_RX Voice Mixer" , "VoiceMMode1" , "VOICEMMODE1_DL1" },
302+ { "QUIN_MI2S_RX Voice Mixer" , "VoiceMMode1" , "VOICEMMODE1_DL1" },
303+
187304 { "PRI_MI2S_RX" , NULL , "PRI_MI2S_RX Voice Mixer" },
188305 { "SEC_MI2S_RX" , NULL , "SEC_MI2S_RX Voice Mixer" },
189306 { "TERT_MI2S_RX" , NULL , "TERT_MI2S_RX Voice Mixer" },
0 commit comments