diff options
Diffstat (limited to 'sound/soc/intel/sst/sst_drv_interface.c')
-rw-r--r-- | sound/soc/intel/sst/sst_drv_interface.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/sst/sst_drv_interface.c index 5f75ef3cdd22..f0e4b99b3aeb 100644 --- a/sound/soc/intel/sst/sst_drv_interface.c +++ b/sound/soc/intel/sst/sst_drv_interface.c | |||
@@ -138,12 +138,36 @@ int sst_get_stream(struct intel_sst_drv *ctx, | |||
138 | static int sst_power_control(struct device *dev, bool state) | 138 | static int sst_power_control(struct device *dev, bool state) |
139 | { | 139 | { |
140 | struct intel_sst_drv *ctx = dev_get_drvdata(dev); | 140 | struct intel_sst_drv *ctx = dev_get_drvdata(dev); |
141 | 141 | int ret = 0; | |
142 | dev_dbg(ctx->dev, "state:%d", state); | 142 | int usage_count = 0; |
143 | if (state == true) | 143 | |
144 | return pm_runtime_get_sync(dev); | 144 | #ifdef CONFIG_PM |
145 | else | 145 | usage_count = atomic_read(&dev->power.usage_count); |
146 | #else | ||
147 | usage_count = 1; | ||
148 | #endif | ||
149 | |||
150 | if (state == true) { | ||
151 | ret = pm_runtime_get_sync(dev); | ||
152 | |||
153 | dev_dbg(ctx->dev, "Enable: pm usage count: %d\n", usage_count); | ||
154 | if (ret < 0) { | ||
155 | dev_err(ctx->dev, "Runtime get failed with err: %d\n", ret); | ||
156 | return ret; | ||
157 | } | ||
158 | if ((ctx->sst_state == SST_RESET) && (usage_count == 1)) { | ||
159 | ret = sst_load_fw(ctx); | ||
160 | if (ret) { | ||
161 | dev_err(dev, "FW download fail %d\n", ret); | ||
162 | sst_set_fw_state_locked(ctx, SST_RESET); | ||
163 | ret = sst_pm_runtime_put(ctx); | ||
164 | } | ||
165 | } | ||
166 | } else { | ||
167 | dev_dbg(ctx->dev, "Disable: pm usage count: %d\n", usage_count); | ||
146 | return sst_pm_runtime_put(ctx); | 168 | return sst_pm_runtime_put(ctx); |
169 | } | ||
170 | return ret; | ||
147 | } | 171 | } |
148 | 172 | ||
149 | /* | 173 | /* |
@@ -572,6 +596,35 @@ static int sst_stream_drop(struct device *dev, int str_id) | |||
572 | return sst_drop_stream(ctx, str_id); | 596 | return sst_drop_stream(ctx, str_id); |
573 | } | 597 | } |
574 | 598 | ||
599 | static int sst_stream_pause(struct device *dev, int str_id) | ||
600 | { | ||
601 | struct stream_info *str_info; | ||
602 | struct intel_sst_drv *ctx = dev_get_drvdata(dev); | ||
603 | |||
604 | if (ctx->sst_state != SST_FW_RUNNING) | ||
605 | return 0; | ||
606 | |||
607 | str_info = get_stream_info(ctx, str_id); | ||
608 | if (!str_info) | ||
609 | return -EINVAL; | ||
610 | |||
611 | return sst_pause_stream(ctx, str_id); | ||
612 | } | ||
613 | |||
614 | static int sst_stream_resume(struct device *dev, int str_id) | ||
615 | { | ||
616 | struct stream_info *str_info; | ||
617 | struct intel_sst_drv *ctx = dev_get_drvdata(dev); | ||
618 | |||
619 | if (ctx->sst_state != SST_FW_RUNNING) | ||
620 | return 0; | ||
621 | |||
622 | str_info = get_stream_info(ctx, str_id); | ||
623 | if (!str_info) | ||
624 | return -EINVAL; | ||
625 | return sst_resume_stream(ctx, str_id); | ||
626 | } | ||
627 | |||
575 | static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info) | 628 | static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info) |
576 | { | 629 | { |
577 | int str_id = 0; | 630 | int str_id = 0; |
@@ -633,6 +686,8 @@ static struct sst_ops pcm_ops = { | |||
633 | .stream_init = sst_stream_init, | 686 | .stream_init = sst_stream_init, |
634 | .stream_start = sst_stream_start, | 687 | .stream_start = sst_stream_start, |
635 | .stream_drop = sst_stream_drop, | 688 | .stream_drop = sst_stream_drop, |
689 | .stream_pause = sst_stream_pause, | ||
690 | .stream_pause_release = sst_stream_resume, | ||
636 | .stream_read_tstamp = sst_read_timestamp, | 691 | .stream_read_tstamp = sst_read_timestamp, |
637 | .send_byte_stream = sst_send_byte_stream, | 692 | .send_byte_stream = sst_send_byte_stream, |
638 | .close = sst_close_pcm_stream, | 693 | .close = sst_close_pcm_stream, |