Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
0004 //
0005 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
0006 //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
0007 //
0008 
0009 #include <linux/clk.h>
0010 #include <linux/dmi.h>
0011 #include <linux/i2c.h>
0012 #include <linux/input.h>
0013 #include <linux/module.h>
0014 #include <linux/platform_device.h>
0015 #include <sound/core.h>
0016 #include <sound/jack.h>
0017 #include <sound/pcm.h>
0018 #include <sound/pcm_params.h>
0019 #include <sound/rt5682.h>
0020 #include <sound/soc.h>
0021 #include <sound/soc-acpi.h>
0022 #include "../../common/soc-intel-quirks.h"
0023 #include "../../../codecs/rt5682.h"
0024 
0025 #define AVS_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
0026 #define AVS_RT5682_SSP_CODEC_MASK   (GENMASK(2, 0))
0027 #define AVS_RT5682_MCLK_EN      BIT(3)
0028 #define AVS_RT5682_MCLK_24MHZ       BIT(4)
0029 
0030 /* Default: MCLK on, MCLK 19.2M, SSP0 */
0031 static unsigned long avs_rt5682_quirk = AVS_RT5682_MCLK_EN | AVS_RT5682_SSP_CODEC(0);
0032 
0033 static int avs_rt5682_quirk_cb(const struct dmi_system_id *id)
0034 {
0035     avs_rt5682_quirk = (unsigned long)id->driver_data;
0036     return 1;
0037 }
0038 
0039 static const struct dmi_system_id avs_rt5682_quirk_table[] = {
0040     {
0041         .callback = avs_rt5682_quirk_cb,
0042         .matches = {
0043             DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
0044             DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"),
0045         },
0046         .driver_data = (void *)(AVS_RT5682_MCLK_EN |
0047                     AVS_RT5682_MCLK_24MHZ |
0048                     AVS_RT5682_SSP_CODEC(1)),
0049     },
0050     {
0051         .callback = avs_rt5682_quirk_cb,
0052         .matches = {
0053             DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
0054             DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
0055         },
0056         .driver_data = (void *)(AVS_RT5682_MCLK_EN |
0057                     AVS_RT5682_SSP_CODEC(0)),
0058     },
0059     {}
0060 };
0061 
0062 static const struct snd_kcontrol_new card_controls[] = {
0063     SOC_DAPM_PIN_SWITCH("Headphone Jack"),
0064     SOC_DAPM_PIN_SWITCH("Headset Mic"),
0065 };
0066 
0067 static const struct snd_soc_dapm_widget card_widgets[] = {
0068     SND_SOC_DAPM_HP("Headphone Jack", NULL),
0069     SND_SOC_DAPM_MIC("Headset Mic", NULL),
0070 };
0071 
0072 static const struct snd_soc_dapm_route card_base_routes[] = {
0073     /* HP jack connectors - unknown if we have jack detect */
0074     { "Headphone Jack", NULL, "HPOL" },
0075     { "Headphone Jack", NULL, "HPOR" },
0076 
0077     /* other jacks */
0078     { "IN1P", NULL, "Headset Mic" },
0079 };
0080 
0081 static int avs_rt5682_codec_init(struct snd_soc_pcm_runtime *runtime)
0082 {
0083     struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component;
0084     struct snd_soc_jack *jack;
0085     struct snd_soc_card *card = runtime->card;
0086     int ret;
0087 
0088     jack = snd_soc_card_get_drvdata(card);
0089 
0090     /* Need to enable ASRC function for 24MHz mclk rate */
0091     if ((avs_rt5682_quirk & AVS_RT5682_MCLK_EN) &&
0092         (avs_rt5682_quirk & AVS_RT5682_MCLK_24MHZ)) {
0093         rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER |
0094                     RT5682_AD_STEREO1_FILTER, RT5682_CLK_SEL_I2S1_ASRC);
0095     }
0096 
0097     /*
0098      * Headset buttons map to the google Reference headset.
0099      * These can be configured by userspace.
0100      */
0101     ret = snd_soc_card_jack_new(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 |
0102                     SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, jack);
0103     if (ret) {
0104         dev_err(card->dev, "Headset Jack creation failed: %d\n", ret);
0105         return ret;
0106     }
0107 
0108     snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0109     snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
0110     snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
0111     snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
0112 
0113     ret = snd_soc_component_set_jack(component, jack, NULL);
0114     if (ret) {
0115         dev_err(card->dev, "Headset Jack call-back failed: %d\n", ret);
0116         return ret;
0117     }
0118 
0119     return 0;
0120 };
0121 
0122 static int
0123 avs_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
0124 {
0125     struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream);
0126     struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0);
0127     int clk_id, clk_freq;
0128     int pll_out, ret;
0129 
0130     if (avs_rt5682_quirk & AVS_RT5682_MCLK_EN) {
0131         clk_id = RT5682_PLL1_S_MCLK;
0132         if (avs_rt5682_quirk & AVS_RT5682_MCLK_24MHZ)
0133             clk_freq = 24000000;
0134         else
0135             clk_freq = 19200000;
0136     } else {
0137         clk_id = RT5682_PLL1_S_BCLK1;
0138         clk_freq = params_rate(params) * 50;
0139     }
0140 
0141     pll_out = params_rate(params) * 512;
0142 
0143     ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out);
0144     if (ret < 0)
0145         dev_err(runtime->dev, "snd_soc_dai_set_pll err = %d\n", ret);
0146 
0147     /* Configure sysclk for codec */
0148     ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, pll_out, SND_SOC_CLOCK_IN);
0149     if (ret < 0)
0150         dev_err(runtime->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
0151 
0152     /* slot_width should equal or large than data length, set them be the same */
0153     ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2, params_width(params));
0154     if (ret < 0) {
0155         dev_err(runtime->dev, "set TDM slot err:%d\n", ret);
0156         return ret;
0157     }
0158 
0159     return 0;
0160 }
0161 
0162 static const struct snd_soc_ops avs_rt5682_ops = {
0163     .hw_params = avs_rt5682_hw_params,
0164 };
0165 
0166 static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port,
0167                    struct snd_soc_dai_link **dai_link)
0168 {
0169     struct snd_soc_dai_link_component *platform;
0170     struct snd_soc_dai_link *dl;
0171 
0172     dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL);
0173     platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL);
0174     if (!dl || !platform)
0175         return -ENOMEM;
0176 
0177     platform->name = platform_name;
0178 
0179     dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port);
0180     dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL);
0181     dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL);
0182     if (!dl->name || !dl->cpus || !dl->codecs)
0183         return -ENOMEM;
0184 
0185     dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port);
0186     dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10EC5682:00");
0187     dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt5682-aif1");
0188     if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name)
0189         return -ENOMEM;
0190 
0191     dl->num_cpus = 1;
0192     dl->num_codecs = 1;
0193     dl->platforms = platform;
0194     dl->num_platforms = 1;
0195     dl->id = 0;
0196     dl->init = avs_rt5682_codec_init;
0197     dl->ops = &avs_rt5682_ops;
0198     dl->nonatomic = 1;
0199     dl->no_pcm = 1;
0200     dl->dpcm_capture = 1;
0201     dl->dpcm_playback = 1;
0202 
0203     *dai_link = dl;
0204 
0205     return 0;
0206 }
0207 
0208 static int avs_create_dapm_routes(struct device *dev, int ssp_port,
0209                   struct snd_soc_dapm_route **routes, int *num_routes)
0210 {
0211     struct snd_soc_dapm_route *dr;
0212     const int num_base = ARRAY_SIZE(card_base_routes);
0213     const int num_dr = num_base + 2;
0214     int idx;
0215 
0216     dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL);
0217     if (!dr)
0218         return -ENOMEM;
0219 
0220     memcpy(dr, card_base_routes, num_base * sizeof(*dr));
0221 
0222     idx = num_base;
0223     dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback");
0224     dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port);
0225     if (!dr[idx].sink || !dr[idx].source)
0226         return -ENOMEM;
0227 
0228     idx++;
0229     dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port);
0230     dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture");
0231     if (!dr[idx].sink || !dr[idx].source)
0232         return -ENOMEM;
0233 
0234     *routes = dr;
0235     *num_routes = num_dr;
0236 
0237     return 0;
0238 }
0239 
0240 static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack)
0241 {
0242     struct snd_soc_component *component;
0243 
0244     for_each_card_components(card, component)
0245         snd_soc_component_set_jack(component, jack, NULL);
0246     return 0;
0247 }
0248 
0249 static int avs_card_remove(struct snd_soc_card *card)
0250 {
0251     return avs_card_set_jack(card, NULL);
0252 }
0253 
0254 static int avs_card_suspend_pre(struct snd_soc_card *card)
0255 {
0256     return avs_card_set_jack(card, NULL);
0257 }
0258 
0259 static int avs_card_resume_post(struct snd_soc_card *card)
0260 {
0261     struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card);
0262 
0263     return avs_card_set_jack(card, jack);
0264 }
0265 
0266 static int avs_rt5682_probe(struct platform_device *pdev)
0267 {
0268     struct snd_soc_dapm_route *routes;
0269     struct snd_soc_dai_link *dai_link;
0270     struct snd_soc_acpi_mach *mach;
0271     struct snd_soc_card *card;
0272     struct snd_soc_jack *jack;
0273     struct device *dev = &pdev->dev;
0274     const char *pname;
0275     int num_routes, ssp_port, ret;
0276 
0277     if (pdev->id_entry && pdev->id_entry->driver_data)
0278         avs_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data;
0279 
0280     dmi_check_system(avs_rt5682_quirk_table);
0281     dev_dbg(dev, "avs_rt5682_quirk = %lx\n", avs_rt5682_quirk);
0282 
0283     mach = dev_get_platdata(dev);
0284     pname = mach->mach_params.platform;
0285     ssp_port = __ffs(mach->mach_params.i2s_link_mask);
0286 
0287     ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link);
0288     if (ret) {
0289         dev_err(dev, "Failed to create dai link: %d", ret);
0290         return ret;
0291     }
0292 
0293     ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes);
0294     if (ret) {
0295         dev_err(dev, "Failed to create dapm routes: %d", ret);
0296         return ret;
0297     }
0298 
0299     jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL);
0300     card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
0301     if (!jack || !card)
0302         return -ENOMEM;
0303 
0304     card->name = "avs_rt5682";
0305     card->dev = dev;
0306     card->owner = THIS_MODULE;
0307     card->remove = avs_card_remove;
0308     card->suspend_pre = avs_card_suspend_pre;
0309     card->resume_post = avs_card_resume_post;
0310     card->dai_link = dai_link;
0311     card->num_links = 1;
0312     card->controls = card_controls;
0313     card->num_controls = ARRAY_SIZE(card_controls);
0314     card->dapm_widgets = card_widgets;
0315     card->num_dapm_widgets = ARRAY_SIZE(card_widgets);
0316     card->dapm_routes = routes;
0317     card->num_dapm_routes = num_routes;
0318     card->fully_routed = true;
0319     snd_soc_card_set_drvdata(card, jack);
0320 
0321     ret = snd_soc_fixup_dai_links_platform_name(card, pname);
0322     if (ret)
0323         return ret;
0324 
0325     return devm_snd_soc_register_card(dev, card);
0326 }
0327 
0328 static struct platform_driver avs_rt5682_driver = {
0329     .probe = avs_rt5682_probe,
0330     .driver = {
0331         .name = "avs_rt5682",
0332         .pm = &snd_soc_pm_ops,
0333     },
0334 };
0335 
0336 module_platform_driver(avs_rt5682_driver)
0337 
0338 MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>");
0339 MODULE_LICENSE("GPL");
0340 MODULE_ALIAS("platform:avs_rt5682");