Skip to content

Commit ef60252

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 7d7e8e9 commit ef60252

3 files changed

Lines changed: 298 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
@@ -270,7 +270,11 @@ int asoc_sdw_ti_amp_init(struct snd_soc_card *card,
270270
struct asoc_sdw_codec_info *info,
271271
bool playback);
272272
int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
273+
int asoc_sdw_ti_tac5xx2_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
274+
struct snd_soc_dai *dai);
273275
int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card,
274276
const char *name_prefix);
277+
int asoc_sdw_ti_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
278+
int asoc_sdw_ti_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
275279

276280
#endif

sound/soc/sdw_utils/soc_sdw_ti_amp.c

Lines changed: 143 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,142 @@ 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 asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
200+
struct snd_soc_component *component;
201+
struct snd_soc_jack *jack;
202+
int ret;
203+
204+
component = dai->component;
205+
206+
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
207+
"%s hs:%s", card->components,
208+
component->name_prefix);
209+
if (!card->components)
210+
return -ENOMEM;
211+
212+
ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
213+
SND_JACK_HEADSET | SND_JACK_BTN_0 |
214+
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
215+
SND_JACK_BTN_3 | SND_JACK_BTN_4,
216+
&ctx->sdw_headset,
217+
ti_sdca_jack_pins,
218+
ARRAY_SIZE(ti_sdca_jack_pins));
219+
if (ret) {
220+
dev_err(rtd->card->dev, "Jack create failed%d\n", ret);
221+
return ret;
222+
}
223+
224+
jack = &ctx->sdw_headset;
225+
226+
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
227+
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
228+
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
229+
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
230+
snd_jack_set_key(jack->jack, SND_JACK_BTN_4, KEY_NEXTSONG);
231+
232+
ret = snd_soc_component_set_jack(component, jack, NULL);
233+
if (ret)
234+
dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
235+
ret);
236+
237+
return ret;
238+
}
239+
EXPORT_SYMBOL_NS(asoc_sdw_ti_sdca_jack_rtd_init, "SND_SOC_SDW_UTILS");

sound/soc/sdw_utils/soc_sdw_utils.c

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

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

0 commit comments

Comments
 (0)