|
@@ -32,10 +32,51 @@
|
|
|
#include <sound/pcm.h>
|
|
|
#include <sound/pcm_params.h>
|
|
|
#include <sound/soc.h>
|
|
|
-#include "../../../drivers/staging/intel_sst/intel_sst_ioctl.h"
|
|
|
-#include "../../../drivers/staging/intel_sst/intel_sst.h"
|
|
|
#include "sst_platform.h"
|
|
|
|
|
|
+static struct sst_device *sst;
|
|
|
+static DEFINE_MUTEX(sst_lock);
|
|
|
+
|
|
|
+int sst_register_dsp(struct sst_device *dev)
|
|
|
+{
|
|
|
+ BUG_ON(!dev);
|
|
|
+ if (!try_module_get(dev->dev->driver->owner))
|
|
|
+ return -ENODEV;
|
|
|
+ mutex_lock(&sst_lock);
|
|
|
+ if (sst) {
|
|
|
+ pr_err("we already have a device %s\n", sst->name);
|
|
|
+ module_put(dev->dev->driver->owner);
|
|
|
+ mutex_unlock(&sst_lock);
|
|
|
+ return -EEXIST;
|
|
|
+ }
|
|
|
+ pr_debug("registering device %s\n", dev->name);
|
|
|
+ sst = dev;
|
|
|
+ mutex_unlock(&sst_lock);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(sst_register_dsp);
|
|
|
+
|
|
|
+int sst_unregister_dsp(struct sst_device *dev)
|
|
|
+{
|
|
|
+ BUG_ON(!dev);
|
|
|
+ if (dev != sst)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ mutex_lock(&sst_lock);
|
|
|
+
|
|
|
+ if (!sst) {
|
|
|
+ mutex_unlock(&sst_lock);
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+ module_put(sst->dev->driver->owner);
|
|
|
+ pr_debug("unreg %s\n", sst->name);
|
|
|
+ sst = NULL;
|
|
|
+ mutex_unlock(&sst_lock);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(sst_unregister_dsp);
|
|
|
+
|
|
|
static struct snd_pcm_hardware sst_platform_pcm_hw = {
|
|
|
.info = (SNDRV_PCM_INFO_INTERLEAVED |
|
|
|
SNDRV_PCM_INFO_DOUBLE |
|
|
@@ -135,37 +176,34 @@ static inline int sst_get_stream_status(struct sst_runtime_stream *stream)
|
|
|
}
|
|
|
|
|
|
static void sst_fill_pcm_params(struct snd_pcm_substream *substream,
|
|
|
- struct snd_sst_stream_params *param)
|
|
|
+ struct sst_pcm_params *param)
|
|
|
{
|
|
|
|
|
|
- param->uc.pcm_params.codec = SST_CODEC_TYPE_PCM;
|
|
|
- param->uc.pcm_params.num_chan = (u8) substream->runtime->channels;
|
|
|
- param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
|
|
|
- param->uc.pcm_params.reserved = 0;
|
|
|
- param->uc.pcm_params.sfreq = substream->runtime->rate;
|
|
|
- param->uc.pcm_params.ring_buffer_size =
|
|
|
- snd_pcm_lib_buffer_bytes(substream);
|
|
|
- param->uc.pcm_params.period_count = substream->runtime->period_size;
|
|
|
- param->uc.pcm_params.ring_buffer_addr =
|
|
|
- virt_to_phys(substream->dma_buffer.area);
|
|
|
- pr_debug("period_cnt = %d\n", param->uc.pcm_params.period_count);
|
|
|
- pr_debug("sfreq= %d, wd_sz = %d\n",
|
|
|
- param->uc.pcm_params.sfreq, param->uc.pcm_params.pcm_wd_sz);
|
|
|
+ param->codec = SST_CODEC_TYPE_PCM;
|
|
|
+ param->num_chan = (u8) substream->runtime->channels;
|
|
|
+ param->pcm_wd_sz = substream->runtime->sample_bits;
|
|
|
+ param->reserved = 0;
|
|
|
+ param->sfreq = substream->runtime->rate;
|
|
|
+ param->ring_buffer_size = snd_pcm_lib_buffer_bytes(substream);
|
|
|
+ param->period_count = substream->runtime->period_size;
|
|
|
+ param->ring_buffer_addr = virt_to_phys(substream->dma_buffer.area);
|
|
|
+ pr_debug("period_cnt = %d\n", param->period_count);
|
|
|
+ pr_debug("sfreq= %d, wd_sz = %d\n", param->sfreq, param->pcm_wd_sz);
|
|
|
}
|
|
|
|
|
|
static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
|
|
|
{
|
|
|
struct sst_runtime_stream *stream =
|
|
|
substream->runtime->private_data;
|
|
|
- struct snd_sst_stream_params param = {{{0,},},};
|
|
|
- struct snd_sst_params str_params = {0};
|
|
|
+ struct sst_pcm_params param = {0};
|
|
|
+ struct sst_stream_params str_params = {0};
|
|
|
int ret_val;
|
|
|
|
|
|
/* set codec params and inform SST driver the same */
|
|
|
sst_fill_pcm_params(substream, ¶m);
|
|
|
substream->runtime->dma_area = substream->dma_buffer.area;
|
|
|
str_params.sparams = param;
|
|
|
- str_params.codec = param.uc.pcm_params.codec;
|
|
|
+ str_params.codec = param.codec;
|
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
|
str_params.ops = STREAM_OPS_PLAYBACK;
|
|
|
str_params.device_type = substream->pcm->device + 1;
|
|
@@ -177,7 +215,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
|
|
|
pr_debug("Capture stream,Device %d\n",
|
|
|
substream->pcm->device);
|
|
|
}
|
|
|
- ret_val = stream->sstdrv_ops->pcm_control->open(&str_params);
|
|
|
+ ret_val = stream->ops->open(&str_params);
|
|
|
pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
|
|
|
if (ret_val < 0)
|
|
|
return ret_val;
|
|
@@ -216,7 +254,7 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream)
|
|
|
stream->stream_info.mad_substream = substream;
|
|
|
stream->stream_info.buffer_ptr = 0;
|
|
|
stream->stream_info.sfreq = substream->runtime->rate;
|
|
|
- ret_val = stream->sstdrv_ops->pcm_control->device_control(
|
|
|
+ ret_val = stream->ops->device_control(
|
|
|
SST_SND_STREAM_INIT, &stream->stream_info);
|
|
|
if (ret_val)
|
|
|
pr_err("control_set ret error %d\n", ret_val);
|
|
@@ -229,7 +267,6 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
|
|
|
{
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
|
|
struct sst_runtime_stream *stream;
|
|
|
- int ret_val = 0;
|
|
|
|
|
|
pr_debug("sst_platform_open called\n");
|
|
|
|
|
@@ -243,27 +280,27 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
|
|
|
if (!stream)
|
|
|
return -ENOMEM;
|
|
|
spin_lock_init(&stream->status_lock);
|
|
|
- stream->stream_info.str_id = 0;
|
|
|
- sst_set_stream_status(stream, SST_PLATFORM_INIT);
|
|
|
- stream->stream_info.mad_substream = substream;
|
|
|
- /* allocate memory for SST API set */
|
|
|
- stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops),
|
|
|
- GFP_KERNEL);
|
|
|
- if (!stream->sstdrv_ops) {
|
|
|
- pr_err("sst: mem allocation for ops fail\n");
|
|
|
+
|
|
|
+ /* get the sst ops */
|
|
|
+ mutex_lock(&sst_lock);
|
|
|
+ if (!sst) {
|
|
|
+ pr_err("no device available to run\n");
|
|
|
+ mutex_unlock(&sst_lock);
|
|
|
kfree(stream);
|
|
|
- return -ENOMEM;
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
- stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID;
|
|
|
- stream->sstdrv_ops->module_name = SST_CARD_NAMES;
|
|
|
- /* registering with SST driver to get access to SST APIs to use */
|
|
|
- ret_val = register_sst_card(stream->sstdrv_ops);
|
|
|
- if (ret_val) {
|
|
|
- pr_err("sst: sst card registration failed\n");
|
|
|
- kfree(stream->sstdrv_ops);
|
|
|
+ if (!try_module_get(sst->dev->driver->owner)) {
|
|
|
+ mutex_unlock(&sst_lock);
|
|
|
kfree(stream);
|
|
|
- return ret_val;
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
+ stream->ops = sst->ops;
|
|
|
+ mutex_unlock(&sst_lock);
|
|
|
+
|
|
|
+ stream->stream_info.str_id = 0;
|
|
|
+ sst_set_stream_status(stream, SST_PLATFORM_INIT);
|
|
|
+ stream->stream_info.mad_substream = substream;
|
|
|
+ /* allocate memory for SST API set */
|
|
|
runtime->private_data = stream;
|
|
|
|
|
|
return 0;
|
|
@@ -278,9 +315,8 @@ static int sst_platform_close(struct snd_pcm_substream *substream)
|
|
|
stream = substream->runtime->private_data;
|
|
|
str_id = stream->stream_info.str_id;
|
|
|
if (str_id)
|
|
|
- ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
|
|
|
- unregister_sst_card(stream->sstdrv_ops);
|
|
|
- kfree(stream->sstdrv_ops);
|
|
|
+ ret_val = stream->ops->close(str_id);
|
|
|
+ module_put(sst->dev->driver->owner);
|
|
|
kfree(stream);
|
|
|
return ret_val;
|
|
|
}
|
|
@@ -294,8 +330,8 @@ static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream)
|
|
|
stream = substream->runtime->private_data;
|
|
|
str_id = stream->stream_info.str_id;
|
|
|
if (stream->stream_info.str_id) {
|
|
|
- ret_val = stream->sstdrv_ops->pcm_control->device_control(
|
|
|
- SST_SND_DROP, &str_id);
|
|
|
+ ret_val = stream->ops->device_control(
|
|
|
+ SST_SND_DROP, &str_id);
|
|
|
return ret_val;
|
|
|
}
|
|
|
|
|
@@ -347,8 +383,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
|
|
|
default:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd,
|
|
|
- &str_id);
|
|
|
+ ret_val = stream->ops->device_control(str_cmd, &str_id);
|
|
|
if (!ret_val)
|
|
|
sst_set_stream_status(stream, status);
|
|
|
|
|
@@ -368,7 +403,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
|
|
|
if (status == SST_PLATFORM_INIT)
|
|
|
return 0;
|
|
|
str_info = &stream->stream_info;
|
|
|
- ret_val = stream->sstdrv_ops->pcm_control->device_control(
|
|
|
+ ret_val = stream->ops->device_control(
|
|
|
SST_SND_BUFFER_POINTER, str_info);
|
|
|
if (ret_val) {
|
|
|
pr_err("sst: error code = %d\n", ret_val);
|
|
@@ -439,6 +474,7 @@ static int sst_platform_probe(struct platform_device *pdev)
|
|
|
int ret;
|
|
|
|
|
|
pr_debug("sst_platform_probe called\n");
|
|
|
+ sst = NULL;
|
|
|
ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
|
|
|
if (ret) {
|
|
|
pr_err("registering soc platform failed\n");
|