Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 // Copyright (c) 2020 Intel Corporation
0003 
0004 /*
0005  *  sof_sdw_rt700 - Helpers to handle RT700 from generic machine driver
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/errno.h>
0010 #include <linux/input.h>
0011 #include <sound/control.h>
0012 #include <sound/soc.h>
0013 #include <sound/soc-acpi.h>
0014 #include <sound/soc-dapm.h>
0015 #include <sound/jack.h>
0016 #include "sof_sdw_common.h"
0017 
0018 static const struct snd_soc_dapm_widget rt700_widgets[] = {
0019     SND_SOC_DAPM_HP("Headphones", NULL),
0020     SND_SOC_DAPM_MIC("AMIC", NULL),
0021     SND_SOC_DAPM_SPK("Speaker", NULL),
0022 };
0023 
0024 static const struct snd_soc_dapm_route rt700_map[] = {
0025     /* Headphones */
0026     { "Headphones", NULL, "rt700 HP" },
0027     { "Speaker", NULL, "rt700 SPK" },
0028     { "rt700 MIC2", NULL, "AMIC" },
0029 };
0030 
0031 static const struct snd_kcontrol_new rt700_controls[] = {
0032     SOC_DAPM_PIN_SWITCH("Headphones"),
0033     SOC_DAPM_PIN_SWITCH("AMIC"),
0034     SOC_DAPM_PIN_SWITCH("Speaker"),
0035 };
0036 
0037 static struct snd_soc_jack_pin rt700_jack_pins[] = {
0038     {
0039         .pin    = "Headphones",
0040         .mask   = SND_JACK_HEADPHONE,
0041     },
0042     {
0043         .pin    = "AMIC",
0044         .mask   = SND_JACK_MICROPHONE,
0045     },
0046 };
0047 
0048 static int rt700_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:rt700",
0059                       card->components);
0060     if (!card->components)
0061         return -ENOMEM;
0062 
0063     ret = snd_soc_add_card_controls(card, rt700_controls,
0064                     ARRAY_SIZE(rt700_controls));
0065     if (ret) {
0066         dev_err(card->dev, "rt700 controls addition failed: %d\n", ret);
0067         return ret;
0068     }
0069 
0070     ret = snd_soc_dapm_new_controls(&card->dapm, rt700_widgets,
0071                     ARRAY_SIZE(rt700_widgets));
0072     if (ret) {
0073         dev_err(card->dev, "rt700 widgets addition failed: %d\n", ret);
0074         return ret;
0075     }
0076 
0077     ret = snd_soc_dapm_add_routes(&card->dapm, rt700_map,
0078                       ARRAY_SIZE(rt700_map));
0079 
0080     if (ret) {
0081         dev_err(card->dev, "rt700 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                      rt700_jack_pins,
0091                      ARRAY_SIZE(rt700_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     if (ret)
0107         dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
0108             ret);
0109 
0110     return ret;
0111 }
0112 
0113 int sof_sdw_rt700_init(struct snd_soc_card *card,
0114                const struct snd_soc_acpi_link_adr *link,
0115                struct snd_soc_dai_link *dai_links,
0116                struct sof_sdw_codec_info *info,
0117                bool playback)
0118 {
0119     /*
0120      * headset should be initialized once.
0121      * Do it with dai link for playback.
0122      */
0123     if (!playback)
0124         return 0;
0125 
0126     dai_links->init = rt700_rtd_init;
0127 
0128     return 0;
0129 }