Skip to content

Commit bc0ed44

Browse files
committed
ASoC: sdw_utils: TI amp utility for tac5xx2 family
Add TI amp utility for supporting the tac5xx2 family of devices to support tac5572, tac5672, tac5682 and tas2883 Signed-off-by: Niranjan H Y <niranjan.hy@ti.com>
1 parent aed9129 commit bc0ed44

3 files changed

Lines changed: 295 additions & 1 deletion

File tree

include/sound/soc_sdw_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,11 @@ int asoc_sdw_ti_amp_init(struct snd_soc_card *card,
267267
struct asoc_sdw_codec_info *info,
268268
bool playback);
269269
int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
270+
int asoc_sdw_ti_tac5xx2_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
271+
struct snd_soc_dai *dai);
270272
int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card,
271273
const char *name_prefix);
274+
int asoc_sdw_ti_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
275+
int asoc_sdw_ti_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
272276

273277
#endif

sound/soc/sdw_utils/soc_sdw_ti_amp.c

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77

88
#include <linux/device.h>
99
#include <linux/errno.h>
10-
#include <sound/soc.h>
10+
#include <linux/input.h>
11+
#include <sound/jack.h>
1112
#include <sound/soc-acpi.h>
1213
#include <sound/soc-dai.h>
14+
#include <sound/soc.h>
1315
#include <sound/soc_sdw_utils.h>
1416

1517
#define TIAMP_SPK_VOLUME_0DB 200
18+
#define TAC5XX2_WIDGET_NAME_MAX 32
1619

1720
int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card,
1821
const char *name_prefix)
@@ -95,3 +98,143 @@ int asoc_sdw_ti_amp_init(struct snd_soc_card *card,
9598
return 0;
9699
}
97100
EXPORT_SYMBOL_NS(asoc_sdw_ti_amp_init, "SND_SOC_SDW_UTILS");
101+
102+
static int asoc_sdw_ti_add_tac5xx2_routes(struct snd_soc_dapm_context *dapm,
103+
const char *name_prefix)
104+
{
105+
struct snd_soc_dapm_route routes[2];
106+
char left_widget[TAC5XX2_WIDGET_NAME_MAX];
107+
char right_widget[TAC5XX2_WIDGET_NAME_MAX];
108+
int ret;
109+
110+
if (strlen(name_prefix) > (TAC5XX2_WIDGET_NAME_MAX - 7))
111+
return -ENAMETOOLONG;
112+
113+
ret = scnprintf(left_widget, sizeof(left_widget), "%s SPK_L", name_prefix);
114+
if (ret <= 0)
115+
return -EINVAL;
116+
117+
ret = scnprintf(right_widget, sizeof(right_widget), "%s SPK_R", name_prefix);
118+
if (ret <= 0)
119+
return -EINVAL;
120+
121+
routes[0] = (struct snd_soc_dapm_route){"Left Spk", NULL, left_widget};
122+
routes[1] = (struct snd_soc_dapm_route){"Right Spk", NULL, right_widget};
123+
124+
return snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
125+
}
126+
127+
int asoc_sdw_ti_tac5xx2_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
128+
struct snd_soc_dai *dai)
129+
{
130+
struct snd_soc_card *card = rtd->card;
131+
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
132+
int ret, i;
133+
struct snd_soc_dai *codec_dai;
134+
const char *prefix;
135+
136+
for_each_rtd_codec_dais(rtd, i, codec_dai) {
137+
if (!strstr(codec_dai->name, "tac5") &&
138+
!strstr(codec_dai->name, "tas2883"))
139+
continue;
140+
141+
prefix = codec_dai->component->name_prefix;
142+
if (!prefix) {
143+
dev_warn(card->dev,
144+
"No name prefix found for codec DAI: %s\n",
145+
codec_dai->name);
146+
continue;
147+
}
148+
ret = asoc_sdw_ti_add_tac5xx2_routes(dapm, prefix);
149+
if (ret) {
150+
dev_err(card->dev, "Failed to add routes for %s: %d\n",
151+
prefix, ret);
152+
return ret;
153+
}
154+
}
155+
156+
dev_dbg(card->dev, "Added TAC5XX2 speaker routes\n");
157+
158+
return 0;
159+
}
160+
EXPORT_SYMBOL_GPL(asoc_sdw_ti_tac5xx2_spk_rtd_init);
161+
162+
int asoc_sdw_ti_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
163+
{
164+
struct snd_soc_card *card = rtd->card;
165+
struct snd_soc_component *component;
166+
char *mic_name;
167+
168+
component = dai->component;
169+
mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s", component->name_prefix);
170+
if (!mic_name)
171+
return -ENOMEM;
172+
173+
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
174+
"%s mic:%s", card->components,
175+
mic_name);
176+
if (!card->components)
177+
return -ENOMEM;
178+
179+
dev_dbg(card->dev, "card->components: %s\n", card->components);
180+
181+
return 0;
182+
}
183+
EXPORT_SYMBOL_NS(asoc_sdw_ti_dmic_rtd_init, "SND_SOC_SDW_UTILS");
184+
185+
static struct snd_soc_jack_pin ti_sdca_jack_pins[] = {
186+
{
187+
.pin = "Headphone",
188+
.mask = SND_JACK_HEADPHONE,
189+
},
190+
{
191+
.pin = "Headset Mic",
192+
.mask = SND_JACK_MICROPHONE,
193+
},
194+
};
195+
196+
int asoc_sdw_ti_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
197+
{
198+
struct snd_soc_card *card = rtd->card;
199+
//struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
200+
struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
201+
struct snd_soc_component *component;
202+
struct snd_soc_jack *jack;
203+
int ret;
204+
205+
component = dai->component;
206+
207+
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
208+
"%s hs:%s", card->components,
209+
component->name_prefix);
210+
if (!card->components)
211+
return -ENOMEM;
212+
213+
ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
214+
SND_JACK_HEADSET | SND_JACK_BTN_0 |
215+
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
216+
SND_JACK_BTN_3 | SND_JACK_BTN_4,
217+
&ctx->sdw_headset,
218+
ti_sdca_jack_pins,
219+
ARRAY_SIZE(ti_sdca_jack_pins));
220+
if (ret) {
221+
dev_err(rtd->card->dev, "Jack create failed%d\n", ret);
222+
return ret;
223+
}
224+
225+
jack = &ctx->sdw_headset;
226+
227+
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
228+
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
229+
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
230+
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
231+
snd_jack_set_key(jack->jack, SND_JACK_BTN_4, KEY_NEXTSONG);
232+
233+
ret = snd_soc_component_set_jack(component, jack, NULL);
234+
if (ret)
235+
dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
236+
ret);
237+
238+
return ret;
239+
}
240+
EXPORT_SYMBOL_NS(asoc_sdw_ti_sdca_jack_rtd_init, "SND_SOC_SDW_UTILS");

sound/soc/sdw_utils/soc_sdw_utils.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,153 @@ static const struct snd_kcontrol_new rt700_controls[] = {
7272
};
7373

7474
struct asoc_sdw_codec_info codec_info_list[] = {
75+
{
76+
.part_id = 0x5572,
77+
.name_prefix = "tac5572",
78+
.dais = {
79+
{
80+
/* speaker */
81+
.direction = {true, false},
82+
.dai_name = "tac5xx2-aif1",
83+
.dai_type = SOC_SDW_DAI_TYPE_AMP,
84+
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
85+
.init = asoc_sdw_ti_amp_init,
86+
.rtd_init = asoc_sdw_ti_tac5xx2_spk_rtd_init,
87+
.controls = lr_spk_controls,
88+
.num_controls = ARRAY_SIZE(lr_spk_controls),
89+
.widgets = lr_spk_widgets,
90+
.num_widgets = ARRAY_SIZE(lr_spk_widgets),
91+
},
92+
{
93+
/* mic */
94+
.direction = {false, true},
95+
.dai_name = "tac5xx2-aif2",
96+
.dai_type = SOC_SDW_DAI_TYPE_MIC,
97+
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
98+
.rtd_init = asoc_sdw_ti_dmic_rtd_init,
99+
},
100+
{
101+
/* UAJ */
102+
.direction = {true, true},
103+
.dai_name = "tac5xx2-aif3",
104+
.dai_type = SOC_SDW_DAI_TYPE_JACK,
105+
.dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
106+
.controls = generic_jack_controls,
107+
.num_controls = ARRAY_SIZE(generic_jack_controls),
108+
.widgets = generic_jack_widgets,
109+
.num_widgets = ARRAY_SIZE(generic_jack_widgets),
110+
.rtd_init = asoc_sdw_ti_sdca_jack_rtd_init,
111+
},
112+
},
113+
.dai_num = 3,
114+
},
115+
{
116+
.part_id = 0x5672,
117+
.name_prefix = "tac5672",
118+
.dais = {
119+
{
120+
/* speaker with IV sense feedback */
121+
.direction = {true, true},
122+
.dai_name = "tac5xx2-aif1",
123+
.dai_type = SOC_SDW_DAI_TYPE_AMP,
124+
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
125+
.init = asoc_sdw_ti_amp_init,
126+
.rtd_init = asoc_sdw_ti_tac5xx2_spk_rtd_init,
127+
.controls = lr_spk_controls,
128+
.num_controls = ARRAY_SIZE(lr_spk_controls),
129+
.widgets = lr_spk_widgets,
130+
.num_widgets = ARRAY_SIZE(lr_spk_widgets),
131+
},
132+
{
133+
/* mic */
134+
.direction = {false, true},
135+
.dai_name = "tac5xx2-aif2",
136+
.dai_type = SOC_SDW_DAI_TYPE_MIC,
137+
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
138+
.rtd_init = asoc_sdw_ti_dmic_rtd_init,
139+
},
140+
{
141+
/* UAJ */
142+
.direction = {true, true},
143+
.dai_name = "tac5xx2-aif3",
144+
.dai_type = SOC_SDW_DAI_TYPE_JACK,
145+
.dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
146+
.controls = generic_jack_controls,
147+
.num_controls = ARRAY_SIZE(generic_jack_controls),
148+
.widgets = generic_jack_widgets,
149+
.num_widgets = ARRAY_SIZE(generic_jack_widgets),
150+
.rtd_init = asoc_sdw_ti_sdca_jack_rtd_init,
151+
},
152+
},
153+
.dai_num = 3,
154+
},
155+
{
156+
.part_id = 0x5682,
157+
.name_prefix = "tac5682",
158+
.dais = {
159+
{
160+
/* speaker with echo reference feedback */
161+
.direction = {true, true},
162+
.dai_name = "tac5xx2-aif1",
163+
.dai_type = SOC_SDW_DAI_TYPE_AMP,
164+
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
165+
.init = asoc_sdw_ti_amp_init,
166+
.rtd_init = asoc_sdw_ti_tac5xx2_spk_rtd_init,
167+
.controls = lr_spk_controls,
168+
.num_controls = ARRAY_SIZE(lr_spk_controls),
169+
.widgets = lr_spk_widgets,
170+
.num_widgets = ARRAY_SIZE(lr_spk_widgets),
171+
},
172+
{
173+
/* mic */
174+
.direction = {false, true},
175+
.dai_name = "tac5xx2-aif2",
176+
.dai_type = SOC_SDW_DAI_TYPE_MIC,
177+
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
178+
.rtd_init = asoc_sdw_ti_dmic_rtd_init,
179+
},
180+
{
181+
/* UAJ */
182+
.direction = {true, true},
183+
.dai_name = "tac5xx2-aif3",
184+
.dai_type = SOC_SDW_DAI_TYPE_JACK,
185+
.dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
186+
.controls = generic_jack_controls,
187+
.num_controls = ARRAY_SIZE(generic_jack_controls),
188+
.widgets = generic_jack_widgets,
189+
.num_widgets = ARRAY_SIZE(generic_jack_widgets),
190+
.rtd_init = asoc_sdw_ti_sdca_jack_rtd_init,
191+
},
192+
},
193+
.dai_num = 3,
194+
},
195+
{
196+
.part_id = 0x2883,
197+
.name_prefix = "tas2883",
198+
.dais = {
199+
{
200+
.direction = {true, false},
201+
.dai_name = "tac5xx2-aif1",
202+
.dai_type = SOC_SDW_DAI_TYPE_AMP,
203+
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
204+
.init = asoc_sdw_ti_amp_init,
205+
.rtd_init = asoc_sdw_ti_tac5xx2_spk_rtd_init,
206+
.controls = lr_spk_controls,
207+
.num_controls = ARRAY_SIZE(lr_spk_controls),
208+
.widgets = lr_spk_widgets,
209+
.num_widgets = ARRAY_SIZE(lr_spk_widgets),
210+
},
211+
{
212+
/* mic */
213+
.direction = {false, true},
214+
.dai_name = "tac5xx2-aif2",
215+
.dai_type = SOC_SDW_DAI_TYPE_MIC,
216+
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
217+
.rtd_init = asoc_sdw_ti_dmic_rtd_init,
218+
},
219+
},
220+
.dai_num = 2,
221+
},
75222
{
76223
.part_id = 0x0000, /* TAS2783A */
77224
.name_prefix = "tas2783",

0 commit comments

Comments
 (0)