diff options
author | Vinod Koul <vinod.koul@intel.com> | 2014-05-05 04:57:50 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-08 13:25:05 -0400 |
commit | 4b68b4e1c564f32e4eb18186749b29c9a78772f4 (patch) | |
tree | 1697bb72f9339f6f20ab7c0c5ddb32bb57a0df74 | |
parent | 4496ffab7dade2206f3d5dea86b9928a5f173de2 (diff) |
ASoC: Intel: split the pcm and compress to different files
For manging them and adding support for more platforms
Code move only
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | sound/soc/intel/sst-mfld-platform-compress.c | 228 | ||||
-rw-r--r-- | sound/soc/intel/sst-mfld-platform-pcm.c | 202 | ||||
-rw-r--r-- | sound/soc/intel/sst-mfld-platform.h | 2 |
3 files changed, 232 insertions, 200 deletions
diff --git a/sound/soc/intel/sst-mfld-platform-compress.c b/sound/soc/intel/sst-mfld-platform-compress.c new file mode 100644 index 000000000000..16d79fb25e59 --- /dev/null +++ b/sound/soc/intel/sst-mfld-platform-compress.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * sst_mfld_platform.c - Intel MID Platform driver | ||
3 | * | ||
4 | * Copyright (C) 2010-2014 Intel Corp | ||
5 | * Author: Vinod Koul <vinod.koul@intel.com> | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
18 | */ | ||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
21 | #include <linux/slab.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/soc.h> | ||
28 | #include <sound/compress_driver.h> | ||
29 | #include "sst-mfld-platform.h" | ||
30 | |||
31 | /* compress stream operations */ | ||
32 | static void sst_compr_fragment_elapsed(void *arg) | ||
33 | { | ||
34 | struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg; | ||
35 | |||
36 | pr_debug("fragment elapsed by driver\n"); | ||
37 | if (cstream) | ||
38 | snd_compr_fragment_elapsed(cstream); | ||
39 | } | ||
40 | |||
41 | static int sst_platform_compr_open(struct snd_compr_stream *cstream) | ||
42 | { | ||
43 | |||
44 | int ret_val = 0; | ||
45 | struct snd_compr_runtime *runtime = cstream->runtime; | ||
46 | struct sst_runtime_stream *stream; | ||
47 | |||
48 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | ||
49 | if (!stream) | ||
50 | return -ENOMEM; | ||
51 | |||
52 | spin_lock_init(&stream->status_lock); | ||
53 | |||
54 | /* get the sst ops */ | ||
55 | if (!sst || !try_module_get(sst->dev->driver->owner)) { | ||
56 | pr_err("no device available to run\n"); | ||
57 | ret_val = -ENODEV; | ||
58 | goto out_ops; | ||
59 | } | ||
60 | stream->compr_ops = sst->compr_ops; | ||
61 | |||
62 | stream->id = 0; | ||
63 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | ||
64 | runtime->private_data = stream; | ||
65 | return 0; | ||
66 | out_ops: | ||
67 | kfree(stream); | ||
68 | return ret_val; | ||
69 | } | ||
70 | |||
71 | static int sst_platform_compr_free(struct snd_compr_stream *cstream) | ||
72 | { | ||
73 | struct sst_runtime_stream *stream; | ||
74 | int ret_val = 0, str_id; | ||
75 | |||
76 | stream = cstream->runtime->private_data; | ||
77 | /*need to check*/ | ||
78 | str_id = stream->id; | ||
79 | if (str_id) | ||
80 | ret_val = stream->compr_ops->close(str_id); | ||
81 | module_put(sst->dev->driver->owner); | ||
82 | kfree(stream); | ||
83 | pr_debug("%s: %d\n", __func__, ret_val); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int sst_platform_compr_set_params(struct snd_compr_stream *cstream, | ||
88 | struct snd_compr_params *params) | ||
89 | { | ||
90 | struct sst_runtime_stream *stream; | ||
91 | int retval; | ||
92 | struct snd_sst_params str_params; | ||
93 | struct sst_compress_cb cb; | ||
94 | |||
95 | stream = cstream->runtime->private_data; | ||
96 | /* construct fw structure for this*/ | ||
97 | memset(&str_params, 0, sizeof(str_params)); | ||
98 | |||
99 | str_params.ops = STREAM_OPS_PLAYBACK; | ||
100 | str_params.stream_type = SST_STREAM_TYPE_MUSIC; | ||
101 | str_params.device_type = SND_SST_DEVICE_COMPRESS; | ||
102 | |||
103 | switch (params->codec.id) { | ||
104 | case SND_AUDIOCODEC_MP3: { | ||
105 | str_params.codec = SST_CODEC_TYPE_MP3; | ||
106 | str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3; | ||
107 | str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in; | ||
108 | str_params.sparams.uc.mp3_params.pcm_wd_sz = 16; | ||
109 | break; | ||
110 | } | ||
111 | |||
112 | case SND_AUDIOCODEC_AAC: { | ||
113 | str_params.codec = SST_CODEC_TYPE_AAC; | ||
114 | str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC; | ||
115 | str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in; | ||
116 | str_params.sparams.uc.aac_params.pcm_wd_sz = 16; | ||
117 | if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS) | ||
118 | str_params.sparams.uc.aac_params.bs_format = | ||
119 | AAC_BIT_STREAM_ADTS; | ||
120 | else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW) | ||
121 | str_params.sparams.uc.aac_params.bs_format = | ||
122 | AAC_BIT_STREAM_RAW; | ||
123 | else { | ||
124 | pr_err("Undefined format%d\n", params->codec.format); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | str_params.sparams.uc.aac_params.externalsr = | ||
128 | params->codec.sample_rate; | ||
129 | break; | ||
130 | } | ||
131 | |||
132 | default: | ||
133 | pr_err("codec not supported, id =%d\n", params->codec.id); | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
137 | str_params.aparams.ring_buf_info[0].addr = | ||
138 | virt_to_phys(cstream->runtime->buffer); | ||
139 | str_params.aparams.ring_buf_info[0].size = | ||
140 | cstream->runtime->buffer_size; | ||
141 | str_params.aparams.sg_count = 1; | ||
142 | str_params.aparams.frag_size = cstream->runtime->fragment_size; | ||
143 | |||
144 | cb.param = cstream; | ||
145 | cb.compr_cb = sst_compr_fragment_elapsed; | ||
146 | |||
147 | retval = stream->compr_ops->open(&str_params, &cb); | ||
148 | if (retval < 0) { | ||
149 | pr_err("stream allocation failed %d\n", retval); | ||
150 | return retval; | ||
151 | } | ||
152 | |||
153 | stream->id = retval; | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
158 | { | ||
159 | struct sst_runtime_stream *stream = | ||
160 | cstream->runtime->private_data; | ||
161 | |||
162 | return stream->compr_ops->control(cmd, stream->id); | ||
163 | } | ||
164 | |||
165 | static int sst_platform_compr_pointer(struct snd_compr_stream *cstream, | ||
166 | struct snd_compr_tstamp *tstamp) | ||
167 | { | ||
168 | struct sst_runtime_stream *stream; | ||
169 | |||
170 | stream = cstream->runtime->private_data; | ||
171 | stream->compr_ops->tstamp(stream->id, tstamp); | ||
172 | tstamp->byte_offset = tstamp->copied_total % | ||
173 | (u32)cstream->runtime->buffer_size; | ||
174 | pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int sst_platform_compr_ack(struct snd_compr_stream *cstream, | ||
179 | size_t bytes) | ||
180 | { | ||
181 | struct sst_runtime_stream *stream; | ||
182 | |||
183 | stream = cstream->runtime->private_data; | ||
184 | stream->compr_ops->ack(stream->id, (unsigned long)bytes); | ||
185 | stream->bytes_written += bytes; | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream, | ||
191 | struct snd_compr_caps *caps) | ||
192 | { | ||
193 | struct sst_runtime_stream *stream = | ||
194 | cstream->runtime->private_data; | ||
195 | |||
196 | return stream->compr_ops->get_caps(caps); | ||
197 | } | ||
198 | |||
199 | static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
200 | struct snd_compr_codec_caps *codec) | ||
201 | { | ||
202 | struct sst_runtime_stream *stream = | ||
203 | cstream->runtime->private_data; | ||
204 | |||
205 | return stream->compr_ops->get_codec_caps(codec); | ||
206 | } | ||
207 | |||
208 | static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream, | ||
209 | struct snd_compr_metadata *metadata) | ||
210 | { | ||
211 | struct sst_runtime_stream *stream = | ||
212 | cstream->runtime->private_data; | ||
213 | |||
214 | return stream->compr_ops->set_metadata(stream->id, metadata); | ||
215 | } | ||
216 | |||
217 | struct snd_compr_ops sst_platform_compr_ops = { | ||
218 | |||
219 | .open = sst_platform_compr_open, | ||
220 | .free = sst_platform_compr_free, | ||
221 | .set_params = sst_platform_compr_set_params, | ||
222 | .set_metadata = sst_platform_compr_set_metadata, | ||
223 | .trigger = sst_platform_compr_trigger, | ||
224 | .pointer = sst_platform_compr_pointer, | ||
225 | .ack = sst_platform_compr_ack, | ||
226 | .get_caps = sst_platform_compr_get_caps, | ||
227 | .get_codec_caps = sst_platform_compr_get_codec_caps, | ||
228 | }; | ||
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index e84f32f0af61..ebadf61367e6 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c | |||
@@ -29,8 +29,9 @@ | |||
29 | #include <sound/compress_driver.h> | 29 | #include <sound/compress_driver.h> |
30 | #include "sst-mfld-platform.h" | 30 | #include "sst-mfld-platform.h" |
31 | 31 | ||
32 | static struct sst_device *sst; | 32 | struct sst_device *sst; |
33 | static DEFINE_MUTEX(sst_lock); | 33 | static DEFINE_MUTEX(sst_lock); |
34 | extern struct snd_compr_ops sst_platform_compr_ops; | ||
34 | 35 | ||
35 | int sst_register_dsp(struct sst_device *dev) | 36 | int sst_register_dsp(struct sst_device *dev) |
36 | { | 37 | { |
@@ -461,205 +462,6 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
461 | return retval; | 462 | return retval; |
462 | } | 463 | } |
463 | 464 | ||
464 | /* compress stream operations */ | ||
465 | static void sst_compr_fragment_elapsed(void *arg) | ||
466 | { | ||
467 | struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg; | ||
468 | |||
469 | pr_debug("fragment elapsed by driver\n"); | ||
470 | if (cstream) | ||
471 | snd_compr_fragment_elapsed(cstream); | ||
472 | } | ||
473 | |||
474 | static int sst_platform_compr_open(struct snd_compr_stream *cstream) | ||
475 | { | ||
476 | |||
477 | int ret_val = 0; | ||
478 | struct snd_compr_runtime *runtime = cstream->runtime; | ||
479 | struct sst_runtime_stream *stream; | ||
480 | |||
481 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | ||
482 | if (!stream) | ||
483 | return -ENOMEM; | ||
484 | |||
485 | spin_lock_init(&stream->status_lock); | ||
486 | |||
487 | /* get the sst ops */ | ||
488 | if (!sst || !try_module_get(sst->dev->driver->owner)) { | ||
489 | pr_err("no device available to run\n"); | ||
490 | ret_val = -ENODEV; | ||
491 | goto out_ops; | ||
492 | } | ||
493 | stream->compr_ops = sst->compr_ops; | ||
494 | |||
495 | stream->id = 0; | ||
496 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | ||
497 | runtime->private_data = stream; | ||
498 | return 0; | ||
499 | out_ops: | ||
500 | kfree(stream); | ||
501 | return ret_val; | ||
502 | } | ||
503 | |||
504 | static int sst_platform_compr_free(struct snd_compr_stream *cstream) | ||
505 | { | ||
506 | struct sst_runtime_stream *stream; | ||
507 | int ret_val = 0, str_id; | ||
508 | |||
509 | stream = cstream->runtime->private_data; | ||
510 | /*need to check*/ | ||
511 | str_id = stream->id; | ||
512 | if (str_id) | ||
513 | ret_val = stream->compr_ops->close(str_id); | ||
514 | module_put(sst->dev->driver->owner); | ||
515 | kfree(stream); | ||
516 | pr_debug("%s: %d\n", __func__, ret_val); | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static int sst_platform_compr_set_params(struct snd_compr_stream *cstream, | ||
521 | struct snd_compr_params *params) | ||
522 | { | ||
523 | struct sst_runtime_stream *stream; | ||
524 | int retval; | ||
525 | struct snd_sst_params str_params; | ||
526 | struct sst_compress_cb cb; | ||
527 | |||
528 | stream = cstream->runtime->private_data; | ||
529 | /* construct fw structure for this*/ | ||
530 | memset(&str_params, 0, sizeof(str_params)); | ||
531 | |||
532 | str_params.ops = STREAM_OPS_PLAYBACK; | ||
533 | str_params.stream_type = SST_STREAM_TYPE_MUSIC; | ||
534 | str_params.device_type = SND_SST_DEVICE_COMPRESS; | ||
535 | |||
536 | switch (params->codec.id) { | ||
537 | case SND_AUDIOCODEC_MP3: { | ||
538 | str_params.codec = SST_CODEC_TYPE_MP3; | ||
539 | str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3; | ||
540 | str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in; | ||
541 | str_params.sparams.uc.mp3_params.pcm_wd_sz = 16; | ||
542 | break; | ||
543 | } | ||
544 | |||
545 | case SND_AUDIOCODEC_AAC: { | ||
546 | str_params.codec = SST_CODEC_TYPE_AAC; | ||
547 | str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC; | ||
548 | str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in; | ||
549 | str_params.sparams.uc.aac_params.pcm_wd_sz = 16; | ||
550 | if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS) | ||
551 | str_params.sparams.uc.aac_params.bs_format = | ||
552 | AAC_BIT_STREAM_ADTS; | ||
553 | else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW) | ||
554 | str_params.sparams.uc.aac_params.bs_format = | ||
555 | AAC_BIT_STREAM_RAW; | ||
556 | else { | ||
557 | pr_err("Undefined format%d\n", params->codec.format); | ||
558 | return -EINVAL; | ||
559 | } | ||
560 | str_params.sparams.uc.aac_params.externalsr = | ||
561 | params->codec.sample_rate; | ||
562 | break; | ||
563 | } | ||
564 | |||
565 | default: | ||
566 | pr_err("codec not supported, id =%d\n", params->codec.id); | ||
567 | return -EINVAL; | ||
568 | } | ||
569 | |||
570 | str_params.aparams.ring_buf_info[0].addr = | ||
571 | virt_to_phys(cstream->runtime->buffer); | ||
572 | str_params.aparams.ring_buf_info[0].size = | ||
573 | cstream->runtime->buffer_size; | ||
574 | str_params.aparams.sg_count = 1; | ||
575 | str_params.aparams.frag_size = cstream->runtime->fragment_size; | ||
576 | |||
577 | cb.param = cstream; | ||
578 | cb.compr_cb = sst_compr_fragment_elapsed; | ||
579 | |||
580 | retval = stream->compr_ops->open(&str_params, &cb); | ||
581 | if (retval < 0) { | ||
582 | pr_err("stream allocation failed %d\n", retval); | ||
583 | return retval; | ||
584 | } | ||
585 | |||
586 | stream->id = retval; | ||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
591 | { | ||
592 | struct sst_runtime_stream *stream = | ||
593 | cstream->runtime->private_data; | ||
594 | |||
595 | return stream->compr_ops->control(cmd, stream->id); | ||
596 | } | ||
597 | |||
598 | static int sst_platform_compr_pointer(struct snd_compr_stream *cstream, | ||
599 | struct snd_compr_tstamp *tstamp) | ||
600 | { | ||
601 | struct sst_runtime_stream *stream; | ||
602 | |||
603 | stream = cstream->runtime->private_data; | ||
604 | stream->compr_ops->tstamp(stream->id, tstamp); | ||
605 | tstamp->byte_offset = tstamp->copied_total % | ||
606 | (u32)cstream->runtime->buffer_size; | ||
607 | pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static int sst_platform_compr_ack(struct snd_compr_stream *cstream, | ||
612 | size_t bytes) | ||
613 | { | ||
614 | struct sst_runtime_stream *stream; | ||
615 | |||
616 | stream = cstream->runtime->private_data; | ||
617 | stream->compr_ops->ack(stream->id, (unsigned long)bytes); | ||
618 | stream->bytes_written += bytes; | ||
619 | |||
620 | return 0; | ||
621 | } | ||
622 | |||
623 | static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream, | ||
624 | struct snd_compr_caps *caps) | ||
625 | { | ||
626 | struct sst_runtime_stream *stream = | ||
627 | cstream->runtime->private_data; | ||
628 | |||
629 | return stream->compr_ops->get_caps(caps); | ||
630 | } | ||
631 | |||
632 | static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
633 | struct snd_compr_codec_caps *codec) | ||
634 | { | ||
635 | struct sst_runtime_stream *stream = | ||
636 | cstream->runtime->private_data; | ||
637 | |||
638 | return stream->compr_ops->get_codec_caps(codec); | ||
639 | } | ||
640 | |||
641 | static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream, | ||
642 | struct snd_compr_metadata *metadata) | ||
643 | { | ||
644 | struct sst_runtime_stream *stream = | ||
645 | cstream->runtime->private_data; | ||
646 | |||
647 | return stream->compr_ops->set_metadata(stream->id, metadata); | ||
648 | } | ||
649 | |||
650 | static struct snd_compr_ops sst_platform_compr_ops = { | ||
651 | |||
652 | .open = sst_platform_compr_open, | ||
653 | .free = sst_platform_compr_free, | ||
654 | .set_params = sst_platform_compr_set_params, | ||
655 | .set_metadata = sst_platform_compr_set_metadata, | ||
656 | .trigger = sst_platform_compr_trigger, | ||
657 | .pointer = sst_platform_compr_pointer, | ||
658 | .ack = sst_platform_compr_ack, | ||
659 | .get_caps = sst_platform_compr_get_caps, | ||
660 | .get_codec_caps = sst_platform_compr_get_codec_caps, | ||
661 | }; | ||
662 | |||
663 | static struct snd_soc_platform_driver sst_soc_platform_drv = { | 465 | static struct snd_soc_platform_driver sst_soc_platform_drv = { |
664 | .ops = &sst_platform_ops, | 466 | .ops = &sst_platform_ops, |
665 | .compr_ops = &sst_platform_compr_ops, | 467 | .compr_ops = &sst_platform_compr_ops, |
diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index 1005f552907f..3ea4fee0ba0d 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #include "sst-mfld-dsp.h" | 24 | #include "sst-mfld-dsp.h" |
25 | 25 | ||
26 | extern struct sst_device *sst; | ||
27 | |||
26 | #define SST_MONO 1 | 28 | #define SST_MONO 1 |
27 | #define SST_STEREO 2 | 29 | #define SST_STEREO 2 |
28 | #define SST_MAX_CAP 5 | 30 | #define SST_MAX_CAP 5 |