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