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>
This commit is contained in:
Родитель
f031efe940
Коммит
03c33042db
|
@ -1,7 +1,6 @@
|
||||||
config SND_MFLD_MACHINE
|
config SND_MFLD_MACHINE
|
||||||
tristate "SOC Machine Audio driver for Intel Medfield MID platform"
|
tristate "SOC Machine Audio driver for Intel Medfield MID platform"
|
||||||
depends on INTEL_SCU_IPC
|
depends on INTEL_SCU_IPC
|
||||||
depends on SND_INTEL_SST
|
|
||||||
select SND_SOC_SN95031
|
select SND_SOC_SN95031
|
||||||
select SND_SST_PLATFORM
|
select SND_SST_PLATFORM
|
||||||
help
|
help
|
||||||
|
|
|
@ -32,10 +32,51 @@
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
#include <sound/soc.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"
|
#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 = {
|
static struct snd_pcm_hardware sst_platform_pcm_hw = {
|
||||||
.info = (SNDRV_PCM_INFO_INTERLEAVED |
|
.info = (SNDRV_PCM_INFO_INTERLEAVED |
|
||||||
SNDRV_PCM_INFO_DOUBLE |
|
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,
|
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->codec = SST_CODEC_TYPE_PCM;
|
||||||
param->uc.pcm_params.num_chan = (u8) substream->runtime->channels;
|
param->num_chan = (u8) substream->runtime->channels;
|
||||||
param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
|
param->pcm_wd_sz = substream->runtime->sample_bits;
|
||||||
param->uc.pcm_params.reserved = 0;
|
param->reserved = 0;
|
||||||
param->uc.pcm_params.sfreq = substream->runtime->rate;
|
param->sfreq = substream->runtime->rate;
|
||||||
param->uc.pcm_params.ring_buffer_size =
|
param->ring_buffer_size = snd_pcm_lib_buffer_bytes(substream);
|
||||||
snd_pcm_lib_buffer_bytes(substream);
|
param->period_count = substream->runtime->period_size;
|
||||||
param->uc.pcm_params.period_count = substream->runtime->period_size;
|
param->ring_buffer_addr = virt_to_phys(substream->dma_buffer.area);
|
||||||
param->uc.pcm_params.ring_buffer_addr =
|
pr_debug("period_cnt = %d\n", param->period_count);
|
||||||
virt_to_phys(substream->dma_buffer.area);
|
pr_debug("sfreq= %d, wd_sz = %d\n", param->sfreq, param->pcm_wd_sz);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
|
static int sst_platform_alloc_stream(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct sst_runtime_stream *stream =
|
struct sst_runtime_stream *stream =
|
||||||
substream->runtime->private_data;
|
substream->runtime->private_data;
|
||||||
struct snd_sst_stream_params param = {{{0,},},};
|
struct sst_pcm_params param = {0};
|
||||||
struct snd_sst_params str_params = {0};
|
struct sst_stream_params str_params = {0};
|
||||||
int ret_val;
|
int ret_val;
|
||||||
|
|
||||||
/* set codec params and inform SST driver the same */
|
/* set codec params and inform SST driver the same */
|
||||||
sst_fill_pcm_params(substream, ¶m);
|
sst_fill_pcm_params(substream, ¶m);
|
||||||
substream->runtime->dma_area = substream->dma_buffer.area;
|
substream->runtime->dma_area = substream->dma_buffer.area;
|
||||||
str_params.sparams = param;
|
str_params.sparams = param;
|
||||||
str_params.codec = param.uc.pcm_params.codec;
|
str_params.codec = param.codec;
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
str_params.ops = STREAM_OPS_PLAYBACK;
|
str_params.ops = STREAM_OPS_PLAYBACK;
|
||||||
str_params.device_type = substream->pcm->device + 1;
|
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",
|
pr_debug("Capture stream,Device %d\n",
|
||||||
substream->pcm->device);
|
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);
|
pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val);
|
||||||
if (ret_val < 0)
|
if (ret_val < 0)
|
||||||
return ret_val;
|
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.mad_substream = substream;
|
||||||
stream->stream_info.buffer_ptr = 0;
|
stream->stream_info.buffer_ptr = 0;
|
||||||
stream->stream_info.sfreq = substream->runtime->rate;
|
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);
|
SST_SND_STREAM_INIT, &stream->stream_info);
|
||||||
if (ret_val)
|
if (ret_val)
|
||||||
pr_err("control_set ret error %d\n", 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 snd_pcm_runtime *runtime = substream->runtime;
|
||||||
struct sst_runtime_stream *stream;
|
struct sst_runtime_stream *stream;
|
||||||
int ret_val = 0;
|
|
||||||
|
|
||||||
pr_debug("sst_platform_open called\n");
|
pr_debug("sst_platform_open called\n");
|
||||||
|
|
||||||
|
@ -243,27 +280,27 @@ static int sst_platform_open(struct snd_pcm_substream *substream)
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
spin_lock_init(&stream->status_lock);
|
spin_lock_init(&stream->status_lock);
|
||||||
|
|
||||||
|
/* 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 -ENODEV;
|
||||||
|
}
|
||||||
|
if (!try_module_get(sst->dev->driver->owner)) {
|
||||||
|
mutex_unlock(&sst_lock);
|
||||||
|
kfree(stream);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
stream->ops = sst->ops;
|
||||||
|
mutex_unlock(&sst_lock);
|
||||||
|
|
||||||
stream->stream_info.str_id = 0;
|
stream->stream_info.str_id = 0;
|
||||||
sst_set_stream_status(stream, SST_PLATFORM_INIT);
|
sst_set_stream_status(stream, SST_PLATFORM_INIT);
|
||||||
stream->stream_info.mad_substream = substream;
|
stream->stream_info.mad_substream = substream;
|
||||||
/* allocate memory for SST API set */
|
/* 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");
|
|
||||||
kfree(stream);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
kfree(stream);
|
|
||||||
return ret_val;
|
|
||||||
}
|
|
||||||
runtime->private_data = stream;
|
runtime->private_data = stream;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -278,9 +315,8 @@ static int sst_platform_close(struct snd_pcm_substream *substream)
|
||||||
stream = substream->runtime->private_data;
|
stream = substream->runtime->private_data;
|
||||||
str_id = stream->stream_info.str_id;
|
str_id = stream->stream_info.str_id;
|
||||||
if (str_id)
|
if (str_id)
|
||||||
ret_val = stream->sstdrv_ops->pcm_control->close(str_id);
|
ret_val = stream->ops->close(str_id);
|
||||||
unregister_sst_card(stream->sstdrv_ops);
|
module_put(sst->dev->driver->owner);
|
||||||
kfree(stream->sstdrv_ops);
|
|
||||||
kfree(stream);
|
kfree(stream);
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +330,7 @@ static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream)
|
||||||
stream = substream->runtime->private_data;
|
stream = substream->runtime->private_data;
|
||||||
str_id = stream->stream_info.str_id;
|
str_id = stream->stream_info.str_id;
|
||||||
if (stream->stream_info.str_id) {
|
if (stream->stream_info.str_id) {
|
||||||
ret_val = stream->sstdrv_ops->pcm_control->device_control(
|
ret_val = stream->ops->device_control(
|
||||||
SST_SND_DROP, &str_id);
|
SST_SND_DROP, &str_id);
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
@ -347,8 +383,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd,
|
ret_val = stream->ops->device_control(str_cmd, &str_id);
|
||||||
&str_id);
|
|
||||||
if (!ret_val)
|
if (!ret_val)
|
||||||
sst_set_stream_status(stream, status);
|
sst_set_stream_status(stream, status);
|
||||||
|
|
||||||
|
@ -368,7 +403,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer
|
||||||
if (status == SST_PLATFORM_INIT)
|
if (status == SST_PLATFORM_INIT)
|
||||||
return 0;
|
return 0;
|
||||||
str_info = &stream->stream_info;
|
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);
|
SST_SND_BUFFER_POINTER, str_info);
|
||||||
if (ret_val) {
|
if (ret_val) {
|
||||||
pr_err("sst: error code = %d\n", 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;
|
int ret;
|
||||||
|
|
||||||
pr_debug("sst_platform_probe called\n");
|
pr_debug("sst_platform_probe called\n");
|
||||||
|
sst = NULL;
|
||||||
ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
|
ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("registering soc platform failed\n");
|
pr_err("registering soc platform failed\n");
|
||||||
|
|
|
@ -42,14 +42,14 @@
|
||||||
#define SST_MIN_PERIODS 2
|
#define SST_MIN_PERIODS 2
|
||||||
#define SST_MAX_PERIODS (1024*2)
|
#define SST_MAX_PERIODS (1024*2)
|
||||||
#define SST_FIFO_SIZE 0
|
#define SST_FIFO_SIZE 0
|
||||||
#define SST_CARD_NAMES "intel_mid_card"
|
#define SST_CODEC_TYPE_PCM 1
|
||||||
#define MSIC_VENDOR_ID 3
|
|
||||||
|
|
||||||
struct sst_runtime_stream {
|
struct pcm_stream_info {
|
||||||
int stream_status;
|
int str_id;
|
||||||
struct pcm_stream_info stream_info;
|
void *mad_substream;
|
||||||
struct intel_sst_card_ops *sstdrv_ops;
|
void (*period_elapsed) (void *mad_substream);
|
||||||
spinlock_t status_lock;
|
unsigned long long buffer_ptr;
|
||||||
|
int sfreq;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sst_drv_status {
|
enum sst_drv_status {
|
||||||
|
@ -60,4 +60,72 @@ enum sst_drv_status {
|
||||||
SST_PLATFORM_DROPPED,
|
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
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче