Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  bytcht_es8316.c - ASoc Machine driver for Intel Baytrail/Cherrytrail
0004  *                    platforms with Everest ES8316 SoC
0005  *
0006  *  Copyright (C) 2017 Endless Mobile, Inc.
0007  *  Authors: David Yang <yangxiaohua@everest-semi.com>,
0008  *           Daniel Drake <drake@endlessm.com>
0009  *
0010  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0011  *
0012  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0013  */
0014 #include <linux/acpi.h>
0015 #include <linux/clk.h>
0016 #include <linux/device.h>
0017 #include <linux/dmi.h>
0018 #include <linux/gpio/consumer.h>
0019 #include <linux/i2c.h>
0020 #include <linux/init.h>
0021 #include <linux/input.h>
0022 #include <linux/module.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/slab.h>
0025 #include <sound/jack.h>
0026 #include <sound/pcm.h>
0027 #include <sound/pcm_params.h>
0028 #include <sound/soc.h>
0029 #include <sound/soc-acpi.h>
0030 #include "../atom/sst-atom-controls.h"
0031 #include "../common/soc-intel-quirks.h"
0032 
0033 /* jd-inv + terminating entry */
0034 #define MAX_NO_PROPS 2
0035 
0036 struct byt_cht_es8316_private {
0037     struct clk *mclk;
0038     struct snd_soc_jack jack;
0039     struct gpio_desc *speaker_en_gpio;
0040     struct device *codec_dev;
0041     bool speaker_en;
0042 };
0043 
0044 enum {
0045     BYT_CHT_ES8316_INTMIC_IN1_MAP,
0046     BYT_CHT_ES8316_INTMIC_IN2_MAP,
0047 };
0048 
0049 #define BYT_CHT_ES8316_MAP(quirk)       ((quirk) & GENMASK(3, 0))
0050 #define BYT_CHT_ES8316_SSP0         BIT(16)
0051 #define BYT_CHT_ES8316_MONO_SPEAKER     BIT(17)
0052 #define BYT_CHT_ES8316_JD_INVERTED      BIT(18)
0053 
0054 static unsigned long quirk;
0055 
0056 static int quirk_override = -1;
0057 module_param_named(quirk, quirk_override, int, 0444);
0058 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
0059 
0060 static void log_quirks(struct device *dev)
0061 {
0062     if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN1_MAP)
0063         dev_info(dev, "quirk IN1_MAP enabled");
0064     if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN2_MAP)
0065         dev_info(dev, "quirk IN2_MAP enabled");
0066     if (quirk & BYT_CHT_ES8316_SSP0)
0067         dev_info(dev, "quirk SSP0 enabled");
0068     if (quirk & BYT_CHT_ES8316_MONO_SPEAKER)
0069         dev_info(dev, "quirk MONO_SPEAKER enabled\n");
0070     if (quirk & BYT_CHT_ES8316_JD_INVERTED)
0071         dev_info(dev, "quirk JD_INVERTED enabled\n");
0072 }
0073 
0074 static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
0075     struct snd_kcontrol *kcontrol, int event)
0076 {
0077     struct snd_soc_card *card = w->dapm->card;
0078     struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
0079 
0080     if (SND_SOC_DAPM_EVENT_ON(event))
0081         priv->speaker_en = true;
0082     else
0083         priv->speaker_en = false;
0084 
0085     gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
0086 
0087     return 0;
0088 }
0089 
0090 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
0091     SND_SOC_DAPM_SPK("Speaker", NULL),
0092     SND_SOC_DAPM_HP("Headphone", NULL),
0093     SND_SOC_DAPM_MIC("Headset Mic", NULL),
0094     SND_SOC_DAPM_MIC("Internal Mic", NULL),
0095 
0096     SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
0097                 byt_cht_es8316_speaker_power_event,
0098                 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
0099 };
0100 
0101 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
0102     {"Headphone", NULL, "HPOL"},
0103     {"Headphone", NULL, "HPOR"},
0104 
0105     /*
0106      * There is no separate speaker output instead the speakers are muxed to
0107      * the HP outputs. The mux is controlled by the "Speaker Power" supply.
0108      */
0109     {"Speaker", NULL, "HPOL"},
0110     {"Speaker", NULL, "HPOR"},
0111     {"Speaker", NULL, "Speaker Power"},
0112 };
0113 
0114 static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in1_map[] = {
0115     {"MIC1", NULL, "Internal Mic"},
0116     {"MIC2", NULL, "Headset Mic"},
0117 };
0118 
0119 static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in2_map[] = {
0120     {"MIC2", NULL, "Internal Mic"},
0121     {"MIC1", NULL, "Headset Mic"},
0122 };
0123 
0124 static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
0125     {"Playback", NULL, "ssp0 Tx"},
0126     {"ssp0 Tx", NULL, "modem_out"},
0127     {"modem_in", NULL, "ssp0 Rx"},
0128     {"ssp0 Rx", NULL, "Capture"},
0129 };
0130 
0131 static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
0132     {"Playback", NULL, "ssp2 Tx"},
0133     {"ssp2 Tx", NULL, "codec_out0"},
0134     {"ssp2 Tx", NULL, "codec_out1"},
0135     {"codec_in0", NULL, "ssp2 Rx" },
0136     {"codec_in1", NULL, "ssp2 Rx" },
0137     {"ssp2 Rx", NULL, "Capture"},
0138 };
0139 
0140 static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
0141     SOC_DAPM_PIN_SWITCH("Speaker"),
0142     SOC_DAPM_PIN_SWITCH("Headphone"),
0143     SOC_DAPM_PIN_SWITCH("Headset Mic"),
0144     SOC_DAPM_PIN_SWITCH("Internal Mic"),
0145 };
0146 
0147 static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
0148     {
0149         .pin    = "Headphone",
0150         .mask   = SND_JACK_HEADPHONE,
0151     },
0152     {
0153         .pin    = "Headset Mic",
0154         .mask   = SND_JACK_MICROPHONE,
0155     },
0156 };
0157 
0158 static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
0159 {
0160     struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component;
0161     struct snd_soc_card *card = runtime->card;
0162     struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
0163     const struct snd_soc_dapm_route *custom_map;
0164     int num_routes;
0165     int ret;
0166 
0167     card->dapm.idle_bias_off = true;
0168 
0169     switch (BYT_CHT_ES8316_MAP(quirk)) {
0170     case BYT_CHT_ES8316_INTMIC_IN1_MAP:
0171     default:
0172         custom_map = byt_cht_es8316_intmic_in1_map;
0173         num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in1_map);
0174         break;
0175     case BYT_CHT_ES8316_INTMIC_IN2_MAP:
0176         custom_map = byt_cht_es8316_intmic_in2_map;
0177         num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in2_map);
0178         break;
0179     }
0180     ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
0181     if (ret)
0182         return ret;
0183 
0184     if (quirk & BYT_CHT_ES8316_SSP0) {
0185         custom_map = byt_cht_es8316_ssp0_map;
0186         num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
0187     } else {
0188         custom_map = byt_cht_es8316_ssp2_map;
0189         num_routes = ARRAY_SIZE(byt_cht_es8316_ssp2_map);
0190     }
0191     ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
0192     if (ret)
0193         return ret;
0194 
0195     /*
0196      * The firmware might enable the clock at boot (this information
0197      * may or may not be reflected in the enable clock register).
0198      * To change the rate we must disable the clock first to cover these
0199      * cases. Due to common clock framework restrictions that do not allow
0200      * to disable a clock that has not been enabled, we need to enable
0201      * the clock first.
0202      */
0203     ret = clk_prepare_enable(priv->mclk);
0204     if (!ret)
0205         clk_disable_unprepare(priv->mclk);
0206 
0207     ret = clk_set_rate(priv->mclk, 19200000);
0208     if (ret)
0209         dev_err(card->dev, "unable to set MCLK rate\n");
0210 
0211     ret = clk_prepare_enable(priv->mclk);
0212     if (ret)
0213         dev_err(card->dev, "unable to enable MCLK\n");
0214 
0215     ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000,
0216                      SND_SOC_CLOCK_IN);
0217     if (ret < 0) {
0218         dev_err(card->dev, "can't set codec clock %d\n", ret);
0219         return ret;
0220     }
0221 
0222     ret = snd_soc_card_jack_new_pins(card, "Headset",
0223                      SND_JACK_HEADSET | SND_JACK_BTN_0,
0224                      &priv->jack, byt_cht_es8316_jack_pins,
0225                      ARRAY_SIZE(byt_cht_es8316_jack_pins));
0226     if (ret) {
0227         dev_err(card->dev, "jack creation failed %d\n", ret);
0228         return ret;
0229     }
0230 
0231     snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
0232     snd_soc_component_set_jack(codec, &priv->jack, NULL);
0233 
0234     return 0;
0235 }
0236 
0237 static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
0238                 struct snd_pcm_hw_params *params)
0239 {
0240     struct snd_interval *rate = hw_param_interval(params,
0241             SNDRV_PCM_HW_PARAM_RATE);
0242     struct snd_interval *channels = hw_param_interval(params,
0243                         SNDRV_PCM_HW_PARAM_CHANNELS);
0244     int ret, bits;
0245 
0246     /* The DSP will covert the FE rate to 48k, stereo */
0247     rate->min = rate->max = 48000;
0248     channels->min = channels->max = 2;
0249 
0250     if (quirk & BYT_CHT_ES8316_SSP0) {
0251         /* set SSP0 to 16-bit */
0252         params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
0253         bits = 16;
0254     } else {
0255         /* set SSP2 to 24-bit */
0256         params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
0257         bits = 24;
0258     }
0259 
0260     /*
0261      * Default mode for SSP configuration is TDM 4 slot, override config
0262      * with explicit setting to I2S 2ch 24-bit. The word length is set with
0263      * dai_set_tdm_slot() since there is no other API exposed
0264      */
0265     ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0),
0266                 SND_SOC_DAIFMT_I2S     |
0267                 SND_SOC_DAIFMT_NB_NF   |
0268                 SND_SOC_DAIFMT_BP_FP
0269         );
0270     if (ret < 0) {
0271         dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
0272         return ret;
0273     }
0274 
0275     ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits);
0276     if (ret < 0) {
0277         dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
0278         return ret;
0279     }
0280 
0281     return 0;
0282 }
0283 
0284 static int byt_cht_es8316_aif1_startup(struct snd_pcm_substream *substream)
0285 {
0286     return snd_pcm_hw_constraint_single(substream->runtime,
0287             SNDRV_PCM_HW_PARAM_RATE, 48000);
0288 }
0289 
0290 static const struct snd_soc_ops byt_cht_es8316_aif1_ops = {
0291     .startup = byt_cht_es8316_aif1_startup,
0292 };
0293 
0294 SND_SOC_DAILINK_DEF(dummy,
0295     DAILINK_COMP_ARRAY(COMP_DUMMY()));
0296 
0297 SND_SOC_DAILINK_DEF(media,
0298     DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
0299 
0300 SND_SOC_DAILINK_DEF(deepbuffer,
0301     DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
0302 
0303 SND_SOC_DAILINK_DEF(ssp2_port,
0304     DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
0305 SND_SOC_DAILINK_DEF(ssp2_codec,
0306     DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ESSX8316:00", "ES8316 HiFi")));
0307 
0308 SND_SOC_DAILINK_DEF(platform,
0309     DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
0310 
0311 static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
0312     [MERR_DPCM_AUDIO] = {
0313         .name = "Audio Port",
0314         .stream_name = "Audio",
0315         .nonatomic = true,
0316         .dynamic = 1,
0317         .dpcm_playback = 1,
0318         .dpcm_capture = 1,
0319         .ops = &byt_cht_es8316_aif1_ops,
0320         SND_SOC_DAILINK_REG(media, dummy, platform),
0321     },
0322 
0323     [MERR_DPCM_DEEP_BUFFER] = {
0324         .name = "Deep-Buffer Audio Port",
0325         .stream_name = "Deep-Buffer Audio",
0326         .nonatomic = true,
0327         .dynamic = 1,
0328         .dpcm_playback = 1,
0329         .ops = &byt_cht_es8316_aif1_ops,
0330         SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
0331     },
0332 
0333         /* back ends */
0334     {
0335         .name = "SSP2-Codec",
0336         .id = 0,
0337         .no_pcm = 1,
0338         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
0339                         | SND_SOC_DAIFMT_CBC_CFC,
0340         .be_hw_params_fixup = byt_cht_es8316_codec_fixup,
0341         .dpcm_playback = 1,
0342         .dpcm_capture = 1,
0343         .init = byt_cht_es8316_init,
0344         SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
0345     },
0346 };
0347 
0348 
0349 /* SoC card */
0350 static char codec_name[SND_ACPI_I2C_ID_LEN];
0351 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
0352 static char long_name[50]; /* = "bytcht-es8316-*-spk-*-mic" */
0353 #endif
0354 static char components_string[32]; /* = "cfg-spk:* cfg-mic:* */
0355 
0356 static int byt_cht_es8316_suspend(struct snd_soc_card *card)
0357 {
0358     struct snd_soc_component *component;
0359 
0360     for_each_card_components(card, component) {
0361         if (!strcmp(component->name, codec_name)) {
0362             dev_dbg(component->dev, "disabling jack detect before suspend\n");
0363             snd_soc_component_set_jack(component, NULL, NULL);
0364             break;
0365         }
0366     }
0367 
0368     return 0;
0369 }
0370 
0371 static int byt_cht_es8316_resume(struct snd_soc_card *card)
0372 {
0373     struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
0374     struct snd_soc_component *component;
0375 
0376     for_each_card_components(card, component) {
0377         if (!strcmp(component->name, codec_name)) {
0378             dev_dbg(component->dev, "re-enabling jack detect after resume\n");
0379             snd_soc_component_set_jack(component, &priv->jack, NULL);
0380             break;
0381         }
0382     }
0383 
0384     /*
0385      * Some Cherry Trail boards with an ES8316 codec have a bug in their
0386      * ACPI tables where the MSSL1680 touchscreen's _PS0 and _PS3 methods
0387      * wrongly also set the speaker-enable GPIO to 1/0. Testing has shown
0388      * that this really is a bug and the GPIO has no influence on the
0389      * touchscreen at all.
0390      *
0391      * The silead.c touchscreen driver does not support runtime suspend, so
0392      * the GPIO can only be changed underneath us during a system suspend.
0393      * This resume() function runs from a pm complete() callback, and thus
0394      * is guaranteed to run after the touchscreen driver/ACPI-subsys has
0395      * brought the touchscreen back up again (and thus changed the GPIO).
0396      *
0397      * So to work around this we pass GPIOD_FLAGS_BIT_NONEXCLUSIVE when
0398      * requesting the GPIO and we set its value here to undo any changes
0399      * done by the touchscreen's broken _PS0 ACPI method.
0400      */
0401     gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
0402 
0403     return 0;
0404 }
0405 
0406 /* use space before codec name to simplify card ID, and simplify driver name */
0407 #define SOF_CARD_NAME "bytcht es8316" /* card name will be 'sof-bytcht es8316' */
0408 #define SOF_DRIVER_NAME "SOF"
0409 
0410 #define CARD_NAME "bytcht-es8316"
0411 #define DRIVER_NAME NULL /* card name will be used for driver name */
0412 
0413 static struct snd_soc_card byt_cht_es8316_card = {
0414     .owner = THIS_MODULE,
0415     .dai_link = byt_cht_es8316_dais,
0416     .num_links = ARRAY_SIZE(byt_cht_es8316_dais),
0417     .dapm_widgets = byt_cht_es8316_widgets,
0418     .num_dapm_widgets = ARRAY_SIZE(byt_cht_es8316_widgets),
0419     .dapm_routes = byt_cht_es8316_audio_map,
0420     .num_dapm_routes = ARRAY_SIZE(byt_cht_es8316_audio_map),
0421     .controls = byt_cht_es8316_controls,
0422     .num_controls = ARRAY_SIZE(byt_cht_es8316_controls),
0423     .fully_routed = true,
0424     .suspend_pre = byt_cht_es8316_suspend,
0425     .resume_post = byt_cht_es8316_resume,
0426 };
0427 
0428 static const struct acpi_gpio_params first_gpio = { 0, 0, false };
0429 
0430 static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
0431     { "speaker-enable-gpios", &first_gpio, 1 },
0432     { },
0433 };
0434 
0435 /* Please keep this list alphabetically sorted */
0436 static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
0437     {   /* Irbis NB41 */
0438         .matches = {
0439             DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"),
0440             DMI_MATCH(DMI_PRODUCT_NAME, "NB41"),
0441         },
0442         .driver_data = (void *)(BYT_CHT_ES8316_SSP0
0443                     | BYT_CHT_ES8316_INTMIC_IN2_MAP
0444                     | BYT_CHT_ES8316_JD_INVERTED),
0445     },
0446     {   /* Teclast X98 Plus II */
0447         .matches = {
0448             DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
0449             DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
0450         },
0451         .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN1_MAP
0452                     | BYT_CHT_ES8316_JD_INVERTED),
0453     },
0454     {}
0455 };
0456 
0457 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
0458 {
0459     struct device *dev = &pdev->dev;
0460     static const char * const mic_name[] = { "in1", "in2" };
0461     struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
0462     struct property_entry props[MAX_NO_PROPS] = {};
0463     struct byt_cht_es8316_private *priv;
0464     const struct dmi_system_id *dmi_id;
0465     struct fwnode_handle *fwnode;
0466     const char *platform_name;
0467     struct acpi_device *adev;
0468     struct device *codec_dev;
0469     bool sof_parent;
0470     unsigned int cnt = 0;
0471     int dai_index = 0;
0472     int i;
0473     int ret = 0;
0474 
0475     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0476     if (!priv)
0477         return -ENOMEM;
0478 
0479     /* fix index of codec dai */
0480     for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) {
0481         if (!strcmp(byt_cht_es8316_dais[i].codecs->name,
0482                 "i2c-ESSX8316:00")) {
0483             dai_index = i;
0484             break;
0485         }
0486     }
0487 
0488     /* fixup codec name based on HID */
0489     adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
0490     if (adev) {
0491         snprintf(codec_name, sizeof(codec_name),
0492              "i2c-%s", acpi_dev_name(adev));
0493         put_device(&adev->dev);
0494         byt_cht_es8316_dais[dai_index].codecs->name = codec_name;
0495     } else {
0496         dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
0497         return -ENXIO;
0498     }
0499 
0500     /* override platform name, if required */
0501     byt_cht_es8316_card.dev = dev;
0502     platform_name = mach->mach_params.platform;
0503 
0504     ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card,
0505                             platform_name);
0506     if (ret)
0507         return ret;
0508 
0509     /* Check for BYTCR or other platform and setup quirks */
0510     dmi_id = dmi_first_match(byt_cht_es8316_quirk_table);
0511     if (dmi_id) {
0512         quirk = (unsigned long)dmi_id->driver_data;
0513     } else if (soc_intel_is_byt() &&
0514            mach->mach_params.acpi_ipc_irq_index == 0) {
0515         /* On BYTCR default to SSP0, internal-mic-in2-map, mono-spk */
0516         quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP |
0517             BYT_CHT_ES8316_MONO_SPEAKER;
0518     } else {
0519         /* Others default to internal-mic-in1-map, mono-speaker */
0520         quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP |
0521             BYT_CHT_ES8316_MONO_SPEAKER;
0522     }
0523     if (quirk_override != -1) {
0524         dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
0525              quirk, quirk_override);
0526         quirk = quirk_override;
0527     }
0528     log_quirks(dev);
0529 
0530     if (quirk & BYT_CHT_ES8316_SSP0)
0531         byt_cht_es8316_dais[dai_index].cpus->dai_name = "ssp0-port";
0532 
0533     /* get the clock */
0534     priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
0535     if (IS_ERR(priv->mclk))
0536         return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n");
0537 
0538     codec_dev = acpi_get_first_physical_node(adev);
0539     if (!codec_dev)
0540         return -EPROBE_DEFER;
0541     priv->codec_dev = get_device(codec_dev);
0542 
0543     if (quirk & BYT_CHT_ES8316_JD_INVERTED)
0544         props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
0545 
0546     if (cnt) {
0547         fwnode = fwnode_create_software_node(props, NULL);
0548         if (IS_ERR(fwnode)) {
0549             put_device(codec_dev);
0550             return PTR_ERR(fwnode);
0551         }
0552 
0553         ret = device_add_software_node(codec_dev, to_software_node(fwnode));
0554 
0555         fwnode_handle_put(fwnode);
0556 
0557         if (ret) {
0558             put_device(codec_dev);
0559             return ret;
0560         }
0561     }
0562 
0563     /* get speaker enable GPIO */
0564     devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios);
0565     priv->speaker_en_gpio =
0566         gpiod_get_optional(codec_dev, "speaker-enable",
0567                    /* see comment in byt_cht_es8316_resume() */
0568                    GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
0569     if (IS_ERR(priv->speaker_en_gpio)) {
0570         ret = dev_err_probe(dev, PTR_ERR(priv->speaker_en_gpio),
0571                     "get speaker GPIO failed\n");
0572         goto err_put_codec;
0573     }
0574 
0575     snprintf(components_string, sizeof(components_string),
0576          "cfg-spk:%s cfg-mic:%s",
0577          (quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "1" : "2",
0578          mic_name[BYT_CHT_ES8316_MAP(quirk)]);
0579     byt_cht_es8316_card.components = components_string;
0580 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
0581     snprintf(long_name, sizeof(long_name), "bytcht-es8316-%s-spk-%s-mic",
0582          (quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "mono" : "stereo",
0583          mic_name[BYT_CHT_ES8316_MAP(quirk)]);
0584     byt_cht_es8316_card.long_name = long_name;
0585 #endif
0586 
0587     sof_parent = snd_soc_acpi_sof_parent(dev);
0588 
0589     /* set card and driver name */
0590     if (sof_parent) {
0591         byt_cht_es8316_card.name = SOF_CARD_NAME;
0592         byt_cht_es8316_card.driver_name = SOF_DRIVER_NAME;
0593     } else {
0594         byt_cht_es8316_card.name = CARD_NAME;
0595         byt_cht_es8316_card.driver_name = DRIVER_NAME;
0596     }
0597 
0598     /* set pm ops */
0599     if (sof_parent)
0600         dev->driver->pm = &snd_soc_pm_ops;
0601 
0602     /* register the soc card */
0603     snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
0604 
0605     ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
0606     if (ret) {
0607         gpiod_put(priv->speaker_en_gpio);
0608         dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
0609         goto err_put_codec;
0610     }
0611     platform_set_drvdata(pdev, &byt_cht_es8316_card);
0612     return 0;
0613 
0614 err_put_codec:
0615     device_remove_software_node(priv->codec_dev);
0616     put_device(priv->codec_dev);
0617     return ret;
0618 }
0619 
0620 static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
0621 {
0622     struct snd_soc_card *card = platform_get_drvdata(pdev);
0623     struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
0624 
0625     gpiod_put(priv->speaker_en_gpio);
0626     device_remove_software_node(priv->codec_dev);
0627     put_device(priv->codec_dev);
0628     return 0;
0629 }
0630 
0631 static struct platform_driver snd_byt_cht_es8316_mc_driver = {
0632     .driver = {
0633         .name = "bytcht_es8316",
0634     },
0635     .probe = snd_byt_cht_es8316_mc_probe,
0636     .remove = snd_byt_cht_es8316_mc_remove,
0637 };
0638 
0639 module_platform_driver(snd_byt_cht_es8316_mc_driver);
0640 MODULE_DESCRIPTION("ASoC Intel(R) Baytrail/Cherrytrail Machine driver");
0641 MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>");
0642 MODULE_LICENSE("GPL v2");
0643 MODULE_ALIAS("platform:bytcht_es8316");