0001
0002
0003
0004
0005
0006
0007 #include <linux/device.h>
0008 #include <linux/errno.h>
0009 #include <sound/control.h>
0010 #include <sound/soc.h>
0011 #include <sound/soc-acpi.h>
0012 #include <sound/soc-dapm.h>
0013 #include "sof_sdw_common.h"
0014 #include "sof_maxim_common.h"
0015
0016 static const struct snd_soc_dapm_widget mx8373_widgets[] = {
0017 SND_SOC_DAPM_SPK("Left Spk", NULL),
0018 SND_SOC_DAPM_SPK("Right Spk", NULL),
0019 };
0020
0021 static const struct snd_kcontrol_new mx8373_controls[] = {
0022 SOC_DAPM_PIN_SWITCH("Left Spk"),
0023 SOC_DAPM_PIN_SWITCH("Right Spk"),
0024 };
0025
0026 static int spk_init(struct snd_soc_pcm_runtime *rtd)
0027 {
0028 struct snd_soc_card *card = rtd->card;
0029 int ret;
0030
0031 card->components = devm_kasprintf(card->dev, GFP_KERNEL,
0032 "%s spk:mx8373",
0033 card->components);
0034 if (!card->components)
0035 return -ENOMEM;
0036
0037 ret = snd_soc_add_card_controls(card, mx8373_controls,
0038 ARRAY_SIZE(mx8373_controls));
0039 if (ret) {
0040 dev_err(card->dev, "mx8373 ctrls addition failed: %d\n", ret);
0041 return ret;
0042 }
0043
0044 ret = snd_soc_dapm_new_controls(&card->dapm, mx8373_widgets,
0045 ARRAY_SIZE(mx8373_widgets));
0046 if (ret) {
0047 dev_err(card->dev, "mx8373 widgets addition failed: %d\n", ret);
0048 return ret;
0049 }
0050
0051 ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes, 2);
0052 if (ret)
0053 dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret);
0054
0055 return ret;
0056 }
0057
0058 static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable)
0059 {
0060 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0061 struct snd_soc_dai *codec_dai;
0062 struct snd_soc_dai *cpu_dai;
0063 int ret;
0064 int j;
0065
0066
0067 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
0068 return 0;
0069
0070 cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0071 for_each_rtd_codec_dais(rtd, j, codec_dai) {
0072 struct snd_soc_dapm_context *dapm =
0073 snd_soc_component_get_dapm(cpu_dai->component);
0074 char pin_name[16];
0075
0076 snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk",
0077 codec_dai->component->name_prefix);
0078
0079 if (enable)
0080 ret = snd_soc_dapm_enable_pin(dapm, pin_name);
0081 else
0082 ret = snd_soc_dapm_disable_pin(dapm, pin_name);
0083
0084 if (!ret)
0085 snd_soc_dapm_sync(dapm);
0086 }
0087
0088 return 0;
0089 }
0090
0091 static int mx8373_sdw_prepare(struct snd_pcm_substream *substream)
0092 {
0093 int ret;
0094
0095
0096 ret = sdw_prepare(substream);
0097 if (ret < 0)
0098 return ret;
0099
0100 return mx8373_enable_spk_pin(substream, true);
0101 }
0102
0103 static int mx8373_sdw_hw_free(struct snd_pcm_substream *substream)
0104 {
0105 int ret;
0106
0107
0108 ret = sdw_hw_free(substream);
0109 if (ret < 0)
0110 return ret;
0111
0112 return mx8373_enable_spk_pin(substream, false);
0113 }
0114
0115 static const struct snd_soc_ops max_98373_sdw_ops = {
0116 .startup = sdw_startup,
0117 .prepare = mx8373_sdw_prepare,
0118 .trigger = sdw_trigger,
0119 .hw_free = mx8373_sdw_hw_free,
0120 .shutdown = sdw_shutdown,
0121 };
0122
0123 int sof_sdw_mx8373_init(struct snd_soc_card *card,
0124 const struct snd_soc_acpi_link_adr *link,
0125 struct snd_soc_dai_link *dai_links,
0126 struct sof_sdw_codec_info *info,
0127 bool playback)
0128 {
0129 info->amp_num++;
0130 if (info->amp_num == 2)
0131 dai_links->init = spk_init;
0132
0133 info->late_probe = true;
0134
0135 dai_links->ops = &max_98373_sdw_ops;
0136
0137 return 0;
0138 }
0139
0140 int sof_sdw_mx8373_late_probe(struct snd_soc_card *card)
0141 {
0142 struct snd_soc_dapm_context *dapm = &card->dapm;
0143
0144
0145 snd_soc_dapm_disable_pin(dapm, "Left Spk");
0146 snd_soc_dapm_disable_pin(dapm, "Right Spk");
0147 return snd_soc_dapm_sync(dapm);
0148 }