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
;
247 struct snd_sst_mmap_buff_entry
*tmp_buf
;
249 pr_debug("sst:called for str_id %d\n", str_id
);
250 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 tmp_buf
= kcalloc(mmap_buf
->entries
, sizeof(*tmp_buf
), GFP_KERNEL
);
268 if (copy_from_user(tmp_buf
, (void __user
*)mmap_buf
->buff
,
269 mmap_buf
->entries
* sizeof(*tmp_buf
))) {
274 pr_debug("sst:new buffers count %d status %d\n",
275 mmap_buf
->entries
, stream
->status
);
277 for (i
= 0; i
< mmap_buf
->entries
; i
++) {
278 bufs
= kzalloc(sizeof(*bufs
), GFP_KERNEL
);
283 bufs
->size
= buf_entry
->size
;
284 bufs
->offset
= buf_entry
->offset
;
285 bufs
->addr
= sst_drv_ctx
->mmap_mem
;
286 bufs
->in_use
= false;
289 mutex_lock(&stream
->lock
);
290 list_add_tail(&bufs
->node
, &stream
->bufs
);
291 mutex_unlock(&stream
->lock
);
294 mutex_lock(&stream
->lock
);
295 stream
->data_blk
.condition
= false;
296 stream
->data_blk
.ret_code
= 0;
297 if (stream
->status
== STREAM_INIT
&&
298 stream
->prev
!= STREAM_UN_INIT
&&
299 stream
->need_draining
!= true) {
300 stream
->prev
= stream
->status
;
301 stream
->status
= STREAM_RUNNING
;
302 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
303 if (sst_play_frame(str_id
) < 0) {
304 pr_warn("sst: play frames fail\n");
305 mutex_unlock(&stream
->lock
);
309 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
310 if (sst_capture_frame(str_id
) < 0) {
311 pr_warn("sst: capture frame fail\n");
312 mutex_unlock(&stream
->lock
);
318 mutex_unlock(&stream
->lock
);
319 /* Block the call for reply */
320 if (!list_empty(&stream
->bufs
)) {
321 stream
->data_blk
.on
= true;
322 retval
= sst_wait_interruptible(sst_drv_ctx
,
327 retval
= stream
->cumm_bytes
;
328 pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval
);
335 /*sets user data buffers to play/capture*/
336 static int intel_sst_play_capture(struct stream_info
*stream
, int str_id
)
340 stream
->data_blk
.ret_code
= 0;
341 stream
->data_blk
.on
= true;
342 stream
->data_blk
.condition
= false;
344 mutex_lock(&stream
->lock
);
345 if (stream
->status
== STREAM_INIT
&& stream
->prev
!= STREAM_UN_INIT
) {
346 /* stream is started */
347 stream
->prev
= stream
->status
;
348 stream
->status
= STREAM_RUNNING
;
351 if (stream
->status
== STREAM_INIT
&& stream
->prev
== STREAM_UN_INIT
) {
352 /* stream is not started yet */
353 pr_debug("sst: Stream isn't in started state %d, prev %d\n",
354 stream
->status
, stream
->prev
);
355 } else if ((stream
->status
== STREAM_RUNNING
||
356 stream
->status
== STREAM_PAUSED
) &&
357 stream
->need_draining
!= true) {
358 /* stream is started */
359 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
360 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
361 if (sst_play_frame(str_id
) < 0) {
362 pr_warn("sst: play frames failed\n");
363 mutex_unlock(&stream
->lock
);
366 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
367 if (sst_capture_frame(str_id
) < 0) {
368 pr_warn("sst: capture frames failed\n ");
369 mutex_unlock(&stream
->lock
);
374 mutex_unlock(&stream
->lock
);
377 mutex_unlock(&stream
->lock
);
378 /* Block the call for reply */
380 retval
= sst_wait_interruptible(sst_drv_ctx
, &stream
->data_blk
);
382 stream
->status
= STREAM_INIT
;
383 pr_debug("sst: wait returned error...\n");
388 /* fills kernel list with buffer addresses for SST DSP driver to process*/
389 static int snd_sst_fill_kernel_list(struct stream_info
*stream
,
390 const struct iovec
*iovec
, unsigned long nr_segs
,
391 struct list_head
*copy_to_list
)
393 struct sst_stream_bufs
*stream_bufs
;
394 unsigned long index
, mmap_len
;
395 unsigned char __user
*bufp
;
396 unsigned long size
, copied_size
;
397 int retval
= 0, add_to_list
= 0;
398 static int sent_offset
;
399 static unsigned long sent_index
;
401 stream_bufs
= kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
404 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
405 #ifdef CONFIG_MRST_RAR_HANDLER
406 if (stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
407 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
409 struct sst_stream_bufs
*stream_bufs
=
410 kzalloc(sizeof(*stream_bufs
), GFP_KERNEL
);
412 stream
->sg_index
= index
;
415 if (copy_from_user((void *) &rar_handle
,
416 iovec
[index
].iov_base
,
419 stream_bufs
->addr
= (char *)rar_handle
;
420 stream_bufs
->in_use
= false;
421 stream_bufs
->size
= iovec
[0].iov_len
;
423 mutex_lock(&stream
->lock
);
424 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
425 mutex_unlock(&stream
->lock
);
427 stream
->sg_index
= index
;
431 mmap_len
= sst_drv_ctx
->mmap_len
;
432 stream_bufs
->addr
= sst_drv_ctx
->mmap_mem
;
433 bufp
= stream
->cur_ptr
;
437 if (!stream
->sg_index
)
438 sent_index
= sent_offset
= 0;
440 for (index
= stream
->sg_index
; index
< nr_segs
; index
++) {
441 stream
->sg_index
= index
;
442 if (!stream
->cur_ptr
)
443 bufp
= iovec
[index
].iov_base
;
445 size
= ((unsigned long)iovec
[index
].iov_base
446 + iovec
[index
].iov_len
) - (unsigned long) bufp
;
448 if ((copied_size
+ size
) > mmap_len
)
449 size
= mmap_len
- copied_size
;
452 if (stream
->ops
== STREAM_OPS_PLAYBACK
) {
453 if (copy_from_user((void *)
454 (stream_bufs
->addr
+ copied_size
),
456 /* Clean up the list and return error code */
460 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
461 struct snd_sst_user_cap_list
*entry
=
462 kzalloc(sizeof(*entry
), GFP_KERNEL
);
468 entry
->iov_index
= index
;
469 entry
->iov_offset
= (unsigned long) bufp
-
470 (unsigned long)iovec
[index
].iov_base
;
471 entry
->offset
= copied_size
;
473 list_add_tail(&entry
->node
, copy_to_list
);
476 stream
->cur_ptr
= bufp
+ size
;
478 if (((unsigned long)iovec
[index
].iov_base
479 + iovec
[index
].iov_len
) <
480 ((unsigned long)iovec
[index
].iov_base
)) {
481 pr_debug("sst: Buffer overflows");
486 if (((unsigned long)iovec
[index
].iov_base
487 + iovec
[index
].iov_len
) ==
488 (unsigned long)stream
->cur_ptr
) {
489 stream
->cur_ptr
= NULL
;
494 pr_debug("sst: copied_size - %lx\n", copied_size
);
495 if ((copied_size
>= mmap_len
) ||
496 (stream
->sg_index
== nr_segs
)) {
501 stream_bufs
->in_use
= false;
502 stream_bufs
->size
= copied_size
;
504 mutex_lock(&stream
->lock
);
505 list_add_tail(&stream_bufs
->node
, &stream
->bufs
);
506 mutex_unlock(&stream
->lock
);
513 /* This function copies the captured data returned from SST DSP engine
514 * to the user buffers*/
515 static int snd_sst_copy_userbuf_capture(struct stream_info
*stream
,
516 const struct iovec
*iovec
,
517 struct list_head
*copy_to_list
)
519 struct snd_sst_user_cap_list
*entry
, *_entry
;
520 struct sst_stream_bufs
*kbufs
= NULL
, *_kbufs
;
523 /* copy sent buffers */
524 pr_debug("sst: capture stream copying to user now...\n");
525 list_for_each_entry_safe(kbufs
, _kbufs
, &stream
->bufs
, node
) {
526 if (kbufs
->in_use
== true) {
528 list_for_each_entry_safe(entry
, _entry
,
529 copy_to_list
, node
) {
530 if (copy_to_user(iovec
[entry
->iov_index
].iov_base
+ entry
->iov_offset
,
531 kbufs
->addr
+ entry
->offset
,
533 /* Clean up the list and return error */
537 list_del(&entry
->node
);
542 pr_debug("sst: end of cap copy\n");
547 * snd_sst_userbufs_play_cap - constructs the list from user buffers
549 * @iovec:pointer to iovec structure
550 * @nr_segs:number entries in the iovec structure
552 * @stream:pointer to stream_info structure
554 * This function will traverse the user list and copy the data to the kernel
557 static int snd_sst_userbufs_play_cap(const struct iovec
*iovec
,
558 unsigned long nr_segs
, unsigned int str_id
,
559 struct stream_info
*stream
)
562 LIST_HEAD(copy_to_list
);
565 retval
= snd_sst_fill_kernel_list(stream
, iovec
, nr_segs
,
568 retval
= intel_sst_play_capture(stream
, str_id
);
572 if (stream
->ops
== STREAM_OPS_CAPTURE
) {
573 retval
= snd_sst_copy_userbuf_capture(stream
, iovec
,
579 /* This function is common function across read/write
580 for user buffers called from system calls*/
581 static int intel_sst_read_write(unsigned int str_id
, char __user
*buf
,
585 struct stream_info
*stream
;
587 unsigned long nr_segs
;
589 retval
= sst_validate_strid(str_id
);
592 stream
= &sst_drv_ctx
->streams
[str_id
];
593 if (stream
->mmapped
== true) {
594 pr_warn("sst: user write and stream is mapped");
599 stream
->curr_bytes
= 0;
600 stream
->cumm_bytes
= 0;
601 /* copy user buf details */
602 pr_debug("sst: new buffers %p, copy size %d, status %d\n" ,
603 buf
, (int) count
, (int) stream
->status
);
605 stream
->buf_type
= SST_BUF_USER_STATIC
;
606 iovec
.iov_base
= buf
;
607 iovec
.iov_len
= count
;
611 retval
= snd_sst_userbufs_play_cap(
612 &iovec
, nr_segs
, str_id
, stream
);
616 } while (stream
->sg_index
< nr_segs
);
618 stream
->sg_index
= 0;
619 stream
->cur_ptr
= NULL
;
621 retval
= stream
->cumm_bytes
;
622 pr_debug("sst: end of play/rec bytes = %d!!\n", retval
);
627 * intel_sst_write - This function is called when user tries to play out data
629 * @file_ptr:pointer to file
630 * @buf:user buffer to be played out
631 * @count:size of tthe buffer
632 * @offset:offset to start from
634 * writes the encoded data into DSP
636 int intel_sst_write(struct file
*file_ptr
, const char __user
*buf
,
637 size_t count
, loff_t
*offset
)
639 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
640 int str_id
= data
->str_id
;
641 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
643 pr_debug("sst: called for %d\n", str_id
);
644 if (stream
->status
== STREAM_UN_INIT
||
645 stream
->status
== STREAM_DECODE
) {
648 return intel_sst_read_write(str_id
, (char __user
*)buf
, count
);
652 * intel_sst_aio_write - write buffers
654 * @kiocb:pointer to a structure containing file pointer
655 * @iov:list of user buffer to be played out
656 * @nr_segs:number of entries
657 * @offset:offset to start from
659 * This function is called when user tries to play out multiple data buffers
661 ssize_t
intel_sst_aio_write(struct kiocb
*kiocb
, const struct iovec
*iov
,
662 unsigned long nr_segs
, loff_t offset
)
665 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
666 int str_id
= data
->str_id
;
667 struct stream_info
*stream
;
669 pr_debug("sst: entry - %ld\n", nr_segs
);
671 if (is_sync_kiocb(kiocb
) == false)
674 pr_debug("sst: called for str_id %d\n", str_id
);
675 retval
= sst_validate_strid(str_id
);
678 stream
= &sst_drv_ctx
->streams
[str_id
];
679 if (stream
->mmapped
== true)
681 if (stream
->status
== STREAM_UN_INIT
||
682 stream
->status
== STREAM_DECODE
) {
685 stream
->curr_bytes
= 0;
686 stream
->cumm_bytes
= 0;
687 pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
688 nr_segs
, (int) offset
, (int) stream
->status
);
689 stream
->buf_type
= SST_BUF_USER_STATIC
;
691 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
696 } while (stream
->sg_index
< nr_segs
);
698 stream
->sg_index
= 0;
699 stream
->cur_ptr
= NULL
;
701 retval
= stream
->cumm_bytes
;
702 pr_debug("sst: end of play/rec bytes = %d!!\n", retval
);
707 * intel_sst_read - read the encoded data
709 * @file_ptr: pointer to file
710 * @buf: user buffer to be filled with captured data
711 * @count: size of tthe buffer
712 * @offset: offset to start from
714 * This function is called when user tries to capture data
716 int intel_sst_read(struct file
*file_ptr
, char __user
*buf
,
717 size_t count
, loff_t
*offset
)
719 struct ioctl_pvt_data
*data
= file_ptr
->private_data
;
720 int str_id
= data
->str_id
;
721 struct stream_info
*stream
= &sst_drv_ctx
->streams
[str_id
];
723 pr_debug("sst: called for %d\n", str_id
);
724 if (stream
->status
== STREAM_UN_INIT
||
725 stream
->status
== STREAM_DECODE
)
727 return intel_sst_read_write(str_id
, buf
, count
);
731 * intel_sst_aio_read - aio read
733 * @kiocb: pointer to a structure containing file pointer
734 * @iov: list of user buffer to be filled with captured
735 * @nr_segs: number of entries
736 * @offset: offset to start from
738 * This function is called when user tries to capture out multiple data buffers
740 ssize_t
intel_sst_aio_read(struct kiocb
*kiocb
, const struct iovec
*iov
,
741 unsigned long nr_segs
, loff_t offset
)
744 struct ioctl_pvt_data
*data
= kiocb
->ki_filp
->private_data
;
745 int str_id
= data
->str_id
;
746 struct stream_info
*stream
;
748 pr_debug("sst: entry - %ld\n", nr_segs
);
750 if (is_sync_kiocb(kiocb
) == false) {
751 pr_debug("sst: aio_read from user space is not allowed\n");
755 pr_debug("sst: called for str_id %d\n", str_id
);
756 retval
= sst_validate_strid(str_id
);
759 stream
= &sst_drv_ctx
->streams
[str_id
];
760 if (stream
->mmapped
== true)
762 if (stream
->status
== STREAM_UN_INIT
||
763 stream
->status
== STREAM_DECODE
)
765 stream
->curr_bytes
= 0;
766 stream
->cumm_bytes
= 0;
768 pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
769 nr_segs
, (int) offset
, (int) stream
->status
);
770 stream
->buf_type
= SST_BUF_USER_STATIC
;
772 retval
= snd_sst_userbufs_play_cap(iov
, nr_segs
,
777 } while (stream
->sg_index
< nr_segs
);
779 stream
->sg_index
= 0;
780 stream
->cur_ptr
= NULL
;
782 retval
= stream
->cumm_bytes
;
783 pr_debug("sst: end of play/rec bytes = %d!!\n", retval
);
787 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
788 static void sst_print_stream_params(struct snd_sst_get_stream_params
*get_prm
)
790 pr_debug("sst: codec params:result =%d\n",
791 get_prm
->codec_params
.result
);
792 pr_debug("sst: codec params:stream = %d\n",
793 get_prm
->codec_params
.stream_id
);
794 pr_debug("sst: codec params:codec = %d\n",
795 get_prm
->codec_params
.codec
);
796 pr_debug("sst: codec params:ops = %d\n",
797 get_prm
->codec_params
.ops
);
798 pr_debug("sst: codec params:stream_type= %d\n",
799 get_prm
->codec_params
.stream_type
);
800 pr_debug("sst: pcmparams:sfreq= %d\n",
801 get_prm
->pcm_params
.sfreq
);
802 pr_debug("sst: pcmparams:num_chan= %d\n",
803 get_prm
->pcm_params
.num_chan
);
804 pr_debug("sst: pcmparams:pcm_wd_sz= %d\n",
805 get_prm
->pcm_params
.pcm_wd_sz
);
810 * intel_sst_ioctl - recieves the device ioctl's
811 * @file_ptr:pointer to file
815 * This function is called by OS when a user space component
816 * sends an Ioctl to SST driver
818 long intel_sst_ioctl(struct file
*file_ptr
, unsigned int cmd
, unsigned long arg
)
821 struct ioctl_pvt_data
*data
= NULL
;
822 int str_id
= 0, minor
= 0;
824 data
= file_ptr
->private_data
;
827 str_id
= data
->str_id
;
831 if (sst_drv_ctx
->sst_state
!= SST_FW_RUNNING
)
834 switch (_IOC_NR(cmd
)) {
835 case _IOC_NR(SNDRV_SST_STREAM_PAUSE
):
836 pr_debug("sst: IOCTL_PAUSE recieved for %d!\n", str_id
);
837 if (minor
!= STREAM_MODULE
) {
841 retval
= sst_pause_stream(str_id
);
844 case _IOC_NR(SNDRV_SST_STREAM_RESUME
):
845 pr_debug("sst: SNDRV_SST_IOCTL_RESUME recieved!\n");
846 if (minor
!= STREAM_MODULE
) {
850 retval
= sst_resume_stream(str_id
);
853 case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS
): {
854 struct snd_sst_params str_param
;
856 pr_debug("sst: IOCTL_SET_PARAMS recieved!\n");
857 if (minor
!= STREAM_MODULE
) {
862 if (copy_from_user(&str_param
, (void __user
*)arg
,
863 sizeof(str_param
))) {
870 retval
= sst_get_stream(&str_param
);
872 struct stream_info
*str_info
;
875 sst_drv_ctx
->stream_cnt
++;
876 data
->str_id
= retval
;
877 str_info
= &sst_drv_ctx
->streams
[retval
];
878 str_info
->src
= SST_DRV
;
879 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_params
, stream_id
);
880 retval
= copy_to_user(dest
, &retval
, sizeof(__u32
));
884 if (retval
== -SST_ERR_INVALID_PARAMS
)
888 pr_debug("sst: SET_STREAM_PARAMS recieved!\n");
889 /* allocated set params only */
890 retval
= sst_set_stream_param(str_id
, &str_param
);
891 /* Block the call for reply */
893 int sfreq
= 0, word_size
= 0, num_channel
= 0;
894 sfreq
= str_param
.sparams
.uc
.pcm_params
.sfreq
;
895 word_size
= str_param
.sparams
.uc
.pcm_params
.pcm_wd_sz
;
896 num_channel
= str_param
.sparams
.uc
.pcm_params
.num_chan
;
897 if (str_param
.ops
== STREAM_OPS_CAPTURE
) {
898 sst_drv_ctx
->scard_ops
->\
899 set_pcm_audio_params(sfreq
,
900 word_size
, num_channel
);
906 case _IOC_NR(SNDRV_SST_SET_VOL
): {
907 struct snd_sst_vol set_vol
;
909 if (copy_from_user(&set_vol
, (void __user
*)arg
,
911 pr_debug("sst: copy failed\n");
915 pr_debug("sst: SET_VOLUME recieved for %d!\n",
917 if (minor
== STREAM_MODULE
&& set_vol
.stream_id
== 0) {
918 pr_debug("sst: invalid operation!\n");
922 retval
= sst_set_vol(&set_vol
);
925 case _IOC_NR(SNDRV_SST_GET_VOL
): {
926 struct snd_sst_vol get_vol
;
928 if (copy_from_user(&get_vol
, (void __user
*)arg
,
933 pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
935 if (minor
== STREAM_MODULE
&& get_vol
.stream_id
== 0) {
936 pr_debug("sst: invalid operation!\n");
940 retval
= sst_get_vol(&get_vol
);
945 pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
946 get_vol
.stream_id
, get_vol
.volume
,
947 get_vol
.ramp_duration
, get_vol
.ramp_type
);
948 if (copy_to_user((struct snd_sst_vol __user
*)arg
,
949 &get_vol
, sizeof(get_vol
))) {
953 /*sst_print_get_vol_info(str_id, &get_vol);*/
957 case _IOC_NR(SNDRV_SST_MUTE
): {
958 struct snd_sst_mute set_mute
;
960 if (copy_from_user(&set_mute
, (void __user
*)arg
,
965 pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
967 if (minor
== STREAM_MODULE
&& set_mute
.stream_id
== 0) {
971 retval
= sst_set_mute(&set_mute
);
974 case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS
): {
975 struct snd_sst_get_stream_params get_params
;
977 pr_debug("sst: IOCTL_GET_PARAMS recieved!\n");
983 retval
= sst_get_stream_params(str_id
, &get_params
);
988 if (copy_to_user((struct snd_sst_get_stream_params __user
*)arg
,
989 &get_params
, sizeof(get_params
))) {
993 sst_print_stream_params(&get_params
);
997 case _IOC_NR(SNDRV_SST_MMAP_PLAY
):
998 case _IOC_NR(SNDRV_SST_MMAP_CAPTURE
): {
999 struct snd_sst_mmap_buffs mmap_buf
;
1001 pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
1002 if (minor
!= STREAM_MODULE
) {
1006 if (copy_from_user(&mmap_buf
, (void __user
*)arg
,
1007 sizeof(mmap_buf
))) {
1011 retval
= intel_sst_mmap_play_capture(str_id
, &mmap_buf
);
1014 case _IOC_NR(SNDRV_SST_STREAM_DROP
):
1015 pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n");
1016 if (minor
!= STREAM_MODULE
) {
1020 retval
= sst_drop_stream(str_id
);
1023 case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP
): {
1024 struct snd_sst_tstamp tstamp
= {0};
1025 unsigned long long time
, freq
, mod
;
1027 pr_debug("sst: SNDRV_SST_STREAM_GET_TSTAMP recieved!\n");
1028 if (minor
!= STREAM_MODULE
) {
1032 memcpy_fromio(&tstamp
,
1033 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1035 time
= tstamp
.samples_rendered
;
1036 freq
= (unsigned long long) tstamp
.sampling_frequency
;
1037 time
= time
* 1000; /* converting it to ms */
1038 mod
= do_div(time
, freq
);
1039 if (copy_to_user((void __user
*)arg
, &time
,
1040 sizeof(unsigned long long)))
1045 case _IOC_NR(SNDRV_SST_STREAM_START
):{
1046 struct stream_info
*stream
;
1048 pr_debug("sst: SNDRV_SST_STREAM_START recieved!\n");
1049 if (minor
!= STREAM_MODULE
) {
1053 retval
= sst_validate_strid(str_id
);
1056 stream
= &sst_drv_ctx
->streams
[str_id
];
1057 mutex_lock(&stream
->lock
);
1058 if (stream
->status
== STREAM_INIT
&&
1059 stream
->need_draining
!= true) {
1060 stream
->prev
= stream
->status
;
1061 stream
->status
= STREAM_RUNNING
;
1062 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
1063 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
1064 retval
= sst_play_frame(str_id
);
1065 } else if (stream
->ops
== STREAM_OPS_CAPTURE
)
1066 retval
= sst_capture_frame(str_id
);
1069 mutex_unlock(&stream
->lock
);
1073 stream
->status
= STREAM_INIT
;
1074 mutex_unlock(&stream
->lock
);
1080 mutex_unlock(&stream
->lock
);
1084 case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE
): {
1085 struct snd_sst_target_device target_device
;
1087 pr_debug("sst: SET_TARGET_DEVICE recieved!\n");
1088 if (copy_from_user(&target_device
, (void __user
*)arg
,
1089 sizeof(target_device
))) {
1093 if (minor
!= AM_MODULE
) {
1097 retval
= sst_target_device_select(&target_device
);
1101 case _IOC_NR(SNDRV_SST_DRIVER_INFO
): {
1102 struct snd_sst_driver_info info
;
1104 pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n");
1105 info
.version
= SST_VERSION_NUM
;
1106 /* hard coding, shud get sumhow later */
1107 info
.active_pcm_streams
= sst_drv_ctx
->stream_cnt
-
1108 sst_drv_ctx
->encoded_cnt
;
1109 info
.active_enc_streams
= sst_drv_ctx
->encoded_cnt
;
1110 info
.max_pcm_streams
= MAX_ACTIVE_STREAM
- MAX_ENC_STREAM
;
1111 info
.max_enc_streams
= MAX_ENC_STREAM
;
1112 info
.buf_per_stream
= sst_drv_ctx
->mmap_len
;
1113 if (copy_to_user((void __user
*)arg
, &info
,
1119 case _IOC_NR(SNDRV_SST_STREAM_DECODE
): {
1120 struct snd_sst_dbufs param
;
1121 struct snd_sst_dbufs dbufs_local
;
1122 struct snd_sst_buffs ibufs
, obufs
;
1123 struct snd_sst_buff_entry
*ibuf_tmp
, *obuf_tmp
;
1126 pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n");
1127 if (minor
!= STREAM_MODULE
) {
1131 if (copy_from_user(¶m
, (void __user
*)arg
,
1137 dbufs_local
.input_bytes_consumed
= param
.input_bytes_consumed
;
1138 dbufs_local
.output_bytes_produced
=
1139 param
.output_bytes_produced
;
1141 if (copy_from_user(&ibufs
, (void __user
*)param
.ibufs
, sizeof(ibufs
))) {
1145 if (copy_from_user(&obufs
, (void __user
*)param
.obufs
, sizeof(obufs
))) {
1150 ibuf_tmp
= kcalloc(ibufs
.entries
, sizeof(*ibuf_tmp
), GFP_KERNEL
);
1151 obuf_tmp
= kcalloc(obufs
.entries
, sizeof(*obuf_tmp
), GFP_KERNEL
);
1152 if (!ibuf_tmp
|| !obuf_tmp
) {
1157 if (copy_from_user(ibuf_tmp
, (void __user
*)ibufs
.buff_entry
,
1158 ibufs
.entries
* sizeof(*ibuf_tmp
))) {
1162 ibufs
.buff_entry
= ibuf_tmp
;
1163 dbufs_local
.ibufs
= &ibufs
;
1165 if (copy_from_user(obuf_tmp
, (void __user
*)obufs
.buff_entry
,
1166 obufs
.entries
* sizeof(*obuf_tmp
))) {
1170 obufs
.buff_entry
= obuf_tmp
;
1171 dbufs_local
.obufs
= &obufs
;
1173 retval
= sst_decode(str_id
, &dbufs_local
);
1179 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1180 if (copy_to_user(dest
,
1181 &dbufs_local
.input_bytes_consumed
,
1182 sizeof(unsigned long long))) {
1187 dest
= (char __user
*)arg
+ offsetof(struct snd_sst_dbufs
, input_bytes_consumed
);
1188 if (copy_to_user(dest
,
1189 &dbufs_local
.output_bytes_produced
,
1190 sizeof(unsigned long long))) {
1200 case _IOC_NR(SNDRV_SST_STREAM_DRAIN
):
1201 pr_debug("sst: SNDRV_SST_STREAM_DRAIN recived\n");
1202 if (minor
!= STREAM_MODULE
) {
1206 retval
= sst_drain_stream(str_id
);
1209 case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED
): {
1210 unsigned long long __user
*bytes
= (unsigned long long __user
*)arg
;
1211 struct snd_sst_tstamp tstamp
= {0};
1213 pr_debug("sst: STREAM_BYTES_DECODED recieved!\n");
1214 if (minor
!= STREAM_MODULE
) {
1218 memcpy_fromio(&tstamp
,
1219 sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
+ str_id
* sizeof(tstamp
),
1221 if (copy_to_user(bytes
, &tstamp
.bytes_processed
,
1226 case _IOC_NR(SNDRV_SST_FW_INFO
): {
1227 struct snd_sst_fw_info
*fw_info
;
1229 pr_debug("sst: SNDRV_SST_FW_INFO recived\n");
1231 fw_info
= kzalloc(sizeof(*fw_info
), GFP_ATOMIC
);
1236 retval
= sst_get_fw_info(fw_info
);
1242 if (copy_to_user((struct snd_sst_dbufs __user
*)arg
,
1243 fw_info
, sizeof(*fw_info
))) {
1248 /*sst_print_fw_info(fw_info);*/
1255 pr_debug("sst: intel_sst_ioctl:complete ret code = %d\n", retval
);