diff options
Diffstat (limited to 'sound/soc/samsung/smdk_wm8994.c')
| -rw-r--r-- | sound/soc/samsung/smdk_wm8994.c | 117 |
1 files changed, 73 insertions, 44 deletions
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index e7c1009a1e1..3d6272a8cad 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -8,6 +8,11 @@ */ #include "../codecs/wm8994.h" +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> /* * Default CFG switch settings to use this driver: @@ -34,33 +39,31 @@ /* SMDK has a 16.934MHZ crystal attached to WM8994 */ #define SMDK_WM8994_FREQ 16934000 +struct smdk_wm8994_data { + int mclk1_rate; +}; + +/* Default SMDKs */ +static struct smdk_wm8994_data smdk_board_data = { + .mclk1_rate = SMDK_WM8994_FREQ, +}; + static int smdk_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; unsigned int pll_out; int ret; /* AIF1CLK should be >=3MHz for optimal performance */ - if (params_rate(params) == 8000 || params_rate(params) == 11025) + if (params_width(params) == 24) + pll_out = params_rate(params) * 384; + else if (params_rate(params) == 8000 || params_rate(params) == 11025) pll_out = params_rate(params) * 512; else pll_out = params_rate(params) * 256; - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, SMDK_WM8994_FREQ, pll_out); if (ret < 0) @@ -86,18 +89,6 @@ static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd) struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - /* HeadPhone */ - snd_soc_dapm_enable_pin(dapm, "HPOUT1R"); - snd_soc_dapm_enable_pin(dapm, "HPOUT1L"); - - /* MicIn */ - snd_soc_dapm_enable_pin(dapm, "IN1LN"); - snd_soc_dapm_enable_pin(dapm, "IN1RN"); - - /* LineIn */ - snd_soc_dapm_enable_pin(dapm, "IN2LN"); - snd_soc_dapm_enable_pin(dapm, "IN2RN"); - /* Other pins NC */ snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); @@ -114,8 +105,6 @@ static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "IN1RP"); snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); - snd_soc_dapm_sync(dapm); - return 0; } @@ -125,52 +114,92 @@ static struct snd_soc_dai_link smdk_dai[] = { .stream_name = "Pri_Dai", .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s.0", .codec_name = "wm8994-codec", .init = smdk_wm8994_init_paiftx, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, .ops = &smdk_ops, }, { /* Sec_Fifo Playback i/f */ .name = "Sec_FIFO TX", .stream_name = "Sec_Dai", - .cpu_dai_name = "samsung-i2s.4", + .cpu_dai_name = "samsung-i2s-sec", .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-audio", + .platform_name = "samsung-i2s-sec", .codec_name = "wm8994-codec", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, .ops = &smdk_ops, }, }; static struct snd_soc_card smdk = { .name = "SMDK-I2S", + .owner = THIS_MODULE, .dai_link = smdk_dai, .num_links = ARRAY_SIZE(smdk_dai), }; -static struct platform_device *smdk_snd_device; +static const struct of_device_id samsung_wm8994_of_match[] = { + { .compatible = "samsung,smdk-wm8994", .data = &smdk_board_data }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_wm8994_of_match); -static int __init smdk_audio_init(void) +static int smdk_audio_probe(struct platform_device *pdev) { int ret; + struct device_node *np = pdev->dev.of_node; + struct snd_soc_card *card = &smdk; + struct smdk_wm8994_data *board; + const struct of_device_id *id; + + card->dev = &pdev->dev; - smdk_snd_device = platform_device_alloc("soc-audio", -1); - if (!smdk_snd_device) + board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL); + if (!board) return -ENOMEM; - platform_set_drvdata(smdk_snd_device, &smdk); + if (np) { + smdk_dai[0].cpu_dai_name = NULL; + smdk_dai[0].cpu_of_node = of_parse_phandle(np, + "samsung,i2s-controller", 0); + if (!smdk_dai[0].cpu_of_node) { + dev_err(&pdev->dev, + "Property 'samsung,i2s-controller' missing or invalid\n"); + ret = -EINVAL; + } + + smdk_dai[0].platform_name = NULL; + smdk_dai[0].platform_of_node = smdk_dai[0].cpu_of_node; + } + + id = of_match_device(of_match_ptr(samsung_wm8994_of_match), &pdev->dev); + if (id) + *board = *((struct smdk_wm8994_data *)id->data); + + platform_set_drvdata(pdev, board); + + ret = devm_snd_soc_register_card(&pdev->dev, card); - ret = platform_device_add(smdk_snd_device); if (ret) - platform_device_put(smdk_snd_device); + dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); return ret; } -module_init(smdk_audio_init); -static void __exit smdk_audio_exit(void) -{ - platform_device_unregister(smdk_snd_device); -} -module_exit(smdk_audio_exit); +static struct platform_driver smdk_audio_driver = { + .driver = { + .name = "smdk-audio-wm8994", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(samsung_wm8994_of_match), + .pm = &snd_soc_pm_ops, + }, + .probe = smdk_audio_probe, +}; + +module_platform_driver(smdk_audio_driver); MODULE_DESCRIPTION("ALSA SoC SMDK WM8994"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:smdk-audio-wm8994"); |
