Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03c33042 authored by Vinod Koul's avatar Vinod Koul Committed by Mark Brown
Browse files

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: default avatarVinod Koul <vinod.koul@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent f031efe9
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
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
+83 −47
Original line number Diff line number Diff line
@@ -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, &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;
@@ -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,7 +330,7 @@ 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(
		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");
+75 −7
Original line number Diff line number Diff line
@@ -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