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_rt5682 - Helpers to handle RT5682 from generic machine driver
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     /*Headphones*/
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      * headset should be initialized once.
0122      * Do it with dai link for playback.
0123      */
0124     if (!playback)
0125         return 0;
0126 
0127     dai_links->init = rt5682_rtd_init;
0128 
0129     return 0;
0130 }