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 --- sound/soc/mid-x86/Kconfig | 1 - sound/soc/mid-x86/sst_platform.c | 130 ++++++++++++++++++++++++-------------- 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 2935042..61c10bf 100644 --- a/sound/soc/mid-x86/Kconfig +++ b/sound/soc/mid-x86/Kconfig @@ -1,7 +1,6 @@ config SND_MFLD_MACHINE tristate "SOC Machine Audio driver for Intel Medfield MID platform" depends on INTEL_SCU_IPC - depends on SND_INTEL_SST select SND_SOC_SN95031 select SND_SST_PLATFORM help diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 3e78260..0012f67 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -31,10 +31,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 | @@ -134,37 +175,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; @@ -176,7 +214,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; @@ -215,7 +253,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); @@ -228,7 +266,6 @@ static int sst_platform_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; struct sst_runtime_stream *stream; - int ret_val = 0;
pr_debug("sst_platform_open called\n"); runtime = substream->runtime; @@ -237,27 +274,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 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); @@ -272,9 +309,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; } @@ -288,8 +324,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; }
@@ -341,8 +377,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);
@@ -362,7 +397,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); @@ -469,6 +504,7 @@ static struct platform_driver sst_platform_driver = { static int __init sst_soc_platform_init(void) { pr_debug("sst_soc_platform_init called\n"); + sst = NULL; return platform_driver_register(&sst_platform_driver); } module_init(sst_soc_platform_init); diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h index df37028..f04f4f7 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/mid-x86/sst_platform.h @@ -42,14 +42,14 @@ #define SST_MIN_PERIODS 2 #define SST_MAX_PERIODS (1024*2) #define SST_FIFO_SIZE 0 -#define SST_CARD_NAMES "intel_mid_card" -#define MSIC_VENDOR_ID 3 +#define SST_CODEC_TYPE_PCM 1
-struct sst_runtime_stream { - int stream_status; - struct pcm_stream_info stream_info; - struct intel_sst_card_ops *sstdrv_ops; - spinlock_t status_lock; +struct pcm_stream_info { + int str_id; + void *mad_substream; + void (*period_elapsed) (void *mad_substream); + unsigned long long buffer_ptr; + int sfreq; };
enum sst_drv_status { @@ -60,4 +60,72 @@ enum sst_drv_status { SST_PLATFORM_DROPPED, };
+enum sst_controls { + SST_SND_ALLOC = 0x00, + SST_SND_PAUSE = 0x01, + SST_SND_RESUME = 0x02, + SST_SND_DROP = 0x03, + SST_SND_FREE = 0x04, + SST_SND_BUFFER_POINTER = 0x05, + SST_SND_STREAM_INIT = 0x06, + SST_SND_START = 0x07, + SST_MAX_CONTROLS = 0x07, +}; + +enum sst_stream_ops { + STREAM_OPS_PLAYBACK = 0, + STREAM_OPS_CAPTURE, +}; + +enum sst_audio_device_type { + SND_SST_DEVICE_HEADSET = 1, + SND_SST_DEVICE_IHF, + SND_SST_DEVICE_VIBRA, + SND_SST_DEVICE_HAPTIC, + SND_SST_DEVICE_CAPTURE, +}; + +/* PCM Parameters */ +struct sst_pcm_params { + u16 codec; /* codec type */ + u8 num_chan; /* 1=Mono, 2=Stereo */ + u8 pcm_wd_sz; /* 16/24 - bit*/ + u32 reserved; /* Bitrate in bits per second */ + u32 sfreq; /* Sampling rate in Hz */ + u32 ring_buffer_size; + u32 period_count; /* period elapsed in samples*/ + u32 ring_buffer_addr; +}; + +struct sst_stream_params { + u32 result; + u32 stream_id; + u8 codec; + u8 ops; + u8 stream_type; + u8 device_type; + struct sst_pcm_params sparams; +}; + +struct sst_ops { + int (*open) (struct sst_stream_params *str_param); + int (*device_control) (int cmd, void *arg); + int (*close) (unsigned int str_id); +}; + +struct sst_runtime_stream { + int stream_status; + struct pcm_stream_info stream_info; + struct sst_ops *ops; + spinlock_t status_lock; +}; + +struct sst_device { + char *name; + struct device *dev; + struct sst_ops *ops; +}; + +int sst_register_dsp(struct sst_device *sst); +int sst_unregister_dsp(struct sst_device *sst); #endif