~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/intel/atom/sst-mfld-platform-compress.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  *  sst_mfld_platform.c - Intel MID Platform driver
  4  *
  5  *  Copyright (C) 2010-2014 Intel Corp
  6  *  Author: Vinod Koul <vinod.koul@intel.com>
  7  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  8  *
  9  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 10  */
 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 12 
 13 #include <linux/slab.h>
 14 #include <linux/io.h>
 15 #include <linux/module.h>
 16 #include <sound/core.h>
 17 #include <sound/pcm.h>
 18 #include <sound/pcm_params.h>
 19 #include <sound/soc.h>
 20 #include <sound/compress_driver.h>
 21 #include "sst-mfld-platform.h"
 22 
 23 /* compress stream operations */
 24 static void sst_compr_fragment_elapsed(void *arg)
 25 {
 26         struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;
 27 
 28         pr_debug("fragment elapsed by driver\n");
 29         if (cstream)
 30                 snd_compr_fragment_elapsed(cstream);
 31 }
 32 
 33 static void sst_drain_notify(void *arg)
 34 {
 35         struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;
 36 
 37         pr_debug("drain notify by driver\n");
 38         if (cstream)
 39                 snd_compr_drain_notify(cstream);
 40 }
 41 
 42 static int sst_platform_compr_open(struct snd_soc_component *component,
 43                                    struct snd_compr_stream *cstream)
 44 {
 45         int ret_val;
 46         struct snd_compr_runtime *runtime = cstream->runtime;
 47         struct sst_runtime_stream *stream;
 48 
 49         stream = kzalloc(sizeof(*stream), GFP_KERNEL);
 50         if (!stream)
 51                 return -ENOMEM;
 52 
 53         spin_lock_init(&stream->status_lock);
 54 
 55         /* get the sst ops */
 56         if (!sst || !try_module_get(sst->dev->driver->owner)) {
 57                 pr_err("no device available to run\n");
 58                 ret_val = -ENODEV;
 59                 goto out_ops;
 60         }
 61         stream->compr_ops = sst->compr_ops;
 62         stream->id = 0;
 63 
 64         /* Turn on LPE */
 65         sst->compr_ops->power(sst->dev, true);
 66 
 67         sst_set_stream_status(stream, SST_PLATFORM_INIT);
 68         runtime->private_data = stream;
 69         return 0;
 70 out_ops:
 71         kfree(stream);
 72         return ret_val;
 73 }
 74 
 75 static int sst_platform_compr_free(struct snd_soc_component *component,
 76                                    struct snd_compr_stream *cstream)
 77 {
 78         struct sst_runtime_stream *stream;
 79         int ret_val = 0, str_id;
 80 
 81         stream = cstream->runtime->private_data;
 82         /* Turn off LPE */
 83         sst->compr_ops->power(sst->dev, false);
 84 
 85         /*need to check*/
 86         str_id = stream->id;
 87         if (str_id)
 88                 ret_val = stream->compr_ops->close(sst->dev, str_id);
 89         module_put(sst->dev->driver->owner);
 90         kfree(stream);
 91         pr_debug("%s: %d\n", __func__, ret_val);
 92         return 0;
 93 }
 94 
 95 static int sst_platform_compr_set_params(struct snd_soc_component *component,
 96                                          struct snd_compr_stream *cstream,
 97                                          struct snd_compr_params *params)
 98 {
 99         struct sst_runtime_stream *stream;
100         int retval;
101         struct snd_sst_params str_params;
102         struct sst_compress_cb cb;
103         struct sst_data *ctx = snd_soc_component_get_drvdata(component);
104 
105         stream = cstream->runtime->private_data;
106         /* construct fw structure for this*/
107         memset(&str_params, 0, sizeof(str_params));
108 
109         /* fill the device type and stream id to pass to SST driver */
110         retval = sst_fill_stream_params(cstream, ctx, &str_params, true);
111         pr_debug("compr_set_params: fill stream params ret_val = 0x%x\n", retval);
112         if (retval < 0)
113                 return retval;
114 
115         switch (params->codec.id) {
116         case SND_AUDIOCODEC_MP3: {
117                 str_params.codec = SST_CODEC_TYPE_MP3;
118                 str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in;
119                 str_params.sparams.uc.mp3_params.pcm_wd_sz = 16;
120                 break;
121         }
122 
123         case SND_AUDIOCODEC_AAC: {
124                 str_params.codec = SST_CODEC_TYPE_AAC;
125                 str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in;
126                 str_params.sparams.uc.aac_params.pcm_wd_sz = 16;
127                 if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS)
128                         str_params.sparams.uc.aac_params.bs_format =
129                                                         AAC_BIT_STREAM_ADTS;
130                 else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW)
131                         str_params.sparams.uc.aac_params.bs_format =
132                                                         AAC_BIT_STREAM_RAW;
133                 else {
134                         pr_err("Undefined format%d\n", params->codec.format);
135                         return -EINVAL;
136                 }
137                 str_params.sparams.uc.aac_params.externalsr =
138                                                 params->codec.sample_rate;
139                 break;
140         }
141 
142         default:
143                 pr_err("codec not supported, id =%d\n", params->codec.id);
144                 return -EINVAL;
145         }
146 
147         str_params.aparams.ring_buf_info[0].addr  =
148                                         virt_to_phys(cstream->runtime->buffer);
149         str_params.aparams.ring_buf_info[0].size =
150                                         cstream->runtime->buffer_size;
151         str_params.aparams.sg_count = 1;
152         str_params.aparams.frag_size = cstream->runtime->fragment_size;
153 
154         cb.param = cstream;
155         cb.compr_cb = sst_compr_fragment_elapsed;
156         cb.drain_cb_param = cstream;
157         cb.drain_notify = sst_drain_notify;
158 
159         retval = stream->compr_ops->open(sst->dev, &str_params, &cb);
160         if (retval < 0) {
161                 pr_err("stream allocation failed %d\n", retval);
162                 return retval;
163         }
164 
165         stream->id = retval;
166         return 0;
167 }
168 
169 static int sst_platform_compr_trigger(struct snd_soc_component *component,
170                                       struct snd_compr_stream *cstream, int cmd)
171 {
172         struct sst_runtime_stream *stream = cstream->runtime->private_data;
173 
174         switch (cmd) {
175         case SNDRV_PCM_TRIGGER_START:
176                 if (stream->compr_ops->stream_start)
177                         return stream->compr_ops->stream_start(sst->dev, stream->id);
178                 break;
179         case SNDRV_PCM_TRIGGER_STOP:
180                 if (stream->compr_ops->stream_drop)
181                         return stream->compr_ops->stream_drop(sst->dev, stream->id);
182                 break;
183         case SND_COMPR_TRIGGER_DRAIN:
184                 if (stream->compr_ops->stream_drain)
185                         return stream->compr_ops->stream_drain(sst->dev, stream->id);
186                 break;
187         case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
188                 if (stream->compr_ops->stream_partial_drain)
189                         return stream->compr_ops->stream_partial_drain(sst->dev, stream->id);
190                 break;
191         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
192                 if (stream->compr_ops->stream_pause)
193                         return stream->compr_ops->stream_pause(sst->dev, stream->id);
194                 break;
195         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
196                 if (stream->compr_ops->stream_pause_release)
197                         return stream->compr_ops->stream_pause_release(sst->dev, stream->id);
198                 break;
199         }
200         return -EINVAL;
201 }
202 
203 static int sst_platform_compr_pointer(struct snd_soc_component *component,
204                                       struct snd_compr_stream *cstream,
205                                       struct snd_compr_tstamp *tstamp)
206 {
207         struct sst_runtime_stream *stream;
208 
209         stream  = cstream->runtime->private_data;
210         stream->compr_ops->tstamp(sst->dev, stream->id, tstamp);
211         tstamp->byte_offset = tstamp->copied_total %
212                                  (u32)cstream->runtime->buffer_size;
213         pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
214         return 0;
215 }
216 
217 static int sst_platform_compr_ack(struct snd_soc_component *component,
218                                   struct snd_compr_stream *cstream,
219                                   size_t bytes)
220 {
221         struct sst_runtime_stream *stream;
222 
223         stream  = cstream->runtime->private_data;
224         stream->compr_ops->ack(sst->dev, stream->id, (unsigned long)bytes);
225         stream->bytes_written += bytes;
226 
227         return 0;
228 }
229 
230 static int sst_platform_compr_get_caps(struct snd_soc_component *component,
231                                        struct snd_compr_stream *cstream,
232                                        struct snd_compr_caps *caps)
233 {
234         struct sst_runtime_stream *stream =
235                 cstream->runtime->private_data;
236 
237         return stream->compr_ops->get_caps(caps);
238 }
239 
240 static int sst_platform_compr_get_codec_caps(struct snd_soc_component *component,
241                                              struct snd_compr_stream *cstream,
242                                              struct snd_compr_codec_caps *codec)
243 {
244         struct sst_runtime_stream *stream =
245                 cstream->runtime->private_data;
246 
247         return stream->compr_ops->get_codec_caps(codec);
248 }
249 
250 static int sst_platform_compr_set_metadata(struct snd_soc_component *component,
251                                            struct snd_compr_stream *cstream,
252                                            struct snd_compr_metadata *metadata)
253 {
254         struct sst_runtime_stream *stream  =
255                  cstream->runtime->private_data;
256 
257         return stream->compr_ops->set_metadata(sst->dev, stream->id, metadata);
258 }
259 
260 const struct snd_compress_ops sst_platform_compress_ops = {
261 
262         .open = sst_platform_compr_open,
263         .free = sst_platform_compr_free,
264         .set_params = sst_platform_compr_set_params,
265         .set_metadata = sst_platform_compr_set_metadata,
266         .trigger = sst_platform_compr_trigger,
267         .pointer = sst_platform_compr_pointer,
268         .ack = sst_platform_compr_ack,
269         .get_caps = sst_platform_compr_get_caps,
270         .get_codec_caps = sst_platform_compr_get_codec_caps,
271 };
272 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php