Skip to content

Commit 065f580

Browse files
affenull2345flamingradian
authored andcommitted
ASoC: qdsp6: q6voice-dai: Add VoiceMMode1 DAI
VoiceMMode1 is used instead of CS-Voice on newer firmwares. Signed-off-by: Otto Pflüger <[email protected]> (cherry picked from commit e20f01b4df65558a5db3d9ad8f6e700fb3e1fb61) Link: msm8916-mainline/linux#331 Link: https://github.com/msm8953-mainline/linux Signed-off-by: Richard Acayan <[email protected]>
1 parent 722cdae commit 065f580

File tree

4 files changed

+173
-41
lines changed

4 files changed

+173
-41
lines changed

include/dt-bindings/sound/qcom,q6voice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
#define __DT_BINDINGS_Q6_VOICE_H__
44

55
#define CS_VOICE 0
6+
#define VOICEMMODE1 1
67

78
#endif /* __DT_BINDINGS_Q6_VOICE_H__ */

sound/soc/qcom/qdsp6/q6mvm.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ static inline const char *q6mvm_session_name(enum q6voice_path_type path)
5151
switch (path) {
5252
case Q6VOICE_PATH_VOICE:
5353
return "default modem voice";
54+
case Q6VOICE_PATH_VOIP:
55+
return "10004000";
56+
case Q6VOICE_PATH_VOLTE:
57+
return "10C02000";
58+
case Q6VOICE_PATH_VOICE2:
59+
return "10DC1000";
60+
case Q6VOICE_PATH_QCHAT:
61+
return "10803000";
62+
case Q6VOICE_PATH_VOWLAN:
63+
return "10002000";
64+
case Q6VOICE_PATH_VOICEMMODE1:
65+
return "11C05000";
66+
case Q6VOICE_PATH_VOICEMMODE2:
67+
return "11DC5000";
5468
default:
5569
return NULL;
5670
}

sound/soc/qcom/qdsp6/q6voice-dai.c

Lines changed: 150 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,44 @@
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+
1426
static 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

2240
static 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

3054
static 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

126216
static 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

131223
static 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

136230
static 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

141237
static 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

146244
static 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

151251
static 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" },

sound/soc/qcom/qdsp6/q6voice.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
#define _Q6_VOICE_H
44

55
enum q6voice_path_type {
6-
Q6VOICE_PATH_VOICE = 0,
7-
/* TODO: Q6VOICE_PATH_VOIP = 1, */
8-
/* TODO: Q6VOICE_PATH_VOLTE = 2, */
9-
/* TODO: Q6VOICE_PATH_VOICE2 = 3, */
10-
/* TODO: Q6VOICE_PATH_QCHAT = 4, */
11-
/* TODO: Q6VOICE_PATH_VOWLAN = 5, */
12-
/* TODO: Q6VOICE_PATH_VOICEMMODE1 = 6, */
13-
/* TODO: Q6VOICE_PATH_VOICEMMODE2 = 7, */
6+
Q6VOICE_PATH_VOICE = 0,
7+
Q6VOICE_PATH_VOIP = 1,
8+
Q6VOICE_PATH_VOLTE = 2,
9+
Q6VOICE_PATH_VOICE2 = 3,
10+
Q6VOICE_PATH_QCHAT = 4,
11+
Q6VOICE_PATH_VOWLAN = 5,
12+
Q6VOICE_PATH_VOICEMMODE1 = 6,
13+
Q6VOICE_PATH_VOICEMMODE2 = 7,
1414
Q6VOICE_PATH_COUNT
1515
};
1616

0 commit comments

Comments
 (0)