Merge branch 'topic/hda' into for-linus
[GitHub/mt8127/android_kernel_alcatel_ttab.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 #include <linux/pci.h>
30 #include <linux/syscalls.h>
31 #include <linux/firmware.h>
32 #include <linux/sched.h>
33 #include <linux/rar_register.h>
34 #ifdef CONFIG_MRST_RAR_HANDLER
35 #include "../../../drivers/staging/memrar/memrar.h"
36 #endif
37 #include "intel_sst_ioctl.h"
38 #include "intel_sst.h"
39 #include "intel_sst_fw_ipc.h"
40 #include "intel_sst_common.h"
41 /**
42 * sst_get_stream_params - Send msg to query for stream parameters
43 * @str_id: stream id for which the parameters are queried for
44 * @get_params: out parameters to which the parameters are copied to
45 *
46 * This function is called when the stream parameters are queiried for
47 */
48 int sst_get_stream_params(int str_id,
49 struct snd_sst_get_stream_params *get_params)
50 {
51 int retval = 0;
52 struct ipc_post *msg = NULL;
53 struct stream_info *str_info;
54 struct snd_sst_fw_get_stream_params *fw_params;
55
56 pr_debug("sst: get_stream for %d\n", str_id);
57 retval = sst_validate_strid(str_id);
58 if (retval)
59 return retval;
60
61 str_info = &sst_drv_ctx->streams[str_id];
62 if (str_info->status != STREAM_UN_INIT) {
63 if (str_info->ctrl_blk.on == true) {
64 pr_err("sst: control path in use\n");
65 return -EINVAL;
66 }
67 if (sst_create_short_msg(&msg)) {
68 pr_err("sst: message creation failed\n");
69 return -ENOMEM;
70 }
71 fw_params = kzalloc(sizeof(*fw_params), GFP_ATOMIC);
72 if (!fw_params) {
73 pr_err("sst: mem allcoation failed\n ");
74 kfree(msg);
75 return -ENOMEM;
76 }
77
78 sst_fill_header(&msg->header, IPC_IA_GET_STREAM_PARAMS,
79 0, str_id);
80 str_info->ctrl_blk.condition = false;
81 str_info->ctrl_blk.ret_code = 0;
82 str_info->ctrl_blk.on = true;
83 str_info->ctrl_blk.data = (void *) fw_params;
84 spin_lock(&sst_drv_ctx->list_spin_lock);
85 list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
86 spin_unlock(&sst_drv_ctx->list_spin_lock);
87 sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
88 retval = sst_wait_interruptible_timeout(sst_drv_ctx,
89 &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
90 if (retval) {
91 get_params->codec_params.result = retval;
92 kfree(fw_params);
93 return -EIO;
94 }
95 memcpy(&get_params->pcm_params, &fw_params->pcm_params,
96 sizeof(fw_params->pcm_params));
97 memcpy(&get_params->codec_params.sparams,
98 &fw_params->codec_params,
99 sizeof(fw_params->codec_params));
100 get_params->codec_params.result = 0;
101 get_params->codec_params.stream_id = str_id;
102 get_params->codec_params.codec = str_info->codec;
103 get_params->codec_params.ops = str_info->ops;
104 get_params->codec_params.stream_type = str_info->str_type;
105 kfree(fw_params);
106 } else {
107 pr_debug("sst: Stream is not in the init state\n");
108 }
109 return retval;
110 }
111
112 /**
113 * sst_set_stream_param - Send msg for setting stream parameters
114 *
115 * @str_id: stream id
116 * @str_param: stream params
117 *
118 * This function sets stream params during runtime
119 */
120 int sst_set_stream_param(int str_id, struct snd_sst_params *str_param)
121 {
122 int retval = 0;
123 struct ipc_post *msg = NULL;
124 struct stream_info *str_info;
125
126 BUG_ON(!str_param);
127 if (sst_drv_ctx->streams[str_id].ops != str_param->ops) {
128 pr_err("sst: Invalid operation\n");
129 return -EINVAL;
130 }
131 retval = sst_validate_strid(str_id);
132 if (retval)
133 return retval;
134 pr_debug("sst: set_stream for %d\n", str_id);
135 str_info = &sst_drv_ctx->streams[str_id];
136 if (sst_drv_ctx->streams[str_id].status == STREAM_INIT) {
137 if (str_info->ctrl_blk.on == true) {
138 pr_err("sst: control path in use\n");
139 return -EAGAIN;
140 }
141 if (sst_create_large_msg(&msg))
142 return -ENOMEM;
143
144 sst_fill_header(&msg->header,
145 IPC_IA_SET_STREAM_PARAMS, 1, str_id);
146 str_info->ctrl_blk.condition = false;
147 str_info->ctrl_blk.ret_code = 0;
148 str_info->ctrl_blk.on = true;
149 msg->header.part.data = sizeof(u32) +
150 sizeof(str_param->sparams);
151 memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
152 memcpy(msg->mailbox_data + sizeof(u32), &str_param->sparams,
153 sizeof(str_param->sparams));
154 spin_lock(&sst_drv_ctx->list_spin_lock);
155 list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
156 spin_unlock(&sst_drv_ctx->list_spin_lock);
157 sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
158 retval = sst_wait_interruptible_timeout(sst_drv_ctx,
159 &str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
160 if (retval < 0) {
161 retval = -EIO;
162 sst_clean_stream(str_info);
163 }
164 } else {
165 retval = -EBADRQC;
166 pr_err("sst: BADQRC for stream\n");
167 }
168 return retval;
169 }
170
171 /**
172 * sst_get_vol - This fuction allows to get the premix gain or gain of a stream
173 *
174 * @get_vol: this is an output param through which the volume
175 * structure is passed back to user
176 *
177 * This function is called when the premix gain or stream gain is queried for
178 */
179 int sst_get_vol(struct snd_sst_vol *get_vol)
180 {
181 int retval = 0;
182 struct ipc_post *msg = NULL;
183 struct snd_sst_vol *fw_get_vol;
184 int str_id = get_vol->stream_id;
185
186 pr_debug("sst: get vol called\n");
187
188 if (sst_create_short_msg(&msg))
189 return -ENOMEM;
190
191 sst_fill_header(&msg->header,
192 IPC_IA_GET_STREAM_VOL, 0, str_id);
193 sst_drv_ctx->vol_info_blk.condition = false;
194 sst_drv_ctx->vol_info_blk.ret_code = 0;
195 sst_drv_ctx->vol_info_blk.on = true;
196 fw_get_vol = kzalloc(sizeof(*fw_get_vol), GFP_ATOMIC);
197 if (!fw_get_vol) {
198 pr_err("sst: mem allocation failed\n");
199 kfree(msg);
200 return -ENOMEM;
201 }
202 sst_drv_ctx->vol_info_blk.data = (void *)fw_get_vol;
203 spin_lock(&sst_drv_ctx->list_spin_lock);
204 list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
205 spin_unlock(&sst_drv_ctx->list_spin_lock);
206 sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
207 retval = sst_wait_interruptible_timeout(sst_drv_ctx,
208 &sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
209 if (retval)
210 retval = -EIO;
211 else {
212 pr_debug("sst: stream id %d\n", fw_get_vol->stream_id);
213 pr_debug("sst: volume %d\n", fw_get_vol->volume);
214 pr_debug("sst: ramp duration %d\n", fw_get_vol->ramp_duration);
215 pr_debug("sst: ramp_type %d\n", fw_get_vol->ramp_type);
216 memcpy(get_vol, fw_get_vol, sizeof(*fw_get_vol));
217 }
218 return retval;
219 }
220
221 /**
222 * sst_set_vol - This fuction allows to set the premix gain or gain of a stream
223 *
224 * @set_vol: this holds the volume structure that needs to be set
225 *
226 * This function is called when premix gain or stream gain is requested to be set
227 */
228 int sst_set_vol(struct snd_sst_vol *set_vol)
229 {
230
231 int retval = 0;
232 struct ipc_post *msg = NULL;
233
234 pr_debug("sst: set vol called\n");
235
236 if (sst_create_large_msg(&msg)) {
237 pr_err("sst: message creation failed\n");
238 return -ENOMEM;
239 }
240 sst_fill_header(&msg->header, IPC_IA_SET_STREAM_VOL, 1,
241 set_vol->stream_id);
242
243 msg->header.part.data = sizeof(u32) + sizeof(*set_vol);
244 memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
245 memcpy(msg->mailbox_data + sizeof(u32), set_vol, sizeof(*set_vol));
246 sst_drv_ctx->vol_info_blk.condition = false;
247 sst_drv_ctx->vol_info_blk.ret_code = 0;
248 sst_drv_ctx->vol_info_blk.on = true;
249 sst_drv_ctx->vol_info_blk.data = set_vol;
250 spin_lock(&sst_drv_ctx->list_spin_lock);
251 list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
252 spin_unlock(&sst_drv_ctx->list_spin_lock);
253 sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
254 retval = sst_wait_interruptible_timeout(sst_drv_ctx,
255 &sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
256 if (retval) {
257 pr_err("sst: error in set_vol = %d\n", retval);
258 retval = -EIO;
259 }
260 return retval;
261 }
262
263 /**
264 * sst_set_mute - This fuction sets premix mute or soft mute of a stream
265 *
266 * @set_mute: this holds the mute structure that needs to be set
267 *
268 * This function is called when premix mute or stream mute requested to be set
269 */
270 int sst_set_mute(struct snd_sst_mute *set_mute)
271 {
272
273 int retval = 0;
274 struct ipc_post *msg = NULL;
275
276 pr_debug("sst: set mute called\n");
277
278 if (sst_create_large_msg(&msg)) {
279 pr_err("sst: message creation failed\n");
280 return -ENOMEM;
281 }
282 sst_fill_header(&msg->header, IPC_IA_SET_STREAM_MUTE, 1,
283 set_mute->stream_id);
284 sst_drv_ctx->mute_info_blk.condition = false;
285 sst_drv_ctx->mute_info_blk.ret_code = 0;
286 sst_drv_ctx->mute_info_blk.on = true;
287 sst_drv_ctx->mute_info_blk.data = set_mute;
288
289 msg->header.part.data = sizeof(u32) + sizeof(*set_mute);
290 memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
291 memcpy(msg->mailbox_data + sizeof(u32), set_mute,
292 sizeof(*set_mute));
293 spin_lock(&sst_drv_ctx->list_spin_lock);
294 list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
295 spin_unlock(&sst_drv_ctx->list_spin_lock);
296 sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
297 retval = sst_wait_interruptible_timeout(sst_drv_ctx,
298 &sst_drv_ctx->mute_info_blk, SST_BLOCK_TIMEOUT);
299 if (retval) {
300 pr_err("sst: error in set_mute = %d\n", retval);
301 retval = -EIO;
302 }
303 return retval;
304 }
305
306 int sst_prepare_target(struct snd_sst_slot_info *slot)
307 {
308 if (slot->target_device == SND_SST_TARGET_PMIC
309 && slot->device_instance == 1) {
310 /*music mode*/
311 if (sst_drv_ctx->pmic_port_instance == 0)
312 sst_drv_ctx->scard_ops->set_voice_port(
313 DEACTIVATE);
314 } else if ((slot->target_device == SND_SST_TARGET_PMIC ||
315 slot->target_device == SND_SST_TARGET_MODEM) &&
316 slot->device_instance == 0) {
317 /*voip mode where pcm0 is active*/
318 if (sst_drv_ctx->pmic_port_instance == 1)
319 sst_drv_ctx->scard_ops->set_audio_port(
320 DEACTIVATE);
321 }
322 return 0;
323 }
324
325 int sst_activate_target(struct snd_sst_slot_info *slot)
326 {
327 if (slot->target_device == SND_SST_TARGET_PMIC &&
328 slot->device_instance == 1) {
329 /*music mode*/
330 sst_drv_ctx->pmic_port_instance = 1;
331 sst_drv_ctx->scard_ops->set_audio_port(ACTIVATE);
332 sst_drv_ctx->scard_ops->set_pcm_audio_params(
333 slot->pcm_params.sfreq,
334 slot->pcm_params.pcm_wd_sz,
335 slot->pcm_params.num_chan);
336 if (sst_drv_ctx->pb_streams)
337 sst_drv_ctx->scard_ops->power_up_pmic_pb(1);
338 if (sst_drv_ctx->cp_streams)
339 sst_drv_ctx->scard_ops->power_up_pmic_cp(1);
340 } else if ((slot->target_device == SND_SST_TARGET_PMIC ||
341 slot->target_device == SND_SST_TARGET_MODEM) &&
342 slot->device_instance == 0) {
343 /*voip mode where pcm0 is active*/
344 sst_drv_ctx->pmic_port_instance = 0;
345 sst_drv_ctx->scard_ops->set_voice_port(
346 ACTIVATE);
347 sst_drv_ctx->scard_ops->power_up_pmic_pb(0);
348 /*sst_drv_ctx->scard_ops->power_up_pmic_cp(0);*/
349 }
350 return 0;
351 }
352
353 int sst_parse_target(struct snd_sst_slot_info *slot)
354 {
355 int retval = 0;
356
357 if (slot->action == SND_SST_PORT_ACTIVATE &&
358 slot->device_type == SND_SST_DEVICE_PCM) {
359 retval = sst_activate_target(slot);
360 if (retval)
361 pr_err("sst: SST_Activate_target_fail\n");
362 else
363 pr_err("sst: SST_Activate_target_pass\n");
364 return retval;
365 } else if (slot->action == SND_SST_PORT_PREPARE &&
366 slot->device_type == SND_SST_DEVICE_PCM) {
367 retval = sst_prepare_target(slot);
368 if (retval)
369 pr_err("sst: SST_prepare_target_fail\n");
370 else
371 pr_err("sst: SST_prepare_target_pass\n");
372 return retval;
373 } else {
374 pr_err("sst: slot_action : %d, device_type: %d\n",
375 slot->action, slot->device_type);
376 return retval;
377 }
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("sst: 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("sst: 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("sst: 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("sst: i/p params incorrect\n");
443 return -EINVAL;
444 }
445 }
446 }
447 return retval;
448 }
449
450 /**
451 * sst_target_device_select - This fuction 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("sst: Target Device Select\n");
464
465 if (target->device_route < 0 || target->device_route > 2) {
466 pr_err("sst: device route is invalid\n");
467 return -EINVAL;
468 }
469
470 if (target->device_route != 0) {
471 pr_err("sst: 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("sst: 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("sst: PREPARE in %d, Forwading\n", i);
489 retval = sst_parse_target(&target->devices[i]);
490 if (retval) {
491 pr_err("sst: Parse Target fail %d", retval);
492 return retval;
493 }
494 pr_debug("sst: Parse Target successful %d", 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("sst: The rar CALL Failed");
516 retval = -EIO;
517 }
518 if (buffers->info.type != RAR_TYPE_AUDIO) {
519 pr_err("sst: 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("sst: DRM playback handling\n");
543 rar_buffers.info.handle = (__u32)kbufs->addr;
544 rar_buffers.info.size = kbufs->size;
545 pr_debug("sst: rar handle 0x%x size=0x%x",
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("sst: 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("sst: 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("sst: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("sst: 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("sst: Null buffer stream status %d\n", stream->status);
619 stream->prev = stream->status;
620 stream->status = STREAM_INIT;
621 pr_debug("sst:new stream status = %d\n", stream->status);
622 if (stream->need_draining == true) {
623 pr_debug("sst:draining stream\n");
624 if (sst_create_short_msg(&msg)) {
625 pr_err("sst: mem alloc 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("sst: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("sst: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("sst:del node\n");
692 }
693 }
694 if (list_empty(&stream->bufs)) {
695 /* no user buffer available */
696 pr_debug("sst:Null buffer!!!!stream status %d\n",
697 stream->status);
698 stream->prev = stream->status;
699 stream->status = STREAM_INIT;
700 pr_debug("sst:new stream status = %d\n",
701 stream->status);
702 if (stream->data_blk.on == true) {
703 pr_debug("sst: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("sst: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("sst: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("sst: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("sst: 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("sst: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("sst: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("sst: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("sst: 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 DBGsst_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("sst: 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 static int sst_prepare_input_buffers_rar(struct stream_info *str_info,
882 struct snd_sst_dbufs *dbufs,
883 int *input_index, int *in_copied,
884 int *input_index_valid_size, int *new_entry_flag)
885 {
886 int retval = 0;
887 #ifdef CONFIG_MRST_RAR_HANDLER
888 int i;
889
890 if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
891 struct RAR_buffer rar_buffers;
892 __u32 info;
893 retval = copy_from_user((void *) &info,
894 dbufs->ibufs->buff_entry[i].buffer,
895 sizeof(__u32));
896 if (retval) {
897 pr_err("sst:cpy from user fail\n");
898 return -EAGAIN;
899 }
900 rar_buffers.info.type = dbufs->ibufs->type;
901 rar_buffers.info.size = dbufs->ibufs->buff_entry[i].size;
902 rar_buffers.info.handle = info;
903 pr_debug("rar in DnR(input buffer function)=0x%x size=0x%x",
904 rar_buffers.info.handle,
905 rar_buffers.info.size);
906 retval = sst_get_RAR(&rar_buffers, 1);
907 if (retval) {
908 pr_debug("SST ERR: RAR API failed\n");
909 return retval;
910 }
911 str_info->decode_ibuf =
912 (void *) ((unsigned long) rar_buffers.bus_address);
913 pr_debug("RAR buf addr in DnR (input buffer function)0x%lu",
914 (unsigned long) str_info->decode_ibuf);
915 pr_debug("rar in DnR decode funtion/output b_add rar =0x%lu",
916 (unsigned long) rar_buffers.bus_address);
917 *input_index = i + 1;
918 str_info->decode_isize = dbufs->ibufs->buff_entry[i].size;
919 str_info->decode_ibuf_type = dbufs->ibufs->type;
920 *in_copied = str_info->decode_isize;
921 }
922 #endif
923 return retval;
924 }
925 /*This function is used to prepare the kernel input buffers with contents
926 before sending for decode*/
927 static int sst_prepare_input_buffers(struct stream_info *str_info,
928 struct snd_sst_dbufs *dbufs,
929 int *input_index, int *in_copied,
930 int *input_index_valid_size, int *new_entry_flag)
931 {
932 int i, cpy_size, retval = 0;
933
934 pr_debug("sst:input_index = %d, input entries = %d\n",
935 *input_index, dbufs->ibufs->entries);
936 for (i = *input_index; i < dbufs->ibufs->entries; i++) {
937 #ifdef CONFIG_MRST_RAR_HANDLER
938 retval = sst_prepare_input_buffers_rar(str_info,
939 dbufs, input_index, in_copied,
940 input_index_valid_size, new_entry_flag);
941 if (retval) {
942 pr_err("sst: In prepare input buffers for RAR\n");
943 return -EIO;
944 }
945 #endif
946 *input_index = i;
947 if (*input_index_valid_size == 0)
948 *input_index_valid_size =
949 dbufs->ibufs->buff_entry[i].size;
950 pr_debug("sst:inout addr = %p, size = %d\n",
951 dbufs->ibufs->buff_entry[i].buffer,
952 *input_index_valid_size);
953 pr_debug("sst:decode_isize = %d, in_copied %d\n",
954 str_info->decode_isize, *in_copied);
955 if (*input_index_valid_size <=
956 (str_info->decode_isize - *in_copied))
957 cpy_size = *input_index_valid_size;
958 else
959 cpy_size = str_info->decode_isize - *in_copied;
960
961 pr_debug("sst:cpy size = %d\n", cpy_size);
962 if (!dbufs->ibufs->buff_entry[i].buffer) {
963 pr_err("sst: i/p buffer is null\n");
964 return -EINVAL;
965 }
966 pr_debug("sst:Try copy To %p, From %p, size %d\n",
967 str_info->decode_ibuf + *in_copied,
968 dbufs->ibufs->buff_entry[i].buffer, cpy_size);
969
970 retval =
971 copy_from_user((void *)(str_info->decode_ibuf + *in_copied),
972 (void *) dbufs->ibufs->buff_entry[i].buffer,
973 cpy_size);
974 if (retval) {
975 pr_err("sst: copy from user failed\n");
976 return -EIO;
977 }
978 *in_copied += cpy_size;
979 *input_index_valid_size -= cpy_size;
980 pr_debug("sst:in buff size = %d, in_copied = %d\n",
981 *input_index_valid_size, *in_copied);
982 if (*input_index_valid_size != 0) {
983 pr_debug("sst:more input buffers left\n");
984 dbufs->ibufs->buff_entry[i].buffer += cpy_size;
985 break;
986 }
987 if (*in_copied == str_info->decode_isize &&
988 *input_index_valid_size == 0 &&
989 (i+1) <= dbufs->ibufs->entries) {
990 pr_debug("sst:all input buffers copied\n");
991 *new_entry_flag = true;
992 *input_index = i + 1;
993 break;
994 }
995 }
996 return retval;
997 }
998
999 /* This function is used to copy the decoded data from kernel buffers to
1000 the user output buffers with contents after decode*/
1001 static int sst_prepare_output_buffers(struct stream_info *str_info,
1002 struct snd_sst_dbufs *dbufs,
1003 int *output_index, int output_size,
1004 int *out_copied)
1005
1006 {
1007 int i, cpy_size, retval = 0;
1008 pr_debug("sst:output_index = %d, output entries = %d\n",
1009 *output_index,
1010 dbufs->obufs->entries);
1011 for (i = *output_index; i < dbufs->obufs->entries; i++) {
1012 *output_index = i;
1013 pr_debug("sst:output addr = %p, size = %d\n",
1014 dbufs->obufs->buff_entry[i].buffer,
1015 dbufs->obufs->buff_entry[i].size);
1016 pr_debug("sst:output_size = %d, out_copied = %d\n",
1017 output_size, *out_copied);
1018 if (dbufs->obufs->buff_entry[i].size <
1019 (output_size - *out_copied))
1020 cpy_size = dbufs->obufs->buff_entry[i].size;
1021 else
1022 cpy_size = output_size - *out_copied;
1023 pr_debug("sst:cpy size = %d\n", cpy_size);
1024 pr_debug("sst:Try copy To: %p, From %p, size %d\n",
1025 dbufs->obufs->buff_entry[i].buffer,
1026 sst_drv_ctx->mmap_mem + *out_copied,
1027 cpy_size);
1028 retval = copy_to_user(dbufs->obufs->buff_entry[i].buffer,
1029 sst_drv_ctx->mmap_mem + *out_copied,
1030 cpy_size);
1031 if (retval) {
1032 pr_err("sst: copy to user failed\n");
1033 return -EIO;
1034 } else
1035 pr_debug("sst:copy to user passed\n");
1036 *out_copied += cpy_size;
1037 dbufs->obufs->buff_entry[i].size -= cpy_size;
1038 pr_debug("sst:o/p buff size %d, out_copied %d\n",
1039 dbufs->obufs->buff_entry[i].size, *out_copied);
1040 if (dbufs->obufs->buff_entry[i].size != 0) {
1041 *output_index = i;
1042 dbufs->obufs->buff_entry[i].buffer += cpy_size;
1043 break;
1044 } else if (*out_copied == output_size) {
1045 *output_index = i + 1;
1046 break;
1047 }
1048 }
1049 return retval;
1050 }
1051
1052 /**
1053 * sst_decode - Send msg for decoding frames
1054 *
1055 * @str_id: ID of stream
1056 * @dbufs: param that holds the user input and output buffers and size
1057 *
1058 * This function is called to decode data from the firmware
1059 */
1060 int sst_decode(int str_id, struct snd_sst_dbufs *dbufs)
1061 {
1062 int retval = 0, i;
1063 unsigned long long total_input = 0 , total_output = 0;
1064 unsigned int cum_input_given = 0 , cum_output_given = 0;
1065 int copy_in_done = false, copy_out_done = false;
1066 int input_index = 0, output_index = 0;
1067 int input_index_valid_size = 0;
1068 int in_copied, out_copied;
1069 int new_entry_flag;
1070 u64 output_size;
1071 struct stream_info *str_info;
1072 struct snd_sst_decode_info dec_info;
1073 unsigned long long input_bytes, output_bytes;
1074
1075 sst_drv_ctx->scard_ops->power_down_pmic();
1076 pr_debug("sst: Powering_down_PMIC...\n");
1077
1078 retval = sst_validate_strid(str_id);
1079 if (retval)
1080 return retval;
1081
1082 str_info = &sst_drv_ctx->streams[str_id];
1083 if (str_info->status != STREAM_INIT) {
1084 pr_err("sst: invalid stream state = %d\n",
1085 str_info->status);
1086 return -EINVAL;
1087 }
1088
1089 str_info->prev = str_info->status;
1090 str_info->status = STREAM_DECODE;
1091
1092 for (i = 0; i < dbufs->ibufs->entries; i++)
1093 cum_input_given += dbufs->ibufs->buff_entry[i].size;
1094 for (i = 0; i < dbufs->obufs->entries; i++)
1095 cum_output_given += dbufs->obufs->buff_entry[i].size;
1096
1097 /* input and output buffer allocation */
1098 retval = sst_allocate_decode_buf(str_info, dbufs,
1099 cum_input_given, cum_output_given);
1100 if (retval) {
1101 pr_err("sst: mem allocation failed, abort!!!\n");
1102 retval = -ENOMEM;
1103 goto finish;
1104 }
1105
1106 str_info->decode_isize = str_info->idecode_alloc;
1107 str_info->decode_ibuf_type = dbufs->ibufs->type;
1108 str_info->decode_obuf_type = dbufs->obufs->type;
1109
1110 while ((copy_out_done == false) && (copy_in_done == false)) {
1111 in_copied = 0;
1112 new_entry_flag = false;
1113 retval = sst_prepare_input_buffers(str_info,\
1114 dbufs, &input_index, &in_copied,
1115 &input_index_valid_size, &new_entry_flag);
1116 if (retval) {
1117 pr_err("sst: prepare in buffers failed\n");
1118 goto finish;
1119 }
1120
1121 if (str_info->ops != STREAM_OPS_PLAYBACK_DRM)
1122 str_info->decode_obuf = sst_drv_ctx->mmap_mem;
1123
1124 #ifdef CONFIG_MRST_RAR_HANDLER
1125 else {
1126 if (dbufs->obufs->type == SST_BUF_RAR) {
1127 struct RAR_buffer rar_buffers;
1128 __u32 info;
1129
1130 pr_debug("DRM");
1131 retval = copy_from_user((void *) &info,
1132 dbufs->obufs->
1133 buff_entry[output_index].buffer,
1134 sizeof(__u32));
1135
1136 rar_buffers.info.size = dbufs->obufs->
1137 buff_entry[output_index].size;
1138 rar_buffers.info.handle = info;
1139 retval = sst_get_RAR(&rar_buffers, 1);
1140 if (retval)
1141 return retval;
1142
1143 str_info->decode_obuf = (void *)((unsigned long)
1144 rar_buffers.bus_address);
1145 str_info->decode_osize = dbufs->obufs->
1146 buff_entry[output_index].size;
1147 str_info->decode_obuf_type = dbufs->obufs->type;
1148 pr_debug("sst:DRM handling\n");
1149 pr_debug("o/p_add=0x%lu Size=0x%x",
1150 (unsigned long) str_info->decode_obuf,
1151 str_info->decode_osize);
1152 } else {
1153 str_info->decode_obuf = sst_drv_ctx->mmap_mem;
1154 str_info->decode_osize = dbufs->obufs->
1155 buff_entry[output_index].size;
1156
1157 }
1158 }
1159 #endif
1160 if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
1161 if (str_info->decode_isize > in_copied) {
1162 str_info->decode_isize = in_copied;
1163 pr_debug("sst:i/p size = %d\n",
1164 str_info->decode_isize);
1165 }
1166 }
1167
1168
1169 retval = sst_send_decode_mess(str_id, str_info, &dec_info);
1170 if (retval || dec_info.input_bytes_consumed == 0) {
1171 pr_err(
1172 "SST ERR: mess failed or no input consumed\n");
1173 goto finish;
1174 }
1175 input_bytes = dec_info.input_bytes_consumed;
1176 output_bytes = dec_info.output_bytes_produced;
1177
1178 pr_debug("sst:in_copied=%d, con=%lld, prod=%lld\n",
1179 in_copied, input_bytes, output_bytes);
1180 if (dbufs->obufs->type == SST_BUF_RAR) {
1181 output_index += 1;
1182 if (output_index == dbufs->obufs->entries) {
1183 copy_in_done = true;
1184 pr_debug("sst:all i/p cpy done\n");
1185 }
1186 total_output += output_bytes;
1187 } else {
1188 out_copied = 0;
1189 output_size = output_bytes;
1190 retval = sst_prepare_output_buffers(str_info, dbufs,
1191 &output_index, output_size, &out_copied);
1192 if (retval) {
1193 pr_err("sst:prep out buff fail\n");
1194 goto finish;
1195 }
1196 if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
1197 if (in_copied != input_bytes) {
1198 int bytes_left = in_copied -
1199 input_bytes;
1200 pr_debug("sst:bytes %d\n",
1201 bytes_left);
1202 if (new_entry_flag == true)
1203 input_index--;
1204 while (bytes_left) {
1205 struct snd_sst_buffs *ibufs;
1206 struct snd_sst_buff_entry
1207 *buff_entry;
1208 unsigned int size_sent;
1209
1210 ibufs = dbufs->ibufs;
1211 buff_entry =
1212 &ibufs->buff_entry[input_index];
1213 size_sent = buff_entry->size -\
1214 input_index_valid_size;
1215 if (bytes_left == size_sent) {
1216 bytes_left = 0;
1217 } else if (bytes_left <
1218 size_sent) {
1219 buff_entry->buffer +=
1220 (size_sent -
1221 bytes_left);
1222 buff_entry->size -=
1223 (size_sent -
1224 bytes_left);
1225 bytes_left = 0;
1226 } else {
1227 bytes_left -= size_sent;
1228 input_index--;
1229 input_index_valid_size =
1230 0;
1231 }
1232 }
1233
1234 }
1235 }
1236
1237 total_output += out_copied;
1238 if (str_info->decode_osize != out_copied) {
1239 str_info->decode_osize -= out_copied;
1240 pr_debug("sst:output size modified = %d\n",
1241 str_info->decode_osize);
1242 }
1243 }
1244 total_input += input_bytes;
1245
1246 if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
1247 if (total_input == cum_input_given)
1248 copy_in_done = true;
1249 copy_out_done = true;
1250
1251 } else {
1252 if (total_output == cum_output_given) {
1253 copy_out_done = true;
1254 pr_debug("sst:all o/p cpy done\n");
1255 }
1256
1257 if (total_input == cum_input_given) {
1258 copy_in_done = true;
1259 pr_debug("sst:all i/p cpy done\n");
1260 }
1261 }
1262
1263 pr_debug("sst:copy_out = %d, copy_in = %d\n",
1264 copy_out_done, copy_in_done);
1265 }
1266
1267 finish:
1268 dbufs->input_bytes_consumed = total_input;
1269 dbufs->output_bytes_produced = total_output;
1270 str_info->status = str_info->prev;
1271 str_info->prev = STREAM_DECODE;
1272 kfree(str_info->decode_ibuf);
1273 str_info->decode_ibuf = NULL;
1274 return retval;
1275 }