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 boundary */
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 #ifdef CONFIG_MRST_RAR_HANDLER
422 if (stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
423 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
425 struct sst_stream_bufs
*stream_bufs
=
426 kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
428 stream
->sg_index
= index
;
431 if (copy_from_user((void *) &rar_handle
,
432 iovec
[index
].iov_base
,
437 stream_bufs
->addr
= (char *)rar_handle
;
438 stream_bufs
->in_use
= false;
439 stream_bufs
->size
= iovec
[0].iov_len
;
441 mutex_lock(&stream
->lock
);
442 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
443 mutex_unlock(&stream
->lock
);
445 stream
->sg_index
= index
;
449 stream_bufs
= kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
452 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
453 mmap_len
= sst_drv_ctx
->mmap_len
;
454 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
455 bufp
= stream
->cur_ptr
;
459 if (!stream
->sg_index
)
460 sent_index
= sent_offset
= 0;
462 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
463 stream
->sg_index
= index
;
464 if (!stream
->cur_ptr
)
465 bufp
= iovec
[index
].iov_base
;
467 size
= ((unsigned long)iovec
[index
].iov_base
468 + iovec
[index
].iov_len
) - (unsigned long) bufp
;
470 if ((copied_size
+ size
) > mmap_len
)
471 size
= mmap_len
- copied_size
;
474 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
475 if (copy_from_user((void *)
476 (stream_bufs
->addr
+ copied_size
),
478 /* Clean up the list and return error code */
482 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
483 struct snd_sst_user_cap_list
*entry
=
484 kzalloc(sizeof(*entry
), GFP_KERNEL
);
490 entry
->iov_index
= index
;
491 entry
->iov_offset
= (unsigned long) bufp
-
492 (unsigned long)iovec
[index
].iov_base
;
493 entry
->offset
= copied_size
;
495 list_add_tail(&entry
->node
, copy_to_list
);
498 stream
->cur_ptr
= bufp
+ size
;
500 if (((unsigned long)iovec
[index
].iov_base
501 + iovec
[index
].iov_len
) <
502 ((unsigned long)iovec
[index
].iov_base
)) {
503 pr_debug("Buffer overflows\n");
508 if (((unsigned long)iovec
[index
].iov_base
509 + iovec
[index
].iov_len
) ==
510 (unsigned long)stream
->cur_ptr
) {
511 stream
->cur_ptr
= NULL
;
516 pr_debug("copied_size - %lx\n", copied_size
);
517 if ((copied_size
>= mmap_len
) ||
518 (stream
->sg_index
== nr_segs
)) {
523 stream_bufs
->in_use
= false;
524 stream_bufs
->size
= copied_size
;
526 mutex_lock(&stream
->lock
);
527 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
528 mutex_unlock(&stream
->lock
);
535 /* This function copies the captured data returned from SST DSP engine
536 * to the user buffers*/
537 static int snd_sst_copy_userbuf_capture(struct stream_info
*stream
,
538 const struct iovec
*iovec
,
539 struct list_head
*copy_to_list
)
541 struct snd_sst_user_cap_list
*entry
, *_entry
;
542 struct sst_stream_bufs
*kbufs
= NULL
, *_kbufs
;
545 /* copy sent buffers */
546 pr_debug("capture stream copying to user now...\n");
547 list_for_each_entry_safe(kbufs
, _kbufs
, &stream
->bufs
, node
) {
548 if (kbufs
->in_use
== true) {
550 list_for_each_entry_safe(entry
, _entry
,
551 copy_to_list
, node
) {
552 if (copy_to_user(iovec
[entry
->iov_index
].iov_base
+ entry
->iov_offset
,
553 kbufs
->addr
+ entry
->offset
,
555 /* Clean up the list and return error */
559 list_del(&entry
->node
);
564 pr_debug("end of cap copy\n");
569 * snd_sst_userbufs_play_cap - constructs the list from user buffers
571 * @iovec:pointer to iovec structure
572 * @nr_segs:number entries in the iovec structure
574 * @stream:pointer to stream_info structure
576 * This function will traverse the user list and copy the data to the kernel
579 static int snd_sst_userbufs_play_cap(const struct iovec
*iovec
,
580 unsigned long nr_segs
, unsigned int str_id
,
581 struct stream_info
*stream
)
584 LIST_HEAD(copy_to_list
);
587 retval
= snd_sst_fill_kernel_list(stream
, iovec
, nr_segs
,
590 retval
= intel_sst_play_capture(stream
, str_id
);
594 if (stream
->ops
== STREAM_OPS_CAPTURE
) {
595 retval
= snd_sst_copy_userbuf_capture(stream
, iovec
,
601 /* This function is common function across read/write
602 for user buffers called from system calls*/
603 static int intel_sst_read_write(unsigned int str_id
, char __user
*buf
,
607 struct stream_info
*stream
;
609 unsigned long nr_segs
;
611 retval
= sst_validate_strid(str_id
);
614 stream
= &sst_drv_ctx
->streams
[str_id
];
615 if (stream
->mmapped
== true) {
616 pr_warn("user write and stream is mapped\n");
621 stream
->curr_bytes
= 0;
622 stream
->cumm_bytes
= 0;
623 /* copy user buf details */
624 pr_debug("new buffers %p, copy size %d, status %d\n" ,
625 buf
, (int) count
, (int) stream
->status
);
627 stream
->buf_type
= SST_BUF_USER_STATIC
;
628 iovec
.iov_base
= buf
;
629 iovec
.iov_len
= count
;
633 retval
= snd_sst_userbufs_play_cap(
634 &iovec
, nr_segs
, str_id
, stream
);
638 } while (stream
->sg_index
< nr_segs
);
640 stream
->sg_index
= 0;
641 stream
->cur_ptr
= NULL
;
643 retval
= stream
->cumm_bytes
;
644 pr_debug("end of play/rec bytes = %d!!\n", retval
);
649 * intel_sst_write - This function is called when user tries to play out data
651 * @file_ptr:pointer to file
652 * @buf:user buffer to be played out
653 * @count:size of tthe buffer
654 * @offset:offset to start from
656 * writes the encoded data into DSP
658 int intel_sst_write(struct file
*file_ptr
, const char __user
*buf
,
659 size_t count
, loff_t
*offset
)
661 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
662 int str_id
= data
->str_id
;
663 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
665 pr_debug("called for %d\n", str_id
);
666 if (stream
->status
== STREAM_UN_INIT
||
667 stream
->status
== STREAM_DECODE
) {
670 return intel_sst_read_write(str_id
, (char __user
*)buf
, count
);
674 * intel_sst_aio_write - write buffers
676 * @kiocb:pointer to a structure containing file pointer
677 * @iov:list of user buffer to be played out
678 * @nr_segs:number of entries
679 * @offset:offset to start from
681 * This function is called when user tries to play out multiple data buffers
683 ssize_t
intel_sst_aio_write(struct kiocb
*kiocb
, const struct iovec
*iov
,
684 unsigned long nr_segs
, loff_t offset
)
687 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
688 int str_id
= data
->str_id
;
689 struct stream_info
*stream
;
691 pr_debug("entry - %ld\n", nr_segs
);
693 if (is_sync_kiocb(kiocb
) == false)
696 pr_debug("called for str_id %d\n", str_id
);
697 retval
= sst_validate_strid(str_id
);
700 stream
= &sst_drv_ctx
->streams
[str_id
];
701 if (stream
->mmapped
== true)
703 if (stream
->status
== STREAM_UN_INIT
||
704 stream
->status
== STREAM_DECODE
) {
707 stream
->curr_bytes
= 0;
708 stream
->cumm_bytes
= 0;
709 pr_debug("new segs %ld, offset %d, status %d\n" ,
710 nr_segs
, (int) offset
, (int) stream
->status
);
711 stream
->buf_type
= SST_BUF_USER_STATIC
;
713 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
718 } while (stream
->sg_index
< nr_segs
);
720 stream
->sg_index
= 0;
721 stream
->cur_ptr
= NULL
;
723 retval
= stream
->cumm_bytes
;
724 pr_debug("end of play/rec bytes = %d!!\n", retval
);
729 * intel_sst_read - read the encoded data
731 * @file_ptr: pointer to file
732 * @buf: user buffer to be filled with captured data
733 * @count: size of tthe buffer
734 * @offset: offset to start from
736 * This function is called when user tries to capture data
738 int intel_sst_read(struct file
*file_ptr
, char __user
*buf
,
739 size_t count
, loff_t
*offset
)
741 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
742 int str_id
= data
->str_id
;
743 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
745 pr_debug("called for %d\n", str_id
);
746 if (stream
->status
== STREAM_UN_INIT
||
747 stream
->status
== STREAM_DECODE
)
749 return intel_sst_read_write(str_id
, buf
, count
);
753 * intel_sst_aio_read - aio read
755 * @kiocb: pointer to a structure containing file pointer
756 * @iov: list of user buffer to be filled with captured
757 * @nr_segs: number of entries
758 * @offset: offset to start from
760 * This function is called when user tries to capture out multiple data buffers
762 ssize_t
intel_sst_aio_read(struct kiocb
*kiocb
, const struct iovec
*iov
,
763 unsigned long nr_segs
, loff_t offset
)
766 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
767 int str_id
= data
->str_id
;
768 struct stream_info
*stream
;
770 pr_debug("entry - %ld\n", nr_segs
);
772 if (is_sync_kiocb(kiocb
) == false) {
773 pr_debug("aio_read from user space is not allowed\n");
777 pr_debug("called for str_id %d\n", str_id
);
778 retval
= sst_validate_strid(str_id
);
781 stream
= &sst_drv_ctx
->streams
[str_id
];
782 if (stream
->mmapped
== true)
784 if (stream
->status
== STREAM_UN_INIT
||
785 stream
->status
== STREAM_DECODE
)
787 stream
->curr_bytes
= 0;
788 stream
->cumm_bytes
= 0;
790 pr_debug("new segs %ld, offset %d, status %d\n" ,
791 nr_segs
, (int) offset
, (int) stream
->status
);
792 stream
->buf_type
= SST_BUF_USER_STATIC
;
794 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
799 } while (stream
->sg_index
< nr_segs
);
801 stream
->sg_index
= 0;
802 stream
->cur_ptr
= NULL
;
804 retval
= stream
->cumm_bytes
;
805 pr_debug("end of play/rec bytes = %d!!\n", retval
);
809 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
810 static void sst_print_stream_params(struct snd_sst_get_stream_params
*get_prm
)
812 pr_debug("codec params:result = %d\n",
813 get_prm
->codec_params
.result
);
814 pr_debug("codec params:stream = %d\n",
815 get_prm
->codec_params
.stream_id
);
816 pr_debug("codec params:codec = %d\n",
817 get_prm
->codec_params
.codec
);
818 pr_debug("codec params:ops = %d\n",
819 get_prm
->codec_params
.ops
);
820 pr_debug("codec params:stream_type = %d\n",
821 get_prm
->codec_params
.stream_type
);
822 pr_debug("pcmparams:sfreq = %d\n",
823 get_prm
->pcm_params
.sfreq
);
824 pr_debug("pcmparams:num_chan = %d\n",
825 get_prm
->pcm_params
.num_chan
);
826 pr_debug("pcmparams:pcm_wd_sz = %d\n",
827 get_prm
->pcm_params
.pcm_wd_sz
);
832 * sst_create_algo_ipc - create ipc msg for algorithm parameters
834 * @algo_params: Algorithm parameters
835 * @msg: post msg pointer
837 * This function is called to create ipc msg
839 int sst_create_algo_ipc(struct snd_ppp_params
*algo_params
,
840 struct ipc_post
**msg
)
842 if (sst_create_large_msg(msg
))
844 sst_fill_header(&(*msg
)->header
,
845 IPC_IA_ALG_PARAMS
, 1, algo_params
->str_id
);
846 (*msg
)->header
.part
.data
= sizeof(u32
) +
847 sizeof(*algo_params
) + algo_params
->size
;
848 memcpy((*msg
)->mailbox_data
, &(*msg
)->header
, sizeof(u32
));
849 memcpy((*msg
)->mailbox_data
+ sizeof(u32
),
850 algo_params
, sizeof(*algo_params
));
855 * sst_send_algo_ipc - send ipc msg for algorithm parameters
857 * @msg: post msg pointer
859 * This function is called to send ipc msg
861 int sst_send_algo_ipc(struct ipc_post
**msg
)
863 sst_drv_ctx
->ppp_params_blk
.condition
= false;
864 sst_drv_ctx
->ppp_params_blk
.ret_code
= 0;
865 sst_drv_ctx
->ppp_params_blk
.on
= true;
866 sst_drv_ctx
->ppp_params_blk
.data
= NULL
;
867 spin_lock(&sst_drv_ctx
->list_spin_lock
);
868 list_add_tail(&(*msg
)->node
, &sst_drv_ctx
->ipc_dispatch_list
);
869 spin_unlock(&sst_drv_ctx
->list_spin_lock
);
870 sst_post_message(&sst_drv_ctx
->ipc_post_msg_wq
);
871 return sst_wait_interruptible_timeout(sst_drv_ctx
,
872 &sst_drv_ctx
->ppp_params_blk
, SST_BLOCK_TIMEOUT
);
876 * intel_sst_ioctl_dsp - receives the device ioctl's
881 * This function is called when a user space component
882 * sends a DSP Ioctl to SST driver
884 long intel_sst_ioctl_dsp(unsigned int cmd
, unsigned long arg
)
887 struct snd_ppp_params algo_params
;
888 struct snd_ppp_params
*algo_params_copied
;
889 struct ipc_post
*msg
;
891 switch (_IOC_NR(cmd
)) {
892 case _IOC_NR(SNDRV_SST_SET_ALGO
):
893 if (copy_from_user(&algo_params
, (void __user
*)arg
,
894 sizeof(algo_params
)))
896 if (algo_params
.size
> SST_MAILBOX_SIZE
)
899 pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
900 algo_params
.algo_id
, algo_params
.str_id
,
901 algo_params
.enable
, algo_params
.size
);
902 retval
= sst_create_algo_ipc(&algo_params
, &msg
);
905 algo_params
.reserved
= 0;
906 if (copy_from_user(msg
->mailbox_data
+ sizeof(algo_params
),
907 algo_params
.params
, algo_params
.size
))
910 retval
= sst_send_algo_ipc(&msg
);
912 pr_debug("Error in sst_set_algo = %d\n", retval
);
917 case _IOC_NR(SNDRV_SST_GET_ALGO
):
918 if (copy_from_user(&algo_params
, (void __user
*)arg
,
919 sizeof(algo_params
)))
921 pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
922 algo_params
.algo_id
, algo_params
.str_id
,
923 algo_params
.enable
, algo_params
.size
);
924 retval
= sst_create_algo_ipc(&algo_params
, &msg
);
927 algo_params
.reserved
= 1;
928 retval
= sst_send_algo_ipc(&msg
);
930 pr_debug("Error in sst_get_algo = %d\n", retval
);
934 algo_params_copied
= (struct snd_ppp_params
*)
935 sst_drv_ctx
->ppp_params_blk
.data
;
936 if (algo_params_copied
->size
> algo_params
.size
) {
937 pr_debug("mem insufficient to copy\n");
943 if (copy_to_user(algo_params
.params
,
944 algo_params_copied
->params
,
945 algo_params_copied
->size
)) {
949 tmp
= (char __user
*)arg
+ offsetof(
950 struct snd_ppp_params
, size
);
951 if (copy_to_user(tmp
, &algo_params_copied
->size
,
959 kfree(algo_params_copied
->params
);
960 kfree(algo_params_copied
);
967 int sst_ioctl_tuning_params(unsigned long arg
)
969 struct snd_sst_tuning_params params
;
970 struct ipc_post
*msg
;
972 if (copy_from_user(¶ms
, (void __user
*)arg
, sizeof(params
)))
974 if (params
.size
> SST_MAILBOX_SIZE
)
976 pr_debug("Parameter %d, Stream %d, Size %d\n", params
.type
,
977 params
.str_id
, params
.size
);
978 if (sst_create_large_msg(&msg
))
981 sst_fill_header(&msg
->header
, IPC_IA_TUNING_PARAMS
, 1, params
.str_id
);
982 msg
->header
.part
.data
= sizeof(u32
) + sizeof(params
) + params
.size
;
983 memcpy(msg
->mailbox_data
, &msg
->header
.full
, sizeof(u32
));
984 memcpy(msg
->mailbox_data
+ sizeof(u32
), ¶ms
, sizeof(params
));
985 if (copy_from_user(msg
->mailbox_data
+ sizeof(params
),
986 (void __user
*)(unsigned long)params
.addr
,
988 kfree(msg
->mailbox_data
);
992 return sst_send_algo_ipc(&msg
);
995 * intel_sst_ioctl - receives the device ioctl's
996 * @file_ptr:pointer to file
1000 * This function is called by OS when a user space component
1001 * sends an Ioctl to SST driver
1003 long intel_sst_ioctl(struct file
*file_ptr
, unsigned int cmd
, unsigned long arg
)
1006 struct ioctl_pvt_data
*data
= NULL
;
1007 int str_id
= 0, minor
= 0;
1009 data
= file_ptr
->private_data
;
1012 str_id
= data
->str_id
;
1016 if (sst_drv_ctx
->sst_state
!= SST_FW_RUNNING
)
1019 switch (_IOC_NR(cmd
)) {
1020 case _IOC_NR(SNDRV_SST_STREAM_PAUSE
):
1021 pr_debug("IOCTL_PAUSE received for %d!\n", str_id
);
1022 if (minor
!= STREAM_MODULE
) {
1026 retval
= sst_pause_stream(str_id
);
1029 case _IOC_NR(SNDRV_SST_STREAM_RESUME
):
1030 pr_debug("SNDRV_SST_IOCTL_RESUME received!\n");
1031 if (minor
!= STREAM_MODULE
) {
1035 retval
= sst_resume_stream(str_id
);
1038 case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS
): {
1039 struct snd_sst_params str_param
;
1041 pr_debug("IOCTL_SET_PARAMS received!\n");
1042 if (minor
!= STREAM_MODULE
) {
1047 if (copy_from_user(&str_param
, (void __user
*)arg
,
1048 sizeof(str_param
))) {
1055 retval
= sst_get_stream(&str_param
);
1057 struct stream_info
*str_info
;
1060 sst_drv_ctx
->stream_cnt
++;
1061 data
->str_id
= retval
;
1062 str_info
= &sst_drv_ctx
->streams
[retval
];
1063 str_info
->src
= SST_DRV
;
1064 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_params
, stream_id
);
1065 retval
= copy_to_user(dest
, &retval
, sizeof(__u32
));
1069 if (retval
== -SST_ERR_INVALID_PARAMS
)
1073 pr_debug("SET_STREAM_PARAMS received!\n");
1074 /* allocated set params only */
1075 retval
= sst_set_stream_param(str_id
, &str_param
);
1076 /* Block the call for reply */
1078 int sfreq
= 0, word_size
= 0, num_channel
= 0;
1079 sfreq
= str_param
.sparams
.uc
.pcm_params
.sfreq
;
1080 word_size
= str_param
.sparams
.uc
.pcm_params
.pcm_wd_sz
;
1081 num_channel
= str_param
.sparams
.uc
.pcm_params
.num_chan
;
1082 if (str_param
.ops
== STREAM_OPS_CAPTURE
) {
1083 sst_drv_ctx
->scard_ops
->\
1084 set_pcm_audio_params(sfreq
,
1085 word_size
, num_channel
);
1091 case _IOC_NR(SNDRV_SST_SET_VOL
): {
1092 struct snd_sst_vol set_vol
;
1094 if (copy_from_user(&set_vol
, (void __user
*)arg
,
1096 pr_debug("copy failed\n");
1100 pr_debug("SET_VOLUME received for %d!\n",
1102 if (minor
== STREAM_MODULE
&& set_vol
.stream_id
== 0) {
1103 pr_debug("invalid operation!\n");
1107 retval
= sst_set_vol(&set_vol
);
1110 case _IOC_NR(SNDRV_SST_GET_VOL
): {
1111 struct snd_sst_vol get_vol
;
1113 if (copy_from_user(&get_vol
, (void __user
*)arg
,
1118 pr_debug("IOCTL_GET_VOLUME received for stream = %d!\n",
1120 if (minor
== STREAM_MODULE
&& get_vol
.stream_id
== 0) {
1121 pr_debug("invalid operation!\n");
1125 retval
= sst_get_vol(&get_vol
);
1130 pr_debug("id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
1131 get_vol
.stream_id
, get_vol
.volume
,
1132 get_vol
.ramp_duration
, get_vol
.ramp_type
);
1133 if (copy_to_user((struct snd_sst_vol __user
*)arg
,
1134 &get_vol
, sizeof(get_vol
))) {
1138 /*sst_print_get_vol_info(str_id, &get_vol);*/
1142 case _IOC_NR(SNDRV_SST_MUTE
): {
1143 struct snd_sst_mute set_mute
;
1145 if (copy_from_user(&set_mute
, (void __user
*)arg
,
1146 sizeof(set_mute
))) {
1150 pr_debug("SNDRV_SST_SET_VOLUME received for %d!\n",
1151 set_mute
.stream_id
);
1152 if (minor
== STREAM_MODULE
&& set_mute
.stream_id
== 0) {
1156 retval
= sst_set_mute(&set_mute
);
1159 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS
): {
1160 struct snd_sst_get_stream_params get_params
;
1162 pr_debug("IOCTL_GET_PARAMS received!\n");
1168 retval
= sst_get_stream_params(str_id
, &get_params
);
1173 if (copy_to_user((struct snd_sst_get_stream_params __user
*)arg
,
1174 &get_params
, sizeof(get_params
))) {
1178 sst_print_stream_params(&get_params
);
1182 case _IOC_NR(SNDRV_SST_MMAP_PLAY
):
1183 case _IOC_NR(SNDRV_SST_MMAP_CAPTURE
): {
1184 struct snd_sst_mmap_buffs mmap_buf
;
1186 pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE received!\n");
1187 if (minor
!= STREAM_MODULE
) {
1191 if (copy_from_user(&mmap_buf
, (void __user
*)arg
,
1192 sizeof(mmap_buf
))) {
1196 retval
= intel_sst_mmap_play_capture(str_id
, &mmap_buf
);
1199 case _IOC_NR(SNDRV_SST_STREAM_DROP
):
1200 pr_debug("SNDRV_SST_IOCTL_DROP received!\n");
1201 if (minor
!= STREAM_MODULE
) {
1205 retval
= sst_drop_stream(str_id
);
1208 case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP
): {
1209 struct snd_sst_tstamp tstamp
= {0};
1210 unsigned long long time
, freq
, mod
;
1212 pr_debug("SNDRV_SST_STREAM_GET_TSTAMP received!\n");
1213 if (minor
!= STREAM_MODULE
) {
1217 memcpy_fromio(&tstamp
,
1218 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1220 time
= tstamp
.samples_rendered
;
1221 freq
= (unsigned long long) tstamp
.sampling_frequency
;
1222 time
= time
* 1000; /* converting it to ms */
1223 mod
= do_div(time
, freq
);
1224 if (copy_to_user((void __user
*)arg
, &time
,
1225 sizeof(unsigned long long)))
1230 case _IOC_NR(SNDRV_SST_STREAM_START
):{
1231 struct stream_info
*stream
;
1233 pr_debug("SNDRV_SST_STREAM_START received!\n");
1234 if (minor
!= STREAM_MODULE
) {
1238 retval
= sst_validate_strid(str_id
);
1241 stream
= &sst_drv_ctx
->streams
[str_id
];
1242 mutex_lock(&stream
->lock
);
1243 if (stream
->status
== STREAM_INIT
&&
1244 stream
->need_draining
!= true) {
1245 stream
->prev
= stream
->status
;
1246 stream
->status
= STREAM_RUNNING
;
1247 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
1248 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
1249 retval
= sst_play_frame(str_id
);
1250 } else if (stream
->ops
== STREAM_OPS_CAPTURE
)
1251 retval
= sst_capture_frame(str_id
);
1254 mutex_unlock(&stream
->lock
);
1258 stream
->status
= STREAM_INIT
;
1259 mutex_unlock(&stream
->lock
);
1265 mutex_unlock(&stream
->lock
);
1269 case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE
): {
1270 struct snd_sst_target_device target_device
;
1272 pr_debug("SET_TARGET_DEVICE received!\n");
1273 if (copy_from_user(&target_device
, (void __user
*)arg
,
1274 sizeof(target_device
))) {
1278 if (minor
!= AM_MODULE
) {
1282 retval
= sst_target_device_select(&target_device
);
1286 case _IOC_NR(SNDRV_SST_DRIVER_INFO
): {
1287 struct snd_sst_driver_info info
;
1289 pr_debug("SNDRV_SST_DRIVER_INFO received\n");
1290 info
.version
= SST_VERSION_NUM
;
1291 /* hard coding, shud get sumhow later */
1292 info
.active_pcm_streams
= sst_drv_ctx
->stream_cnt
-
1293 sst_drv_ctx
->encoded_cnt
;
1294 info
.active_enc_streams
= sst_drv_ctx
->encoded_cnt
;
1295 info
.max_pcm_streams
= MAX_ACTIVE_STREAM
- MAX_ENC_STREAM
;
1296 info
.max_enc_streams
= MAX_ENC_STREAM
;
1297 info
.buf_per_stream
= sst_drv_ctx
->mmap_len
;
1298 if (copy_to_user((void __user
*)arg
, &info
,
1304 case _IOC_NR(SNDRV_SST_STREAM_DECODE
): {
1305 struct snd_sst_dbufs param
;
1306 struct snd_sst_dbufs dbufs_local
;
1307 struct snd_sst_buffs ibufs
, obufs
;
1308 struct snd_sst_buff_entry
*ibuf_tmp
, *obuf_tmp
;
1311 pr_debug("SNDRV_SST_STREAM_DECODE received\n");
1312 if (minor
!= STREAM_MODULE
) {
1316 if (copy_from_user(¶m
, (void __user
*)arg
,
1322 dbufs_local
.input_bytes_consumed
= param
.input_bytes_consumed
;
1323 dbufs_local
.output_bytes_produced
=
1324 param
.output_bytes_produced
;
1326 if (copy_from_user(&ibufs
, (void __user
*)param
.ibufs
, sizeof(ibufs
))) {
1330 if (copy_from_user(&obufs
, (void __user
*)param
.obufs
, sizeof(obufs
))) {
1335 ibuf_tmp
= kcalloc(ibufs
.entries
, sizeof(*ibuf_tmp
), GFP_KERNEL
);
1336 obuf_tmp
= kcalloc(obufs
.entries
, sizeof(*obuf_tmp
), GFP_KERNEL
);
1337 if (!ibuf_tmp
|| !obuf_tmp
) {
1342 if (copy_from_user(ibuf_tmp
, (void __user
*)ibufs
.buff_entry
,
1343 ibufs
.entries
* sizeof(*ibuf_tmp
))) {
1347 ibufs
.buff_entry
= ibuf_tmp
;
1348 dbufs_local
.ibufs
= &ibufs
;
1350 if (copy_from_user(obuf_tmp
, (void __user
*)obufs
.buff_entry
,
1351 obufs
.entries
* sizeof(*obuf_tmp
))) {
1355 obufs
.buff_entry
= obuf_tmp
;
1356 dbufs_local
.obufs
= &obufs
;
1358 retval
= sst_decode(str_id
, &dbufs_local
);
1364 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1365 if (copy_to_user(dest
,
1366 &dbufs_local
.input_bytes_consumed
,
1367 sizeof(unsigned long long))) {
1372 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1373 if (copy_to_user(dest
,
1374 &dbufs_local
.output_bytes_produced
,
1375 sizeof(unsigned long long))) {
1385 case _IOC_NR(SNDRV_SST_STREAM_DRAIN
):
1386 pr_debug("SNDRV_SST_STREAM_DRAIN received\n");
1387 if (minor
!= STREAM_MODULE
) {
1391 retval
= sst_drain_stream(str_id
);
1394 case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED
): {
1395 unsigned long long __user
*bytes
= (unsigned long long __user
*)arg
;
1396 struct snd_sst_tstamp tstamp
= {0};
1398 pr_debug("STREAM_BYTES_DECODED received!\n");
1399 if (minor
!= STREAM_MODULE
) {
1403 memcpy_fromio(&tstamp
,
1404 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1406 if (copy_to_user(bytes
, &tstamp
.bytes_processed
,
1411 case _IOC_NR(SNDRV_SST_FW_INFO
): {
1412 struct snd_sst_fw_info
*fw_info
;
1414 pr_debug("SNDRV_SST_FW_INFO received\n");
1416 fw_info
= kzalloc(sizeof(*fw_info
), GFP_ATOMIC
);
1421 retval
= sst_get_fw_info(fw_info
);
1427 if (copy_to_user((struct snd_sst_dbufs __user
*)arg
,
1428 fw_info
, sizeof(*fw_info
))) {
1433 /*sst_print_fw_info(fw_info);*/
1437 case _IOC_NR(SNDRV_SST_GET_ALGO
):
1438 case _IOC_NR(SNDRV_SST_SET_ALGO
):
1439 if (minor
!= AM_MODULE
) {
1443 retval
= intel_sst_ioctl_dsp(cmd
, arg
);
1446 case _IOC_NR(SNDRV_SST_TUNING_PARAMS
):
1447 if (minor
!= AM_MODULE
) {
1451 retval
= sst_ioctl_tuning_params(arg
);
1457 pr_debug("intel_sst_ioctl:complete ret code = %d\n", retval
);