18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// Copyright(c) 2020 Intel Corporation. All rights reserved. 48c2ecf20Sopenharmony_ci#include <linux/string.h> 58c2ecf20Sopenharmony_ci#include <sound/pcm.h> 68c2ecf20Sopenharmony_ci#include <sound/soc.h> 78c2ecf20Sopenharmony_ci#include <sound/soc-dai.h> 88c2ecf20Sopenharmony_ci#include <sound/soc-dapm.h> 98c2ecf20Sopenharmony_ci#include <uapi/sound/asound.h> 108c2ecf20Sopenharmony_ci#include "sof_maxim_common.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define MAX_98373_PIN_NAME 16 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciconst struct snd_soc_dapm_route max_98373_dapm_routes[] = { 158c2ecf20Sopenharmony_ci /* speaker */ 168c2ecf20Sopenharmony_ci { "Left Spk", NULL, "Left BE_OUT" }, 178c2ecf20Sopenharmony_ci { "Right Spk", NULL, "Right BE_OUT" }, 188c2ecf20Sopenharmony_ci}; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistatic struct snd_soc_codec_conf max_98373_codec_conf[] = { 218c2ecf20Sopenharmony_ci { 228c2ecf20Sopenharmony_ci .dlc = COMP_CODEC_CONF(MAX_98373_DEV0_NAME), 238c2ecf20Sopenharmony_ci .name_prefix = "Right", 248c2ecf20Sopenharmony_ci }, 258c2ecf20Sopenharmony_ci { 268c2ecf20Sopenharmony_ci .dlc = COMP_CODEC_CONF(MAX_98373_DEV1_NAME), 278c2ecf20Sopenharmony_ci .name_prefix = "Left", 288c2ecf20Sopenharmony_ci }, 298c2ecf20Sopenharmony_ci}; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistruct snd_soc_dai_link_component max_98373_components[] = { 328c2ecf20Sopenharmony_ci { /* For Right */ 338c2ecf20Sopenharmony_ci .name = MAX_98373_DEV0_NAME, 348c2ecf20Sopenharmony_ci .dai_name = MAX_98373_CODEC_DAI, 358c2ecf20Sopenharmony_ci }, 368c2ecf20Sopenharmony_ci { /* For Left */ 378c2ecf20Sopenharmony_ci .name = MAX_98373_DEV1_NAME, 388c2ecf20Sopenharmony_ci .dai_name = MAX_98373_CODEC_DAI, 398c2ecf20Sopenharmony_ci }, 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic int max98373_hw_params(struct snd_pcm_substream *substream, 438c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 468c2ecf20Sopenharmony_ci struct snd_soc_dai *codec_dai; 478c2ecf20Sopenharmony_ci int j; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci for_each_rtd_codec_dais(rtd, j, codec_dai) { 508c2ecf20Sopenharmony_ci if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) { 518c2ecf20Sopenharmony_ci /* DEV0 tdm slot configuration */ 528c2ecf20Sopenharmony_ci snd_soc_dai_set_tdm_slot(codec_dai, 0x03, 3, 8, 32); 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) { 558c2ecf20Sopenharmony_ci /* DEV1 tdm slot configuration */ 568c2ecf20Sopenharmony_ci snd_soc_dai_set_tdm_slot(codec_dai, 0x0C, 3, 8, 32); 578c2ecf20Sopenharmony_ci } 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci return 0; 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ciint max98373_trigger(struct snd_pcm_substream *substream, int cmd) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 658c2ecf20Sopenharmony_ci struct snd_soc_dai *codec_dai; 668c2ecf20Sopenharmony_ci int j; 678c2ecf20Sopenharmony_ci int ret = 0; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci /* set spk pin by playback only */ 708c2ecf20Sopenharmony_ci if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 718c2ecf20Sopenharmony_ci return 0; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci for_each_rtd_codec_dais(rtd, j, codec_dai) { 748c2ecf20Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 758c2ecf20Sopenharmony_ci struct snd_soc_dapm_context *dapm = 768c2ecf20Sopenharmony_ci snd_soc_component_get_dapm(component); 778c2ecf20Sopenharmony_ci char pin_name[MAX_98373_PIN_NAME]; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk", 808c2ecf20Sopenharmony_ci codec_dai->component->name_prefix); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci switch (cmd) { 838c2ecf20Sopenharmony_ci case SNDRV_PCM_TRIGGER_START: 848c2ecf20Sopenharmony_ci case SNDRV_PCM_TRIGGER_RESUME: 858c2ecf20Sopenharmony_ci case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 868c2ecf20Sopenharmony_ci ret = snd_soc_dapm_enable_pin(dapm, pin_name); 878c2ecf20Sopenharmony_ci if (!ret) 888c2ecf20Sopenharmony_ci snd_soc_dapm_sync(dapm); 898c2ecf20Sopenharmony_ci break; 908c2ecf20Sopenharmony_ci case SNDRV_PCM_TRIGGER_STOP: 918c2ecf20Sopenharmony_ci case SNDRV_PCM_TRIGGER_SUSPEND: 928c2ecf20Sopenharmony_ci case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 938c2ecf20Sopenharmony_ci ret = snd_soc_dapm_disable_pin(dapm, pin_name); 948c2ecf20Sopenharmony_ci if (!ret) 958c2ecf20Sopenharmony_ci snd_soc_dapm_sync(dapm); 968c2ecf20Sopenharmony_ci break; 978c2ecf20Sopenharmony_ci default: 988c2ecf20Sopenharmony_ci break; 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci return ret; 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistruct snd_soc_ops max_98373_ops = { 1068c2ecf20Sopenharmony_ci .hw_params = max98373_hw_params, 1078c2ecf20Sopenharmony_ci .trigger = max98373_trigger, 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ciint max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci struct snd_soc_card *card = rtd->card; 1138c2ecf20Sopenharmony_ci int ret; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 1168c2ecf20Sopenharmony_ci ARRAY_SIZE(max_98373_dapm_routes)); 1178c2ecf20Sopenharmony_ci if (ret) 1188c2ecf20Sopenharmony_ci dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); 1198c2ecf20Sopenharmony_ci return ret; 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_civoid sof_max98373_codec_conf(struct snd_soc_card *card) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci card->codec_conf = max_98373_codec_conf; 1258c2ecf20Sopenharmony_ci card->num_configs = ARRAY_SIZE(max_98373_codec_conf); 1268c2ecf20Sopenharmony_ci} 127