2 * sst_drv_interface.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-14 Intel Corp
5 * Authors: Vinod Koul <vinod.koul@intel.com>
6 * Harsha Priya <priya.harsha@intel.com>
7 * Dharageswari R <dharageswari.r@intel.com)
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 #include <linux/delay.h>
22 #include <linux/pci.h>
24 #include <linux/firmware.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/pm_qos.h>
27 #include <linux/math64.h>
28 #include <sound/core.h>
29 #include <sound/pcm.h>
30 #include <sound/soc.h>
31 #include <sound/compress_driver.h>
32 #include <asm/platform_sst_audio.h>
33 #include "../sst-mfld-platform.h"
35 #include "../sst-dsp.h"
40 #define MIN_FRAGMENT 2
41 #define MAX_FRAGMENT 4
42 #define MIN_FRAGMENT_SIZE (50 * 1024)
43 #define MAX_FRAGMENT_SIZE (1024 * 1024)
44 #define SST_GET_BYTES_PER_SAMPLE(pcm_wd_sz) (((pcm_wd_sz + 15) >> 4) << 1)
46 int free_stream_context(struct intel_sst_drv
*ctx
, unsigned int str_id
)
48 struct stream_info
*stream
;
51 stream
= get_stream_info(ctx
, str_id
);
53 /* str_id is valid, so stream is alloacted */
54 ret
= sst_free_stream(ctx
, str_id
);
56 sst_clean_stream(&ctx
->streams
[str_id
]);
59 dev_err(ctx
->dev
, "we tried to free stream context %d which was freed!!!\n", str_id
);
64 int sst_get_stream_allocated(struct intel_sst_drv
*ctx
,
65 struct snd_sst_params
*str_param
,
66 struct snd_sst_lib_download
**lib_dnld
)
70 retval
= ctx
->ops
->alloc_stream(ctx
, str_param
);
72 dev_dbg(ctx
->dev
, "Stream allocated %d\n", retval
);
78 * sst_get_sfreq - this function returns the frequency of the stream
80 * @str_param : stream params
82 int sst_get_sfreq(struct snd_sst_params
*str_param
)
84 switch (str_param
->codec
) {
85 case SST_CODEC_TYPE_PCM
:
86 return str_param
->sparams
.uc
.pcm_params
.sfreq
;
87 case SST_CODEC_TYPE_AAC
:
88 return str_param
->sparams
.uc
.aac_params
.externalsr
;
89 case SST_CODEC_TYPE_MP3
:
97 * sst_get_num_channel - get number of channels for the stream
99 * @str_param : stream params
101 int sst_get_num_channel(struct snd_sst_params
*str_param
)
103 switch (str_param
->codec
) {
104 case SST_CODEC_TYPE_PCM
:
105 return str_param
->sparams
.uc
.pcm_params
.num_chan
;
106 case SST_CODEC_TYPE_MP3
:
107 return str_param
->sparams
.uc
.mp3_params
.num_chan
;
108 case SST_CODEC_TYPE_AAC
:
109 return str_param
->sparams
.uc
.aac_params
.num_chan
;
116 * sst_get_stream - this function prepares for stream allocation
118 * @str_param : stream param
120 int sst_get_stream(struct intel_sst_drv
*ctx
,
121 struct snd_sst_params
*str_param
)
124 struct stream_info
*str_info
;
126 /* stream is not allocated, we are allocating */
127 retval
= ctx
->ops
->alloc_stream(ctx
, str_param
);
131 /* store sampling freq */
132 str_info
= &ctx
->streams
[retval
];
133 str_info
->sfreq
= sst_get_sfreq(str_param
);
138 static int sst_power_control(struct device
*dev
, bool state
)
140 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
142 dev_dbg(ctx
->dev
, "state:%d", state
);
144 return pm_runtime_get_sync(dev
);
146 return sst_pm_runtime_put(ctx
);
150 * sst_open_pcm_stream - Open PCM interface
152 * @str_param: parameters of pcm stream
154 * This function is called by MID sound card driver to open
155 * a new pcm interface
157 static int sst_open_pcm_stream(struct device
*dev
,
158 struct snd_sst_params
*str_param
)
161 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
166 retval
= sst_get_stream(ctx
, str_param
);
170 dev_err(ctx
->dev
, "sst_get_stream returned err %d\n", retval
);
175 static int sst_cdev_open(struct device
*dev
,
176 struct snd_sst_params
*str_params
, struct sst_compress_cb
*cb
)
179 struct stream_info
*stream
;
180 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
182 retval
= pm_runtime_get_sync(ctx
->dev
);
186 str_id
= sst_get_stream(ctx
, str_params
);
188 dev_dbg(dev
, "stream allocated in sst_cdev_open %d\n", str_id
);
189 stream
= &ctx
->streams
[str_id
];
190 stream
->compr_cb
= cb
->compr_cb
;
191 stream
->compr_cb_param
= cb
->param
;
192 stream
->drain_notify
= cb
->drain_notify
;
193 stream
->drain_cb_param
= cb
->drain_cb_param
;
195 dev_err(dev
, "stream encountered error during alloc %d\n", str_id
);
197 sst_pm_runtime_put(ctx
);
202 static int sst_cdev_close(struct device
*dev
, unsigned int str_id
)
205 struct stream_info
*stream
;
206 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
208 stream
= get_stream_info(ctx
, str_id
);
210 dev_err(dev
, "stream info is NULL for str %d!!!\n", str_id
);
214 if (stream
->status
== STREAM_RESET
) {
215 dev_dbg(dev
, "stream in reset state...\n");
216 stream
->status
= STREAM_UN_INIT
;
222 retval
= sst_free_stream(ctx
, str_id
);
224 stream
->compr_cb_param
= NULL
;
225 stream
->compr_cb
= NULL
;
228 dev_err(dev
, "free stream returned err %d\n", retval
);
230 dev_dbg(dev
, "End\n");
235 static int sst_cdev_ack(struct device
*dev
, unsigned int str_id
,
238 struct stream_info
*stream
;
239 struct snd_sst_tstamp fw_tstamp
= {0,};
242 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
244 stream
= get_stream_info(ctx
, str_id
);
248 /* update bytes sent */
249 stream
->cumm_bytes
+= bytes
;
250 dev_dbg(dev
, "bytes copied %d inc by %ld\n", stream
->cumm_bytes
, bytes
);
252 memcpy_fromio(&fw_tstamp
,
253 ((void *)(ctx
->mailbox
+ ctx
->tstamp
)
254 +(str_id
* sizeof(fw_tstamp
))),
257 fw_tstamp
.bytes_copied
= stream
->cumm_bytes
;
258 dev_dbg(dev
, "bytes sent to fw %llu inc by %ld\n",
259 fw_tstamp
.bytes_copied
, bytes
);
261 addr
= ((void *)(ctx
->mailbox
+ ctx
->tstamp
)) +
262 (str_id
* sizeof(fw_tstamp
));
263 offset
= offsetof(struct snd_sst_tstamp
, bytes_copied
);
264 sst_shim_write(addr
, offset
, fw_tstamp
.bytes_copied
);
268 static int sst_cdev_set_metadata(struct device
*dev
,
269 unsigned int str_id
, struct snd_compr_metadata
*metadata
)
272 struct stream_info
*str_info
;
273 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
275 dev_dbg(dev
, "set metadata for stream %d\n", str_id
);
277 str_info
= get_stream_info(ctx
, str_id
);
281 dev_dbg(dev
, "pipe id = %d\n", str_info
->pipe_id
);
282 retval
= sst_prepare_and_post_msg(ctx
, str_info
->task_id
, IPC_CMD
,
283 IPC_IA_SET_STREAM_PARAMS_MRFLD
, str_info
->pipe_id
,
284 sizeof(*metadata
), metadata
, NULL
,
285 true, true, true, false);
290 static int sst_cdev_stream_pause(struct device
*dev
, unsigned int str_id
)
292 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
294 return sst_pause_stream(ctx
, str_id
);
297 static int sst_cdev_stream_pause_release(struct device
*dev
,
300 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
302 return sst_resume_stream(ctx
, str_id
);
305 static int sst_cdev_stream_start(struct device
*dev
, unsigned int str_id
)
307 struct stream_info
*str_info
;
308 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
310 str_info
= get_stream_info(ctx
, str_id
);
313 str_info
->prev
= str_info
->status
;
314 str_info
->status
= STREAM_RUNNING
;
315 return sst_start_stream(ctx
, str_id
);
318 static int sst_cdev_stream_drop(struct device
*dev
, unsigned int str_id
)
320 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
322 return sst_drop_stream(ctx
, str_id
);
325 static int sst_cdev_stream_drain(struct device
*dev
, unsigned int str_id
)
327 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
329 return sst_drain_stream(ctx
, str_id
, false);
332 static int sst_cdev_stream_partial_drain(struct device
*dev
,
335 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
337 return sst_drain_stream(ctx
, str_id
, true);
340 static int sst_cdev_tstamp(struct device
*dev
, unsigned int str_id
,
341 struct snd_compr_tstamp
*tstamp
)
343 struct snd_sst_tstamp fw_tstamp
= {0,};
344 struct stream_info
*stream
;
345 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
347 memcpy_fromio(&fw_tstamp
,
348 ((void *)(ctx
->mailbox
+ ctx
->tstamp
)
349 +(str_id
* sizeof(fw_tstamp
))),
352 stream
= get_stream_info(ctx
, str_id
);
355 dev_dbg(dev
, "rb_counter %llu in bytes\n", fw_tstamp
.ring_buffer_counter
);
357 tstamp
->copied_total
= fw_tstamp
.ring_buffer_counter
;
358 tstamp
->pcm_frames
= fw_tstamp
.frames_decoded
;
359 tstamp
->pcm_io_frames
= div_u64(fw_tstamp
.hardware_counter
,
360 (u64
)((stream
->num_ch
) * SST_GET_BYTES_PER_SAMPLE(24)));
361 tstamp
->sampling_rate
= fw_tstamp
.sampling_frequency
;
363 dev_dbg(dev
, "PCM = %u\n", tstamp
->pcm_io_frames
);
364 dev_dbg(dev
, "Ptr Query on strid = %d copied_total %d, decodec %d\n",
365 str_id
, tstamp
->copied_total
, tstamp
->pcm_frames
);
366 dev_dbg(dev
, "rendered %d\n", tstamp
->pcm_io_frames
);
371 static int sst_cdev_caps(struct snd_compr_caps
*caps
)
373 caps
->num_codecs
= NUM_CODEC
;
374 caps
->min_fragment_size
= MIN_FRAGMENT_SIZE
; /* 50KB */
375 caps
->max_fragment_size
= MAX_FRAGMENT_SIZE
; /* 1024KB */
376 caps
->min_fragments
= MIN_FRAGMENT
;
377 caps
->max_fragments
= MAX_FRAGMENT
;
378 caps
->codecs
[0] = SND_AUDIOCODEC_MP3
;
379 caps
->codecs
[1] = SND_AUDIOCODEC_AAC
;
383 static struct snd_compr_codec_caps caps_mp3
= {
384 .num_descriptors
= 1,
385 .descriptor
[0].max_ch
= 2,
386 .descriptor
[0].sample_rates
[0] = 48000,
387 .descriptor
[0].sample_rates
[1] = 44100,
388 .descriptor
[0].sample_rates
[2] = 32000,
389 .descriptor
[0].sample_rates
[3] = 16000,
390 .descriptor
[0].sample_rates
[4] = 8000,
391 .descriptor
[0].num_sample_rates
= 5,
392 .descriptor
[0].bit_rate
[0] = 320,
393 .descriptor
[0].bit_rate
[1] = 192,
394 .descriptor
[0].num_bitrates
= 2,
395 .descriptor
[0].profiles
= 0,
396 .descriptor
[0].modes
= SND_AUDIOCHANMODE_MP3_STEREO
,
397 .descriptor
[0].formats
= 0,
400 static struct snd_compr_codec_caps caps_aac
= {
401 .num_descriptors
= 2,
402 .descriptor
[1].max_ch
= 2,
403 .descriptor
[0].sample_rates
[0] = 48000,
404 .descriptor
[0].sample_rates
[1] = 44100,
405 .descriptor
[0].sample_rates
[2] = 32000,
406 .descriptor
[0].sample_rates
[3] = 16000,
407 .descriptor
[0].sample_rates
[4] = 8000,
408 .descriptor
[0].num_sample_rates
= 5,
409 .descriptor
[1].bit_rate
[0] = 320,
410 .descriptor
[1].bit_rate
[1] = 192,
411 .descriptor
[1].num_bitrates
= 2,
412 .descriptor
[1].profiles
= 0,
413 .descriptor
[1].modes
= 0,
414 .descriptor
[1].formats
=
415 (SND_AUDIOSTREAMFORMAT_MP4ADTS
|
416 SND_AUDIOSTREAMFORMAT_RAW
),
419 static int sst_cdev_codec_caps(struct snd_compr_codec_caps
*codec
)
421 if (codec
->codec
== SND_AUDIOCODEC_MP3
)
423 else if (codec
->codec
== SND_AUDIOCODEC_AAC
)
431 void sst_cdev_fragment_elapsed(struct intel_sst_drv
*ctx
, int str_id
)
433 struct stream_info
*stream
;
435 dev_dbg(ctx
->dev
, "fragment elapsed from firmware for str_id %d\n",
437 stream
= &ctx
->streams
[str_id
];
438 if (stream
->compr_cb
)
439 stream
->compr_cb(stream
->compr_cb_param
);
443 * sst_close_pcm_stream - Close PCM interface
445 * @str_id: stream id to be closed
447 * This function is called by MID sound card driver to close
448 * an existing pcm interface
450 static int sst_close_pcm_stream(struct device
*dev
, unsigned int str_id
)
452 struct stream_info
*stream
;
454 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
456 stream
= get_stream_info(ctx
, str_id
);
458 dev_err(ctx
->dev
, "stream info is NULL for str %d!!!\n", str_id
);
462 if (stream
->status
== STREAM_RESET
) {
463 /* silently fail here as we have cleaned the stream earlier */
464 dev_dbg(ctx
->dev
, "stream in reset state...\n");
470 retval
= free_stream_context(ctx
, str_id
);
472 stream
->pcm_substream
= NULL
;
473 stream
->status
= STREAM_UN_INIT
;
474 stream
->period_elapsed
= NULL
;
478 dev_err(ctx
->dev
, "free stream returned err %d\n", retval
);
480 dev_dbg(ctx
->dev
, "Exit\n");
484 static inline int sst_calc_tstamp(struct intel_sst_drv
*ctx
,
485 struct pcm_stream_info
*info
,
486 struct snd_pcm_substream
*substream
,
487 struct snd_sst_tstamp
*fw_tstamp
)
489 size_t delay_bytes
, delay_frames
;
491 u32 pointer_bytes
, pointer_samples
;
493 dev_dbg(ctx
->dev
, "mrfld ring_buffer_counter %llu in bytes\n",
494 fw_tstamp
->ring_buffer_counter
);
495 dev_dbg(ctx
->dev
, "mrfld hardware_counter %llu in bytes\n",
496 fw_tstamp
->hardware_counter
);
497 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
498 delay_bytes
= (size_t) (fw_tstamp
->ring_buffer_counter
-
499 fw_tstamp
->hardware_counter
);
501 delay_bytes
= (size_t) (fw_tstamp
->hardware_counter
-
502 fw_tstamp
->ring_buffer_counter
);
503 delay_frames
= bytes_to_frames(substream
->runtime
, delay_bytes
);
504 buffer_sz
= snd_pcm_lib_buffer_bytes(substream
);
505 div_u64_rem(fw_tstamp
->ring_buffer_counter
, buffer_sz
, &pointer_bytes
);
506 pointer_samples
= bytes_to_samples(substream
->runtime
, pointer_bytes
);
508 dev_dbg(ctx
->dev
, "pcm delay %zu in bytes\n", delay_bytes
);
510 info
->buffer_ptr
= pointer_samples
/ substream
->runtime
->channels
;
512 info
->pcm_delay
= delay_frames
/ substream
->runtime
->channels
;
513 dev_dbg(ctx
->dev
, "buffer ptr %llu pcm_delay rep: %llu\n",
514 info
->buffer_ptr
, info
->pcm_delay
);
518 static int sst_read_timestamp(struct device
*dev
, struct pcm_stream_info
*info
)
520 struct stream_info
*stream
;
521 struct snd_pcm_substream
*substream
;
522 struct snd_sst_tstamp fw_tstamp
;
524 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
526 str_id
= info
->str_id
;
527 stream
= get_stream_info(ctx
, str_id
);
531 if (!stream
->pcm_substream
)
533 substream
= stream
->pcm_substream
;
535 memcpy_fromio(&fw_tstamp
,
536 ((void *)(ctx
->mailbox
+ ctx
->tstamp
)
537 + (str_id
* sizeof(fw_tstamp
))),
539 return sst_calc_tstamp(ctx
, info
, substream
, &fw_tstamp
);
542 static int sst_stream_start(struct device
*dev
, int str_id
)
544 struct stream_info
*str_info
;
545 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
547 if (ctx
->sst_state
!= SST_FW_RUNNING
)
549 str_info
= get_stream_info(ctx
, str_id
);
552 str_info
->prev
= str_info
->status
;
553 str_info
->status
= STREAM_RUNNING
;
554 sst_start_stream(ctx
, str_id
);
559 static int sst_stream_drop(struct device
*dev
, int str_id
)
561 struct stream_info
*str_info
;
562 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
564 if (ctx
->sst_state
!= SST_FW_RUNNING
)
567 str_info
= get_stream_info(ctx
, str_id
);
570 str_info
->prev
= STREAM_UN_INIT
;
571 str_info
->status
= STREAM_INIT
;
572 return sst_drop_stream(ctx
, str_id
);
575 static int sst_stream_init(struct device
*dev
, struct pcm_stream_info
*str_info
)
578 struct stream_info
*stream
;
579 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
581 str_id
= str_info
->str_id
;
583 if (ctx
->sst_state
!= SST_FW_RUNNING
)
586 stream
= get_stream_info(ctx
, str_id
);
590 dev_dbg(ctx
->dev
, "setting the period ptrs\n");
591 stream
->pcm_substream
= str_info
->arg
;
592 stream
->period_elapsed
= str_info
->period_elapsed
;
593 stream
->sfreq
= str_info
->sfreq
;
594 stream
->prev
= stream
->status
;
595 stream
->status
= STREAM_INIT
;
597 "pcm_substream %p, period_elapsed %p, sfreq %d, status %d\n",
598 stream
->pcm_substream
, stream
->period_elapsed
,
599 stream
->sfreq
, stream
->status
);
605 * sst_set_byte_stream - Set generic params
607 * @cmd: control cmd to be set
608 * @arg: command argument
610 * This function is called by MID sound card driver to configure
611 * SST runtime params.
613 static int sst_send_byte_stream(struct device
*dev
,
614 struct snd_sst_bytes_v2
*bytes
)
617 struct intel_sst_drv
*ctx
= dev_get_drvdata(dev
);
621 ret_val
= pm_runtime_get_sync(ctx
->dev
);
625 ret_val
= sst_send_byte_stream_mrfld(ctx
, bytes
);
626 sst_pm_runtime_put(ctx
);
631 static struct sst_ops pcm_ops
= {
632 .open
= sst_open_pcm_stream
,
633 .stream_init
= sst_stream_init
,
634 .stream_start
= sst_stream_start
,
635 .stream_drop
= sst_stream_drop
,
636 .stream_read_tstamp
= sst_read_timestamp
,
637 .send_byte_stream
= sst_send_byte_stream
,
638 .close
= sst_close_pcm_stream
,
639 .power
= sst_power_control
,
642 static struct compress_sst_ops compr_ops
= {
643 .open
= sst_cdev_open
,
644 .close
= sst_cdev_close
,
645 .stream_pause
= sst_cdev_stream_pause
,
646 .stream_pause_release
= sst_cdev_stream_pause_release
,
647 .stream_start
= sst_cdev_stream_start
,
648 .stream_drop
= sst_cdev_stream_drop
,
649 .stream_drain
= sst_cdev_stream_drain
,
650 .stream_partial_drain
= sst_cdev_stream_partial_drain
,
651 .tstamp
= sst_cdev_tstamp
,
653 .get_caps
= sst_cdev_caps
,
654 .get_codec_caps
= sst_cdev_codec_caps
,
655 .set_metadata
= sst_cdev_set_metadata
,
656 .power
= sst_power_control
,
659 static struct sst_device sst_dsp_device
= {
660 .name
= "Intel(R) SST LPE",
663 .compr_ops
= &compr_ops
,
667 * sst_register - function to register DSP
669 * This functions registers DSP with the platform driver
671 int sst_register(struct device
*dev
)
675 sst_dsp_device
.dev
= dev
;
676 ret_val
= sst_register_dsp(&sst_dsp_device
);
678 dev_err(dev
, "Unable to register DSP with platform driver\n");
683 int sst_unregister(struct device
*dev
)
685 return sst_unregister_dsp(&sst_dsp_device
);