microblaze: trivial: Fix removed the part of line
[cascardo/linux.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         struct snd_sst_mmap_buff_entry *tmp_buf;
248
249         pr_debug("sst:called for str_id %d\n", str_id);
250         retval = sst_validate_strid(str_id);
251         if (retval)
252                 return -EINVAL;
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         tmp_buf = kcalloc(mmap_buf->entries, sizeof(*tmp_buf), GFP_KERNEL);
266         if (!tmp_buf)
267                 return -ENOMEM;
268         if (copy_from_user(tmp_buf, (void __user *)mmap_buf->buff,
269                         mmap_buf->entries * sizeof(*tmp_buf))) {
270                 retval = -EFAULT;
271                 goto out_free;
272         }
273
274         pr_debug("sst:new buffers count %d status %d\n",
275                         mmap_buf->entries, stream->status);
276         buf_entry = tmp_buf;
277         for (i = 0; i < mmap_buf->entries; i++) {
278                 bufs = kzalloc(sizeof(*bufs), GFP_KERNEL);
279                 if (!bufs) {
280                         retval = -ENOMEM;
281                         goto out_free;
282                 }
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;
287                 buf_entry++;
288                 /* locking here */
289                 mutex_lock(&stream->lock);
290                 list_add_tail(&bufs->node, &stream->bufs);
291                 mutex_unlock(&stream->lock);
292         }
293
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);
306                                 retval = -EIO;
307                                 goto out_free;
308                         }
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);
313                                 retval = -EIO;
314                                 goto out_free;
315                         }
316                 }
317         }
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,
323                                         &stream->data_blk);
324         }
325
326         if (retval >= 0)
327                 retval = stream->cumm_bytes;
328         pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval);
329
330 out_free:
331         kfree(tmp_buf);
332         return retval;
333 }
334
335 /*sets user data buffers to play/capture*/
336 static int intel_sst_play_capture(struct stream_info *stream, int str_id)
337 {
338         int retval;
339
340         stream->data_blk.ret_code = 0;
341         stream->data_blk.on = true;
342         stream->data_blk.condition = false;
343
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;
349         }
350
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);
364                                 return -EIO;
365                         }
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);
370                                 return -EIO;
371                         }
372                 }
373         } else {
374                 mutex_unlock(&stream->lock);
375                 return -EIO;
376         }
377         mutex_unlock(&stream->lock);
378         /* Block the call for reply */
379
380         retval = sst_wait_interruptible(sst_drv_ctx, &stream->data_blk);
381         if (retval) {
382                 stream->status = STREAM_INIT;
383                 pr_debug("sst: wait returned error...\n");
384         }
385         return retval;
386 }
387
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)
392 {
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;
400
401         stream_bufs = kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
402         if (!stream_bufs)
403                 return -ENOMEM;
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++) {
408                         __u32 rar_handle;
409                         struct sst_stream_bufs *stream_bufs =
410                                 kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
411
412                         stream->sg_index = index;
413                         if (!stream_bufs)
414                                 return -ENOMEM;
415                         if (copy_from_user((void *) &rar_handle,
416                                         iovec[index].iov_base,
417                                         sizeof(__u32)))
418                                 return -EFAULT;
419                         stream_bufs->addr = (char *)rar_handle;
420                         stream_bufs->in_use = false;
421                         stream_bufs->size = iovec[0].iov_len;
422                         /* locking here */
423                         mutex_lock(&stream->lock);
424                         list_add_tail(&stream_bufs->node, &stream->bufs);
425                         mutex_unlock(&stream->lock);
426                 }
427                 stream->sg_index = index;
428                 return retval;
429         }
430 #endif
431         mmap_len = sst_drv_ctx->mmap_len;
432         stream_bufs->addr = sst_drv_ctx->mmap_mem;
433         bufp = stream->cur_ptr;
434
435         copied_size = 0;
436
437         if (!stream->sg_index)
438                 sent_index = sent_offset = 0;
439
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;
444
445                 size = ((unsigned long)iovec[index].iov_base
446                         + iovec[index].iov_len) - (unsigned long) bufp;
447
448                 if ((copied_size + size) > mmap_len)
449                         size = mmap_len - copied_size;
450
451
452                 if (stream->ops == STREAM_OPS_PLAYBACK) {
453                         if (copy_from_user((void *)
454                                         (stream_bufs->addr + copied_size),
455                                         bufp, size)) {
456                                 /* Clean up the list and return error code */
457                                 retval = -EFAULT;
458                                 break;
459                         }
460                 } else if (stream->ops == STREAM_OPS_CAPTURE) {
461                         struct snd_sst_user_cap_list *entry =
462                                 kzalloc(sizeof(*entry), GFP_KERNEL);
463
464                         if (!entry) {
465                                 kfree(stream_bufs);
466                                 return -ENOMEM;
467                         }
468                         entry->iov_index = index;
469                         entry->iov_offset = (unsigned long) bufp -
470                                         (unsigned long)iovec[index].iov_base;
471                         entry->offset = copied_size;
472                         entry->size = size;
473                         list_add_tail(&entry->node, copy_to_list);
474                 }
475
476                 stream->cur_ptr = bufp + size;
477
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");
482                         kfree(stream_bufs);
483                         return -EINVAL;
484                 }
485
486                 if (((unsigned long)iovec[index].iov_base
487                                         + iovec[index].iov_len) ==
488                                         (unsigned long)stream->cur_ptr) {
489                         stream->cur_ptr = NULL;
490                         stream->sg_index++;
491                 }
492
493                 copied_size += size;
494                 pr_debug("sst: copied_size - %lx\n", copied_size);
495                 if ((copied_size >= mmap_len) ||
496                                 (stream->sg_index == nr_segs)) {
497                         add_to_list = 1;
498                 }
499
500                 if (add_to_list) {
501                         stream_bufs->in_use = false;
502                         stream_bufs->size = copied_size;
503                         /* locking here */
504                         mutex_lock(&stream->lock);
505                         list_add_tail(&stream_bufs->node, &stream->bufs);
506                         mutex_unlock(&stream->lock);
507                         break;
508                 }
509         }
510         return retval;
511 }
512
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)
518 {
519         struct snd_sst_user_cap_list *entry, *_entry;
520         struct sst_stream_bufs *kbufs = NULL, *_kbufs;
521         int retval = 0;
522
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) {
527                         /* copy to user */
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,
532                                              entry->size)) {
533                                         /* Clean up the list and return error */
534                                         retval = -EFAULT;
535                                         break;
536                                 }
537                                 list_del(&entry->node);
538                                 kfree(entry);
539                         }
540                 }
541         }
542         pr_debug("sst: end of cap copy\n");
543         return retval;
544 }
545
546 /*
547  * snd_sst_userbufs_play_cap - constructs the list from user buffers
548  *
549  * @iovec:pointer to iovec structure
550  * @nr_segs:number entries in the iovec structure
551  * @str_id:stream id
552  * @stream:pointer to stream_info structure
553  *
554  * This function will traverse the user list and copy the data to the kernel
555  * space buffers.
556  */
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)
560 {
561         int retval;
562         LIST_HEAD(copy_to_list);
563
564
565         retval = snd_sst_fill_kernel_list(stream, iovec, nr_segs,
566                        &copy_to_list);
567
568         retval = intel_sst_play_capture(stream, str_id);
569         if (retval < 0)
570                 return retval;
571
572         if (stream->ops == STREAM_OPS_CAPTURE) {
573                 retval = snd_sst_copy_userbuf_capture(stream, iovec,
574                                 &copy_to_list);
575         }
576         return retval;
577 }
578
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,
582                                         size_t count)
583 {
584         int retval;
585         struct stream_info *stream;
586         struct iovec iovec;
587         unsigned long nr_segs;
588
589         retval = sst_validate_strid(str_id);
590         if (retval)
591                 return -EINVAL;
592         stream = &sst_drv_ctx->streams[str_id];
593         if (stream->mmapped == true) {
594                 pr_warn("sst: user write and stream is mapped");
595                 return -EIO;
596         }
597         if (!count)
598                 return -EINVAL;
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);
604
605         stream->buf_type = SST_BUF_USER_STATIC;
606         iovec.iov_base = buf;
607         iovec.iov_len  = count;
608         nr_segs = 1;
609
610         do {
611                 retval = snd_sst_userbufs_play_cap(
612                                 &iovec, nr_segs, str_id, stream);
613                 if (retval < 0)
614                         break;
615
616         } while (stream->sg_index < nr_segs);
617
618         stream->sg_index = 0;
619         stream->cur_ptr = NULL;
620         if (retval >= 0)
621                 retval = stream->cumm_bytes;
622         pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
623         return retval;
624 }
625
626 /***
627  * intel_sst_write - This function is called when user tries to play out data
628  *
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
633  *
634  * writes the encoded data into DSP
635  */
636 int intel_sst_write(struct file *file_ptr, const char __user *buf,
637                         size_t count, loff_t *offset)
638 {
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];
642
643         pr_debug("sst: called for %d\n", str_id);
644         if (stream->status == STREAM_UN_INIT ||
645                 stream->status == STREAM_DECODE) {
646                 return -EBADRQC;
647         }
648         return intel_sst_read_write(str_id, (char __user *)buf, count);
649 }
650
651 /*
652  * intel_sst_aio_write - write buffers
653  *
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
658  *
659  * This function is called when user tries to play out multiple data buffers
660  */
661 ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov,
662                         unsigned long nr_segs, loff_t  offset)
663 {
664         int retval;
665         struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
666         int str_id = data->str_id;
667         struct stream_info *stream;
668
669         pr_debug("sst: entry - %ld\n", nr_segs);
670
671         if (is_sync_kiocb(kiocb) == false)
672                 return -EINVAL;
673
674         pr_debug("sst: called for str_id %d\n", str_id);
675         retval = sst_validate_strid(str_id);
676         if (retval)
677                 return -EINVAL;
678         stream = &sst_drv_ctx->streams[str_id];
679         if (stream->mmapped == true)
680                 return -EIO;
681         if (stream->status == STREAM_UN_INIT ||
682                 stream->status == STREAM_DECODE) {
683                 return -EBADRQC;
684         }
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;
690         do {
691                 retval = snd_sst_userbufs_play_cap(iov, nr_segs,
692                                                 str_id, stream);
693                 if (retval < 0)
694                         break;
695
696         } while (stream->sg_index < nr_segs);
697
698         stream->sg_index = 0;
699         stream->cur_ptr = NULL;
700         if (retval >= 0)
701                 retval = stream->cumm_bytes;
702         pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
703         return retval;
704 }
705
706 /*
707  * intel_sst_read - read the encoded data
708  *
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
713  *
714  * This function is called when user tries to capture data
715  */
716 int intel_sst_read(struct file *file_ptr, char __user *buf,
717                         size_t count, loff_t *offset)
718 {
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];
722
723         pr_debug("sst: called for %d\n", str_id);
724         if (stream->status == STREAM_UN_INIT ||
725                         stream->status == STREAM_DECODE)
726                 return -EBADRQC;
727         return intel_sst_read_write(str_id, buf, count);
728 }
729
730 /*
731  * intel_sst_aio_read - aio read
732  *
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
737  *
738  * This function is called when user tries to capture out multiple data buffers
739  */
740 ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov,
741                          unsigned long nr_segs, loff_t offset)
742 {
743         int retval;
744         struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
745         int str_id = data->str_id;
746         struct stream_info *stream;
747
748         pr_debug("sst: entry - %ld\n", nr_segs);
749
750         if (is_sync_kiocb(kiocb) == false) {
751                 pr_debug("sst: aio_read from user space is not allowed\n");
752                 return -EINVAL;
753         }
754
755         pr_debug("sst: called for str_id %d\n", str_id);
756         retval = sst_validate_strid(str_id);
757         if (retval)
758                 return -EINVAL;
759         stream = &sst_drv_ctx->streams[str_id];
760         if (stream->mmapped == true)
761                 return -EIO;
762         if (stream->status == STREAM_UN_INIT ||
763                         stream->status == STREAM_DECODE)
764                 return -EBADRQC;
765         stream->curr_bytes = 0;
766         stream->cumm_bytes = 0;
767
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;
771         do {
772                 retval = snd_sst_userbufs_play_cap(iov, nr_segs,
773                                                 str_id, stream);
774                 if (retval < 0)
775                         break;
776
777         } while (stream->sg_index < nr_segs);
778
779         stream->sg_index = 0;
780         stream->cur_ptr = NULL;
781         if (retval >= 0)
782                 retval = stream->cumm_bytes;
783         pr_debug("sst: end of play/rec bytes = %d!!\n", retval);
784         return retval;
785 }
786
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)
789 {
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);
806         return;
807 }
808
809 /**
810  * intel_sst_ioctl - recieves the device ioctl's
811  * @file_ptr:pointer to file
812  * @cmd:Ioctl cmd
813  * @arg:data
814  *
815  * This function is called by OS when a user space component
816  * sends an Ioctl to SST driver
817  */
818 long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
819 {
820         int retval = 0;
821         struct ioctl_pvt_data *data = NULL;
822         int str_id = 0, minor = 0;
823
824         data = file_ptr->private_data;
825         if (data) {
826                 minor = 0;
827                 str_id = data->str_id;
828         } else
829                 minor = 1;
830
831         if (sst_drv_ctx->sst_state != SST_FW_RUNNING)
832                 return -EBUSY;
833
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) {
838                         retval = -EBADRQC;
839                         break;
840                 }
841                 retval = sst_pause_stream(str_id);
842                 break;
843
844         case _IOC_NR(SNDRV_SST_STREAM_RESUME):
845                 pr_debug("sst: SNDRV_SST_IOCTL_RESUME recieved!\n");
846                 if (minor != STREAM_MODULE) {
847                         retval = -EBADRQC;
848                         break;
849                 }
850                 retval = sst_resume_stream(str_id);
851                 break;
852
853         case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): {
854                 struct snd_sst_params str_param;
855
856                 pr_debug("sst: IOCTL_SET_PARAMS recieved!\n");
857                 if (minor != STREAM_MODULE) {
858                         retval = -EBADRQC;
859                         break;
860                 }
861
862                 if (copy_from_user(&str_param, (void __user *)arg,
863                                 sizeof(str_param))) {
864                         retval = -EFAULT;
865                         break;
866                 }
867
868                 if (!str_id) {
869
870                         retval = sst_get_stream(&str_param);
871                         if (retval > 0) {
872                                 struct stream_info *str_info;
873                                 char __user *dest;
874
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));
881                                 if (retval)
882                                         retval = -EFAULT;
883                         } else {
884                                 if (retval == -SST_ERR_INVALID_PARAMS)
885                                         retval = -EINVAL;
886                         }
887                 } else {
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 */
892                         if (!retval) {
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);
901                                 }
902                         }
903                 }
904                 break;
905         }
906         case _IOC_NR(SNDRV_SST_SET_VOL): {
907                 struct snd_sst_vol set_vol;
908
909                 if (copy_from_user(&set_vol, (void __user *)arg,
910                                 sizeof(set_vol))) {
911                         pr_debug("sst: copy failed\n");
912                         retval = -EFAULT;
913                         break;
914                 }
915                 pr_debug("sst: SET_VOLUME recieved for %d!\n",
916                                 set_vol.stream_id);
917                 if (minor == STREAM_MODULE && set_vol.stream_id == 0) {
918                         pr_debug("sst: invalid operation!\n");
919                         retval = -EPERM;
920                         break;
921                 }
922                 retval = sst_set_vol(&set_vol);
923                 break;
924         }
925         case _IOC_NR(SNDRV_SST_GET_VOL): {
926                 struct snd_sst_vol get_vol;
927
928                 if (copy_from_user(&get_vol, (void __user *)arg,
929                                 sizeof(get_vol))) {
930                         retval = -EFAULT;
931                         break;
932                 }
933                 pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n",
934                                 get_vol.stream_id);
935                 if (minor == STREAM_MODULE && get_vol.stream_id == 0) {
936                         pr_debug("sst: invalid operation!\n");
937                         retval = -EPERM;
938                         break;
939                 }
940                 retval = sst_get_vol(&get_vol);
941                 if (retval) {
942                         retval = -EIO;
943                         break;
944                 }
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))) {
950                         retval = -EFAULT;
951                         break;
952                 }
953                 /*sst_print_get_vol_info(str_id, &get_vol);*/
954                 break;
955         }
956
957         case _IOC_NR(SNDRV_SST_MUTE): {
958                 struct snd_sst_mute set_mute;
959
960                 if (copy_from_user(&set_mute, (void __user *)arg,
961                                 sizeof(set_mute))) {
962                         retval = -EFAULT;
963                         break;
964                 }
965                 pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n",
966                         set_mute.stream_id);
967                 if (minor == STREAM_MODULE && set_mute.stream_id == 0) {
968                         retval = -EPERM;
969                         break;
970                 }
971                 retval = sst_set_mute(&set_mute);
972                 break;
973         }
974         case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {
975                 struct snd_sst_get_stream_params get_params;
976
977                 pr_debug("sst: IOCTL_GET_PARAMS recieved!\n");
978                 if (minor != 0) {
979                         retval = -EBADRQC;
980                         break;
981                 }
982
983                 retval = sst_get_stream_params(str_id, &get_params);
984                 if (retval) {
985                         retval = -EIO;
986                         break;
987                 }
988                 if (copy_to_user((struct snd_sst_get_stream_params __user *)arg,
989                                         &get_params, sizeof(get_params))) {
990                         retval = -EFAULT;
991                         break;
992                 }
993                 sst_print_stream_params(&get_params);
994                 break;
995         }
996
997         case _IOC_NR(SNDRV_SST_MMAP_PLAY):
998         case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): {
999                 struct snd_sst_mmap_buffs mmap_buf;
1000
1001                 pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
1002                 if (minor != STREAM_MODULE) {
1003                         retval = -EBADRQC;
1004                         break;
1005                 }
1006                 if (copy_from_user(&mmap_buf, (void __user *)arg,
1007                                 sizeof(mmap_buf))) {
1008                         retval = -EFAULT;
1009                         break;
1010                 }
1011                 retval = intel_sst_mmap_play_capture(str_id, &mmap_buf);
1012                 break;
1013         }
1014         case _IOC_NR(SNDRV_SST_STREAM_DROP):
1015                 pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n");
1016                 if (minor != STREAM_MODULE) {
1017                         retval = -EINVAL;
1018                         break;
1019                 }
1020                 retval = sst_drop_stream(str_id);
1021                 break;
1022
1023         case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): {
1024                 struct snd_sst_tstamp tstamp = {0};
1025                 unsigned long long time, freq, mod;
1026
1027                 pr_debug("sst: SNDRV_SST_STREAM_GET_TSTAMP recieved!\n");
1028                 if (minor != STREAM_MODULE) {
1029                         retval = -EBADRQC;
1030                         break;
1031                 }
1032                 memcpy_fromio(&tstamp,
1033                         sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
1034                         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)))
1041                         retval = -EFAULT;
1042                 break;
1043         }
1044
1045         case _IOC_NR(SNDRV_SST_STREAM_START):{
1046                 struct stream_info *stream;
1047
1048                 pr_debug("sst: SNDRV_SST_STREAM_START recieved!\n");
1049                 if (minor != STREAM_MODULE) {
1050                         retval = -EINVAL;
1051                         break;
1052                 }
1053                 retval = sst_validate_strid(str_id);
1054                 if (retval)
1055                         break;
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);
1067                         else {
1068                                 retval = -EINVAL;
1069                                 mutex_unlock(&stream->lock);
1070                                 break;
1071                         }
1072                         if (retval < 0) {
1073                                 stream->status = STREAM_INIT;
1074                                 mutex_unlock(&stream->lock);
1075                                 break;
1076                         }
1077                 } else {
1078                         retval = -EINVAL;
1079                 }
1080                 mutex_unlock(&stream->lock);
1081                 break;
1082         }
1083
1084         case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): {
1085                 struct snd_sst_target_device target_device;
1086
1087                 pr_debug("sst: SET_TARGET_DEVICE recieved!\n");
1088                 if (copy_from_user(&target_device, (void __user *)arg,
1089                                 sizeof(target_device))) {
1090                         retval = -EFAULT;
1091                         break;
1092                 }
1093                 if (minor != AM_MODULE) {
1094                         retval = -EBADRQC;
1095                         break;
1096                 }
1097                 retval = sst_target_device_select(&target_device);
1098                 break;
1099         }
1100
1101         case _IOC_NR(SNDRV_SST_DRIVER_INFO): {
1102                 struct snd_sst_driver_info info;
1103
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,
1114                                 sizeof(info)))
1115                         retval = -EFAULT;
1116                 break;
1117         }
1118
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;
1124                 char __user *dest;
1125
1126                 pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n");
1127                 if (minor != STREAM_MODULE) {
1128                         retval = -EBADRQC;
1129                         break;
1130                 }
1131                 if (copy_from_user(&param, (void __user *)arg,
1132                                 sizeof(param))) {
1133                         retval = -EFAULT;
1134                         break;
1135                 }
1136
1137                 dbufs_local.input_bytes_consumed = param.input_bytes_consumed;
1138                 dbufs_local.output_bytes_produced =
1139                                         param.output_bytes_produced;
1140
1141                 if (copy_from_user(&ibufs, (void __user *)param.ibufs, sizeof(ibufs))) {
1142                         retval = -EFAULT;
1143                         break;
1144                 }
1145                 if (copy_from_user(&obufs, (void __user *)param.obufs, sizeof(obufs))) {
1146                         retval = -EFAULT;
1147                         break;
1148                 }
1149
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) {
1153                         retval = -ENOMEM;
1154                         goto free_iobufs;
1155                 }
1156
1157                 if (copy_from_user(ibuf_tmp, (void __user *)ibufs.buff_entry,
1158                                 ibufs.entries * sizeof(*ibuf_tmp))) {
1159                         retval = -EFAULT;
1160                         goto free_iobufs;
1161                 }
1162                 ibufs.buff_entry = ibuf_tmp;
1163                 dbufs_local.ibufs = &ibufs;
1164
1165                 if (copy_from_user(obuf_tmp, (void __user *)obufs.buff_entry,
1166                                 obufs.entries * sizeof(*obuf_tmp))) {
1167                         retval = -EFAULT;
1168                         goto free_iobufs;
1169                 }
1170                 obufs.buff_entry = obuf_tmp;
1171                 dbufs_local.obufs = &obufs;
1172
1173                 retval = sst_decode(str_id, &dbufs_local);
1174                 if (retval) {
1175                         retval = -EAGAIN;
1176                         goto free_iobufs;
1177                 }
1178
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))) {
1183                         retval = -EFAULT;
1184                         goto free_iobufs;
1185                 }
1186
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))) {
1191                         retval = -EFAULT;
1192                         goto free_iobufs;
1193                 }
1194 free_iobufs:
1195                 kfree(ibuf_tmp);
1196                 kfree(obuf_tmp);
1197                 break;
1198         }
1199
1200         case _IOC_NR(SNDRV_SST_STREAM_DRAIN):
1201                 pr_debug("sst: SNDRV_SST_STREAM_DRAIN recived\n");
1202                 if (minor != STREAM_MODULE) {
1203                         retval = -EINVAL;
1204                         break;
1205                 }
1206                 retval = sst_drain_stream(str_id);
1207                 break;
1208
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};
1212
1213                 pr_debug("sst: STREAM_BYTES_DECODED recieved!\n");
1214                 if (minor != STREAM_MODULE) {
1215                         retval = -EINVAL;
1216                         break;
1217                 }
1218                 memcpy_fromio(&tstamp,
1219                         sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
1220                         sizeof(tstamp));
1221                 if (copy_to_user(bytes, &tstamp.bytes_processed,
1222                                 sizeof(*bytes)))
1223                         retval = -EFAULT;
1224                 break;
1225         }
1226         case _IOC_NR(SNDRV_SST_FW_INFO): {
1227                 struct snd_sst_fw_info *fw_info;
1228
1229                 pr_debug("sst: SNDRV_SST_FW_INFO recived\n");
1230
1231                 fw_info = kzalloc(sizeof(*fw_info), GFP_ATOMIC);
1232                 if (!fw_info) {
1233                         retval = -ENOMEM;
1234                         break;
1235                 }
1236                 retval = sst_get_fw_info(fw_info);
1237                 if (retval) {
1238                         retval = -EIO;
1239                         kfree(fw_info);
1240                         break;
1241                 }
1242                 if (copy_to_user((struct snd_sst_dbufs __user *)arg,
1243                                 fw_info, sizeof(*fw_info))) {
1244                         kfree(fw_info);
1245                         retval = -EFAULT;
1246                         break;
1247                 }
1248                 /*sst_print_fw_info(fw_info);*/
1249                 kfree(fw_info);
1250                 break;
1251         }
1252         default:
1253                 retval = -EINVAL;
1254         }
1255         pr_debug("sst: intel_sst_ioctl:complete ret code = %d\n", retval);
1256         return retval;
1257 }
1258