0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/errno.h>
0010 #include <linux/input.h>
0011 #include <linux/soundwire/sdw.h>
0012 #include <linux/soundwire/sdw_type.h>
0013 #include <sound/control.h>
0014 #include <sound/soc.h>
0015 #include <sound/soc-acpi.h>
0016 #include <sound/soc-dapm.h>
0017 #include <sound/jack.h>
0018 #include "sof_sdw_common.h"
0019
0020 static const struct snd_soc_dapm_widget rt5682_widgets[] = {
0021 SND_SOC_DAPM_HP("Headphone", NULL),
0022 SND_SOC_DAPM_MIC("Headset Mic", NULL),
0023 };
0024
0025 static const struct snd_soc_dapm_route rt5682_map[] = {
0026
0027 { "Headphone", NULL, "rt5682 HPOL" },
0028 { "Headphone", NULL, "rt5682 HPOR" },
0029 { "rt5682 IN1P", NULL, "Headset Mic" },
0030 };
0031
0032 static const struct snd_kcontrol_new rt5682_controls[] = {
0033 SOC_DAPM_PIN_SWITCH("Headphone"),
0034 SOC_DAPM_PIN_SWITCH("Headset Mic"),
0035 };
0036
0037 static struct snd_soc_jack_pin rt5682_jack_pins[] = {
0038 {
0039 .pin = "Headphone",
0040 .mask = SND_JACK_HEADPHONE,
0041 },
0042 {
0043 .pin = "Headset Mic",
0044 .mask = SND_JACK_MICROPHONE,
0045 },
0046 };
0047
0048 static int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd)
0049 {
0050 struct snd_soc_card *card = rtd->card;
0051 struct mc_private *ctx = snd_soc_card_get_drvdata(card);
0052 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
0053 struct snd_soc_component *component = codec_dai->component;
0054 struct snd_soc_jack *jack;
0055 int ret;
0056
0057 card->components = devm_kasprintf(card->dev, GFP_KERNEL,
0058 "%s hs:rt5682",
0059 card->components);
0060 if (!card->components)
0061 return -ENOMEM;
0062
0063 ret = snd_soc_add_card_controls(card, rt5682_controls,
0064 ARRAY_SIZE(rt5682_controls));
0065 if (ret) {
0066 dev_err(card->dev, "rt5682 control addition failed: %d\n", ret);
0067 return ret;
0068 }
0069
0070 ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets,
0071 ARRAY_SIZE(rt5682_widgets));
0072 if (ret) {
0073 dev_err(card->dev, "rt5682 widgets addition failed: %d\n", ret);
0074 return ret;
0075 }
0076
0077 ret = snd_soc_dapm_add_routes(&card->dapm, rt5682_map,
0078 ARRAY_SIZE(rt5682_map));
0079
0080 if (ret) {
0081 dev_err(card->dev, "rt5682 map addition failed: %d\n", ret);
0082 return ret;
0083 }
0084
0085 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
0086 SND_JACK_HEADSET | SND_JACK_BTN_0 |
0087 SND_JACK_BTN_1 | SND_JACK_BTN_2 |
0088 SND_JACK_BTN_3,
0089 &ctx->sdw_headset,
0090 rt5682_jack_pins,
0091 ARRAY_SIZE(rt5682_jack_pins));
0092 if (ret) {
0093 dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n",
0094 ret);
0095 return ret;
0096 }
0097
0098 jack = &ctx->sdw_headset;
0099
0100 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0101 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0102 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0103 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0104
0105 ret = snd_soc_component_set_jack(component, jack, NULL);
0106
0107 if (ret)
0108 dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
0109 ret);
0110
0111 return ret;
0112 }
0113
0114 int sof_sdw_rt5682_init(struct snd_soc_card *card,
0115 const struct snd_soc_acpi_link_adr *link,
0116 struct snd_soc_dai_link *dai_links,
0117 struct sof_sdw_codec_info *info,
0118 bool playback)
0119 {
0120
0121
0122
0123
0124 if (!playback)
0125 return 0;
0126
0127 dai_links->init = rt5682_rtd_init;
0128
0129 return 0;
0130 }