2 * intel_sst_interface.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-10 Intel Corp
5 * Authors: Vinod Koul <vinod.koul@intel.com>
6 * Harsha Priya <priya.harsha@intel.com>
7 * Dharageswari R <dharageswari.r@intel.com>
8 * Jeeja KP <jeeja.kp@intel.com>
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 * This driver exposes the audio engine functionalities to the ALSA
27 * Upper layer interfaces (MAD driver, MMF) to SST driver
30 #include <linux/pci.h>
32 #include <linux/uio.h>
33 #include <linux/aio.h>
34 #include <linux/uaccess.h>
35 #include <linux/firmware.h>
36 #include <linux/ioctl.h>
37 #include <linux/smp_lock.h>
38 #ifdef CONFIG_MRST_RAR_HANDLER
39 #include <linux/rar_register.h>
40 #include "../../../drivers/staging/memrar/memrar.h"
42 #include "intel_sst.h"
43 #include "intel_sst_ioctl.h"
44 #include "intel_sst_fw_ipc.h"
45 #include "intel_sst_common.h"
48 #define STREAM_MODULE 0
52 * intel_sst_check_device - checks SST device
54 * This utility function checks the state of SST device and downlaods FW if
55 * not done, or resumes the device if suspended
58 static int intel_sst_check_device(void)
61 if (sst_drv_ctx
->pmic_state
!= SND_MAD_INIT_DONE
) {
62 pr_warn("sst: Sound card not availble\n ");
65 if (sst_drv_ctx
->sst_state
== SST_SUSPENDED
) {
66 pr_debug("sst: Resuming from Suspended state\n");
67 retval
= intel_sst_resume(sst_drv_ctx
->pci
);
69 pr_debug("sst: Resume Failed= %#x,abort\n", retval
);
74 if (sst_drv_ctx
->sst_state
== SST_UN_INIT
) {
75 /* FW is not downloaded */
76 retval
= sst_download_fw();
79 if (sst_drv_ctx
->pci_id
== SST_MRST_PCI_ID
) {
80 retval
= sst_drv_ctx
->rx_time_slot_status
;
81 if (retval
!= RX_TIMESLOT_UNINIT
82 && sst_drv_ctx
->pmic_vendor
!= SND_NC
)
83 sst_enable_rx_timeslot(retval
);
90 * intel_sst_open - opens a handle to driver
92 * @i_node: inode structure
93 * @file_ptr:pointer to file
95 * This function is called by OS when a user space component
96 * tries to get a driver handle. Only one handle at a time
99 int intel_sst_open(struct inode
*i_node
, struct file
*file_ptr
)
101 int retval
= intel_sst_check_device();
105 mutex_lock(&sst_drv_ctx
->stream_lock
);
106 if (sst_drv_ctx
->encoded_cnt
< MAX_ENC_STREAM
) {
107 struct ioctl_pvt_data
*data
=
108 kzalloc(sizeof(struct ioctl_pvt_data
), GFP_KERNEL
);
110 mutex_unlock(&sst_drv_ctx
->stream_lock
);
114 sst_drv_ctx
->encoded_cnt
++;
115 mutex_unlock(&sst_drv_ctx
->stream_lock
);
116 data
->pvt_id
= sst_assign_pvt_id(sst_drv_ctx
);
118 file_ptr
->private_data
= (void *)data
;
119 pr_debug("sst: pvt_id handle = %d!\n", data
->pvt_id
);
122 mutex_unlock(&sst_drv_ctx
->stream_lock
);
128 * intel_sst_open_cntrl - opens a handle to driver
130 * @i_node: inode structure
131 * @file_ptr:pointer to file
133 * This function is called by OS when a user space component
134 * tries to get a driver handle to /dev/intel_sst_control.
135 * Only one handle at a time will be allowed
136 * This is for control operations only
138 int intel_sst_open_cntrl(struct inode
*i_node
, struct file
*file_ptr
)
140 int retval
= intel_sst_check_device();
144 /* audio manager open */
145 mutex_lock(&sst_drv_ctx
->stream_lock
);
146 if (sst_drv_ctx
->am_cnt
< MAX_AM_HANDLES
) {
147 sst_drv_ctx
->am_cnt
++;
148 pr_debug("sst: AM handle opened...\n");
149 file_ptr
->private_data
= NULL
;
153 mutex_unlock(&sst_drv_ctx
->stream_lock
);
158 * intel_sst_release - releases a handle to driver
160 * @i_node: inode structure
161 * @file_ptr: pointer to file
163 * This function is called by OS when a user space component
164 * tries to release a driver handle.
166 int intel_sst_release(struct inode
*i_node
, struct file
*file_ptr
)
168 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
170 pr_debug("sst: Release called, closing app handle\n");
171 mutex_lock(&sst_drv_ctx
->stream_lock
);
172 sst_drv_ctx
->encoded_cnt
--;
173 sst_drv_ctx
->stream_cnt
--;
174 mutex_unlock(&sst_drv_ctx
->stream_lock
);
175 free_stream_context(data
->str_id
);
180 int intel_sst_release_cntrl(struct inode
*i_node
, struct file
*file_ptr
)
182 /* audio manager close */
183 mutex_lock(&sst_drv_ctx
->stream_lock
);
184 sst_drv_ctx
->am_cnt
--;
185 mutex_unlock(&sst_drv_ctx
->stream_lock
);
186 pr_debug("sst: AM handle closed\n");
191 * intel_sst_mmap - mmaps a kernel buffer to user space for copying data
193 * @vma: vm area structure instance
194 * @file_ptr: pointer to file
196 * This function is called by OS when a user space component
197 * tries to get mmap memory from driver
199 int intel_sst_mmap(struct file
*file_ptr
, struct vm_area_struct
*vma
)
202 struct ioctl_pvt_data
*data
=
203 (struct ioctl_pvt_data
*)file_ptr
->private_data
;
204 int str_id
= data
->str_id
;
207 retval
= sst_validate_strid(str_id
);
211 length
= vma
->vm_end
- vma
->vm_start
;
212 pr_debug("sst: called for stream %d length 0x%x\n", str_id
, length
);
214 if (length
> sst_drv_ctx
->mmap_len
)
216 if (!sst_drv_ctx
->mmap_mem
)
219 /* round it up to the page bondary */
220 /*mem_area = (void *)((((unsigned long)sst_drv_ctx->mmap_mem)
221 + PAGE_SIZE - 1) & PAGE_MASK);*/
222 mem_area
= (void *) PAGE_ALIGN((unsigned int) sst_drv_ctx
->mmap_mem
);
224 /* map the whole physically contiguous area in one piece */
225 retval
= remap_pfn_range(vma
,
227 virt_to_phys((void *)mem_area
) >> PAGE_SHIFT
,
231 sst_drv_ctx
->streams
[str_id
].mmapped
= false;
233 sst_drv_ctx
->streams
[str_id
].mmapped
= true;
235 pr_debug("sst: mmap ret 0x%x\n", retval
);
239 /* sets mmap data buffers to play/capture*/
240 static int intel_sst_mmap_play_capture(u32 str_id
,
241 struct snd_sst_mmap_buffs
*mmap_buf
)
243 struct sst_stream_bufs
*bufs
;
245 struct stream_info
*stream
;
246 struct snd_sst_mmap_buff_entry
*buf_entry
;
248 pr_debug("sst:called for str_id %d\n", str_id
);
249 retval
= sst_validate_strid(str_id
);
254 stream
= &sst_drv_ctx
->streams
[str_id
];
255 if (stream
->mmapped
!= true)
258 if (stream
->status
== STREAM_UN_INIT
||
259 stream
->status
== STREAM_DECODE
) {
262 stream
->curr_bytes
= 0;
263 stream
->cumm_bytes
= 0;
265 pr_debug("sst:new buffers count %d status %d\n",
266 mmap_buf
->entries
, stream
->status
);
267 buf_entry
= mmap_buf
->buff
;
268 for (i
= 0; i
< mmap_buf
->entries
; i
++) {
270 bufs
= kzalloc(sizeof(*bufs
), GFP_KERNEL
);
273 bufs
->size
= buf_entry
->size
;
274 bufs
->offset
= buf_entry
->offset
;
275 bufs
->addr
= sst_drv_ctx
->mmap_mem
;
276 bufs
->in_use
= false;
279 mutex_lock(&stream
->lock
);
280 list_add_tail(&bufs
->node
, &stream
->bufs
);
281 mutex_unlock(&stream
->lock
);
284 mutex_lock(&stream
->lock
);
285 stream
->data_blk
.condition
= false;
286 stream
->data_blk
.ret_code
= 0;
287 if (stream
->status
== STREAM_INIT
&&
288 stream
->prev
!= STREAM_UN_INIT
&&
289 stream
->need_draining
!= true) {
290 stream
->prev
= stream
->status
;
291 stream
->status
= STREAM_RUNNING
;
292 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
293 if (sst_play_frame(str_id
) < 0) {
294 pr_warn("sst: play frames fail\n");
295 mutex_unlock(&stream
->lock
);
298 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
299 if (sst_capture_frame(str_id
) < 0) {
300 pr_warn("sst: capture frame fail\n");
301 mutex_unlock(&stream
->lock
);
306 mutex_unlock(&stream
->lock
);
307 /* Block the call for reply */
308 if (!list_empty(&stream
->bufs
)) {
309 stream
->data_blk
.on
= true;
310 retval
= sst_wait_interruptible(sst_drv_ctx
,
315 retval
= stream
->cumm_bytes
;
316 pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval
);
320 /*sets user data buffers to play/capture*/
321 static int intel_sst_play_capture(struct stream_info
*stream
, int str_id
)
325 stream
->data_blk
.ret_code
= 0;
326 stream
->data_blk
.on
= true;
327 stream
->data_blk
.condition
= false;
329 mutex_lock(&stream
->lock
);
330 if (stream
->status
== STREAM_INIT
&& stream
->prev
!= STREAM_UN_INIT
) {
331 /* stream is started */
332 stream
->prev
= stream
->status
;
333 stream
->status
= STREAM_RUNNING
;
336 if (stream
->status
== STREAM_INIT
&& stream
->prev
== STREAM_UN_INIT
) {
337 /* stream is not started yet */
338 pr_debug("sst: Stream isn't in started state %d, prev %d\n",
339 stream
->status
, stream
->prev
);
340 } else if ((stream
->status
== STREAM_RUNNING
||
341 stream
->status
== STREAM_PAUSED
) &&
342 stream
->need_draining
!= true) {
343 /* stream is started */
344 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
345 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
346 if (sst_play_frame(str_id
) < 0) {
347 pr_warn("sst: play frames failed\n");
348 mutex_unlock(&stream
->lock
);
351 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
352 if (sst_capture_frame(str_id
) < 0) {
353 pr_warn("sst: capture frames failed\n ");
354 mutex_unlock(&stream
->lock
);
359 mutex_unlock(&stream
->lock
);
362 mutex_unlock(&stream
->lock
);
363 /* Block the call for reply */
365 retval
= sst_wait_interruptible(sst_drv_ctx
, &stream
->data_blk
);
367 stream
->status
= STREAM_INIT
;
368 pr_debug("sst: wait returned error...\n");
373 /* fills kernel list with buffer addresses for SST DSP driver to process*/
374 static int snd_sst_fill_kernel_list(struct stream_info
*stream
,
375 const struct iovec
*iovec
, unsigned long nr_segs
,
376 struct list_head
*copy_to_list
)
378 struct sst_stream_bufs
*stream_bufs
;
379 unsigned long index
, data_not_copied
, mmap_len
;
381 unsigned long size
, copied_size
;
382 int retval
= 0, add_to_list
= 0;
383 static int sent_offset
;
384 static unsigned long sent_index
;
386 stream_bufs
= kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
389 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
390 #ifdef CONFIG_MRST_RAR_HANDLER
391 if (stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
392 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
394 struct sst_stream_bufs
*stream_bufs
=
395 kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
397 stream
->sg_index
= index
;
400 retval
= copy_from_user((void *) &rar_handle
,
401 iovec
[index
].iov_base
,
405 stream_bufs
->addr
= (char *)rar_handle
;
406 stream_bufs
->in_use
= false;
407 stream_bufs
->size
= iovec
[0].iov_len
;
409 mutex_lock(&stream
->lock
);
410 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
411 mutex_unlock(&stream
->lock
);
413 stream
->sg_index
= index
;
417 mmap_len
= sst_drv_ctx
->mmap_len
;
418 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
419 bufp
= stream
->cur_ptr
;
423 if (!stream
->sg_index
)
424 sent_index
= sent_offset
= 0;
426 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
427 stream
->sg_index
= index
;
428 if (!stream
->cur_ptr
)
429 bufp
= iovec
[index
].iov_base
;
431 size
= ((unsigned long)iovec
[index
].iov_base
432 + iovec
[index
].iov_len
) - (unsigned long) bufp
;
434 if ((copied_size
+ size
) > mmap_len
)
435 size
= mmap_len
- copied_size
;
438 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
439 data_not_copied
= copy_from_user(
440 (void *)(stream_bufs
->addr
+ copied_size
),
442 if (data_not_copied
> 0) {
443 /* Clean up the list and return error code */
447 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
448 struct snd_sst_user_cap_list
*entry
=
449 kzalloc(sizeof(*entry
), GFP_KERNEL
);
455 entry
->iov_index
= index
;
456 entry
->iov_offset
= (unsigned long) bufp
-
457 (unsigned long)iovec
[index
].iov_base
;
458 entry
->offset
= copied_size
;
460 list_add_tail(&entry
->node
, copy_to_list
);
463 stream
->cur_ptr
= bufp
+ size
;
465 if (((unsigned long)iovec
[index
].iov_base
466 + iovec
[index
].iov_len
) <
467 ((unsigned long)iovec
[index
].iov_base
)) {
468 pr_debug("sst: Buffer overflows");
473 if (((unsigned long)iovec
[index
].iov_base
474 + iovec
[index
].iov_len
) ==
475 (unsigned long)stream
->cur_ptr
) {
476 stream
->cur_ptr
= NULL
;
481 pr_debug("sst: copied_size - %lx\n", copied_size
);
482 if ((copied_size
>= mmap_len
) ||
483 (stream
->sg_index
== nr_segs
)) {
488 stream_bufs
->in_use
= false;
489 stream_bufs
->size
= copied_size
;
491 mutex_lock(&stream
->lock
);
492 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
493 mutex_unlock(&stream
->lock
);
500 /* This function copies the captured data returned from SST DSP engine
501 * to the user buffers*/
502 static int snd_sst_copy_userbuf_capture(struct stream_info
*stream
,
503 const struct iovec
*iovec
,
504 struct list_head
*copy_to_list
)
506 struct snd_sst_user_cap_list
*entry
, *_entry
;
507 struct sst_stream_bufs
*kbufs
= NULL
, *_kbufs
;
509 unsigned long data_not_copied
;
511 /* copy sent buffers */
512 pr_debug("sst: capture stream copying to user now...\n");
513 list_for_each_entry_safe(kbufs
, _kbufs
, &stream
->bufs
, node
) {
514 if (kbufs
->in_use
== true) {
516 list_for_each_entry_safe(entry
, _entry
,
517 copy_to_list
, node
) {
518 data_not_copied
= copy_to_user((void *)
519 iovec
[entry
->iov_index
].iov_base
+
521 kbufs
->addr
+ entry
->offset
,
523 if (data_not_copied
> 0) {
524 /* Clean up the list and return error */
528 list_del(&entry
->node
);
533 pr_debug("sst: end of cap copy\n");
538 * snd_sst_userbufs_play_cap - constructs the list from user buffers
540 * @iovec:pointer to iovec structure
541 * @nr_segs:number entries in the iovec structure
543 * @stream:pointer to stream_info structure
545 * This function will traverse the user list and copy the data to the kernel
548 static int snd_sst_userbufs_play_cap(const struct iovec
*iovec
,
549 unsigned long nr_segs
, unsigned int str_id
,
550 struct stream_info
*stream
)
553 LIST_HEAD(copy_to_list
);
556 retval
= snd_sst_fill_kernel_list(stream
, iovec
, nr_segs
,
559 retval
= intel_sst_play_capture(stream
, str_id
);
563 if (stream
->ops
== STREAM_OPS_CAPTURE
) {
564 retval
= snd_sst_copy_userbuf_capture(stream
, iovec
,
570 /* This function is common function across read/write
571 for user buffers called from system calls*/
572 static int intel_sst_read_write(unsigned int str_id
, char __user
*buf
,
576 struct stream_info
*stream
;
578 unsigned long nr_segs
;
580 retval
= sst_validate_strid(str_id
);
583 stream
= &sst_drv_ctx
->streams
[str_id
];
584 if (stream
->mmapped
== true) {
585 pr_warn("sst: user write and stream is mapped");
590 stream
->curr_bytes
= 0;
591 stream
->cumm_bytes
= 0;
592 /* copy user buf details */
593 pr_debug("sst: new buffers %p, copy size %d, status %d\n" ,
594 buf
, (int) count
, (int) stream
->status
);
596 stream
->buf_type
= SST_BUF_USER_STATIC
;
597 iovec
.iov_base
= (void *)buf
;
598 iovec
.iov_len
= count
;
602 retval
= snd_sst_userbufs_play_cap(
603 &iovec
, nr_segs
, str_id
, stream
);
607 } while (stream
->sg_index
< nr_segs
);
609 stream
->sg_index
= 0;
610 stream
->cur_ptr
= NULL
;
612 retval
= stream
->cumm_bytes
;
613 pr_debug("sst: end of play/rec bytes = %d!!\n", retval
);
618 * intel_sst_write - This function is called when user tries to play out data
620 * @file_ptr:pointer to file
621 * @buf:user buffer to be played out
622 * @count:size of tthe buffer
623 * @offset:offset to start from
625 * writes the encoded data into DSP
627 int intel_sst_write(struct file
*file_ptr
, const char __user
*buf
,
628 size_t count
, loff_t
*offset
)
630 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
631 int str_id
= data
->str_id
;
632 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
634 pr_debug("sst: called for %d\n", str_id
);
635 if (stream
->status
== STREAM_UN_INIT
||
636 stream
->status
== STREAM_DECODE
) {
639 return intel_sst_read_write(str_id
, (char __user
*)buf
, count
);
643 * intel_sst_aio_write - write buffers
645 * @kiocb:pointer to a structure containing file pointer
646 * @iov:list of user buffer to be played out
647 * @nr_segs:number of entries
648 * @offset:offset to start from
650 * This function is called when user tries to play out multiple data buffers
652 ssize_t
intel_sst_aio_write(struct kiocb
*kiocb
, const struct iovec
*iov
,
653 unsigned long nr_segs
, loff_t offset
)
656 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
657 int str_id
= data
->str_id
;
658 struct stream_info
*stream
;
660 pr_debug("sst: entry - %ld\n", nr_segs
);
662 if (is_sync_kiocb(kiocb
) == false)
665 pr_debug("sst: called for str_id %d\n", str_id
);
666 retval
= sst_validate_strid(str_id
);
669 stream
= &sst_drv_ctx
->streams
[str_id
];
670 if (stream
->mmapped
== true)
672 if (stream
->status
== STREAM_UN_INIT
||
673 stream
->status
== STREAM_DECODE
) {
676 stream
->curr_bytes
= 0;
677 stream
->cumm_bytes
= 0;
678 pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
679 nr_segs
, (int) offset
, (int) stream
->status
);
680 stream
->buf_type
= SST_BUF_USER_STATIC
;
682 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
687 } while (stream
->sg_index
< nr_segs
);
689 stream
->sg_index
= 0;
690 stream
->cur_ptr
= NULL
;
692 retval
= stream
->cumm_bytes
;
693 pr_debug("sst: end of play/rec bytes = %d!!\n", retval
);
698 * intel_sst_read - read the encoded data
700 * @file_ptr: pointer to file
701 * @buf: user buffer to be filled with captured data
702 * @count: size of tthe buffer
703 * @offset: offset to start from
705 * This function is called when user tries to capture data
707 int intel_sst_read(struct file
*file_ptr
, char __user
*buf
,
708 size_t count
, loff_t
*offset
)
710 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
711 int str_id
= data
->str_id
;
712 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
714 pr_debug("sst: called for %d\n", str_id
);
715 if (stream
->status
== STREAM_UN_INIT
||
716 stream
->status
== STREAM_DECODE
)
718 return intel_sst_read_write(str_id
, buf
, count
);
722 * intel_sst_aio_read - aio read
724 * @kiocb: pointer to a structure containing file pointer
725 * @iov: list of user buffer to be filled with captured
726 * @nr_segs: number of entries
727 * @offset: offset to start from
729 * This function is called when user tries to capture out multiple data buffers
731 ssize_t
intel_sst_aio_read(struct kiocb
*kiocb
, const struct iovec
*iov
,
732 unsigned long nr_segs
, loff_t offset
)
735 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
736 int str_id
= data
->str_id
;
737 struct stream_info
*stream
;
739 pr_debug("sst: entry - %ld\n", nr_segs
);
741 if (is_sync_kiocb(kiocb
) == false) {
742 pr_debug("sst: aio_read from user space is not allowed\n");
746 pr_debug("sst: called for str_id %d\n", str_id
);
747 retval
= sst_validate_strid(str_id
);
750 stream
= &sst_drv_ctx
->streams
[str_id
];
751 if (stream
->mmapped
== true)
753 if (stream
->status
== STREAM_UN_INIT
||
754 stream
->status
== STREAM_DECODE
)
756 stream
->curr_bytes
= 0;
757 stream
->cumm_bytes
= 0;
759 pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
760 nr_segs
, (int) offset
, (int) stream
->status
);
761 stream
->buf_type
= SST_BUF_USER_STATIC
;
763 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
768 } while (stream
->sg_index
< nr_segs
);
770 stream
->sg_index
= 0;
771 stream
->cur_ptr
= NULL
;
773 retval
= stream
->cumm_bytes
;
774 pr_debug("sst: end of play/rec bytes = %d!!\n", retval
);
778 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
779 static void sst_print_stream_params(struct snd_sst_get_stream_params
*get_prm
)
781 pr_debug("sst: codec params:result =%d\n",
782 get_prm
->codec_params
.result
);
783 pr_debug("sst: codec params:stream = %d\n",
784 get_prm
->codec_params
.stream_id
);
785 pr_debug("sst: codec params:codec = %d\n",
786 get_prm
->codec_params
.codec
);
787 pr_debug("sst: codec params:ops = %d\n",
788 get_prm
->codec_params
.ops
);
789 pr_debug("sst: codec params:stream_type= %d\n",
790 get_prm
->codec_params
.stream_type
);
791 pr_debug("sst: pcmparams:sfreq= %d\n",
792 get_prm
->pcm_params
.sfreq
);
793 pr_debug("sst: pcmparams:num_chan= %d\n",
794 get_prm
->pcm_params
.num_chan
);
795 pr_debug("sst: pcmparams:pcm_wd_sz= %d\n",
796 get_prm
->pcm_params
.pcm_wd_sz
);
801 * intel_sst_ioctl - recieves the device ioctl's
802 * @file_ptr:pointer to file
806 * This function is called by OS when a user space component
807 * sends an Ioctl to SST driver
809 long intel_sst_ioctl(struct file
*file_ptr
, unsigned int cmd
, unsigned long arg
)
812 struct ioctl_pvt_data
*data
= NULL
;
813 int str_id
= 0, minor
= 0;
815 data
= file_ptr
->private_data
;
818 str_id
= data
->str_id
;
822 if (sst_drv_ctx
->sst_state
!= SST_FW_RUNNING
)
825 switch (_IOC_NR(cmd
)) {
826 case _IOC_NR(SNDRV_SST_STREAM_PAUSE
):
827 pr_debug("sst: IOCTL_PAUSE recieved for %d!\n", str_id
);
828 if (minor
!= STREAM_MODULE
) {
832 retval
= sst_pause_stream(str_id
);
835 case _IOC_NR(SNDRV_SST_STREAM_RESUME
):
836 pr_debug("sst: SNDRV_SST_IOCTL_RESUME recieved!\n");
837 if (minor
!= STREAM_MODULE
) {
841 retval
= sst_resume_stream(str_id
);
844 case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS
): {
845 struct snd_sst_params
*str_param
= (struct snd_sst_params
*)arg
;
847 pr_debug("sst: IOCTL_SET_PARAMS recieved!\n");
848 if (minor
!= STREAM_MODULE
) {
855 retval
= sst_get_stream(str_param
);
857 struct stream_info
*str_info
;
858 sst_drv_ctx
->stream_cnt
++;
859 data
->str_id
= retval
;
860 str_info
= &sst_drv_ctx
->streams
[retval
];
861 str_info
->src
= SST_DRV
;
862 retval
= copy_to_user(&str_param
->stream_id
,
863 &retval
, sizeof(__u32
));
867 if (retval
== -SST_ERR_INVALID_PARAMS
)
871 pr_debug("sst: SET_STREAM_PARAMS recieved!\n");
872 /* allocated set params only */
873 retval
= sst_set_stream_param(str_id
, str_param
);
874 /* Block the call for reply */
876 int sfreq
= 0, word_size
= 0, num_channel
= 0;
877 sfreq
= str_param
->sparams
.uc
.pcm_params
.sfreq
;
878 word_size
= str_param
->sparams
.
879 uc
.pcm_params
.pcm_wd_sz
;
880 num_channel
= str_param
->
881 sparams
.uc
.pcm_params
.num_chan
;
882 if (str_param
->ops
== STREAM_OPS_CAPTURE
) {
883 sst_drv_ctx
->scard_ops
->\
884 set_pcm_audio_params(sfreq
,
885 word_size
, num_channel
);
891 case _IOC_NR(SNDRV_SST_SET_VOL
): {
892 struct snd_sst_vol
*set_vol
;
893 struct snd_sst_vol
*rec_vol
= (struct snd_sst_vol
*)arg
;
894 pr_debug("sst: SET_VOLUME recieved for %d!\n",
896 if (minor
== STREAM_MODULE
&& rec_vol
->stream_id
== 0) {
897 pr_debug("sst: invalid operation!\n");
901 set_vol
= kzalloc(sizeof(*set_vol
), GFP_ATOMIC
);
903 pr_debug("sst: mem allocation failed\n");
907 retval
= copy_from_user(set_vol
, rec_vol
, sizeof(*set_vol
));
909 pr_debug("sst: copy failed\n");
913 retval
= sst_set_vol(set_vol
);
917 case _IOC_NR(SNDRV_SST_GET_VOL
): {
918 struct snd_sst_vol
*rec_vol
= (struct snd_sst_vol
*)arg
;
919 struct snd_sst_vol get_vol
;
920 pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
922 if (minor
== STREAM_MODULE
&& rec_vol
->stream_id
== 0) {
923 pr_debug("sst: invalid operation!\n");
927 get_vol
.stream_id
= rec_vol
->stream_id
;
928 retval
= sst_get_vol(&get_vol
);
933 pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
934 get_vol
.stream_id
, get_vol
.volume
,
935 get_vol
.ramp_duration
, get_vol
.ramp_type
);
936 retval
= copy_to_user((struct snd_sst_vol
*)arg
,
937 &get_vol
, sizeof(get_vol
));
942 /*sst_print_get_vol_info(str_id, &get_vol);*/
946 case _IOC_NR(SNDRV_SST_MUTE
): {
947 struct snd_sst_mute
*set_mute
;
948 struct snd_sst_vol
*rec_mute
= (struct snd_sst_vol
*)arg
;
949 pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
950 rec_mute
->stream_id
);
951 if (minor
== STREAM_MODULE
&& rec_mute
->stream_id
== 0) {
955 set_mute
= kzalloc(sizeof(*set_mute
), GFP_ATOMIC
);
960 retval
= copy_from_user(set_mute
, rec_mute
, sizeof(*set_mute
));
965 retval
= sst_set_mute(set_mute
);
969 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS
): {
970 struct snd_sst_get_stream_params get_params
;
972 pr_debug("sst: IOCTL_GET_PARAMS recieved!\n");
978 retval
= sst_get_stream_params(str_id
, &get_params
);
983 retval
= copy_to_user((struct snd_sst_get_stream_params
*)arg
,
984 &get_params
, sizeof(get_params
));
989 sst_print_stream_params(&get_params
);
993 case _IOC_NR(SNDRV_SST_MMAP_PLAY
):
994 case _IOC_NR(SNDRV_SST_MMAP_CAPTURE
):
995 pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
996 if (minor
!= STREAM_MODULE
) {
1000 retval
= intel_sst_mmap_play_capture(str_id
,
1001 (struct snd_sst_mmap_buffs
*)arg
);
1004 case _IOC_NR(SNDRV_SST_STREAM_DROP
):
1005 pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n");
1006 if (minor
!= STREAM_MODULE
) {
1010 retval
= sst_drop_stream(str_id
);
1013 case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP
): {
1014 unsigned long long *ms
= (unsigned long long *)arg
;
1015 struct snd_sst_tstamp tstamp
= {0};
1016 unsigned long long time
, freq
, mod
;
1018 pr_debug("sst: SNDRV_SST_STREAM_GET_TSTAMP recieved!\n");
1019 if (minor
!= STREAM_MODULE
) {
1023 memcpy_fromio(&tstamp
,
1024 ((void *)(sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
)
1025 +(str_id
* sizeof(tstamp
))),
1027 time
= tstamp
.samples_rendered
;
1028 freq
= (unsigned long long) tstamp
.sampling_frequency
;
1029 time
= time
* 1000; /* converting it to ms */
1030 mod
= do_div(time
, freq
);
1031 retval
= copy_to_user(ms
, &time
, sizeof(*ms
));
1037 case _IOC_NR(SNDRV_SST_STREAM_START
):{
1038 struct stream_info
*stream
;
1040 pr_debug("sst: SNDRV_SST_STREAM_START recieved!\n");
1041 if (minor
!= STREAM_MODULE
) {
1045 retval
= sst_validate_strid(str_id
);
1048 stream
= &sst_drv_ctx
->streams
[str_id
];
1049 mutex_lock(&stream
->lock
);
1050 if (stream
->status
== STREAM_INIT
&&
1051 stream
->need_draining
!= true) {
1052 stream
->prev
= stream
->status
;
1053 stream
->status
= STREAM_RUNNING
;
1054 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
1055 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
1056 retval
= sst_play_frame(str_id
);
1057 } else if (stream
->ops
== STREAM_OPS_CAPTURE
)
1058 retval
= sst_capture_frame(str_id
);
1061 mutex_unlock(&stream
->lock
);
1065 stream
->status
= STREAM_INIT
;
1066 mutex_unlock(&stream
->lock
);
1072 mutex_unlock(&stream
->lock
);
1076 case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE
): {
1077 struct snd_sst_target_device
*target_device
;
1079 pr_debug("sst: SET_TARGET_DEVICE recieved!\n");
1080 target_device
= (struct snd_sst_target_device
*)arg
;
1081 BUG_ON(!target_device
);
1082 if (minor
!= AM_MODULE
) {
1086 retval
= sst_target_device_select(target_device
);
1090 case _IOC_NR(SNDRV_SST_DRIVER_INFO
): {
1091 struct snd_sst_driver_info
*info
=
1092 (struct snd_sst_driver_info
*)arg
;
1094 pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n");
1095 info
->version
= SST_VERSION_NUM
;
1096 /* hard coding, shud get sumhow later */
1097 info
->active_pcm_streams
= sst_drv_ctx
->stream_cnt
-
1098 sst_drv_ctx
->encoded_cnt
;
1099 info
->active_enc_streams
= sst_drv_ctx
->encoded_cnt
;
1100 info
->max_pcm_streams
= MAX_ACTIVE_STREAM
- MAX_ENC_STREAM
;
1101 info
->max_enc_streams
= MAX_ENC_STREAM
;
1102 info
->buf_per_stream
= sst_drv_ctx
->mmap_len
;
1106 case _IOC_NR(SNDRV_SST_STREAM_DECODE
): {
1107 struct snd_sst_dbufs
*param
=
1108 (struct snd_sst_dbufs
*)arg
, dbufs_local
;
1110 struct snd_sst_buffs ibufs
, obufs
;
1111 struct snd_sst_buff_entry ibuf_temp
[param
->ibufs
->entries
],
1112 obuf_temp
[param
->obufs
->entries
];
1114 pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n");
1115 if (minor
!= STREAM_MODULE
) {
1124 dbufs_local
.input_bytes_consumed
= param
->input_bytes_consumed
;
1125 dbufs_local
.output_bytes_produced
=
1126 param
->output_bytes_produced
;
1127 dbufs_local
.ibufs
= &ibufs
;
1128 dbufs_local
.obufs
= &obufs
;
1129 dbufs_local
.ibufs
->entries
= param
->ibufs
->entries
;
1130 dbufs_local
.ibufs
->type
= param
->ibufs
->type
;
1131 dbufs_local
.obufs
->entries
= param
->obufs
->entries
;
1132 dbufs_local
.obufs
->type
= param
->obufs
->type
;
1134 dbufs_local
.ibufs
->buff_entry
= ibuf_temp
;
1135 for (i
= 0; i
< dbufs_local
.ibufs
->entries
; i
++) {
1136 ibuf_temp
[i
].buffer
=
1137 param
->ibufs
->buff_entry
[i
].buffer
;
1139 param
->ibufs
->buff_entry
[i
].size
;
1141 dbufs_local
.obufs
->buff_entry
= obuf_temp
;
1142 for (i
= 0; i
< dbufs_local
.obufs
->entries
; i
++) {
1143 obuf_temp
[i
].buffer
=
1144 param
->obufs
->buff_entry
[i
].buffer
;
1146 param
->obufs
->buff_entry
[i
].size
;
1148 retval
= sst_decode(str_id
, &dbufs_local
);
1151 retval
= copy_to_user(¶m
->input_bytes_consumed
,
1152 &dbufs_local
.input_bytes_consumed
,
1153 sizeof(unsigned long long));
1158 retval
= copy_to_user(¶m
->output_bytes_produced
,
1159 &dbufs_local
.output_bytes_produced
,
1160 sizeof(unsigned long long));
1168 case _IOC_NR(SNDRV_SST_STREAM_DRAIN
):
1169 pr_debug("sst: SNDRV_SST_STREAM_DRAIN recived\n");
1170 if (minor
!= STREAM_MODULE
) {
1174 retval
= sst_drain_stream(str_id
);
1177 case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED
): {
1178 unsigned long long *bytes
= (unsigned long long *)arg
;
1179 struct snd_sst_tstamp tstamp
= {0};
1181 pr_debug("sst: STREAM_BYTES_DECODED recieved!\n");
1182 if (minor
!= STREAM_MODULE
) {
1186 memcpy_fromio(&tstamp
,
1187 ((void *)(sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
)
1188 +(str_id
* sizeof(tstamp
))),
1190 retval
= copy_to_user(bytes
, &tstamp
.bytes_processed
,
1196 case _IOC_NR(SNDRV_SST_FW_INFO
): {
1197 struct snd_sst_fw_info
*fw_info
;
1199 pr_debug("sst: SNDRV_SST_FW_INFO recived\n");
1201 fw_info
= kzalloc(sizeof(*fw_info
), GFP_ATOMIC
);
1206 retval
= sst_get_fw_info(fw_info
);
1212 retval
= copy_to_user((struct snd_sst_dbufs
*)arg
,
1213 fw_info
, sizeof(*fw_info
));
1219 /*sst_print_fw_info(fw_info);*/
1226 pr_debug("sst: intel_sst_ioctl:complete ret code = %d\n", retval
);