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 #include <linux/smp_lock.h>
41 #ifdef CONFIG_MRST_RAR_HANDLER
42 #include <linux/rar_register.h>
43 #include "../../../drivers/staging/memrar/memrar.h"
45 #include "intel_sst.h"
46 #include "intel_sst_ioctl.h"
47 #include "intel_sst_fw_ipc.h"
48 #include "intel_sst_common.h"
51 #define STREAM_MODULE 0
55 * intel_sst_check_device - checks SST device
57 * This utility function checks the state of SST device and downlaods FW if
58 * not done, or resumes the device if suspended
61 static int intel_sst_check_device(void)
64 if (sst_drv_ctx
->pmic_state
!= SND_MAD_INIT_DONE
) {
65 pr_warn("Sound card not available\n");
68 if (sst_drv_ctx
->sst_state
== SST_SUSPENDED
) {
69 pr_debug("Resuming from Suspended state\n");
70 retval
= intel_sst_resume(sst_drv_ctx
->pci
);
72 pr_debug("Resume Failed= %#x,abort\n", retval
);
77 if (sst_drv_ctx
->sst_state
== SST_UN_INIT
) {
78 /* FW is not downloaded */
79 retval
= sst_download_fw();
82 if (sst_drv_ctx
->pci_id
== SST_MRST_PCI_ID
) {
83 retval
= sst_drv_ctx
->rx_time_slot_status
;
84 if (retval
!= RX_TIMESLOT_UNINIT
85 && sst_drv_ctx
->pmic_vendor
!= SND_NC
)
86 sst_enable_rx_timeslot(retval
);
93 * intel_sst_open - opens a handle to driver
95 * @i_node: inode structure
96 * @file_ptr:pointer to file
98 * This function is called by OS when a user space component
99 * tries to get a driver handle. Only one handle at a time
102 int intel_sst_open(struct inode
*i_node
, struct file
*file_ptr
)
106 mutex_lock(&sst_drv_ctx
->stream_lock
);
107 pm_runtime_get_sync(&sst_drv_ctx
->pci
->dev
);
108 retval
= intel_sst_check_device();
110 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
111 mutex_unlock(&sst_drv_ctx
->stream_lock
);
115 if (sst_drv_ctx
->encoded_cnt
< MAX_ENC_STREAM
) {
116 struct ioctl_pvt_data
*data
=
117 kzalloc(sizeof(struct ioctl_pvt_data
), GFP_KERNEL
);
119 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
120 mutex_unlock(&sst_drv_ctx
->stream_lock
);
124 sst_drv_ctx
->encoded_cnt
++;
125 mutex_unlock(&sst_drv_ctx
->stream_lock
);
126 data
->pvt_id
= sst_assign_pvt_id(sst_drv_ctx
);
128 file_ptr
->private_data
= (void *)data
;
129 pr_debug("pvt_id handle = %d!\n", data
->pvt_id
);
132 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
133 mutex_unlock(&sst_drv_ctx
->stream_lock
);
139 * intel_sst_open_cntrl - opens a handle to driver
141 * @i_node: inode structure
142 * @file_ptr:pointer to file
144 * This function is called by OS when a user space component
145 * tries to get a driver handle to /dev/intel_sst_control.
146 * Only one handle at a time will be allowed
147 * This is for control operations only
149 int intel_sst_open_cntrl(struct inode
*i_node
, struct file
*file_ptr
)
153 /* audio manager open */
154 mutex_lock(&sst_drv_ctx
->stream_lock
);
155 pm_runtime_get_sync(&sst_drv_ctx
->pci
->dev
);
156 retval
= intel_sst_check_device();
158 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
159 mutex_unlock(&sst_drv_ctx
->stream_lock
);
163 if (sst_drv_ctx
->am_cnt
< MAX_AM_HANDLES
) {
164 sst_drv_ctx
->am_cnt
++;
165 pr_debug("AM handle opened...\n");
166 file_ptr
->private_data
= NULL
;
169 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
172 mutex_unlock(&sst_drv_ctx
->stream_lock
);
177 * intel_sst_release - releases a handle to driver
179 * @i_node: inode structure
180 * @file_ptr: pointer to file
182 * This function is called by OS when a user space component
183 * tries to release a driver handle.
185 int intel_sst_release(struct inode
*i_node
, struct file
*file_ptr
)
187 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
189 pr_debug("Release called, closing app handle\n");
190 mutex_lock(&sst_drv_ctx
->stream_lock
);
191 sst_drv_ctx
->encoded_cnt
--;
192 sst_drv_ctx
->stream_cnt
--;
193 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
194 mutex_unlock(&sst_drv_ctx
->stream_lock
);
195 free_stream_context(data
->str_id
);
200 int intel_sst_release_cntrl(struct inode
*i_node
, struct file
*file_ptr
)
202 /* audio manager close */
203 mutex_lock(&sst_drv_ctx
->stream_lock
);
204 sst_drv_ctx
->am_cnt
--;
205 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
206 mutex_unlock(&sst_drv_ctx
->stream_lock
);
207 pr_debug("AM handle closed\n");
212 * intel_sst_mmap - mmaps a kernel buffer to user space for copying data
214 * @vma: vm area structure instance
215 * @file_ptr: pointer to file
217 * This function is called by OS when a user space component
218 * tries to get mmap memory from driver
220 int intel_sst_mmap(struct file
*file_ptr
, struct vm_area_struct
*vma
)
223 struct ioctl_pvt_data
*data
=
224 (struct ioctl_pvt_data
*)file_ptr
->private_data
;
225 int str_id
= data
->str_id
;
228 retval
= sst_validate_strid(str_id
);
232 length
= vma
->vm_end
- vma
->vm_start
;
233 pr_debug("called for stream %d length 0x%x\n", str_id
, length
);
235 if (length
> sst_drv_ctx
->mmap_len
)
237 if (!sst_drv_ctx
->mmap_mem
)
240 /* round it up to the page bondary */
241 /*mem_area = (void *)((((unsigned long)sst_drv_ctx->mmap_mem)
242 + PAGE_SIZE - 1) & PAGE_MASK);*/
243 mem_area
= (void *) PAGE_ALIGN((unsigned int) sst_drv_ctx
->mmap_mem
);
245 /* map the whole physically contiguous area in one piece */
246 retval
= remap_pfn_range(vma
,
248 virt_to_phys((void *)mem_area
) >> PAGE_SHIFT
,
252 sst_drv_ctx
->streams
[str_id
].mmapped
= false;
254 sst_drv_ctx
->streams
[str_id
].mmapped
= true;
256 pr_debug("mmap ret 0x%x\n", retval
);
260 /* sets mmap data buffers to play/capture*/
261 static int intel_sst_mmap_play_capture(u32 str_id
,
262 struct snd_sst_mmap_buffs
*mmap_buf
)
264 struct sst_stream_bufs
*bufs
;
266 struct stream_info
*stream
;
267 struct snd_sst_mmap_buff_entry
*buf_entry
;
268 struct snd_sst_mmap_buff_entry
*tmp_buf
;
270 pr_debug("called for str_id %d\n", str_id
);
271 retval
= sst_validate_strid(str_id
);
275 stream
= &sst_drv_ctx
->streams
[str_id
];
276 if (stream
->mmapped
!= true)
279 if (stream
->status
== STREAM_UN_INIT
||
280 stream
->status
== STREAM_DECODE
) {
283 stream
->curr_bytes
= 0;
284 stream
->cumm_bytes
= 0;
286 tmp_buf
= kcalloc(mmap_buf
->entries
, sizeof(*tmp_buf
), GFP_KERNEL
);
289 if (copy_from_user(tmp_buf
, (void __user
*)mmap_buf
->buff
,
290 mmap_buf
->entries
* sizeof(*tmp_buf
))) {
295 pr_debug("new buffers count %d status %d\n",
296 mmap_buf
->entries
, stream
->status
);
298 for (i
= 0; i
< mmap_buf
->entries
; i
++) {
299 bufs
= kzalloc(sizeof(*bufs
), GFP_KERNEL
);
304 bufs
->size
= buf_entry
->size
;
305 bufs
->offset
= buf_entry
->offset
;
306 bufs
->addr
= sst_drv_ctx
->mmap_mem
;
307 bufs
->in_use
= false;
310 mutex_lock(&stream
->lock
);
311 list_add_tail(&bufs
->node
, &stream
->bufs
);
312 mutex_unlock(&stream
->lock
);
315 mutex_lock(&stream
->lock
);
316 stream
->data_blk
.condition
= false;
317 stream
->data_blk
.ret_code
= 0;
318 if (stream
->status
== STREAM_INIT
&&
319 stream
->prev
!= STREAM_UN_INIT
&&
320 stream
->need_draining
!= true) {
321 stream
->prev
= stream
->status
;
322 stream
->status
= STREAM_RUNNING
;
323 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
324 if (sst_play_frame(str_id
) < 0) {
325 pr_warn("play frames fail\n");
326 mutex_unlock(&stream
->lock
);
330 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
331 if (sst_capture_frame(str_id
) < 0) {
332 pr_warn("capture frame fail\n");
333 mutex_unlock(&stream
->lock
);
339 mutex_unlock(&stream
->lock
);
340 /* Block the call for reply */
341 if (!list_empty(&stream
->bufs
)) {
342 stream
->data_blk
.on
= true;
343 retval
= sst_wait_interruptible(sst_drv_ctx
,
348 retval
= stream
->cumm_bytes
;
349 pr_debug("end of play/rec ioctl bytes = %d!!\n", retval
);
356 /*sets user data buffers to play/capture*/
357 static int intel_sst_play_capture(struct stream_info
*stream
, int str_id
)
361 stream
->data_blk
.ret_code
= 0;
362 stream
->data_blk
.on
= true;
363 stream
->data_blk
.condition
= false;
365 mutex_lock(&stream
->lock
);
366 if (stream
->status
== STREAM_INIT
&& stream
->prev
!= STREAM_UN_INIT
) {
367 /* stream is started */
368 stream
->prev
= stream
->status
;
369 stream
->status
= STREAM_RUNNING
;
372 if (stream
->status
== STREAM_INIT
&& stream
->prev
== STREAM_UN_INIT
) {
373 /* stream is not started yet */
374 pr_debug("Stream isn't in started state %d, prev %d\n",
375 stream
->status
, stream
->prev
);
376 } else if ((stream
->status
== STREAM_RUNNING
||
377 stream
->status
== STREAM_PAUSED
) &&
378 stream
->need_draining
!= true) {
379 /* stream is started */
380 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
381 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
382 if (sst_play_frame(str_id
) < 0) {
383 pr_warn("play frames failed\n");
384 mutex_unlock(&stream
->lock
);
387 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
388 if (sst_capture_frame(str_id
) < 0) {
389 pr_warn("capture frames failed\n");
390 mutex_unlock(&stream
->lock
);
395 mutex_unlock(&stream
->lock
);
398 mutex_unlock(&stream
->lock
);
399 /* Block the call for reply */
401 retval
= sst_wait_interruptible(sst_drv_ctx
, &stream
->data_blk
);
403 stream
->status
= STREAM_INIT
;
404 pr_debug("wait returned error...\n");
409 /* fills kernel list with buffer addresses for SST DSP driver to process*/
410 static int snd_sst_fill_kernel_list(struct stream_info
*stream
,
411 const struct iovec
*iovec
, unsigned long nr_segs
,
412 struct list_head
*copy_to_list
)
414 struct sst_stream_bufs
*stream_bufs
;
415 unsigned long index
, mmap_len
;
416 unsigned char __user
*bufp
;
417 unsigned long size
, copied_size
;
418 int retval
= 0, add_to_list
= 0;
419 static int sent_offset
;
420 static unsigned long sent_index
;
422 stream_bufs
= kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
425 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
426 #ifdef CONFIG_MRST_RAR_HANDLER
427 if (stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
428 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
430 struct sst_stream_bufs
*stream_bufs
=
431 kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
433 stream
->sg_index
= index
;
436 if (copy_from_user((void *) &rar_handle
,
437 iovec
[index
].iov_base
,
440 stream_bufs
->addr
= (char *)rar_handle
;
441 stream_bufs
->in_use
= false;
442 stream_bufs
->size
= iovec
[0].iov_len
;
444 mutex_lock(&stream
->lock
);
445 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
446 mutex_unlock(&stream
->lock
);
448 stream
->sg_index
= index
;
452 mmap_len
= sst_drv_ctx
->mmap_len
;
453 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
454 bufp
= stream
->cur_ptr
;
458 if (!stream
->sg_index
)
459 sent_index
= sent_offset
= 0;
461 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
462 stream
->sg_index
= index
;
463 if (!stream
->cur_ptr
)
464 bufp
= iovec
[index
].iov_base
;
466 size
= ((unsigned long)iovec
[index
].iov_base
467 + iovec
[index
].iov_len
) - (unsigned long) bufp
;
469 if ((copied_size
+ size
) > mmap_len
)
470 size
= mmap_len
- copied_size
;
473 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
474 if (copy_from_user((void *)
475 (stream_bufs
->addr
+ copied_size
),
477 /* Clean up the list and return error code */
481 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
482 struct snd_sst_user_cap_list
*entry
=
483 kzalloc(sizeof(*entry
), GFP_KERNEL
);
489 entry
->iov_index
= index
;
490 entry
->iov_offset
= (unsigned long) bufp
-
491 (unsigned long)iovec
[index
].iov_base
;
492 entry
->offset
= copied_size
;
494 list_add_tail(&entry
->node
, copy_to_list
);
497 stream
->cur_ptr
= bufp
+ size
;
499 if (((unsigned long)iovec
[index
].iov_base
500 + iovec
[index
].iov_len
) <
501 ((unsigned long)iovec
[index
].iov_base
)) {
502 pr_debug("Buffer overflows\n");
507 if (((unsigned long)iovec
[index
].iov_base
508 + iovec
[index
].iov_len
) ==
509 (unsigned long)stream
->cur_ptr
) {
510 stream
->cur_ptr
= NULL
;
515 pr_debug("copied_size - %lx\n", copied_size
);
516 if ((copied_size
>= mmap_len
) ||
517 (stream
->sg_index
== nr_segs
)) {
522 stream_bufs
->in_use
= false;
523 stream_bufs
->size
= copied_size
;
525 mutex_lock(&stream
->lock
);
526 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
527 mutex_unlock(&stream
->lock
);
534 /* This function copies the captured data returned from SST DSP engine
535 * to the user buffers*/
536 static int snd_sst_copy_userbuf_capture(struct stream_info
*stream
,
537 const struct iovec
*iovec
,
538 struct list_head
*copy_to_list
)
540 struct snd_sst_user_cap_list
*entry
, *_entry
;
541 struct sst_stream_bufs
*kbufs
= NULL
, *_kbufs
;
544 /* copy sent buffers */
545 pr_debug("capture stream copying to user now...\n");
546 list_for_each_entry_safe(kbufs
, _kbufs
, &stream
->bufs
, node
) {
547 if (kbufs
->in_use
== true) {
549 list_for_each_entry_safe(entry
, _entry
,
550 copy_to_list
, node
) {
551 if (copy_to_user(iovec
[entry
->iov_index
].iov_base
+ entry
->iov_offset
,
552 kbufs
->addr
+ entry
->offset
,
554 /* Clean up the list and return error */
558 list_del(&entry
->node
);
563 pr_debug("end of cap copy\n");
568 * snd_sst_userbufs_play_cap - constructs the list from user buffers
570 * @iovec:pointer to iovec structure
571 * @nr_segs:number entries in the iovec structure
573 * @stream:pointer to stream_info structure
575 * This function will traverse the user list and copy the data to the kernel
578 static int snd_sst_userbufs_play_cap(const struct iovec
*iovec
,
579 unsigned long nr_segs
, unsigned int str_id
,
580 struct stream_info
*stream
)
583 LIST_HEAD(copy_to_list
);
586 retval
= snd_sst_fill_kernel_list(stream
, iovec
, nr_segs
,
589 retval
= intel_sst_play_capture(stream
, str_id
);
593 if (stream
->ops
== STREAM_OPS_CAPTURE
) {
594 retval
= snd_sst_copy_userbuf_capture(stream
, iovec
,
600 /* This function is common function across read/write
601 for user buffers called from system calls*/
602 static int intel_sst_read_write(unsigned int str_id
, char __user
*buf
,
606 struct stream_info
*stream
;
608 unsigned long nr_segs
;
610 retval
= sst_validate_strid(str_id
);
613 stream
= &sst_drv_ctx
->streams
[str_id
];
614 if (stream
->mmapped
== true) {
615 pr_warn("user write and stream is mapped\n");
620 stream
->curr_bytes
= 0;
621 stream
->cumm_bytes
= 0;
622 /* copy user buf details */
623 pr_debug("new buffers %p, copy size %d, status %d\n" ,
624 buf
, (int) count
, (int) stream
->status
);
626 stream
->buf_type
= SST_BUF_USER_STATIC
;
627 iovec
.iov_base
= buf
;
628 iovec
.iov_len
= count
;
632 retval
= snd_sst_userbufs_play_cap(
633 &iovec
, nr_segs
, str_id
, stream
);
637 } while (stream
->sg_index
< nr_segs
);
639 stream
->sg_index
= 0;
640 stream
->cur_ptr
= NULL
;
642 retval
= stream
->cumm_bytes
;
643 pr_debug("end of play/rec bytes = %d!!\n", retval
);
648 * intel_sst_write - This function is called when user tries to play out data
650 * @file_ptr:pointer to file
651 * @buf:user buffer to be played out
652 * @count:size of tthe buffer
653 * @offset:offset to start from
655 * writes the encoded data into DSP
657 int intel_sst_write(struct file
*file_ptr
, const char __user
*buf
,
658 size_t count
, loff_t
*offset
)
660 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
661 int str_id
= data
->str_id
;
662 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
664 pr_debug("called for %d\n", str_id
);
665 if (stream
->status
== STREAM_UN_INIT
||
666 stream
->status
== STREAM_DECODE
) {
669 return intel_sst_read_write(str_id
, (char __user
*)buf
, count
);
673 * intel_sst_aio_write - write buffers
675 * @kiocb:pointer to a structure containing file pointer
676 * @iov:list of user buffer to be played out
677 * @nr_segs:number of entries
678 * @offset:offset to start from
680 * This function is called when user tries to play out multiple data buffers
682 ssize_t
intel_sst_aio_write(struct kiocb
*kiocb
, const struct iovec
*iov
,
683 unsigned long nr_segs
, loff_t offset
)
686 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
687 int str_id
= data
->str_id
;
688 struct stream_info
*stream
;
690 pr_debug("entry - %ld\n", nr_segs
);
692 if (is_sync_kiocb(kiocb
) == false)
695 pr_debug("called for str_id %d\n", str_id
);
696 retval
= sst_validate_strid(str_id
);
699 stream
= &sst_drv_ctx
->streams
[str_id
];
700 if (stream
->mmapped
== true)
702 if (stream
->status
== STREAM_UN_INIT
||
703 stream
->status
== STREAM_DECODE
) {
706 stream
->curr_bytes
= 0;
707 stream
->cumm_bytes
= 0;
708 pr_debug("new segs %ld, offset %d, status %d\n" ,
709 nr_segs
, (int) offset
, (int) stream
->status
);
710 stream
->buf_type
= SST_BUF_USER_STATIC
;
712 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
717 } while (stream
->sg_index
< nr_segs
);
719 stream
->sg_index
= 0;
720 stream
->cur_ptr
= NULL
;
722 retval
= stream
->cumm_bytes
;
723 pr_debug("end of play/rec bytes = %d!!\n", retval
);
728 * intel_sst_read - read the encoded data
730 * @file_ptr: pointer to file
731 * @buf: user buffer to be filled with captured data
732 * @count: size of tthe buffer
733 * @offset: offset to start from
735 * This function is called when user tries to capture data
737 int intel_sst_read(struct file
*file_ptr
, char __user
*buf
,
738 size_t count
, loff_t
*offset
)
740 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
741 int str_id
= data
->str_id
;
742 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
744 pr_debug("called for %d\n", str_id
);
745 if (stream
->status
== STREAM_UN_INIT
||
746 stream
->status
== STREAM_DECODE
)
748 return intel_sst_read_write(str_id
, buf
, count
);
752 * intel_sst_aio_read - aio read
754 * @kiocb: pointer to a structure containing file pointer
755 * @iov: list of user buffer to be filled with captured
756 * @nr_segs: number of entries
757 * @offset: offset to start from
759 * This function is called when user tries to capture out multiple data buffers
761 ssize_t
intel_sst_aio_read(struct kiocb
*kiocb
, const struct iovec
*iov
,
762 unsigned long nr_segs
, loff_t offset
)
765 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
766 int str_id
= data
->str_id
;
767 struct stream_info
*stream
;
769 pr_debug("entry - %ld\n", nr_segs
);
771 if (is_sync_kiocb(kiocb
) == false) {
772 pr_debug("aio_read from user space is not allowed\n");
776 pr_debug("called for str_id %d\n", str_id
);
777 retval
= sst_validate_strid(str_id
);
780 stream
= &sst_drv_ctx
->streams
[str_id
];
781 if (stream
->mmapped
== true)
783 if (stream
->status
== STREAM_UN_INIT
||
784 stream
->status
== STREAM_DECODE
)
786 stream
->curr_bytes
= 0;
787 stream
->cumm_bytes
= 0;
789 pr_debug("new segs %ld, offset %d, status %d\n" ,
790 nr_segs
, (int) offset
, (int) stream
->status
);
791 stream
->buf_type
= SST_BUF_USER_STATIC
;
793 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
798 } while (stream
->sg_index
< nr_segs
);
800 stream
->sg_index
= 0;
801 stream
->cur_ptr
= NULL
;
803 retval
= stream
->cumm_bytes
;
804 pr_debug("end of play/rec bytes = %d!!\n", retval
);
808 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
809 static void sst_print_stream_params(struct snd_sst_get_stream_params
*get_prm
)
811 pr_debug("codec params:result = %d\n",
812 get_prm
->codec_params
.result
);
813 pr_debug("codec params:stream = %d\n",
814 get_prm
->codec_params
.stream_id
);
815 pr_debug("codec params:codec = %d\n",
816 get_prm
->codec_params
.codec
);
817 pr_debug("codec params:ops = %d\n",
818 get_prm
->codec_params
.ops
);
819 pr_debug("codec params:stream_type = %d\n",
820 get_prm
->codec_params
.stream_type
);
821 pr_debug("pcmparams:sfreq = %d\n",
822 get_prm
->pcm_params
.sfreq
);
823 pr_debug("pcmparams:num_chan = %d\n",
824 get_prm
->pcm_params
.num_chan
);
825 pr_debug("pcmparams:pcm_wd_sz = %d\n",
826 get_prm
->pcm_params
.pcm_wd_sz
);
831 * intel_sst_ioctl - receives the device ioctl's
832 * @file_ptr:pointer to file
836 * This function is called by OS when a user space component
837 * sends an Ioctl to SST driver
839 long intel_sst_ioctl(struct file
*file_ptr
, unsigned int cmd
, unsigned long arg
)
842 struct ioctl_pvt_data
*data
= NULL
;
843 int str_id
= 0, minor
= 0;
845 data
= file_ptr
->private_data
;
848 str_id
= data
->str_id
;
852 if (sst_drv_ctx
->sst_state
!= SST_FW_RUNNING
)
855 switch (_IOC_NR(cmd
)) {
856 case _IOC_NR(SNDRV_SST_STREAM_PAUSE
):
857 pr_debug("IOCTL_PAUSE received for %d!\n", str_id
);
858 if (minor
!= STREAM_MODULE
) {
862 retval
= sst_pause_stream(str_id
);
865 case _IOC_NR(SNDRV_SST_STREAM_RESUME
):
866 pr_debug("SNDRV_SST_IOCTL_RESUME received!\n");
867 if (minor
!= STREAM_MODULE
) {
871 retval
= sst_resume_stream(str_id
);
874 case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS
): {
875 struct snd_sst_params str_param
;
877 pr_debug("IOCTL_SET_PARAMS received!\n");
878 if (minor
!= STREAM_MODULE
) {
883 if (copy_from_user(&str_param
, (void __user
*)arg
,
884 sizeof(str_param
))) {
891 retval
= sst_get_stream(&str_param
);
893 struct stream_info
*str_info
;
896 sst_drv_ctx
->stream_cnt
++;
897 data
->str_id
= retval
;
898 str_info
= &sst_drv_ctx
->streams
[retval
];
899 str_info
->src
= SST_DRV
;
900 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_params
, stream_id
);
901 retval
= copy_to_user(dest
, &retval
, sizeof(__u32
));
905 if (retval
== -SST_ERR_INVALID_PARAMS
)
909 pr_debug("SET_STREAM_PARAMS received!\n");
910 /* allocated set params only */
911 retval
= sst_set_stream_param(str_id
, &str_param
);
912 /* Block the call for reply */
914 int sfreq
= 0, word_size
= 0, num_channel
= 0;
915 sfreq
= str_param
.sparams
.uc
.pcm_params
.sfreq
;
916 word_size
= str_param
.sparams
.uc
.pcm_params
.pcm_wd_sz
;
917 num_channel
= str_param
.sparams
.uc
.pcm_params
.num_chan
;
918 if (str_param
.ops
== STREAM_OPS_CAPTURE
) {
919 sst_drv_ctx
->scard_ops
->\
920 set_pcm_audio_params(sfreq
,
921 word_size
, num_channel
);
927 case _IOC_NR(SNDRV_SST_SET_VOL
): {
928 struct snd_sst_vol set_vol
;
930 if (copy_from_user(&set_vol
, (void __user
*)arg
,
932 pr_debug("copy failed\n");
936 pr_debug("SET_VOLUME recieved for %d!\n",
938 if (minor
== STREAM_MODULE
&& set_vol
.stream_id
== 0) {
939 pr_debug("invalid operation!\n");
943 retval
= sst_set_vol(&set_vol
);
946 case _IOC_NR(SNDRV_SST_GET_VOL
): {
947 struct snd_sst_vol get_vol
;
949 if (copy_from_user(&get_vol
, (void __user
*)arg
,
954 pr_debug("IOCTL_GET_VOLUME recieved for stream = %d!\n",
956 if (minor
== STREAM_MODULE
&& get_vol
.stream_id
== 0) {
957 pr_debug("invalid operation!\n");
961 retval
= sst_get_vol(&get_vol
);
966 pr_debug("id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
967 get_vol
.stream_id
, get_vol
.volume
,
968 get_vol
.ramp_duration
, get_vol
.ramp_type
);
969 if (copy_to_user((struct snd_sst_vol __user
*)arg
,
970 &get_vol
, sizeof(get_vol
))) {
974 /*sst_print_get_vol_info(str_id, &get_vol);*/
978 case _IOC_NR(SNDRV_SST_MUTE
): {
979 struct snd_sst_mute set_mute
;
981 if (copy_from_user(&set_mute
, (void __user
*)arg
,
986 pr_debug("SNDRV_SST_SET_VOLUME recieved for %d!\n",
988 if (minor
== STREAM_MODULE
&& set_mute
.stream_id
== 0) {
992 retval
= sst_set_mute(&set_mute
);
995 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS
): {
996 struct snd_sst_get_stream_params get_params
;
998 pr_debug("IOCTL_GET_PARAMS received!\n");
1004 retval
= sst_get_stream_params(str_id
, &get_params
);
1009 if (copy_to_user((struct snd_sst_get_stream_params __user
*)arg
,
1010 &get_params
, sizeof(get_params
))) {
1014 sst_print_stream_params(&get_params
);
1018 case _IOC_NR(SNDRV_SST_MMAP_PLAY
):
1019 case _IOC_NR(SNDRV_SST_MMAP_CAPTURE
): {
1020 struct snd_sst_mmap_buffs mmap_buf
;
1022 pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
1023 if (minor
!= STREAM_MODULE
) {
1027 if (copy_from_user(&mmap_buf
, (void __user
*)arg
,
1028 sizeof(mmap_buf
))) {
1032 retval
= intel_sst_mmap_play_capture(str_id
, &mmap_buf
);
1035 case _IOC_NR(SNDRV_SST_STREAM_DROP
):
1036 pr_debug("SNDRV_SST_IOCTL_DROP received!\n");
1037 if (minor
!= STREAM_MODULE
) {
1041 retval
= sst_drop_stream(str_id
);
1044 case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP
): {
1045 struct snd_sst_tstamp tstamp
= {0};
1046 unsigned long long time
, freq
, mod
;
1048 pr_debug("SNDRV_SST_STREAM_GET_TSTAMP received!\n");
1049 if (minor
!= STREAM_MODULE
) {
1053 memcpy_fromio(&tstamp
,
1054 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1056 time
= tstamp
.samples_rendered
;
1057 freq
= (unsigned long long) tstamp
.sampling_frequency
;
1058 time
= time
* 1000; /* converting it to ms */
1059 mod
= do_div(time
, freq
);
1060 if (copy_to_user((void __user
*)arg
, &time
,
1061 sizeof(unsigned long long)))
1066 case _IOC_NR(SNDRV_SST_STREAM_START
):{
1067 struct stream_info
*stream
;
1069 pr_debug("SNDRV_SST_STREAM_START received!\n");
1070 if (minor
!= STREAM_MODULE
) {
1074 retval
= sst_validate_strid(str_id
);
1077 stream
= &sst_drv_ctx
->streams
[str_id
];
1078 mutex_lock(&stream
->lock
);
1079 if (stream
->status
== STREAM_INIT
&&
1080 stream
->need_draining
!= true) {
1081 stream
->prev
= stream
->status
;
1082 stream
->status
= STREAM_RUNNING
;
1083 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
1084 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
1085 retval
= sst_play_frame(str_id
);
1086 } else if (stream
->ops
== STREAM_OPS_CAPTURE
)
1087 retval
= sst_capture_frame(str_id
);
1090 mutex_unlock(&stream
->lock
);
1094 stream
->status
= STREAM_INIT
;
1095 mutex_unlock(&stream
->lock
);
1101 mutex_unlock(&stream
->lock
);
1105 case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE
): {
1106 struct snd_sst_target_device target_device
;
1108 pr_debug("SET_TARGET_DEVICE recieved!\n");
1109 if (copy_from_user(&target_device
, (void __user
*)arg
,
1110 sizeof(target_device
))) {
1114 if (minor
!= AM_MODULE
) {
1118 retval
= sst_target_device_select(&target_device
);
1122 case _IOC_NR(SNDRV_SST_DRIVER_INFO
): {
1123 struct snd_sst_driver_info info
;
1125 pr_debug("SNDRV_SST_DRIVER_INFO recived\n");
1126 info
.version
= SST_VERSION_NUM
;
1127 /* hard coding, shud get sumhow later */
1128 info
.active_pcm_streams
= sst_drv_ctx
->stream_cnt
-
1129 sst_drv_ctx
->encoded_cnt
;
1130 info
.active_enc_streams
= sst_drv_ctx
->encoded_cnt
;
1131 info
.max_pcm_streams
= MAX_ACTIVE_STREAM
- MAX_ENC_STREAM
;
1132 info
.max_enc_streams
= MAX_ENC_STREAM
;
1133 info
.buf_per_stream
= sst_drv_ctx
->mmap_len
;
1134 if (copy_to_user((void __user
*)arg
, &info
,
1140 case _IOC_NR(SNDRV_SST_STREAM_DECODE
): {
1141 struct snd_sst_dbufs param
;
1142 struct snd_sst_dbufs dbufs_local
;
1143 struct snd_sst_buffs ibufs
, obufs
;
1144 struct snd_sst_buff_entry
*ibuf_tmp
, *obuf_tmp
;
1147 pr_debug("SNDRV_SST_STREAM_DECODE received\n");
1148 if (minor
!= STREAM_MODULE
) {
1152 if (copy_from_user(¶m
, (void __user
*)arg
,
1158 dbufs_local
.input_bytes_consumed
= param
.input_bytes_consumed
;
1159 dbufs_local
.output_bytes_produced
=
1160 param
.output_bytes_produced
;
1162 if (copy_from_user(&ibufs
, (void __user
*)param
.ibufs
, sizeof(ibufs
))) {
1166 if (copy_from_user(&obufs
, (void __user
*)param
.obufs
, sizeof(obufs
))) {
1171 ibuf_tmp
= kcalloc(ibufs
.entries
, sizeof(*ibuf_tmp
), GFP_KERNEL
);
1172 obuf_tmp
= kcalloc(obufs
.entries
, sizeof(*obuf_tmp
), GFP_KERNEL
);
1173 if (!ibuf_tmp
|| !obuf_tmp
) {
1178 if (copy_from_user(ibuf_tmp
, (void __user
*)ibufs
.buff_entry
,
1179 ibufs
.entries
* sizeof(*ibuf_tmp
))) {
1183 ibufs
.buff_entry
= ibuf_tmp
;
1184 dbufs_local
.ibufs
= &ibufs
;
1186 if (copy_from_user(obuf_tmp
, (void __user
*)obufs
.buff_entry
,
1187 obufs
.entries
* sizeof(*obuf_tmp
))) {
1191 obufs
.buff_entry
= obuf_tmp
;
1192 dbufs_local
.obufs
= &obufs
;
1194 retval
= sst_decode(str_id
, &dbufs_local
);
1200 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1201 if (copy_to_user(dest
,
1202 &dbufs_local
.input_bytes_consumed
,
1203 sizeof(unsigned long long))) {
1208 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1209 if (copy_to_user(dest
,
1210 &dbufs_local
.output_bytes_produced
,
1211 sizeof(unsigned long long))) {
1221 case _IOC_NR(SNDRV_SST_STREAM_DRAIN
):
1222 pr_debug("SNDRV_SST_STREAM_DRAIN received\n");
1223 if (minor
!= STREAM_MODULE
) {
1227 retval
= sst_drain_stream(str_id
);
1230 case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED
): {
1231 unsigned long long __user
*bytes
= (unsigned long long __user
*)arg
;
1232 struct snd_sst_tstamp tstamp
= {0};
1234 pr_debug("STREAM_BYTES_DECODED received!\n");
1235 if (minor
!= STREAM_MODULE
) {
1239 memcpy_fromio(&tstamp
,
1240 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1242 if (copy_to_user(bytes
, &tstamp
.bytes_processed
,
1247 case _IOC_NR(SNDRV_SST_FW_INFO
): {
1248 struct snd_sst_fw_info
*fw_info
;
1250 pr_debug("SNDRV_SST_FW_INFO received\n");
1252 fw_info
= kzalloc(sizeof(*fw_info
), GFP_ATOMIC
);
1257 retval
= sst_get_fw_info(fw_info
);
1263 if (copy_to_user((struct snd_sst_dbufs __user
*)arg
,
1264 fw_info
, sizeof(*fw_info
))) {
1269 /*sst_print_fw_info(fw_info);*/
1276 pr_debug("intel_sst_ioctl:complete ret code = %d\n", retval
);