diff options
author | Vinod Koul <vinod.koul@linux.intel.com> | 2011-12-05 08:43:41 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-12-05 09:02:31 -0500 |
commit | 03c33042dbcd087303062c51f462c4575eb630d6 (patch) | |
tree | e7199d42c3ebb7272e53673c7a1adf8caf3c90a6 /sound/soc/mid-x86 | |
parent | f031efe9402e4ab6a6cd86bbda54b30ed9171237 (diff) |
ASoC: sst_platform: fix the dsp driver interface
lower level drivers typically register with upper layers.
So fix by exporting symbols from sst_platform driver for dsp driver to
register to sst platform driver
Now this driver doesnt depend on sst driver, so remove the dependency
and the header files
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/mid-x86')
-rw-r--r-- | sound/soc/mid-x86/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/mid-x86/sst_platform.c | 130 | ||||
-rw-r--r-- | sound/soc/mid-x86/sst_platform.h | 82 |
3 files changed, 158 insertions, 55 deletions
diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig index 29350428f1c2..61c10bf503d2 100644 --- a/sound/soc/mid-x86/Kconfig +++ b/sound/soc/mid-x86/Kconfig | |||
@@ -1,7 +1,6 @@ | |||
1 | config SND_MFLD_MACHINE | 1 | config SND_MFLD_MACHINE |
2 | tristate "SOC Machine Audio driver for Intel Medfield MID platform" | 2 | tristate "SOC Machine Audio driver for Intel Medfield MID platform" |
3 | depends on INTEL_SCU_IPC | 3 | depends on INTEL_SCU_IPC |
4 | depends on SND_INTEL_SST | ||
5 | select SND_SOC_SN95031 | 4 | select SND_SOC_SN95031 |
6 | select SND_SST_PLATFORM | 5 | select SND_SST_PLATFORM |
7 | help | 6 | help |
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 94f70b3f94e6..24f947146947 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c | |||
@@ -32,10 +32,51 @@ | |||
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
33 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
34 | #include <sound/soc.h> | 34 | #include <sound/soc.h> |
35 | #include "../../../drivers/staging/intel_sst/intel_sst_ioctl.h" | ||
36 | #include "../../../drivers/staging/intel_sst/intel_sst.h" | ||
37 | #include "sst_platform.h" | 35 | #include "sst_platform.h" |
38 | 36 | ||
37 | static struct sst_device *sst; | ||
38 | static DEFINE_MUTEX(sst_lock); | ||
39 | |||
40 | int sst_register_dsp(struct sst_device *dev) | ||
41 | { | ||
42 | BUG_ON(!dev); | ||
43 | if (!try_module_get(dev->dev->driver->owner)) | ||
44 | return -ENODEV; | ||
45 | mutex_lock(&sst_lock); | ||
46 | if (sst) { | ||
47 | pr_err("we already have a device %s\n", sst->name); | ||
48 | module_put(dev->dev->driver->owner); | ||
49 | mutex_unlock(&sst_lock); | ||
50 | return -EEXIST; | ||
51 | } | ||
52 | pr_debug("registering device %s\n", dev->name); | ||
53 | sst = dev; | ||
54 | mutex_unlock(&sst_lock); | ||
55 | return 0; | ||
56 | } | ||
57 | EXPORT_SYMBOL_GPL(sst_register_dsp); | ||
58 | |||
59 | int sst_unregister_dsp(struct sst_device *dev) | ||
60 | { | ||
61 | BUG_ON(!dev); | ||
62 | if (dev != sst) | ||
63 | return -EINVAL; | ||
64 | |||
65 | mutex_lock(&sst_lock); | ||
66 | |||
67 | if (!sst) { | ||
68 | mutex_unlock(&sst_lock); | ||
69 | return -EIO; | ||
70 | } | ||
71 | |||
72 | module_put(sst->dev->driver->owner); | ||
73 | pr_debug("unreg %s\n", sst->name); | ||
74 | sst = NULL; | ||
75 | mutex_unlock(&sst_lock); | ||
76 | return 0; | ||
77 | } | ||
78 | EXPORT_SYMBOL_GPL(sst_unregister_dsp); | ||
79 | |||
39 | static struct snd_pcm_hardware sst_platform_pcm_hw = { | 80 | static struct snd_pcm_hardware sst_platform_pcm_hw = { |
40 | .info = (SNDRV_PCM_INFO_INTERLEAVED | | 81 | .info = (SNDRV_PCM_INFO_INTERLEAVED | |
41 | SNDRV_PCM_INFO_DOUBLE | | 82 | SNDRV_PCM_INFO_DOUBLE | |
@@ -135,37 +176,34 @@ static inline int sst_get_stream_status(struct sst_runtime_stream *stream) | |||
135 | } | 176 | } |
136 | 177 | ||
137 | static void sst_fill_pcm_params(struct snd_pcm_substream *substream, | 178 | static void sst_fill_pcm_params(struct snd_pcm_substream *substream, |
138 | struct snd_sst_stream_params *param) | 179 | struct sst_pcm_params *param) |
139 | { | 180 | { |
140 | 181 | ||
141 | param->uc.pcm_params.codec = SST_CODEC_TYPE_PCM; | 182 | param->codec = SST_CODEC_TYPE_PCM; |
142 | param->uc.pcm_params.num_chan = (u8) substream->runtime->channels; | 183 | param->num_chan = (u8) substream->runtime->channels; |
143 | param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits; | 184 | param->pcm_wd_sz = substream->runtime->sample_bits; |
144 | param->uc.pcm_params.reserved = 0; | 185 | param->reserved = 0; |
145 | param->uc.pcm_params.sfreq = substream->runtime->rate; | 186 | param->sfreq = substream->runtime->rate; |
146 | param->uc.pcm_params.ring_buffer_size = | 187 | param->ring_buffer_size = snd_pcm_lib_buffer_bytes(substream); |
147 | snd_pcm_lib_buffer_bytes(substream); | 188 | param->period_count = substream->runtime->period_size; |
148 | param->uc.pcm_params.period_count = substream->runtime->period_size; | 189 | param->ring_buffer_addr = virt_to_phys(substream->dma_buffer.area); |
149 | param->uc.pcm_params.ring_buffer_addr = | 190 | pr_debug("period_cnt = %d\n", param->period_count); |
150 | virt_to_phys(substream->dma_buffer.area); | 191 | pr_debug("sfreq= %d, wd_sz = %d\n", param->sfreq, param->pcm_wd_sz); |
151 | pr_debug("period_cnt = %d\n", param->uc.pcm_params.period_count); | ||
152 | pr_debug("sfreq= %d, wd_sz = %d\n", | ||
153 | param->uc.pcm_params.sfreq, param->uc.pcm_params.pcm_wd_sz); | ||
154 | } | 192 | } |
155 | 193 | ||
156 | static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) | 194 | static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) |
157 | { | 195 | { |
158 | struct sst_runtime_stream *stream = | 196 | struct sst_runtime_stream *stream = |
159 | substream->runtime->private_data; | 197 | substream->runtime->private_data; |
160 | struct snd_sst_stream_params param = {{{0,},},}; | 198 | struct sst_pcm_params param = {0}; |
161 | struct snd_sst_params str_params = {0}; | 199 | struct sst_stream_params str_params = {0}; |
162 | int ret_val; | 200 | int ret_val; |
163 | 201 | ||
164 | /* set codec params and inform SST driver the same */ | 202 | /* set codec params and inform SST driver the same */ |
165 | sst_fill_pcm_params(substream, ¶m); | 203 | sst_fill_pcm_params(substream, ¶m); |
166 | substream->runtime->dma_area = substream->dma_buffer.area; | 204 | substream->runtime->dma_area = substream->dma_buffer.area; |
167 | str_params.sparams = param; | 205 | str_params.sparams = param; |
168 | str_params.codec = param.uc.pcm_params.codec; | 206 | str_params.codec = param.codec; |
169 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 207 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
170 | str_params.ops = STREAM_OPS_PLAYBACK; | 208 | str_params.ops = STREAM_OPS_PLAYBACK; |
171 | str_params.device_type = substream->pcm->device + 1; | 209 | str_params.device_type = substream->pcm->device + 1; |
@@ -177,7 +215,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) | |||
177 | pr_debug("Capture stream,Device %d\n", | 215 | pr_debug("Capture stream,Device %d\n", |
178 | substream->pcm->device); | 216 | substream->pcm->device); |
179 | } | 217 | } |
180 | ret_val = stream->sstdrv_ops->pcm_control->open(&str_params); | 218 | ret_val = stream->ops->open(&str_params); |
181 | pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val); | 219 | pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val); |
182 | if (ret_val < 0) | 220 | if (ret_val < 0) |
183 | return ret_val; | 221 | return ret_val; |
@@ -216,7 +254,7 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) | |||
216 | stream->stream_info.mad_substream = substream; | 254 | stream->stream_info.mad_substream = substream; |
217 | stream->stream_info.buffer_ptr = 0; | 255 | stream->stream_info.buffer_ptr = 0; |
218 | stream->stream_info.sfreq = substream->runtime->rate; | 256 | stream->stream_info.sfreq = substream->runtime->rate; |
219 | ret_val = stream->sstdrv_ops->pcm_control->device_control( | 257 | ret_val = stream->ops->device_control( |
220 | SST_SND_STREAM_INIT, &stream->stream_info); | 258 | SST_SND_STREAM_INIT, &stream->stream_info); |
221 | if (ret_val) | 259 | if (ret_val) |
222 | pr_err("control_set ret error %d\n", ret_val); | 260 | pr_err("control_set ret error %d\n", ret_val); |
@@ -229,7 +267,6 @@ static int sst_platform_open(struct snd_pcm_substream *substream) | |||
229 | { | 267 | { |
230 | struct snd_pcm_runtime *runtime = substream->runtime; | 268 | struct snd_pcm_runtime *runtime = substream->runtime; |
231 | struct sst_runtime_stream *stream; | 269 | struct sst_runtime_stream *stream; |
232 | int ret_val = 0; | ||
233 | 270 | ||
234 | pr_debug("sst_platform_open called\n"); | 271 | pr_debug("sst_platform_open called\n"); |
235 | 272 | ||
@@ -243,27 +280,27 @@ static int sst_platform_open(struct snd_pcm_substream *substream) | |||
243 | if (!stream) | 280 | if (!stream) |
244 | return -ENOMEM; | 281 | return -ENOMEM; |
245 | spin_lock_init(&stream->status_lock); | 282 | spin_lock_init(&stream->status_lock); |
246 | stream->stream_info.str_id = 0; | 283 | |
247 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | 284 | /* get the sst ops */ |
248 | stream->stream_info.mad_substream = substream; | 285 | mutex_lock(&sst_lock); |
249 | /* allocate memory for SST API set */ | 286 | if (!sst) { |
250 | stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops), | 287 | pr_err("no device available to run\n"); |
251 | GFP_KERNEL); | 288 | mutex_unlock(&sst_lock); |
252 | if (!stream->sstdrv_ops) { | ||
253 | pr_err("sst: mem allocation for ops fail\n"); | ||
254 | kfree(stream); | 289 | kfree(stream); |
255 | return -ENOMEM; | 290 | return -ENODEV; |
256 | } | 291 | } |
257 | stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID; | 292 | if (!try_module_get(sst->dev->driver->owner)) { |
258 | stream->sstdrv_ops->module_name = SST_CARD_NAMES; | 293 | mutex_unlock(&sst_lock); |
259 | /* registering with SST driver to get access to SST APIs to use */ | ||
260 | ret_val = register_sst_card(stream->sstdrv_ops); | ||
261 | if (ret_val) { | ||
262 | pr_err("sst: sst card registration failed\n"); | ||
263 | kfree(stream->sstdrv_ops); | ||
264 | kfree(stream); | 294 | kfree(stream); |
265 | return ret_val; | 295 | return -ENODEV; |
266 | } | 296 | } |
297 | stream->ops = sst->ops; | ||
298 | mutex_unlock(&sst_lock); | ||
299 | |||
300 | stream->stream_info.str_id = 0; | ||
301 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | ||
302 | stream->stream_info.mad_substream = substream; | ||
303 | /* allocate memory for SST API set */ | ||
267 | runtime->private_data = stream; | 304 | runtime->private_data = stream; |
268 | 305 | ||
269 | return 0; | 306 | return 0; |
@@ -278,9 +315,8 @@ static int sst_platform_close(struct snd_pcm_substream *substream) | |||
278 | stream = substream->runtime->private_data; | 315 | stream = substream->runtime->private_data; |
279 | str_id = stream->stream_info.str_id; | 316 | str_id = stream->stream_info.str_id; |
280 | if (str_id) | 317 | if (str_id) |
281 | ret_val = stream->sstdrv_ops->pcm_control->close(str_id); | 318 | ret_val = stream->ops->close(str_id); |
282 | unregister_sst_card(stream->sstdrv_ops); | 319 | module_put(sst->dev->driver->owner); |
283 | kfree(stream->sstdrv_ops); | ||
284 | kfree(stream); | 320 | kfree(stream); |
285 | return ret_val; | 321 | return ret_val; |
286 | } | 322 | } |
@@ -294,8 +330,8 @@ static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream) | |||
294 | stream = substream->runtime->private_data; | 330 | stream = substream->runtime->private_data; |
295 | str_id = stream->stream_info.str_id; | 331 | str_id = stream->stream_info.str_id; |
296 | if (stream->stream_info.str_id) { | 332 | if (stream->stream_info.str_id) { |
297 | ret_val = stream->sstdrv_ops->pcm_control->device_control( | 333 | ret_val = stream->ops->device_control( |
298 | SST_SND_DROP, &str_id); | 334 | SST_SND_DROP, &str_id); |
299 | return ret_val; | 335 | return ret_val; |
300 | } | 336 | } |
301 | 337 | ||
@@ -347,8 +383,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, | |||
347 | default: | 383 | default: |
348 | return -EINVAL; | 384 | return -EINVAL; |
349 | } | 385 | } |
350 | ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd, | 386 | ret_val = stream->ops->device_control(str_cmd, &str_id); |
351 | &str_id); | ||
352 | if (!ret_val) | 387 | if (!ret_val) |
353 | sst_set_stream_status(stream, status); | 388 | sst_set_stream_status(stream, status); |
354 | 389 | ||
@@ -368,7 +403,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer | |||
368 | if (status == SST_PLATFORM_INIT) | 403 | if (status == SST_PLATFORM_INIT) |
369 | return 0; | 404 | return 0; |
370 | str_info = &stream->stream_info; | 405 | str_info = &stream->stream_info; |
371 | ret_val = stream->sstdrv_ops->pcm_control->device_control( | 406 | ret_val = stream->ops->device_control( |
372 | SST_SND_BUFFER_POINTER, str_info); | 407 | SST_SND_BUFFER_POINTER, str_info); |
373 | if (ret_val) { | 408 | if (ret_val) { |
374 | pr_err("sst: error code = %d\n", ret_val); | 409 | pr_err("sst: error code = %d\n", ret_val); |
@@ -439,6 +474,7 @@ static int sst_platform_probe(struct platform_device *pdev) | |||
439 | int ret; | 474 | int ret; |
440 | 475 | ||
441 | pr_debug("sst_platform_probe called\n"); | 476 | pr_debug("sst_platform_probe called\n"); |
477 | sst = NULL; | ||
442 | ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv); | 478 | ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv); |
443 | if (ret) { | 479 | if (ret) { |
444 | pr_err("registering soc platform failed\n"); | 480 | pr_err("registering soc platform failed\n"); |
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h index df370286694f..f04f4f72daa0 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/mid-x86/sst_platform.h | |||
@@ -42,14 +42,14 @@ | |||
42 | #define SST_MIN_PERIODS 2 | 42 | #define SST_MIN_PERIODS 2 |
43 | #define SST_MAX_PERIODS (1024*2) | 43 | #define SST_MAX_PERIODS (1024*2) |
44 | #define SST_FIFO_SIZE 0 | 44 | #define SST_FIFO_SIZE 0 |
45 | #define SST_CARD_NAMES "intel_mid_card" | 45 | #define SST_CODEC_TYPE_PCM 1 |
46 | #define MSIC_VENDOR_ID 3 | ||
47 | 46 | ||
48 | struct sst_runtime_stream { | 47 | struct pcm_stream_info { |
49 | int stream_status; | 48 | int str_id; |
50 | struct pcm_stream_info stream_info; | 49 | void *mad_substream; |
51 | struct intel_sst_card_ops *sstdrv_ops; | 50 | void (*period_elapsed) (void *mad_substream); |
52 | spinlock_t status_lock; | 51 | unsigned long long buffer_ptr; |
52 | int sfreq; | ||
53 | }; | 53 | }; |
54 | 54 | ||
55 | enum sst_drv_status { | 55 | enum sst_drv_status { |
@@ -60,4 +60,72 @@ enum sst_drv_status { | |||
60 | SST_PLATFORM_DROPPED, | 60 | SST_PLATFORM_DROPPED, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | enum sst_controls { | ||
64 | SST_SND_ALLOC = 0x00, | ||
65 | SST_SND_PAUSE = 0x01, | ||
66 | SST_SND_RESUME = 0x02, | ||
67 | SST_SND_DROP = 0x03, | ||
68 | SST_SND_FREE = 0x04, | ||
69 | SST_SND_BUFFER_POINTER = 0x05, | ||
70 | SST_SND_STREAM_INIT = 0x06, | ||
71 | SST_SND_START = 0x07, | ||
72 | SST_MAX_CONTROLS = 0x07, | ||
73 | }; | ||
74 | |||
75 | enum sst_stream_ops { | ||
76 | STREAM_OPS_PLAYBACK = 0, | ||
77 | STREAM_OPS_CAPTURE, | ||
78 | }; | ||
79 | |||
80 | enum sst_audio_device_type { | ||
81 | SND_SST_DEVICE_HEADSET = 1, | ||
82 | SND_SST_DEVICE_IHF, | ||
83 | SND_SST_DEVICE_VIBRA, | ||
84 | SND_SST_DEVICE_HAPTIC, | ||
85 | SND_SST_DEVICE_CAPTURE, | ||
86 | }; | ||
87 | |||
88 | /* PCM Parameters */ | ||
89 | struct sst_pcm_params { | ||
90 | u16 codec; /* codec type */ | ||
91 | u8 num_chan; /* 1=Mono, 2=Stereo */ | ||
92 | u8 pcm_wd_sz; /* 16/24 - bit*/ | ||
93 | u32 reserved; /* Bitrate in bits per second */ | ||
94 | u32 sfreq; /* Sampling rate in Hz */ | ||
95 | u32 ring_buffer_size; | ||
96 | u32 period_count; /* period elapsed in samples*/ | ||
97 | u32 ring_buffer_addr; | ||
98 | }; | ||
99 | |||
100 | struct sst_stream_params { | ||
101 | u32 result; | ||
102 | u32 stream_id; | ||
103 | u8 codec; | ||
104 | u8 ops; | ||
105 | u8 stream_type; | ||
106 | u8 device_type; | ||
107 | struct sst_pcm_params sparams; | ||
108 | }; | ||
109 | |||
110 | struct sst_ops { | ||
111 | int (*open) (struct sst_stream_params *str_param); | ||
112 | int (*device_control) (int cmd, void *arg); | ||
113 | int (*close) (unsigned int str_id); | ||
114 | }; | ||
115 | |||
116 | struct sst_runtime_stream { | ||
117 | int stream_status; | ||
118 | struct pcm_stream_info stream_info; | ||
119 | struct sst_ops *ops; | ||
120 | spinlock_t status_lock; | ||
121 | }; | ||
122 | |||
123 | struct sst_device { | ||
124 | char *name; | ||
125 | struct device *dev; | ||
126 | struct sst_ops *ops; | ||
127 | }; | ||
128 | |||
129 | int sst_register_dsp(struct sst_device *sst); | ||
130 | int sst_unregister_dsp(struct sst_device *sst); | ||
63 | #endif | 131 | #endif |