Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: SOF: Intel: Add legacy IPC support

Add IPC support required for devices introduced before Skylake
(Merrifield, baytrail, CherryTrail, Haswell, Broadwell)

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Guennadi Liakhovetski and committed by
Mark Brown
351d1174 458bc729

+92
+92
sound/soc/sof/intel/intel-ipc.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 + // 3 + // This file is provided under a dual BSD/GPLv2 license. When using or 4 + // redistributing this file, you may do so under either license. 5 + // 6 + // Copyright(c) 2019 Intel Corporation. All rights reserved. 7 + // 8 + // Authors: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> 9 + 10 + /* Intel-specific SOF IPC code */ 11 + 12 + #include <linux/device.h> 13 + #include <linux/export.h> 14 + #include <linux/module.h> 15 + #include <linux/types.h> 16 + 17 + #include <sound/pcm.h> 18 + #include <sound/sof/stream.h> 19 + 20 + #include "../ops.h" 21 + #include "../sof-priv.h" 22 + 23 + struct intel_stream { 24 + size_t posn_offset; 25 + }; 26 + 27 + /* Mailbox-based Intel IPC implementation */ 28 + void intel_ipc_msg_data(struct snd_sof_dev *sdev, 29 + struct snd_pcm_substream *substream, 30 + void *p, size_t sz) 31 + { 32 + if (!substream || !sdev->stream_box.size) { 33 + sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); 34 + } else { 35 + struct intel_stream *stream = substream->runtime->private_data; 36 + 37 + /* The stream might already be closed */ 38 + if (stream) 39 + sof_mailbox_read(sdev, stream->posn_offset, p, sz); 40 + } 41 + } 42 + EXPORT_SYMBOL(intel_ipc_msg_data); 43 + 44 + int intel_ipc_pcm_params(struct snd_sof_dev *sdev, 45 + struct snd_pcm_substream *substream, 46 + const struct sof_ipc_pcm_params_reply *reply) 47 + { 48 + struct intel_stream *stream = substream->runtime->private_data; 49 + size_t posn_offset = reply->posn_offset; 50 + 51 + /* check if offset is overflow or it is not aligned */ 52 + if (posn_offset > sdev->stream_box.size || 53 + posn_offset % sizeof(struct sof_ipc_stream_posn) != 0) 54 + return -EINVAL; 55 + 56 + stream->posn_offset = sdev->stream_box.offset + posn_offset; 57 + 58 + dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu", 59 + substream->stream, stream->posn_offset); 60 + 61 + return 0; 62 + } 63 + EXPORT_SYMBOL(intel_ipc_pcm_params); 64 + 65 + int intel_pcm_open(struct snd_sof_dev *sdev, 66 + struct snd_pcm_substream *substream) 67 + { 68 + struct intel_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL); 69 + 70 + if (!stream) 71 + return -ENOMEM; 72 + 73 + /* binding pcm substream to hda stream */ 74 + substream->runtime->private_data = stream; 75 + 76 + return 0; 77 + } 78 + EXPORT_SYMBOL(intel_pcm_open); 79 + 80 + int intel_pcm_close(struct snd_sof_dev *sdev, 81 + struct snd_pcm_substream *substream) 82 + { 83 + struct intel_stream *stream = substream->runtime->private_data; 84 + 85 + substream->runtime->private_data = NULL; 86 + kfree(stream); 87 + 88 + return 0; 89 + } 90 + EXPORT_SYMBOL(intel_pcm_close); 91 + 92 + MODULE_LICENSE("Dual BSD/GPL");