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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32 #include <linux/pci.h>
34 #include <linux/uio.h>
35 #include <linux/aio.h>
36 #include <linux/uaccess.h>
37 #include <linux/firmware.h>
38 #include <linux/pm_runtime.h>
39 #include <linux/ioctl.h>
40 #ifdef CONFIG_MRST_RAR_HANDLER
41 #include <linux/rar_register.h>
42 #include "../../../drivers/staging/memrar/memrar.h"
44 #include "intel_sst.h"
45 #include "intel_sst_ioctl.h"
46 #include "intel_sst_fw_ipc.h"
47 #include "intel_sst_common.h"
50 #define STREAM_MODULE 0
54 * intel_sst_check_device - checks SST device
56 * This utility function checks the state of SST device and downlaods FW if
57 * not done, or resumes the device if suspended
60 static int intel_sst_check_device(void)
63 if (sst_drv_ctx
->pmic_state
!= SND_MAD_INIT_DONE
) {
64 pr_warn("Sound card not available\n");
67 if (sst_drv_ctx
->sst_state
== SST_SUSPENDED
) {
68 pr_debug("Resuming from Suspended state\n");
69 retval
= intel_sst_resume(sst_drv_ctx
->pci
);
71 pr_debug("Resume Failed= %#x,abort\n", retval
);
76 if (sst_drv_ctx
->sst_state
== SST_UN_INIT
) {
77 /* FW is not downloaded */
78 retval
= sst_download_fw();
81 if (sst_drv_ctx
->pci_id
== SST_MRST_PCI_ID
) {
82 retval
= sst_drv_ctx
->rx_time_slot_status
;
83 if (retval
!= RX_TIMESLOT_UNINIT
84 && sst_drv_ctx
->pmic_vendor
!= SND_NC
)
85 sst_enable_rx_timeslot(retval
);
92 * intel_sst_open - opens a handle to driver
94 * @i_node: inode structure
95 * @file_ptr:pointer to file
97 * This function is called by OS when a user space component
98 * tries to get a driver handle. Only one handle at a time
101 int intel_sst_open(struct inode
*i_node
, struct file
*file_ptr
)
105 mutex_lock(&sst_drv_ctx
->stream_lock
);
106 pm_runtime_get_sync(&sst_drv_ctx
->pci
->dev
);
107 retval
= intel_sst_check_device();
109 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
110 mutex_unlock(&sst_drv_ctx
->stream_lock
);
114 if (sst_drv_ctx
->encoded_cnt
< MAX_ENC_STREAM
) {
115 struct ioctl_pvt_data
*data
=
116 kzalloc(sizeof(struct ioctl_pvt_data
), GFP_KERNEL
);
118 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
119 mutex_unlock(&sst_drv_ctx
->stream_lock
);
123 sst_drv_ctx
->encoded_cnt
++;
124 mutex_unlock(&sst_drv_ctx
->stream_lock
);
125 data
->pvt_id
= sst_assign_pvt_id(sst_drv_ctx
);
127 file_ptr
->private_data
= (void *)data
;
128 pr_debug("pvt_id handle = %d!\n", data
->pvt_id
);
131 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
132 mutex_unlock(&sst_drv_ctx
->stream_lock
);
138 * intel_sst_open_cntrl - opens a handle to driver
140 * @i_node: inode structure
141 * @file_ptr:pointer to file
143 * This function is called by OS when a user space component
144 * tries to get a driver handle to /dev/intel_sst_control.
145 * Only one handle at a time will be allowed
146 * This is for control operations only
148 int intel_sst_open_cntrl(struct inode
*i_node
, struct file
*file_ptr
)
152 /* audio manager open */
153 mutex_lock(&sst_drv_ctx
->stream_lock
);
154 pm_runtime_get_sync(&sst_drv_ctx
->pci
->dev
);
155 retval
= intel_sst_check_device();
157 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
158 mutex_unlock(&sst_drv_ctx
->stream_lock
);
162 if (sst_drv_ctx
->am_cnt
< MAX_AM_HANDLES
) {
163 sst_drv_ctx
->am_cnt
++;
164 pr_debug("AM handle opened...\n");
165 file_ptr
->private_data
= NULL
;
168 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
171 mutex_unlock(&sst_drv_ctx
->stream_lock
);
176 * intel_sst_release - releases a handle to driver
178 * @i_node: inode structure
179 * @file_ptr: pointer to file
181 * This function is called by OS when a user space component
182 * tries to release a driver handle.
184 int intel_sst_release(struct inode
*i_node
, struct file
*file_ptr
)
186 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
188 pr_debug("Release called, closing app handle\n");
189 mutex_lock(&sst_drv_ctx
->stream_lock
);
190 sst_drv_ctx
->encoded_cnt
--;
191 sst_drv_ctx
->stream_cnt
--;
192 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
193 mutex_unlock(&sst_drv_ctx
->stream_lock
);
194 free_stream_context(data
->str_id
);
199 int intel_sst_release_cntrl(struct inode
*i_node
, struct file
*file_ptr
)
201 /* audio manager close */
202 mutex_lock(&sst_drv_ctx
->stream_lock
);
203 sst_drv_ctx
->am_cnt
--;
204 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
205 mutex_unlock(&sst_drv_ctx
->stream_lock
);
206 pr_debug("AM handle closed\n");
211 * intel_sst_mmap - mmaps a kernel buffer to user space for copying data
213 * @vma: vm area structure instance
214 * @file_ptr: pointer to file
216 * This function is called by OS when a user space component
217 * tries to get mmap memory from driver
219 int intel_sst_mmap(struct file
*file_ptr
, struct vm_area_struct
*vma
)
222 struct ioctl_pvt_data
*data
=
223 (struct ioctl_pvt_data
*)file_ptr
->private_data
;
224 int str_id
= data
->str_id
;
227 retval
= sst_validate_strid(str_id
);
231 length
= vma
->vm_end
- vma
->vm_start
;
232 pr_debug("called for stream %d length 0x%x\n", str_id
, length
);
234 if (length
> sst_drv_ctx
->mmap_len
)
236 if (!sst_drv_ctx
->mmap_mem
)
239 /* round it up to the page bondary */
240 /*mem_area = (void *)((((unsigned long)sst_drv_ctx->mmap_mem)
241 + PAGE_SIZE - 1) & PAGE_MASK);*/
242 mem_area
= (void *) PAGE_ALIGN((unsigned int) sst_drv_ctx
->mmap_mem
);
244 /* map the whole physically contiguous area in one piece */
245 retval
= remap_pfn_range(vma
,
247 virt_to_phys((void *)mem_area
) >> PAGE_SHIFT
,
251 sst_drv_ctx
->streams
[str_id
].mmapped
= false;
253 sst_drv_ctx
->streams
[str_id
].mmapped
= true;
255 pr_debug("mmap ret 0x%x\n", retval
);
259 /* sets mmap data buffers to play/capture*/
260 static int intel_sst_mmap_play_capture(u32 str_id
,
261 struct snd_sst_mmap_buffs
*mmap_buf
)
263 struct sst_stream_bufs
*bufs
;
265 struct stream_info
*stream
;
266 struct snd_sst_mmap_buff_entry
*buf_entry
;
267 struct snd_sst_mmap_buff_entry
*tmp_buf
;
269 pr_debug("called for str_id %d\n", str_id
);
270 retval
= sst_validate_strid(str_id
);
274 stream
= &sst_drv_ctx
->streams
[str_id
];
275 if (stream
->mmapped
!= true)
278 if (stream
->status
== STREAM_UN_INIT
||
279 stream
->status
== STREAM_DECODE
) {
282 stream
->curr_bytes
= 0;
283 stream
->cumm_bytes
= 0;
285 tmp_buf
= kcalloc(mmap_buf
->entries
, sizeof(*tmp_buf
), GFP_KERNEL
);
288 if (copy_from_user(tmp_buf
, (void __user
*)mmap_buf
->buff
,
289 mmap_buf
->entries
* sizeof(*tmp_buf
))) {
294 pr_debug("new buffers count %d status %d\n",
295 mmap_buf
->entries
, stream
->status
);
297 for (i
= 0; i
< mmap_buf
->entries
; i
++) {
298 bufs
= kzalloc(sizeof(*bufs
), GFP_KERNEL
);
303 bufs
->size
= buf_entry
->size
;
304 bufs
->offset
= buf_entry
->offset
;
305 bufs
->addr
= sst_drv_ctx
->mmap_mem
;
306 bufs
->in_use
= false;
309 mutex_lock(&stream
->lock
);
310 list_add_tail(&bufs
->node
, &stream
->bufs
);
311 mutex_unlock(&stream
->lock
);
314 mutex_lock(&stream
->lock
);
315 stream
->data_blk
.condition
= false;
316 stream
->data_blk
.ret_code
= 0;
317 if (stream
->status
== STREAM_INIT
&&
318 stream
->prev
!= STREAM_UN_INIT
&&
319 stream
->need_draining
!= true) {
320 stream
->prev
= stream
->status
;
321 stream
->status
= STREAM_RUNNING
;
322 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
323 if (sst_play_frame(str_id
) < 0) {
324 pr_warn("play frames fail\n");
325 mutex_unlock(&stream
->lock
);
329 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
330 if (sst_capture_frame(str_id
) < 0) {
331 pr_warn("capture frame fail\n");
332 mutex_unlock(&stream
->lock
);
338 mutex_unlock(&stream
->lock
);
339 /* Block the call for reply */
340 if (!list_empty(&stream
->bufs
)) {
341 stream
->data_blk
.on
= true;
342 retval
= sst_wait_interruptible(sst_drv_ctx
,
347 retval
= stream
->cumm_bytes
;
348 pr_debug("end of play/rec ioctl bytes = %d!!\n", retval
);
355 /*sets user data buffers to play/capture*/
356 static int intel_sst_play_capture(struct stream_info
*stream
, int str_id
)
360 stream
->data_blk
.ret_code
= 0;
361 stream
->data_blk
.on
= true;
362 stream
->data_blk
.condition
= false;
364 mutex_lock(&stream
->lock
);
365 if (stream
->status
== STREAM_INIT
&& stream
->prev
!= STREAM_UN_INIT
) {
366 /* stream is started */
367 stream
->prev
= stream
->status
;
368 stream
->status
= STREAM_RUNNING
;
371 if (stream
->status
== STREAM_INIT
&& stream
->prev
== STREAM_UN_INIT
) {
372 /* stream is not started yet */
373 pr_debug("Stream isn't in started state %d, prev %d\n",
374 stream
->status
, stream
->prev
);
375 } else if ((stream
->status
== STREAM_RUNNING
||
376 stream
->status
== STREAM_PAUSED
) &&
377 stream
->need_draining
!= true) {
378 /* stream is started */
379 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
380 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
381 if (sst_play_frame(str_id
) < 0) {
382 pr_warn("play frames failed\n");
383 mutex_unlock(&stream
->lock
);
386 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
387 if (sst_capture_frame(str_id
) < 0) {
388 pr_warn("capture frames failed\n");
389 mutex_unlock(&stream
->lock
);
394 mutex_unlock(&stream
->lock
);
397 mutex_unlock(&stream
->lock
);
398 /* Block the call for reply */
400 retval
= sst_wait_interruptible(sst_drv_ctx
, &stream
->data_blk
);
402 stream
->status
= STREAM_INIT
;
403 pr_debug("wait returned error...\n");
408 /* fills kernel list with buffer addresses for SST DSP driver to process*/
409 static int snd_sst_fill_kernel_list(struct stream_info
*stream
,
410 const struct iovec
*iovec
, unsigned long nr_segs
,
411 struct list_head
*copy_to_list
)
413 struct sst_stream_bufs
*stream_bufs
;
414 unsigned long index
, mmap_len
;
415 unsigned char __user
*bufp
;
416 unsigned long size
, copied_size
;
417 int retval
= 0, add_to_list
= 0;
418 static int sent_offset
;
419 static unsigned long sent_index
;
421 stream_bufs
= kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
424 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
425 #ifdef CONFIG_MRST_RAR_HANDLER
426 if (stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
427 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
429 struct sst_stream_bufs
*stream_bufs
=
430 kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
432 stream
->sg_index
= index
;
435 if (copy_from_user((void *) &rar_handle
,
436 iovec
[index
].iov_base
,
439 stream_bufs
->addr
= (char *)rar_handle
;
440 stream_bufs
->in_use
= false;
441 stream_bufs
->size
= iovec
[0].iov_len
;
443 mutex_lock(&stream
->lock
);
444 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
445 mutex_unlock(&stream
->lock
);
447 stream
->sg_index
= index
;
451 mmap_len
= sst_drv_ctx
->mmap_len
;
452 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
453 bufp
= stream
->cur_ptr
;
457 if (!stream
->sg_index
)
458 sent_index
= sent_offset
= 0;
460 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
461 stream
->sg_index
= index
;
462 if (!stream
->cur_ptr
)
463 bufp
= iovec
[index
].iov_base
;
465 size
= ((unsigned long)iovec
[index
].iov_base
466 + iovec
[index
].iov_len
) - (unsigned long) bufp
;
468 if ((copied_size
+ size
) > mmap_len
)
469 size
= mmap_len
- copied_size
;
472 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
473 if (copy_from_user((void *)
474 (stream_bufs
->addr
+ copied_size
),
476 /* Clean up the list and return error code */
480 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
481 struct snd_sst_user_cap_list
*entry
=
482 kzalloc(sizeof(*entry
), GFP_KERNEL
);
488 entry
->iov_index
= index
;
489 entry
->iov_offset
= (unsigned long) bufp
-
490 (unsigned long)iovec
[index
].iov_base
;
491 entry
->offset
= copied_size
;
493 list_add_tail(&entry
->node
, copy_to_list
);
496 stream
->cur_ptr
= bufp
+ size
;
498 if (((unsigned long)iovec
[index
].iov_base
499 + iovec
[index
].iov_len
) <
500 ((unsigned long)iovec
[index
].iov_base
)) {
501 pr_debug("Buffer overflows\n");
506 if (((unsigned long)iovec
[index
].iov_base
507 + iovec
[index
].iov_len
) ==
508 (unsigned long)stream
->cur_ptr
) {
509 stream
->cur_ptr
= NULL
;
514 pr_debug("copied_size - %lx\n", copied_size
);
515 if ((copied_size
>= mmap_len
) ||
516 (stream
->sg_index
== nr_segs
)) {
521 stream_bufs
->in_use
= false;
522 stream_bufs
->size
= copied_size
;
524 mutex_lock(&stream
->lock
);
525 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
526 mutex_unlock(&stream
->lock
);
533 /* This function copies the captured data returned from SST DSP engine
534 * to the user buffers*/
535 static int snd_sst_copy_userbuf_capture(struct stream_info
*stream
,
536 const struct iovec
*iovec
,
537 struct list_head
*copy_to_list
)
539 struct snd_sst_user_cap_list
*entry
, *_entry
;
540 struct sst_stream_bufs
*kbufs
= NULL
, *_kbufs
;
543 /* copy sent buffers */
544 pr_debug("capture stream copying to user now...\n");
545 list_for_each_entry_safe(kbufs
, _kbufs
, &stream
->bufs
, node
) {
546 if (kbufs
->in_use
== true) {
548 list_for_each_entry_safe(entry
, _entry
,
549 copy_to_list
, node
) {
550 if (copy_to_user(iovec
[entry
->iov_index
].iov_base
+ entry
->iov_offset
,
551 kbufs
->addr
+ entry
->offset
,
553 /* Clean up the list and return error */
557 list_del(&entry
->node
);
562 pr_debug("end of cap copy\n");
567 * snd_sst_userbufs_play_cap - constructs the list from user buffers
569 * @iovec:pointer to iovec structure
570 * @nr_segs:number entries in the iovec structure
572 * @stream:pointer to stream_info structure
574 * This function will traverse the user list and copy the data to the kernel
577 static int snd_sst_userbufs_play_cap(const struct iovec
*iovec
,
578 unsigned long nr_segs
, unsigned int str_id
,
579 struct stream_info
*stream
)
582 LIST_HEAD(copy_to_list
);
585 retval
= snd_sst_fill_kernel_list(stream
, iovec
, nr_segs
,
588 retval
= intel_sst_play_capture(stream
, str_id
);
592 if (stream
->ops
== STREAM_OPS_CAPTURE
) {
593 retval
= snd_sst_copy_userbuf_capture(stream
, iovec
,
599 /* This function is common function across read/write
600 for user buffers called from system calls*/
601 static int intel_sst_read_write(unsigned int str_id
, char __user
*buf
,
605 struct stream_info
*stream
;
607 unsigned long nr_segs
;
609 retval
= sst_validate_strid(str_id
);
612 stream
= &sst_drv_ctx
->streams
[str_id
];
613 if (stream
->mmapped
== true) {
614 pr_warn("user write and stream is mapped\n");
619 stream
->curr_bytes
= 0;
620 stream
->cumm_bytes
= 0;
621 /* copy user buf details */
622 pr_debug("new buffers %p, copy size %d, status %d\n" ,
623 buf
, (int) count
, (int) stream
->status
);
625 stream
->buf_type
= SST_BUF_USER_STATIC
;
626 iovec
.iov_base
= buf
;
627 iovec
.iov_len
= count
;
631 retval
= snd_sst_userbufs_play_cap(
632 &iovec
, nr_segs
, str_id
, stream
);
636 } while (stream
->sg_index
< nr_segs
);
638 stream
->sg_index
= 0;
639 stream
->cur_ptr
= NULL
;
641 retval
= stream
->cumm_bytes
;
642 pr_debug("end of play/rec bytes = %d!!\n", retval
);
647 * intel_sst_write - This function is called when user tries to play out data
649 * @file_ptr:pointer to file
650 * @buf:user buffer to be played out
651 * @count:size of tthe buffer
652 * @offset:offset to start from
654 * writes the encoded data into DSP
656 int intel_sst_write(struct file
*file_ptr
, const char __user
*buf
,
657 size_t count
, loff_t
*offset
)
659 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
660 int str_id
= data
->str_id
;
661 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
663 pr_debug("called for %d\n", str_id
);
664 if (stream
->status
== STREAM_UN_INIT
||
665 stream
->status
== STREAM_DECODE
) {
668 return intel_sst_read_write(str_id
, (char __user
*)buf
, count
);
672 * intel_sst_aio_write - write buffers
674 * @kiocb:pointer to a structure containing file pointer
675 * @iov:list of user buffer to be played out
676 * @nr_segs:number of entries
677 * @offset:offset to start from
679 * This function is called when user tries to play out multiple data buffers
681 ssize_t
intel_sst_aio_write(struct kiocb
*kiocb
, const struct iovec
*iov
,
682 unsigned long nr_segs
, loff_t offset
)
685 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
686 int str_id
= data
->str_id
;
687 struct stream_info
*stream
;
689 pr_debug("entry - %ld\n", nr_segs
);
691 if (is_sync_kiocb(kiocb
) == false)
694 pr_debug("called for str_id %d\n", str_id
);
695 retval
= sst_validate_strid(str_id
);
698 stream
= &sst_drv_ctx
->streams
[str_id
];
699 if (stream
->mmapped
== true)
701 if (stream
->status
== STREAM_UN_INIT
||
702 stream
->status
== STREAM_DECODE
) {
705 stream
->curr_bytes
= 0;
706 stream
->cumm_bytes
= 0;
707 pr_debug("new segs %ld, offset %d, status %d\n" ,
708 nr_segs
, (int) offset
, (int) stream
->status
);
709 stream
->buf_type
= SST_BUF_USER_STATIC
;
711 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
716 } while (stream
->sg_index
< nr_segs
);
718 stream
->sg_index
= 0;
719 stream
->cur_ptr
= NULL
;
721 retval
= stream
->cumm_bytes
;
722 pr_debug("end of play/rec bytes = %d!!\n", retval
);
727 * intel_sst_read - read the encoded data
729 * @file_ptr: pointer to file
730 * @buf: user buffer to be filled with captured data
731 * @count: size of tthe buffer
732 * @offset: offset to start from
734 * This function is called when user tries to capture data
736 int intel_sst_read(struct file
*file_ptr
, char __user
*buf
,
737 size_t count
, loff_t
*offset
)
739 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
740 int str_id
= data
->str_id
;
741 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
743 pr_debug("called for %d\n", str_id
);
744 if (stream
->status
== STREAM_UN_INIT
||
745 stream
->status
== STREAM_DECODE
)
747 return intel_sst_read_write(str_id
, buf
, count
);
751 * intel_sst_aio_read - aio read
753 * @kiocb: pointer to a structure containing file pointer
754 * @iov: list of user buffer to be filled with captured
755 * @nr_segs: number of entries
756 * @offset: offset to start from
758 * This function is called when user tries to capture out multiple data buffers
760 ssize_t
intel_sst_aio_read(struct kiocb
*kiocb
, const struct iovec
*iov
,
761 unsigned long nr_segs
, loff_t offset
)
764 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
765 int str_id
= data
->str_id
;
766 struct stream_info
*stream
;
768 pr_debug("entry - %ld\n", nr_segs
);
770 if (is_sync_kiocb(kiocb
) == false) {
771 pr_debug("aio_read from user space is not allowed\n");
775 pr_debug("called for str_id %d\n", str_id
);
776 retval
= sst_validate_strid(str_id
);
779 stream
= &sst_drv_ctx
->streams
[str_id
];
780 if (stream
->mmapped
== true)
782 if (stream
->status
== STREAM_UN_INIT
||
783 stream
->status
== STREAM_DECODE
)
785 stream
->curr_bytes
= 0;
786 stream
->cumm_bytes
= 0;
788 pr_debug("new segs %ld, offset %d, status %d\n" ,
789 nr_segs
, (int) offset
, (int) stream
->status
);
790 stream
->buf_type
= SST_BUF_USER_STATIC
;
792 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
797 } while (stream
->sg_index
< nr_segs
);
799 stream
->sg_index
= 0;
800 stream
->cur_ptr
= NULL
;
802 retval
= stream
->cumm_bytes
;
803 pr_debug("end of play/rec bytes = %d!!\n", retval
);
807 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
808 static void sst_print_stream_params(struct snd_sst_get_stream_params
*get_prm
)
810 pr_debug("codec params:result = %d\n",
811 get_prm
->codec_params
.result
);
812 pr_debug("codec params:stream = %d\n",
813 get_prm
->codec_params
.stream_id
);
814 pr_debug("codec params:codec = %d\n",
815 get_prm
->codec_params
.codec
);
816 pr_debug("codec params:ops = %d\n",
817 get_prm
->codec_params
.ops
);
818 pr_debug("codec params:stream_type = %d\n",
819 get_prm
->codec_params
.stream_type
);
820 pr_debug("pcmparams:sfreq = %d\n",
821 get_prm
->pcm_params
.sfreq
);
822 pr_debug("pcmparams:num_chan = %d\n",
823 get_prm
->pcm_params
.num_chan
);
824 pr_debug("pcmparams:pcm_wd_sz = %d\n",
825 get_prm
->pcm_params
.pcm_wd_sz
);
830 * sst_create_algo_ipc - create ipc msg for algorithm parameters
832 * @algo_params: Algorithm parameters
833 * @msg: post msg pointer
835 * This function is called to create ipc msg
837 int sst_create_algo_ipc(struct snd_ppp_params
*algo_params
,
838 struct ipc_post
**msg
)
840 if (sst_create_large_msg(msg
))
842 sst_fill_header(&(*msg
)->header
,
843 IPC_IA_ALG_PARAMS
, 1, algo_params
->str_id
);
844 (*msg
)->header
.part
.data
= sizeof(u32
) +
845 sizeof(*algo_params
) + algo_params
->size
;
846 memcpy((*msg
)->mailbox_data
, &(*msg
)->header
, sizeof(u32
));
847 memcpy((*msg
)->mailbox_data
+ sizeof(u32
),
848 algo_params
, sizeof(*algo_params
));
853 * sst_send_algo_ipc - send ipc msg for algorithm parameters
855 * @msg: post msg pointer
857 * This function is called to send ipc msg
859 int sst_send_algo_ipc(struct ipc_post
**msg
)
861 sst_drv_ctx
->ppp_params_blk
.condition
= false;
862 sst_drv_ctx
->ppp_params_blk
.ret_code
= 0;
863 sst_drv_ctx
->ppp_params_blk
.on
= true;
864 sst_drv_ctx
->ppp_params_blk
.data
= NULL
;
865 spin_lock(&sst_drv_ctx
->list_spin_lock
);
866 list_add_tail(&(*msg
)->node
, &sst_drv_ctx
->ipc_dispatch_list
);
867 spin_unlock(&sst_drv_ctx
->list_spin_lock
);
868 sst_post_message(&sst_drv_ctx
->ipc_post_msg_wq
);
869 return sst_wait_interruptible_timeout(sst_drv_ctx
,
870 &sst_drv_ctx
->ppp_params_blk
, SST_BLOCK_TIMEOUT
);
874 * intel_sst_ioctl_dsp - recieves the device ioctl's
879 * This function is called when a user space component
880 * sends a DSP Ioctl to SST driver
882 long intel_sst_ioctl_dsp(unsigned int cmd
, unsigned long arg
)
885 struct snd_ppp_params algo_params
;
886 struct snd_ppp_params
*algo_params_copied
;
887 struct ipc_post
*msg
;
889 switch (_IOC_NR(cmd
)) {
890 case _IOC_NR(SNDRV_SST_SET_ALGO
):
891 if (copy_from_user(&algo_params
, (void __user
*)arg
,
892 sizeof(algo_params
)))
894 if (algo_params
.size
> SST_MAILBOX_SIZE
)
897 pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
898 algo_params
.algo_id
, algo_params
.str_id
,
899 algo_params
.enable
, algo_params
.size
);
900 retval
= sst_create_algo_ipc(&algo_params
, &msg
);
903 algo_params
.reserved
= 0;
904 if (copy_from_user(msg
->mailbox_data
+ sizeof(algo_params
),
905 algo_params
.params
, algo_params
.size
))
908 retval
= sst_send_algo_ipc(&msg
);
910 pr_debug("Error in sst_set_algo = %d\n", retval
);
915 case _IOC_NR(SNDRV_SST_GET_ALGO
):
916 if (copy_from_user(&algo_params
, (void __user
*)arg
,
917 sizeof(algo_params
)))
919 pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
920 algo_params
.algo_id
, algo_params
.str_id
,
921 algo_params
.enable
, algo_params
.size
);
922 retval
= sst_create_algo_ipc(&algo_params
, &msg
);
925 algo_params
.reserved
= 1;
926 retval
= sst_send_algo_ipc(&msg
);
928 pr_debug("Error in sst_get_algo = %d\n", retval
);
932 algo_params_copied
= (struct snd_ppp_params
*)
933 sst_drv_ctx
->ppp_params_blk
.data
;
934 if (algo_params_copied
->size
> algo_params
.size
) {
935 pr_debug("mem insufficient to copy\n");
941 if (copy_to_user(algo_params
.params
,
942 algo_params_copied
->params
,
943 algo_params_copied
->size
)) {
947 tmp
= (char __user
*)arg
+ offsetof(
948 struct snd_ppp_params
, size
);
949 if (copy_to_user(tmp
, &algo_params_copied
->size
,
957 kfree(algo_params_copied
->params
);
958 kfree(algo_params_copied
);
965 * intel_sst_ioctl - receives the device ioctl's
966 * @file_ptr:pointer to file
970 * This function is called by OS when a user space component
971 * sends an Ioctl to SST driver
973 long intel_sst_ioctl(struct file
*file_ptr
, unsigned int cmd
, unsigned long arg
)
976 struct ioctl_pvt_data
*data
= NULL
;
977 int str_id
= 0, minor
= 0;
979 data
= file_ptr
->private_data
;
982 str_id
= data
->str_id
;
986 if (sst_drv_ctx
->sst_state
!= SST_FW_RUNNING
)
989 switch (_IOC_NR(cmd
)) {
990 case _IOC_NR(SNDRV_SST_STREAM_PAUSE
):
991 pr_debug("IOCTL_PAUSE received for %d!\n", str_id
);
992 if (minor
!= STREAM_MODULE
) {
996 retval
= sst_pause_stream(str_id
);
999 case _IOC_NR(SNDRV_SST_STREAM_RESUME
):
1000 pr_debug("SNDRV_SST_IOCTL_RESUME received!\n");
1001 if (minor
!= STREAM_MODULE
) {
1005 retval
= sst_resume_stream(str_id
);
1008 case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS
): {
1009 struct snd_sst_params str_param
;
1011 pr_debug("IOCTL_SET_PARAMS received!\n");
1012 if (minor
!= STREAM_MODULE
) {
1017 if (copy_from_user(&str_param
, (void __user
*)arg
,
1018 sizeof(str_param
))) {
1025 retval
= sst_get_stream(&str_param
);
1027 struct stream_info
*str_info
;
1030 sst_drv_ctx
->stream_cnt
++;
1031 data
->str_id
= retval
;
1032 str_info
= &sst_drv_ctx
->streams
[retval
];
1033 str_info
->src
= SST_DRV
;
1034 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_params
, stream_id
);
1035 retval
= copy_to_user(dest
, &retval
, sizeof(__u32
));
1039 if (retval
== -SST_ERR_INVALID_PARAMS
)
1043 pr_debug("SET_STREAM_PARAMS received!\n");
1044 /* allocated set params only */
1045 retval
= sst_set_stream_param(str_id
, &str_param
);
1046 /* Block the call for reply */
1048 int sfreq
= 0, word_size
= 0, num_channel
= 0;
1049 sfreq
= str_param
.sparams
.uc
.pcm_params
.sfreq
;
1050 word_size
= str_param
.sparams
.uc
.pcm_params
.pcm_wd_sz
;
1051 num_channel
= str_param
.sparams
.uc
.pcm_params
.num_chan
;
1052 if (str_param
.ops
== STREAM_OPS_CAPTURE
) {
1053 sst_drv_ctx
->scard_ops
->\
1054 set_pcm_audio_params(sfreq
,
1055 word_size
, num_channel
);
1061 case _IOC_NR(SNDRV_SST_SET_VOL
): {
1062 struct snd_sst_vol set_vol
;
1064 if (copy_from_user(&set_vol
, (void __user
*)arg
,
1066 pr_debug("copy failed\n");
1070 pr_debug("SET_VOLUME recieved for %d!\n",
1072 if (minor
== STREAM_MODULE
&& set_vol
.stream_id
== 0) {
1073 pr_debug("invalid operation!\n");
1077 retval
= sst_set_vol(&set_vol
);
1080 case _IOC_NR(SNDRV_SST_GET_VOL
): {
1081 struct snd_sst_vol get_vol
;
1083 if (copy_from_user(&get_vol
, (void __user
*)arg
,
1088 pr_debug("IOCTL_GET_VOLUME recieved for stream = %d!\n",
1090 if (minor
== STREAM_MODULE
&& get_vol
.stream_id
== 0) {
1091 pr_debug("invalid operation!\n");
1095 retval
= sst_get_vol(&get_vol
);
1100 pr_debug("id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
1101 get_vol
.stream_id
, get_vol
.volume
,
1102 get_vol
.ramp_duration
, get_vol
.ramp_type
);
1103 if (copy_to_user((struct snd_sst_vol __user
*)arg
,
1104 &get_vol
, sizeof(get_vol
))) {
1108 /*sst_print_get_vol_info(str_id, &get_vol);*/
1112 case _IOC_NR(SNDRV_SST_MUTE
): {
1113 struct snd_sst_mute set_mute
;
1115 if (copy_from_user(&set_mute
, (void __user
*)arg
,
1116 sizeof(set_mute
))) {
1120 pr_debug("SNDRV_SST_SET_VOLUME recieved for %d!\n",
1121 set_mute
.stream_id
);
1122 if (minor
== STREAM_MODULE
&& set_mute
.stream_id
== 0) {
1126 retval
= sst_set_mute(&set_mute
);
1129 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS
): {
1130 struct snd_sst_get_stream_params get_params
;
1132 pr_debug("IOCTL_GET_PARAMS received!\n");
1138 retval
= sst_get_stream_params(str_id
, &get_params
);
1143 if (copy_to_user((struct snd_sst_get_stream_params __user
*)arg
,
1144 &get_params
, sizeof(get_params
))) {
1148 sst_print_stream_params(&get_params
);
1152 case _IOC_NR(SNDRV_SST_MMAP_PLAY
):
1153 case _IOC_NR(SNDRV_SST_MMAP_CAPTURE
): {
1154 struct snd_sst_mmap_buffs mmap_buf
;
1156 pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
1157 if (minor
!= STREAM_MODULE
) {
1161 if (copy_from_user(&mmap_buf
, (void __user
*)arg
,
1162 sizeof(mmap_buf
))) {
1166 retval
= intel_sst_mmap_play_capture(str_id
, &mmap_buf
);
1169 case _IOC_NR(SNDRV_SST_STREAM_DROP
):
1170 pr_debug("SNDRV_SST_IOCTL_DROP received!\n");
1171 if (minor
!= STREAM_MODULE
) {
1175 retval
= sst_drop_stream(str_id
);
1178 case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP
): {
1179 struct snd_sst_tstamp tstamp
= {0};
1180 unsigned long long time
, freq
, mod
;
1182 pr_debug("SNDRV_SST_STREAM_GET_TSTAMP received!\n");
1183 if (minor
!= STREAM_MODULE
) {
1187 memcpy_fromio(&tstamp
,
1188 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1190 time
= tstamp
.samples_rendered
;
1191 freq
= (unsigned long long) tstamp
.sampling_frequency
;
1192 time
= time
* 1000; /* converting it to ms */
1193 mod
= do_div(time
, freq
);
1194 if (copy_to_user((void __user
*)arg
, &time
,
1195 sizeof(unsigned long long)))
1200 case _IOC_NR(SNDRV_SST_STREAM_START
):{
1201 struct stream_info
*stream
;
1203 pr_debug("SNDRV_SST_STREAM_START received!\n");
1204 if (minor
!= STREAM_MODULE
) {
1208 retval
= sst_validate_strid(str_id
);
1211 stream
= &sst_drv_ctx
->streams
[str_id
];
1212 mutex_lock(&stream
->lock
);
1213 if (stream
->status
== STREAM_INIT
&&
1214 stream
->need_draining
!= true) {
1215 stream
->prev
= stream
->status
;
1216 stream
->status
= STREAM_RUNNING
;
1217 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
1218 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
1219 retval
= sst_play_frame(str_id
);
1220 } else if (stream
->ops
== STREAM_OPS_CAPTURE
)
1221 retval
= sst_capture_frame(str_id
);
1224 mutex_unlock(&stream
->lock
);
1228 stream
->status
= STREAM_INIT
;
1229 mutex_unlock(&stream
->lock
);
1235 mutex_unlock(&stream
->lock
);
1239 case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE
): {
1240 struct snd_sst_target_device target_device
;
1242 pr_debug("SET_TARGET_DEVICE recieved!\n");
1243 if (copy_from_user(&target_device
, (void __user
*)arg
,
1244 sizeof(target_device
))) {
1248 if (minor
!= AM_MODULE
) {
1252 retval
= sst_target_device_select(&target_device
);
1256 case _IOC_NR(SNDRV_SST_DRIVER_INFO
): {
1257 struct snd_sst_driver_info info
;
1259 pr_debug("SNDRV_SST_DRIVER_INFO recived\n");
1260 info
.version
= SST_VERSION_NUM
;
1261 /* hard coding, shud get sumhow later */
1262 info
.active_pcm_streams
= sst_drv_ctx
->stream_cnt
-
1263 sst_drv_ctx
->encoded_cnt
;
1264 info
.active_enc_streams
= sst_drv_ctx
->encoded_cnt
;
1265 info
.max_pcm_streams
= MAX_ACTIVE_STREAM
- MAX_ENC_STREAM
;
1266 info
.max_enc_streams
= MAX_ENC_STREAM
;
1267 info
.buf_per_stream
= sst_drv_ctx
->mmap_len
;
1268 if (copy_to_user((void __user
*)arg
, &info
,
1274 case _IOC_NR(SNDRV_SST_STREAM_DECODE
): {
1275 struct snd_sst_dbufs param
;
1276 struct snd_sst_dbufs dbufs_local
;
1277 struct snd_sst_buffs ibufs
, obufs
;
1278 struct snd_sst_buff_entry
*ibuf_tmp
, *obuf_tmp
;
1281 pr_debug("SNDRV_SST_STREAM_DECODE received\n");
1282 if (minor
!= STREAM_MODULE
) {
1286 if (copy_from_user(¶m
, (void __user
*)arg
,
1292 dbufs_local
.input_bytes_consumed
= param
.input_bytes_consumed
;
1293 dbufs_local
.output_bytes_produced
=
1294 param
.output_bytes_produced
;
1296 if (copy_from_user(&ibufs
, (void __user
*)param
.ibufs
, sizeof(ibufs
))) {
1300 if (copy_from_user(&obufs
, (void __user
*)param
.obufs
, sizeof(obufs
))) {
1305 ibuf_tmp
= kcalloc(ibufs
.entries
, sizeof(*ibuf_tmp
), GFP_KERNEL
);
1306 obuf_tmp
= kcalloc(obufs
.entries
, sizeof(*obuf_tmp
), GFP_KERNEL
);
1307 if (!ibuf_tmp
|| !obuf_tmp
) {
1312 if (copy_from_user(ibuf_tmp
, (void __user
*)ibufs
.buff_entry
,
1313 ibufs
.entries
* sizeof(*ibuf_tmp
))) {
1317 ibufs
.buff_entry
= ibuf_tmp
;
1318 dbufs_local
.ibufs
= &ibufs
;
1320 if (copy_from_user(obuf_tmp
, (void __user
*)obufs
.buff_entry
,
1321 obufs
.entries
* sizeof(*obuf_tmp
))) {
1325 obufs
.buff_entry
= obuf_tmp
;
1326 dbufs_local
.obufs
= &obufs
;
1328 retval
= sst_decode(str_id
, &dbufs_local
);
1334 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1335 if (copy_to_user(dest
,
1336 &dbufs_local
.input_bytes_consumed
,
1337 sizeof(unsigned long long))) {
1342 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1343 if (copy_to_user(dest
,
1344 &dbufs_local
.output_bytes_produced
,
1345 sizeof(unsigned long long))) {
1355 case _IOC_NR(SNDRV_SST_STREAM_DRAIN
):
1356 pr_debug("SNDRV_SST_STREAM_DRAIN received\n");
1357 if (minor
!= STREAM_MODULE
) {
1361 retval
= sst_drain_stream(str_id
);
1364 case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED
): {
1365 unsigned long long __user
*bytes
= (unsigned long long __user
*)arg
;
1366 struct snd_sst_tstamp tstamp
= {0};
1368 pr_debug("STREAM_BYTES_DECODED received!\n");
1369 if (minor
!= STREAM_MODULE
) {
1373 memcpy_fromio(&tstamp
,
1374 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1376 if (copy_to_user(bytes
, &tstamp
.bytes_processed
,
1381 case _IOC_NR(SNDRV_SST_FW_INFO
): {
1382 struct snd_sst_fw_info
*fw_info
;
1384 pr_debug("SNDRV_SST_FW_INFO received\n");
1386 fw_info
= kzalloc(sizeof(*fw_info
), GFP_ATOMIC
);
1391 retval
= sst_get_fw_info(fw_info
);
1397 if (copy_to_user((struct snd_sst_dbufs __user
*)arg
,
1398 fw_info
, sizeof(*fw_info
))) {
1403 /*sst_print_fw_info(fw_info);*/
1407 case _IOC_NR(SNDRV_SST_GET_ALGO
):
1408 case _IOC_NR(SNDRV_SST_SET_ALGO
):
1409 if (minor
!= AM_MODULE
) {
1413 retval
= intel_sst_ioctl_dsp(cmd
, arg
);
1418 pr_debug("intel_sst_ioctl:complete ret code = %d\n", retval
);