xref: /linux/sound/soc/sdw_utils/soc_sdw_ti_amp.c (revision 48a710760e10a4f36e11233a21860796ba204b1e)
1*96384a34SNiranjan H Y // SPDX-License-Identifier: GPL-2.0-only
2*96384a34SNiranjan H Y // Copyright (c) 2025 Texas Instruments Inc.
3*96384a34SNiranjan H Y 
4*96384a34SNiranjan H Y /*
5*96384a34SNiranjan H Y  *  soc_sdw_ti_amp - Helpers to handle TI's soundwire based codecs
6*96384a34SNiranjan H Y  */
7*96384a34SNiranjan H Y 
8*96384a34SNiranjan H Y #include <linux/device.h>
9*96384a34SNiranjan H Y #include <linux/errno.h>
10*96384a34SNiranjan H Y #include <sound/soc.h>
11*96384a34SNiranjan H Y #include <sound/soc-acpi.h>
12*96384a34SNiranjan H Y #include <sound/soc-dai.h>
13*96384a34SNiranjan H Y #include <sound/soc_sdw_utils.h>
14*96384a34SNiranjan H Y 
15*96384a34SNiranjan H Y #define TIAMP_SPK_VOLUME_0DB		200
16*96384a34SNiranjan H Y 
17*96384a34SNiranjan H Y int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card,
18*96384a34SNiranjan H Y 				     const char *name_prefix)
19*96384a34SNiranjan H Y {
20*96384a34SNiranjan H Y 	char *volume_ctl_name;
21*96384a34SNiranjan H Y 	int ret;
22*96384a34SNiranjan H Y 
23*96384a34SNiranjan H Y 	volume_ctl_name = kasprintf(GFP_KERNEL, "%s Speaker Volume",
24*96384a34SNiranjan H Y 				    name_prefix);
25*96384a34SNiranjan H Y 	if (!volume_ctl_name)
26*96384a34SNiranjan H Y 		return -ENOMEM;
27*96384a34SNiranjan H Y 
28*96384a34SNiranjan H Y 	ret = snd_soc_limit_volume(card, volume_ctl_name,
29*96384a34SNiranjan H Y 				   TIAMP_SPK_VOLUME_0DB);
30*96384a34SNiranjan H Y 	if (ret)
31*96384a34SNiranjan H Y 		dev_err(card->dev,
32*96384a34SNiranjan H Y 			"%s update failed %d\n",
33*96384a34SNiranjan H Y 			volume_ctl_name, ret);
34*96384a34SNiranjan H Y 
35*96384a34SNiranjan H Y 	kfree(volume_ctl_name);
36*96384a34SNiranjan H Y 	return 0;
37*96384a34SNiranjan H Y }
38*96384a34SNiranjan H Y EXPORT_SYMBOL_NS(asoc_sdw_ti_amp_initial_settings, "SND_SOC_SDW_UTILS");
39*96384a34SNiranjan H Y 
40*96384a34SNiranjan H Y int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
41*96384a34SNiranjan H Y 			     struct snd_soc_dai *dai)
42*96384a34SNiranjan H Y {
43*96384a34SNiranjan H Y 	struct snd_soc_card *card = rtd->card;
44*96384a34SNiranjan H Y 	char widget_name[16];
45*96384a34SNiranjan H Y 	char speaker[16];
46*96384a34SNiranjan H Y 	struct snd_soc_dapm_route route = {speaker, NULL, widget_name};
47*96384a34SNiranjan H Y 	struct snd_soc_dai *codec_dai;
48*96384a34SNiranjan H Y 	const char *prefix;
49*96384a34SNiranjan H Y 	int i, ret = 0;
50*96384a34SNiranjan H Y 
51*96384a34SNiranjan H Y 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
52*96384a34SNiranjan H Y 		if (!strstr(codec_dai->name, "tas2783"))
53*96384a34SNiranjan H Y 			continue;
54*96384a34SNiranjan H Y 
55*96384a34SNiranjan H Y 		prefix = codec_dai->component->name_prefix;
56*96384a34SNiranjan H Y 		if (!strncmp(prefix, "tas2783-1", strlen("tas2783-1"))) {
57*96384a34SNiranjan H Y 			strscpy(speaker, "Left Spk", sizeof(speaker));
58*96384a34SNiranjan H Y 		} else if (!strncmp(prefix, "tas2783-2", strlen("tas2783-2"))) {
59*96384a34SNiranjan H Y 			strscpy(speaker, "Right Spk", sizeof(speaker));
60*96384a34SNiranjan H Y 		} else {
61*96384a34SNiranjan H Y 			ret = -EINVAL;
62*96384a34SNiranjan H Y 			dev_err(card->dev, "unhandled prefix %s", prefix);
63*96384a34SNiranjan H Y 			break;
64*96384a34SNiranjan H Y 		}
65*96384a34SNiranjan H Y 
66*96384a34SNiranjan H Y 		snprintf(widget_name, sizeof(widget_name), "%s SPK", prefix);
67*96384a34SNiranjan H Y 		ret = asoc_sdw_ti_amp_initial_settings(card, prefix);
68*96384a34SNiranjan H Y 		if (ret)
69*96384a34SNiranjan H Y 			return ret;
70*96384a34SNiranjan H Y 
71*96384a34SNiranjan H Y 		ret = snd_soc_dapm_add_routes(&card->dapm, &route, 1);
72*96384a34SNiranjan H Y 		if (ret)
73*96384a34SNiranjan H Y 			return ret;
74*96384a34SNiranjan H Y 	}
75*96384a34SNiranjan H Y 
76*96384a34SNiranjan H Y 	return ret;
77*96384a34SNiranjan H Y }
78*96384a34SNiranjan H Y EXPORT_SYMBOL_NS(asoc_sdw_ti_spk_rtd_init, "SND_SOC_SDW_UTILS");
79*96384a34SNiranjan H Y 
80*96384a34SNiranjan H Y int asoc_sdw_ti_amp_init(struct snd_soc_card *card,
81*96384a34SNiranjan H Y 			 struct snd_soc_dai_link *dai_links,
82*96384a34SNiranjan H Y 			 struct asoc_sdw_codec_info *info,
83*96384a34SNiranjan H Y 			 bool playback)
84*96384a34SNiranjan H Y {
85*96384a34SNiranjan H Y 	if (!playback)
86*96384a34SNiranjan H Y 		return 0;
87*96384a34SNiranjan H Y 
88*96384a34SNiranjan H Y 	info->amp_num++;
89*96384a34SNiranjan H Y 
90*96384a34SNiranjan H Y 	return 0;
91*96384a34SNiranjan H Y }
92*96384a34SNiranjan H Y EXPORT_SYMBOL_NS(asoc_sdw_ti_amp_init, "SND_SOC_SDW_UTILS");
93