linux/sound/soc/intel/boards/sof_sdw_rt700.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2020 Intel Corporation
   3
   4/*
   5 *  sof_sdw_rt700 - Helpers to handle RT700 from generic machine driver
   6 */
   7
   8#include <linux/device.h>
   9#include <linux/errno.h>
  10#include <linux/input.h>
  11#include <sound/soc.h>
  12#include <sound/soc-acpi.h>
  13#include <sound/jack.h>
  14#include "sof_sdw_common.h"
  15
  16static const struct snd_soc_dapm_widget rt700_widgets[] = {
  17        SND_SOC_DAPM_HP("Headphones", NULL),
  18        SND_SOC_DAPM_MIC("AMIC", NULL),
  19        SND_SOC_DAPM_SPK("Speaker", NULL),
  20};
  21
  22static const struct snd_soc_dapm_route rt700_map[] = {
  23        /* Headphones */
  24        { "Headphones", NULL, "HP" },
  25        { "Speaker", NULL, "SPK" },
  26        { "MIC2", NULL, "AMIC" },
  27};
  28
  29static const struct snd_kcontrol_new rt700_controls[] = {
  30        SOC_DAPM_PIN_SWITCH("Headphones"),
  31        SOC_DAPM_PIN_SWITCH("AMIC"),
  32        SOC_DAPM_PIN_SWITCH("Speaker"),
  33};
  34
  35static struct snd_soc_jack_pin rt700_jack_pins[] = {
  36        {
  37                .pin    = "Headphones",
  38                .mask   = SND_JACK_HEADPHONE,
  39        },
  40        {
  41                .pin    = "AMIC",
  42                .mask   = SND_JACK_MICROPHONE,
  43        },
  44};
  45
  46static int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd)
  47{
  48        struct snd_soc_card *card = rtd->card;
  49        struct mc_private *ctx = snd_soc_card_get_drvdata(card);
  50        struct snd_soc_component *component = rtd->codec_dai->component;
  51        struct snd_soc_jack *jack;
  52        int ret;
  53
  54        card->components = devm_kasprintf(card->dev, GFP_KERNEL,
  55                                          "%s hs:rt700",
  56                                          card->components);
  57        if (!card->components)
  58                return -ENOMEM;
  59
  60        ret = snd_soc_add_card_controls(card, rt700_controls,
  61                                        ARRAY_SIZE(rt700_controls));
  62        if (ret) {
  63                dev_err(card->dev, "rt700 controls addition failed: %d\n", ret);
  64                return ret;
  65        }
  66
  67        ret = snd_soc_dapm_new_controls(&card->dapm, rt700_widgets,
  68                                        ARRAY_SIZE(rt700_widgets));
  69        if (ret) {
  70                dev_err(card->dev, "rt700 widgets addition failed: %d\n", ret);
  71                return ret;
  72        }
  73
  74        ret = snd_soc_dapm_add_routes(&card->dapm, rt700_map,
  75                                      ARRAY_SIZE(rt700_map));
  76
  77        if (ret) {
  78                dev_err(card->dev, "rt700 map addition failed: %d\n", ret);
  79                return ret;
  80        }
  81
  82        ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
  83                                    SND_JACK_HEADSET | SND_JACK_BTN_0 |
  84                                    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
  85                                    SND_JACK_BTN_3,
  86                                    &ctx->sdw_headset,
  87                                    rt700_jack_pins,
  88                                    ARRAY_SIZE(rt700_jack_pins));
  89        if (ret) {
  90                dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n",
  91                        ret);
  92                return ret;
  93        }
  94
  95        jack = &ctx->sdw_headset;
  96
  97        snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_VOLUMEUP);
  98        snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_PLAYPAUSE);
  99        snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
 100        snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
 101
 102        ret = snd_soc_component_set_jack(component, jack, NULL);
 103        if (ret)
 104                dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n",
 105                        ret);
 106
 107        return ret;
 108}
 109
 110int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link,
 111                       struct snd_soc_dai_link *dai_links,
 112                       struct sof_sdw_codec_info *info,
 113                       bool playback)
 114{
 115        /*
 116         * headset should be initialized once.
 117         * Do it with dai link for playback.
 118         */
 119        if (!playback)
 120                return 0;
 121
 122        dai_links->init = rt700_rtd_init;
 123
 124        return 0;
 125}
 126