aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/mid-x86
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@linux.intel.com>2011-12-05 08:43:41 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-05 09:02:31 -0500
commit03c33042dbcd087303062c51f462c4575eb630d6 (patch)
treee7199d42c3ebb7272e53673c7a1adf8caf3c90a6 /sound/soc/mid-x86
parentf031efe9402e4ab6a6cd86bbda54b30ed9171237 (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/Kconfig1
-rw-r--r--sound/soc/mid-x86/sst_platform.c130
-rw-r--r--sound/soc/mid-x86/sst_platform.h82
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 @@
1config SND_MFLD_MACHINE 1config 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
37static struct sst_device *sst;
38static DEFINE_MUTEX(sst_lock);
39
40int 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}
57EXPORT_SYMBOL_GPL(sst_register_dsp);
58
59int 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}
78EXPORT_SYMBOL_GPL(sst_unregister_dsp);
79
39static struct snd_pcm_hardware sst_platform_pcm_hw = { 80static 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
137static void sst_fill_pcm_params(struct snd_pcm_substream *substream, 178static 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
156static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) 194static 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, &param); 203 sst_fill_pcm_params(substream, &param);
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
48struct sst_runtime_stream { 47struct 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
55enum sst_drv_status { 55enum sst_drv_status {
@@ -60,4 +60,72 @@ enum sst_drv_status {
60 SST_PLATFORM_DROPPED, 60 SST_PLATFORM_DROPPED,
61}; 61};
62 62
63enum 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
75enum sst_stream_ops {
76 STREAM_OPS_PLAYBACK = 0,
77 STREAM_OPS_CAPTURE,
78};
79
80enum 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 */
89struct 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
100struct 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
110struct 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
116struct 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
123struct sst_device {
124 char *name;
125 struct device *dev;
126 struct sst_ops *ops;
127};
128
129int sst_register_dsp(struct sst_device *sst);
130int sst_unregister_dsp(struct sst_device *sst);
63#endif 131#endif