summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 11:51:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 11:51:59 -0500
commita323ae93a74f669d890926187c68c711895e3454 (patch)
tree9a4ab8ed7bb98dc4321606332a883834ef7c8f6f /sound/soc/intel
parent3e63430a5cc26bc90a6e33ab33f901196b7b63ac (diff)
parent0e806151e86be52caa1349fa490eab8f09a2b6f5 (diff)
Merge tag 'sound-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "In this batch, you can find lots of cleanups through the whole subsystem, as our good New Year's resolution. Lots of LOCs and commits are about LINE6 driver that was promoted finally from staging tree, and as usual, there've been widely spread ASoC changes. Here some highlights: ALSA core changes - Embedding struct device into ALSA core structures - sequencer core cleanups / fixes - PCM msbits constraints cleanups / fixes - New SNDRV_PCM_TRIGGER_DRAIN command - PCM kerneldoc fixes, header cleanups - PCM code cleanups using more standard codes - Control notification ID fixes Driver cleanups - Cleanups of PCI PM callbacks - Timer helper usages cleanups - Simplification (e.g. argument reduction) of many driver codes HD-audio - Hotkey and LED support on HP laptops with Realtek codecs - Dock station support on HP laptops - Toshiba Satellite S50D fixup - Enhanced wallclock timestamp handling for HD-audio - Componentization to simplify the linkage between i915 and hd-audio drivers for Intel HDMI/DP USB-audio - Akai MPC Element support - Enhanced timestamp handling ASoC - Lots of refactoringin ASoC core, moving drivers to more data driven initialization and rationalizing a lot of DAPM usage - Much improved handling of CDCLK clocks on Samsung I2S controllers - Lots of driver specific cleanups and feature improvements - CODEC support for TI PCM514x and TLV320AIC3104 devices - Board support for Tegra systems with Realtek RT5677 - New driver for Maxim max98357a - More enhancements / fixes for Intel SST driver Others - Promotion of LINE6 driver from staging along with lots of rewrites and cleanups - DT support for old non-ASoC atmel driver - oxygen cleanups, XIO2001 init, Studio Evolution SE6x support - Emu8000 DRAM size detection fix on ISA(!!) AWE64 boards - A few more ak411x fixes for ice1724 boards" * tag 'sound-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (542 commits) ALSA: line6: toneport: Use explicit type for firmware version ALSA: line6: Use explicit type for serial number ALSA: line6: Return EIO if read/write not successful ALSA: line6: Return error if device not responding ALSA: line6: Add delay before reading status ASoC: Intel: Clean data after SST fw fetch ALSA: hda - Add docking station support for another HP machine ALSA: control: fix failure to return new numerical ID in 'replace' event data ALSA: usb: update trigger timestamp on first non-zero URB submitted ALSA: hda: read trigger_timestamp immediately after starting DMA ALSA: pcm: allow for trigger_tstamp snapshot in .trigger ALSA: pcm: don't override timestamp unconditionally ALSA: off by one bug in snd_riptide_joystick_probe() ASoC: rt5670: Set use_single_rw flag for regmap ASoC: rt286: Add rt288 codec support ASoC: max98357a: Fix build in !CONFIG_OF case ASoC: Intel: fix platform_no_drv_owner.cocci warnings ARM: dts: Switch Odroid X2/U2 to simple-audio-card ARM: dts: Exynos4 and Odroid X2/U3 sound device nodes update ALSA: control: fix failure to return numerical ID in 'add' event ...
Diffstat (limited to 'sound/soc/intel')
-rw-r--r--sound/soc/intel/Kconfig15
-rw-r--r--sound/soc/intel/Makefile2
-rw-r--r--sound/soc/intel/broadwell.c10
-rw-r--r--sound/soc/intel/byt-rt5640.c12
-rw-r--r--sound/soc/intel/bytcr_dpcm_rt5640.c1
-rw-r--r--sound/soc/intel/cht_bsw_rt5645.c326
-rw-r--r--sound/soc/intel/cht_bsw_rt5672.c15
-rw-r--r--sound/soc/intel/sst-baytrail-pcm.c6
-rw-r--r--sound/soc/intel/sst-dsp.c3
-rw-r--r--sound/soc/intel/sst-firmware.c3
-rw-r--r--sound/soc/intel/sst-haswell-dsp.c17
-rw-r--r--sound/soc/intel/sst-haswell-ipc.c177
-rw-r--r--sound/soc/intel/sst-haswell-ipc.h36
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c232
-rw-r--r--sound/soc/intel/sst-mfld-platform-pcm.c7
-rw-r--r--sound/soc/intel/sst/sst.h3
-rw-r--r--sound/soc/intel/sst/sst_acpi.c9
-rw-r--r--sound/soc/intel/sst/sst_loader.c3
18 files changed, 570 insertions, 307 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index f86de1211b96..ee03dbdda235 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -46,7 +46,7 @@ config SND_SOC_INTEL_BAYTRAIL
46 46
47config SND_SOC_INTEL_HASWELL_MACH 47config SND_SOC_INTEL_HASWELL_MACH
48 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" 48 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
49 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \\ 49 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \
50 I2C_DESIGNWARE_PLATFORM 50 I2C_DESIGNWARE_PLATFORM
51 select SND_SOC_INTEL_HASWELL 51 select SND_SOC_INTEL_HASWELL
52 select SND_SOC_RT5640 52 select SND_SOC_RT5640
@@ -76,7 +76,7 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH
76 76
77config SND_SOC_INTEL_BROADWELL_MACH 77config SND_SOC_INTEL_BROADWELL_MACH
78 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" 78 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
79 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \\ 79 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \
80 I2C_DESIGNWARE_PLATFORM 80 I2C_DESIGNWARE_PLATFORM
81 select SND_SOC_INTEL_HASWELL 81 select SND_SOC_INTEL_HASWELL
82 select SND_COMPRESS_OFFLOAD 82 select SND_COMPRESS_OFFLOAD
@@ -110,3 +110,14 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
110 platforms with RT5672 audio codec. 110 platforms with RT5672 audio codec.
111 Say Y if you have such a device 111 Say Y if you have such a device
112 If unsure select "N". 112 If unsure select "N".
113
114config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
115 tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645 codec"
116 depends on X86_INTEL_LPSS
117 select SND_SOC_RT5645
118 select SND_SST_MFLD_PLATFORM
119 select SND_SST_IPC_ACPI
120 help
121 This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
122 platforms with RT5645 audio codec.
123 If unsure select "N".
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index e928ec385300..a8e53c45c6b6 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -28,6 +28,7 @@ snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
28snd-soc-sst-broadwell-objs := broadwell.o 28snd-soc-sst-broadwell-objs := broadwell.o
29snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o 29snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o
30snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 30snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
31snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
31 32
32obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 33obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
33obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 34obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
@@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
35obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o 36obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
36obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o 37obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o
37obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 38obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
39obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
38 40
39# DSP driver 41# DSP driver
40obj-$(CONFIG_SND_SST_IPC) += sst/ 42obj-$(CONFIG_SND_SST_IPC) += sst/
diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/broadwell.c
index 7cf95d5d5d80..9cf7d01479ad 100644
--- a/sound/soc/intel/broadwell.c
+++ b/sound/soc/intel/broadwell.c
@@ -140,8 +140,6 @@ static struct snd_soc_ops broadwell_rt286_ops = {
140 140
141static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) 141static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
142{ 142{
143 struct snd_soc_codec *codec = rtd->codec;
144 struct snd_soc_dapm_context *dapm = &codec->dapm;
145 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); 143 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
146 struct sst_hsw *broadwell = pdata->dsp; 144 struct sst_hsw *broadwell = pdata->dsp;
147 int ret; 145 int ret;
@@ -155,14 +153,6 @@ static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
155 return ret; 153 return ret;
156 } 154 }
157 155
158 /* always connected - check HP for jack detect */
159 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
160 snd_soc_dapm_enable_pin(dapm, "Speaker");
161 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
162 snd_soc_dapm_enable_pin(dapm, "Line Jack");
163 snd_soc_dapm_enable_pin(dapm, "DMIC1");
164 snd_soc_dapm_enable_pin(dapm, "DMIC2");
165
166 return 0; 156 return 0;
167} 157}
168 158
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c
index 0cba7830c5e9..354eaad886e1 100644
--- a/sound/soc/intel/byt-rt5640.c
+++ b/sound/soc/intel/byt-rt5640.c
@@ -132,7 +132,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
132{ 132{
133 int ret; 133 int ret;
134 struct snd_soc_codec *codec = runtime->codec; 134 struct snd_soc_codec *codec = runtime->codec;
135 struct snd_soc_dapm_context *dapm = &codec->dapm;
136 struct snd_soc_card *card = runtime->card; 135 struct snd_soc_card *card = runtime->card;
137 const struct snd_soc_dapm_route *custom_map; 136 const struct snd_soc_dapm_route *custom_map;
138 int num_routes; 137 int num_routes;
@@ -161,7 +160,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
161 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map); 160 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
162 } 161 }
163 162
164 ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes); 163 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
165 if (ret) 164 if (ret)
166 return ret; 165 return ret;
167 166
@@ -171,13 +170,8 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
171 return ret; 170 return ret;
172 } 171 }
173 172
174 snd_soc_dapm_ignore_suspend(dapm, "HPOL"); 173 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
175 snd_soc_dapm_ignore_suspend(dapm, "HPOR"); 174 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
176
177 snd_soc_dapm_ignore_suspend(dapm, "SPOLP");
178 snd_soc_dapm_ignore_suspend(dapm, "SPOLN");
179 snd_soc_dapm_ignore_suspend(dapm, "SPORP");
180 snd_soc_dapm_ignore_suspend(dapm, "SPORN");
181 175
182 return ret; 176 return ret;
183} 177}
diff --git a/sound/soc/intel/bytcr_dpcm_rt5640.c b/sound/soc/intel/bytcr_dpcm_rt5640.c
index eef0c56ec32e..59308629043e 100644
--- a/sound/soc/intel/bytcr_dpcm_rt5640.c
+++ b/sound/soc/intel/bytcr_dpcm_rt5640.c
@@ -215,7 +215,6 @@ static int snd_byt_mc_probe(struct platform_device *pdev)
215 215
216static struct platform_driver snd_byt_mc_driver = { 216static struct platform_driver snd_byt_mc_driver = {
217 .driver = { 217 .driver = {
218 .owner = THIS_MODULE,
219 .name = "bytt100_rt5640", 218 .name = "bytt100_rt5640",
220 .pm = &snd_soc_pm_ops, 219 .pm = &snd_soc_pm_ops,
221 }, 220 },
diff --git a/sound/soc/intel/cht_bsw_rt5645.c b/sound/soc/intel/cht_bsw_rt5645.c
new file mode 100644
index 000000000000..bd29617a9ab9
--- /dev/null
+++ b/sound/soc/intel/cht_bsw_rt5645.c
@@ -0,0 +1,326 @@
1/*
2 * cht-bsw-rt5645.c - ASoc Machine driver for Intel Cherryview-based platforms
3 * Cherrytrail and Braswell, with RT5645 codec.
4 *
5 * Copyright (C) 2015 Intel Corp
6 * Author: Fang, Yang A <yang.a.fang@intel.com>
7 * N,Harshapriya <harshapriya.n@intel.com>
8 * This file is modified from cht_bsw_rt5672.c
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 */
22
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/jack.h>
30#include "../codecs/rt5645.h"
31#include "sst-atom-controls.h"
32
33#define CHT_PLAT_CLK_3_HZ 19200000
34#define CHT_CODEC_DAI "rt5645-aif1"
35
36struct cht_mc_private {
37 struct snd_soc_jack hp_jack;
38 struct snd_soc_jack mic_jack;
39};
40
41static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
42{
43 int i;
44
45 for (i = 0; i < card->num_rtd; i++) {
46 struct snd_soc_pcm_runtime *rtd;
47
48 rtd = card->rtd + i;
49 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
50 strlen(CHT_CODEC_DAI)))
51 return rtd->codec_dai;
52 }
53 return NULL;
54}
55
56static int platform_clock_control(struct snd_soc_dapm_widget *w,
57 struct snd_kcontrol *k, int event)
58{
59 struct snd_soc_dapm_context *dapm = w->dapm;
60 struct snd_soc_card *card = dapm->card;
61 struct snd_soc_dai *codec_dai;
62 int ret;
63
64 codec_dai = cht_get_codec_dai(card);
65 if (!codec_dai) {
66 dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
67 return -EIO;
68 }
69
70 if (!SND_SOC_DAPM_EVENT_OFF(event))
71 return 0;
72
73 /* Set codec sysclk source to its internal clock because codec PLL will
74 * be off when idle and MCLK will also be off by ACPI when codec is
75 * runtime suspended. Codec needs clock for jack detection and button
76 * press.
77 */
78 ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK,
79 0, SND_SOC_CLOCK_IN);
80 if (ret < 0) {
81 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
82 return ret;
83 }
84
85 return 0;
86}
87
88static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
89 SND_SOC_DAPM_HP("Headphone", NULL),
90 SND_SOC_DAPM_MIC("Headset Mic", NULL),
91 SND_SOC_DAPM_MIC("Int Mic", NULL),
92 SND_SOC_DAPM_SPK("Ext Spk", NULL),
93 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
94 platform_clock_control, SND_SOC_DAPM_POST_PMD),
95};
96
97static const struct snd_soc_dapm_route cht_audio_map[] = {
98 {"IN1P", NULL, "Headset Mic"},
99 {"IN1N", NULL, "Headset Mic"},
100 {"DMIC L1", NULL, "Int Mic"},
101 {"DMIC R1", NULL, "Int Mic"},
102 {"Headphone", NULL, "HPOL"},
103 {"Headphone", NULL, "HPOR"},
104 {"Ext Spk", NULL, "SPOL"},
105 {"Ext Spk", NULL, "SPOR"},
106 {"AIF1 Playback", NULL, "ssp2 Tx"},
107 {"ssp2 Tx", NULL, "codec_out0"},
108 {"ssp2 Tx", NULL, "codec_out1"},
109 {"codec_in0", NULL, "ssp2 Rx" },
110 {"codec_in1", NULL, "ssp2 Rx" },
111 {"ssp2 Rx", NULL, "AIF1 Capture"},
112 {"Headphone", NULL, "Platform Clock"},
113 {"Headset Mic", NULL, "Platform Clock"},
114 {"Int Mic", NULL, "Platform Clock"},
115 {"Ext Spk", NULL, "Platform Clock"},
116};
117
118static const struct snd_kcontrol_new cht_mc_controls[] = {
119 SOC_DAPM_PIN_SWITCH("Headphone"),
120 SOC_DAPM_PIN_SWITCH("Headset Mic"),
121 SOC_DAPM_PIN_SWITCH("Int Mic"),
122 SOC_DAPM_PIN_SWITCH("Ext Spk"),
123};
124
125static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
126 struct snd_pcm_hw_params *params)
127{
128 struct snd_soc_pcm_runtime *rtd = substream->private_data;
129 struct snd_soc_dai *codec_dai = rtd->codec_dai;
130 int ret;
131
132 /* set codec PLL source to the 19.2MHz platform clock (MCLK) */
133 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK,
134 CHT_PLAT_CLK_3_HZ, params_rate(params) * 512);
135 if (ret < 0) {
136 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
137 return ret;
138 }
139
140 ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_PLL1,
141 params_rate(params) * 512, SND_SOC_CLOCK_IN);
142 if (ret < 0) {
143 dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret);
144 return ret;
145 }
146
147 return 0;
148}
149
150static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
151{
152 int ret;
153 struct snd_soc_codec *codec = runtime->codec;
154 struct snd_soc_dai *codec_dai = runtime->codec_dai;
155 struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
156
157 /* Select clk_i2s1_asrc as ASRC clock source */
158 rt5645_sel_asrc_clk_src(codec,
159 RT5645_DA_STEREO_FILTER |
160 RT5645_DA_MONO_L_FILTER |
161 RT5645_DA_MONO_R_FILTER |
162 RT5645_AD_STEREO_FILTER,
163 RT5645_CLK_SEL_I2S1_ASRC);
164
165 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
166 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
167 if (ret < 0) {
168 dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret);
169 return ret;
170 }
171
172 ret = snd_soc_jack_new(codec, "Headphone Jack",
173 SND_JACK_HEADPHONE,
174 &ctx->hp_jack);
175 if (ret) {
176 dev_err(runtime->dev, "HP jack creation failed %d\n", ret);
177 return ret;
178 }
179
180 ret = snd_soc_jack_new(codec, "Mic Jack",
181 SND_JACK_MICROPHONE,
182 &ctx->mic_jack);
183 if (ret) {
184 dev_err(runtime->dev, "Mic jack creation failed %d\n", ret);
185 return ret;
186 }
187
188 rt5645_set_jack_detect(codec, &ctx->hp_jack, &ctx->mic_jack);
189
190 return ret;
191}
192
193static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
194 struct snd_pcm_hw_params *params)
195{
196 struct snd_interval *rate = hw_param_interval(params,
197 SNDRV_PCM_HW_PARAM_RATE);
198 struct snd_interval *channels = hw_param_interval(params,
199 SNDRV_PCM_HW_PARAM_CHANNELS);
200
201 /* The DSP will covert the FE rate to 48k, stereo, 24bits */
202 rate->min = rate->max = 48000;
203 channels->min = channels->max = 2;
204
205 /* set SSP2 to 24-bit */
206 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
207 SNDRV_PCM_HW_PARAM_FIRST_MASK],
208 SNDRV_PCM_FORMAT_S24_LE);
209 return 0;
210}
211
212static unsigned int rates_48000[] = {
213 48000,
214};
215
216static struct snd_pcm_hw_constraint_list constraints_48000 = {
217 .count = ARRAY_SIZE(rates_48000),
218 .list = rates_48000,
219};
220
221static int cht_aif1_startup(struct snd_pcm_substream *substream)
222{
223 return snd_pcm_hw_constraint_list(substream->runtime, 0,
224 SNDRV_PCM_HW_PARAM_RATE,
225 &constraints_48000);
226}
227
228static struct snd_soc_ops cht_aif1_ops = {
229 .startup = cht_aif1_startup,
230};
231
232static struct snd_soc_ops cht_be_ssp2_ops = {
233 .hw_params = cht_aif1_hw_params,
234};
235
236static struct snd_soc_dai_link cht_dailink[] = {
237 [MERR_DPCM_AUDIO] = {
238 .name = "Audio Port",
239 .stream_name = "Audio",
240 .cpu_dai_name = "media-cpu-dai",
241 .codec_dai_name = "snd-soc-dummy-dai",
242 .codec_name = "snd-soc-dummy",
243 .platform_name = "sst-mfld-platform",
244 .ignore_suspend = 1,
245 .dynamic = 1,
246 .dpcm_playback = 1,
247 .dpcm_capture = 1,
248 .ops = &cht_aif1_ops,
249 },
250 [MERR_DPCM_COMPR] = {
251 .name = "Compressed Port",
252 .stream_name = "Compress",
253 .cpu_dai_name = "compress-cpu-dai",
254 .codec_dai_name = "snd-soc-dummy-dai",
255 .codec_name = "snd-soc-dummy",
256 .platform_name = "sst-mfld-platform",
257 },
258 /* CODEC<->CODEC link */
259 /* back ends */
260 {
261 .name = "SSP2-Codec",
262 .be_id = 1,
263 .cpu_dai_name = "ssp2-port",
264 .platform_name = "sst-mfld-platform",
265 .no_pcm = 1,
266 .codec_dai_name = "rt5645-aif1",
267 .codec_name = "i2c-10EC5645:00",
268 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
269 | SND_SOC_DAIFMT_CBS_CFS,
270 .init = cht_codec_init,
271 .be_hw_params_fixup = cht_codec_fixup,
272 .ignore_suspend = 1,
273 .dpcm_playback = 1,
274 .dpcm_capture = 1,
275 .ops = &cht_be_ssp2_ops,
276 },
277};
278
279/* SoC card */
280static struct snd_soc_card snd_soc_card_cht = {
281 .name = "chtrt5645",
282 .dai_link = cht_dailink,
283 .num_links = ARRAY_SIZE(cht_dailink),
284 .dapm_widgets = cht_dapm_widgets,
285 .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
286 .dapm_routes = cht_audio_map,
287 .num_dapm_routes = ARRAY_SIZE(cht_audio_map),
288 .controls = cht_mc_controls,
289 .num_controls = ARRAY_SIZE(cht_mc_controls),
290};
291
292static int snd_cht_mc_probe(struct platform_device *pdev)
293{
294 int ret_val = 0;
295 struct cht_mc_private *drv;
296
297 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
298 if (!drv)
299 return -ENOMEM;
300
301 snd_soc_card_cht.dev = &pdev->dev;
302 snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
303 ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
304 if (ret_val) {
305 dev_err(&pdev->dev,
306 "snd_soc_register_card failed %d\n", ret_val);
307 return ret_val;
308 }
309 platform_set_drvdata(pdev, &snd_soc_card_cht);
310 return ret_val;
311}
312
313static struct platform_driver snd_cht_mc_driver = {
314 .driver = {
315 .name = "cht-bsw-rt5645",
316 .pm = &snd_soc_pm_ops,
317 },
318 .probe = snd_cht_mc_probe,
319};
320
321module_platform_driver(snd_cht_mc_driver)
322
323MODULE_DESCRIPTION("ASoC Intel(R) Braswell Machine driver");
324MODULE_AUTHOR("Fang, Yang A,N,Harshapriya");
325MODULE_LICENSE("GPL v2");
326MODULE_ALIAS("platform:cht-bsw-rt5645");
diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/cht_bsw_rt5672.c
index 9b8b561171b7..ff016621583a 100644
--- a/sound/soc/intel/cht_bsw_rt5672.c
+++ b/sound/soc/intel/cht_bsw_rt5672.c
@@ -140,6 +140,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
140{ 140{
141 int ret; 141 int ret;
142 struct snd_soc_dai *codec_dai = runtime->codec_dai; 142 struct snd_soc_dai *codec_dai = runtime->codec_dai;
143 struct snd_soc_codec *codec = codec_dai->codec;
143 144
144 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ 145 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
145 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); 146 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
@@ -148,6 +149,19 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
148 return ret; 149 return ret;
149 } 150 }
150 151
152 /* Select codec ASRC clock source to track I2S1 clock, because codec
153 * is in slave mode and 100fs I2S format (BCLK = 100 * LRCLK) cannot
154 * be supported by RT5672. Otherwise, ASRC will be disabled and cause
155 * noise.
156 */
157 rt5670_sel_asrc_clk_src(codec,
158 RT5670_DA_STEREO_FILTER
159 | RT5670_DA_MONO_L_FILTER
160 | RT5670_DA_MONO_R_FILTER
161 | RT5670_AD_STEREO_FILTER
162 | RT5670_AD_MONO_L_FILTER
163 | RT5670_AD_MONO_R_FILTER,
164 RT5670_CLK_SEL_I2S1_ASRC);
151 return 0; 165 return 0;
152} 166}
153 167
@@ -270,7 +284,6 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
270 284
271static struct platform_driver snd_cht_mc_driver = { 285static struct platform_driver snd_cht_mc_driver = {
272 .driver = { 286 .driver = {
273 .owner = THIS_MODULE,
274 .name = "cht-bsw-rt5672", 287 .name = "cht-bsw-rt5672",
275 .pm = &snd_soc_pm_ops, 288 .pm = &snd_soc_pm_ops,
276 }, 289 },
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c
index 3bb6288d8b4d..224c49c9f135 100644
--- a/sound/soc/intel/sst-baytrail-pcm.c
+++ b/sound/soc/intel/sst-baytrail-pcm.c
@@ -320,11 +320,6 @@ static struct snd_pcm_ops sst_byt_pcm_ops = {
320 .mmap = sst_byt_pcm_mmap, 320 .mmap = sst_byt_pcm_mmap,
321}; 321};
322 322
323static void sst_byt_pcm_free(struct snd_pcm *pcm)
324{
325 snd_pcm_lib_preallocate_free_for_all(pcm);
326}
327
328static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd) 323static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
329{ 324{
330 struct snd_pcm *pcm = rtd->pcm; 325 struct snd_pcm *pcm = rtd->pcm;
@@ -403,7 +398,6 @@ static struct snd_soc_platform_driver byt_soc_platform = {
403 .remove = sst_byt_pcm_remove, 398 .remove = sst_byt_pcm_remove,
404 .ops = &sst_byt_pcm_ops, 399 .ops = &sst_byt_pcm_ops,
405 .pcm_new = sst_byt_pcm_new, 400 .pcm_new = sst_byt_pcm_new,
406 .pcm_free = sst_byt_pcm_free,
407}; 401};
408 402
409static const struct snd_soc_component_driver byt_dai_component = { 403static const struct snd_soc_component_driver byt_dai_component = {
diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/sst-dsp.c
index 86e410845670..64e94212d2d2 100644
--- a/sound/soc/intel/sst-dsp.c
+++ b/sound/soc/intel/sst-dsp.c
@@ -410,8 +410,7 @@ void sst_dsp_free(struct sst_dsp *sst)
410 if (sst->ops->free) 410 if (sst->ops->free)
411 sst->ops->free(sst); 411 sst->ops->free(sst);
412 412
413 if (sst->dma) 413 sst_dma_free(sst->dma);
414 sst_dma_free(sst->dma);
415} 414}
416EXPORT_SYMBOL_GPL(sst_dsp_free); 415EXPORT_SYMBOL_GPL(sst_dsp_free);
417 416
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c
index b3f9489794a6..5f71ef607a57 100644
--- a/sound/soc/intel/sst-firmware.c
+++ b/sound/soc/intel/sst-firmware.c
@@ -497,6 +497,7 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw,
497 sst_module->sst_fw = sst_fw; 497 sst_module->sst_fw = sst_fw;
498 sst_module->scratch_size = template->scratch_size; 498 sst_module->scratch_size = template->scratch_size;
499 sst_module->persistent_size = template->persistent_size; 499 sst_module->persistent_size = template->persistent_size;
500 sst_module->entry = template->entry;
500 501
501 INIT_LIST_HEAD(&sst_module->block_list); 502 INIT_LIST_HEAD(&sst_module->block_list);
502 INIT_LIST_HEAD(&sst_module->runtime_list); 503 INIT_LIST_HEAD(&sst_module->runtime_list);
@@ -790,6 +791,7 @@ int sst_module_alloc_blocks(struct sst_module *module)
790 struct sst_block_allocator ba; 791 struct sst_block_allocator ba;
791 int ret; 792 int ret;
792 793
794 memset(&ba, 0, sizeof(ba));
793 ba.size = module->size; 795 ba.size = module->size;
794 ba.type = module->type; 796 ba.type = module->type;
795 ba.offset = module->offset; 797 ba.offset = module->offset;
@@ -863,6 +865,7 @@ int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime,
863 if (module->persistent_size == 0) 865 if (module->persistent_size == 0)
864 return 0; 866 return 0;
865 867
868 memset(&ba, 0, sizeof(ba));
866 ba.size = module->persistent_size; 869 ba.size = module->persistent_size;
867 ba.type = SST_MEM_DRAM; 870 ba.type = SST_MEM_DRAM;
868 871
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/sst-haswell-dsp.c
index 57039b00efc2..c42ffae5fe9f 100644
--- a/sound/soc/intel/sst-haswell-dsp.c
+++ b/sound/soc/intel/sst-haswell-dsp.c
@@ -306,7 +306,7 @@ static void hsw_reset(struct sst_dsp *sst)
306static int hsw_set_dsp_D0(struct sst_dsp *sst) 306static int hsw_set_dsp_D0(struct sst_dsp *sst)
307{ 307{
308 int tries = 10; 308 int tries = 10;
309 u32 reg; 309 u32 reg, fw_dump_bit;
310 310
311 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */ 311 /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
312 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2); 312 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
@@ -368,7 +368,9 @@ finish:
368 can't be accessed, please enable each block before accessing. */ 368 can't be accessed, please enable each block before accessing. */
369 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0); 369 reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
370 reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK; 370 reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK;
371 writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0); 371 /* for D0, always enable the block(DSRAM[0]) used for FW dump */
372 fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
373 writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
372 374
373 375
374 /* disable DMA finish function for SSP0 & SSP1 */ 376 /* disable DMA finish function for SSP0 & SSP1 */
@@ -491,6 +493,7 @@ static const struct sst_sram_shift sram_shift[] = {
491 {SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */ 493 {SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */
492 {SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */ 494 {SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */
493}; 495};
496
494static u32 hsw_block_get_bit(struct sst_mem_block *block) 497static u32 hsw_block_get_bit(struct sst_mem_block *block)
495{ 498{
496 u32 bit = 0, shift = 0, index; 499 u32 bit = 0, shift = 0, index;
@@ -587,7 +590,9 @@ static int hsw_block_disable(struct sst_mem_block *block)
587 590
588 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0); 591 val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
589 bit = hsw_block_get_bit(block); 592 bit = hsw_block_get_bit(block);
590 writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0); 593 /* don't disable DSRAM[0], keep it always enable for FW dump*/
594 if (bit != (1 << SST_VDRTCL0_DSRAMPGE_SHIFT))
595 writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0);
591 596
592 /* wait 18 DSP clock ticks */ 597 /* wait 18 DSP clock ticks */
593 udelay(10); 598 udelay(10);
@@ -612,7 +617,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
612 const struct sst_adsp_memregion *region; 617 const struct sst_adsp_memregion *region;
613 struct device *dev; 618 struct device *dev;
614 int ret = -ENODEV, i, j, region_count; 619 int ret = -ENODEV, i, j, region_count;
615 u32 offset, size; 620 u32 offset, size, fw_dump_bit;
616 621
617 dev = sst->dma_dev; 622 dev = sst->dma_dev;
618 623
@@ -669,9 +674,11 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
669 } 674 }
670 } 675 }
671 676
677 /* always enable the block(DSRAM[0]) used for FW dump */
678 fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
672 /* set default power gating control, enable power gating control for all blocks. that is, 679 /* set default power gating control, enable power gating control for all blocks. that is,
673 can't be accessed, please enable each block before accessing. */ 680 can't be accessed, please enable each block before accessing. */
674 writel(0xffffffff, sst->addr.pci_cfg + SST_VDRTCTL0); 681 writel(0xffffffff & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
675 682
676 return 0; 683 return 0;
677} 684}
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c
index 8156cc1accb7..394af5684c05 100644
--- a/sound/soc/intel/sst-haswell-ipc.c
+++ b/sound/soc/intel/sst-haswell-ipc.c
@@ -31,6 +31,7 @@
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
34#include <sound/asound.h>
34 35
35#include "sst-haswell-ipc.h" 36#include "sst-haswell-ipc.h"
36#include "sst-dsp.h" 37#include "sst-dsp.h"
@@ -94,6 +95,8 @@
94/* Mailbox */ 95/* Mailbox */
95#define IPC_MAX_MAILBOX_BYTES 256 96#define IPC_MAX_MAILBOX_BYTES 256
96 97
98#define INVALID_STREAM_HW_ID 0xffffffff
99
97/* Global Message - Types and Replies */ 100/* Global Message - Types and Replies */
98enum ipc_glb_type { 101enum ipc_glb_type {
99 IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */ 102 IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
@@ -240,6 +243,9 @@ struct sst_hsw_stream {
240 u32 (*notify_position)(struct sst_hsw_stream *stream, void *data); 243 u32 (*notify_position)(struct sst_hsw_stream *stream, void *data);
241 void *pdata; 244 void *pdata;
242 245
246 /* record the fw read position when playback */
247 snd_pcm_uframes_t old_position;
248 bool play_silence;
243 struct list_head node; 249 struct list_head node;
244}; 250};
245 251
@@ -275,7 +281,6 @@ struct sst_hsw {
275 /* FW config */ 281 /* FW config */
276 struct sst_hsw_ipc_fw_ready fw_ready; 282 struct sst_hsw_ipc_fw_ready fw_ready;
277 struct sst_hsw_ipc_fw_version version; 283 struct sst_hsw_ipc_fw_version version;
278 struct sst_module *scratch;
279 bool fw_done; 284 bool fw_done;
280 struct sst_fw *sst_fw; 285 struct sst_fw *sst_fw;
281 286
@@ -337,12 +342,6 @@ static inline u32 msg_get_stage_type(u32 msg)
337 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT; 342 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT;
338} 343}
339 344
340static inline u32 msg_set_stage_type(u32 msg, u32 type)
341{
342 return (msg & ~IPC_STG_TYPE_MASK) +
343 (type << IPC_STG_TYPE_SHIFT);
344}
345
346static inline u32 msg_get_stream_id(u32 msg) 345static inline u32 msg_get_stream_id(u32 msg)
347{ 346{
348 return (msg & IPC_STR_ID_MASK) >> IPC_STR_ID_SHIFT; 347 return (msg & IPC_STR_ID_MASK) >> IPC_STR_ID_SHIFT;
@@ -969,45 +968,6 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw,
969} 968}
970 969
971/* Mixer Controls */ 970/* Mixer Controls */
972int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
973 u32 stage_id, u32 channel)
974{
975 int ret;
976
977 ret = sst_hsw_stream_get_volume(hsw, stream, stage_id, channel,
978 &stream->mute_volume[channel]);
979 if (ret < 0)
980 return ret;
981
982 ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel, 0);
983 if (ret < 0) {
984 dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n",
985 stream->reply.stream_hw_id, channel);
986 return ret;
987 }
988
989 stream->mute[channel] = 1;
990 return 0;
991}
992
993int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
994 u32 stage_id, u32 channel)
995
996{
997 int ret;
998
999 stream->mute[channel] = 0;
1000 ret = sst_hsw_stream_set_volume(hsw, stream, stage_id, channel,
1001 stream->mute_volume[channel]);
1002 if (ret < 0) {
1003 dev_err(hsw->dev, "error: can't unmute stream %d channel %d\n",
1004 stream->reply.stream_hw_id, channel);
1005 return ret;
1006 }
1007
1008 return 0;
1009}
1010
1011int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream, 971int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
1012 u32 stage_id, u32 channel, u32 *volume) 972 u32 stage_id, u32 channel, u32 *volume)
1013{ 973{
@@ -1021,17 +981,6 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream
1021 return 0; 981 return 0;
1022} 982}
1023 983
1024int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw,
1025 struct sst_hsw_stream *stream, u64 curve_duration,
1026 enum sst_hsw_volume_curve curve)
1027{
1028 /* curve duration in steps of 100ns */
1029 stream->vol_req.curve_duration = curve_duration;
1030 stream->vol_req.curve_type = curve;
1031
1032 return 0;
1033}
1034
1035/* stream volume */ 984/* stream volume */
1036int sst_hsw_stream_set_volume(struct sst_hsw *hsw, 985int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
1037 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume) 986 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume)
@@ -1083,42 +1032,6 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
1083 return 0; 1032 return 0;
1084} 1033}
1085 1034
1086int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel)
1087{
1088 int ret;
1089
1090 ret = sst_hsw_mixer_get_volume(hsw, stage_id, channel,
1091 &hsw->mute_volume[channel]);
1092 if (ret < 0)
1093 return ret;
1094
1095 ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel, 0);
1096 if (ret < 0) {
1097 dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n",
1098 channel);
1099 return ret;
1100 }
1101
1102 hsw->mute[channel] = 1;
1103 return 0;
1104}
1105
1106int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel)
1107{
1108 int ret;
1109
1110 ret = sst_hsw_mixer_set_volume(hsw, stage_id, channel,
1111 hsw->mixer_info.volume_register_address[channel]);
1112 if (ret < 0) {
1113 dev_err(hsw->dev, "error: failed to unmute mixer channel %d\n",
1114 channel);
1115 return ret;
1116 }
1117
1118 hsw->mute[channel] = 0;
1119 return 0;
1120}
1121
1122int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 1035int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1123 u32 *volume) 1036 u32 *volume)
1124{ 1037{
@@ -1132,16 +1045,6 @@ int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1132 return 0; 1045 return 0;
1133} 1046}
1134 1047
1135int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw,
1136 u64 curve_duration, enum sst_hsw_volume_curve curve)
1137{
1138 /* curve duration in steps of 100ns */
1139 hsw->curve_duration = curve_duration;
1140 hsw->curve_type = curve;
1141
1142 return 0;
1143}
1144
1145/* global mixer volume */ 1048/* global mixer volume */
1146int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 1049int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1147 u32 volume) 1050 u32 volume)
@@ -1208,6 +1111,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
1208 return NULL; 1111 return NULL;
1209 1112
1210 spin_lock_irqsave(&sst->spinlock, flags); 1113 spin_lock_irqsave(&sst->spinlock, flags);
1114 stream->reply.stream_hw_id = INVALID_STREAM_HW_ID;
1211 list_add(&stream->node, &hsw->stream_list); 1115 list_add(&stream->node, &hsw->stream_list);
1212 stream->notify_position = notify_position; 1116 stream->notify_position = notify_position;
1213 stream->pdata = data; 1117 stream->pdata = data;
@@ -1447,50 +1351,32 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1447 return 0; 1351 return 0;
1448} 1352}
1449 1353
1450/* Stream Information - these calls could be inline but we want the IPC 1354snd_pcm_uframes_t sst_hsw_stream_get_old_position(struct sst_hsw *hsw,
1451 ABI to be opaque to client PCM drivers to cope with any future ABI changes */
1452int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw,
1453 struct sst_hsw_stream *stream) 1355 struct sst_hsw_stream *stream)
1454{ 1356{
1455 return stream->reply.stream_hw_id; 1357 return stream->old_position;
1456} 1358}
1457 1359
1458int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw, 1360void sst_hsw_stream_set_old_position(struct sst_hsw *hsw,
1459 struct sst_hsw_stream *stream) 1361 struct sst_hsw_stream *stream, snd_pcm_uframes_t val)
1460{ 1362{
1461 return stream->reply.mixer_hw_id; 1363 stream->old_position = val;
1462} 1364}
1463 1365
1464u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw, 1366bool sst_hsw_stream_get_silence_start(struct sst_hsw *hsw,
1465 struct sst_hsw_stream *stream) 1367 struct sst_hsw_stream *stream)
1466{ 1368{
1467 return stream->reply.read_position_register_address; 1369 return stream->play_silence;
1468}
1469
1470u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw,
1471 struct sst_hsw_stream *stream)
1472{
1473 return stream->reply.presentation_position_register_address;
1474}
1475
1476u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw,
1477 struct sst_hsw_stream *stream, u32 channel)
1478{
1479 if (channel >= 2)
1480 return 0;
1481
1482 return stream->reply.peak_meter_register_address[channel];
1483} 1370}
1484 1371
1485u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw, 1372void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw,
1486 struct sst_hsw_stream *stream, u32 channel) 1373 struct sst_hsw_stream *stream, bool val)
1487{ 1374{
1488 if (channel >= 2) 1375 stream->play_silence = val;
1489 return 0;
1490
1491 return stream->reply.volume_register_address[channel];
1492} 1376}
1493 1377
1378/* Stream Information - these calls could be inline but we want the IPC
1379 ABI to be opaque to client PCM drivers to cope with any future ABI changes */
1494int sst_hsw_mixer_get_info(struct sst_hsw *hsw) 1380int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
1495{ 1381{
1496 struct sst_hsw_ipc_stream_info_reply *reply; 1382 struct sst_hsw_ipc_stream_info_reply *reply;
@@ -1628,30 +1514,6 @@ u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
1628 return ppos; 1514 return ppos;
1629} 1515}
1630 1516
1631int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
1632 struct sst_hsw_stream *stream, u32 stage_id, u32 position)
1633{
1634 u32 header;
1635 int ret;
1636
1637 trace_stream_write_position(stream->reply.stream_hw_id, position);
1638
1639 header = IPC_GLB_TYPE(IPC_GLB_STREAM_MESSAGE) |
1640 IPC_STR_TYPE(IPC_STR_STAGE_MESSAGE);
1641 header |= (stream->reply.stream_hw_id << IPC_STR_ID_SHIFT);
1642 header |= (IPC_STG_SET_WRITE_POSITION << IPC_STG_TYPE_SHIFT);
1643 header |= (stage_id << IPC_STG_ID_SHIFT);
1644 stream->wpos.position = position;
1645
1646 ret = ipc_tx_message_nowait(hsw, header, &stream->wpos,
1647 sizeof(stream->wpos));
1648 if (ret < 0)
1649 dev_err(hsw->dev, "error: stream %d set position %d failed\n",
1650 stream->reply.stream_hw_id, position);
1651
1652 return ret;
1653}
1654
1655/* physical BE config */ 1517/* physical BE config */
1656int sst_hsw_device_set_config(struct sst_hsw *hsw, 1518int sst_hsw_device_set_config(struct sst_hsw *hsw,
1657 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk, 1519 enum sst_hsw_device_id dev, enum sst_hsw_device_mclk mclk,
@@ -2132,7 +1994,6 @@ void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata)
2132 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, 1994 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
2133 hsw->dx_context, hsw->dx_context_paddr); 1995 hsw->dx_context, hsw->dx_context_paddr);
2134 sst_dsp_free(hsw->dsp); 1996 sst_dsp_free(hsw->dsp);
2135 kfree(hsw->scratch);
2136 kthread_stop(hsw->tx_thread); 1997 kthread_stop(hsw->tx_thread);
2137 kfree(hsw->msg); 1998 kfree(hsw->msg);
2138} 1999}
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/sst-haswell-ipc.h
index 138e894ab413..858096041cb1 100644
--- a/sound/soc/intel/sst-haswell-ipc.h
+++ b/sound/soc/intel/sst-haswell-ipc.h
@@ -20,6 +20,7 @@
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <sound/asound.h>
23 24
24#define SST_HSW_NO_CHANNELS 4 25#define SST_HSW_NO_CHANNELS 4
25#define SST_HSW_MAX_DX_REGIONS 14 26#define SST_HSW_MAX_DX_REGIONS 14
@@ -376,32 +377,17 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw,
376u32 create_channel_map(enum sst_hsw_channel_config config); 377u32 create_channel_map(enum sst_hsw_channel_config config);
377 378
378/* Stream Mixer Controls - */ 379/* Stream Mixer Controls - */
379int sst_hsw_stream_mute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
380 u32 stage_id, u32 channel);
381int sst_hsw_stream_unmute(struct sst_hsw *hsw, struct sst_hsw_stream *stream,
382 u32 stage_id, u32 channel);
383
384int sst_hsw_stream_set_volume(struct sst_hsw *hsw, 380int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
385 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume); 381 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 volume);
386int sst_hsw_stream_get_volume(struct sst_hsw *hsw, 382int sst_hsw_stream_get_volume(struct sst_hsw *hsw,
387 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 *volume); 383 struct sst_hsw_stream *stream, u32 stage_id, u32 channel, u32 *volume);
388 384
389int sst_hsw_stream_set_volume_curve(struct sst_hsw *hsw,
390 struct sst_hsw_stream *stream, u64 curve_duration,
391 enum sst_hsw_volume_curve curve);
392
393/* Global Mixer Controls - */ 385/* Global Mixer Controls - */
394int sst_hsw_mixer_mute(struct sst_hsw *hsw, u32 stage_id, u32 channel);
395int sst_hsw_mixer_unmute(struct sst_hsw *hsw, u32 stage_id, u32 channel);
396
397int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 386int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
398 u32 volume); 387 u32 volume);
399int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel, 388int sst_hsw_mixer_get_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
400 u32 *volume); 389 u32 *volume);
401 390
402int sst_hsw_mixer_set_volume_curve(struct sst_hsw *hsw,
403 u64 curve_duration, enum sst_hsw_volume_curve curve);
404
405/* Stream API */ 391/* Stream API */
406struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id, 392struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
407 u32 (*get_write_position)(struct sst_hsw_stream *stream, void *data), 393 u32 (*get_write_position)(struct sst_hsw_stream *stream, void *data),
@@ -440,18 +426,14 @@ int sst_hsw_stream_set_pmemory_info(struct sst_hsw *hsw,
440 struct sst_hsw_stream *stream, u32 offset, u32 size); 426 struct sst_hsw_stream *stream, u32 offset, u32 size);
441int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw, 427int sst_hsw_stream_set_smemory_info(struct sst_hsw *hsw,
442 struct sst_hsw_stream *stream, u32 offset, u32 size); 428 struct sst_hsw_stream *stream, u32 offset, u32 size);
443int sst_hsw_stream_get_hw_id(struct sst_hsw *hsw, 429snd_pcm_uframes_t sst_hsw_stream_get_old_position(struct sst_hsw *hsw,
444 struct sst_hsw_stream *stream);
445int sst_hsw_stream_get_mixer_id(struct sst_hsw *hsw,
446 struct sst_hsw_stream *stream);
447u32 sst_hsw_stream_get_read_reg(struct sst_hsw *hsw,
448 struct sst_hsw_stream *stream); 430 struct sst_hsw_stream *stream);
449u32 sst_hsw_stream_get_pointer_reg(struct sst_hsw *hsw, 431void sst_hsw_stream_set_old_position(struct sst_hsw *hsw,
432 struct sst_hsw_stream *stream, snd_pcm_uframes_t val);
433bool sst_hsw_stream_get_silence_start(struct sst_hsw *hsw,
450 struct sst_hsw_stream *stream); 434 struct sst_hsw_stream *stream);
451u32 sst_hsw_stream_get_peak_reg(struct sst_hsw *hsw, 435void sst_hsw_stream_set_silence_start(struct sst_hsw *hsw,
452 struct sst_hsw_stream *stream, u32 channel); 436 struct sst_hsw_stream *stream, bool val);
453u32 sst_hsw_stream_get_vol_reg(struct sst_hsw *hsw,
454 struct sst_hsw_stream *stream, u32 channel);
455int sst_hsw_mixer_get_info(struct sst_hsw *hsw); 437int sst_hsw_mixer_get_info(struct sst_hsw *hsw);
456 438
457/* Stream ALSA trigger operations */ 439/* Stream ALSA trigger operations */
@@ -466,8 +448,6 @@ int sst_hsw_stream_get_read_pos(struct sst_hsw *hsw,
466 struct sst_hsw_stream *stream, u32 *position); 448 struct sst_hsw_stream *stream, u32 *position);
467int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw, 449int sst_hsw_stream_get_write_pos(struct sst_hsw *hsw,
468 struct sst_hsw_stream *stream, u32 *position); 450 struct sst_hsw_stream *stream, u32 *position);
469int sst_hsw_stream_set_write_position(struct sst_hsw *hsw,
470 struct sst_hsw_stream *stream, u32 stage_id, u32 position);
471u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw, 451u32 sst_hsw_get_dsp_position(struct sst_hsw *hsw,
472 struct sst_hsw_stream *stream); 452 struct sst_hsw_stream *stream);
473u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw, 453u64 sst_hsw_get_dsp_presentation_position(struct sst_hsw *hsw,
@@ -481,8 +461,6 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
481/* DX Config */ 461/* DX Config */
482int sst_hsw_dx_set_state(struct sst_hsw *hsw, 462int sst_hsw_dx_set_state(struct sst_hsw *hsw,
483 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx); 463 enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx);
484int sst_hsw_dx_get_state(struct sst_hsw *hsw, u32 item,
485 u32 *offset, u32 *size, u32 *source);
486 464
487/* init */ 465/* init */
488int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata); 466int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata);
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c
index 619525200705..d6fa9d5514e1 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/sst-haswell-pcm.c
@@ -36,6 +36,11 @@
36#define HSW_PCM_COUNT 6 36#define HSW_PCM_COUNT 6
37#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */ 37#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
38 38
39#define SST_OLD_POSITION(d, r, o) ((d) + \
40 frames_to_bytes(r, o))
41#define SST_SAMPLES(r, x) (bytes_to_samples(r, \
42 frames_to_bytes(r, (x))))
43
39/* simple volume table */ 44/* simple volume table */
40static const u32 volume_map[] = { 45static const u32 volume_map[] = {
41 HSW_VOLUME_MAX >> 30, 46 HSW_VOLUME_MAX >> 30,
@@ -78,7 +83,6 @@ static const u32 volume_map[] = {
78#define HSW_PCM_DAI_ID_OFFLOAD0 1 83#define HSW_PCM_DAI_ID_OFFLOAD0 1
79#define HSW_PCM_DAI_ID_OFFLOAD1 2 84#define HSW_PCM_DAI_ID_OFFLOAD1 2
80#define HSW_PCM_DAI_ID_LOOPBACK 3 85#define HSW_PCM_DAI_ID_LOOPBACK 3
81#define HSW_PCM_DAI_ID_CAPTURE 4
82 86
83 87
84static const struct snd_pcm_hardware hsw_pcm_hardware = { 88static const struct snd_pcm_hardware hsw_pcm_hardware = {
@@ -99,6 +103,7 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = {
99 103
100struct hsw_pcm_module_map { 104struct hsw_pcm_module_map {
101 int dai_id; 105 int dai_id;
106 int stream;
102 enum sst_hsw_module_id mod_id; 107 enum sst_hsw_module_id mod_id;
103}; 108};
104 109
@@ -119,8 +124,9 @@ struct hsw_pcm_data {
119}; 124};
120 125
121enum hsw_pm_state { 126enum hsw_pm_state {
122 HSW_PM_STATE_D3 = 0, 127 HSW_PM_STATE_D0 = 0,
123 HSW_PM_STATE_D0 = 1, 128 HSW_PM_STATE_RTD3 = 1,
129 HSW_PM_STATE_D3 = 2,
124}; 130};
125 131
126/* private data for the driver */ 132/* private data for the driver */
@@ -135,7 +141,17 @@ struct hsw_priv_data {
135 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; 141 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
136 142
137 /* DAI data */ 143 /* DAI data */
138 struct hsw_pcm_data pcm[HSW_PCM_COUNT]; 144 struct hsw_pcm_data pcm[HSW_PCM_COUNT][2];
145};
146
147
148/* static mappings between PCMs and modules - may be dynamic in future */
149static struct hsw_pcm_module_map mod_map[] = {
150 {HSW_PCM_DAI_ID_SYSTEM, 0, SST_HSW_MODULE_PCM_SYSTEM},
151 {HSW_PCM_DAI_ID_OFFLOAD0, 0, SST_HSW_MODULE_PCM},
152 {HSW_PCM_DAI_ID_OFFLOAD1, 0, SST_HSW_MODULE_PCM},
153 {HSW_PCM_DAI_ID_LOOPBACK, 1, SST_HSW_MODULE_PCM_REFERENCE},
154 {HSW_PCM_DAI_ID_SYSTEM, 1, SST_HSW_MODULE_PCM_CAPTURE},
139}; 155};
140 156
141static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data); 157static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data);
@@ -168,9 +184,14 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
168 (struct soc_mixer_control *)kcontrol->private_value; 184 (struct soc_mixer_control *)kcontrol->private_value;
169 struct hsw_priv_data *pdata = 185 struct hsw_priv_data *pdata =
170 snd_soc_platform_get_drvdata(platform); 186 snd_soc_platform_get_drvdata(platform);
171 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 187 struct hsw_pcm_data *pcm_data;
172 struct sst_hsw *hsw = pdata->hsw; 188 struct sst_hsw *hsw = pdata->hsw;
173 u32 volume; 189 u32 volume;
190 int dai, stream;
191
192 dai = mod_map[mc->reg].dai_id;
193 stream = mod_map[mc->reg].stream;
194 pcm_data = &pdata->pcm[dai][stream];
174 195
175 mutex_lock(&pcm_data->mutex); 196 mutex_lock(&pcm_data->mutex);
176 pm_runtime_get_sync(pdata->dev); 197 pm_runtime_get_sync(pdata->dev);
@@ -212,9 +233,14 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
212 (struct soc_mixer_control *)kcontrol->private_value; 233 (struct soc_mixer_control *)kcontrol->private_value;
213 struct hsw_priv_data *pdata = 234 struct hsw_priv_data *pdata =
214 snd_soc_platform_get_drvdata(platform); 235 snd_soc_platform_get_drvdata(platform);
215 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 236 struct hsw_pcm_data *pcm_data;
216 struct sst_hsw *hsw = pdata->hsw; 237 struct sst_hsw *hsw = pdata->hsw;
217 u32 volume; 238 u32 volume;
239 int dai, stream;
240
241 dai = mod_map[mc->reg].dai_id;
242 stream = mod_map[mc->reg].stream;
243 pcm_data = &pdata->pcm[dai][stream];
218 244
219 mutex_lock(&pcm_data->mutex); 245 mutex_lock(&pcm_data->mutex);
220 pm_runtime_get_sync(pdata->dev); 246 pm_runtime_get_sync(pdata->dev);
@@ -309,7 +335,7 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = {
309 ARRAY_SIZE(volume_map) - 1, 0, 335 ARRAY_SIZE(volume_map) - 1, 0,
310 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 336 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
311 /* Mic Capture volume */ 337 /* Mic Capture volume */
312 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 0, 0, 8, 338 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
313 ARRAY_SIZE(volume_map) - 1, 0, 339 ARRAY_SIZE(volume_map) - 1, 0,
314 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 340 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
315}; 341};
@@ -353,7 +379,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
353 struct snd_pcm_runtime *runtime = substream->runtime; 379 struct snd_pcm_runtime *runtime = substream->runtime;
354 struct hsw_priv_data *pdata = 380 struct hsw_priv_data *pdata =
355 snd_soc_platform_get_drvdata(rtd->platform); 381 snd_soc_platform_get_drvdata(rtd->platform);
356 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 382 struct hsw_pcm_data *pcm_data;
357 struct sst_hsw *hsw = pdata->hsw; 383 struct sst_hsw *hsw = pdata->hsw;
358 struct sst_module *module_data; 384 struct sst_module *module_data;
359 struct sst_dsp *dsp; 385 struct sst_dsp *dsp;
@@ -362,7 +388,10 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
362 enum sst_hsw_stream_path_id path_id; 388 enum sst_hsw_stream_path_id path_id;
363 u32 rate, bits, map, pages, module_id; 389 u32 rate, bits, map, pages, module_id;
364 u8 channels; 390 u8 channels;
365 int ret; 391 int ret, dai;
392
393 dai = mod_map[rtd->cpu_dai->id].dai_id;
394 pcm_data = &pdata->pcm[dai][substream->stream];
366 395
367 /* check if we are being called a subsequent time */ 396 /* check if we are being called a subsequent time */
368 if (pcm_data->allocated) { 397 if (pcm_data->allocated) {
@@ -552,20 +581,35 @@ static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
552 struct snd_soc_pcm_runtime *rtd = substream->private_data; 581 struct snd_soc_pcm_runtime *rtd = substream->private_data;
553 struct hsw_priv_data *pdata = 582 struct hsw_priv_data *pdata =
554 snd_soc_platform_get_drvdata(rtd->platform); 583 snd_soc_platform_get_drvdata(rtd->platform);
555 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 584 struct hsw_pcm_data *pcm_data;
585 struct sst_hsw_stream *sst_stream;
556 struct sst_hsw *hsw = pdata->hsw; 586 struct sst_hsw *hsw = pdata->hsw;
587 struct snd_pcm_runtime *runtime = substream->runtime;
588 snd_pcm_uframes_t pos;
589 int dai;
590
591 dai = mod_map[rtd->cpu_dai->id].dai_id;
592 pcm_data = &pdata->pcm[dai][substream->stream];
593 sst_stream = pcm_data->stream;
557 594
558 switch (cmd) { 595 switch (cmd) {
559 case SNDRV_PCM_TRIGGER_START: 596 case SNDRV_PCM_TRIGGER_START:
560 case SNDRV_PCM_TRIGGER_RESUME: 597 case SNDRV_PCM_TRIGGER_RESUME:
561 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 598 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
599 sst_hsw_stream_set_silence_start(hsw, sst_stream, false);
562 sst_hsw_stream_resume(hsw, pcm_data->stream, 0); 600 sst_hsw_stream_resume(hsw, pcm_data->stream, 0);
563 break; 601 break;
564 case SNDRV_PCM_TRIGGER_STOP: 602 case SNDRV_PCM_TRIGGER_STOP:
565 case SNDRV_PCM_TRIGGER_SUSPEND: 603 case SNDRV_PCM_TRIGGER_SUSPEND:
566 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 604 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
605 sst_hsw_stream_set_silence_start(hsw, sst_stream, false);
567 sst_hsw_stream_pause(hsw, pcm_data->stream, 0); 606 sst_hsw_stream_pause(hsw, pcm_data->stream, 0);
568 break; 607 break;
608 case SNDRV_PCM_TRIGGER_DRAIN:
609 pos = runtime->control->appl_ptr % runtime->buffer_size;
610 sst_hsw_stream_set_old_position(hsw, pcm_data->stream, pos);
611 sst_hsw_stream_set_silence_start(hsw, sst_stream, true);
612 break;
569 default: 613 default:
570 break; 614 break;
571 } 615 }
@@ -579,13 +623,62 @@ static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
579 struct snd_pcm_substream *substream = pcm_data->substream; 623 struct snd_pcm_substream *substream = pcm_data->substream;
580 struct snd_pcm_runtime *runtime = substream->runtime; 624 struct snd_pcm_runtime *runtime = substream->runtime;
581 struct snd_soc_pcm_runtime *rtd = substream->private_data; 625 struct snd_soc_pcm_runtime *rtd = substream->private_data;
626 struct hsw_priv_data *pdata =
627 snd_soc_platform_get_drvdata(rtd->platform);
628 struct sst_hsw *hsw = pdata->hsw;
582 u32 pos; 629 u32 pos;
630 snd_pcm_uframes_t position = bytes_to_frames(runtime,
631 sst_hsw_get_dsp_position(hsw, pcm_data->stream));
632 unsigned char *dma_area = runtime->dma_area;
633 snd_pcm_uframes_t dma_frames =
634 bytes_to_frames(runtime, runtime->dma_bytes);
635 snd_pcm_uframes_t old_position;
636 ssize_t samples;
583 637
584 pos = frames_to_bytes(runtime, 638 pos = frames_to_bytes(runtime,
585 (runtime->control->appl_ptr % runtime->buffer_size)); 639 (runtime->control->appl_ptr % runtime->buffer_size));
586 640
587 dev_vdbg(rtd->dev, "PCM: App pointer %d bytes\n", pos); 641 dev_vdbg(rtd->dev, "PCM: App pointer %d bytes\n", pos);
588 642
643 /* SST fw don't know where to stop dma
644 * So, SST driver need to clean the data which has been consumed
645 */
646 if (dma_area == NULL || dma_frames <= 0
647 || (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
648 || !sst_hsw_stream_get_silence_start(hsw, stream)) {
649 snd_pcm_period_elapsed(substream);
650 return pos;
651 }
652
653 old_position = sst_hsw_stream_get_old_position(hsw, stream);
654 if (position > old_position) {
655 if (position < dma_frames) {
656 samples = SST_SAMPLES(runtime, position - old_position);
657 snd_pcm_format_set_silence(runtime->format,
658 SST_OLD_POSITION(dma_area,
659 runtime, old_position),
660 samples);
661 } else
662 dev_err(rtd->dev, "PCM: position is wrong\n");
663 } else {
664 if (old_position < dma_frames) {
665 samples = SST_SAMPLES(runtime,
666 dma_frames - old_position);
667 snd_pcm_format_set_silence(runtime->format,
668 SST_OLD_POSITION(dma_area,
669 runtime, old_position),
670 samples);
671 } else
672 dev_err(rtd->dev, "PCM: dma_bytes is wrong\n");
673 if (position < dma_frames) {
674 samples = SST_SAMPLES(runtime, position);
675 snd_pcm_format_set_silence(runtime->format,
676 dma_area, samples);
677 } else
678 dev_err(rtd->dev, "PCM: position is wrong\n");
679 }
680 sst_hsw_stream_set_old_position(hsw, stream, position);
681
589 /* let alsa know we have play a period */ 682 /* let alsa know we have play a period */
590 snd_pcm_period_elapsed(substream); 683 snd_pcm_period_elapsed(substream);
591 return pos; 684 return pos;
@@ -597,11 +690,16 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
597 struct snd_pcm_runtime *runtime = substream->runtime; 690 struct snd_pcm_runtime *runtime = substream->runtime;
598 struct hsw_priv_data *pdata = 691 struct hsw_priv_data *pdata =
599 snd_soc_platform_get_drvdata(rtd->platform); 692 snd_soc_platform_get_drvdata(rtd->platform);
600 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 693 struct hsw_pcm_data *pcm_data;
601 struct sst_hsw *hsw = pdata->hsw; 694 struct sst_hsw *hsw = pdata->hsw;
602 snd_pcm_uframes_t offset; 695 snd_pcm_uframes_t offset;
603 uint64_t ppos; 696 uint64_t ppos;
604 u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); 697 u32 position;
698 int dai;
699
700 dai = mod_map[rtd->cpu_dai->id].dai_id;
701 pcm_data = &pdata->pcm[dai][substream->stream];
702 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
605 703
606 offset = bytes_to_frames(runtime, position); 704 offset = bytes_to_frames(runtime, position);
607 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); 705 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
@@ -618,8 +716,10 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
618 snd_soc_platform_get_drvdata(rtd->platform); 716 snd_soc_platform_get_drvdata(rtd->platform);
619 struct hsw_pcm_data *pcm_data; 717 struct hsw_pcm_data *pcm_data;
620 struct sst_hsw *hsw = pdata->hsw; 718 struct sst_hsw *hsw = pdata->hsw;
719 int dai;
621 720
622 pcm_data = &pdata->pcm[rtd->cpu_dai->id]; 721 dai = mod_map[rtd->cpu_dai->id].dai_id;
722 pcm_data = &pdata->pcm[dai][substream->stream];
623 723
624 mutex_lock(&pcm_data->mutex); 724 mutex_lock(&pcm_data->mutex);
625 pm_runtime_get_sync(pdata->dev); 725 pm_runtime_get_sync(pdata->dev);
@@ -648,9 +748,12 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream)
648 struct snd_soc_pcm_runtime *rtd = substream->private_data; 748 struct snd_soc_pcm_runtime *rtd = substream->private_data;
649 struct hsw_priv_data *pdata = 749 struct hsw_priv_data *pdata =
650 snd_soc_platform_get_drvdata(rtd->platform); 750 snd_soc_platform_get_drvdata(rtd->platform);
651 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 751 struct hsw_pcm_data *pcm_data;
652 struct sst_hsw *hsw = pdata->hsw; 752 struct sst_hsw *hsw = pdata->hsw;
653 int ret; 753 int ret, dai;
754
755 dai = mod_map[rtd->cpu_dai->id].dai_id;
756 pcm_data = &pdata->pcm[dai][substream->stream];
654 757
655 mutex_lock(&pcm_data->mutex); 758 mutex_lock(&pcm_data->mutex);
656 ret = sst_hsw_stream_reset(hsw, pcm_data->stream); 759 ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
@@ -685,15 +788,6 @@ static struct snd_pcm_ops hsw_pcm_ops = {
685 .page = snd_pcm_sgbuf_ops_page, 788 .page = snd_pcm_sgbuf_ops_page,
686}; 789};
687 790
688/* static mappings between PCMs and modules - may be dynamic in future */
689static struct hsw_pcm_module_map mod_map[] = {
690 {HSW_PCM_DAI_ID_SYSTEM, SST_HSW_MODULE_PCM_SYSTEM},
691 {HSW_PCM_DAI_ID_OFFLOAD0, SST_HSW_MODULE_PCM},
692 {HSW_PCM_DAI_ID_OFFLOAD1, SST_HSW_MODULE_PCM},
693 {HSW_PCM_DAI_ID_LOOPBACK, SST_HSW_MODULE_PCM_REFERENCE},
694 {HSW_PCM_DAI_ID_CAPTURE, SST_HSW_MODULE_PCM_CAPTURE},
695};
696
697static int hsw_pcm_create_modules(struct hsw_priv_data *pdata) 791static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
698{ 792{
699 struct sst_hsw *hsw = pdata->hsw; 793 struct sst_hsw *hsw = pdata->hsw;
@@ -701,7 +795,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
701 int i; 795 int i;
702 796
703 for (i = 0; i < ARRAY_SIZE(mod_map); i++) { 797 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
704 pcm_data = &pdata->pcm[i]; 798 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
705 799
706 /* create new runtime module, use same offset if recreated */ 800 /* create new runtime module, use same offset if recreated */
707 pcm_data->runtime = sst_hsw_runtime_module_create(hsw, 801 pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
@@ -716,7 +810,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
716 810
717err: 811err:
718 for (--i; i >= 0; i--) { 812 for (--i; i >= 0; i--) {
719 pcm_data = &pdata->pcm[i]; 813 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
720 sst_hsw_runtime_module_free(pcm_data->runtime); 814 sst_hsw_runtime_module_free(pcm_data->runtime);
721 } 815 }
722 816
@@ -729,17 +823,12 @@ static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
729 int i; 823 int i;
730 824
731 for (i = 0; i < ARRAY_SIZE(mod_map); i++) { 825 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
732 pcm_data = &pdata->pcm[i]; 826 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
733 827
734 sst_hsw_runtime_module_free(pcm_data->runtime); 828 sst_hsw_runtime_module_free(pcm_data->runtime);
735 } 829 }
736} 830}
737 831
738static void hsw_pcm_free(struct snd_pcm *pcm)
739{
740 snd_pcm_lib_preallocate_free_for_all(pcm);
741}
742
743static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) 832static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
744{ 833{
745 struct snd_pcm *pcm = rtd->pcm; 834 struct snd_pcm *pcm = rtd->pcm;
@@ -762,7 +851,10 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
762 return ret; 851 return ret;
763 } 852 }
764 } 853 }
765 priv_data->pcm[rtd->cpu_dai->id].hsw_pcm = pcm; 854 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
855 priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_PLAYBACK].hsw_pcm = pcm;
856 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
857 priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_CAPTURE].hsw_pcm = pcm;
766 858
767 return ret; 859 return ret;
768} 860}
@@ -871,10 +963,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
871 /* allocate DSP buffer page tables */ 963 /* allocate DSP buffer page tables */
872 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { 964 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
873 965
874 mutex_init(&priv_data->pcm[i].mutex);
875
876 /* playback */ 966 /* playback */
877 if (hsw_dais[i].playback.channels_min) { 967 if (hsw_dais[i].playback.channels_min) {
968 mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_PLAYBACK].mutex);
878 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, 969 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
879 PAGE_SIZE, &priv_data->dmab[i][0]); 970 PAGE_SIZE, &priv_data->dmab[i][0]);
880 if (ret < 0) 971 if (ret < 0)
@@ -883,6 +974,7 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
883 974
884 /* capture */ 975 /* capture */
885 if (hsw_dais[i].capture.channels_min) { 976 if (hsw_dais[i].capture.channels_min) {
977 mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_CAPTURE].mutex);
886 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, 978 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
887 PAGE_SIZE, &priv_data->dmab[i][1]); 979 PAGE_SIZE, &priv_data->dmab[i][1]);
888 if (ret < 0) 980 if (ret < 0)
@@ -936,7 +1028,6 @@ static struct snd_soc_platform_driver hsw_soc_platform = {
936 .remove = hsw_pcm_remove, 1028 .remove = hsw_pcm_remove,
937 .ops = &hsw_pcm_ops, 1029 .ops = &hsw_pcm_ops,
938 .pcm_new = hsw_pcm_new, 1030 .pcm_new = hsw_pcm_new,
939 .pcm_free = hsw_pcm_free,
940}; 1031};
941 1032
942static const struct snd_soc_component_driver hsw_dai_component = { 1033static const struct snd_soc_component_driver hsw_dai_component = {
@@ -1010,12 +1101,12 @@ static int hsw_pcm_runtime_suspend(struct device *dev)
1010 struct hsw_priv_data *pdata = dev_get_drvdata(dev); 1101 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1011 struct sst_hsw *hsw = pdata->hsw; 1102 struct sst_hsw *hsw = pdata->hsw;
1012 1103
1013 if (pdata->pm_state == HSW_PM_STATE_D3) 1104 if (pdata->pm_state >= HSW_PM_STATE_RTD3)
1014 return 0; 1105 return 0;
1015 1106
1016 sst_hsw_dsp_runtime_suspend(hsw); 1107 sst_hsw_dsp_runtime_suspend(hsw);
1017 sst_hsw_dsp_runtime_sleep(hsw); 1108 sst_hsw_dsp_runtime_sleep(hsw);
1018 pdata->pm_state = HSW_PM_STATE_D3; 1109 pdata->pm_state = HSW_PM_STATE_RTD3;
1019 1110
1020 return 0; 1111 return 0;
1021} 1112}
@@ -1026,7 +1117,7 @@ static int hsw_pcm_runtime_resume(struct device *dev)
1026 struct sst_hsw *hsw = pdata->hsw; 1117 struct sst_hsw *hsw = pdata->hsw;
1027 int ret; 1118 int ret;
1028 1119
1029 if (pdata->pm_state == HSW_PM_STATE_D0) 1120 if (pdata->pm_state != HSW_PM_STATE_RTD3)
1030 return 0; 1121 return 0;
1031 1122
1032 ret = sst_hsw_dsp_load(hsw); 1123 ret = sst_hsw_dsp_load(hsw);
@@ -1066,7 +1157,7 @@ static void hsw_pcm_complete(struct device *dev)
1066 struct hsw_pcm_data *pcm_data; 1157 struct hsw_pcm_data *pcm_data;
1067 int i, err; 1158 int i, err;
1068 1159
1069 if (pdata->pm_state == HSW_PM_STATE_D0) 1160 if (pdata->pm_state != HSW_PM_STATE_D3)
1070 return; 1161 return;
1071 1162
1072 err = sst_hsw_dsp_load(hsw); 1163 err = sst_hsw_dsp_load(hsw);
@@ -1081,8 +1172,8 @@ static void hsw_pcm_complete(struct device *dev)
1081 return; 1172 return;
1082 } 1173 }
1083 1174
1084 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { 1175 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
1085 pcm_data = &pdata->pcm[i]; 1176 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
1086 1177
1087 if (!pcm_data->substream) 1178 if (!pcm_data->substream)
1088 continue; 1179 continue;
@@ -1114,41 +1205,42 @@ static int hsw_pcm_prepare(struct device *dev)
1114 1205
1115 if (pdata->pm_state == HSW_PM_STATE_D3) 1206 if (pdata->pm_state == HSW_PM_STATE_D3)
1116 return 0; 1207 return 0;
1117 /* suspend all active streams */ 1208 else if (pdata->pm_state == HSW_PM_STATE_D0) {
1118 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) { 1209 /* suspend all active streams */
1119 pcm_data = &pdata->pcm[i]; 1210 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
1211 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
1212
1213 if (!pcm_data->substream)
1214 continue;
1215 dev_dbg(dev, "suspending pcm %d\n", i);
1216 snd_pcm_suspend_all(pcm_data->hsw_pcm);
1217
1218 /* We need to wait until the DSP FW stops the streams */
1219 msleep(2);
1220 }
1120 1221
1121 if (!pcm_data->substream) 1222 /* preserve persistent memory */
1122 continue; 1223 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
1123 dev_dbg(dev, "suspending pcm %d\n", i); 1224 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
1124 snd_pcm_suspend_all(pcm_data->hsw_pcm); 1225
1226 if (!pcm_data->substream)
1227 continue;
1125 1228
1126 /* We need to wait until the DSP FW stops the streams */ 1229 dev_dbg(dev, "saving context pcm %d\n", i);
1127 msleep(2); 1230 err = sst_module_runtime_save(pcm_data->runtime,
1231 &pcm_data->context);
1232 if (err < 0)
1233 dev_err(dev, "failed to save context for PCM %d\n", i);
1234 }
1235 /* enter D3 state and stall */
1236 sst_hsw_dsp_runtime_suspend(hsw);
1237 /* put the DSP to sleep */
1238 sst_hsw_dsp_runtime_sleep(hsw);
1128 } 1239 }
1129 1240
1130 snd_soc_suspend(pdata->soc_card->dev); 1241 snd_soc_suspend(pdata->soc_card->dev);
1131 snd_soc_poweroff(pdata->soc_card->dev); 1242 snd_soc_poweroff(pdata->soc_card->dev);
1132 1243
1133 /* enter D3 state and stall */
1134 sst_hsw_dsp_runtime_suspend(hsw);
1135
1136 /* preserve persistent memory */
1137 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
1138 pcm_data = &pdata->pcm[i];
1139
1140 if (!pcm_data->substream)
1141 continue;
1142
1143 dev_dbg(dev, "saving context pcm %d\n", i);
1144 err = sst_module_runtime_save(pcm_data->runtime,
1145 &pcm_data->context);
1146 if (err < 0)
1147 dev_err(dev, "failed to save context for PCM %d\n", i);
1148 }
1149
1150 /* put the DSP to sleep */
1151 sst_hsw_dsp_runtime_sleep(hsw);
1152 pdata->pm_state = HSW_PM_STATE_D3; 1244 pdata->pm_state = HSW_PM_STATE_D3;
1153 1245
1154 return 0; 1246 return 0;
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c
index a1a8d9d91539..7523cbef8780 100644
--- a/sound/soc/intel/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/sst-mfld-platform-pcm.c
@@ -643,12 +643,6 @@ static struct snd_pcm_ops sst_platform_ops = {
643 .pointer = sst_platform_pcm_pointer, 643 .pointer = sst_platform_pcm_pointer,
644}; 644};
645 645
646static void sst_pcm_free(struct snd_pcm *pcm)
647{
648 dev_dbg(pcm->dev, "sst_pcm_free called\n");
649 snd_pcm_lib_preallocate_free_for_all(pcm);
650}
651
652static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) 646static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
653{ 647{
654 struct snd_soc_dai *dai = rtd->cpu_dai; 648 struct snd_soc_dai *dai = rtd->cpu_dai;
@@ -679,7 +673,6 @@ static struct snd_soc_platform_driver sst_soc_platform_drv = {
679 .ops = &sst_platform_ops, 673 .ops = &sst_platform_ops,
680 .compr_ops = &sst_platform_compr_ops, 674 .compr_ops = &sst_platform_compr_ops,
681 .pcm_new = sst_pcm_new, 675 .pcm_new = sst_pcm_new,
682 .pcm_free = sst_pcm_free,
683}; 676};
684 677
685static const struct snd_soc_component_driver sst_component = { 678static const struct snd_soc_component_driver sst_component = {
diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h
index 7f4bbfcbc6f5..562bc483d6b7 100644
--- a/sound/soc/intel/sst/sst.h
+++ b/sound/soc/intel/sst/sst.h
@@ -58,6 +58,7 @@ enum sst_algo_ops {
58#define SST_BLOCK_TIMEOUT 1000 58#define SST_BLOCK_TIMEOUT 1000
59 59
60#define FW_SIGNATURE_SIZE 4 60#define FW_SIGNATURE_SIZE 4
61#define FW_NAME_SIZE 32
61 62
62/* stream states */ 63/* stream states */
63enum sst_stream_states { 64enum sst_stream_states {
@@ -426,7 +427,7 @@ struct intel_sst_drv {
426 * Holder for firmware name. Due to async call it needs to be 427 * Holder for firmware name. Due to async call it needs to be
427 * persistent till worker thread gets called 428 * persistent till worker thread gets called
428 */ 429 */
429 char firmware_name[20]; 430 char firmware_name[FW_NAME_SIZE];
430}; 431};
431 432
432/* misc definitions */ 433/* misc definitions */
diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c
index b3360139c41a..b782dfdcdbba 100644
--- a/sound/soc/intel/sst/sst_acpi.c
+++ b/sound/soc/intel/sst/sst_acpi.c
@@ -47,7 +47,7 @@ struct sst_machines {
47 char board[32]; 47 char board[32];
48 char machine[32]; 48 char machine[32];
49 void (*machine_quirk)(void); 49 void (*machine_quirk)(void);
50 char firmware[32]; 50 char firmware[FW_NAME_SIZE];
51 struct sst_platform_info *pdata; 51 struct sst_platform_info *pdata;
52 52
53}; 53};
@@ -245,7 +245,7 @@ static struct sst_machines *sst_acpi_find_machine(
245 return NULL; 245 return NULL;
246} 246}
247 247
248int sst_acpi_probe(struct platform_device *pdev) 248static int sst_acpi_probe(struct platform_device *pdev)
249{ 249{
250 struct device *dev = &pdev->dev; 250 struct device *dev = &pdev->dev;
251 int ret = 0; 251 int ret = 0;
@@ -332,7 +332,7 @@ do_sst_cleanup:
332* This function is called by OS when a device is unloaded 332* This function is called by OS when a device is unloaded
333* This frees the interrupt etc 333* This frees the interrupt etc
334*/ 334*/
335int sst_acpi_remove(struct platform_device *pdev) 335static int sst_acpi_remove(struct platform_device *pdev)
336{ 336{
337 struct intel_sst_drv *ctx; 337 struct intel_sst_drv *ctx;
338 338
@@ -352,6 +352,8 @@ static struct sst_machines sst_acpi_bytcr[] = {
352static struct sst_machines sst_acpi_chv[] = { 352static struct sst_machines sst_acpi_chv[] = {
353 {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "intel/fw_sst_22a8.bin", 353 {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "intel/fw_sst_22a8.bin",
354 &chv_platform_data }, 354 &chv_platform_data },
355 {"10EC5645", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin",
356 &chv_platform_data },
355 {}, 357 {},
356}; 358};
357 359
@@ -366,7 +368,6 @@ MODULE_DEVICE_TABLE(acpi, sst_acpi_ids);
366static struct platform_driver sst_acpi_driver = { 368static struct platform_driver sst_acpi_driver = {
367 .driver = { 369 .driver = {
368 .name = "intel_sst_acpi", 370 .name = "intel_sst_acpi",
369 .owner = THIS_MODULE,
370 .acpi_match_table = ACPI_PTR(sst_acpi_ids), 371 .acpi_match_table = ACPI_PTR(sst_acpi_ids),
371 .pm = &intel_sst_pm, 372 .pm = &intel_sst_pm,
372 }, 373 },
diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/sst/sst_loader.c
index b580f96e25e5..7888cd707853 100644
--- a/sound/soc/intel/sst/sst_loader.c
+++ b/sound/soc/intel/sst/sst_loader.c
@@ -324,8 +324,7 @@ void sst_firmware_load_cb(const struct firmware *fw, void *context)
324 324
325 if (ctx->sst_state != SST_RESET || 325 if (ctx->sst_state != SST_RESET ||
326 ctx->fw_in_mem != NULL) { 326 ctx->fw_in_mem != NULL) {
327 if (fw != NULL) 327 release_firmware(fw);
328 release_firmware(fw);
329 mutex_unlock(&ctx->sst_lock); 328 mutex_unlock(&ctx->sst_lock);
330 return; 329 return;
331 } 330 }