17aae816dSMark Brown /* 27aae816dSMark Brown * soc-util.c -- ALSA SoC Audio Layer utility functions 37aae816dSMark Brown * 47aae816dSMark Brown * Copyright 2009 Wolfson Microelectronics PLC. 57aae816dSMark Brown * 67aae816dSMark Brown * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 77aae816dSMark Brown * Liam Girdwood <lrg@slimlogic.co.uk> 87aae816dSMark Brown * 97aae816dSMark Brown * 107aae816dSMark Brown * This program is free software; you can redistribute it and/or modify it 117aae816dSMark Brown * under the terms of the GNU General Public License as published by the 127aae816dSMark Brown * Free Software Foundation; either version 2 of the License, or (at your 137aae816dSMark Brown * option) any later version. 147aae816dSMark Brown */ 157aae816dSMark Brown 16848dd8beSMark Brown #include <linux/platform_device.h> 17d81a6d71SPaul Gortmaker #include <linux/export.h> 187aae816dSMark Brown #include <sound/core.h> 197aae816dSMark Brown #include <sound/pcm.h> 207aae816dSMark Brown #include <sound/pcm_params.h> 217aae816dSMark Brown #include <sound/soc.h> 227aae816dSMark Brown 237aae816dSMark Brown int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots) 247aae816dSMark Brown { 257aae816dSMark Brown return sample_size * channels * tdm_slots; 267aae816dSMark Brown } 277aae816dSMark Brown EXPORT_SYMBOL_GPL(snd_soc_calc_frame_size); 287aae816dSMark Brown 297aae816dSMark Brown int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params) 307aae816dSMark Brown { 317aae816dSMark Brown int sample_size; 327aae816dSMark Brown 333d8b2ce0SMark Brown sample_size = snd_pcm_format_width(params_format(params)); 343d8b2ce0SMark Brown if (sample_size < 0) 353d8b2ce0SMark Brown return sample_size; 367aae816dSMark Brown 377aae816dSMark Brown return snd_soc_calc_frame_size(sample_size, params_channels(params), 387aae816dSMark Brown 1); 397aae816dSMark Brown } 407aae816dSMark Brown EXPORT_SYMBOL_GPL(snd_soc_params_to_frame_size); 417aae816dSMark Brown 42c0fa59dfSMark Brown int snd_soc_calc_bclk(int fs, int sample_size, int channels, int tdm_slots) 43c0fa59dfSMark Brown { 44c0fa59dfSMark Brown return fs * snd_soc_calc_frame_size(sample_size, channels, tdm_slots); 45c0fa59dfSMark Brown } 46c0fa59dfSMark Brown EXPORT_SYMBOL_GPL(snd_soc_calc_bclk); 47c0fa59dfSMark Brown 487aae816dSMark Brown int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) 497aae816dSMark Brown { 507aae816dSMark Brown int ret; 517aae816dSMark Brown 527aae816dSMark Brown ret = snd_soc_params_to_frame_size(params); 537aae816dSMark Brown 547aae816dSMark Brown if (ret > 0) 557aae816dSMark Brown return ret * params_rate(params); 567aae816dSMark Brown else 577aae816dSMark Brown return ret; 587aae816dSMark Brown } 597aae816dSMark Brown EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); 60848dd8beSMark Brown 611b4d9c22SRichard Fitzgerald int snd_soc_component_enable_pin(struct snd_soc_component *component, 621b4d9c22SRichard Fitzgerald const char *pin) 631b4d9c22SRichard Fitzgerald { 641b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 651b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 661b4d9c22SRichard Fitzgerald char *full_name; 671b4d9c22SRichard Fitzgerald int ret; 681b4d9c22SRichard Fitzgerald 691b4d9c22SRichard Fitzgerald if (!component->name_prefix) 701b4d9c22SRichard Fitzgerald return snd_soc_dapm_enable_pin(dapm, pin); 711b4d9c22SRichard Fitzgerald 721b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 731b4d9c22SRichard Fitzgerald if (!full_name) 741b4d9c22SRichard Fitzgerald return -ENOMEM; 751b4d9c22SRichard Fitzgerald 761b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_enable_pin(dapm, full_name); 771b4d9c22SRichard Fitzgerald kfree(full_name); 781b4d9c22SRichard Fitzgerald 791b4d9c22SRichard Fitzgerald return ret; 801b4d9c22SRichard Fitzgerald } 811b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin); 821b4d9c22SRichard Fitzgerald 831b4d9c22SRichard Fitzgerald int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, 841b4d9c22SRichard Fitzgerald const char *pin) 851b4d9c22SRichard Fitzgerald { 861b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 871b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 881b4d9c22SRichard Fitzgerald char *full_name; 891b4d9c22SRichard Fitzgerald int ret; 901b4d9c22SRichard Fitzgerald 911b4d9c22SRichard Fitzgerald if (!component->name_prefix) 921b4d9c22SRichard Fitzgerald return snd_soc_dapm_enable_pin_unlocked(dapm, pin); 931b4d9c22SRichard Fitzgerald 941b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 951b4d9c22SRichard Fitzgerald if (!full_name) 961b4d9c22SRichard Fitzgerald return -ENOMEM; 971b4d9c22SRichard Fitzgerald 981b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name); 991b4d9c22SRichard Fitzgerald kfree(full_name); 1001b4d9c22SRichard Fitzgerald 1011b4d9c22SRichard Fitzgerald return ret; 1021b4d9c22SRichard Fitzgerald } 1031b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked); 1041b4d9c22SRichard Fitzgerald 1051b4d9c22SRichard Fitzgerald int snd_soc_component_disable_pin(struct snd_soc_component *component, 1061b4d9c22SRichard Fitzgerald const char *pin) 1071b4d9c22SRichard Fitzgerald { 1081b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 1091b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 1101b4d9c22SRichard Fitzgerald char *full_name; 1111b4d9c22SRichard Fitzgerald int ret; 1121b4d9c22SRichard Fitzgerald 1131b4d9c22SRichard Fitzgerald if (!component->name_prefix) 1141b4d9c22SRichard Fitzgerald return snd_soc_dapm_disable_pin(dapm, pin); 1151b4d9c22SRichard Fitzgerald 1161b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 1171b4d9c22SRichard Fitzgerald if (!full_name) 1181b4d9c22SRichard Fitzgerald return -ENOMEM; 1191b4d9c22SRichard Fitzgerald 1201b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_disable_pin(dapm, full_name); 1211b4d9c22SRichard Fitzgerald kfree(full_name); 1221b4d9c22SRichard Fitzgerald 1231b4d9c22SRichard Fitzgerald return ret; 1241b4d9c22SRichard Fitzgerald } 1251b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin); 1261b4d9c22SRichard Fitzgerald 1271b4d9c22SRichard Fitzgerald int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, 1281b4d9c22SRichard Fitzgerald const char *pin) 1291b4d9c22SRichard Fitzgerald { 1301b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 1311b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 1321b4d9c22SRichard Fitzgerald char *full_name; 1331b4d9c22SRichard Fitzgerald int ret; 1341b4d9c22SRichard Fitzgerald 1351b4d9c22SRichard Fitzgerald if (!component->name_prefix) 1361b4d9c22SRichard Fitzgerald return snd_soc_dapm_disable_pin_unlocked(dapm, pin); 1371b4d9c22SRichard Fitzgerald 1381b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 1391b4d9c22SRichard Fitzgerald if (!full_name) 1401b4d9c22SRichard Fitzgerald return -ENOMEM; 1411b4d9c22SRichard Fitzgerald 1421b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name); 1431b4d9c22SRichard Fitzgerald kfree(full_name); 1441b4d9c22SRichard Fitzgerald 1451b4d9c22SRichard Fitzgerald return ret; 1461b4d9c22SRichard Fitzgerald } 1471b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked); 1481b4d9c22SRichard Fitzgerald 1491b4d9c22SRichard Fitzgerald int snd_soc_component_nc_pin(struct snd_soc_component *component, 1501b4d9c22SRichard Fitzgerald const char *pin) 1511b4d9c22SRichard Fitzgerald { 1521b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 1531b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 1541b4d9c22SRichard Fitzgerald char *full_name; 1551b4d9c22SRichard Fitzgerald int ret; 1561b4d9c22SRichard Fitzgerald 1571b4d9c22SRichard Fitzgerald if (!component->name_prefix) 1581b4d9c22SRichard Fitzgerald return snd_soc_dapm_nc_pin(dapm, pin); 1591b4d9c22SRichard Fitzgerald 1601b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 1611b4d9c22SRichard Fitzgerald if (!full_name) 1621b4d9c22SRichard Fitzgerald return -ENOMEM; 1631b4d9c22SRichard Fitzgerald 1641b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_nc_pin(dapm, full_name); 1651b4d9c22SRichard Fitzgerald kfree(full_name); 1661b4d9c22SRichard Fitzgerald 1671b4d9c22SRichard Fitzgerald return ret; 1681b4d9c22SRichard Fitzgerald } 1691b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin); 1701b4d9c22SRichard Fitzgerald 1711b4d9c22SRichard Fitzgerald int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, 1721b4d9c22SRichard Fitzgerald const char *pin) 1731b4d9c22SRichard Fitzgerald { 1741b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 1751b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 1761b4d9c22SRichard Fitzgerald char *full_name; 1771b4d9c22SRichard Fitzgerald int ret; 1781b4d9c22SRichard Fitzgerald 1791b4d9c22SRichard Fitzgerald if (!component->name_prefix) 1801b4d9c22SRichard Fitzgerald return snd_soc_dapm_nc_pin_unlocked(dapm, pin); 1811b4d9c22SRichard Fitzgerald 1821b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 1831b4d9c22SRichard Fitzgerald if (!full_name) 1841b4d9c22SRichard Fitzgerald return -ENOMEM; 1851b4d9c22SRichard Fitzgerald 1861b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name); 1871b4d9c22SRichard Fitzgerald kfree(full_name); 1881b4d9c22SRichard Fitzgerald 1891b4d9c22SRichard Fitzgerald return ret; 1901b4d9c22SRichard Fitzgerald } 1911b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked); 1921b4d9c22SRichard Fitzgerald 1931b4d9c22SRichard Fitzgerald int snd_soc_component_get_pin_status(struct snd_soc_component *component, 1941b4d9c22SRichard Fitzgerald const char *pin) 1951b4d9c22SRichard Fitzgerald { 1961b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 1971b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 1981b4d9c22SRichard Fitzgerald char *full_name; 1991b4d9c22SRichard Fitzgerald int ret; 2001b4d9c22SRichard Fitzgerald 2011b4d9c22SRichard Fitzgerald if (!component->name_prefix) 2021b4d9c22SRichard Fitzgerald return snd_soc_dapm_get_pin_status(dapm, pin); 2031b4d9c22SRichard Fitzgerald 2041b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 2051b4d9c22SRichard Fitzgerald if (!full_name) 2061b4d9c22SRichard Fitzgerald return -ENOMEM; 2071b4d9c22SRichard Fitzgerald 2081b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_get_pin_status(dapm, full_name); 2091b4d9c22SRichard Fitzgerald kfree(full_name); 2101b4d9c22SRichard Fitzgerald 2111b4d9c22SRichard Fitzgerald return ret; 2121b4d9c22SRichard Fitzgerald } 2131b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status); 2141b4d9c22SRichard Fitzgerald 2151b4d9c22SRichard Fitzgerald int snd_soc_component_force_enable_pin(struct snd_soc_component *component, 2161b4d9c22SRichard Fitzgerald const char *pin) 2171b4d9c22SRichard Fitzgerald { 2181b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 2191b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 2201b4d9c22SRichard Fitzgerald char *full_name; 2211b4d9c22SRichard Fitzgerald int ret; 2221b4d9c22SRichard Fitzgerald 2231b4d9c22SRichard Fitzgerald if (!component->name_prefix) 2241b4d9c22SRichard Fitzgerald return snd_soc_dapm_force_enable_pin(dapm, pin); 2251b4d9c22SRichard Fitzgerald 2261b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 2271b4d9c22SRichard Fitzgerald if (!full_name) 2281b4d9c22SRichard Fitzgerald return -ENOMEM; 2291b4d9c22SRichard Fitzgerald 2301b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_force_enable_pin(dapm, full_name); 2311b4d9c22SRichard Fitzgerald kfree(full_name); 2321b4d9c22SRichard Fitzgerald 2331b4d9c22SRichard Fitzgerald return ret; 2341b4d9c22SRichard Fitzgerald } 2351b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin); 2361b4d9c22SRichard Fitzgerald 2371b4d9c22SRichard Fitzgerald int snd_soc_component_force_enable_pin_unlocked( 2381b4d9c22SRichard Fitzgerald struct snd_soc_component *component, 2391b4d9c22SRichard Fitzgerald const char *pin) 2401b4d9c22SRichard Fitzgerald { 2411b4d9c22SRichard Fitzgerald struct snd_soc_dapm_context *dapm = 2421b4d9c22SRichard Fitzgerald snd_soc_component_get_dapm(component); 2431b4d9c22SRichard Fitzgerald char *full_name; 2441b4d9c22SRichard Fitzgerald int ret; 2451b4d9c22SRichard Fitzgerald 2461b4d9c22SRichard Fitzgerald if (!component->name_prefix) 2471b4d9c22SRichard Fitzgerald return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); 2481b4d9c22SRichard Fitzgerald 2491b4d9c22SRichard Fitzgerald full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 2501b4d9c22SRichard Fitzgerald if (!full_name) 2511b4d9c22SRichard Fitzgerald return -ENOMEM; 2521b4d9c22SRichard Fitzgerald 2531b4d9c22SRichard Fitzgerald ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name); 2541b4d9c22SRichard Fitzgerald kfree(full_name); 2551b4d9c22SRichard Fitzgerald 2561b4d9c22SRichard Fitzgerald return ret; 2571b4d9c22SRichard Fitzgerald } 2581b4d9c22SRichard Fitzgerald EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked); 2591b4d9c22SRichard Fitzgerald 260cefcc03fSMark Brown static const struct snd_pcm_hardware dummy_dma_hardware = { 261cefcc03fSMark Brown /* Random values to keep userspace happy when checking constraints */ 262cefcc03fSMark Brown .info = SNDRV_PCM_INFO_INTERLEAVED | 263cefcc03fSMark Brown SNDRV_PCM_INFO_BLOCK_TRANSFER, 264cefcc03fSMark Brown .buffer_bytes_max = 128*1024, 265cefcc03fSMark Brown .period_bytes_min = PAGE_SIZE, 266cefcc03fSMark Brown .period_bytes_max = PAGE_SIZE*2, 267cefcc03fSMark Brown .periods_min = 2, 268cefcc03fSMark Brown .periods_max = 128, 269cefcc03fSMark Brown }; 270cefcc03fSMark Brown 271cefcc03fSMark Brown static int dummy_dma_open(struct snd_pcm_substream *substream) 272cefcc03fSMark Brown { 2737f05cc98SLiam Girdwood struct snd_soc_pcm_runtime *rtd = substream->private_data; 2747f05cc98SLiam Girdwood 2757f05cc98SLiam Girdwood /* BE's dont need dummy params */ 2767f05cc98SLiam Girdwood if (!rtd->dai_link->no_pcm) 277cefcc03fSMark Brown snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); 278cefcc03fSMark Brown 279cefcc03fSMark Brown return 0; 280cefcc03fSMark Brown } 281cefcc03fSMark Brown 282115c7254SJulia Lawall static const struct snd_pcm_ops dummy_dma_ops = { 283cefcc03fSMark Brown .open = dummy_dma_open, 284cefcc03fSMark Brown .ioctl = snd_pcm_lib_ioctl, 285cefcc03fSMark Brown }; 286cefcc03fSMark Brown 2872d59ebd3SKuninori Morimoto static const struct snd_soc_component_driver dummy_platform = { 288cefcc03fSMark Brown .ops = &dummy_dma_ops, 289cefcc03fSMark Brown }; 290848dd8beSMark Brown 291*03a0ddedSKuninori Morimoto static const struct snd_soc_component_driver dummy_codec = { 292*03a0ddedSKuninori Morimoto .idle_bias_on = 1, 293*03a0ddedSKuninori Morimoto .use_pmdown_time = 1, 294*03a0ddedSKuninori Morimoto .endianness = 1, 295*03a0ddedSKuninori Morimoto .non_legacy_dai_naming = 1, 296*03a0ddedSKuninori Morimoto }; 29760b6f1a1SStas Sergeev 29860b6f1a1SStas Sergeev #define STUB_RATES SNDRV_PCM_RATE_8000_192000 29960b6f1a1SStas Sergeev #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 30060b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_U8 | \ 30160b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_S16_LE | \ 30260b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_U16_LE | \ 30360b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_S24_LE | \ 30460b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_U24_LE | \ 30560b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_S32_LE | \ 30660b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_U32_LE | \ 30760b6f1a1SStas Sergeev SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) 308d76f4198SAnatol Pomozov /* 309d76f4198SAnatol Pomozov * The dummy CODEC is only meant to be used in situations where there is no 310d76f4198SAnatol Pomozov * actual hardware. 311d76f4198SAnatol Pomozov * 312d76f4198SAnatol Pomozov * If there is actual hardware even if it does not have a control bus 313d76f4198SAnatol Pomozov * the hardware will still have constraints like supported samplerates, etc. 314d76f4198SAnatol Pomozov * which should be modelled. And the data flow graph also should be modelled 315d76f4198SAnatol Pomozov * using DAPM. 316d76f4198SAnatol Pomozov */ 3177aca69f9SLiam Girdwood static struct snd_soc_dai_driver dummy_dai = { 3187aca69f9SLiam Girdwood .name = "snd-soc-dummy-dai", 31960b6f1a1SStas Sergeev .playback = { 32060b6f1a1SStas Sergeev .stream_name = "Playback", 32160b6f1a1SStas Sergeev .channels_min = 1, 32260b6f1a1SStas Sergeev .channels_max = 384, 32360b6f1a1SStas Sergeev .rates = STUB_RATES, 32460b6f1a1SStas Sergeev .formats = STUB_FORMATS, 32560b6f1a1SStas Sergeev }, 32660b6f1a1SStas Sergeev .capture = { 32760b6f1a1SStas Sergeev .stream_name = "Capture", 32860b6f1a1SStas Sergeev .channels_min = 1, 32960b6f1a1SStas Sergeev .channels_max = 384, 33060b6f1a1SStas Sergeev .rates = STUB_RATES, 33160b6f1a1SStas Sergeev .formats = STUB_FORMATS, 33260b6f1a1SStas Sergeev }, 3337aca69f9SLiam Girdwood }; 3347aca69f9SLiam Girdwood 335bece9e95SLiam Girdwood int snd_soc_dai_is_dummy(struct snd_soc_dai *dai) 336bece9e95SLiam Girdwood { 337bece9e95SLiam Girdwood if (dai->driver == &dummy_dai) 338bece9e95SLiam Girdwood return 1; 339bece9e95SLiam Girdwood return 0; 340bece9e95SLiam Girdwood } 341bece9e95SLiam Girdwood 342e51e97eeSBill Pemberton static int snd_soc_dummy_probe(struct platform_device *pdev) 343848dd8beSMark Brown { 3447aca69f9SLiam Girdwood int ret; 3457aca69f9SLiam Girdwood 346*03a0ddedSKuninori Morimoto ret = devm_snd_soc_register_component(&pdev->dev, 347*03a0ddedSKuninori Morimoto &dummy_codec, &dummy_dai, 1); 3487aca69f9SLiam Girdwood if (ret < 0) 3497aca69f9SLiam Girdwood return ret; 3507aca69f9SLiam Girdwood 3512d59ebd3SKuninori Morimoto ret = devm_snd_soc_register_component(&pdev->dev, &dummy_platform, 3522d59ebd3SKuninori Morimoto NULL, 0); 3537aca69f9SLiam Girdwood 3547aca69f9SLiam Girdwood return ret; 355848dd8beSMark Brown } 356848dd8beSMark Brown 357848dd8beSMark Brown static struct platform_driver soc_dummy_driver = { 358848dd8beSMark Brown .driver = { 359848dd8beSMark Brown .name = "snd-soc-dummy", 360848dd8beSMark Brown }, 361848dd8beSMark Brown .probe = snd_soc_dummy_probe, 362848dd8beSMark Brown }; 363848dd8beSMark Brown 364848dd8beSMark Brown static struct platform_device *soc_dummy_dev; 365848dd8beSMark Brown 366fb257897SMark Brown int __init snd_soc_util_init(void) 367848dd8beSMark Brown { 368848dd8beSMark Brown int ret; 369848dd8beSMark Brown 3707d0cd223SUwe Kleine-König soc_dummy_dev = 3717d0cd223SUwe Kleine-König platform_device_register_simple("snd-soc-dummy", -1, NULL, 0); 3727d0cd223SUwe Kleine-König if (IS_ERR(soc_dummy_dev)) 3737d0cd223SUwe Kleine-König return PTR_ERR(soc_dummy_dev); 374848dd8beSMark Brown 375848dd8beSMark Brown ret = platform_driver_register(&soc_dummy_driver); 376848dd8beSMark Brown if (ret != 0) 377848dd8beSMark Brown platform_device_unregister(soc_dummy_dev); 378848dd8beSMark Brown 379848dd8beSMark Brown return ret; 380848dd8beSMark Brown } 381848dd8beSMark Brown 382fb257897SMark Brown void __exit snd_soc_util_exit(void) 383848dd8beSMark Brown { 384848dd8beSMark Brown platform_device_unregister(soc_dummy_dev); 385848dd8beSMark Brown platform_driver_unregister(&soc_dummy_driver); 386848dd8beSMark Brown } 387