2 * intel_sst_interface.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-10 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 * Jeeja KP <jeeja.kp@intel.com>
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 * This driver exposes the audio engine functionalities to the ALSA
27 * Upper layer interfaces (MAD driver, MMF) to SST driver
30 #include <linux/pci.h>
32 #include <linux/uio.h>
33 #include <linux/aio.h>
34 #include <linux/uaccess.h>
35 #include <linux/firmware.h>
36 #include <linux/ioctl.h>
37 #ifdef CONFIG_MRST_RAR_HANDLER
38 #include <linux/rar_register.h>
39 #include "../../../drivers/staging/memrar/memrar.h"
41 #include "intel_sst.h"
42 #include "intel_sst_ioctl.h"
43 #include "intel_sst_fw_ipc.h"
44 #include "intel_sst_common.h"
47 #define STREAM_MODULE 0
51 * intel_sst_check_device - checks SST device
53 * This utility function checks the state of SST device and downlaods FW if
54 * not done, or resumes the device if suspended
57 static int intel_sst_check_device(void)
60 if (sst_drv_ctx->pmic_state != SND_MAD_INIT_DONE) {
61 pr_warn("sst: Sound card not availble\n ");
64 if (sst_drv_ctx->sst_state == SST_SUSPENDED) {
65 pr_debug("sst: Resuming from Suspended state\n");
66 retval = intel_sst_resume(sst_drv_ctx->pci);
68 pr_debug("sst: Resume Failed= %#x,abort\n", retval);
73 if (sst_drv_ctx->sst_state == SST_UN_INIT) {
74 /* FW is not downloaded */
75 retval = sst_download_fw();
78 if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
79 retval = sst_drv_ctx->rx_time_slot_status;
80 if (retval != RX_TIMESLOT_UNINIT
81 && sst_drv_ctx->pmic_vendor != SND_NC)
82 sst_enable_rx_timeslot(retval);
89 * intel_sst_open - opens a handle to driver
91 * @i_node: inode structure
92 * @file_ptr:pointer to file
94 * This function is called by OS when a user space component
95 * tries to get a driver handle. Only one handle at a time
98 int intel_sst_open(struct inode *i_node, struct file *file_ptr)
100 int retval = intel_sst_check_device();
104 mutex_lock(&sst_drv_ctx->stream_lock);
105 if (sst_drv_ctx->encoded_cnt < MAX_ENC_STREAM) {
106 struct ioctl_pvt_data *data =
107 kzalloc(sizeof(struct ioctl_pvt_data), GFP_KERNEL);
109 mutex_unlock(&sst_drv_ctx->stream_lock);
113 sst_drv_ctx->encoded_cnt++;
114 mutex_unlock(&sst_drv_ctx->stream_lock);
115 data->pvt_id = sst_assign_pvt_id(sst_drv_ctx);
117 file_ptr->private_data = (void *)data;
118 pr_debug("sst: pvt_id handle = %d!\n", data->pvt_id);
121 mutex_unlock(&sst_drv_ctx->stream_lock);
127 * intel_sst_open_cntrl - opens a handle to driver
129 * @i_node: inode structure
130 * @file_ptr:pointer to file
132 * This function is called by OS when a user space component
133 * tries to get a driver handle to /dev/intel_sst_control.
134 * Only one handle at a time will be allowed
135 * This is for control operations only
137 int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr)
139 int retval = intel_sst_check_device();
143 /* audio manager open */
144 mutex_lock(&sst_drv_ctx->stream_lock);
145 if (sst_drv_ctx->am_cnt < MAX_AM_HANDLES) {
146 sst_drv_ctx->am_cnt++;
147 pr_debug("sst: AM handle opened...\n");
148 file_ptr->private_data = NULL;
152 mutex_unlock(&sst_drv_ctx->stream_lock);
157 * intel_sst_release - releases a handle to driver
159 * @i_node: inode structure
160 * @file_ptr: pointer to file
162 * This function is called by OS when a user space component
163 * tries to release a driver handle.
165 int intel_sst_release(struct inode *i_node, struct file *file_ptr)
167 struct ioctl_pvt_data *data = file_ptr->private_data;
169 pr_debug("sst: Release called, closing app handle\n");
170 mutex_lock(&sst_drv_ctx->stream_lock);
171 sst_drv_ctx->encoded_cnt--;
172 sst_drv_ctx->stream_cnt--;
173 mutex_unlock(&sst_drv_ctx->stream_lock);
174 free_stream_context(data->str_id);
179 int intel_sst_release_cntrl(struct inode *i_node, struct file *file_ptr)
181 /* audio manager close */
182 mutex_lock(&sst_drv_ctx->stream_lock);
183 sst_drv_ctx->am_cnt--;
184 mutex_unlock(&sst_drv_ctx->stream_lock);
185 pr_debug("sst: AM handle closed\n");
190 * intel_sst_mmap - mmaps a kernel buffer to user space for copying data
192 * @vma: vm area structure instance
193 * @file_ptr: pointer to file
195 * This function is called by OS when a user space component
196 * tries to get mmap memory from driver
198 int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma)
201 struct ioctl_pvt_data *data =
202 (struct ioctl_pvt_data *)file_ptr->private_data;
203 int str_id = data->str_id;
206 retval = sst_validate_strid(str_id);
210 length = vma->vm_end - vma->vm_start;
211 pr_debug("sst: called for stream %d length 0x%x\n", str_id, length);
213 if (length > sst_drv_ctx->mmap_len)
215 if (!sst_drv_ctx->mmap_mem)
218 /* round it up to the page bondary */
219 /*mem_area = (void *)((((unsigned long)sst_drv_ctx->mmap_mem)
220 + PAGE_SIZE - 1) & PAGE_MASK);*/
221 mem_area = (void *) PAGE_ALIGN((unsigned int) sst_drv_ctx->mmap_mem);
223 /* map the whole physically contiguous area in one piece */
224 retval = remap_pfn_range(vma,
226 virt_to_phys((void *)mem_area) >> PAGE_SHIFT,
230 sst_drv_ctx->streams[str_id].mmapped = false;
232 sst_drv_ctx->streams[str_id].mmapped = true;
234 pr_debug("sst: mmap ret 0x%x\n", retval);
238 /* sets mmap data buffers to play/capture*/
239 static int intel_sst_mmap_play_capture(u32 str_id,
240 struct snd_sst_mmap_buffs *mmap_buf)
242 struct sst_stream_bufs *bufs;
244 struct stream_info *stream;
245 struct snd_sst_mmap_buff_entry *buf_entry;
246 struct snd_sst_mmap_buff_entry *tmp_buf;
248 pr_debug("sst:called for str_id %d\n", str_id);
249 retval = sst_validate_strid(str_id);
253 stream = &sst_drv_ctx->streams[str_id];
254 if (stream->mmapped != true)
257 if (stream->status == STREAM_UN_INIT ||
258 stream->status == STREAM_DECODE) {
261 stream->curr_bytes = 0;
262 stream->cumm_bytes = 0;
264 tmp_buf = kcalloc(mmap_buf->entries, sizeof(*tmp_buf), GFP_KERNEL);
267 if (copy_from_user(tmp_buf, (void __user *)mmap_buf->buff,
268 mmap_buf->entries * sizeof(*tmp_buf))) {
273 pr_debug("sst:new buffers count %d status %d\n",
274 mmap_buf->entries, stream->status);
276 for (i = 0; i < mmap_buf->entries; i++) {
277 bufs = kzalloc(sizeof(*bufs), GFP_KERNEL);
282 bufs->size = buf_entry->size;
283 bufs->offset = buf_entry->offset;
284 bufs->addr = sst_drv_ctx->mmap_mem;
285 bufs->in_use = false;
288 mutex_lock(&stream->lock);
289 list_add_tail(&bufs->node, &stream->bufs);
290 mutex_unlock(&stream->lock);
293 mutex_lock(&stream->lock);
294 stream->data_blk.condition = false;
295 stream->data_blk.ret_code = 0;
296 if (stream->status == STREAM_INIT &&
297 stream->prev != STREAM_UN_INIT &&
298 stream->need_draining != true) {
299 stream->prev = stream->status;
300 stream->status = STREAM_RUNNING;
301 if (stream->ops == STREAM_OPS_PLAYBACK) {
302 if (sst_play_frame(str_id) < 0) {
303 pr_warn("sst: play frames fail\n");
304 mutex_unlock(&stream->lock);
308 } else if (stream->ops == STREAM_OPS_CAPTURE) {
309 if (sst_capture_frame(str_id) < 0) {
310 pr_warn("sst: capture frame fail\n");
311 mutex_unlock(&stream->lock);
317 mutex_unlock(&stream->lock);
318 /* Block the call for reply */
319 if (!list_empty(&stream->bufs)) {
320 stream->data_blk.on = true;
321 retval = sst_wait_interruptible(sst_drv_ctx,
326 retval = stream->cumm_bytes;
327 pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval);
334 /*sets user data buffers to play/capture*/
335 static int intel_sst_play_capture(struct stream_info *stream, int str_id)
339 stream->data_blk.ret_code = 0;
340 stream->data_blk.on = true;
341 stream->data_blk.condition = false;
343 mutex_lock(&stream->lock);
344 if (stream->status == STREAM_INIT && stream->prev != STREAM_UN_INIT) {
345 /* stream is started */
346 stream->prev = stream->status;
347 stream->status = STREAM_RUNNING;
350 if (stream->status == STREAM_INIT && stream->prev == STREAM_UN_INIT) {
351 /* stream is not started yet */
352 pr_debug("sst: Stream isn't in started state %d, prev %d\n",
353 stream->status, stream->prev);
354 } else if ((stream->status == STREAM_RUNNING ||
355 stream->status == STREAM_PAUSED) &&
356 stream->need_draining != true) {
357 /* stream is started */
358 if (stream->ops == STREAM_OPS_PLAYBACK ||
359 stream->ops == STREAM_OPS_PLAYBACK_DRM) {
360 if (sst_play_frame(str_id) < 0) {
361 pr_warn("sst: play frames failed\n");
362 mutex_unlock(&stream->lock);
365 } else if (stream->ops == STREAM_OPS_CAPTURE) {
366 if (sst_capture_frame(str_id) < 0) {
367 pr_warn("sst: capture frames failed\n ");
368 mutex_unlock(&stream->lock);
373 mutex_unlock(&stream->lock);
376 mutex_unlock(&stream->lock);
377 /* Block the call for reply */
379 retval = sst_wait_interruptible(sst_drv_ctx, &stream->data_blk);
381 stream->status = STREAM_INIT;
382 pr_debug("sst: wait returned error...\n");
387 /* fills kernel list with buffer addresses for SST DSP driver to process*/
388 static int snd_sst_fill_kernel_list(struct stream_info *stream,
389 const struct iovec *iovec, unsigned long nr_segs,
390 struct list_head *copy_to_list)
392 struct sst_stream_bufs *stream_bufs;
393 unsigned long index, mmap_len;
394 unsigned char __user *bufp;
395 unsigned long size, copied_size;
396 int retval = 0, add_to_list = 0;
397 static int sent_offset;
398 static unsigned long sent_index;
400 stream_bufs = kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
403 stream_bufs->addr = sst_drv_ctx->mmap_mem;
404 #ifdef CONFIG_MRST_RAR_HANDLER
405 if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
406 for (index = stream->sg_index; index < nr_segs; index++) {
408 struct sst_stream_bufs *stream_bufs =
409 kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
411 stream->sg_index = index;
414 if (copy_from_user((void *) &rar_handle,
415 iovec[index].iov_base,
418 stream_bufs->addr = (char *)rar_handle;
419 stream_bufs->in_use = false;
420 stream_bufs->size = iovec[0].iov_len;
422 mutex_lock(&stream->lock);
423 list_add_tail(&stream_bufs->node, &stream->bufs);
424 mutex_unlock(&stream->lock);
426 stream->sg_index = index;
430 mmap_len = sst_drv_ctx->mmap_len;
431 stream_bufs->addr = sst_drv_ctx->mmap_mem;
432 bufp = stream->cur_ptr;
436 if (!stream->sg_index)
437 sent_index = sent_offset = 0;
439 for (index = stream->sg_index; index < nr_segs; index++) {
440 stream->sg_index = index;
441 if (!stream->cur_ptr)
442 bufp = iovec[index].iov_base;
444 size = ((unsigned long)iovec[index].iov_base
445 + iovec[index].iov_len) - (unsigned long) bufp;
447 if ((copied_size + size) > mmap_len)
448 size = mmap_len - copied_size;
451 if (stream->ops == STREAM_OPS_PLAYBACK) {
452 if (copy_from_user((void *)
453 (stream_bufs->addr + copied_size),
455 /* Clean up the list and return error code */
459 } else if (stream->ops == STREAM_OPS_CAPTURE) {
460 struct snd_sst_user_cap_list *entry =
461 kzalloc(sizeof(*entry), GFP_KERNEL);
467 entry->iov_index = index;
468 entry->iov_offset = (unsigned long) bufp -
469 (unsigned long)iovec[index].iov_base;
470 entry->offset = copied_size;
472 list_add_tail(&entry->node, copy_to_list);
475 stream->cur_ptr = bufp + size;
477 if (((unsigned long)iovec[index].iov_base
478 + iovec[index].iov_len) <
479 ((unsigned long)iovec[index].iov_base)) {
480 pr_debug("sst: Buffer overflows");
485 if (((unsigned long)iovec[index].iov_base
486 + iovec[index].iov_len) ==
487 (unsigned long)stream->cur_ptr) {
488 stream->cur_ptr = NULL;
493 pr_debug("sst: copied_size - %lx\n", copied_size);
494 if ((copied_size >= mmap_len) ||
495 (stream->sg_index == nr_segs)) {
500 stream_bufs->in_use = false;
501 stream_bufs->size = copied_size;
503 mutex_lock(&stream->lock);
504 list_add_tail(&stream_bufs->node, &stream->bufs);
505 mutex_unlock(&stream->lock);
512 /* This function copies the captured data returned from SST DSP engine
513 * to the user buffers*/
514 static int snd_sst_copy_userbuf_capture(struct stream_info *stream,
515 const struct iovec *iovec,
516 struct list_head *copy_to_list)
518 struct snd_sst_user_cap_list *entry, *_entry;
519 struct sst_stream_bufs *kbufs = NULL, *_kbufs;
522 /* copy sent buffers */
523 pr_debug("sst: capture stream copying to user now...\n");
524 list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
525 if (kbufs->in_use == true) {
527 list_for_each_entry_safe(entry, _entry,
528 copy_to_list, node) {
529 if (copy_to_user(iovec[entry->iov_index].iov_base + entry->iov_offset,
530 kbufs->addr + entry->offset,
532 /* Clean up the list and return error */
536 list_del(&entry->node);
541 pr_debug("sst: end of cap copy\n");
546 * snd_sst_userbufs_play_cap - constructs the list from user buffers
548 * @iovec:pointer to iovec structure
549 * @nr_segs:number entries in the iovec structure
551 * @stream:pointer to stream_info structure
553 * This function will traverse the user list and copy the data to the kernel
556 static int snd_sst_userbufs_play_cap(const struct iovec *iovec,
557 unsigned long nr_segs, unsigned int str_id,
558 struct stream_info *stream)
561 LIST_HEAD(copy_to_list);
564 retval = snd_sst_fill_kernel_list(stream, iovec, nr_segs,
567 retval = intel_sst_play_capture(stream, str_id);
571 if (stream->ops == STREAM_OPS_CAPTURE) {
572 retval = snd_sst_copy_userbuf_capture(stream, iovec,
578 /* This function is common function across read/write
579 for user buffers called from system calls*/
580 static int intel_sst_read_write(unsigned int str_id, char __user *buf,
584 struct stream_info *stream;
586 unsigned long nr_segs;
588 retval = sst_validate_strid(str_id);
591 stream = &sst_drv_ctx->streams[str_id];
592 if (stream->mmapped == true) {
593 pr_warn("sst: user write and stream is mapped");
598 stream->curr_bytes = 0;
599 stream->cumm_bytes = 0;
600 /* copy user buf details */
601 pr_debug("sst: new buffers %p, copy size %d, status %d\n" ,
602 buf, (int) count, (int) stream->status);
604 stream->buf_type = SST_BUF_USER_STATIC;
605 iovec.iov_base = buf;
606 iovec.iov_len = count;
610 retval = snd_sst_userbufs_play_cap(
611 &iovec, nr_segs, str_id, stream);
615 } while (stream->sg_index < nr_segs);
617 stream->sg_index = 0;
618 stream->cur_ptr = NULL;
620 retval = stream->cumm_bytes;
621 pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
626 * intel_sst_write - This function is called when user tries to play out data
628 * @file_ptr:pointer to file
629 * @buf:user buffer to be played out
630 * @count:size of tthe buffer
631 * @offset:offset to start from
633 * writes the encoded data into DSP
635 int intel_sst_write(struct file *file_ptr, const char __user *buf,
636 size_t count, loff_t *offset)
638 struct ioctl_pvt_data *data = file_ptr->private_data;
639 int str_id = data->str_id;
640 struct stream_info *stream = &sst_drv_ctx->streams[str_id];
642 pr_debug("sst: called for %d\n", str_id);
643 if (stream->status == STREAM_UN_INIT ||
644 stream->status == STREAM_DECODE) {
647 return intel_sst_read_write(str_id, (char __user *)buf, count);
651 * intel_sst_aio_write - write buffers
653 * @kiocb:pointer to a structure containing file pointer
654 * @iov:list of user buffer to be played out
655 * @nr_segs:number of entries
656 * @offset:offset to start from
658 * This function is called when user tries to play out multiple data buffers
660 ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov,
661 unsigned long nr_segs, loff_t offset)
664 struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
665 int str_id = data->str_id;
666 struct stream_info *stream;
668 pr_debug("sst: entry - %ld\n", nr_segs);
670 if (is_sync_kiocb(kiocb) == false)
673 pr_debug("sst: called for str_id %d\n", str_id);
674 retval = sst_validate_strid(str_id);
677 stream = &sst_drv_ctx->streams[str_id];
678 if (stream->mmapped == true)
680 if (stream->status == STREAM_UN_INIT ||
681 stream->status == STREAM_DECODE) {
684 stream->curr_bytes = 0;
685 stream->cumm_bytes = 0;
686 pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
687 nr_segs, (int) offset, (int) stream->status);
688 stream->buf_type = SST_BUF_USER_STATIC;
690 retval = snd_sst_userbufs_play_cap(iov, nr_segs,
695 } while (stream->sg_index < nr_segs);
697 stream->sg_index = 0;
698 stream->cur_ptr = NULL;
700 retval = stream->cumm_bytes;
701 pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
706 * intel_sst_read - read the encoded data
708 * @file_ptr: pointer to file
709 * @buf: user buffer to be filled with captured data
710 * @count: size of tthe buffer
711 * @offset: offset to start from
713 * This function is called when user tries to capture data
715 int intel_sst_read(struct file *file_ptr, char __user *buf,
716 size_t count, loff_t *offset)
718 struct ioctl_pvt_data *data = file_ptr->private_data;
719 int str_id = data->str_id;
720 struct stream_info *stream = &sst_drv_ctx->streams[str_id];
722 pr_debug("sst: called for %d\n", str_id);
723 if (stream->status == STREAM_UN_INIT ||
724 stream->status == STREAM_DECODE)
726 return intel_sst_read_write(str_id, buf, count);
730 * intel_sst_aio_read - aio read
732 * @kiocb: pointer to a structure containing file pointer
733 * @iov: list of user buffer to be filled with captured
734 * @nr_segs: number of entries
735 * @offset: offset to start from
737 * This function is called when user tries to capture out multiple data buffers
739 ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov,
740 unsigned long nr_segs, loff_t offset)
743 struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
744 int str_id = data->str_id;
745 struct stream_info *stream;
747 pr_debug("sst: entry - %ld\n", nr_segs);
749 if (is_sync_kiocb(kiocb) == false) {
750 pr_debug("sst: aio_read from user space is not allowed\n");
754 pr_debug("sst: called for str_id %d\n", str_id);
755 retval = sst_validate_strid(str_id);
758 stream = &sst_drv_ctx->streams[str_id];
759 if (stream->mmapped == true)
761 if (stream->status == STREAM_UN_INIT ||
762 stream->status == STREAM_DECODE)
764 stream->curr_bytes = 0;
765 stream->cumm_bytes = 0;
767 pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
768 nr_segs, (int) offset, (int) stream->status);
769 stream->buf_type = SST_BUF_USER_STATIC;
771 retval = snd_sst_userbufs_play_cap(iov, nr_segs,
776 } while (stream->sg_index < nr_segs);
778 stream->sg_index = 0;
779 stream->cur_ptr = NULL;
781 retval = stream->cumm_bytes;
782 pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
786 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
787 static void sst_print_stream_params(struct snd_sst_get_stream_params *get_prm)
789 pr_debug("sst: codec params:result =%d\n",
790 get_prm->codec_params.result);
791 pr_debug("sst: codec params:stream = %d\n",
792 get_prm->codec_params.stream_id);
793 pr_debug("sst: codec params:codec = %d\n",
794 get_prm->codec_params.codec);
795 pr_debug("sst: codec params:ops = %d\n",
796 get_prm->codec_params.ops);
797 pr_debug("sst: codec params:stream_type= %d\n",
798 get_prm->codec_params.stream_type);
799 pr_debug("sst: pcmparams:sfreq= %d\n",
800 get_prm->pcm_params.sfreq);
801 pr_debug("sst: pcmparams:num_chan= %d\n",
802 get_prm->pcm_params.num_chan);
803 pr_debug("sst: pcmparams:pcm_wd_sz= %d\n",
804 get_prm->pcm_params.pcm_wd_sz);
809 * intel_sst_ioctl - recieves the device ioctl's
810 * @file_ptr:pointer to file
814 * This function is called by OS when a user space component
815 * sends an Ioctl to SST driver
817 long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
820 struct ioctl_pvt_data *data = NULL;
821 int str_id = 0, minor = 0;
823 data = file_ptr->private_data;
826 str_id = data->str_id;
830 if (sst_drv_ctx->sst_state != SST_FW_RUNNING)
833 switch (_IOC_NR(cmd)) {
834 case _IOC_NR(SNDRV_SST_STREAM_PAUSE):
835 pr_debug("sst: IOCTL_PAUSE recieved for %d!\n", str_id);
836 if (minor != STREAM_MODULE) {
840 retval = sst_pause_stream(str_id);
843 case _IOC_NR(SNDRV_SST_STREAM_RESUME):
844 pr_debug("sst: SNDRV_SST_IOCTL_RESUME recieved!\n");
845 if (minor != STREAM_MODULE) {
849 retval = sst_resume_stream(str_id);
852 case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): {
853 struct snd_sst_params str_param;
855 pr_debug("sst: IOCTL_SET_PARAMS recieved!\n");
856 if (minor != STREAM_MODULE) {
861 if (copy_from_user(&str_param, (void __user *)arg,
862 sizeof(str_param))) {
869 retval = sst_get_stream(&str_param);
871 struct stream_info *str_info;
874 sst_drv_ctx->stream_cnt++;
875 data->str_id = retval;
876 str_info = &sst_drv_ctx->streams[retval];
877 str_info->src = SST_DRV;
878 dest = (char __user *)arg + offsetof(struct snd_sst_params, stream_id);
879 retval = copy_to_user(dest, &retval, sizeof(__u32));
883 if (retval == -SST_ERR_INVALID_PARAMS)
887 pr_debug("sst: SET_STREAM_PARAMS recieved!\n");
888 /* allocated set params only */
889 retval = sst_set_stream_param(str_id, &str_param);
890 /* Block the call for reply */
892 int sfreq = 0, word_size = 0, num_channel = 0;
893 sfreq = str_param.sparams.uc.pcm_params.sfreq;
894 word_size = str_param.sparams.uc.pcm_params.pcm_wd_sz;
895 num_channel = str_param.sparams.uc.pcm_params.num_chan;
896 if (str_param.ops == STREAM_OPS_CAPTURE) {
897 sst_drv_ctx->scard_ops->\
898 set_pcm_audio_params(sfreq,
899 word_size, num_channel);
905 case _IOC_NR(SNDRV_SST_SET_VOL): {
906 struct snd_sst_vol set_vol;
908 if (copy_from_user(&set_vol, (void __user *)arg,
910 pr_debug("sst: copy failed\n");
914 pr_debug("sst: SET_VOLUME recieved for %d!\n",
916 if (minor == STREAM_MODULE && set_vol.stream_id == 0) {
917 pr_debug("sst: invalid operation!\n");
921 retval = sst_set_vol(&set_vol);
924 case _IOC_NR(SNDRV_SST_GET_VOL): {
925 struct snd_sst_vol get_vol;
927 if (copy_from_user(&get_vol, (void __user *)arg,
932 pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
934 if (minor == STREAM_MODULE && get_vol.stream_id == 0) {
935 pr_debug("sst: invalid operation!\n");
939 retval = sst_get_vol(&get_vol);
944 pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
945 get_vol.stream_id, get_vol.volume,
946 get_vol.ramp_duration, get_vol.ramp_type);
947 if (copy_to_user((struct snd_sst_vol __user *)arg,
948 &get_vol, sizeof(get_vol))) {
952 /*sst_print_get_vol_info(str_id, &get_vol);*/
956 case _IOC_NR(SNDRV_SST_MUTE): {
957 struct snd_sst_mute set_mute;
959 if (copy_from_user(&set_mute, (void __user *)arg,
964 pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
966 if (minor == STREAM_MODULE && set_mute.stream_id == 0) {
970 retval = sst_set_mute(&set_mute);
973 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {
974 struct snd_sst_get_stream_params get_params;
976 pr_debug("sst: IOCTL_GET_PARAMS recieved!\n");
982 retval = sst_get_stream_params(str_id, &get_params);
987 if (copy_to_user((struct snd_sst_get_stream_params __user *)arg,
988 &get_params, sizeof(get_params))) {
992 sst_print_stream_params(&get_params);
996 case _IOC_NR(SNDRV_SST_MMAP_PLAY):
997 case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): {
998 struct snd_sst_mmap_buffs mmap_buf;
1000 pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
1001 if (minor != STREAM_MODULE) {
1005 if (copy_from_user(&mmap_buf, (void __user *)arg,
1006 sizeof(mmap_buf))) {
1010 retval = intel_sst_mmap_play_capture(str_id, &mmap_buf);
1013 case _IOC_NR(SNDRV_SST_STREAM_DROP):
1014 pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n");
1015 if (minor != STREAM_MODULE) {
1019 retval = sst_drop_stream(str_id);
1022 case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): {
1023 struct snd_sst_tstamp tstamp = {0};
1024 unsigned long long time, freq, mod;
1026 pr_debug("sst: SNDRV_SST_STREAM_GET_TSTAMP recieved!\n");
1027 if (minor != STREAM_MODULE) {
1031 memcpy_fromio(&tstamp,
1032 sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
1034 time = tstamp.samples_rendered;
1035 freq = (unsigned long long) tstamp.sampling_frequency;
1036 time = time * 1000; /* converting it to ms */
1037 mod = do_div(time, freq);
1038 if (copy_to_user((void __user *)arg, &time,
1039 sizeof(unsigned long long)))
1044 case _IOC_NR(SNDRV_SST_STREAM_START):{
1045 struct stream_info *stream;
1047 pr_debug("sst: SNDRV_SST_STREAM_START recieved!\n");
1048 if (minor != STREAM_MODULE) {
1052 retval = sst_validate_strid(str_id);
1055 stream = &sst_drv_ctx->streams[str_id];
1056 mutex_lock(&stream->lock);
1057 if (stream->status == STREAM_INIT &&
1058 stream->need_draining != true) {
1059 stream->prev = stream->status;
1060 stream->status = STREAM_RUNNING;
1061 if (stream->ops == STREAM_OPS_PLAYBACK ||
1062 stream->ops == STREAM_OPS_PLAYBACK_DRM) {
1063 retval = sst_play_frame(str_id);
1064 } else if (stream->ops == STREAM_OPS_CAPTURE)
1065 retval = sst_capture_frame(str_id);
1068 mutex_unlock(&stream->lock);
1072 stream->status = STREAM_INIT;
1073 mutex_unlock(&stream->lock);
1079 mutex_unlock(&stream->lock);
1083 case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): {
1084 struct snd_sst_target_device target_device;
1086 pr_debug("sst: SET_TARGET_DEVICE recieved!\n");
1087 if (copy_from_user(&target_device, (void __user *)arg,
1088 sizeof(target_device))) {
1092 if (minor != AM_MODULE) {
1096 retval = sst_target_device_select(&target_device);
1100 case _IOC_NR(SNDRV_SST_DRIVER_INFO): {
1101 struct snd_sst_driver_info info;
1103 pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n");
1104 info.version = SST_VERSION_NUM;
1105 /* hard coding, shud get sumhow later */
1106 info.active_pcm_streams = sst_drv_ctx->stream_cnt -
1107 sst_drv_ctx->encoded_cnt;
1108 info.active_enc_streams = sst_drv_ctx->encoded_cnt;
1109 info.max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM;
1110 info.max_enc_streams = MAX_ENC_STREAM;
1111 info.buf_per_stream = sst_drv_ctx->mmap_len;
1112 if (copy_to_user((void __user *)arg, &info,
1118 case _IOC_NR(SNDRV_SST_STREAM_DECODE): {
1119 struct snd_sst_dbufs param;
1120 struct snd_sst_dbufs dbufs_local;
1121 struct snd_sst_buffs ibufs, obufs;
1122 struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp;
1125 pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n");
1126 if (minor != STREAM_MODULE) {
1130 if (copy_from_user(¶m, (void __user *)arg,
1136 dbufs_local.input_bytes_consumed = param.input_bytes_consumed;
1137 dbufs_local.output_bytes_produced =
1138 param.output_bytes_produced;
1140 if (copy_from_user(&ibufs, (void __user *)param.ibufs, sizeof(ibufs))) {
1144 if (copy_from_user(&obufs, (void __user *)param.obufs, sizeof(obufs))) {
1149 ibuf_tmp = kcalloc(ibufs.entries, sizeof(*ibuf_tmp), GFP_KERNEL);
1150 obuf_tmp = kcalloc(obufs.entries, sizeof(*obuf_tmp), GFP_KERNEL);
1151 if (!ibuf_tmp || !obuf_tmp) {
1156 if (copy_from_user(ibuf_tmp, (void __user *)ibufs.buff_entry,
1157 ibufs.entries * sizeof(*ibuf_tmp))) {
1161 ibufs.buff_entry = ibuf_tmp;
1162 dbufs_local.ibufs = &ibufs;
1164 if (copy_from_user(obuf_tmp, (void __user *)obufs.buff_entry,
1165 obufs.entries * sizeof(*obuf_tmp))) {
1169 obufs.buff_entry = obuf_tmp;
1170 dbufs_local.obufs = &obufs;
1172 retval = sst_decode(str_id, &dbufs_local);
1178 dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
1179 if (copy_to_user(dest,
1180 &dbufs_local.input_bytes_consumed,
1181 sizeof(unsigned long long))) {
1186 dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
1187 if (copy_to_user(dest,
1188 &dbufs_local.output_bytes_produced,
1189 sizeof(unsigned long long))) {
1199 case _IOC_NR(SNDRV_SST_STREAM_DRAIN):
1200 pr_debug("sst: SNDRV_SST_STREAM_DRAIN recived\n");
1201 if (minor != STREAM_MODULE) {
1205 retval = sst_drain_stream(str_id);
1208 case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED): {
1209 unsigned long long __user *bytes = (unsigned long long __user *)arg;
1210 struct snd_sst_tstamp tstamp = {0};
1212 pr_debug("sst: STREAM_BYTES_DECODED recieved!\n");
1213 if (minor != STREAM_MODULE) {
1217 memcpy_fromio(&tstamp,
1218 sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
1220 if (copy_to_user(bytes, &tstamp.bytes_processed,
1225 case _IOC_NR(SNDRV_SST_FW_INFO): {
1226 struct snd_sst_fw_info *fw_info;
1228 pr_debug("sst: SNDRV_SST_FW_INFO recived\n");
1230 fw_info = kzalloc(sizeof(*fw_info), GFP_ATOMIC);
1235 retval = sst_get_fw_info(fw_info);
1241 if (copy_to_user((struct snd_sst_dbufs __user *)arg,
1242 fw_info, sizeof(*fw_info))) {
1247 /*sst_print_fw_info(fw_info);*/
1254 pr_debug("sst: intel_sst_ioctl:complete ret code = %d\n", retval);