Skip to content

Commit

Permalink
ASoC: sst_platform: fix the dsp driver interface
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Vinod Koul authored and Mark Brown committed Dec 5, 2011
1 parent f031efe commit 03c3304
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 55 deletions.
1 change: 0 additions & 1 deletion sound/soc/mid-x86/Kconfig
Original file line number Diff line number Diff line change
@@ -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
Expand Down
130 changes: 83 additions & 47 deletions sound/soc/mid-x86/sst_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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, &param);
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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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");

Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand Down Expand Up @@ -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");
Expand Down
82 changes: 75 additions & 7 deletions sound/soc/mid-x86/sst_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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

0 comments on commit 03c3304

Please sign in to comment.