Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / intel_sst / intel_sst_app_interface.c
1 /*
2  *  intel_sst_interface.c - Intel SST Driver for audio engine
3  *
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  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10  *
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.
14  *
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.
19  *
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.
23  *
24  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25  *  This driver exposes the audio engine functionalities to the ALSA
26  *      and middleware.
27  *  Upper layer interfaces (MAD driver, MMF) to SST driver
28  */
29
30 #include <linux/pci.h>
31 #include <linux/fs.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"
41 #endif
42 #include "intel_sst.h"
43 #include "intel_sst_ioctl.h"
44 #include "intel_sst_fw_ipc.h"
45 #include "intel_sst_common.h"
46
47 #define AM_MODULE 1
48 #define STREAM_MODULE 0
49
50
51 /**
52 * intel_sst_check_device - checks SST device
53 *
54 * This utility function checks the state of SST device and downlaods FW if
55 * not done, or resumes the device if suspended
56 */
57
58 static int intel_sst_check_device(void)
59 {
60         int retval = 0;
61         if (sst_drv_ctx->pmic_state != SND_MAD_INIT_DONE) {
62                 pr_warn("sst: Sound card not availble\n ");
63                 return -EIO;
64         }
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);
68                 if (retval) {
69                         pr_debug("sst: Resume Failed= %#x,abort\n", retval);
70                         return retval;
71                 }
72         }
73
74         if (sst_drv_ctx->sst_state == SST_UN_INIT) {
75                 /* FW is not downloaded */
76                 retval = sst_download_fw();
77                 if (retval)
78                         return -ENODEV;
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);
84                 }
85         }
86         return 0;
87 }
88
89 /**
90  * intel_sst_open - opens a handle to driver
91  *
92  * @i_node:     inode structure
93  * @file_ptr:pointer to file
94  *
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
97  * will be allowed
98  */
99 int intel_sst_open(struct inode *i_node, struct file *file_ptr)
100 {
101         int retval = intel_sst_check_device();
102         if (retval)
103                 return retval;
104
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);
109                 if (!data) {
110                         mutex_unlock(&sst_drv_ctx->stream_lock);
111                         return -ENOMEM;
112                 }
113
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);
117                 data->str_id = 0;
118                 file_ptr->private_data = (void *)data;
119                 pr_debug("sst: pvt_id handle = %d!\n", data->pvt_id);
120         } else {
121                 retval = -EUSERS;
122                 mutex_unlock(&sst_drv_ctx->stream_lock);
123         }
124         return retval;
125 }
126
127 /**
128  * intel_sst_open_cntrl - opens a handle to driver
129  *
130  * @i_node:     inode structure
131  * @file_ptr:pointer to file
132  *
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
137  */
138 int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr)
139 {
140         int retval = intel_sst_check_device();
141         if (retval)
142                 return retval;
143
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;
150         } else
151                 retval = -EACCES;
152
153         mutex_unlock(&sst_drv_ctx->stream_lock);
154         return retval;
155 }
156
157 /**
158  * intel_sst_release - releases a handle to driver
159  *
160  * @i_node:     inode structure
161  * @file_ptr:   pointer to file
162  *
163  * This function is called by OS when a user space component
164  * tries to release a driver handle.
165  */
166 int intel_sst_release(struct inode *i_node, struct file *file_ptr)
167 {
168         struct ioctl_pvt_data *data = file_ptr->private_data;
169
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);
176         kfree(data);
177         return 0;
178 }
179
180 int intel_sst_release_cntrl(struct inode *i_node, struct file *file_ptr)
181 {
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");
187         return 0;
188 }
189
190 /**
191 * intel_sst_mmap - mmaps a kernel buffer to user space for copying data
192 *
193 * @vma:         vm area structure instance
194 * @file_ptr:    pointer to file
195 *
196 * This function is called by OS when a user space component
197 * tries to get mmap memory from driver
198 */
199 int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma)
200 {
201         int retval, length;
202         struct ioctl_pvt_data *data =
203                 (struct ioctl_pvt_data *)file_ptr->private_data;
204         int str_id = data->str_id;
205         void *mem_area;
206
207         retval = sst_validate_strid(str_id);
208         if (retval)
209                 return -EINVAL;
210
211         length = vma->vm_end - vma->vm_start;
212         pr_debug("sst: called for stream %d length 0x%x\n", str_id, length);
213
214         if (length > sst_drv_ctx->mmap_len)
215                 return -ENOMEM;
216         if (!sst_drv_ctx->mmap_mem)
217                 return -EIO;
218
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);
223
224         /* map the whole physically contiguous area in one piece  */
225         retval = remap_pfn_range(vma,
226                         vma->vm_start,
227                         virt_to_phys((void *)mem_area) >> PAGE_SHIFT,
228                         length,
229                         vma->vm_page_prot);
230         if (retval)
231                 sst_drv_ctx->streams[str_id].mmapped = false;
232         else
233                 sst_drv_ctx->streams[str_id].mmapped = true;
234
235         pr_debug("sst: mmap ret 0x%x\n", retval);
236         return retval;
237 }
238
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)
242 {
243         struct sst_stream_bufs *bufs;
244         int retval, i;
245         struct stream_info *stream;
246         struct snd_sst_mmap_buff_entry *buf_entry;
247
248         pr_debug("sst:called for str_id %d\n", str_id);
249         retval = sst_validate_strid(str_id);
250         if (retval)
251                 return -EINVAL;
252         BUG_ON(!mmap_buf);
253
254         stream = &sst_drv_ctx->streams[str_id];
255         if (stream->mmapped != true)
256                 return -EIO;
257
258         if (stream->status == STREAM_UN_INIT ||
259                 stream->status == STREAM_DECODE) {
260                 return -EBADRQC;
261         }
262         stream->curr_bytes = 0;
263         stream->cumm_bytes = 0;
264
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++) {
269                 BUG_ON(!buf_entry);
270                 bufs = kzalloc(sizeof(*bufs), GFP_KERNEL);
271                 if (!bufs)
272                         return -ENOMEM;
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;
277                 buf_entry++;
278                 /* locking here */
279                 mutex_lock(&stream->lock);
280                 list_add_tail(&bufs->node, &stream->bufs);
281                 mutex_unlock(&stream->lock);
282         }
283
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);
296                                 return -EIO;
297                         }
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);
302                                 return -EIO;
303                         }
304                 }
305         }
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,
311                                         &stream->data_blk);
312         }
313
314         if (retval >= 0)
315                 retval = stream->cumm_bytes;
316         pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval);
317         return retval;
318 }
319
320 /*sets user data buffers to play/capture*/
321 static int intel_sst_play_capture(struct stream_info *stream, int str_id)
322 {
323         int retval;
324
325         stream->data_blk.ret_code = 0;
326         stream->data_blk.on = true;
327         stream->data_blk.condition = false;
328
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;
334         }
335
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);
349                                 return -EIO;
350                         }
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);
355                                 return -EIO;
356                         }
357                 }
358         } else {
359                 mutex_unlock(&stream->lock);
360                 return -EIO;
361         }
362         mutex_unlock(&stream->lock);
363         /* Block the call for reply */
364
365         retval = sst_wait_interruptible(sst_drv_ctx, &stream->data_blk);
366         if (retval) {
367                 stream->status = STREAM_INIT;
368                 pr_debug("sst: wait returned error...\n");
369         }
370         return retval;
371 }
372
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)
377 {
378         struct sst_stream_bufs *stream_bufs;
379         unsigned long index, mmap_len;
380         unsigned char *bufp;
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;
385
386         stream_bufs = kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
387         if (!stream_bufs)
388                 return -ENOMEM;
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++) {
393                         __u32 rar_handle;
394                         struct sst_stream_bufs *stream_bufs =
395                                 kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
396
397                         stream->sg_index = index;
398                         if (!stream_bufs)
399                                 return -ENOMEM;
400                         if (copy_from_user((void *) &rar_handle,
401                                         iovec[index].iov_base,
402                                         sizeof(__u32)))
403                                 return -EFAULT;
404                         stream_bufs->addr = (char *)rar_handle;
405                         stream_bufs->in_use = false;
406                         stream_bufs->size = iovec[0].iov_len;
407                         /* locking here */
408                         mutex_lock(&stream->lock);
409                         list_add_tail(&stream_bufs->node, &stream->bufs);
410                         mutex_unlock(&stream->lock);
411                 }
412                 stream->sg_index = index;
413                 return retval;
414         }
415 #endif
416         mmap_len = sst_drv_ctx->mmap_len;
417         stream_bufs->addr = sst_drv_ctx->mmap_mem;
418         bufp = stream->cur_ptr;
419
420         copied_size = 0;
421
422         if (!stream->sg_index)
423                 sent_index = sent_offset = 0;
424
425         for (index = stream->sg_index; index < nr_segs; index++) {
426                 stream->sg_index = index;
427                 if (!stream->cur_ptr)
428                         bufp = iovec[index].iov_base;
429
430                 size = ((unsigned long)iovec[index].iov_base
431                         + iovec[index].iov_len) - (unsigned long) bufp;
432
433                 if ((copied_size + size) > mmap_len)
434                         size = mmap_len - copied_size;
435
436
437                 if (stream->ops == STREAM_OPS_PLAYBACK) {
438                         if (copy_from_user((void *)
439                                         (stream_bufs->addr + copied_size),
440                                         bufp, size)) {
441                                 /* Clean up the list and return error code */
442                                 retval = -EFAULT;
443                                 break;
444                         }
445                 } else if (stream->ops == STREAM_OPS_CAPTURE) {
446                         struct snd_sst_user_cap_list *entry =
447                                 kzalloc(sizeof(*entry), GFP_KERNEL);
448
449                         if (!entry) {
450                                 kfree(stream_bufs);
451                                 return -ENOMEM;
452                         }
453                         entry->iov_index = index;
454                         entry->iov_offset = (unsigned long) bufp -
455                                         (unsigned long)iovec[index].iov_base;
456                         entry->offset = copied_size;
457                         entry->size = size;
458                         list_add_tail(&entry->node, copy_to_list);
459                 }
460
461                 stream->cur_ptr = bufp + size;
462
463                 if (((unsigned long)iovec[index].iov_base
464                                 + iovec[index].iov_len) <
465                                 ((unsigned long)iovec[index].iov_base)) {
466                         pr_debug("sst: Buffer overflows");
467                         kfree(stream_bufs);
468                         return -EINVAL;
469                 }
470
471                 if (((unsigned long)iovec[index].iov_base
472                                         + iovec[index].iov_len) ==
473                                         (unsigned long)stream->cur_ptr) {
474                         stream->cur_ptr = NULL;
475                         stream->sg_index++;
476                 }
477
478                 copied_size += size;
479                 pr_debug("sst: copied_size - %lx\n", copied_size);
480                 if ((copied_size >= mmap_len) ||
481                                 (stream->sg_index == nr_segs)) {
482                         add_to_list = 1;
483                 }
484
485                 if (add_to_list) {
486                         stream_bufs->in_use = false;
487                         stream_bufs->size = copied_size;
488                         /* locking here */
489                         mutex_lock(&stream->lock);
490                         list_add_tail(&stream_bufs->node, &stream->bufs);
491                         mutex_unlock(&stream->lock);
492                         break;
493                 }
494         }
495         return retval;
496 }
497
498 /* This function copies the captured data returned from SST DSP engine
499  * to the user buffers*/
500 static int snd_sst_copy_userbuf_capture(struct stream_info *stream,
501                         const struct iovec *iovec,
502                         struct list_head *copy_to_list)
503 {
504         struct snd_sst_user_cap_list *entry, *_entry;
505         struct sst_stream_bufs *kbufs = NULL, *_kbufs;
506         int retval = 0;
507
508         /* copy sent buffers */
509         pr_debug("sst: capture stream copying to user now...\n");
510         list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
511                 if (kbufs->in_use == true) {
512                         /* copy to user */
513                         list_for_each_entry_safe(entry, _entry,
514                                                 copy_to_list, node) {
515                                 if (copy_to_user((void *)
516                                              iovec[entry->iov_index].iov_base +
517                                              entry->iov_offset,
518                                              kbufs->addr + entry->offset,
519                                              entry->size)) {
520                                         /* Clean up the list and return error */
521                                         retval = -EFAULT;
522                                         break;
523                                 }
524                                 list_del(&entry->node);
525                                 kfree(entry);
526                         }
527                 }
528         }
529         pr_debug("sst: end of cap copy\n");
530         return retval;
531 }
532
533 /*
534  * snd_sst_userbufs_play_cap - constructs the list from user buffers
535  *
536  * @iovec:pointer to iovec structure
537  * @nr_segs:number entries in the iovec structure
538  * @str_id:stream id
539  * @stream:pointer to stream_info structure
540  *
541  * This function will traverse the user list and copy the data to the kernel
542  * space buffers.
543  */
544 static int snd_sst_userbufs_play_cap(const struct iovec *iovec,
545                         unsigned long nr_segs, unsigned int str_id,
546                         struct stream_info *stream)
547 {
548         int retval;
549         LIST_HEAD(copy_to_list);
550
551
552         retval = snd_sst_fill_kernel_list(stream, iovec, nr_segs,
553                        &copy_to_list);
554
555         retval = intel_sst_play_capture(stream, str_id);
556         if (retval < 0)
557                 return retval;
558
559         if (stream->ops == STREAM_OPS_CAPTURE) {
560                 retval = snd_sst_copy_userbuf_capture(stream, iovec,
561                                 &copy_to_list);
562         }
563         return retval;
564 }
565
566 /* This function is common function across read/write
567   for user buffers called from system calls*/
568 static int intel_sst_read_write(unsigned int str_id, char __user *buf,
569                                         size_t count)
570 {
571         int retval;
572         struct stream_info *stream;
573         struct iovec iovec;
574         unsigned long nr_segs;
575
576         retval = sst_validate_strid(str_id);
577         if (retval)
578                 return -EINVAL;
579         stream = &sst_drv_ctx->streams[str_id];
580         if (stream->mmapped == true) {
581                 pr_warn("sst: user write and stream is mapped");
582                 return -EIO;
583         }
584         if (!count)
585                 return -EINVAL;
586         stream->curr_bytes = 0;
587         stream->cumm_bytes = 0;
588         /* copy user buf details */
589         pr_debug("sst: new buffers %p, copy size %d, status %d\n" ,
590                         buf, (int) count, (int) stream->status);
591
592         stream->buf_type = SST_BUF_USER_STATIC;
593         iovec.iov_base = (void *)buf;
594         iovec.iov_len  = count;
595         nr_segs = 1;
596
597         do {
598                 retval = snd_sst_userbufs_play_cap(
599                                 &iovec, nr_segs, str_id, stream);
600                 if (retval < 0)
601                         break;
602
603         } while (stream->sg_index < nr_segs);
604
605         stream->sg_index = 0;
606         stream->cur_ptr = NULL;
607         if (retval >= 0)
608                 retval = stream->cumm_bytes;
609         pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
610         return retval;
611 }
612
613 /***
614  * intel_sst_write - This function is called when user tries to play out data
615  *
616  * @file_ptr:pointer to file
617  * @buf:user buffer to be played out
618  * @count:size of tthe buffer
619  * @offset:offset to start from
620  *
621  * writes the encoded data into DSP
622  */
623 int intel_sst_write(struct file *file_ptr, const char __user *buf,
624                         size_t count, loff_t *offset)
625 {
626         struct ioctl_pvt_data *data = file_ptr->private_data;
627         int str_id = data->str_id;
628         struct stream_info *stream = &sst_drv_ctx->streams[str_id];
629
630         pr_debug("sst: called for %d\n", str_id);
631         if (stream->status == STREAM_UN_INIT ||
632                 stream->status == STREAM_DECODE) {
633                 return -EBADRQC;
634         }
635         return intel_sst_read_write(str_id, (char __user *)buf, count);
636 }
637
638 /*
639  * intel_sst_aio_write - write buffers
640  *
641  * @kiocb:pointer to a structure containing file pointer
642  * @iov:list of user buffer to be played out
643  * @nr_segs:number of entries
644  * @offset:offset to start from
645  *
646  * This function is called when user tries to play out multiple data buffers
647  */
648 ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov,
649                         unsigned long nr_segs, loff_t  offset)
650 {
651         int retval;
652         struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
653         int str_id = data->str_id;
654         struct stream_info *stream;
655
656         pr_debug("sst: entry - %ld\n", nr_segs);
657
658         if (is_sync_kiocb(kiocb) == false)
659                 return -EINVAL;
660
661         pr_debug("sst: called for str_id %d\n", str_id);
662         retval = sst_validate_strid(str_id);
663         if (retval)
664                 return -EINVAL;
665         stream = &sst_drv_ctx->streams[str_id];
666         if (stream->mmapped == true)
667                 return -EIO;
668         if (stream->status == STREAM_UN_INIT ||
669                 stream->status == STREAM_DECODE) {
670                 return -EBADRQC;
671         }
672         stream->curr_bytes = 0;
673         stream->cumm_bytes = 0;
674         pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
675                         nr_segs, (int) offset, (int) stream->status);
676         stream->buf_type = SST_BUF_USER_STATIC;
677         do {
678                 retval = snd_sst_userbufs_play_cap(iov, nr_segs,
679                                                 str_id, stream);
680                 if (retval < 0)
681                         break;
682
683         } while (stream->sg_index < nr_segs);
684
685         stream->sg_index = 0;
686         stream->cur_ptr = NULL;
687         if (retval >= 0)
688                 retval = stream->cumm_bytes;
689         pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
690         return retval;
691 }
692
693 /*
694  * intel_sst_read - read the encoded data
695  *
696  * @file_ptr: pointer to file
697  * @buf: user buffer to be filled with captured data
698  * @count: size of tthe buffer
699  * @offset: offset to start from
700  *
701  * This function is called when user tries to capture data
702  */
703 int intel_sst_read(struct file *file_ptr, char __user *buf,
704                         size_t count, loff_t *offset)
705 {
706         struct ioctl_pvt_data *data = file_ptr->private_data;
707         int str_id = data->str_id;
708         struct stream_info *stream = &sst_drv_ctx->streams[str_id];
709
710         pr_debug("sst: called for %d\n", str_id);
711         if (stream->status == STREAM_UN_INIT ||
712                         stream->status == STREAM_DECODE)
713                 return -EBADRQC;
714         return intel_sst_read_write(str_id, buf, count);
715 }
716
717 /*
718  * intel_sst_aio_read - aio read
719  *
720  * @kiocb: pointer to a structure containing file pointer
721  * @iov: list of user buffer to be filled with captured
722  * @nr_segs: number of entries
723  * @offset: offset to start from
724  *
725  * This function is called when user tries to capture out multiple data buffers
726  */
727 ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov,
728                          unsigned long nr_segs, loff_t offset)
729 {
730         int retval;
731         struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
732         int str_id = data->str_id;
733         struct stream_info *stream;
734
735         pr_debug("sst: entry - %ld\n", nr_segs);
736
737         if (is_sync_kiocb(kiocb) == false) {
738                 pr_debug("sst: aio_read from user space is not allowed\n");
739                 return -EINVAL;
740         }
741
742         pr_debug("sst: called for str_id %d\n", str_id);
743         retval = sst_validate_strid(str_id);
744         if (retval)
745                 return -EINVAL;
746         stream = &sst_drv_ctx->streams[str_id];
747         if (stream->mmapped == true)
748                 return -EIO;
749         if (stream->status == STREAM_UN_INIT ||
750                         stream->status == STREAM_DECODE)
751                 return -EBADRQC;
752         stream->curr_bytes = 0;
753         stream->cumm_bytes = 0;
754
755         pr_debug("sst: new segs %ld, offset %d, status %d\n" ,
756                         nr_segs, (int) offset, (int) stream->status);
757         stream->buf_type = SST_BUF_USER_STATIC;
758         do {
759                 retval = snd_sst_userbufs_play_cap(iov, nr_segs,
760                                                 str_id, stream);
761                 if (retval < 0)
762                         break;
763
764         } while (stream->sg_index < nr_segs);
765
766         stream->sg_index = 0;
767         stream->cur_ptr = NULL;
768         if (retval >= 0)
769                 retval = stream->cumm_bytes;
770         pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
771         return retval;
772 }
773
774 /* sst_print_stream_params - prints the stream parameters (debug fn)*/
775 static void sst_print_stream_params(struct snd_sst_get_stream_params *get_prm)
776 {
777         pr_debug("sst: codec params:result =%d\n",
778                                 get_prm->codec_params.result);
779         pr_debug("sst: codec params:stream = %d\n",
780                                 get_prm->codec_params.stream_id);
781         pr_debug("sst: codec params:codec = %d\n",
782                                 get_prm->codec_params.codec);
783         pr_debug("sst: codec params:ops = %d\n",
784                                 get_prm->codec_params.ops);
785         pr_debug("sst: codec params:stream_type= %d\n",
786                                 get_prm->codec_params.stream_type);
787         pr_debug("sst: pcmparams:sfreq= %d\n",
788                                 get_prm->pcm_params.sfreq);
789         pr_debug("sst: pcmparams:num_chan= %d\n",
790                                 get_prm->pcm_params.num_chan);
791         pr_debug("sst: pcmparams:pcm_wd_sz= %d\n",
792                                 get_prm->pcm_params.pcm_wd_sz);
793         return;
794 }
795
796 /**
797  * intel_sst_ioctl - recieves the device ioctl's
798  * @file_ptr:pointer to file
799  * @cmd:Ioctl cmd
800  * @arg:data
801  *
802  * This function is called by OS when a user space component
803  * sends an Ioctl to SST driver
804  */
805 long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
806 {
807         int retval = 0;
808         struct ioctl_pvt_data *data = NULL;
809         int str_id = 0, minor = 0;
810
811         data = file_ptr->private_data;
812         if (data) {
813                 minor = 0;
814                 str_id = data->str_id;
815         } else
816                 minor = 1;
817
818         if (sst_drv_ctx->sst_state != SST_FW_RUNNING)
819                 return -EBUSY;
820
821         switch (_IOC_NR(cmd)) {
822         case _IOC_NR(SNDRV_SST_STREAM_PAUSE):
823                 pr_debug("sst: IOCTL_PAUSE recieved for %d!\n", str_id);
824                 if (minor != STREAM_MODULE) {
825                         retval = -EBADRQC;
826                         break;
827                 }
828                 retval = sst_pause_stream(str_id);
829                 break;
830
831         case _IOC_NR(SNDRV_SST_STREAM_RESUME):
832                 pr_debug("sst: SNDRV_SST_IOCTL_RESUME recieved!\n");
833                 if (minor != STREAM_MODULE) {
834                         retval = -EBADRQC;
835                         break;
836                 }
837                 retval = sst_resume_stream(str_id);
838                 break;
839
840         case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): {
841                 struct snd_sst_params *str_param = (struct snd_sst_params *)arg;
842
843                 pr_debug("sst: IOCTL_SET_PARAMS recieved!\n");
844                 if (minor != STREAM_MODULE) {
845                         retval = -EBADRQC;
846                         break;
847                 }
848
849                 if (!str_id) {
850
851                         retval = sst_get_stream(str_param);
852                         if (retval > 0) {
853                                 struct stream_info *str_info;
854                                 sst_drv_ctx->stream_cnt++;
855                                 data->str_id = retval;
856                                 str_info = &sst_drv_ctx->streams[retval];
857                                 str_info->src = SST_DRV;
858                                 retval = copy_to_user(&str_param->stream_id,
859                                                 &retval, sizeof(__u32));
860                                 if (retval)
861                                         retval = -EFAULT;
862                         } else {
863                                 if (retval == -SST_ERR_INVALID_PARAMS)
864                                         retval = -EINVAL;
865                         }
866                 } else {
867                         pr_debug("sst: SET_STREAM_PARAMS recieved!\n");
868                         /* allocated set params only */
869                         retval = sst_set_stream_param(str_id, str_param);
870                         /* Block the call for reply */
871                         if (!retval) {
872                                 int sfreq = 0, word_size = 0, num_channel = 0;
873                                 sfreq = str_param->sparams.uc.pcm_params.sfreq;
874                                 word_size = str_param->sparams.
875                                                 uc.pcm_params.pcm_wd_sz;
876                                 num_channel = str_param->
877                                         sparams.uc.pcm_params.num_chan;
878                                 if (str_param->ops == STREAM_OPS_CAPTURE) {
879                                         sst_drv_ctx->scard_ops->\
880                                         set_pcm_audio_params(sfreq,
881                                                 word_size, num_channel);
882                                 }
883                         }
884                 }
885                 break;
886         }
887         case _IOC_NR(SNDRV_SST_SET_VOL): {
888                 struct snd_sst_vol *set_vol;
889                 struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg;
890                 pr_debug("sst: SET_VOLUME recieved for %d!\n",
891                                 rec_vol->stream_id);
892                 if (minor == STREAM_MODULE && rec_vol->stream_id == 0) {
893                         pr_debug("sst: invalid operation!\n");
894                         retval = -EPERM;
895                         break;
896                 }
897                 set_vol = kzalloc(sizeof(*set_vol), GFP_ATOMIC);
898                 if (!set_vol) {
899                         pr_debug("sst: mem allocation failed\n");
900                         retval = -ENOMEM;
901                         break;
902                 }
903                 if (copy_from_user(set_vol, rec_vol, sizeof(*set_vol))) {
904                         pr_debug("sst: copy failed\n");
905                         retval = -EFAULT;
906                         break;
907                 }
908                 retval = sst_set_vol(set_vol);
909                 kfree(set_vol);
910                 break;
911         }
912         case _IOC_NR(SNDRV_SST_GET_VOL): {
913                 struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg;
914                 struct snd_sst_vol get_vol;
915                 pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
916                                 rec_vol->stream_id);
917                 if (minor == STREAM_MODULE && rec_vol->stream_id == 0) {
918                         pr_debug("sst: invalid operation!\n");
919                         retval = -EPERM;
920                         break;
921                 }
922                 get_vol.stream_id = rec_vol->stream_id;
923                 retval = sst_get_vol(&get_vol);
924                 if (retval) {
925                         retval = -EIO;
926                         break;
927                 }
928                 pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
929                                 get_vol.stream_id, get_vol.volume,
930                                 get_vol.ramp_duration, get_vol.ramp_type);
931                 if (copy_to_user((struct snd_sst_vol *)arg,
932                                 &get_vol, sizeof(get_vol))) {
933                         retval = -EFAULT;
934                         break;
935                 }
936                 /*sst_print_get_vol_info(str_id, &get_vol);*/
937                 break;
938         }
939
940         case _IOC_NR(SNDRV_SST_MUTE): {
941                 struct snd_sst_mute *set_mute;
942                 struct snd_sst_vol *rec_mute = (struct snd_sst_vol *)arg;
943                 pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
944                         rec_mute->stream_id);
945                 if (minor == STREAM_MODULE && rec_mute->stream_id == 0) {
946                         retval = -EPERM;
947                         break;
948                 }
949                 set_mute = kzalloc(sizeof(*set_mute), GFP_ATOMIC);
950                 if (!set_mute) {
951                         retval = -ENOMEM;
952                         break;
953                 }
954                 if (copy_from_user(set_mute, rec_mute, sizeof(*set_mute))) {
955                         retval = -EFAULT;
956                         break;
957                 }
958                 retval = sst_set_mute(set_mute);
959                 kfree(set_mute);
960                 break;
961         }
962         case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {
963                 struct snd_sst_get_stream_params get_params;
964
965                 pr_debug("sst: IOCTL_GET_PARAMS recieved!\n");
966                 if (minor != 0) {
967                         retval = -EBADRQC;
968                         break;
969                 }
970
971                 retval = sst_get_stream_params(str_id, &get_params);
972                 if (retval) {
973                         retval = -EIO;
974                         break;
975                 }
976                 if (copy_to_user((struct snd_sst_get_stream_params *)arg,
977                                         &get_params, sizeof(get_params))) {
978                         retval = -EFAULT;
979                         break;
980                 }
981                 sst_print_stream_params(&get_params);
982                 break;
983         }
984
985         case _IOC_NR(SNDRV_SST_MMAP_PLAY):
986         case _IOC_NR(SNDRV_SST_MMAP_CAPTURE):
987                 pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
988                 if (minor != STREAM_MODULE) {
989                         retval = -EBADRQC;
990                         break;
991                 }
992                 retval = intel_sst_mmap_play_capture(str_id,
993                                 (struct snd_sst_mmap_buffs *)arg);
994                 break;
995
996         case _IOC_NR(SNDRV_SST_STREAM_DROP):
997                 pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n");
998                 if (minor != STREAM_MODULE) {
999                         retval = -EINVAL;
1000                         break;
1001                 }
1002                 retval = sst_drop_stream(str_id);
1003                 break;
1004
1005         case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): {
1006                 unsigned long long *ms = (unsigned long long *)arg;
1007                 struct snd_sst_tstamp tstamp = {0};
1008                 unsigned long long time, freq, mod;
1009
1010                 pr_debug("sst: SNDRV_SST_STREAM_GET_TSTAMP recieved!\n");
1011                 if (minor != STREAM_MODULE) {
1012                         retval = -EBADRQC;
1013                         break;
1014                 }
1015                 memcpy_fromio(&tstamp,
1016                         ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP)
1017                         +(str_id * sizeof(tstamp))),
1018                         sizeof(tstamp));
1019                 time = tstamp.samples_rendered;
1020                 freq = (unsigned long long) tstamp.sampling_frequency;
1021                 time = time * 1000; /* converting it to ms */
1022                 mod = do_div(time, freq);
1023                 if (copy_to_user(ms, &time, sizeof(*ms)))
1024                         retval = -EFAULT;
1025                 break;
1026         }
1027
1028         case _IOC_NR(SNDRV_SST_STREAM_START):{
1029                 struct stream_info *stream;
1030
1031                 pr_debug("sst: SNDRV_SST_STREAM_START recieved!\n");
1032                 if (minor != STREAM_MODULE) {
1033                         retval = -EINVAL;
1034                         break;
1035                 }
1036                 retval = sst_validate_strid(str_id);
1037                 if (retval)
1038                         break;
1039                 stream = &sst_drv_ctx->streams[str_id];
1040                 mutex_lock(&stream->lock);
1041                 if (stream->status == STREAM_INIT &&
1042                         stream->need_draining != true) {
1043                         stream->prev = stream->status;
1044                         stream->status = STREAM_RUNNING;
1045                         if (stream->ops == STREAM_OPS_PLAYBACK ||
1046                                 stream->ops == STREAM_OPS_PLAYBACK_DRM) {
1047                                 retval = sst_play_frame(str_id);
1048                         } else if (stream->ops == STREAM_OPS_CAPTURE)
1049                                 retval = sst_capture_frame(str_id);
1050                         else {
1051                                 retval = -EINVAL;
1052                                 mutex_unlock(&stream->lock);
1053                                 break;
1054                         }
1055                         if (retval < 0) {
1056                                 stream->status = STREAM_INIT;
1057                                 mutex_unlock(&stream->lock);
1058                                 break;
1059                         }
1060                 } else {
1061                         retval = -EINVAL;
1062                 }
1063                 mutex_unlock(&stream->lock);
1064                 break;
1065         }
1066
1067         case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): {
1068                 struct snd_sst_target_device *target_device;
1069
1070                 pr_debug("sst: SET_TARGET_DEVICE recieved!\n");
1071                 target_device = (struct snd_sst_target_device *)arg;
1072                 BUG_ON(!target_device);
1073                 if (minor != AM_MODULE) {
1074                         retval = -EBADRQC;
1075                         break;
1076                 }
1077                 retval = sst_target_device_select(target_device);
1078                 break;
1079         }
1080
1081         case _IOC_NR(SNDRV_SST_DRIVER_INFO): {
1082                 struct snd_sst_driver_info *info =
1083                         (struct snd_sst_driver_info *)arg;
1084
1085                 pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n");
1086                 info->version = SST_VERSION_NUM;
1087                 /* hard coding, shud get sumhow later */
1088                 info->active_pcm_streams = sst_drv_ctx->stream_cnt -
1089                                                 sst_drv_ctx->encoded_cnt;
1090                 info->active_enc_streams = sst_drv_ctx->encoded_cnt;
1091                 info->max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM;
1092                 info->max_enc_streams = MAX_ENC_STREAM;
1093                 info->buf_per_stream = sst_drv_ctx->mmap_len;
1094                 break;
1095         }
1096
1097         case _IOC_NR(SNDRV_SST_STREAM_DECODE): {
1098                 struct snd_sst_dbufs *param =
1099                                 (struct snd_sst_dbufs *)arg, dbufs_local;
1100                 int i;
1101                 struct snd_sst_buffs ibufs, obufs;
1102                 struct snd_sst_buff_entry ibuf_temp[param->ibufs->entries],
1103                                 obuf_temp[param->obufs->entries];
1104
1105                 pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n");
1106                 if (minor != STREAM_MODULE) {
1107                         retval = -EBADRQC;
1108                         break;
1109                 }
1110                 if (!param) {
1111                         retval = -EINVAL;
1112                         break;
1113                 }
1114
1115                 dbufs_local.input_bytes_consumed = param->input_bytes_consumed;
1116                 dbufs_local.output_bytes_produced =
1117                                         param->output_bytes_produced;
1118                 dbufs_local.ibufs = &ibufs;
1119                 dbufs_local.obufs = &obufs;
1120                 dbufs_local.ibufs->entries = param->ibufs->entries;
1121                 dbufs_local.ibufs->type = param->ibufs->type;
1122                 dbufs_local.obufs->entries = param->obufs->entries;
1123                 dbufs_local.obufs->type = param->obufs->type;
1124
1125                 dbufs_local.ibufs->buff_entry = ibuf_temp;
1126                 for (i = 0; i < dbufs_local.ibufs->entries; i++) {
1127                         ibuf_temp[i].buffer =
1128                                 param->ibufs->buff_entry[i].buffer;
1129                         ibuf_temp[i].size =
1130                                 param->ibufs->buff_entry[i].size;
1131                 }
1132                 dbufs_local.obufs->buff_entry = obuf_temp;
1133                 for (i = 0; i < dbufs_local.obufs->entries; i++) {
1134                         obuf_temp[i].buffer =
1135                                 param->obufs->buff_entry[i].buffer;
1136                         obuf_temp[i].size =
1137                                 param->obufs->buff_entry[i].size;
1138                 }
1139                 retval = sst_decode(str_id, &dbufs_local);
1140                 if (retval)
1141                         retval =  -EAGAIN;
1142                 if (copy_to_user(&param->input_bytes_consumed,
1143                                 &dbufs_local.input_bytes_consumed,
1144                                 sizeof(unsigned long long))) {
1145                         retval =  -EFAULT;
1146                         break;
1147                 }
1148                 if (copy_to_user(&param->output_bytes_produced,
1149                                 &dbufs_local.output_bytes_produced,
1150                                 sizeof(unsigned long long))) {
1151                         retval =  -EFAULT;
1152                         break;
1153                 }
1154                 break;
1155         }
1156
1157         case _IOC_NR(SNDRV_SST_STREAM_DRAIN):
1158                 pr_debug("sst: SNDRV_SST_STREAM_DRAIN recived\n");
1159                 if (minor != STREAM_MODULE) {
1160                         retval = -EINVAL;
1161                         break;
1162                 }
1163                 retval = sst_drain_stream(str_id);
1164                 break;
1165
1166         case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED): {
1167                 unsigned long long *bytes = (unsigned long long *)arg;
1168                 struct snd_sst_tstamp tstamp = {0};
1169
1170                 pr_debug("sst: STREAM_BYTES_DECODED recieved!\n");
1171                 if (minor != STREAM_MODULE) {
1172                         retval = -EINVAL;
1173                         break;
1174                 }
1175                 memcpy_fromio(&tstamp,
1176                         ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP)
1177                         +(str_id * sizeof(tstamp))),
1178                         sizeof(tstamp));
1179                 if (copy_to_user(bytes, &tstamp.bytes_processed,
1180                                 sizeof(*bytes)))
1181                         retval = -EFAULT;
1182                 break;
1183         }
1184         case _IOC_NR(SNDRV_SST_FW_INFO): {
1185                 struct snd_sst_fw_info *fw_info;
1186
1187                 pr_debug("sst: SNDRV_SST_FW_INFO recived\n");
1188
1189                 fw_info = kzalloc(sizeof(*fw_info), GFP_ATOMIC);
1190                 if (!fw_info) {
1191                         retval = -ENOMEM;
1192                         break;
1193                 }
1194                 retval = sst_get_fw_info(fw_info);
1195                 if (retval) {
1196                         retval = -EIO;
1197                         kfree(fw_info);
1198                         break;
1199                 }
1200                 if (copy_to_user((struct snd_sst_dbufs *)arg,
1201                                 fw_info, sizeof(*fw_info))) {
1202                         kfree(fw_info);
1203                         retval = -EFAULT;
1204                         break;
1205                 }
1206                 /*sst_print_fw_info(fw_info);*/
1207                 kfree(fw_info);
1208                 break;
1209         }
1210         default:
1211                 retval = -EINVAL;
1212         }
1213         pr_debug("sst: intel_sst_ioctl:complete ret code = %d\n", retval);
1214         return retval;
1215 }
1216