Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / drivers / staging / intel_sst / intel_sst_stream_encoded.c
1 /*
2  *  intel_sst_stream.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  *              KP Jeeja <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  *
26  *  This file contains the stream operations of SST driver
27  */
28
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30
31 #include <linux/pci.h>
32 #include <linux/syscalls.h>
33 #include <linux/firmware.h>
34 #include <linux/sched.h>
35 #ifdef CONFIG_MRST_RAR_HANDLER
36 #include <linux/rar_register.h>
37 #include "../memrar/memrar.h"
38 #endif
39 #include "intel_sst_ioctl.h"
40 #include "intel_sst.h"
41 #include "intel_sst_fw_ipc.h"
42 #include "intel_sst_common.h"
43 /**
44 * sst_get_stream_params - Send msg to query for stream parameters
45 * @str_id:      stream id for which the parameters are queried for
46 * @get_params:  out parameters to which the parameters are copied to
47 *
48 * This function is called when the stream parameters are queiried for
49 */
50 int sst_get_stream_params(int str_id,
51                         struct snd_sst_get_stream_params *get_params)
52 {
53         int retval = 0;
54         struct ipc_post *msg = NULL;
55         struct stream_info *str_info;
56         struct snd_sst_fw_get_stream_params *fw_params;
57
58         pr_debug("get_stream for %d\n", str_id);
59         retval = sst_validate_strid(str_id);
60         if (retval)
61                 return retval;
62
63         str_info = &sst_drv_ctx->streams[str_id];
64         if (str_info->status != STREAM_UN_INIT) {
65                 if (str_info->ctrl_blk.on == true) {
66                         pr_err("control path in use\n");
67                         return -EINVAL;
68                 }
69                 if (sst_create_short_msg(&msg)) {
70                         pr_err("message creation failed\n");
71                         return -ENOMEM;
72                 }
73                 fw_params = kzalloc(sizeof(*fw_params), GFP_ATOMIC);
74                 if (!fw_params) {
75                         pr_err("mem allocation failed\n");
76                         kfree(msg);
77                         return -ENOMEM;
78                 }
79
80                 sst_fill_header(&msg->header, IPC_IA_GET_STREAM_PARAMS,
81                                         0, str_id);
82                 str_info->ctrl_blk.condition = false;
83                 str_info->ctrl_blk.ret_code = 0;
84                 str_info->ctrl_blk.on = true;
85                 str_info->ctrl_blk.data = (void *) fw_params;
86                 spin_lock(&sst_drv_ctx->list_spin_lock);
87                 list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
88                 spin_unlock(&sst_drv_ctx->list_spin_lock);
89                 sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
90                 retval = sst_wait_interruptible_timeout(sst_drv_ctx,
91                                 &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
92                 if (retval) {
93                         get_params->codec_params.result = retval;
94                         kfree(fw_params);
95                         return -EIO;
96                 }
97                 memcpy(&get_params->pcm_params, &fw_params->pcm_params,
98                                 sizeof(fw_params->pcm_params));
99                 memcpy(&get_params->codec_params.sparams,
100                                 &fw_params->codec_params,
101                                 sizeof(fw_params->codec_params));
102                 get_params->codec_params.result = 0;
103                 get_params->codec_params.stream_id = str_id;
104                 get_params->codec_params.codec = str_info->codec;
105                 get_params->codec_params.ops = str_info->ops;
106                 get_params->codec_params.stream_type = str_info->str_type;
107                 kfree(fw_params);
108         } else {
109                 pr_debug("Stream is not in the init state\n");
110         }
111         return retval;
112 }
113
114 /**
115  * sst_set_stream_param - Send msg for setting stream parameters
116  *
117  * @str_id: stream id
118  * @str_param: stream params
119  *
120  * This function sets stream params during runtime
121  */
122 int sst_set_stream_param(int str_id, struct snd_sst_params *str_param)
123 {
124         int retval = 0;
125         struct ipc_post *msg = NULL;
126         struct stream_info *str_info;
127
128         BUG_ON(!str_param);
129         if (sst_drv_ctx->streams[str_id].ops != str_param->ops) {
130                 pr_err("Invalid operation\n");
131                 return -EINVAL;
132         }
133         retval = sst_validate_strid(str_id);
134         if (retval)
135                 return retval;
136         pr_debug("set_stream for %d\n", str_id);
137         str_info =  &sst_drv_ctx->streams[str_id];
138         if (sst_drv_ctx->streams[str_id].status == STREAM_INIT) {
139                 if (str_info->ctrl_blk.on == true) {
140                         pr_err("control path in use\n");
141                         return -EAGAIN;
142                 }
143                 if (sst_create_large_msg(&msg))
144                         return -ENOMEM;
145
146                 sst_fill_header(&msg->header,
147                                 IPC_IA_SET_STREAM_PARAMS, 1, str_id);
148                 str_info->ctrl_blk.condition = false;
149                 str_info->ctrl_blk.ret_code = 0;
150                 str_info->ctrl_blk.on = true;
151                 msg->header.part.data = sizeof(u32) +
152                                 sizeof(str_param->sparams);
153                 memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
154                 memcpy(msg->mailbox_data + sizeof(u32), &str_param->sparams,
155                                 sizeof(str_param->sparams));
156                 spin_lock(&sst_drv_ctx->list_spin_lock);
157                 list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
158                 spin_unlock(&sst_drv_ctx->list_spin_lock);
159                 sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
160                 retval = sst_wait_interruptible_timeout(sst_drv_ctx,
161                                 &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
162                 if (retval < 0) {
163                         retval = -EIO;
164                         sst_clean_stream(str_info);
165                 }
166         } else {
167                 retval = -EBADRQC;
168                 pr_err("BADQRC for stream\n");
169         }
170         return retval;
171 }
172
173 /**
174 * sst_get_vol - This function allows to get the premix gain or gain of a stream
175 *
176 * @get_vol: this is an output param through which the volume
177 *       structure is passed back to user
178 *
179 * This function is called when the premix gain or stream gain is queried for
180 */
181 int sst_get_vol(struct snd_sst_vol *get_vol)
182 {
183         int retval = 0;
184         struct ipc_post *msg = NULL;
185         struct snd_sst_vol *fw_get_vol;
186         int str_id = get_vol->stream_id;
187
188         pr_debug("get vol called\n");
189
190         if (sst_create_short_msg(&msg))
191                 return -ENOMEM;
192
193         sst_fill_header(&msg->header,
194                                 IPC_IA_GET_STREAM_VOL, 0, str_id);
195         sst_drv_ctx->vol_info_blk.condition = false;
196         sst_drv_ctx->vol_info_blk.ret_code = 0;
197         sst_drv_ctx->vol_info_blk.on = true;
198         fw_get_vol = kzalloc(sizeof(*fw_get_vol), GFP_ATOMIC);
199         if (!fw_get_vol) {
200                 pr_err("mem allocation failed\n");
201                 kfree(msg);
202                 return -ENOMEM;
203         }
204         sst_drv_ctx->vol_info_blk.data = (void *)fw_get_vol;
205         spin_lock(&sst_drv_ctx->list_spin_lock);
206         list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
207         spin_unlock(&sst_drv_ctx->list_spin_lock);
208         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
209         retval = sst_wait_interruptible_timeout(sst_drv_ctx,
210                         &sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
211         if (retval)
212                 retval = -EIO;
213         else {
214                 pr_debug("stream id %d\n", fw_get_vol->stream_id);
215                 pr_debug("volume %d\n", fw_get_vol->volume);
216                 pr_debug("ramp duration %d\n", fw_get_vol->ramp_duration);
217                 pr_debug("ramp_type %d\n", fw_get_vol->ramp_type);
218                 memcpy(get_vol, fw_get_vol, sizeof(*fw_get_vol));
219         }
220         return retval;
221 }
222
223 /**
224 * sst_set_vol - This function allows to set the premix gain or gain of a stream
225 *
226 * @set_vol:     this holds the volume structure that needs to be set
227 *
228 * This function is called when premix gain or stream gain is requested to be set
229 */
230 int sst_set_vol(struct snd_sst_vol *set_vol)
231 {
232
233         int retval = 0;
234         struct ipc_post *msg = NULL;
235
236         pr_debug("set vol called\n");
237
238         if (sst_create_large_msg(&msg)) {
239                 pr_err("message creation failed\n");
240                 return -ENOMEM;
241         }
242         sst_fill_header(&msg->header, IPC_IA_SET_STREAM_VOL, 1,
243                                 set_vol->stream_id);
244
245         msg->header.part.data = sizeof(u32) + sizeof(*set_vol);
246         memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
247         memcpy(msg->mailbox_data + sizeof(u32), set_vol, sizeof(*set_vol));
248         sst_drv_ctx->vol_info_blk.condition = false;
249         sst_drv_ctx->vol_info_blk.ret_code = 0;
250         sst_drv_ctx->vol_info_blk.on = true;
251         sst_drv_ctx->vol_info_blk.data = set_vol;
252         spin_lock(&sst_drv_ctx->list_spin_lock);
253         list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
254         spin_unlock(&sst_drv_ctx->list_spin_lock);
255         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
256         retval = sst_wait_interruptible_timeout(sst_drv_ctx,
257                         &sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
258         if (retval) {
259                 pr_err("error in set_vol = %d\n", retval);
260                 retval = -EIO;
261         }
262         return retval;
263 }
264
265 /**
266 * sst_set_mute - This function sets premix mute or soft mute of a stream
267 *
268 * @set_mute:    this holds the mute structure that needs to be set
269 *
270 * This function is called when premix mute or stream mute requested to be set
271 */
272 int sst_set_mute(struct snd_sst_mute *set_mute)
273 {
274
275         int retval = 0;
276         struct ipc_post *msg = NULL;
277
278         pr_debug("set mute called\n");
279
280         if (sst_create_large_msg(&msg)) {
281                 pr_err("message creation failed\n");
282                 return -ENOMEM;
283         }
284         sst_fill_header(&msg->header, IPC_IA_SET_STREAM_MUTE, 1,
285                                 set_mute->stream_id);
286         sst_drv_ctx->mute_info_blk.condition = false;
287         sst_drv_ctx->mute_info_blk.ret_code = 0;
288         sst_drv_ctx->mute_info_blk.on = true;
289         sst_drv_ctx->mute_info_blk.data = set_mute;
290
291         msg->header.part.data = sizeof(u32) + sizeof(*set_mute);
292         memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
293         memcpy(msg->mailbox_data + sizeof(u32), set_mute,
294                         sizeof(*set_mute));
295         spin_lock(&sst_drv_ctx->list_spin_lock);
296         list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
297         spin_unlock(&sst_drv_ctx->list_spin_lock);
298         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
299         retval = sst_wait_interruptible_timeout(sst_drv_ctx,
300                         &sst_drv_ctx->mute_info_blk, SST_BLOCK_TIMEOUT);
301         if (retval) {
302                 pr_err("error in set_mute = %d\n", retval);
303                 retval = -EIO;
304         }
305         return retval;
306 }
307
308 int sst_prepare_target(struct snd_sst_slot_info *slot)
309 {
310         if (slot->target_device == SND_SST_TARGET_PMIC
311                 && slot->device_instance == 1) {
312                         /*music mode*/
313                         if (sst_drv_ctx->pmic_port_instance == 0)
314                                 sst_drv_ctx->scard_ops->set_voice_port(
315                                         DEACTIVATE);
316         } else if ((slot->target_device == SND_SST_TARGET_PMIC ||
317                         slot->target_device == SND_SST_TARGET_MODEM) &&
318                         slot->device_instance == 0) {
319                                 /*voip mode where pcm0 is active*/
320                                 if (sst_drv_ctx->pmic_port_instance == 1)
321                                         sst_drv_ctx->scard_ops->set_audio_port(
322                                                 DEACTIVATE);
323         }
324         return 0;
325 }
326
327 int sst_activate_target(struct snd_sst_slot_info *slot)
328 {
329         if (slot->target_device == SND_SST_TARGET_PMIC &&
330                 slot->device_instance == 1) {
331                         /*music mode*/
332                         sst_drv_ctx->pmic_port_instance = 1;
333                         sst_drv_ctx->scard_ops->set_audio_port(ACTIVATE);
334                         sst_drv_ctx->scard_ops->set_pcm_audio_params(
335                                 slot->pcm_params.sfreq,
336                                 slot->pcm_params.pcm_wd_sz,
337                                 slot->pcm_params.num_chan);
338                         if (sst_drv_ctx->pb_streams)
339                                 sst_drv_ctx->scard_ops->power_up_pmic_pb(1);
340                         if (sst_drv_ctx->cp_streams)
341                                 sst_drv_ctx->scard_ops->power_up_pmic_cp(1);
342         } else if ((slot->target_device == SND_SST_TARGET_PMIC ||
343                         slot->target_device == SND_SST_TARGET_MODEM) &&
344                         slot->device_instance == 0) {
345                                 /*voip mode where pcm0 is active*/
346                                 sst_drv_ctx->pmic_port_instance = 0;
347                                 sst_drv_ctx->scard_ops->set_voice_port(
348                                         ACTIVATE);
349                                 sst_drv_ctx->scard_ops->power_up_pmic_pb(0);
350                                 /*sst_drv_ctx->scard_ops->power_up_pmic_cp(0);*/
351         }
352         return 0;
353 }
354
355 int sst_parse_target(struct snd_sst_slot_info *slot)
356 {
357         int retval = 0;
358
359         if (slot->action == SND_SST_PORT_ACTIVATE &&
360                 slot->device_type == SND_SST_DEVICE_PCM) {
361                         retval = sst_activate_target(slot);
362                         if (retval)
363                                 pr_err("SST_Activate_target_fail\n");
364                         else
365                                 pr_err("SST_Activate_target_pass\n");
366         } else if (slot->action == SND_SST_PORT_PREPARE &&
367                         slot->device_type == SND_SST_DEVICE_PCM) {
368                                 retval = sst_prepare_target(slot);
369                         if (retval)
370                                 pr_err("SST_prepare_target_fail\n");
371                         else
372                                 pr_err("SST_prepare_target_pass\n");
373         } else {
374                 pr_err("slot_action : %d, device_type: %d\n",
375                                 slot->action, slot->device_type);
376         }
377         return retval;
378 }
379
380 int sst_send_target(struct snd_sst_target_device *target)
381 {
382         int retval;
383         struct ipc_post *msg;
384
385         if (sst_create_large_msg(&msg)) {
386                 pr_err("message creation failed\n");
387                 return -ENOMEM;
388         }
389         sst_fill_header(&msg->header, IPC_IA_TARGET_DEV_SELECT, 1, 0);
390         sst_drv_ctx->tgt_dev_blk.condition = false;
391         sst_drv_ctx->tgt_dev_blk.ret_code = 0;
392         sst_drv_ctx->tgt_dev_blk.on = true;
393
394         msg->header.part.data = sizeof(u32) + sizeof(*target);
395         memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
396         memcpy(msg->mailbox_data + sizeof(u32), target,
397                         sizeof(*target));
398         spin_lock(&sst_drv_ctx->list_spin_lock);
399         list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
400         spin_unlock(&sst_drv_ctx->list_spin_lock);
401         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
402         pr_debug("message sent- waiting\n");
403         retval = sst_wait_interruptible_timeout(sst_drv_ctx,
404                         &sst_drv_ctx->tgt_dev_blk, TARGET_DEV_BLOCK_TIMEOUT);
405         if (retval)
406                 pr_err("target device ipc failed = 0x%x\n", retval);
407         return retval;
408
409 }
410
411 int sst_target_device_validate(struct snd_sst_target_device *target)
412 {
413         int retval = 0;
414        int i;
415
416         for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) {
417                 if (target->devices[i].device_type == SND_SST_DEVICE_PCM) {
418                         /*pcm device, check params*/
419                         if (target->devices[i].device_instance == 1) {
420                                 if ((target->devices[i].device_mode !=
421                                 SND_SST_DEV_MODE_PCM_MODE4_I2S) &&
422                                 (target->devices[i].device_mode !=
423                                 SND_SST_DEV_MODE_PCM_MODE4_RIGHT_JUSTIFIED)
424                                 && (target->devices[i].device_mode !=
425                                 SND_SST_DEV_MODE_PCM_MODE1))
426                                         goto err;
427                         } else if (target->devices[i].device_instance == 0) {
428                                 if ((target->devices[i].device_mode !=
429                                                 SND_SST_DEV_MODE_PCM_MODE2)
430                                         && (target->devices[i].device_mode !=
431                                                 SND_SST_DEV_MODE_PCM_MODE4_I2S)
432                                         && (target->devices[i].device_mode !=
433                                                 SND_SST_DEV_MODE_PCM_MODE1))
434                                         goto err;
435                                 if (target->devices[i].pcm_params.sfreq != 8000
436                                 || target->devices[i].pcm_params.num_chan != 1
437                                 || target->devices[i].pcm_params.pcm_wd_sz !=
438                                                                         16)
439                                         goto err;
440                         } else {
441 err:
442                                 pr_err("i/p params incorrect\n");
443                                 return -EINVAL;
444                         }
445                 }
446         }
447     return retval;
448 }
449
450 /**
451  * sst_target_device_select - This function sets the target device configurations
452  *
453  * @target: this parameter holds the configurations to be set
454  *
455  * This function is called when the user layer wants to change the target
456  * device's configurations
457  */
458
459 int sst_target_device_select(struct snd_sst_target_device *target)
460 {
461         int retval, i, prepare_count = 0;
462
463         pr_debug("Target Device Select\n");
464
465         if (target->device_route < 0 || target->device_route > 2) {
466                 pr_err("device route is invalid\n");
467                 return -EINVAL;
468         }
469
470         if (target->device_route != 0) {
471                 pr_err("Unsupported config\n");
472                 return -EIO;
473         }
474         retval = sst_target_device_validate(target);
475         if (retval)
476                 return retval;
477
478         retval = sst_send_target(target);
479         if (retval)
480                 return retval;
481         for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) {
482                 if (target->devices[i].action == SND_SST_PORT_ACTIVATE) {
483                         pr_debug("activate called in %d\n", i);
484                         retval = sst_parse_target(&target->devices[i]);
485                         if (retval)
486                                 return retval;
487                 } else if (target->devices[i].action == SND_SST_PORT_PREPARE) {
488                         pr_debug("PREPARE in %d, Forwarding\n", i);
489                         retval = sst_parse_target(&target->devices[i]);
490                         if (retval) {
491                                 pr_err("Parse Target fail %d\n", retval);
492                                 return retval;
493                         }
494                         pr_debug("Parse Target successful %d\n", retval);
495                         if (target->devices[i].device_type ==
496                                                 SND_SST_DEVICE_PCM)
497                                 prepare_count++;
498                 }
499         }
500         if (target->devices[0].action == SND_SST_PORT_PREPARE &&
501                 prepare_count == 0)
502                         sst_drv_ctx->scard_ops->power_down_pmic();
503
504         return retval;
505 }
506 #ifdef CONFIG_MRST_RAR_HANDLER
507 /*This function gets the physical address of the secure memory from the handle*/
508 static inline int sst_get_RAR(struct RAR_buffer *buffers, int count)
509 {
510         int retval = 0, rar_status = 0;
511
512         rar_status = rar_handle_to_bus(buffers, count);
513
514         if (count != rar_status) {
515                 pr_err("The rar CALL Failed");
516                 retval = -EIO;
517         }
518         if (buffers->info.type != RAR_TYPE_AUDIO) {
519                 pr_err("Invalid RAR type\n");
520                 return -EINVAL;
521         }
522         return retval;
523 }
524
525 #endif
526
527 /* This function creates the scatter gather list to be sent to firmware to
528 capture/playback data*/
529 static int sst_create_sg_list(struct stream_info *stream,
530                 struct sst_frame_info *sg_list)
531 {
532         struct sst_stream_bufs *kbufs = NULL;
533 #ifdef CONFIG_MRST_RAR_HANDLER
534         struct RAR_buffer rar_buffers;
535         int retval = 0;
536 #endif
537         int i = 0;
538         list_for_each_entry(kbufs, &stream->bufs, node) {
539                 if (kbufs->in_use == false) {
540 #ifdef CONFIG_MRST_RAR_HANDLER
541                         if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
542                                 pr_debug("DRM playback handling\n");
543                                 rar_buffers.info.handle = (__u32)kbufs->addr;
544                                 rar_buffers.info.size = kbufs->size;
545                                 pr_debug("rar handle 0x%x size=0x%x\n",
546                                         rar_buffers.info.handle,
547                                         rar_buffers.info.size);
548                                 retval =  sst_get_RAR(&rar_buffers, 1);
549
550                                 if (retval)
551                                         return retval;
552                                 sg_list->addr[i].addr = rar_buffers.bus_address;
553                                 /* rar_buffers.info.size; */
554                                 sg_list->addr[i].size = (__u32)kbufs->size;
555                                 pr_debug("phyaddr[%d] 0x%x Size:0x%x\n"
556                                         , i, sg_list->addr[i].addr,
557                                         sg_list->addr[i].size);
558                         }
559 #endif
560                         if (stream->ops != STREAM_OPS_PLAYBACK_DRM) {
561                                 sg_list->addr[i].addr =
562                                         virt_to_phys((void *)
563                                                 kbufs->addr + kbufs->offset);
564                                 sg_list->addr[i].size = kbufs->size;
565                                 pr_debug("phyaddr[%d]:0x%x Size:0x%x\n"
566                                 , i , sg_list->addr[i].addr, kbufs->size);
567                         }
568                         stream->curr_bytes += sg_list->addr[i].size;
569                         kbufs->in_use = true;
570                         i++;
571                 }
572                 if (i >= MAX_NUM_SCATTER_BUFFERS)
573                         break;
574         }
575
576         sg_list->num_entries = i;
577         pr_debug("sg list entries = %d\n", sg_list->num_entries);
578         return i;
579 }
580
581
582 /**
583  * sst_play_frame - Send msg for sending stream frames
584  *
585  * @str_id:     ID of stream
586  *
587  * This function is called to send data to be played out
588  * to the firmware
589  */
590 int sst_play_frame(int str_id)
591 {
592         int i = 0, retval = 0;
593         struct ipc_post *msg = NULL;
594         struct sst_frame_info sg_list = {0};
595         struct sst_stream_bufs *kbufs = NULL, *_kbufs;
596         struct stream_info *stream;
597
598         pr_debug("play frame for %d\n", str_id);
599         retval = sst_validate_strid(str_id);
600         if (retval)
601                 return retval;
602
603         stream = &sst_drv_ctx->streams[str_id];
604         /* clear prev sent buffers */
605         list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
606                 if (kbufs->in_use == true) {
607                         spin_lock(&stream->pcm_lock);
608                         list_del(&kbufs->node);
609                         spin_unlock(&stream->pcm_lock);
610                         kfree(kbufs);
611                 }
612         }
613         /* update bytes sent */
614         stream->cumm_bytes += stream->curr_bytes;
615         stream->curr_bytes = 0;
616         if (list_empty(&stream->bufs)) {
617                 /* no user buffer available */
618                 pr_debug("Null buffer stream status %d\n", stream->status);
619                 stream->prev = stream->status;
620                 stream->status = STREAM_INIT;
621                 pr_debug("new stream status = %d\n", stream->status);
622                 if (stream->need_draining == true) {
623                         pr_debug("draining stream\n");
624                         if (sst_create_short_msg(&msg)) {
625                                 pr_err("mem allocation failed\n");
626                                 return -ENOMEM;
627                         }
628                         sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM,
629                                                 0, str_id);
630                         spin_lock(&sst_drv_ctx->list_spin_lock);
631                         list_add_tail(&msg->node,
632                                         &sst_drv_ctx->ipc_dispatch_list);
633                         spin_unlock(&sst_drv_ctx->list_spin_lock);
634                         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
635                 } else if (stream->data_blk.on == true) {
636                         pr_debug("user list empty.. wake\n");
637                         /* unblock */
638                         stream->data_blk.ret_code = 0;
639                         stream->data_blk.condition = true;
640                         stream->data_blk.on = false;
641                         wake_up(&sst_drv_ctx->wait_queue);
642                 }
643                 return 0;
644         }
645
646         /* create list */
647         i = sst_create_sg_list(stream, &sg_list);
648
649         /* post msg */
650         if (sst_create_large_msg(&msg))
651                 return -ENOMEM;
652
653         sst_fill_header(&msg->header, IPC_IA_PLAY_FRAMES, 1, str_id);
654         msg->header.part.data = sizeof(u32) + sizeof(sg_list);
655         memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
656         memcpy(msg->mailbox_data + sizeof(u32), &sg_list, sizeof(sg_list));
657         spin_lock(&sst_drv_ctx->list_spin_lock);
658         list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
659         spin_unlock(&sst_drv_ctx->list_spin_lock);
660         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
661         return 0;
662
663 }
664
665 /**
666  * sst_capture_frame - Send msg for sending stream frames
667  *
668  * @str_id:     ID of stream
669  *
670  * This function is called to capture data from the firmware
671  */
672 int sst_capture_frame(int str_id)
673 {
674         int i = 0, retval = 0;
675         struct ipc_post *msg = NULL;
676         struct sst_frame_info sg_list = {0};
677         struct sst_stream_bufs *kbufs = NULL, *_kbufs;
678         struct stream_info *stream;
679
680
681         pr_debug("capture frame for %d\n", str_id);
682         retval = sst_validate_strid(str_id);
683         if (retval)
684                 return retval;
685         stream = &sst_drv_ctx->streams[str_id];
686         /* clear prev sent buffers */
687         list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
688                 if (kbufs->in_use == true) {
689                         list_del(&kbufs->node);
690                         kfree(kbufs);
691                         pr_debug("del node\n");
692                 }
693         }
694         if (list_empty(&stream->bufs)) {
695                 /* no user buffer available */
696                 pr_debug("Null buffer!!!!stream status %d\n",
697                                stream->status);
698                 stream->prev = stream->status;
699                 stream->status = STREAM_INIT;
700                 pr_debug("new stream status = %d\n",
701                                stream->status);
702                 if (stream->data_blk.on == true) {
703                         pr_debug("user list empty.. wake\n");
704                         /* unblock */
705                         stream->data_blk.ret_code = 0;
706                         stream->data_blk.condition = true;
707                         stream->data_blk.on = false;
708                         wake_up(&sst_drv_ctx->wait_queue);
709
710                 }
711                 return 0;
712         }
713         /* create new sg list */
714         i = sst_create_sg_list(stream, &sg_list);
715
716         /* post msg */
717         if (sst_create_large_msg(&msg))
718                 return -ENOMEM;
719
720         sst_fill_header(&msg->header, IPC_IA_CAPT_FRAMES, 1, str_id);
721         msg->header.part.data = sizeof(u32) + sizeof(sg_list);
722         memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
723         memcpy(msg->mailbox_data + sizeof(u32), &sg_list, sizeof(sg_list));
724         spin_lock(&sst_drv_ctx->list_spin_lock);
725         list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
726         spin_unlock(&sst_drv_ctx->list_spin_lock);
727         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
728
729
730         /*update bytes recevied*/
731         stream->cumm_bytes += stream->curr_bytes;
732         stream->curr_bytes = 0;
733
734     pr_debug("Cum bytes  = %d\n", stream->cumm_bytes);
735         return 0;
736 }
737
738 /*This function is used to calculate the minimum size of input buffers given*/
739 static unsigned int calculate_min_size(struct snd_sst_buffs *bufs)
740 {
741         int i, min_val = bufs->buff_entry[0].size;
742         for (i = 1 ; i < bufs->entries; i++) {
743                 if (bufs->buff_entry[i].size < min_val)
744                         min_val = bufs->buff_entry[i].size;
745         }
746         pr_debug("min_val = %d\n", min_val);
747         return min_val;
748 }
749
750 static unsigned int calculate_max_size(struct snd_sst_buffs *bufs)
751 {
752         int i, max_val = bufs->buff_entry[0].size;
753         for (i = 1 ; i < bufs->entries; i++) {
754                 if (bufs->buff_entry[i].size > max_val)
755                         max_val = bufs->buff_entry[i].size;
756         }
757         pr_debug("max_val = %d\n", max_val);
758         return max_val;
759 }
760
761 /*This function is used to allocate input and output buffers to be sent to
762 the firmware that will take encoded data and return decoded data*/
763 static int sst_allocate_decode_buf(struct stream_info *str_info,
764                                 struct snd_sst_dbufs *dbufs,
765                                 unsigned int cum_input_given,
766                                 unsigned int cum_output_given)
767 {
768 #ifdef CONFIG_MRST_RAR_HANDLER
769         if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
770
771                 if (dbufs->ibufs->type == SST_BUF_RAR  &&
772                         dbufs->obufs->type == SST_BUF_RAR) {
773                         if (dbufs->ibufs->entries == dbufs->obufs->entries)
774                                 return 0;
775                         else {
776                                 pr_err("RAR entries dont match\n");
777                                  return -EINVAL;
778                         }
779                 } else
780                         str_info->decode_osize = cum_output_given;
781                 return 0;
782
783         }
784 #endif
785         if (!str_info->decode_ibuf) {
786                 pr_debug("no i/p buffers, trying full size\n");
787                 str_info->decode_isize = cum_input_given;
788                 str_info->decode_ibuf = kzalloc(str_info->decode_isize,
789                                                 GFP_KERNEL);
790                 str_info->idecode_alloc = str_info->decode_isize;
791         }
792         if (!str_info->decode_ibuf) {
793                 pr_debug("buff alloc failed, try max size\n");
794                 str_info->decode_isize = calculate_max_size(dbufs->ibufs);
795                 str_info->decode_ibuf = kzalloc(
796                                 str_info->decode_isize, GFP_KERNEL);
797                 str_info->idecode_alloc = str_info->decode_isize;
798         }
799         if (!str_info->decode_ibuf) {
800                 pr_debug("buff alloc failed, try min size\n");
801                 str_info->decode_isize = calculate_min_size(dbufs->ibufs);
802                 str_info->decode_ibuf = kzalloc(str_info->decode_isize,
803                                                 GFP_KERNEL);
804                 if (!str_info->decode_ibuf) {
805                         pr_err("mem allocation failed\n");
806                         return -ENOMEM;
807                 }
808                 str_info->idecode_alloc = str_info->decode_isize;
809         }
810         str_info->decode_osize = cum_output_given;
811         if (str_info->decode_osize > sst_drv_ctx->mmap_len)
812                 str_info->decode_osize = sst_drv_ctx->mmap_len;
813         return 0;
814 }
815
816 /*This function is used to send the message to firmware to decode the data*/
817 static int sst_send_decode_mess(int str_id, struct stream_info *str_info,
818                                 struct snd_sst_decode_info *dec_info)
819 {
820         struct ipc_post *msg = NULL;
821         int retval = 0;
822
823         pr_debug("SST DBG:sst_set_mute:called\n");
824
825         if (str_info->decode_ibuf_type == SST_BUF_RAR) {
826 #ifdef CONFIG_MRST_RAR_HANDLER
827                         dec_info->frames_in.addr[0].addr =
828                                 (unsigned long)str_info->decode_ibuf;
829                         dec_info->frames_in.addr[0].size =
830                                                         str_info->decode_isize;
831 #endif
832
833         } else {
834                 dec_info->frames_in.addr[0].addr = virt_to_phys((void *)
835                                         str_info->decode_ibuf);
836                 dec_info->frames_in.addr[0].size = str_info->decode_isize;
837         }
838
839
840         if (str_info->decode_obuf_type == SST_BUF_RAR) {
841 #ifdef CONFIG_MRST_RAR_HANDLER
842                 dec_info->frames_out.addr[0].addr =
843                                 (unsigned long)str_info->decode_obuf;
844                 dec_info->frames_out.addr[0].size = str_info->decode_osize;
845 #endif
846
847         } else {
848                 dec_info->frames_out.addr[0].addr = virt_to_phys((void *)
849                                                 str_info->decode_obuf) ;
850                 dec_info->frames_out.addr[0].size = str_info->decode_osize;
851         }
852
853         dec_info->frames_in.num_entries = 1;
854         dec_info->frames_out.num_entries = 1;
855         dec_info->frames_in.rsrvd = 0;
856         dec_info->frames_out.rsrvd = 0;
857         dec_info->input_bytes_consumed = 0;
858         dec_info->output_bytes_produced = 0;
859         if (sst_create_large_msg(&msg)) {
860                 pr_err("message creation failed\n");
861                 return -ENOMEM;
862         }
863
864         sst_fill_header(&msg->header, IPC_IA_DECODE_FRAMES, 1, str_id);
865         msg->header.part.data = sizeof(u32) + sizeof(*dec_info);
866         memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
867         memcpy(msg->mailbox_data + sizeof(u32), dec_info,
868                         sizeof(*dec_info));
869         spin_lock(&sst_drv_ctx->list_spin_lock);
870         list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
871         spin_unlock(&sst_drv_ctx->list_spin_lock);
872         str_info->data_blk.condition = false;
873         str_info->data_blk.ret_code = 0;
874         str_info->data_blk.on = true;
875         str_info->data_blk.data = dec_info;
876         sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
877         retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk);
878         return retval;
879 }
880
881 #ifdef CONFIG_MRST_RAR_HANDLER
882 static int sst_prepare_input_buffers_rar(struct stream_info *str_info,
883                         struct snd_sst_dbufs *dbufs,
884                         int *input_index, int *in_copied,
885                         int *input_index_valid_size, int *new_entry_flag)
886 {
887         int retval = 0, i;
888
889         if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
890                 struct RAR_buffer rar_buffers;
891                 __u32 info;
892                 retval = copy_from_user((void *) &info,
893                                 dbufs->ibufs->buff_entry[i].buffer,
894                                 sizeof(__u32));
895                 if (retval) {
896                         pr_err("cpy from user fail\n");
897                         return -EAGAIN;
898                 }
899                 rar_buffers.info.type = dbufs->ibufs->type;
900                 rar_buffers.info.size = dbufs->ibufs->buff_entry[i].size;
901                 rar_buffers.info.handle =  info;
902                 pr_debug("rar in DnR(input buffer function)=0x%x size=0x%x",
903                                 rar_buffers.info.handle,
904                                 rar_buffers.info.size);
905                 retval =  sst_get_RAR(&rar_buffers, 1);
906                 if (retval) {
907                         pr_debug("SST ERR: RAR API failed\n");
908                         return retval;
909                 }
910                 str_info->decode_ibuf =
911                 (void *) ((unsigned long) rar_buffers.bus_address);
912                 pr_debug("RAR buf addr in DnR (input buffer function)0x%lu",
913                                  (unsigned long) str_info->decode_ibuf);
914                 pr_debug("rar in DnR decode function/output b_add rar =0x%lu",
915                                 (unsigned long) rar_buffers.bus_address);
916                 *input_index = i + 1;
917                 str_info->decode_isize = dbufs->ibufs->buff_entry[i].size;
918                 str_info->decode_ibuf_type = dbufs->ibufs->type;
919                 *in_copied = str_info->decode_isize;
920         }
921         return retval;
922 }
923 #endif
924 /*This function is used to prepare the kernel input buffers with contents
925 before sending for decode*/
926 static int sst_prepare_input_buffers(struct stream_info *str_info,
927                         struct snd_sst_dbufs *dbufs,
928                         int *input_index, int *in_copied,
929                         int *input_index_valid_size, int *new_entry_flag)
930 {
931         int i, cpy_size, retval = 0;
932
933         pr_debug("input_index = %d, input entries = %d\n",
934                          *input_index, dbufs->ibufs->entries);
935         for (i = *input_index; i < dbufs->ibufs->entries; i++) {
936 #ifdef CONFIG_MRST_RAR_HANDLER
937                 retval = sst_prepare_input_buffers_rar(str_info,
938                         dbufs, input_index, in_copied,
939                                 input_index_valid_size, new_entry_flag);
940                 if (retval) {
941                         pr_err("In prepare input buffers for RAR\n");
942                         return -EIO;
943                 }
944 #endif
945                 *input_index = i;
946                 if (*input_index_valid_size == 0)
947                         *input_index_valid_size =
948                                 dbufs->ibufs->buff_entry[i].size;
949                 pr_debug("inout addr = %p, size = %d\n",
950                         dbufs->ibufs->buff_entry[i].buffer,
951                         *input_index_valid_size);
952                 pr_debug("decode_isize = %d, in_copied %d\n",
953                         str_info->decode_isize, *in_copied);
954                 if (*input_index_valid_size <=
955                                         (str_info->decode_isize - *in_copied))
956                         cpy_size = *input_index_valid_size;
957                 else
958                         cpy_size = str_info->decode_isize - *in_copied;
959
960                 pr_debug("cpy size = %d\n", cpy_size);
961                 if (!dbufs->ibufs->buff_entry[i].buffer) {
962                         pr_err("i/p buffer is null\n");
963                         return -EINVAL;
964                 }
965                 pr_debug("Try copy To %p, From %p, size %d\n",
966                                 str_info->decode_ibuf + *in_copied,
967                                 dbufs->ibufs->buff_entry[i].buffer, cpy_size);
968
969                 retval =
970                 copy_from_user((void *)(str_info->decode_ibuf + *in_copied),
971                                 (void *) dbufs->ibufs->buff_entry[i].buffer,
972                                 cpy_size);
973                 if (retval) {
974                         pr_err("copy from user failed\n");
975                         return -EIO;
976                 }
977                 *in_copied += cpy_size;
978                 *input_index_valid_size -= cpy_size;
979                 pr_debug("in buff size = %d, in_copied = %d\n",
980                         *input_index_valid_size, *in_copied);
981                 if (*input_index_valid_size != 0) {
982                         pr_debug("more input buffers left\n");
983                         dbufs->ibufs->buff_entry[i].buffer += cpy_size;
984                         break;
985                 }
986                 if (*in_copied == str_info->decode_isize &&
987                         *input_index_valid_size == 0 &&
988                         (i+1) <= dbufs->ibufs->entries) {
989                         pr_debug("all input buffers copied\n");
990                         *new_entry_flag = true;
991                         *input_index = i + 1;
992                         break;
993                 }
994         }
995         return retval;
996 }
997
998 /* This function is used to copy the decoded data from kernel buffers to
999 the user output buffers with contents after decode*/
1000 static int sst_prepare_output_buffers(struct stream_info *str_info,
1001                         struct snd_sst_dbufs *dbufs,
1002                         int *output_index, int output_size,
1003                         int *out_copied)
1004
1005 {
1006         int i, cpy_size, retval = 0;
1007         pr_debug("output_index = %d, output entries = %d\n",
1008                                 *output_index,
1009                                 dbufs->obufs->entries);
1010         for (i = *output_index; i < dbufs->obufs->entries; i++) {
1011                 *output_index = i;
1012                 pr_debug("output addr = %p, size = %d\n",
1013                         dbufs->obufs->buff_entry[i].buffer,
1014                         dbufs->obufs->buff_entry[i].size);
1015                 pr_debug("output_size = %d, out_copied = %d\n",
1016                                 output_size, *out_copied);
1017                 if (dbufs->obufs->buff_entry[i].size <
1018                                 (output_size - *out_copied))
1019                         cpy_size = dbufs->obufs->buff_entry[i].size;
1020                 else
1021                         cpy_size = output_size - *out_copied;
1022                 pr_debug("cpy size = %d\n", cpy_size);
1023                 pr_debug("Try copy To: %p, From %p, size %d\n",
1024                                 dbufs->obufs->buff_entry[i].buffer,
1025                                 sst_drv_ctx->mmap_mem + *out_copied,
1026                                 cpy_size);
1027                 retval = copy_to_user(dbufs->obufs->buff_entry[i].buffer,
1028                                         sst_drv_ctx->mmap_mem + *out_copied,
1029                                         cpy_size);
1030                 if (retval) {
1031                         pr_err("copy to user failed\n");
1032                         return -EIO;
1033                 } else
1034                         pr_debug("copy to user passed\n");
1035                 *out_copied += cpy_size;
1036                 dbufs->obufs->buff_entry[i].size -= cpy_size;
1037                 pr_debug("o/p buff size %d, out_copied %d\n",
1038                         dbufs->obufs->buff_entry[i].size, *out_copied);
1039                 if (dbufs->obufs->buff_entry[i].size != 0) {
1040                         *output_index = i;
1041                         dbufs->obufs->buff_entry[i].buffer += cpy_size;
1042                         break;
1043                 } else if (*out_copied == output_size) {
1044                         *output_index = i + 1;
1045                         break;
1046                 }
1047         }
1048         return retval;
1049 }
1050
1051 /**
1052  * sst_decode - Send msg for decoding frames
1053  *
1054  * @str_id: ID of stream
1055  * @dbufs: param that holds the user input and output buffers and size
1056  *
1057  * This function is called to decode data from the firmware
1058  */
1059 int sst_decode(int str_id, struct snd_sst_dbufs *dbufs)
1060 {
1061         int retval = 0, i;
1062         unsigned long long total_input = 0 , total_output = 0;
1063         unsigned int cum_input_given = 0 , cum_output_given = 0;
1064         int copy_in_done = false, copy_out_done = false;
1065         int input_index = 0, output_index = 0;
1066         int input_index_valid_size = 0;
1067         int in_copied, out_copied;
1068         int new_entry_flag;
1069         u64 output_size;
1070         struct stream_info *str_info;
1071         struct snd_sst_decode_info dec_info;
1072         unsigned long long input_bytes, output_bytes;
1073
1074         sst_drv_ctx->scard_ops->power_down_pmic();
1075         pr_debug("Powering_down_PMIC...\n");
1076
1077         retval = sst_validate_strid(str_id);
1078         if (retval)
1079                 return retval;
1080
1081         str_info = &sst_drv_ctx->streams[str_id];
1082         if (str_info->status != STREAM_INIT) {
1083                 pr_err("invalid stream state = %d\n",
1084                                str_info->status);
1085                 return -EINVAL;
1086         }
1087
1088         str_info->prev = str_info->status;
1089         str_info->status = STREAM_DECODE;
1090
1091         for (i = 0; i < dbufs->ibufs->entries; i++)
1092                 cum_input_given += dbufs->ibufs->buff_entry[i].size;
1093         for (i = 0; i < dbufs->obufs->entries; i++)
1094                 cum_output_given += dbufs->obufs->buff_entry[i].size;
1095
1096         /* input and output buffer allocation */
1097         retval =  sst_allocate_decode_buf(str_info, dbufs,
1098                                 cum_input_given, cum_output_given);
1099         if (retval) {
1100                 pr_err("mem allocation failed, abort!!!\n");
1101                 retval = -ENOMEM;
1102                 goto finish;
1103         }
1104
1105         str_info->decode_isize = str_info->idecode_alloc;
1106         str_info->decode_ibuf_type = dbufs->ibufs->type;
1107         str_info->decode_obuf_type = dbufs->obufs->type;
1108
1109         while ((copy_out_done == false) && (copy_in_done == false)) {
1110                 in_copied = 0;
1111                 new_entry_flag = false;
1112                 retval = sst_prepare_input_buffers(str_info,\
1113                         dbufs, &input_index, &in_copied,
1114                         &input_index_valid_size, &new_entry_flag);
1115                 if (retval) {
1116                         pr_err("prepare in buffers failed\n");
1117                         goto finish;
1118                 }
1119
1120                 if (str_info->ops != STREAM_OPS_PLAYBACK_DRM)
1121                         str_info->decode_obuf = sst_drv_ctx->mmap_mem;
1122
1123 #ifdef CONFIG_MRST_RAR_HANDLER
1124                 else {
1125                         if (dbufs->obufs->type == SST_BUF_RAR) {
1126                                 struct RAR_buffer rar_buffers;
1127                                 __u32 info;
1128
1129                                 pr_debug("DRM");
1130                                 retval = copy_from_user((void *) &info,
1131                                                 dbufs->obufs->
1132                                                 buff_entry[output_index].buffer,
1133                                                 sizeof(__u32));
1134
1135                                 rar_buffers.info.size = dbufs->obufs->
1136                                         buff_entry[output_index].size;
1137                                 rar_buffers.info.handle =  info;
1138                                 retval =  sst_get_RAR(&rar_buffers, 1);
1139                                 if (retval)
1140                                         return retval;
1141
1142                                 str_info->decode_obuf = (void *)((unsigned long)
1143                                                 rar_buffers.bus_address);
1144                                 str_info->decode_osize = dbufs->obufs->
1145                                         buff_entry[output_index].size;
1146                                 str_info->decode_obuf_type = dbufs->obufs->type;
1147                                 pr_debug("DRM handling\n");
1148                                 pr_debug("o/p_add=0x%lu Size=0x%x\n",
1149                                         (unsigned long) str_info->decode_obuf,
1150                                         str_info->decode_osize);
1151                         } else {
1152                                 str_info->decode_obuf = sst_drv_ctx->mmap_mem;
1153                                 str_info->decode_osize = dbufs->obufs->
1154                                         buff_entry[output_index].size;
1155
1156                         }
1157                 }
1158 #endif
1159                 if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
1160                         if (str_info->decode_isize > in_copied) {
1161                                 str_info->decode_isize = in_copied;
1162                                 pr_debug("i/p size = %d\n",
1163                                                 str_info->decode_isize);
1164                         }
1165                 }
1166
1167
1168                 retval = sst_send_decode_mess(str_id, str_info, &dec_info);
1169                 if (retval || dec_info.input_bytes_consumed == 0) {
1170                         pr_err("SST ERR: mess failed or no input consumed\n");
1171                         goto finish;
1172                 }
1173                 input_bytes = dec_info.input_bytes_consumed;
1174                 output_bytes = dec_info.output_bytes_produced;
1175
1176                 pr_debug("in_copied=%d, con=%lld, prod=%lld\n",
1177                         in_copied, input_bytes, output_bytes);
1178                 if (dbufs->obufs->type == SST_BUF_RAR) {
1179                         output_index += 1;
1180                         if (output_index == dbufs->obufs->entries) {
1181                                 copy_in_done = true;
1182                                 pr_debug("all i/p cpy done\n");
1183                         }
1184                         total_output += output_bytes;
1185                 } else {
1186                         out_copied = 0;
1187                         output_size = output_bytes;
1188                         retval = sst_prepare_output_buffers(str_info, dbufs,
1189                                 &output_index, output_size, &out_copied);
1190                         if (retval) {
1191                                 pr_err("prep out buff fail\n");
1192                                 goto finish;
1193                         }
1194                         if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
1195                                 if (in_copied != input_bytes) {
1196                                         int bytes_left = in_copied -
1197                                                                 input_bytes;
1198                                         pr_debug("bytes %d\n",
1199                                                         bytes_left);
1200                                         if (new_entry_flag == true)
1201                                                 input_index--;
1202                                         while (bytes_left) {
1203                                                 struct snd_sst_buffs *ibufs;
1204                                                 struct snd_sst_buff_entry
1205                                                                 *buff_entry;
1206                                                 unsigned int size_sent;
1207
1208                                                 ibufs = dbufs->ibufs;
1209                                                 buff_entry =
1210                                                 &ibufs->buff_entry[input_index];
1211                                                 size_sent = buff_entry->size -\
1212                                                         input_index_valid_size;
1213                                                 if (bytes_left == size_sent) {
1214                                                                 bytes_left = 0;
1215                                                 } else if (bytes_left <
1216                                                                 size_sent) {
1217                                                         buff_entry->buffer +=
1218                                                          (size_sent -
1219                                                                 bytes_left);
1220                                                         buff_entry->size -=
1221                                                          (size_sent -
1222                                                                 bytes_left);
1223                                                         bytes_left = 0;
1224                                                 } else {
1225                                                         bytes_left -= size_sent;
1226                                                         input_index--;
1227                                                         input_index_valid_size =
1228                                                                         0;
1229                                                 }
1230                                         }
1231
1232                                 }
1233                         }
1234
1235                         total_output += out_copied;
1236                         if (str_info->decode_osize != out_copied) {
1237                                 str_info->decode_osize -= out_copied;
1238                                 pr_debug("output size modified = %d\n",
1239                                                 str_info->decode_osize);
1240                         }
1241                 }
1242                 total_input += input_bytes;
1243
1244                 if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
1245                         if (total_input == cum_input_given)
1246                                 copy_in_done = true;
1247                         copy_out_done = true;
1248
1249                 } else {
1250                         if (total_output == cum_output_given) {
1251                                 copy_out_done = true;
1252                                 pr_debug("all o/p cpy done\n");
1253                         }
1254
1255                         if (total_input == cum_input_given) {
1256                                 copy_in_done = true;
1257                                 pr_debug("all i/p cpy done\n");
1258                         }
1259                 }
1260
1261                 pr_debug("copy_out = %d, copy_in = %d\n",
1262                                 copy_out_done, copy_in_done);
1263         }
1264
1265 finish:
1266         dbufs->input_bytes_consumed = total_input;
1267         dbufs->output_bytes_produced = total_output;
1268         str_info->status = str_info->prev;
1269         str_info->prev = STREAM_DECODE;
1270         kfree(str_info->decode_ibuf);
1271         str_info->decode_ibuf = NULL;
1272         return retval;
1273 }