From 03da09a02de2ffd15df89b9ddef17dd7af195f32 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 21 Dec 2014 22:14:48 +0100 Subject: ASoC: samsung: drop owner assignment from platform_drivers This platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- sound/soc/samsung/arndale_rt5631.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/arndale_rt5631.c b/sound/soc/samsung/arndale_rt5631.c index 1e2b61ca8db2..8bf2e2c4bafb 100644 --- a/sound/soc/samsung/arndale_rt5631.c +++ b/sound/soc/samsung/arndale_rt5631.c @@ -135,7 +135,6 @@ MODULE_DEVICE_TABLE(of, samsung_arndale_rt5631_of_match); static struct platform_driver arndale_audio_driver = { .driver = { .name = "arndale-audio", - .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), }, -- cgit v1.2.3 From 0af76f918adb8487a911bc136a6f1b12c46cd056 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:19 +0100 Subject: ASoC: goni_wm8994: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/goni_wm8994.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index 3b527dcfc0aa..fad56b9e7369 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c @@ -136,22 +136,9 @@ static int goni_hifi_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int pll_out = 24000000; int ret = 0; - /* set the cpu DAI configuration */ - 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; - - /* set codec DAI configuration */ - 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; - /* set the codec FLL */ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, params_rate(params) * 256); @@ -182,12 +169,6 @@ static int goni_voice_hw_params(struct snd_pcm_substream *substream, if (params_rate(params) != 8000) return -EINVAL; - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | - SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - /* set the codec FLL */ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, params_rate(params) * 256); @@ -234,6 +215,8 @@ static struct snd_soc_dai_link goni_dai[] = { .codec_dai_name = "wm8994-aif1", .platform_name = "samsung-i2s.0", .codec_name = "wm8994-codec.0-001a", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, .init = goni_wm8994_init, .ops = &goni_hifi_ops, }, { @@ -242,6 +225,8 @@ static struct snd_soc_dai_link goni_dai[] = { .cpu_dai_name = "goni-voice-dai", .codec_dai_name = "wm8994-aif2", .codec_name = "wm8994-codec.0-001a", + .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_IB_IF | + SND_SOC_DAIFMT_CBM_CFM, .ops = &goni_voice_ops, }, }; -- cgit v1.2.3 From 5cc10b9b77c234e89e7c4aca56d8a3c571111955 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:20 +0100 Subject: ASoC: h1940_uda1380: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/h1940_uda1380.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index f2d7980d7ddc..59b044255b78 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -76,7 +76,6 @@ static int h1940_hw_params(struct snd_pcm_substream *substream, { 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; int div; int ret; unsigned int rate = params_rate(params); @@ -95,18 +94,6 @@ static int h1940_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* select clock source */ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate, SND_SOC_CLOCK_OUT); @@ -207,6 +194,8 @@ static struct snd_soc_dai_link h1940_uda1380_dai[] = { .init = h1940_uda1380_init, .platform_name = "s3c24xx-iis", .codec_name = "uda1380-codec.0-001a", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &h1940_ops, }, }; -- cgit v1.2.3 From 72303cafcb5cc9fd1227d0edd458f62bef1a397e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:21 +0100 Subject: ASoC: jive_wm8750: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/jive_wm8750.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index b5f6abd9d221..6c3b359bb4c1 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c @@ -61,20 +61,6 @@ static int jive_hw_params(struct snd_pcm_substream *substream, s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), s3c_i2sv2_get_clock(cpu_dai)); - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* set the codec system clock for DAC and ADC */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, SND_SOC_CLOCK_IN); @@ -121,6 +107,8 @@ static struct snd_soc_dai_link jive_dai = { .platform_name = "s3c2412-i2s", .codec_name = "wm8750.0-001a", .init = jive_wm8750_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &jive_ops, }; -- cgit v1.2.3 From e16514d931635640906ab2810c98f6a9047cb87a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:22 +0100 Subject: ASoC: neo1973_wm8753: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/neo1973_wm8753.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 9b4a09f14b6c..65602b935377 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c @@ -70,20 +70,6 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, break; } - /* set codec DAI configuration */ - 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; - - /* set cpu DAI configuration */ - 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; - /* set the codec system clock for DAC and ADC */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, SND_SOC_CLOCK_IN); @@ -151,13 +137,6 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ - /* todo: gg check mode (DSP_B) against CSR datasheet */ - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* set the codec system clock for DAC and ADC */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, SND_SOC_CLOCK_IN); @@ -300,6 +279,8 @@ static struct snd_soc_dai_link neo1973_dai[] = { .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "wm8753-hifi", .codec_name = "wm8753.0-001a", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, .init = neo1973_wm8753_init, .ops = &neo1973_hifi_ops, }, @@ -309,6 +290,8 @@ static struct snd_soc_dai_link neo1973_dai[] = { .cpu_dai_name = "bt-sco-pcm", .codec_dai_name = "wm8753-voice", .codec_name = "wm8753.0-001a", + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &neo1973_voice_ops, }, }; -- cgit v1.2.3 From 5f0acedddf533c086edf29eefdc743dc1e756b5d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:23 +0100 Subject: ASoC: rx1950_uda1380: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/rx1950_uda1380.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 37688ebbb2b4..873f2cb4bebe 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -89,6 +89,8 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = { .init = rx1950_uda1380_init, .platform_name = "s3c24xx-iis", .codec_name = "uda1380-codec.0-001a", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &rx1950_ops, }, }; @@ -154,7 +156,6 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, { 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; int div; int ret; unsigned int rate = params_rate(params); @@ -181,18 +182,6 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* select clock source */ ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source, rate, SND_SOC_CLOCK_OUT); -- cgit v1.2.3 From d27e51dade482acdf67021c12d692041a35bea77 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:24 +0100 Subject: ASoC: s3c24xx_simtec: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/s3c24xx_simtec.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index 2c015f62ead6..dcc008d1e1ab 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c @@ -169,24 +169,6 @@ static int simtec_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret; - /* Set the CODEC as the bus clock master, I2S */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret) { - pr_err("%s: failed set cpu dai format\n", __func__); - return ret; - } - - /* Set the CODEC as the bus clock master */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret) { - pr_err("%s: failed set codec dai format\n", __func__); - return ret; - } - ret = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); if (ret) { @@ -320,6 +302,8 @@ int simtec_audio_core_probe(struct platform_device *pdev, int ret; card->dai_link->ops = &simtec_snd_ops; + card->dai_link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM; pdata = pdev->dev.platform_data; if (!pdata) { -- cgit v1.2.3 From 517b9a2a90676aeeefc7e2b8508fe4260e02c432 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:25 +0100 Subject: ASoC: s3c24xx_uda134x: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/s3c24xx_uda134x.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 9c6f7db56f60..50849e137fc0 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -173,16 +173,6 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - 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_CBS_CFS); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk, SND_SOC_CLOCK_IN); if (ret < 0) @@ -223,6 +213,8 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { .codec_name = "uda134x-codec", .codec_dai_name = "uda134x-hifi", .cpu_dai_name = "s3c24xx-iis", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &s3c24xx_uda134x_ops, .platform_name = "s3c24xx-iis", }; -- cgit v1.2.3 From 10756c2770d7f4758e36d2a9e37ff2637001d610 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:26 +0100 Subject: ASoC: smartq_wm8987: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/smartq_wm8987.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index 9b0ffacab790..8291d2a5f152 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -56,20 +56,6 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, break; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* Use PCLK for I2S signal generation */ ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, 0, SND_SOC_CLOCK_IN); @@ -199,6 +185,8 @@ static struct snd_soc_dai_link smartq_dai[] = { .platform_name = "samsung-i2s.0", .codec_name = "wm8750.0-0x1a", .init = smartq_wm8987_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &smartq_hifi_ops, }, }; -- cgit v1.2.3 From 7a57ca2362a55c34b96d90539dd8b7cb6c1c09a1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:27 +0100 Subject: ASoC: smdk_wm8580: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm8580.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index b1a519f83b29..17a2f717ec02 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -32,7 +32,6 @@ 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 bfs, rfs, ret; @@ -77,20 +76,6 @@ static int smdk_hw_params(struct snd_pcm_substream *substream, } pll_out = params_rate(params) * rfs; - /* Set the Codec DAI configuration */ - 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; - - /* Set the AP DAI configuration */ - 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; - /* Set WM8580 to drive MCLK from its PLLA */ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, WM8580_CLKSRC_PLLA); @@ -168,6 +153,9 @@ enum { SEC_PLAYBACK, }; +#define SMDK_DAI_FMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ + SND_SOC_DAIFMT_CBM_CFM) + static struct snd_soc_dai_link smdk_dai[] = { [PRI_PLAYBACK] = { /* Primary Playback i/f */ .name = "WM8580 PAIF RX", @@ -176,6 +164,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .codec_dai_name = "wm8580-hifi-playback", .platform_name = "samsung-i2s.0", .codec_name = "wm8580.0-001b", + .dai_fmt = SMDK_DAI_FMT, .ops = &smdk_ops, }, [PRI_CAPTURE] = { /* Primary Capture i/f */ @@ -185,6 +174,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .codec_dai_name = "wm8580-hifi-capture", .platform_name = "samsung-i2s.0", .codec_name = "wm8580.0-001b", + .dai_fmt = SMDK_DAI_FMT, .init = smdk_wm8580_init_paiftx, .ops = &smdk_ops, }, @@ -195,6 +185,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .codec_dai_name = "wm8580-hifi-playback", .platform_name = "samsung-i2s-sec", .codec_name = "wm8580.0-001b", + .dai_fmt = SMDK_DAI_FMT, .ops = &smdk_ops, }, }; -- cgit v1.2.3 From 6a5794f2c653e78127123b3cd266b3c4d4c50606 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:28 +0100 Subject: ASoC: smdk_wm8570pcm: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm8580pcm.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 05c609c62de9..6deec5234c92 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c @@ -62,20 +62,6 @@ static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream, rfs = mclk_freq / params_rate(params) / 2; - /* Set the codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B - | SND_SOC_DAIFMT_IB_NF - | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* Set the cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B - | SND_SOC_DAIFMT_IB_NF - | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - if (mclk_freq == xtal_freq) { ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK, mclk_freq, SND_SOC_CLOCK_IN); @@ -121,6 +107,9 @@ static struct snd_soc_ops smdk_wm8580_pcm_ops = { .hw_params = smdk_wm8580_pcm_hw_params, }; +#define SMDK_DAI_FMT (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | \ + SND_SOC_DAIFMT_CBS_CFS) + static struct snd_soc_dai_link smdk_dai[] = { { .name = "WM8580 PAIF PCM RX", @@ -129,6 +118,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .codec_dai_name = "wm8580-hifi-playback", .platform_name = "samsung-audio", .codec_name = "wm8580.0-001b", + .dai_fmt = SMDK_DAI_FMT, .ops = &smdk_wm8580_pcm_ops, }, { .name = "WM8580 PAIF PCM TX", @@ -137,6 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = { .codec_dai_name = "wm8580-hifi-capture", .platform_name = "samsung-pcm.0", .codec_name = "wm8580.0-001b", + .dai_fmt = SMDK_DAI_FMT, .ops = &smdk_wm8580_pcm_ops, }, }; -- cgit v1.2.3 From fce20bf879dd5ce309c593c91bbb7b5e6ffd22e7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 1 Jan 2015 17:16:29 +0100 Subject: ASoC: smdk_wm8994pcm: Use static DAI format setup Set the dai_fmt field in the dai_link struct instead of manually calling snd_soc_dai_fmt(). This makes the code cleaner and shorter. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm8994pcm.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index c470e8eed6e1..b1c89ec2d999 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c @@ -68,20 +68,6 @@ static int smdk_wm8994_pcm_hw_params(struct snd_pcm_substream *substream, mclk_freq = params_rate(params) * rfs; - /* Set the codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B - | SND_SOC_DAIFMT_IB_NF - | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* Set the cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B - | SND_SOC_DAIFMT_IB_NF - | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, mclk_freq, SND_SOC_CLOCK_IN); if (ret < 0) @@ -118,6 +104,8 @@ static struct snd_soc_dai_link smdk_dai[] = { .codec_dai_name = "wm8994-aif1", .platform_name = "samsung-pcm.0", .codec_name = "wm8994-codec", + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &smdk_wm8994_pcm_ops, }, }; -- cgit v1.2.3 From fce091ee0a7f25108c7ab3eb06b9e436b7aeac11 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 19 Dec 2014 14:55:21 +0100 Subject: ASoC: samsung: i2s: Remove unused gpios field from struct i2s The 'gpios' field in 'struct i2s' is now unused, this change seems to be missing in commit 0429ffeff460c4302bd1520e6 ("ASoC: samsung: Remove obsolete GPIO based DT pinmuxing"). Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index b5a80c528d86..86491c9f121f 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -95,7 +95,6 @@ struct i2s_dai { u32 suspend_i2smod; u32 suspend_i2scon; u32 suspend_i2spsr; - unsigned long gpios[7]; /* i2s gpio line numbers */ const struct samsung_i2s_variant_regs *variant_regs; }; -- cgit v1.2.3 From 9cf247473167df29a3d99464385b4afe1fc16f2f Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:28 +0100 Subject: ASoC: samsung: i2s: samsung_i2s_get_driver_data() cleanup Tidy up the samsung_i2s_get_driver_data() function by using IS_ENABLE() instead of #ifdef and add missing braces for the 'else' part. Also ensure we are not dereferencing NULL 'match' pointer. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 86491c9f121f..e5473ee799d7 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1123,15 +1123,14 @@ static const struct of_device_id exynos_i2s_match[]; static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data( struct platform_device *pdev) { -#ifdef CONFIG_OF - if (pdev->dev.of_node) { + if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { const struct of_device_id *match; match = of_match_node(exynos_i2s_match, pdev->dev.of_node); - return match->data; - } else -#endif + return match ? match->data : NULL; + } else { return (struct samsung_i2s_dai_data *) platform_get_device_id(pdev)->driver_data; + } } #ifdef CONFIG_PM -- cgit v1.2.3 From 53f7faa17e9489f8b7be67dd9e87167f1779ef28 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:29 +0100 Subject: ASoC: samsung: i2s: Add return value checks in probe() These functions may fail so let's properly report any errors. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index e5473ee799d7..aa52b41f1749 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1173,11 +1173,13 @@ static int samsung_i2s_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to get drvdata\n"); return -EFAULT; } - devm_snd_soc_register_component(&sec_dai->pdev->dev, + ret = devm_snd_soc_register_component(&sec_dai->pdev->dev, &samsung_i2s_component, &sec_dai->i2s_dai_drv, 1); - samsung_asoc_dma_platform_register(&pdev->dev); - return 0; + if (ret != 0) + return ret; + + return samsung_asoc_dma_platform_register(&pdev->dev); } pri_dai = i2s_alloc_dai(pdev, false); @@ -1290,7 +1292,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - samsung_asoc_dma_platform_register(&pdev->dev); + ret = samsung_asoc_dma_platform_register(&pdev->dev); + if (ret != 0) + return ret; return 0; err: -- cgit v1.2.3 From af1cf5cf9c1881192f72af204e873ac345a3e265 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:30 +0100 Subject: ASoC: samsung: i2s: Request memory region in driver probe() The memory mapped registers region is common for both DAIs so request it in the I2S platform device driver's probe for the platform device corresponding to the primary DAI, rather than in the ASoC DAI's probe callback. While at it switch to devm_ioremap_resource(). This also drops the hard coded (0x100) register region size in the driver. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 45 +++++++-------------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index aa52b41f1749..366b720731e1 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -59,10 +59,8 @@ struct samsung_i2s_dai_data { struct i2s_dai { /* Platform device for this DAI */ struct platform_device *pdev; - /* IOREMAP'd SFRs */ + /* Memory mapped SFR region */ void __iomem *addr; - /* Physical base address of SFRs */ - u32 base; /* Rate of RCLK source clock */ unsigned long rclk_srcrate; /* Frame Clock */ @@ -979,16 +977,9 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) goto probe_exit; } - i2s->addr = ioremap(i2s->base, 0x100); - if (i2s->addr == NULL) { - dev_err(&i2s->pdev->dev, "cannot ioremap registers\n"); - return -ENXIO; - } - i2s->clk = clk_get(&i2s->pdev->dev, "iis"); if (IS_ERR(i2s->clk)) { dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); - iounmap(i2s->addr); return PTR_ERR(i2s->clk); } @@ -1001,7 +992,6 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); if (other) { - other->addr = i2s->addr; other->clk = i2s->clk; } @@ -1043,8 +1033,6 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) clk_disable_unprepare(i2s->clk); clk_put(i2s->clk); - - iounmap(i2s->addr); } i2s->clk = NULL; @@ -1162,7 +1150,6 @@ static int samsung_i2s_probe(struct platform_device *pdev) u32 regs_base, quirks = 0, idma_addr = 0; struct device_node *np = pdev->dev.of_node; const struct samsung_i2s_dai_data *i2s_dai_data; - int ret = 0; /* Call during Seconday interface registration */ i2s_dai_data = samsung_i2s_get_driver_data(pdev); @@ -1229,16 +1216,10 @@ static int samsung_i2s_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); - return -ENXIO; - } + pri_dai->addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pri_dai->addr)) + return PTR_ERR(pri_dai->addr); - if (!request_mem_region(res->start, resource_size(res), - "samsung-i2s")) { - dev_err(&pdev->dev, "Unable to request SFR region\n"); - return -EBUSY; - } regs_base = res->start; pri_dai->dma_playback.dma_addr = regs_base + I2STXD; @@ -1247,7 +1228,6 @@ static int samsung_i2s_probe(struct platform_device *pdev) pri_dai->dma_capture.ch_name = "rx"; pri_dai->dma_playback.dma_size = 4; pri_dai->dma_capture.dma_size = 4; - pri_dai->base = regs_base; pri_dai->quirks = quirks; pri_dai->variant_regs = i2s_dai_data->i2s_variant_regs; @@ -1258,8 +1238,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) sec_dai = i2s_alloc_dai(pdev, true); if (!sec_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); - ret = -ENOMEM; - goto err; + return -ENOMEM; } sec_dai->variant_regs = pri_dai->variant_regs; @@ -1273,7 +1252,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) } sec_dai->dma_playback.dma_size = 4; - sec_dai->base = regs_base; + sec_dai->addr = pri_dai->addr; sec_dai->quirks = quirks; sec_dai->idma_playback.dma_addr = idma_addr; sec_dai->pri_dai = pri_dai; @@ -1282,8 +1261,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { dev_err(&pdev->dev, "Unable to configure gpio\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } devm_snd_soc_register_component(&pri_dai->pdev->dev, @@ -1297,17 +1275,11 @@ static int samsung_i2s_probe(struct platform_device *pdev) return ret; return 0; -err: - if (res) - release_mem_region(regs_base, resource_size(res)); - - return ret; } static int samsung_i2s_remove(struct platform_device *pdev) { struct i2s_dai *i2s, *other; - struct resource *res; i2s = dev_get_drvdata(&pdev->dev); other = i2s->pri_dai ? : i2s->sec_dai; @@ -1317,9 +1289,6 @@ static int samsung_i2s_remove(struct platform_device *pdev) other->sec_dai = NULL; } else { pm_runtime_disable(&pdev->dev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) - release_mem_region(res->start, resource_size(res)); } i2s->pri_dai = NULL; -- cgit v1.2.3 From 0ec2ba807c1563134a865b6f0b326b8a2e776937 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:31 +0100 Subject: ASoC: samsung: i2s: Move clk_get() to platform driver probe() Acquire the I2S interface clock in driver probe() callback as it's a per-device not a per-DAI clock. While at it switch to the resource managed clk_get(). Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 366b720731e1..a854ffca2416 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -971,18 +971,12 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; int ret; - if (other && other->clk) { /* If this is probe on secondary */ + if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, NULL); goto probe_exit; } - i2s->clk = clk_get(&i2s->pdev->dev, "iis"); - if (IS_ERR(i2s->clk)) { - dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); - return PTR_ERR(i2s->clk); - } - ret = clk_prepare_enable(i2s->clk); if (ret != 0) { dev_err(&i2s->pdev->dev, "failed to enable clock: %d\n", ret); @@ -991,10 +985,6 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); - if (other) { - other->clk = i2s->clk; - } - if (i2s->quirks & QUIRK_NEED_RSTCLR) writel(CON_RSTCLR, i2s->addr + I2SCON); @@ -1032,7 +1022,6 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) writel(0, i2s->addr + I2SCON); clk_disable_unprepare(i2s->clk); - clk_put(i2s->clk); } i2s->clk = NULL; @@ -1222,6 +1211,11 @@ static int samsung_i2s_probe(struct platform_device *pdev) regs_base = res->start; + pri_dai->clk = devm_clk_get(&pdev->dev, "iis"); + if (IS_ERR(pri_dai->clk)) { + dev_err(&pdev->dev, "Failed to get iis clock\n"); + return PTR_ERR(pri_dai->clk); + } pri_dai->dma_playback.dma_addr = regs_base + I2STXD; pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; pri_dai->dma_playback.ch_name = "tx"; @@ -1253,6 +1247,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) sec_dai->dma_playback.dma_size = 4; sec_dai->addr = pri_dai->addr; + sec_dai->clk = pri_dai->clk; sec_dai->quirks = quirks; sec_dai->idma_playback.dma_addr = idma_addr; sec_dai->pri_dai = pri_dai; -- cgit v1.2.3 From c92f1d0e7c8431f8b3bf1d42e951ead07b22078e Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:32 +0100 Subject: ASoC: samsung: i2s: Move clk enable to the platform driver probe() The clk_prepare_enable() call on the "iis" clock is moved to happen earlier in the DAI platform device driver's probe() callback, so the I2S registers can be safely accessed through the clk API, after the clk supplier is registered in the platform device probe(). After this patch the "iis" clock is kept enabled since the (primary) I2S platform device probe() and until the platform device driver remove() call. This is similar to gating the clock in the snd_soc_dai probe() and remove() callbacks. Normally, in addition to that we should mark the device as PM runtime active, so if runtime PM is enabled it can idle the device by turning off the clock. Correcting this issue is left for a separate patch series, as we need to ensure the BUSCLK clock is always enabled when required. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index a854ffca2416..f75c19e5b5c3 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -969,7 +969,6 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - int ret; if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, @@ -977,12 +976,6 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) goto probe_exit; } - ret = clk_prepare_enable(i2s->clk); - if (ret != 0) { - dev_err(&i2s->pdev->dev, "failed to enable clock: %d\n", ret); - return ret; - } - samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); if (i2s->quirks & QUIRK_NEED_RSTCLR) @@ -1014,18 +1007,12 @@ probe_exit: static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) { struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - - if (!other || !other->clk) { + if (!is_secondary(i2s)) { if (i2s->quirks & QUIRK_NEED_RSTCLR) writel(0, i2s->addr + I2SCON); - - clk_disable_unprepare(i2s->clk); } - i2s->clk = NULL; - return 0; } @@ -1139,6 +1126,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) u32 regs_base, quirks = 0, idma_addr = 0; struct device_node *np = pdev->dev.of_node; const struct samsung_i2s_dai_data *i2s_dai_data; + int ret; /* Call during Seconday interface registration */ i2s_dai_data = samsung_i2s_get_driver_data(pdev); @@ -1216,6 +1204,12 @@ static int samsung_i2s_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to get iis clock\n"); return PTR_ERR(pri_dai->clk); } + + ret = clk_prepare_enable(pri_dai->clk); + if (ret != 0) { + dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); + return ret; + } pri_dai->dma_playback.dma_addr = regs_base + I2STXD; pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; pri_dai->dma_playback.ch_name = "tx"; @@ -1286,6 +1280,9 @@ static int samsung_i2s_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } + if (!is_secondary(i2s)) + clk_disable_unprepare(i2s->clk); + i2s->pri_dai = NULL; i2s->sec_dai = NULL; -- cgit v1.2.3 From dcd60fc3445329d738a23ab7997717491c2f4cec Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:33 +0100 Subject: ASoC: samsung: i2s: Add get_other_dai helper function The code to get pointer to the other DAI is repeated multiple times. Add a helper function and use it instead. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index f75c19e5b5c3..cab2a2abc89b 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -130,10 +130,16 @@ static inline bool tx_active(struct i2s_dai *i2s) return active ? true : false; } +/* Return pointer to the other DAI */ +static inline struct i2s_dai *get_other_dai(struct i2s_dai *i2s) +{ + return i2s->pri_dai ? : i2s->sec_dai; +} + /* If the other interface of the controller is transmitting data */ static inline bool other_tx_active(struct i2s_dai *i2s) { - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); return tx_active(other); } @@ -160,7 +166,7 @@ static inline bool rx_active(struct i2s_dai *i2s) /* If the other interface of the controller is receiving data */ static inline bool other_rx_active(struct i2s_dai *i2s) { - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); return rx_active(other); } @@ -461,7 +467,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int rfs, int dir) { struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); u32 mod = readl(i2s->addr + I2SMOD); const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; @@ -733,7 +739,7 @@ static int i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); unsigned long flags; spin_lock_irqsave(&lock, flags); @@ -760,7 +766,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); unsigned long flags; const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; @@ -791,7 +797,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, static int config_setup(struct i2s_dai *i2s) { - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); unsigned rfs, bfs, blc; u32 psr; @@ -899,7 +905,7 @@ static int i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) { struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); switch (div_id) { case SAMSUNG_I2S_DIV_BCLK: @@ -968,7 +974,7 @@ static int i2s_resume(struct snd_soc_dai *dai) static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + struct i2s_dai *other = get_other_dai(i2s); if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, @@ -1271,7 +1277,7 @@ static int samsung_i2s_remove(struct platform_device *pdev) struct i2s_dai *i2s, *other; i2s = dev_get_drvdata(&pdev->dev); - other = i2s->pri_dai ? : i2s->sec_dai; + other = get_other_dai(i2s); if (other) { other->pri_dai = NULL; -- cgit v1.2.3 From 872c26bd801dcda21402caa2dcd0a39315b08b65 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:34 +0100 Subject: ASoC: samsung: i2s: Remove an unneeded goto usage The usage of this goto seems unjustified, use if/else statement instead. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index cab2a2abc89b..2bac71945b3e 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -979,19 +979,18 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, NULL); - goto probe_exit; - } - - samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + } else { + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, + &i2s->dma_capture); - if (i2s->quirks & QUIRK_NEED_RSTCLR) - writel(CON_RSTCLR, i2s->addr + I2SCON); + if (i2s->quirks & QUIRK_NEED_RSTCLR) + writel(CON_RSTCLR, i2s->addr + I2SCON); - if (i2s->quirks & QUIRK_SUPPORTS_IDMA) - idma_reg_addr_init(i2s->addr, + if (i2s->quirks & QUIRK_SUPPORTS_IDMA) + idma_reg_addr_init(i2s->addr, i2s->sec_dai->idma_playback.dma_addr); + } -probe_exit: /* Reset any constraint on RFS and BFS */ i2s->rfs = 0; i2s->bfs = 0; -- cgit v1.2.3 From f36705366a2324fedd6cca7683fadf947ac0b154 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:35 +0100 Subject: ASoC: samsung: i2s: Add spinlock in place of local_irq_* calls It seems this driver hasn't been updated for SMP, as local_irq_save/ local_irq_restore don't provide proper protection of read/modify/write of the device's registers on such systems. Introduce a spinlock serializing access to the register region, it will be helpful later when I2SMOD, I2SPSR registers are made also accessible through the clk API. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 2bac71945b3e..20cc51fc76ae 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -94,6 +94,10 @@ struct i2s_dai { u32 suspend_i2scon; u32 suspend_i2spsr; const struct samsung_i2s_variant_regs *variant_regs; + + /* Spinlock protecting access to the device's registers */ + spinlock_t spinlock; + spinlock_t *lock; }; /* Lock for cross i/f checks */ @@ -867,10 +871,10 @@ static int i2s_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - local_irq_save(flags); + spin_lock_irqsave(i2s->lock, flags); if (config_setup(i2s)) { - local_irq_restore(flags); + spin_unlock_irqrestore(i2s->lock, flags); return -EINVAL; } @@ -879,12 +883,12 @@ static int i2s_trigger(struct snd_pcm_substream *substream, else i2s_txctrl(i2s, 1); - local_irq_restore(flags); + spin_unlock_irqrestore(i2s->lock, flags); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - local_irq_save(flags); + spin_lock_irqsave(i2s->lock, flags); if (capture) { i2s_rxctrl(i2s, 0); @@ -894,7 +898,7 @@ static int i2s_trigger(struct snd_pcm_substream *substream, i2s_fifo(i2s, FIC_TXFLUSH); } - local_irq_restore(flags); + spin_unlock_irqrestore(i2s->lock, flags); break; } @@ -1157,6 +1161,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) return -ENOMEM; } + spin_lock_init(&pri_dai->spinlock); + pri_dai->lock = &pri_dai->spinlock; + if (!np) { res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { @@ -1234,6 +1241,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) return -ENOMEM; } + sec_dai->lock = &pri_dai->spinlock; sec_dai->variant_regs = pri_dai->variant_regs; sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; sec_dai->dma_playback.ch_name = "tx-sec"; -- cgit v1.2.3 From ce8bcdbb61d96de481de14b3ad985797a417246c Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:36 +0100 Subject: ASoC: samsung: i2s: Protect more registers with a spinlock Ensure the I2SMOD, I2SPSR registers, which are also exposed through clk API are only accessed with the i2s->spinlock spinlock held. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 81 +++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 30 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 20cc51fc76ae..05fc2f0e91ca 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -472,17 +472,22 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, { struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = get_other_dai(i2s); - u32 mod = readl(i2s->addr + I2SMOD); const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; + u32 mod, mask, val = 0; + + spin_lock(i2s->lock); + mod = readl(i2s->addr + I2SMOD); + spin_unlock(i2s->lock); switch (clk_id) { case SAMSUNG_I2S_OPCLK: - mod &= ~MOD_OPCLK_MASK; - mod |= dir; + mask = MOD_OPCLK_MASK; + val = dir; break; case SAMSUNG_I2S_CDCLK: + mask = 1 << i2s_regs->cdclkcon_off; /* Shouldn't matter in GATING(CLOCK_IN) mode */ if (dir == SND_SOC_CLOCK_IN) rfs = 0; @@ -499,15 +504,15 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, } if (dir == SND_SOC_CLOCK_IN) - mod |= 1 << i2s_regs->cdclkcon_off; - else - mod &= ~(1 << i2s_regs->cdclkcon_off); + val = 1 << i2s_regs->cdclkcon_off; i2s->rfs = rfs; break; case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ + mask = 1 << i2s_regs->rclksrc_off; + if ((i2s->quirks & QUIRK_NO_MUXPSR) || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) clk_id = 0; @@ -557,18 +562,19 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, return 0; } - if (clk_id == 0) - mod &= ~(1 << i2s_regs->rclksrc_off); - else - mod |= 1 << i2s_regs->rclksrc_off; - + if (clk_id == 1) + val = 1 << i2s_regs->rclksrc_off; break; default: dev_err(&i2s->pdev->dev, "We don't serve that!\n"); return -EINVAL; } + spin_lock(i2s->lock); + mod = readl(i2s->addr + I2SMOD); + mod = (mod & ~mask) | val; writel(mod, i2s->addr + I2SMOD); + spin_unlock(i2s->lock); return 0; } @@ -577,9 +583,8 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct i2s_dai *i2s = to_info(dai); - u32 mod = readl(i2s->addr + I2SMOD); int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave; - u32 tmp = 0; + u32 mod, tmp = 0; lrp_shift = i2s->variant_regs->lrp_off; sdf_shift = i2s->variant_regs->sdf_off; @@ -639,12 +644,15 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, return -EINVAL; } + spin_lock(i2s->lock); + mod = readl(i2s->addr + I2SMOD); /* * Don't change the I2S mode if any controller is active on this * channel. */ if (any_active(i2s) && ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) { + spin_unlock(i2s->lock); dev_err(&i2s->pdev->dev, "%s:%d Other DAI busy\n", __func__, __LINE__); return -EAGAIN; @@ -653,6 +661,7 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, mod &= ~(sdf_mask | lrp_rlow | mod_slave); mod |= tmp; writel(mod, i2s->addr + I2SMOD); + spin_unlock(i2s->lock); return 0; } @@ -661,16 +670,16 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); - u32 mod = readl(i2s->addr + I2SMOD); + u32 mod, mask = 0, val = 0; if (!is_secondary(i2s)) - mod &= ~(MOD_DC2_EN | MOD_DC1_EN); + mask |= (MOD_DC2_EN | MOD_DC1_EN); switch (params_channels(params)) { case 6: - mod |= MOD_DC2_EN; + val |= MOD_DC2_EN; case 4: - mod |= MOD_DC1_EN; + val |= MOD_DC1_EN; break; case 2: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -692,44 +701,49 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, } if (is_secondary(i2s)) - mod &= ~MOD_BLCS_MASK; + mask |= MOD_BLCS_MASK; else - mod &= ~MOD_BLCP_MASK; + mask |= MOD_BLCP_MASK; if (is_manager(i2s)) - mod &= ~MOD_BLC_MASK; + mask |= MOD_BLC_MASK; switch (params_width(params)) { case 8: if (is_secondary(i2s)) - mod |= MOD_BLCS_8BIT; + val |= MOD_BLCS_8BIT; else - mod |= MOD_BLCP_8BIT; + val |= MOD_BLCP_8BIT; if (is_manager(i2s)) - mod |= MOD_BLC_8BIT; + val |= MOD_BLC_8BIT; break; case 16: if (is_secondary(i2s)) - mod |= MOD_BLCS_16BIT; + val |= MOD_BLCS_16BIT; else - mod |= MOD_BLCP_16BIT; + val |= MOD_BLCP_16BIT; if (is_manager(i2s)) - mod |= MOD_BLC_16BIT; + val |= MOD_BLC_16BIT; break; case 24: if (is_secondary(i2s)) - mod |= MOD_BLCS_24BIT; + val |= MOD_BLCS_24BIT; else - mod |= MOD_BLCP_24BIT; + val |= MOD_BLCP_24BIT; if (is_manager(i2s)) - mod |= MOD_BLC_24BIT; + val |= MOD_BLC_24BIT; break; default: dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", params_format(params)); return -EINVAL; } + + spin_lock(i2s->lock); + mod = readl(i2s->addr + I2SMOD); + mod = (mod & ~mask) | val; writel(mod, i2s->addr + I2SMOD); + spin_unlock(i2s->lock); samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); @@ -979,6 +993,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) { struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = get_other_dai(i2s); + unsigned long flags; if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, @@ -999,11 +1014,14 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) i2s->rfs = 0; i2s->bfs = 0; i2s->rclk_srcrate = 0; + + spin_lock_irqsave(i2s->lock, flags); i2s_txctrl(i2s, 0); i2s_rxctrl(i2s, 0); i2s_fifo(i2s, FIC_TXFLUSH); i2s_fifo(other, FIC_TXFLUSH); i2s_fifo(i2s, FIC_RXFLUSH); + spin_unlock_irqrestore(i2s->lock, flags); /* Gate CDCLK by default */ if (!is_opened(other)) @@ -1018,8 +1036,11 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); if (!is_secondary(i2s)) { - if (i2s->quirks & QUIRK_NEED_RSTCLR) + if (i2s->quirks & QUIRK_NEED_RSTCLR) { + spin_lock(i2s->lock); writel(0, i2s->addr + I2SCON); + spin_unlock(i2s->lock); + } } return 0; -- cgit v1.2.3 From ecb400cabb37cfef3221e45e4f6370a855aa7a44 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:37 +0100 Subject: ASoC: samsung: odroidx2: Handle I2S CDCLK clock conditionally In order to support old DTs we check the codec device node if it contains "clocks" property and only if it doesn't (which indicates an old DT) we proceed with enabling the CDCLK clock by means of the set_sysclk() callback. For new DTs which use the common clock bindings for CDCLK that clock is supposed to be handled outside the sound machine driver. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/odroidx2_max98090.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c index fa4f1d2f69bf..596f1180a369 100644 --- a/sound/soc/samsung/odroidx2_max98090.c +++ b/sound/soc/samsung/odroidx2_max98090.c @@ -21,6 +21,8 @@ struct odroidx2_drv_data { /* The I2S CDCLK output clock frequency for the MAX98090 codec */ #define MAX98090_MCLK 19200000 +static struct snd_soc_dai_link odroidx2_dai[]; + static int odroidx2_late_probe(struct snd_soc_card *card) { struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; @@ -29,7 +31,9 @@ static int odroidx2_late_probe(struct snd_soc_card *card) ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, SND_SOC_CLOCK_IN); - if (ret < 0) + + if (ret < 0 || of_find_property(odroidx2_dai[0].codec_of_node, + "clocks", NULL)) return ret; /* Set the cpu DAI configuration in order to use CDCLK */ -- cgit v1.2.3 From 074b89bb5fb7e80e0f98f1b45f276b0386269e3d Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 14 Jan 2015 19:42:39 +0100 Subject: ASoC: samsung: i2s: Add clock provider for the I2S internal clocks This patch adds clock provider (currently only for DT platforms) for the CODECLKO (CDCLK) gate, RCLKSRC mux and RCLK pre-scaler divider divider clock. Those all tree clock are only available in the IIS Multi Audio Interface (I2S0), the regular IIS Bus Interface has only CDCLK gate clock. The motivation behind this patch is to expose the I2S internal clocks which are currently controlled through set_sysclk() through the clk API, so dedicated sound machine driver per each board can be avoided. The intention is also to fix the CDCLK gating issue reported by Daniel Drake: http://mailman.alsa-project.org/pipermail/alsa-devel/2014-September/081753.html This patch also reverts commit b97c60abf9a561f86ae71bd741add02673cc1 ("ASoC: samsung-i2s: Maintain CDCLK settings across i2s_{shutdown/ startup}") The problem that commit attempted to solve only affects the Odroid X2/U3, which doesn't configure the CDCLK clock in struct snd_soc_dai_ops hw_params callback and the issue should be now resolved by using clk API, i.e. having the codec enabling/ disabling the CDCLK clock as required. Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 113 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 20 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 05fc2f0e91ca..b92ab40d2be6 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -10,9 +10,11 @@ * published by the Free Software Foundation. */ +#include #include #include #include +#include #include #include #include @@ -81,8 +83,6 @@ struct i2s_dai { #define DAI_OPENED (1 << 0) /* Dai is opened */ #define DAI_MANAGER (1 << 1) /* Dai is the manager */ unsigned mode; - /* CDCLK pin direction: 0 - input, 1 - output */ - unsigned int cdclk_out:1; /* Driver for this DAI */ struct snd_soc_dai_driver i2s_dai_drv; /* DMA parameters */ @@ -98,6 +98,10 @@ struct i2s_dai { /* Spinlock protecting access to the device's registers */ spinlock_t spinlock; spinlock_t *lock; + + /* Below fields are only valid if this is the primary FIFO */ + struct clk *clk_table[3]; + struct clk_onecell_data clk_data; }; /* Lock for cross i/f checks */ @@ -774,9 +778,6 @@ static int i2s_startup(struct snd_pcm_substream *substream, spin_unlock_irqrestore(&lock, flags); - if (!is_opened(other) && i2s->cdclk_out) - i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, - 0, SND_SOC_CLOCK_OUT); return 0; } @@ -786,31 +787,20 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = get_other_dai(i2s); unsigned long flags; - const struct samsung_i2s_variant_regs *i2s_regs = i2s->variant_regs; spin_lock_irqsave(&lock, flags); i2s->mode &= ~DAI_OPENED; i2s->mode &= ~DAI_MANAGER; - if (is_opened(other)) { + if (is_opened(other)) other->mode |= DAI_MANAGER; - } else { - u32 mod = readl(i2s->addr + I2SMOD); - i2s->cdclk_out = !(mod & (1 << i2s_regs->cdclkcon_off)); - if (other) - other->cdclk_out = i2s->cdclk_out; - } + /* Reset any constraint on RFS and BFS */ i2s->rfs = 0; i2s->bfs = 0; spin_unlock_irqrestore(&lock, flags); - - /* Gate CDCLK by default */ - if (!is_opened(other)) - i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, - 0, SND_SOC_CLOCK_IN); } static int config_setup(struct i2s_dai *i2s) @@ -1147,6 +1137,87 @@ static int i2s_runtime_resume(struct device *dev) } #endif /* CONFIG_PM */ +static void i2s_unregister_clocks(struct i2s_dai *i2s) +{ + int i; + + for (i = 0; i < i2s->clk_data.clk_num; i++) { + if (!IS_ERR(i2s->clk_table[i])) + clk_unregister(i2s->clk_table[i]); + } +} + +static void i2s_unregister_clock_provider(struct platform_device *pdev) +{ + struct i2s_dai *i2s = dev_get_drvdata(&pdev->dev); + + of_clk_del_provider(pdev->dev.of_node); + i2s_unregister_clocks(i2s); +} + +static int i2s_register_clock_provider(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct i2s_dai *i2s = dev_get_drvdata(dev); + const char *clk_name[2] = { "i2s_opclk0", "i2s_opclk1" }; + const char *p_names[2] = { NULL }; + const struct samsung_i2s_variant_regs *reg_info = i2s->variant_regs; + struct clk *rclksrc; + int ret, i; + + /* Register the clock provider only if it's expected in the DTB */ + if (!of_find_property(dev->of_node, "#clock-cells", NULL)) + return 0; + + /* Get the RCLKSRC mux clock parent clock names */ + for (i = 0; i < ARRAY_SIZE(p_names); i++) { + rclksrc = clk_get(dev, clk_name[i]); + if (IS_ERR(rclksrc)) + continue; + p_names[i] = __clk_get_name(rclksrc); + clk_put(rclksrc); + } + + if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { + /* Activate the prescaler */ + u32 val = readl(i2s->addr + I2SPSR); + writel(val | PSR_PSREN, i2s->addr + I2SPSR); + + i2s->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(NULL, + "i2s_rclksrc", p_names, ARRAY_SIZE(p_names), + CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, + i2s->addr + I2SMOD, reg_info->rclksrc_off, + 1, 0, i2s->lock); + + i2s->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(NULL, + "i2s_presc", "i2s_rclksrc", + CLK_SET_RATE_PARENT, + i2s->addr + I2SPSR, 8, 6, 0, i2s->lock); + + p_names[0] = "i2s_presc"; + i2s->clk_data.clk_num = 2; + } + of_property_read_string_index(dev->of_node, + "clock-output-names", 0, &clk_name[0]); + + i2s->clk_table[CLK_I2S_CDCLK] = clk_register_gate(NULL, clk_name[0], + p_names[0], CLK_SET_RATE_PARENT, + i2s->addr + I2SMOD, reg_info->cdclkcon_off, + CLK_GATE_SET_TO_DISABLE, i2s->lock); + + i2s->clk_data.clk_num += 1; + i2s->clk_data.clks = i2s->clk_table; + + ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, + &i2s->clk_data); + if (ret < 0) { + dev_err(dev, "failed to add clock provider: %d\n", ret); + i2s_unregister_clocks(i2s); + } + + return ret; +} + static int samsung_i2s_probe(struct platform_device *pdev) { struct i2s_dai *pri_dai, *sec_dai = NULL; @@ -1297,7 +1368,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) if (ret != 0) return ret; - return 0; + return i2s_register_clock_provider(pdev); } static int samsung_i2s_remove(struct platform_device *pdev) @@ -1314,8 +1385,10 @@ static int samsung_i2s_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } - if (!is_secondary(i2s)) + if (!is_secondary(i2s)) { + i2s_unregister_clock_provider(pdev); clk_disable_unprepare(i2s->clk); + } i2s->pri_dai = NULL; i2s->sec_dai = NULL; -- cgit v1.2.3 From 3a41e0f7233a644b45e536a31c0116500ac106a4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 16 Jan 2015 14:34:52 +0100 Subject: ASoC: jive: Automatically disconnect non-connected pins All DAPM input and output pins of the wm8750 are either used in the card's DAPM routing table or are marked as not connected. Set the fully_routed flag of the card instead of manually marking the unused inputs and outputs as not connected. This makes the code a bit shorter and cleaner. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/jive_wm8750.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 6c3b359bb4c1..7fcb51faa2a0 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c @@ -83,22 +83,6 @@ static struct snd_soc_ops jive_ops = { .hw_params = jive_hw_params, }; -static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - /* These endpoints are not being used. */ - snd_soc_dapm_nc_pin(dapm, "LINPUT2"); - snd_soc_dapm_nc_pin(dapm, "RINPUT2"); - snd_soc_dapm_nc_pin(dapm, "LINPUT3"); - snd_soc_dapm_nc_pin(dapm, "RINPUT3"); - snd_soc_dapm_nc_pin(dapm, "OUT3"); - snd_soc_dapm_nc_pin(dapm, "MONO"); - - return 0; -} - static struct snd_soc_dai_link jive_dai = { .name = "wm8750", .stream_name = "WM8750", @@ -106,7 +90,6 @@ static struct snd_soc_dai_link jive_dai = { .codec_dai_name = "wm8750-hifi", .platform_name = "s3c2412-i2s", .codec_name = "wm8750.0-001a", - .init = jive_wm8750_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .ops = &jive_ops, @@ -123,6 +106,7 @@ static struct snd_soc_card snd_soc_machine_jive = { .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), .dapm_routes = audio_map, .num_dapm_routes = ARRAY_SIZE(audio_map), + .fully_routed = true, }; static struct platform_device *jive_snd_device; -- cgit v1.2.3 From e236d4d796f87d062f59af8004c8f485baf10b62 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 16 Jan 2015 14:34:53 +0100 Subject: ASoC: smdk_wm8580: Pass card DAPM context to snd_soc_dapm_disable_pin() The "MicIn" widget is a card level DAPM element so pass the card's DAPM context instead of the CODEC's DAPM context to snd_soc_dapm_disable_pin(). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm8580.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 17a2f717ec02..548bfd993788 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -136,13 +136,10 @@ static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = { static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - /* Enabling the microphone requires the fitting of a 0R * resistor to connect the line from the microphone jack. */ - snd_soc_dapm_disable_pin(dapm, "MicIn"); + snd_soc_dapm_disable_pin(&rtd->card->dapm, "MicIn"); return 0; } -- cgit v1.2.3 From a59aa180ea56004a8dd6ece93699adf5eacdf4d9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 16 Jan 2015 20:04:16 +0100 Subject: ASoC: samsung: Replace depends on REGMAP_I2C with depends on I2C regmap is a library function that gets selected by drivers that need it. No driver modules should depend on it, since this can create dependency loops. E.g. if machine driver depends on REGMAP_I2C and selects the CODEC driver and the CODEC driver selects REGMAP_I2C, then the machine driver selects by extension one of its dependencies. The proper way to handle this is for machine drivers to depend on the same dependencies as the CODEC driver they select. In this case it is I2C. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fc67f97f19f6..e817a2f43ea8 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -54,7 +54,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 config SND_SOC_SAMSUNG_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) - depends on REGMAP_I2C + depends on I2C select SND_SOC_WM8580 select SND_SAMSUNG_I2S help @@ -167,7 +167,7 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF config SND_SOC_SMDK_WM8580_PCM tristate "SoC PCM Audio support for WM8580 on SMDK" depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110) - depends on REGMAP_I2C + depends on I2C select SND_SOC_WM8580 select SND_SAMSUNG_PCM help -- cgit v1.2.3 From 6cf2cf31507522c199cf7974245bec9ac94cd9ea Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 19 Jan 2015 11:41:41 +0100 Subject: ASoC: samsung: Remove goni or aquila with the WM8994 Commit 28c8331d386a ("ARM: S5PV210: Remove support for board files") removed the Kconfig symbols MACH_GONI and MACH_AQUILA. As a result the dependencies of SND_SOC_GONI_AQUILA_WM8994 can never be met. So remove the unbuildable "SoC I2S Audio support for AQUILA/GONI - WM8994". Signed-off-by: Paul Bolle Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 11 -- sound/soc/samsung/Makefile | 2 - sound/soc/samsung/goni_wm8994.c | 289 ---------------------------------------- 3 files changed, 302 deletions(-) delete mode 100644 sound/soc/samsung/goni_wm8994.c (limited to 'sound/soc/samsung') diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index e817a2f43ea8..3cebf6ca03df 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -146,17 +146,6 @@ config SND_SOC_SMARTQ select SND_SAMSUNG_I2S select SND_SOC_WM8750 -config SND_SOC_GONI_AQUILA_WM8994 - tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" - depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) - depends on I2C=y - select SND_SAMSUNG_I2S - select MFD_WM8994 - select SND_SOC_WM8994 - help - Say Y if you want to add support for SoC audio on goni or aquila - with the WM8994. - config SND_SOC_SAMSUNG_SMDK_SPDIF tristate "SoC S/PDIF Audio support for SMDK" depends on SND_SOC_SAMSUNG diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 31e3dba7e3b5..052fe71be518 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -35,7 +35,6 @@ snd-soc-smdk-wm8994-objs := smdk_wm8994.o snd-soc-snow-objs := snow.o snd-soc-smdk-wm9713-objs := smdk_wm9713.o snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o -snd-soc-goni-wm8994-objs := goni_wm8994.o snd-soc-smdk-spdif-objs := smdk_spdif.o snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o @@ -63,7 +62,6 @@ obj-$(CONFIG_SND_SOC_SNOW) += snd-soc-snow.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o -obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c deleted file mode 100644 index fad56b9e7369..000000000000 --- a/sound/soc/samsung/goni_wm8994.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * goni_wm8994.c - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Chanwoo Choi - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include - -#include -#include - -#include "../codecs/wm8994.h" - -#define MACHINE_NAME 0 -#define CPU_VOICE_DAI 1 - -static const char *aquila_str[] = { - [MACHINE_NAME] = "aquila", - [CPU_VOICE_DAI] = "aquila-voice-dai", -}; - -static struct snd_soc_card goni; -static struct platform_device *goni_snd_device; - -/* 3.5 pie jack */ -static struct snd_soc_jack jack; - -/* 3.5 pie jack detection DAPM pins */ -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, { - .pin = "Headset Stereophone", - .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - }, -}; - -/* 3.5 pie jack detection gpios */ -static struct snd_soc_jack_gpio jack_gpios[] = { - { - .gpio = S5PV210_GPH0(6), - .name = "DET_3.5", - .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - .debounce_time = 200, - }, -}; - -static const struct snd_soc_dapm_widget goni_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Ext Left Spk", NULL), - SND_SOC_DAPM_SPK("Ext Right Spk", NULL), - SND_SOC_DAPM_SPK("Ext Rcv", NULL), - SND_SOC_DAPM_HP("Headset Stereophone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Main Mic", NULL), - SND_SOC_DAPM_MIC("2nd Mic", NULL), - SND_SOC_DAPM_LINE("Radio In", NULL), -}; - -static const struct snd_soc_dapm_route goni_dapm_routes[] = { - {"Ext Left Spk", NULL, "SPKOUTLP"}, - {"Ext Left Spk", NULL, "SPKOUTLN"}, - - {"Ext Right Spk", NULL, "SPKOUTRP"}, - {"Ext Right Spk", NULL, "SPKOUTRN"}, - - {"Ext Rcv", NULL, "HPOUT2N"}, - {"Ext Rcv", NULL, "HPOUT2P"}, - - {"Headset Stereophone", NULL, "HPOUT1L"}, - {"Headset Stereophone", NULL, "HPOUT1R"}, - - {"IN1RN", NULL, "Headset Mic"}, - {"IN1RP", NULL, "Headset Mic"}, - - {"IN1RN", NULL, "2nd Mic"}, - {"IN1RP", NULL, "2nd Mic"}, - - {"IN1LN", NULL, "Main Mic"}, - {"IN1LP", NULL, "Main Mic"}, - - {"IN2LN", NULL, "Radio In"}, - {"IN2RN", NULL, "Radio In"}, -}; - -static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); - - if (machine_is_aquila()) { - snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); - } - - /* Headset jack detection */ - ret = snd_soc_jack_new(codec, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, - &jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); - if (ret) - return ret; - - ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); - if (ret) - return ret; - - return 0; -} - -static int goni_hifi_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 *codec_dai = rtd->codec_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops goni_hifi_ops = { - .hw_params = goni_hifi_hw_params, -}; - -static int goni_voice_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 *codec_dai = rtd->codec_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - if (params_rate(params) != 8000) - return -EINVAL; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_dai_driver voice_dai = { - .name = "goni-voice-dai", - .id = 0, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static const struct snd_soc_component_driver voice_component = { - .name = "goni-voice", -}; - -static struct snd_soc_ops goni_voice_ops = { - .hw_params = goni_voice_hw_params, -}; - -static struct snd_soc_dai_link goni_dai[] = { -{ - .name = "WM8994", - .stream_name = "WM8994 HiFi", - .cpu_dai_name = "samsung-i2s.0", - .codec_dai_name = "wm8994-aif1", - .platform_name = "samsung-i2s.0", - .codec_name = "wm8994-codec.0-001a", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, - .init = goni_wm8994_init, - .ops = &goni_hifi_ops, -}, { - .name = "WM8994 Voice", - .stream_name = "Voice", - .cpu_dai_name = "goni-voice-dai", - .codec_dai_name = "wm8994-aif2", - .codec_name = "wm8994-codec.0-001a", - .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_IB_IF | - SND_SOC_DAIFMT_CBM_CFM, - .ops = &goni_voice_ops, -}, -}; - -static struct snd_soc_card goni = { - .name = "goni", - .owner = THIS_MODULE, - .dai_link = goni_dai, - .num_links = ARRAY_SIZE(goni_dai), - - .dapm_widgets = goni_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(goni_dapm_widgets), - .dapm_routes = goni_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(goni_dapm_routes), -}; - -static int __init goni_init(void) -{ - int ret; - - if (machine_is_aquila()) { - voice_dai.name = aquila_str[CPU_VOICE_DAI]; - goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI]; - goni.name = aquila_str[MACHINE_NAME]; - } else if (!machine_is_goni()) - return -ENODEV; - - goni_snd_device = platform_device_alloc("soc-audio", -1); - if (!goni_snd_device) - return -ENOMEM; - - /* register voice DAI here */ - ret = devm_snd_soc_register_component(&goni_snd_device->dev, - &voice_component, &voice_dai, 1); - if (ret) { - platform_device_put(goni_snd_device); - return ret; - } - - platform_set_drvdata(goni_snd_device, &goni); - ret = platform_device_add(goni_snd_device); - - if (ret) - platform_device_put(goni_snd_device); - - return ret; -} - -static void __exit goni_exit(void) -{ - platform_device_unregister(goni_snd_device); -} - -module_init(goni_init); -module_exit(goni_exit); - -/* Module information */ -MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)"); -MODULE_AUTHOR("Chanwoo Choi "); -MODULE_LICENSE("GPL"); -- cgit v1.2.3