topology.c (78fd4ffd75eed354c1c8b567dd0b384053c933da) | topology.c (ee1e79b72e3cf5eac42ba9de827536f91d4c04e2) |
---|---|
1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9// 10 11#include <linux/firmware.h> 12#include <sound/tlv.h> 13#include <sound/pcm_params.h> 14#include <uapi/sound/sof/tokens.h> 15#include "sof-priv.h" | 1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9// 10 11#include <linux/firmware.h> 12#include <sound/tlv.h> 13#include <sound/pcm_params.h> 14#include <uapi/sound/sof/tokens.h> 15#include "sof-priv.h" |
16#include "sof-audio.h" |
|
16#include "ops.h" 17 18#define COMP_ID_UNASSIGNED 0xffffffff 19/* 20 * Constants used in the computation of linear volume gain 21 * from dB gain 20th root of 10 in Q1.16 fixed-point notation 22 */ 23#define VOL_TWENTIETH_ROOT_OF_TEN 73533 --- 24 unchanged lines hidden (view full) --- 48 struct sof_abi_hdr *pdata; 49 struct snd_sof_control *control; 50}; 51 52/* send pcm params ipc */ 53static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir) 54{ 55 struct sof_ipc_pcm_params_reply ipc_params_reply; | 17#include "ops.h" 18 19#define COMP_ID_UNASSIGNED 0xffffffff 20/* 21 * Constants used in the computation of linear volume gain 22 * from dB gain 20th root of 10 in Q1.16 fixed-point notation 23 */ 24#define VOL_TWENTIETH_ROOT_OF_TEN 73533 --- 24 unchanged lines hidden (view full) --- 49 struct sof_abi_hdr *pdata; 50 struct snd_sof_control *control; 51}; 52 53/* send pcm params ipc */ 54static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir) 55{ 56 struct sof_ipc_pcm_params_reply ipc_params_reply; |
56 struct snd_sof_dev *sdev = swidget->sdev; | 57 struct snd_soc_component *scomp = swidget->scomp; 58 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); |
57 struct sof_ipc_pcm_params pcm; 58 struct snd_pcm_hw_params *params; 59 struct snd_sof_pcm *spcm; 60 int ret = 0; 61 62 memset(&pcm, 0, sizeof(pcm)); 63 64 /* get runtime PCM params using widget's stream name */ | 59 struct sof_ipc_pcm_params pcm; 60 struct snd_pcm_hw_params *params; 61 struct snd_sof_pcm *spcm; 62 int ret = 0; 63 64 memset(&pcm, 0, sizeof(pcm)); 65 66 /* get runtime PCM params using widget's stream name */ |
65 spcm = snd_sof_find_spcm_name(sdev, swidget->widget->sname); | 67 spcm = snd_sof_find_spcm_name(scomp, swidget->widget->sname); |
66 if (!spcm) { | 68 if (!spcm) { |
67 dev_err(sdev->dev, "error: cannot find PCM for %s\n", | 69 dev_err(scomp->dev, "error: cannot find PCM for %s\n", |
68 swidget->widget->name); 69 return -EINVAL; 70 } 71 72 params = &spcm->params[dir]; 73 74 /* set IPC PCM params */ 75 pcm.hdr.size = sizeof(pcm); --- 21 unchanged lines hidden (view full) --- 97 default: 98 return -EINVAL; 99 } 100 101 /* send IPC to the DSP */ 102 ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm), 103 &ipc_params_reply, sizeof(ipc_params_reply)); 104 if (ret < 0) | 70 swidget->widget->name); 71 return -EINVAL; 72 } 73 74 params = &spcm->params[dir]; 75 76 /* set IPC PCM params */ 77 pcm.hdr.size = sizeof(pcm); --- 21 unchanged lines hidden (view full) --- 99 default: 100 return -EINVAL; 101 } 102 103 /* send IPC to the DSP */ 104 ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm), 105 &ipc_params_reply, sizeof(ipc_params_reply)); 106 if (ret < 0) |
105 dev_err(sdev->dev, "error: pcm params failed for %s\n", | 107 dev_err(scomp->dev, "error: pcm params failed for %s\n", |
106 swidget->widget->name); 107 108 return ret; 109} 110 111 /* send stream trigger ipc */ 112static int ipc_trigger(struct snd_sof_widget *swidget, int cmd) 113{ | 108 swidget->widget->name); 109 110 return ret; 111} 112 113 /* send stream trigger ipc */ 114static int ipc_trigger(struct snd_sof_widget *swidget, int cmd) 115{ |
114 struct snd_sof_dev *sdev = swidget->sdev; | 116 struct snd_soc_component *scomp = swidget->scomp; 117 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); |
115 struct sof_ipc_stream stream; 116 struct sof_ipc_reply reply; 117 int ret = 0; 118 119 /* set IPC stream params */ 120 stream.hdr.size = sizeof(stream); 121 stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | cmd; 122 stream.comp_id = swidget->comp_id; 123 124 /* send IPC to the DSP */ 125 ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, 126 sizeof(stream), &reply, sizeof(reply)); 127 if (ret < 0) | 118 struct sof_ipc_stream stream; 119 struct sof_ipc_reply reply; 120 int ret = 0; 121 122 /* set IPC stream params */ 123 stream.hdr.size = sizeof(stream); 124 stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | cmd; 125 stream.comp_id = swidget->comp_id; 126 127 /* send IPC to the DSP */ 128 ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, 129 sizeof(stream), &reply, sizeof(reply)); 130 if (ret < 0) |
128 dev_err(sdev->dev, "error: failed to trigger %s\n", | 131 dev_err(scomp->dev, "error: failed to trigger %s\n", |
129 swidget->widget->name); 130 131 return ret; 132} 133 134static int sof_keyword_dapm_event(struct snd_soc_dapm_widget *w, 135 struct snd_kcontrol *k, int event) 136{ 137 struct snd_sof_widget *swidget = w->dobj.private; | 132 swidget->widget->name); 133 134 return ret; 135} 136 137static int sof_keyword_dapm_event(struct snd_soc_dapm_widget *w, 138 struct snd_kcontrol *k, int event) 139{ 140 struct snd_sof_widget *swidget = w->dobj.private; |
141 struct snd_soc_component *scomp; |
|
138 int stream = SNDRV_PCM_STREAM_CAPTURE; | 142 int stream = SNDRV_PCM_STREAM_CAPTURE; |
139 struct snd_sof_dev *sdev; | |
140 struct snd_sof_pcm *spcm; 141 int ret = 0; 142 143 if (!swidget) 144 return 0; 145 | 143 struct snd_sof_pcm *spcm; 144 int ret = 0; 145 146 if (!swidget) 147 return 0; 148 |
146 sdev = swidget->sdev; | 149 scomp = swidget->scomp; |
147 | 150 |
148 dev_dbg(sdev->dev, "received event %d for widget %s\n", | 151 dev_dbg(scomp->dev, "received event %d for widget %s\n", |
149 event, w->name); 150 151 /* get runtime PCM params using widget's stream name */ | 152 event, w->name); 153 154 /* get runtime PCM params using widget's stream name */ |
152 spcm = snd_sof_find_spcm_name(sdev, swidget->widget->sname); | 155 spcm = snd_sof_find_spcm_name(scomp, swidget->widget->sname); |
153 if (!spcm) { | 156 if (!spcm) { |
154 dev_err(sdev->dev, "error: cannot find PCM for %s\n", | 157 dev_err(scomp->dev, "error: cannot find PCM for %s\n", |
155 swidget->widget->name); 156 return -EINVAL; 157 } 158 159 /* process events */ 160 switch (event) { 161 case SND_SOC_DAPM_PRE_PMU: 162 if (spcm->stream[stream].suspend_ignored) { | 158 swidget->widget->name); 159 return -EINVAL; 160 } 161 162 /* process events */ 163 switch (event) { 164 case SND_SOC_DAPM_PRE_PMU: 165 if (spcm->stream[stream].suspend_ignored) { |
163 dev_dbg(sdev->dev, "PRE_PMU event ignored, KWD pipeline is already RUNNING\n"); | 166 dev_dbg(scomp->dev, "PRE_PMU event ignored, KWD pipeline is already RUNNING\n"); |
164 return 0; 165 } 166 167 /* set pcm params */ 168 ret = ipc_pcm_params(swidget, stream); 169 if (ret < 0) { | 167 return 0; 168 } 169 170 /* set pcm params */ 171 ret = ipc_pcm_params(swidget, stream); 172 if (ret < 0) { |
170 dev_err(sdev->dev, | 173 dev_err(scomp->dev, |
171 "error: failed to set pcm params for widget %s\n", 172 swidget->widget->name); 173 break; 174 } 175 176 /* start trigger */ 177 ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_START); 178 if (ret < 0) | 174 "error: failed to set pcm params for widget %s\n", 175 swidget->widget->name); 176 break; 177 } 178 179 /* start trigger */ 180 ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_START); 181 if (ret < 0) |
179 dev_err(sdev->dev, | 182 dev_err(scomp->dev, |
180 "error: failed to trigger widget %s\n", 181 swidget->widget->name); 182 break; 183 case SND_SOC_DAPM_POST_PMD: 184 if (spcm->stream[stream].suspend_ignored) { | 183 "error: failed to trigger widget %s\n", 184 swidget->widget->name); 185 break; 186 case SND_SOC_DAPM_POST_PMD: 187 if (spcm->stream[stream].suspend_ignored) { |
185 dev_dbg(sdev->dev, "POST_PMD even ignored, KWD pipeline will remain RUNNING\n"); | 188 dev_dbg(scomp->dev, "POST_PMD even ignored, KWD pipeline will remain RUNNING\n"); |
186 return 0; 187 } 188 189 /* stop trigger */ 190 ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_STOP); 191 if (ret < 0) | 189 return 0; 190 } 191 192 /* stop trigger */ 193 ret = ipc_trigger(swidget, SOF_IPC_STREAM_TRIG_STOP); 194 if (ret < 0) |
192 dev_err(sdev->dev, | 195 dev_err(scomp->dev, |
193 "error: failed to trigger widget %s\n", 194 swidget->widget->name); 195 196 /* pcm free */ 197 ret = ipc_trigger(swidget, SOF_IPC_STREAM_PCM_FREE); 198 if (ret < 0) | 196 "error: failed to trigger widget %s\n", 197 swidget->widget->name); 198 199 /* pcm free */ 200 ret = ipc_trigger(swidget, SOF_IPC_STREAM_PCM_FREE); 201 if (ret < 0) |
199 dev_err(sdev->dev, | 202 dev_err(scomp->dev, |
200 "error: failed to trigger widget %s\n", 201 swidget->widget->name); 202 break; 203 default: 204 break; 205 } 206 207 return ret; --- 625 unchanged lines hidden (view full) --- 833 case SOF_TKN_INTEL_DMIC_PDM_MIC_B_Enable: 834 case SOF_TKN_INTEL_DMIC_PDM_POLARITY_A: 835 case SOF_TKN_INTEL_DMIC_PDM_POLARITY_B: 836 case SOF_TKN_INTEL_DMIC_PDM_CLK_EDGE: 837 case SOF_TKN_INTEL_DMIC_PDM_SKEW: 838 839 /* check if array index is valid */ 840 if (!index || *index == 0) { | 203 "error: failed to trigger widget %s\n", 204 swidget->widget->name); 205 break; 206 default: 207 break; 208 } 209 210 return ret; --- 625 unchanged lines hidden (view full) --- 836 case SOF_TKN_INTEL_DMIC_PDM_MIC_B_Enable: 837 case SOF_TKN_INTEL_DMIC_PDM_POLARITY_A: 838 case SOF_TKN_INTEL_DMIC_PDM_POLARITY_B: 839 case SOF_TKN_INTEL_DMIC_PDM_CLK_EDGE: 840 case SOF_TKN_INTEL_DMIC_PDM_SKEW: 841 842 /* check if array index is valid */ 843 if (!index || *index == 0) { |
841 dev_err(sdev->dev, | 844 dev_err(scomp->dev, |
842 "error: invalid array offset\n"); 843 continue; 844 } else { 845 /* offset within the pdm config array */ 846 offset = size * (*index - 1); 847 } 848 break; 849 default: --- 11 unchanged lines hidden (view full) --- 861 862static int sof_parse_tokens(struct snd_soc_component *scomp, 863 void *object, 864 const struct sof_topology_token *tokens, 865 int count, 866 struct snd_soc_tplg_vendor_array *array, 867 int priv_size) 868{ | 845 "error: invalid array offset\n"); 846 continue; 847 } else { 848 /* offset within the pdm config array */ 849 offset = size * (*index - 1); 850 } 851 break; 852 default: --- 11 unchanged lines hidden (view full) --- 864 865static int sof_parse_tokens(struct snd_soc_component *scomp, 866 void *object, 867 const struct sof_topology_token *tokens, 868 int count, 869 struct snd_soc_tplg_vendor_array *array, 870 int priv_size) 871{ |
869 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); | |
870 int asize; 871 872 while (priv_size > 0) { 873 asize = le32_to_cpu(array->size); 874 875 /* validate asize */ 876 if (asize < 0) { /* FIXME: A zero-size array makes no sense */ | 872 int asize; 873 874 while (priv_size > 0) { 875 asize = le32_to_cpu(array->size); 876 877 /* validate asize */ 878 if (asize < 0) { /* FIXME: A zero-size array makes no sense */ |
877 dev_err(sdev->dev, "error: invalid array size 0x%x\n", | 879 dev_err(scomp->dev, "error: invalid array size 0x%x\n", |
878 asize); 879 return -EINVAL; 880 } 881 882 /* make sure there is enough data before parsing */ 883 priv_size -= asize; 884 if (priv_size < 0) { | 880 asize); 881 return -EINVAL; 882 } 883 884 /* make sure there is enough data before parsing */ 885 priv_size -= asize; 886 if (priv_size < 0) { |
885 dev_err(sdev->dev, "error: invalid array size 0x%x\n", | 887 dev_err(scomp->dev, "error: invalid array size 0x%x\n", |
886 asize); 887 return -EINVAL; 888 } 889 890 /* call correct parser depending on type */ 891 switch (le32_to_cpu(array->type)) { 892 case SND_SOC_TPLG_TUPLE_TYPE_UUID: 893 sof_parse_uuid_tokens(scomp, object, tokens, count, --- 6 unchanged lines hidden (view full) --- 900 case SND_SOC_TPLG_TUPLE_TYPE_BOOL: 901 case SND_SOC_TPLG_TUPLE_TYPE_BYTE: 902 case SND_SOC_TPLG_TUPLE_TYPE_WORD: 903 case SND_SOC_TPLG_TUPLE_TYPE_SHORT: 904 sof_parse_word_tokens(scomp, object, tokens, count, 905 array); 906 break; 907 default: | 888 asize); 889 return -EINVAL; 890 } 891 892 /* call correct parser depending on type */ 893 switch (le32_to_cpu(array->type)) { 894 case SND_SOC_TPLG_TUPLE_TYPE_UUID: 895 sof_parse_uuid_tokens(scomp, object, tokens, count, --- 6 unchanged lines hidden (view full) --- 902 case SND_SOC_TPLG_TUPLE_TYPE_BOOL: 903 case SND_SOC_TPLG_TUPLE_TYPE_BYTE: 904 case SND_SOC_TPLG_TUPLE_TYPE_WORD: 905 case SND_SOC_TPLG_TUPLE_TYPE_SHORT: 906 sof_parse_word_tokens(scomp, object, tokens, count, 907 array); 908 break; 909 default: |
908 dev_err(sdev->dev, "error: unknown token type %d\n", | 910 dev_err(scomp->dev, "error: unknown token type %d\n", |
909 array->type); 910 return -EINVAL; 911 } 912 913 /* next array */ 914 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array 915 + asize); 916 } 917 return 0; 918} 919 920static void sof_dbg_comp_config(struct snd_soc_component *scomp, 921 struct sof_ipc_comp_config *config) 922{ | 911 array->type); 912 return -EINVAL; 913 } 914 915 /* next array */ 916 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array 917 + asize); 918 } 919 return 0; 920} 921 922static void sof_dbg_comp_config(struct snd_soc_component *scomp, 923 struct sof_ipc_comp_config *config) 924{ |
923 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 924 925 dev_dbg(sdev->dev, " config: periods snk %d src %d fmt %d\n", | 925 dev_dbg(scomp->dev, " config: periods snk %d src %d fmt %d\n", |
926 config->periods_sink, config->periods_source, 927 config->frame_fmt); 928} 929 930/* 931 * Standard Kcontrols. 932 */ 933 --- 35 unchanged lines hidden (view full) --- 969 scontrol->cmd = SOF_CTRL_CMD_SWITCH; 970 goto skip; 971 } 972 973 scontrol->cmd = SOF_CTRL_CMD_VOLUME; 974 975 /* extract tlv data */ 976 if (get_tlv_data(kc->tlv.p, tlv) < 0) { | 926 config->periods_sink, config->periods_source, 927 config->frame_fmt); 928} 929 930/* 931 * Standard Kcontrols. 932 */ 933 --- 35 unchanged lines hidden (view full) --- 969 scontrol->cmd = SOF_CTRL_CMD_SWITCH; 970 goto skip; 971 } 972 973 scontrol->cmd = SOF_CTRL_CMD_VOLUME; 974 975 /* extract tlv data */ 976 if (get_tlv_data(kc->tlv.p, tlv) < 0) { |
977 dev_err(sdev->dev, "error: invalid TLV data\n"); | 977 dev_err(scomp->dev, "error: invalid TLV data\n"); |
978 ret = -EINVAL; 979 goto out_free; 980 } 981 982 /* set up volume table */ 983 ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1); 984 if (ret < 0) { | 978 ret = -EINVAL; 979 goto out_free; 980 } 981 982 /* set up volume table */ 983 ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1); 984 if (ret < 0) { |
985 dev_err(sdev->dev, "error: setting up volume table\n"); | 985 dev_err(scomp->dev, "error: setting up volume table\n"); |
986 goto out_free; 987 } 988 989 /* set default volume values to 0dB in control */ 990 cdata = scontrol->control_data; 991 for (i = 0; i < scontrol->num_channels; i++) { 992 cdata->chanv[i].channel = i; 993 cdata->chanv[i].value = VOL_ZERO_DB; 994 } 995 996skip: 997 /* set up possible led control from mixer private data */ 998 ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens, 999 ARRAY_SIZE(led_tokens), mc->priv.array, 1000 le32_to_cpu(mc->priv.size)); 1001 if (ret != 0) { | 986 goto out_free; 987 } 988 989 /* set default volume values to 0dB in control */ 990 cdata = scontrol->control_data; 991 for (i = 0; i < scontrol->num_channels; i++) { 992 cdata->chanv[i].channel = i; 993 cdata->chanv[i].value = VOL_ZERO_DB; 994 } 995 996skip: 997 /* set up possible led control from mixer private data */ 998 ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens, 999 ARRAY_SIZE(led_tokens), mc->priv.array, 1000 le32_to_cpu(mc->priv.size)); 1001 if (ret != 0) { |
1002 dev_err(sdev->dev, "error: parse led tokens failed %d\n", | 1002 dev_err(scomp->dev, "error: parse led tokens failed %d\n", |
1003 le32_to_cpu(mc->priv.size)); 1004 goto out_free_table; 1005 } 1006 | 1003 le32_to_cpu(mc->priv.size)); 1004 goto out_free_table; 1005 } 1006 |
1007 dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", | 1007 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n", |
1008 scontrol->comp_id, scontrol->num_channels); 1009 1010 return ret; 1011 1012out_free_table: 1013 if (le32_to_cpu(mc->max) > 1) 1014 kfree(scontrol->volume_table); 1015out_free: --- 22 unchanged lines hidden (view full) --- 1038 if (!scontrol->control_data) 1039 return -ENOMEM; 1040 1041 scontrol->comp_id = sdev->next_comp_id; 1042 scontrol->num_channels = le32_to_cpu(ec->num_channels); 1043 1044 scontrol->cmd = SOF_CTRL_CMD_ENUM; 1045 | 1008 scontrol->comp_id, scontrol->num_channels); 1009 1010 return ret; 1011 1012out_free_table: 1013 if (le32_to_cpu(mc->max) > 1) 1014 kfree(scontrol->volume_table); 1015out_free: --- 22 unchanged lines hidden (view full) --- 1038 if (!scontrol->control_data) 1039 return -ENOMEM; 1040 1041 scontrol->comp_id = sdev->next_comp_id; 1042 scontrol->num_channels = le32_to_cpu(ec->num_channels); 1043 1044 scontrol->cmd = SOF_CTRL_CMD_ENUM; 1045 |
1046 dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n", | 1046 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n", |
1047 scontrol->comp_id, scontrol->num_channels, scontrol->comp_id); 1048 1049 return 0; 1050} 1051 1052static int sof_control_load_bytes(struct snd_soc_component *scomp, 1053 struct snd_sof_control *scontrol, 1054 struct snd_kcontrol_new *kc, --- 7 unchanged lines hidden (view full) --- 1062 int max_size = sbe->max; 1063 int ret = 0; 1064 1065 /* init the get/put bytes data */ 1066 scontrol->size = sizeof(struct sof_ipc_ctrl_data) + 1067 le32_to_cpu(control->priv.size); 1068 1069 if (scontrol->size > max_size) { | 1047 scontrol->comp_id, scontrol->num_channels, scontrol->comp_id); 1048 1049 return 0; 1050} 1051 1052static int sof_control_load_bytes(struct snd_soc_component *scomp, 1053 struct snd_sof_control *scontrol, 1054 struct snd_kcontrol_new *kc, --- 7 unchanged lines hidden (view full) --- 1062 int max_size = sbe->max; 1063 int ret = 0; 1064 1065 /* init the get/put bytes data */ 1066 scontrol->size = sizeof(struct sof_ipc_ctrl_data) + 1067 le32_to_cpu(control->priv.size); 1068 1069 if (scontrol->size > max_size) { |
1070 dev_err(sdev->dev, "err: bytes data size %d exceeds max %d.\n", | 1070 dev_err(scomp->dev, "err: bytes data size %d exceeds max %d.\n", |
1071 scontrol->size, max_size); 1072 ret = -EINVAL; 1073 goto out; 1074 } 1075 1076 scontrol->control_data = kzalloc(max_size, GFP_KERNEL); 1077 cdata = scontrol->control_data; 1078 if (!scontrol->control_data) { 1079 ret = -ENOMEM; 1080 goto out; 1081 } 1082 1083 scontrol->comp_id = sdev->next_comp_id; 1084 scontrol->cmd = SOF_CTRL_CMD_BINARY; 1085 | 1071 scontrol->size, max_size); 1072 ret = -EINVAL; 1073 goto out; 1074 } 1075 1076 scontrol->control_data = kzalloc(max_size, GFP_KERNEL); 1077 cdata = scontrol->control_data; 1078 if (!scontrol->control_data) { 1079 ret = -ENOMEM; 1080 goto out; 1081 } 1082 1083 scontrol->comp_id = sdev->next_comp_id; 1084 scontrol->cmd = SOF_CTRL_CMD_BINARY; 1085 |
1086 dev_dbg(sdev->dev, "tplg: load kcontrol index %d chans %d\n", | 1086 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n", |
1087 scontrol->comp_id, scontrol->num_channels); 1088 1089 if (le32_to_cpu(control->priv.size) > 0) { 1090 memcpy(cdata->data, control->priv.data, 1091 le32_to_cpu(control->priv.size)); 1092 1093 if (cdata->data->magic != SOF_ABI_MAGIC) { | 1087 scontrol->comp_id, scontrol->num_channels); 1088 1089 if (le32_to_cpu(control->priv.size) > 0) { 1090 memcpy(cdata->data, control->priv.data, 1091 le32_to_cpu(control->priv.size)); 1092 1093 if (cdata->data->magic != SOF_ABI_MAGIC) { |
1094 dev_err(sdev->dev, "error: Wrong ABI magic 0x%08x.\n", | 1094 dev_err(scomp->dev, "error: Wrong ABI magic 0x%08x.\n", |
1095 cdata->data->magic); 1096 ret = -EINVAL; 1097 goto out_free; 1098 } 1099 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, 1100 cdata->data->abi)) { | 1095 cdata->data->magic); 1096 ret = -EINVAL; 1097 goto out_free; 1098 } 1099 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, 1100 cdata->data->abi)) { |
1101 dev_err(sdev->dev, | 1101 dev_err(scomp->dev, |
1102 "error: Incompatible ABI version 0x%08x.\n", 1103 cdata->data->abi); 1104 ret = -EINVAL; 1105 goto out_free; 1106 } 1107 if (cdata->data->size + sizeof(const struct sof_abi_hdr) != 1108 le32_to_cpu(control->priv.size)) { | 1102 "error: Incompatible ABI version 0x%08x.\n", 1103 cdata->data->abi); 1104 ret = -EINVAL; 1105 goto out_free; 1106 } 1107 if (cdata->data->size + sizeof(const struct sof_abi_hdr) != 1108 le32_to_cpu(control->priv.size)) { |
1109 dev_err(sdev->dev, | 1109 dev_err(scomp->dev, |
1110 "error: Conflict in bytes vs. priv size.\n"); 1111 ret = -EINVAL; 1112 goto out_free; 1113 } 1114 } 1115 1116 return ret; 1117 --- 11 unchanged lines hidden (view full) --- 1129 struct soc_mixer_control *sm; 1130 struct soc_bytes_ext *sbe; 1131 struct soc_enum *se; 1132 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1133 struct snd_soc_dobj *dobj; 1134 struct snd_sof_control *scontrol; 1135 int ret = -EINVAL; 1136 | 1110 "error: Conflict in bytes vs. priv size.\n"); 1111 ret = -EINVAL; 1112 goto out_free; 1113 } 1114 } 1115 1116 return ret; 1117 --- 11 unchanged lines hidden (view full) --- 1129 struct soc_mixer_control *sm; 1130 struct soc_bytes_ext *sbe; 1131 struct soc_enum *se; 1132 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1133 struct snd_soc_dobj *dobj; 1134 struct snd_sof_control *scontrol; 1135 int ret = -EINVAL; 1136 |
1137 dev_dbg(sdev->dev, "tplg: load control type %d name : %s\n", | 1137 dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n", |
1138 hdr->type, hdr->name); 1139 1140 scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL); 1141 if (!scontrol) 1142 return -ENOMEM; 1143 | 1138 hdr->type, hdr->name); 1139 1140 scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL); 1141 if (!scontrol) 1142 return -ENOMEM; 1143 |
1144 scontrol->sdev = sdev; | 1144 scontrol->scomp = scomp; |
1145 1146 switch (le32_to_cpu(hdr->ops.info)) { 1147 case SND_SOC_TPLG_CTL_VOLSW: 1148 case SND_SOC_TPLG_CTL_VOLSW_SX: 1149 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 1150 sm = (struct soc_mixer_control *)kc->private_value; 1151 dobj = &sm->dobj; 1152 ret = sof_control_load_volume(scomp, scontrol, kc, hdr); --- 12 unchanged lines hidden (view full) --- 1165 case SND_SOC_TPLG_CTL_RANGE: 1166 case SND_SOC_TPLG_CTL_STROBE: 1167 case SND_SOC_TPLG_DAPM_CTL_VOLSW: 1168 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 1169 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 1170 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 1171 case SND_SOC_TPLG_DAPM_CTL_PIN: 1172 default: | 1145 1146 switch (le32_to_cpu(hdr->ops.info)) { 1147 case SND_SOC_TPLG_CTL_VOLSW: 1148 case SND_SOC_TPLG_CTL_VOLSW_SX: 1149 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 1150 sm = (struct soc_mixer_control *)kc->private_value; 1151 dobj = &sm->dobj; 1152 ret = sof_control_load_volume(scomp, scontrol, kc, hdr); --- 12 unchanged lines hidden (view full) --- 1165 case SND_SOC_TPLG_CTL_RANGE: 1166 case SND_SOC_TPLG_CTL_STROBE: 1167 case SND_SOC_TPLG_DAPM_CTL_VOLSW: 1168 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 1169 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 1170 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 1171 case SND_SOC_TPLG_DAPM_CTL_PIN: 1172 default: |
1173 dev_warn(sdev->dev, "control type not supported %d:%d:%d\n", | 1173 dev_warn(scomp->dev, "control type not supported %d:%d:%d\n", |
1174 hdr->ops.get, hdr->ops.put, hdr->ops.info); 1175 kfree(scontrol); 1176 return 0; 1177 } 1178 1179 if (ret < 0) { 1180 kfree(scontrol); 1181 return ret; --- 6 unchanged lines hidden (view full) --- 1188 1189static int sof_control_unload(struct snd_soc_component *scomp, 1190 struct snd_soc_dobj *dobj) 1191{ 1192 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1193 struct sof_ipc_free fcomp; 1194 struct snd_sof_control *scontrol = dobj->private; 1195 | 1174 hdr->ops.get, hdr->ops.put, hdr->ops.info); 1175 kfree(scontrol); 1176 return 0; 1177 } 1178 1179 if (ret < 0) { 1180 kfree(scontrol); 1181 return ret; --- 6 unchanged lines hidden (view full) --- 1188 1189static int sof_control_unload(struct snd_soc_component *scomp, 1190 struct snd_soc_dobj *dobj) 1191{ 1192 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1193 struct sof_ipc_free fcomp; 1194 struct snd_sof_control *scontrol = dobj->private; 1195 |
1196 dev_dbg(sdev->dev, "tplg: unload control name : %s\n", scomp->name); | 1196 dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scomp->name); |
1197 1198 fcomp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_FREE; 1199 fcomp.hdr.size = sizeof(fcomp); 1200 fcomp.id = scontrol->comp_id; 1201 1202 kfree(scontrol->control_data); 1203 list_del(&scontrol->list); 1204 kfree(scontrol); --- 7 unchanged lines hidden (view full) --- 1212 * DAI Topology 1213 */ 1214 1215static int sof_connect_dai_widget(struct snd_soc_component *scomp, 1216 struct snd_soc_dapm_widget *w, 1217 struct snd_soc_tplg_dapm_widget *tw, 1218 struct snd_sof_dai *dai) 1219{ | 1197 1198 fcomp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_FREE; 1199 fcomp.hdr.size = sizeof(fcomp); 1200 fcomp.id = scontrol->comp_id; 1201 1202 kfree(scontrol->control_data); 1203 list_del(&scontrol->list); 1204 kfree(scontrol); --- 7 unchanged lines hidden (view full) --- 1212 * DAI Topology 1213 */ 1214 1215static int sof_connect_dai_widget(struct snd_soc_component *scomp, 1216 struct snd_soc_dapm_widget *w, 1217 struct snd_soc_tplg_dapm_widget *tw, 1218 struct snd_sof_dai *dai) 1219{ |
1220 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); | |
1221 struct snd_soc_card *card = scomp->card; 1222 struct snd_soc_pcm_runtime *rtd; 1223 1224 list_for_each_entry(rtd, &card->rtd_list, list) { | 1220 struct snd_soc_card *card = scomp->card; 1221 struct snd_soc_pcm_runtime *rtd; 1222 1223 list_for_each_entry(rtd, &card->rtd_list, list) { |
1225 dev_vdbg(sdev->dev, "tplg: check widget: %s stream: %s dai stream: %s\n", | 1224 dev_vdbg(scomp->dev, "tplg: check widget: %s stream: %s dai stream: %s\n", |
1226 w->name, w->sname, rtd->dai_link->stream_name); 1227 1228 if (!w->sname || !rtd->dai_link->stream_name) 1229 continue; 1230 1231 /* does stream match DAI link ? */ 1232 if (strcmp(w->sname, rtd->dai_link->stream_name)) 1233 continue; 1234 1235 switch (w->id) { 1236 case snd_soc_dapm_dai_out: 1237 rtd->cpu_dai->capture_widget = w; 1238 dai->name = rtd->dai_link->name; | 1225 w->name, w->sname, rtd->dai_link->stream_name); 1226 1227 if (!w->sname || !rtd->dai_link->stream_name) 1228 continue; 1229 1230 /* does stream match DAI link ? */ 1231 if (strcmp(w->sname, rtd->dai_link->stream_name)) 1232 continue; 1233 1234 switch (w->id) { 1235 case snd_soc_dapm_dai_out: 1236 rtd->cpu_dai->capture_widget = w; 1237 dai->name = rtd->dai_link->name; |
1239 dev_dbg(sdev->dev, "tplg: connected widget %s -> DAI link %s\n", | 1238 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n", |
1240 w->name, rtd->dai_link->name); 1241 break; 1242 case snd_soc_dapm_dai_in: 1243 rtd->cpu_dai->playback_widget = w; 1244 dai->name = rtd->dai_link->name; | 1239 w->name, rtd->dai_link->name); 1240 break; 1241 case snd_soc_dapm_dai_in: 1242 rtd->cpu_dai->playback_widget = w; 1243 dai->name = rtd->dai_link->name; |
1245 dev_dbg(sdev->dev, "tplg: connected widget %s -> DAI link %s\n", | 1244 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n", |
1246 w->name, rtd->dai_link->name); 1247 break; 1248 default: 1249 break; 1250 } 1251 } 1252 1253 /* check we have a connection */ 1254 if (!dai->name) { | 1245 w->name, rtd->dai_link->name); 1246 break; 1247 default: 1248 break; 1249 } 1250 } 1251 1252 /* check we have a connection */ 1253 if (!dai->name) { |
1255 dev_err(sdev->dev, "error: can't connect DAI %s stream %s\n", | 1254 dev_err(scomp->dev, "error: can't connect DAI %s stream %s\n", |
1256 w->name, w->sname); 1257 return -EINVAL; 1258 } 1259 1260 return 0; 1261} 1262 1263static int sof_widget_load_dai(struct snd_soc_component *scomp, int index, --- 15 unchanged lines hidden (view full) --- 1279 comp_dai.comp.type = SOF_COMP_DAI; 1280 comp_dai.comp.pipeline_id = index; 1281 comp_dai.config.hdr.size = sizeof(comp_dai.config); 1282 1283 ret = sof_parse_tokens(scomp, &comp_dai, dai_tokens, 1284 ARRAY_SIZE(dai_tokens), private->array, 1285 le32_to_cpu(private->size)); 1286 if (ret != 0) { | 1255 w->name, w->sname); 1256 return -EINVAL; 1257 } 1258 1259 return 0; 1260} 1261 1262static int sof_widget_load_dai(struct snd_soc_component *scomp, int index, --- 15 unchanged lines hidden (view full) --- 1278 comp_dai.comp.type = SOF_COMP_DAI; 1279 comp_dai.comp.pipeline_id = index; 1280 comp_dai.config.hdr.size = sizeof(comp_dai.config); 1281 1282 ret = sof_parse_tokens(scomp, &comp_dai, dai_tokens, 1283 ARRAY_SIZE(dai_tokens), private->array, 1284 le32_to_cpu(private->size)); 1285 if (ret != 0) { |
1287 dev_err(sdev->dev, "error: parse dai tokens failed %d\n", | 1286 dev_err(scomp->dev, "error: parse dai tokens failed %d\n", |
1288 le32_to_cpu(private->size)); 1289 return ret; 1290 } 1291 1292 ret = sof_parse_tokens(scomp, &comp_dai.config, comp_tokens, 1293 ARRAY_SIZE(comp_tokens), private->array, 1294 le32_to_cpu(private->size)); 1295 if (ret != 0) { | 1287 le32_to_cpu(private->size)); 1288 return ret; 1289 } 1290 1291 ret = sof_parse_tokens(scomp, &comp_dai.config, comp_tokens, 1292 ARRAY_SIZE(comp_tokens), private->array, 1293 le32_to_cpu(private->size)); 1294 if (ret != 0) { |
1296 dev_err(sdev->dev, "error: parse dai.cfg tokens failed %d\n", | 1295 dev_err(scomp->dev, "error: parse dai.cfg tokens failed %d\n", |
1297 private->size); 1298 return ret; 1299 } 1300 | 1296 private->size); 1297 return ret; 1298 } 1299 |
1301 dev_dbg(sdev->dev, "dai %s: type %d index %d\n", | 1300 dev_dbg(scomp->dev, "dai %s: type %d index %d\n", |
1302 swidget->widget->name, comp_dai.type, comp_dai.dai_index); 1303 sof_dbg_comp_config(scomp, &comp_dai.config); 1304 1305 ret = sof_ipc_tx_message(sdev->ipc, comp_dai.comp.hdr.cmd, 1306 &comp_dai, sizeof(comp_dai), r, sizeof(*r)); 1307 1308 if (ret == 0 && dai) { | 1301 swidget->widget->name, comp_dai.type, comp_dai.dai_index); 1302 sof_dbg_comp_config(scomp, &comp_dai.config); 1303 1304 ret = sof_ipc_tx_message(sdev->ipc, comp_dai.comp.hdr.cmd, 1305 &comp_dai, sizeof(comp_dai), r, sizeof(*r)); 1306 1307 if (ret == 0 && dai) { |
1309 dai->sdev = sdev; | 1308 dai->scomp = scomp; |
1310 memcpy(&dai->comp_dai, &comp_dai, sizeof(comp_dai)); 1311 } 1312 1313 return ret; 1314} 1315 1316/* 1317 * Buffer topology --- 19 unchanged lines hidden (view full) --- 1337 buffer->comp.id = swidget->comp_id; 1338 buffer->comp.type = SOF_COMP_BUFFER; 1339 buffer->comp.pipeline_id = index; 1340 1341 ret = sof_parse_tokens(scomp, buffer, buffer_tokens, 1342 ARRAY_SIZE(buffer_tokens), private->array, 1343 le32_to_cpu(private->size)); 1344 if (ret != 0) { | 1309 memcpy(&dai->comp_dai, &comp_dai, sizeof(comp_dai)); 1310 } 1311 1312 return ret; 1313} 1314 1315/* 1316 * Buffer topology --- 19 unchanged lines hidden (view full) --- 1336 buffer->comp.id = swidget->comp_id; 1337 buffer->comp.type = SOF_COMP_BUFFER; 1338 buffer->comp.pipeline_id = index; 1339 1340 ret = sof_parse_tokens(scomp, buffer, buffer_tokens, 1341 ARRAY_SIZE(buffer_tokens), private->array, 1342 le32_to_cpu(private->size)); 1343 if (ret != 0) { |
1345 dev_err(sdev->dev, "error: parse buffer tokens failed %d\n", | 1344 dev_err(scomp->dev, "error: parse buffer tokens failed %d\n", |
1346 private->size); 1347 kfree(buffer); 1348 return ret; 1349 } 1350 | 1345 private->size); 1346 kfree(buffer); 1347 return ret; 1348 } 1349 |
1351 dev_dbg(sdev->dev, "buffer %s: size %d caps 0x%x\n", | 1350 dev_dbg(scomp->dev, "buffer %s: size %d caps 0x%x\n", |
1352 swidget->widget->name, buffer->size, buffer->caps); 1353 1354 swidget->private = buffer; 1355 1356 ret = sof_ipc_tx_message(sdev->ipc, buffer->comp.hdr.cmd, buffer, 1357 sizeof(*buffer), r, sizeof(*r)); 1358 if (ret < 0) { | 1351 swidget->widget->name, buffer->size, buffer->caps); 1352 1353 swidget->private = buffer; 1354 1355 ret = sof_ipc_tx_message(sdev->ipc, buffer->comp.hdr.cmd, buffer, 1356 sizeof(*buffer), r, sizeof(*r)); 1357 if (ret < 0) { |
1359 dev_err(sdev->dev, "error: buffer %s load failed\n", | 1358 dev_err(scomp->dev, "error: buffer %s load failed\n", |
1360 swidget->widget->name); 1361 kfree(buffer); 1362 } 1363 1364 return ret; 1365} 1366 1367/* bind PCM ID to host component ID */ | 1359 swidget->widget->name); 1360 kfree(buffer); 1361 } 1362 1363 return ret; 1364} 1365 1366/* bind PCM ID to host component ID */ |
1368static int spcm_bind(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, | 1367static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm, |
1369 int dir) 1370{ 1371 struct snd_sof_widget *host_widget; 1372 | 1368 int dir) 1369{ 1370 struct snd_sof_widget *host_widget; 1371 |
1373 host_widget = snd_sof_find_swidget_sname(sdev, | 1372 host_widget = snd_sof_find_swidget_sname(scomp, |
1374 spcm->pcm.caps[dir].name, 1375 dir); 1376 if (!host_widget) { | 1373 spcm->pcm.caps[dir].name, 1374 dir); 1375 if (!host_widget) { |
1377 dev_err(sdev->dev, "can't find host comp to bind pcm\n"); | 1376 dev_err(scomp->dev, "can't find host comp to bind pcm\n"); |
1378 return -EINVAL; 1379 } 1380 1381 spcm->stream[dir].comp_id = host_widget->comp_id; 1382 1383 return 0; 1384} 1385 --- 24 unchanged lines hidden (view full) --- 1410 host->comp.pipeline_id = index; 1411 host->direction = dir; 1412 host->config.hdr.size = sizeof(host->config); 1413 1414 ret = sof_parse_tokens(scomp, host, pcm_tokens, 1415 ARRAY_SIZE(pcm_tokens), private->array, 1416 le32_to_cpu(private->size)); 1417 if (ret != 0) { | 1377 return -EINVAL; 1378 } 1379 1380 spcm->stream[dir].comp_id = host_widget->comp_id; 1381 1382 return 0; 1383} 1384 --- 24 unchanged lines hidden (view full) --- 1409 host->comp.pipeline_id = index; 1410 host->direction = dir; 1411 host->config.hdr.size = sizeof(host->config); 1412 1413 ret = sof_parse_tokens(scomp, host, pcm_tokens, 1414 ARRAY_SIZE(pcm_tokens), private->array, 1415 le32_to_cpu(private->size)); 1416 if (ret != 0) { |
1418 dev_err(sdev->dev, "error: parse host tokens failed %d\n", | 1417 dev_err(scomp->dev, "error: parse host tokens failed %d\n", |
1419 private->size); 1420 goto err; 1421 } 1422 1423 ret = sof_parse_tokens(scomp, &host->config, comp_tokens, 1424 ARRAY_SIZE(comp_tokens), private->array, 1425 le32_to_cpu(private->size)); 1426 if (ret != 0) { | 1418 private->size); 1419 goto err; 1420 } 1421 1422 ret = sof_parse_tokens(scomp, &host->config, comp_tokens, 1423 ARRAY_SIZE(comp_tokens), private->array, 1424 le32_to_cpu(private->size)); 1425 if (ret != 0) { |
1427 dev_err(sdev->dev, "error: parse host.cfg tokens failed %d\n", | 1426 dev_err(scomp->dev, "error: parse host.cfg tokens failed %d\n", |
1428 le32_to_cpu(private->size)); 1429 goto err; 1430 } 1431 | 1427 le32_to_cpu(private->size)); 1428 goto err; 1429 } 1430 |
1432 dev_dbg(sdev->dev, "loaded host %s\n", swidget->widget->name); | 1431 dev_dbg(scomp->dev, "loaded host %s\n", swidget->widget->name); |
1433 sof_dbg_comp_config(scomp, &host->config); 1434 1435 swidget->private = host; 1436 1437 ret = sof_ipc_tx_message(sdev->ipc, host->comp.hdr.cmd, host, 1438 sizeof(*host), r, sizeof(*r)); 1439 if (ret >= 0) 1440 return ret; 1441err: 1442 kfree(host); 1443 return ret; 1444} 1445 1446/* 1447 * Pipeline Topology 1448 */ | 1432 sof_dbg_comp_config(scomp, &host->config); 1433 1434 swidget->private = host; 1435 1436 ret = sof_ipc_tx_message(sdev->ipc, host->comp.hdr.cmd, host, 1437 sizeof(*host), r, sizeof(*r)); 1438 if (ret >= 0) 1439 return ret; 1440err: 1441 kfree(host); 1442 return ret; 1443} 1444 1445/* 1446 * Pipeline Topology 1447 */ |
1449int sof_load_pipeline_ipc(struct snd_sof_dev *sdev, | 1448int sof_load_pipeline_ipc(struct device *dev, |
1450 struct sof_ipc_pipe_new *pipeline, 1451 struct sof_ipc_comp_reply *r) 1452{ | 1449 struct sof_ipc_pipe_new *pipeline, 1450 struct sof_ipc_comp_reply *r) 1451{ |
1452 struct snd_sof_dev *sdev = dev_get_drvdata(dev); |
|
1453 struct sof_ipc_pm_core_config pm_core_config; 1454 int ret; 1455 1456 ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline, 1457 sizeof(*pipeline), r, sizeof(*r)); 1458 if (ret < 0) { | 1453 struct sof_ipc_pm_core_config pm_core_config; 1454 int ret; 1455 1456 ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline, 1457 sizeof(*pipeline), r, sizeof(*r)); 1458 if (ret < 0) { |
1459 dev_err(sdev->dev, "error: load pipeline ipc failure\n"); | 1459 dev_err(dev, "error: load pipeline ipc failure\n"); |
1460 return ret; 1461 } 1462 1463 /* power up the core that this pipeline is scheduled on */ 1464 ret = snd_sof_dsp_core_power_up(sdev, 1 << pipeline->core); 1465 if (ret < 0) { | 1460 return ret; 1461 } 1462 1463 /* power up the core that this pipeline is scheduled on */ 1464 ret = snd_sof_dsp_core_power_up(sdev, 1 << pipeline->core); 1465 if (ret < 0) { |
1466 dev_err(sdev->dev, "error: powering up pipeline schedule core %d\n", | 1466 dev_err(dev, "error: powering up pipeline schedule core %d\n", |
1467 pipeline->core); 1468 return ret; 1469 } 1470 1471 /* update enabled cores mask */ 1472 sdev->enabled_cores_mask |= 1 << pipeline->core; 1473 1474 /* --- 7 unchanged lines hidden (view full) --- 1482 pm_core_config.hdr.size = sizeof(pm_core_config); 1483 pm_core_config.hdr.cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE; 1484 1485 /* send ipc */ 1486 ret = sof_ipc_tx_message(sdev->ipc, pm_core_config.hdr.cmd, 1487 &pm_core_config, sizeof(pm_core_config), 1488 &pm_core_config, sizeof(pm_core_config)); 1489 if (ret < 0) | 1467 pipeline->core); 1468 return ret; 1469 } 1470 1471 /* update enabled cores mask */ 1472 sdev->enabled_cores_mask |= 1 << pipeline->core; 1473 1474 /* --- 7 unchanged lines hidden (view full) --- 1482 pm_core_config.hdr.size = sizeof(pm_core_config); 1483 pm_core_config.hdr.cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE; 1484 1485 /* send ipc */ 1486 ret = sof_ipc_tx_message(sdev->ipc, pm_core_config.hdr.cmd, 1487 &pm_core_config, sizeof(pm_core_config), 1488 &pm_core_config, sizeof(pm_core_config)); 1489 if (ret < 0) |
1490 dev_err(sdev->dev, "error: core enable ipc failure\n"); | 1490 dev_err(dev, "error: core enable ipc failure\n"); |
1491 1492 return ret; 1493} 1494 1495static int sof_widget_load_pipeline(struct snd_soc_component *scomp, 1496 int index, struct snd_sof_widget *swidget, 1497 struct snd_soc_tplg_dapm_widget *tw, 1498 struct sof_ipc_comp_reply *r) 1499{ | 1491 1492 return ret; 1493} 1494 1495static int sof_widget_load_pipeline(struct snd_soc_component *scomp, 1496 int index, struct snd_sof_widget *swidget, 1497 struct snd_soc_tplg_dapm_widget *tw, 1498 struct sof_ipc_comp_reply *r) 1499{ |
1500 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); | |
1501 struct snd_soc_tplg_private *private = &tw->priv; 1502 struct sof_ipc_pipe_new *pipeline; 1503 struct snd_sof_widget *comp_swidget; 1504 int ret; 1505 1506 pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL); 1507 if (!pipeline) 1508 return -ENOMEM; 1509 1510 /* configure dai IPC message */ 1511 pipeline->hdr.size = sizeof(*pipeline); 1512 pipeline->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_NEW; 1513 pipeline->pipeline_id = index; 1514 pipeline->comp_id = swidget->comp_id; 1515 1516 /* component at start of pipeline is our stream id */ | 1500 struct snd_soc_tplg_private *private = &tw->priv; 1501 struct sof_ipc_pipe_new *pipeline; 1502 struct snd_sof_widget *comp_swidget; 1503 int ret; 1504 1505 pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL); 1506 if (!pipeline) 1507 return -ENOMEM; 1508 1509 /* configure dai IPC message */ 1510 pipeline->hdr.size = sizeof(*pipeline); 1511 pipeline->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_NEW; 1512 pipeline->pipeline_id = index; 1513 pipeline->comp_id = swidget->comp_id; 1514 1515 /* component at start of pipeline is our stream id */ |
1517 comp_swidget = snd_sof_find_swidget(sdev, tw->sname); | 1516 comp_swidget = snd_sof_find_swidget(scomp, tw->sname); |
1518 if (!comp_swidget) { | 1517 if (!comp_swidget) { |
1519 dev_err(sdev->dev, "error: widget %s refers to non existent widget %s\n", | 1518 dev_err(scomp->dev, "error: widget %s refers to non existent widget %s\n", |
1520 tw->name, tw->sname); 1521 ret = -EINVAL; 1522 goto err; 1523 } 1524 1525 pipeline->sched_id = comp_swidget->comp_id; 1526 | 1519 tw->name, tw->sname); 1520 ret = -EINVAL; 1521 goto err; 1522 } 1523 1524 pipeline->sched_id = comp_swidget->comp_id; 1525 |
1527 dev_dbg(sdev->dev, "tplg: pipeline id %d comp %d scheduling comp id %d\n", | 1526 dev_dbg(scomp->dev, "tplg: pipeline id %d comp %d scheduling comp id %d\n", |
1528 pipeline->pipeline_id, pipeline->comp_id, pipeline->sched_id); 1529 1530 ret = sof_parse_tokens(scomp, pipeline, sched_tokens, 1531 ARRAY_SIZE(sched_tokens), private->array, 1532 le32_to_cpu(private->size)); 1533 if (ret != 0) { | 1527 pipeline->pipeline_id, pipeline->comp_id, pipeline->sched_id); 1528 1529 ret = sof_parse_tokens(scomp, pipeline, sched_tokens, 1530 ARRAY_SIZE(sched_tokens), private->array, 1531 le32_to_cpu(private->size)); 1532 if (ret != 0) { |
1534 dev_err(sdev->dev, "error: parse pipeline tokens failed %d\n", | 1533 dev_err(scomp->dev, "error: parse pipeline tokens failed %d\n", |
1535 private->size); 1536 goto err; 1537 } 1538 | 1534 private->size); 1535 goto err; 1536 } 1537 |
1539 dev_dbg(sdev->dev, "pipeline %s: period %d pri %d mips %d core %d frames %d\n", | 1538 dev_dbg(scomp->dev, "pipeline %s: period %d pri %d mips %d core %d frames %d\n", |
1540 swidget->widget->name, pipeline->period, pipeline->priority, 1541 pipeline->period_mips, pipeline->core, pipeline->frames_per_sched); 1542 1543 swidget->private = pipeline; 1544 1545 /* send ipc's to create pipeline comp and power up schedule core */ | 1539 swidget->widget->name, pipeline->period, pipeline->priority, 1540 pipeline->period_mips, pipeline->core, pipeline->frames_per_sched); 1541 1542 swidget->private = pipeline; 1543 1544 /* send ipc's to create pipeline comp and power up schedule core */ |
1546 ret = sof_load_pipeline_ipc(sdev, pipeline, r); | 1545 ret = sof_load_pipeline_ipc(scomp->dev, pipeline, r); |
1547 if (ret >= 0) 1548 return ret; 1549err: 1550 kfree(pipeline); 1551 return ret; 1552} 1553 1554/* --- 21 unchanged lines hidden (view full) --- 1576 mixer->comp.type = SOF_COMP_MIXER; 1577 mixer->comp.pipeline_id = index; 1578 mixer->config.hdr.size = sizeof(mixer->config); 1579 1580 ret = sof_parse_tokens(scomp, &mixer->config, comp_tokens, 1581 ARRAY_SIZE(comp_tokens), private->array, 1582 le32_to_cpu(private->size)); 1583 if (ret != 0) { | 1546 if (ret >= 0) 1547 return ret; 1548err: 1549 kfree(pipeline); 1550 return ret; 1551} 1552 1553/* --- 21 unchanged lines hidden (view full) --- 1575 mixer->comp.type = SOF_COMP_MIXER; 1576 mixer->comp.pipeline_id = index; 1577 mixer->config.hdr.size = sizeof(mixer->config); 1578 1579 ret = sof_parse_tokens(scomp, &mixer->config, comp_tokens, 1580 ARRAY_SIZE(comp_tokens), private->array, 1581 le32_to_cpu(private->size)); 1582 if (ret != 0) { |
1584 dev_err(sdev->dev, "error: parse mixer.cfg tokens failed %d\n", | 1583 dev_err(scomp->dev, "error: parse mixer.cfg tokens failed %d\n", |
1585 private->size); 1586 kfree(mixer); 1587 return ret; 1588 } 1589 1590 sof_dbg_comp_config(scomp, &mixer->config); 1591 1592 swidget->private = mixer; --- 30 unchanged lines hidden (view full) --- 1623 mux->comp.type = SOF_COMP_MUX; 1624 mux->comp.pipeline_id = index; 1625 mux->config.hdr.size = sizeof(mux->config); 1626 1627 ret = sof_parse_tokens(scomp, &mux->config, comp_tokens, 1628 ARRAY_SIZE(comp_tokens), private->array, 1629 le32_to_cpu(private->size)); 1630 if (ret != 0) { | 1584 private->size); 1585 kfree(mixer); 1586 return ret; 1587 } 1588 1589 sof_dbg_comp_config(scomp, &mixer->config); 1590 1591 swidget->private = mixer; --- 30 unchanged lines hidden (view full) --- 1622 mux->comp.type = SOF_COMP_MUX; 1623 mux->comp.pipeline_id = index; 1624 mux->config.hdr.size = sizeof(mux->config); 1625 1626 ret = sof_parse_tokens(scomp, &mux->config, comp_tokens, 1627 ARRAY_SIZE(comp_tokens), private->array, 1628 le32_to_cpu(private->size)); 1629 if (ret != 0) { |
1631 dev_err(sdev->dev, "error: parse mux.cfg tokens failed %d\n", | 1630 dev_err(scomp->dev, "error: parse mux.cfg tokens failed %d\n", |
1632 private->size); 1633 kfree(mux); 1634 return ret; 1635 } 1636 1637 sof_dbg_comp_config(scomp, &mux->config); 1638 1639 swidget->private = mux; --- 23 unchanged lines hidden (view full) --- 1663 int max_step; 1664 int ret; 1665 1666 volume = kzalloc(sizeof(*volume), GFP_KERNEL); 1667 if (!volume) 1668 return -ENOMEM; 1669 1670 if (!le32_to_cpu(tw->num_kcontrols)) { | 1631 private->size); 1632 kfree(mux); 1633 return ret; 1634 } 1635 1636 sof_dbg_comp_config(scomp, &mux->config); 1637 1638 swidget->private = mux; --- 23 unchanged lines hidden (view full) --- 1662 int max_step; 1663 int ret; 1664 1665 volume = kzalloc(sizeof(*volume), GFP_KERNEL); 1666 if (!volume) 1667 return -ENOMEM; 1668 1669 if (!le32_to_cpu(tw->num_kcontrols)) { |
1671 dev_err(sdev->dev, "error: invalid kcontrol count %d for volume\n", | 1670 dev_err(scomp->dev, "error: invalid kcontrol count %d for volume\n", |
1672 tw->num_kcontrols); 1673 ret = -EINVAL; 1674 goto err; 1675 } 1676 1677 /* configure volume IPC message */ 1678 volume->comp.hdr.size = sizeof(*volume); 1679 volume->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1680 volume->comp.id = swidget->comp_id; 1681 volume->comp.type = SOF_COMP_VOLUME; 1682 volume->comp.pipeline_id = index; 1683 volume->config.hdr.size = sizeof(volume->config); 1684 1685 ret = sof_parse_tokens(scomp, volume, volume_tokens, 1686 ARRAY_SIZE(volume_tokens), private->array, 1687 le32_to_cpu(private->size)); 1688 if (ret != 0) { | 1671 tw->num_kcontrols); 1672 ret = -EINVAL; 1673 goto err; 1674 } 1675 1676 /* configure volume IPC message */ 1677 volume->comp.hdr.size = sizeof(*volume); 1678 volume->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; 1679 volume->comp.id = swidget->comp_id; 1680 volume->comp.type = SOF_COMP_VOLUME; 1681 volume->comp.pipeline_id = index; 1682 volume->config.hdr.size = sizeof(volume->config); 1683 1684 ret = sof_parse_tokens(scomp, volume, volume_tokens, 1685 ARRAY_SIZE(volume_tokens), private->array, 1686 le32_to_cpu(private->size)); 1687 if (ret != 0) { |
1689 dev_err(sdev->dev, "error: parse volume tokens failed %d\n", | 1688 dev_err(scomp->dev, "error: parse volume tokens failed %d\n", |
1690 private->size); 1691 goto err; 1692 } 1693 ret = sof_parse_tokens(scomp, &volume->config, comp_tokens, 1694 ARRAY_SIZE(comp_tokens), private->array, 1695 le32_to_cpu(private->size)); 1696 if (ret != 0) { | 1689 private->size); 1690 goto err; 1691 } 1692 ret = sof_parse_tokens(scomp, &volume->config, comp_tokens, 1693 ARRAY_SIZE(comp_tokens), private->array, 1694 le32_to_cpu(private->size)); 1695 if (ret != 0) { |
1697 dev_err(sdev->dev, "error: parse volume.cfg tokens failed %d\n", | 1696 dev_err(scomp->dev, "error: parse volume.cfg tokens failed %d\n", |
1698 le32_to_cpu(private->size)); 1699 goto err; 1700 } 1701 1702 sof_dbg_comp_config(scomp, &volume->config); 1703 1704 swidget->private = volume; 1705 --- 43 unchanged lines hidden (view full) --- 1749 src->comp.type = SOF_COMP_SRC; 1750 src->comp.pipeline_id = index; 1751 src->config.hdr.size = sizeof(src->config); 1752 1753 ret = sof_parse_tokens(scomp, src, src_tokens, 1754 ARRAY_SIZE(src_tokens), private->array, 1755 le32_to_cpu(private->size)); 1756 if (ret != 0) { | 1697 le32_to_cpu(private->size)); 1698 goto err; 1699 } 1700 1701 sof_dbg_comp_config(scomp, &volume->config); 1702 1703 swidget->private = volume; 1704 --- 43 unchanged lines hidden (view full) --- 1748 src->comp.type = SOF_COMP_SRC; 1749 src->comp.pipeline_id = index; 1750 src->config.hdr.size = sizeof(src->config); 1751 1752 ret = sof_parse_tokens(scomp, src, src_tokens, 1753 ARRAY_SIZE(src_tokens), private->array, 1754 le32_to_cpu(private->size)); 1755 if (ret != 0) { |
1757 dev_err(sdev->dev, "error: parse src tokens failed %d\n", | 1756 dev_err(scomp->dev, "error: parse src tokens failed %d\n", |
1758 private->size); 1759 goto err; 1760 } 1761 1762 ret = sof_parse_tokens(scomp, &src->config, comp_tokens, 1763 ARRAY_SIZE(comp_tokens), private->array, 1764 le32_to_cpu(private->size)); 1765 if (ret != 0) { | 1757 private->size); 1758 goto err; 1759 } 1760 1761 ret = sof_parse_tokens(scomp, &src->config, comp_tokens, 1762 ARRAY_SIZE(comp_tokens), private->array, 1763 le32_to_cpu(private->size)); 1764 if (ret != 0) { |
1766 dev_err(sdev->dev, "error: parse src.cfg tokens failed %d\n", | 1765 dev_err(scomp->dev, "error: parse src.cfg tokens failed %d\n", |
1767 le32_to_cpu(private->size)); 1768 goto err; 1769 } 1770 | 1766 le32_to_cpu(private->size)); 1767 goto err; 1768 } 1769 |
1771 dev_dbg(sdev->dev, "src %s: source rate %d sink rate %d\n", | 1770 dev_dbg(scomp->dev, "src %s: source rate %d sink rate %d\n", |
1772 swidget->widget->name, src->source_rate, src->sink_rate); 1773 sof_dbg_comp_config(scomp, &src->config); 1774 1775 swidget->private = src; 1776 1777 ret = sof_ipc_tx_message(sdev->ipc, src->comp.hdr.cmd, src, 1778 sizeof(*src), r, sizeof(*r)); 1779 if (ret >= 0) --- 28 unchanged lines hidden (view full) --- 1808 tone->comp.type = SOF_COMP_TONE; 1809 tone->comp.pipeline_id = index; 1810 tone->config.hdr.size = sizeof(tone->config); 1811 1812 ret = sof_parse_tokens(scomp, tone, tone_tokens, 1813 ARRAY_SIZE(tone_tokens), private->array, 1814 le32_to_cpu(private->size)); 1815 if (ret != 0) { | 1771 swidget->widget->name, src->source_rate, src->sink_rate); 1772 sof_dbg_comp_config(scomp, &src->config); 1773 1774 swidget->private = src; 1775 1776 ret = sof_ipc_tx_message(sdev->ipc, src->comp.hdr.cmd, src, 1777 sizeof(*src), r, sizeof(*r)); 1778 if (ret >= 0) --- 28 unchanged lines hidden (view full) --- 1807 tone->comp.type = SOF_COMP_TONE; 1808 tone->comp.pipeline_id = index; 1809 tone->config.hdr.size = sizeof(tone->config); 1810 1811 ret = sof_parse_tokens(scomp, tone, tone_tokens, 1812 ARRAY_SIZE(tone_tokens), private->array, 1813 le32_to_cpu(private->size)); 1814 if (ret != 0) { |
1816 dev_err(sdev->dev, "error: parse tone tokens failed %d\n", | 1815 dev_err(scomp->dev, "error: parse tone tokens failed %d\n", |
1817 le32_to_cpu(private->size)); 1818 goto err; 1819 } 1820 1821 ret = sof_parse_tokens(scomp, &tone->config, comp_tokens, 1822 ARRAY_SIZE(comp_tokens), private->array, 1823 le32_to_cpu(private->size)); 1824 if (ret != 0) { | 1816 le32_to_cpu(private->size)); 1817 goto err; 1818 } 1819 1820 ret = sof_parse_tokens(scomp, &tone->config, comp_tokens, 1821 ARRAY_SIZE(comp_tokens), private->array, 1822 le32_to_cpu(private->size)); 1823 if (ret != 0) { |
1825 dev_err(sdev->dev, "error: parse tone.cfg tokens failed %d\n", | 1824 dev_err(scomp->dev, "error: parse tone.cfg tokens failed %d\n", |
1826 le32_to_cpu(private->size)); 1827 goto err; 1828 } 1829 | 1825 le32_to_cpu(private->size)); 1826 goto err; 1827 } 1828 |
1830 dev_dbg(sdev->dev, "tone %s: frequency %d amplitude %d\n", | 1829 dev_dbg(scomp->dev, "tone %s: frequency %d amplitude %d\n", |
1831 swidget->widget->name, tone->frequency, tone->amplitude); 1832 sof_dbg_comp_config(scomp, &tone->config); 1833 1834 swidget->private = tone; 1835 1836 ret = sof_ipc_tx_message(sdev->ipc, tone->comp.hdr.cmd, tone, 1837 sizeof(*tone), r, sizeof(*r)); 1838 if (ret >= 0) 1839 return ret; 1840err: 1841 kfree(tone); 1842 return ret; 1843} 1844 | 1830 swidget->widget->name, tone->frequency, tone->amplitude); 1831 sof_dbg_comp_config(scomp, &tone->config); 1832 1833 swidget->private = tone; 1834 1835 ret = sof_ipc_tx_message(sdev->ipc, tone->comp.hdr.cmd, tone, 1836 sizeof(*tone), r, sizeof(*r)); 1837 if (ret >= 0) 1838 return ret; 1839err: 1840 kfree(tone); 1841 return ret; 1842} 1843 |
1845static int sof_get_control_data(struct snd_sof_dev *sdev, | 1844static int sof_get_control_data(struct snd_soc_component *scomp, |
1846 struct snd_soc_dapm_widget *widget, 1847 struct sof_widget_data *wdata, 1848 size_t *size) 1849{ 1850 const struct snd_kcontrol_new *kc; 1851 struct soc_mixer_control *sm; 1852 struct soc_bytes_ext *sbe; 1853 struct soc_enum *se; --- 13 unchanged lines hidden (view full) --- 1867 sbe = (struct soc_bytes_ext *)kc->private_value; 1868 wdata[i].control = sbe->dobj.private; 1869 break; 1870 case SND_SOC_TPLG_TYPE_ENUM: 1871 se = (struct soc_enum *)kc->private_value; 1872 wdata[i].control = se->dobj.private; 1873 break; 1874 default: | 1845 struct snd_soc_dapm_widget *widget, 1846 struct sof_widget_data *wdata, 1847 size_t *size) 1848{ 1849 const struct snd_kcontrol_new *kc; 1850 struct soc_mixer_control *sm; 1851 struct soc_bytes_ext *sbe; 1852 struct soc_enum *se; --- 13 unchanged lines hidden (view full) --- 1866 sbe = (struct soc_bytes_ext *)kc->private_value; 1867 wdata[i].control = sbe->dobj.private; 1868 break; 1869 case SND_SOC_TPLG_TYPE_ENUM: 1870 se = (struct soc_enum *)kc->private_value; 1871 wdata[i].control = se->dobj.private; 1872 break; 1873 default: |
1875 dev_err(sdev->dev, "error: unknown kcontrol type %d in widget %s\n", | 1874 dev_err(scomp->dev, "error: unknown kcontrol type %d in widget %s\n", |
1876 widget->dobj.widget.kcontrol_type, 1877 widget->name); 1878 return -EINVAL; 1879 } 1880 1881 if (!wdata[i].control) { | 1875 widget->dobj.widget.kcontrol_type, 1876 widget->name); 1877 return -EINVAL; 1878 } 1879 1880 if (!wdata[i].control) { |
1882 dev_err(sdev->dev, "error: no scontrol for widget %s\n", | 1881 dev_err(scomp->dev, "error: no scontrol for widget %s\n", |
1883 widget->name); 1884 return -EINVAL; 1885 } 1886 1887 wdata[i].pdata = wdata[i].control->control_data->data; 1888 if (!wdata[i].pdata) 1889 return -EINVAL; 1890 --- 36 unchanged lines hidden (view full) --- 1927 struct sof_widget_data *wdata = NULL; 1928 size_t ipc_data_size = 0; 1929 size_t ipc_size; 1930 int offset = 0; 1931 int ret = 0; 1932 int i; 1933 1934 if (type == SOF_COMP_NONE) { | 1882 widget->name); 1883 return -EINVAL; 1884 } 1885 1886 wdata[i].pdata = wdata[i].control->control_data->data; 1887 if (!wdata[i].pdata) 1888 return -EINVAL; 1889 --- 36 unchanged lines hidden (view full) --- 1926 struct sof_widget_data *wdata = NULL; 1927 size_t ipc_data_size = 0; 1928 size_t ipc_size; 1929 int offset = 0; 1930 int ret = 0; 1931 int i; 1932 1933 if (type == SOF_COMP_NONE) { |
1935 dev_err(sdev->dev, "error: invalid process comp type %d\n", | 1934 dev_err(scomp->dev, "error: invalid process comp type %d\n", |
1936 type); 1937 return -EINVAL; 1938 } 1939 1940 /* allocate struct for widget control data sizes and types */ 1941 if (widget->num_kcontrols) { 1942 wdata = kcalloc(widget->num_kcontrols, 1943 sizeof(*wdata), 1944 GFP_KERNEL); 1945 1946 if (!wdata) 1947 return -ENOMEM; 1948 1949 /* get possible component controls and get size of all pdata */ | 1935 type); 1936 return -EINVAL; 1937 } 1938 1939 /* allocate struct for widget control data sizes and types */ 1940 if (widget->num_kcontrols) { 1941 wdata = kcalloc(widget->num_kcontrols, 1942 sizeof(*wdata), 1943 GFP_KERNEL); 1944 1945 if (!wdata) 1946 return -ENOMEM; 1947 1948 /* get possible component controls and get size of all pdata */ |
1950 ret = sof_get_control_data(sdev, widget, wdata, | 1949 ret = sof_get_control_data(scomp, widget, wdata, |
1951 &ipc_data_size); 1952 1953 if (ret < 0) 1954 goto out; 1955 } 1956 1957 ipc_size = sizeof(struct sof_ipc_comp_process) + 1958 le32_to_cpu(private->size) + --- 18 unchanged lines hidden (view full) --- 1977 process->comp.type = type; 1978 process->comp.pipeline_id = index; 1979 process->config.hdr.size = sizeof(process->config); 1980 1981 ret = sof_parse_tokens(scomp, &process->config, comp_tokens, 1982 ARRAY_SIZE(comp_tokens), private->array, 1983 le32_to_cpu(private->size)); 1984 if (ret != 0) { | 1950 &ipc_data_size); 1951 1952 if (ret < 0) 1953 goto out; 1954 } 1955 1956 ipc_size = sizeof(struct sof_ipc_comp_process) + 1957 le32_to_cpu(private->size) + --- 18 unchanged lines hidden (view full) --- 1976 process->comp.type = type; 1977 process->comp.pipeline_id = index; 1978 process->config.hdr.size = sizeof(process->config); 1979 1980 ret = sof_parse_tokens(scomp, &process->config, comp_tokens, 1981 ARRAY_SIZE(comp_tokens), private->array, 1982 le32_to_cpu(private->size)); 1983 if (ret != 0) { |
1985 dev_err(sdev->dev, "error: parse process.cfg tokens failed %d\n", | 1984 dev_err(scomp->dev, "error: parse process.cfg tokens failed %d\n", |
1986 le32_to_cpu(private->size)); 1987 goto err; 1988 } 1989 1990 sof_dbg_comp_config(scomp, &process->config); 1991 1992 /* 1993 * found private data in control, so copy it. --- 11 unchanged lines hidden (view full) --- 2005 2006 process->size = ipc_data_size; 2007 swidget->private = process; 2008 2009 ret = sof_ipc_tx_message(sdev->ipc, process->comp.hdr.cmd, process, 2010 ipc_size, r, sizeof(*r)); 2011 2012 if (ret < 0) { | 1985 le32_to_cpu(private->size)); 1986 goto err; 1987 } 1988 1989 sof_dbg_comp_config(scomp, &process->config); 1990 1991 /* 1992 * found private data in control, so copy it. --- 11 unchanged lines hidden (view full) --- 2004 2005 process->size = ipc_data_size; 2006 swidget->private = process; 2007 2008 ret = sof_ipc_tx_message(sdev->ipc, process->comp.hdr.cmd, process, 2009 ipc_size, r, sizeof(*r)); 2010 2011 if (ret < 0) { |
2013 dev_err(sdev->dev, "error: create process failed\n"); | 2012 dev_err(scomp->dev, "error: create process failed\n"); |
2014 goto err; 2015 } 2016 2017 /* we sent the data in single message so return */ 2018 if (ipc_data_size) 2019 goto out; 2020 2021 /* send control data with large message supported method */ 2022 for (i = 0; i < widget->num_kcontrols; i++) { 2023 wdata[i].control->readback_offset = 0; | 2013 goto err; 2014 } 2015 2016 /* we sent the data in single message so return */ 2017 if (ipc_data_size) 2018 goto out; 2019 2020 /* send control data with large message supported method */ 2021 for (i = 0; i < widget->num_kcontrols; i++) { 2022 wdata[i].control->readback_offset = 0; |
2024 ret = snd_sof_ipc_set_get_comp_data(sdev->ipc, wdata[i].control, | 2023 ret = snd_sof_ipc_set_get_comp_data(wdata[i].control, |
2025 wdata[i].ipc_cmd, 2026 wdata[i].ctrl_type, 2027 wdata[i].control->cmd, 2028 true); 2029 if (ret != 0) { | 2024 wdata[i].ipc_cmd, 2025 wdata[i].ctrl_type, 2026 wdata[i].control->cmd, 2027 true); 2028 if (ret != 0) { |
2030 dev_err(sdev->dev, "error: send control failed\n"); | 2029 dev_err(scomp->dev, "error: send control failed\n"); |
2031 break; 2032 } 2033 } 2034 2035err: 2036 if (ret < 0) 2037 kfree(process); 2038out: --- 6 unchanged lines hidden (view full) --- 2045 * "processing". 2046 */ 2047 2048static int sof_widget_load_process(struct snd_soc_component *scomp, int index, 2049 struct snd_sof_widget *swidget, 2050 struct snd_soc_tplg_dapm_widget *tw, 2051 struct sof_ipc_comp_reply *r) 2052{ | 2030 break; 2031 } 2032 } 2033 2034err: 2035 if (ret < 0) 2036 kfree(process); 2037out: --- 6 unchanged lines hidden (view full) --- 2044 * "processing". 2045 */ 2046 2047static int sof_widget_load_process(struct snd_soc_component *scomp, int index, 2048 struct snd_sof_widget *swidget, 2049 struct snd_soc_tplg_dapm_widget *tw, 2050 struct sof_ipc_comp_reply *r) 2051{ |
2053 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); | |
2054 struct snd_soc_tplg_private *private = &tw->priv; 2055 struct sof_ipc_comp_process config; 2056 int ret; 2057 2058 /* check we have some tokens - we need at least process type */ 2059 if (le32_to_cpu(private->size) == 0) { | 2052 struct snd_soc_tplg_private *private = &tw->priv; 2053 struct sof_ipc_comp_process config; 2054 int ret; 2055 2056 /* check we have some tokens - we need at least process type */ 2057 if (le32_to_cpu(private->size) == 0) { |
2060 dev_err(sdev->dev, "error: process tokens not found\n"); | 2058 dev_err(scomp->dev, "error: process tokens not found\n"); |
2061 return -EINVAL; 2062 } 2063 2064 memset(&config, 0, sizeof(config)); 2065 2066 /* get the process token */ 2067 ret = sof_parse_tokens(scomp, &config, process_tokens, 2068 ARRAY_SIZE(process_tokens), private->array, 2069 le32_to_cpu(private->size)); 2070 if (ret != 0) { | 2059 return -EINVAL; 2060 } 2061 2062 memset(&config, 0, sizeof(config)); 2063 2064 /* get the process token */ 2065 ret = sof_parse_tokens(scomp, &config, process_tokens, 2066 ARRAY_SIZE(process_tokens), private->array, 2067 le32_to_cpu(private->size)); 2068 if (ret != 0) { |
2071 dev_err(sdev->dev, "error: parse process tokens failed %d\n", | 2069 dev_err(scomp->dev, "error: parse process tokens failed %d\n", |
2072 le32_to_cpu(private->size)); 2073 return ret; 2074 } 2075 2076 /* now load process specific data and send IPC */ 2077 ret = sof_process_load(scomp, index, swidget, tw, r, 2078 find_process_comp_type(config.type)); 2079 if (ret < 0) { | 2070 le32_to_cpu(private->size)); 2071 return ret; 2072 } 2073 2074 /* now load process specific data and send IPC */ 2075 ret = sof_process_load(scomp, index, swidget, tw, r, 2076 find_process_comp_type(config.type)); 2077 if (ret < 0) { |
2080 dev_err(sdev->dev, "error: process loading failed\n"); | 2078 dev_err(scomp->dev, "error: process loading failed\n"); |
2081 return ret; 2082 } 2083 2084 return 0; 2085} 2086 | 2079 return ret; 2080 } 2081 2082 return 0; 2083} 2084 |
2087static int sof_widget_bind_event(struct snd_sof_dev *sdev, | 2085static int sof_widget_bind_event(struct snd_soc_component *scomp, |
2088 struct snd_sof_widget *swidget, 2089 u16 event_type) 2090{ 2091 struct sof_ipc_comp *ipc_comp; 2092 2093 /* validate widget event type */ 2094 switch (event_type) { 2095 case SOF_KEYWORD_DETECT_DAPM_EVENT: --- 9 unchanged lines hidden (view full) --- 2105 return snd_soc_tplg_widget_bind_event(swidget->widget, 2106 sof_kwd_events, 2107 ARRAY_SIZE(sof_kwd_events), 2108 event_type); 2109 default: 2110 break; 2111 } 2112 | 2086 struct snd_sof_widget *swidget, 2087 u16 event_type) 2088{ 2089 struct sof_ipc_comp *ipc_comp; 2090 2091 /* validate widget event type */ 2092 switch (event_type) { 2093 case SOF_KEYWORD_DETECT_DAPM_EVENT: --- 9 unchanged lines hidden (view full) --- 2103 return snd_soc_tplg_widget_bind_event(swidget->widget, 2104 sof_kwd_events, 2105 ARRAY_SIZE(sof_kwd_events), 2106 event_type); 2107 default: 2108 break; 2109 } 2110 |
2113 dev_err(sdev->dev, | 2111 dev_err(scomp->dev, |
2114 "error: invalid event type %d for widget %s\n", 2115 event_type, swidget->widget->name); 2116 return -EINVAL; 2117} 2118 2119/* external widget init - used for any driver specific init */ 2120static int sof_widget_ready(struct snd_soc_component *scomp, int index, 2121 struct snd_soc_dapm_widget *w, --- 5 unchanged lines hidden (view full) --- 2127 struct sof_ipc_comp_reply reply; 2128 struct snd_sof_control *scontrol; 2129 int ret = 0; 2130 2131 swidget = kzalloc(sizeof(*swidget), GFP_KERNEL); 2132 if (!swidget) 2133 return -ENOMEM; 2134 | 2112 "error: invalid event type %d for widget %s\n", 2113 event_type, swidget->widget->name); 2114 return -EINVAL; 2115} 2116 2117/* external widget init - used for any driver specific init */ 2118static int sof_widget_ready(struct snd_soc_component *scomp, int index, 2119 struct snd_soc_dapm_widget *w, --- 5 unchanged lines hidden (view full) --- 2125 struct sof_ipc_comp_reply reply; 2126 struct snd_sof_control *scontrol; 2127 int ret = 0; 2128 2129 swidget = kzalloc(sizeof(*swidget), GFP_KERNEL); 2130 if (!swidget) 2131 return -ENOMEM; 2132 |
2135 swidget->sdev = sdev; | 2133 swidget->scomp = scomp; |
2136 swidget->widget = w; 2137 swidget->comp_id = sdev->next_comp_id++; 2138 swidget->complete = 0; 2139 swidget->id = w->id; 2140 swidget->pipeline_id = index; 2141 swidget->private = NULL; 2142 memset(&reply, 0, sizeof(reply)); 2143 | 2134 swidget->widget = w; 2135 swidget->comp_id = sdev->next_comp_id++; 2136 swidget->complete = 0; 2137 swidget->id = w->id; 2138 swidget->pipeline_id = index; 2139 swidget->private = NULL; 2140 memset(&reply, 0, sizeof(reply)); 2141 |
2144 dev_dbg(sdev->dev, "tplg: ready widget id %d pipe %d type %d name : %s stream %s\n", | 2142 dev_dbg(scomp->dev, "tplg: ready widget id %d pipe %d type %d name : %s stream %s\n", |
2145 swidget->comp_id, index, swidget->id, tw->name, 2146 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 2147 ? tw->sname : "none"); 2148 2149 /* handle any special case widgets */ 2150 switch (w->id) { 2151 case snd_soc_dapm_dai_in: 2152 case snd_soc_dapm_dai_out: --- 54 unchanged lines hidden (view full) --- 2207 case snd_soc_dapm_mux: 2208 case snd_soc_dapm_demux: 2209 ret = sof_widget_load_mux(scomp, index, swidget, tw, &reply); 2210 break; 2211 case snd_soc_dapm_switch: 2212 case snd_soc_dapm_dai_link: 2213 case snd_soc_dapm_kcontrol: 2214 default: | 2143 swidget->comp_id, index, swidget->id, tw->name, 2144 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 2145 ? tw->sname : "none"); 2146 2147 /* handle any special case widgets */ 2148 switch (w->id) { 2149 case snd_soc_dapm_dai_in: 2150 case snd_soc_dapm_dai_out: --- 54 unchanged lines hidden (view full) --- 2205 case snd_soc_dapm_mux: 2206 case snd_soc_dapm_demux: 2207 ret = sof_widget_load_mux(scomp, index, swidget, tw, &reply); 2208 break; 2209 case snd_soc_dapm_switch: 2210 case snd_soc_dapm_dai_link: 2211 case snd_soc_dapm_kcontrol: 2212 default: |
2215 dev_warn(sdev->dev, "warning: widget type %d name %s not handled\n", | 2213 dev_warn(scomp->dev, "warning: widget type %d name %s not handled\n", |
2216 swidget->id, tw->name); 2217 break; 2218 } 2219 2220 /* check IPC reply */ 2221 if (ret < 0 || reply.rhdr.error < 0) { | 2214 swidget->id, tw->name); 2215 break; 2216 } 2217 2218 /* check IPC reply */ 2219 if (ret < 0 || reply.rhdr.error < 0) { |
2222 dev_err(sdev->dev, | 2220 dev_err(scomp->dev, |
2223 "error: DSP failed to add widget id %d type %d name : %s stream %s reply %d\n", 2224 tw->shift, swidget->id, tw->name, 2225 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 2226 ? tw->sname : "none", reply.rhdr.error); 2227 kfree(swidget); 2228 return ret; 2229 } 2230 2231 /* bind widget to external event */ 2232 if (tw->event_type) { | 2221 "error: DSP failed to add widget id %d type %d name : %s stream %s reply %d\n", 2222 tw->shift, swidget->id, tw->name, 2223 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 2224 ? tw->sname : "none", reply.rhdr.error); 2225 kfree(swidget); 2226 return ret; 2227 } 2228 2229 /* bind widget to external event */ 2230 if (tw->event_type) { |
2233 ret = sof_widget_bind_event(sdev, swidget, | 2231 ret = sof_widget_bind_event(scomp, swidget, |
2234 le16_to_cpu(tw->event_type)); 2235 if (ret) { | 2232 le16_to_cpu(tw->event_type)); 2233 if (ret) { |
2236 dev_err(sdev->dev, "error: widget event binding failed\n"); | 2234 dev_err(scomp->dev, "error: widget event binding failed\n"); |
2237 kfree(swidget->private); 2238 kfree(swidget); 2239 return ret; 2240 } 2241 } 2242 2243 w->dobj.private = swidget; 2244 list_add(&swidget->list, &sdev->widget_list); --- 51 unchanged lines hidden (view full) --- 2296 } 2297 break; 2298 case snd_soc_dapm_scheduler: 2299 2300 /* power down the pipeline schedule core */ 2301 pipeline = swidget->private; 2302 ret = snd_sof_dsp_core_power_down(sdev, 1 << pipeline->core); 2303 if (ret < 0) | 2235 kfree(swidget->private); 2236 kfree(swidget); 2237 return ret; 2238 } 2239 } 2240 2241 w->dobj.private = swidget; 2242 list_add(&swidget->list, &sdev->widget_list); --- 51 unchanged lines hidden (view full) --- 2294 } 2295 break; 2296 case snd_soc_dapm_scheduler: 2297 2298 /* power down the pipeline schedule core */ 2299 pipeline = swidget->private; 2300 ret = snd_sof_dsp_core_power_down(sdev, 1 << pipeline->core); 2301 if (ret < 0) |
2304 dev_err(sdev->dev, "error: powering down pipeline schedule core %d\n", | 2302 dev_err(scomp->dev, "error: powering down pipeline schedule core %d\n", |
2305 pipeline->core); 2306 2307 /* update enabled cores mask */ 2308 sdev->enabled_cores_mask &= ~(1 << pipeline->core); 2309 2310 break; 2311 default: 2312 break; --- 11 unchanged lines hidden (view full) --- 2324 se = (struct soc_enum *)kc->private_value; 2325 scontrol = se->dobj.private; 2326 break; 2327 case SND_SOC_TPLG_TYPE_BYTES: 2328 sbe = (struct soc_bytes_ext *)kc->private_value; 2329 scontrol = sbe->dobj.private; 2330 break; 2331 default: | 2303 pipeline->core); 2304 2305 /* update enabled cores mask */ 2306 sdev->enabled_cores_mask &= ~(1 << pipeline->core); 2307 2308 break; 2309 default: 2310 break; --- 11 unchanged lines hidden (view full) --- 2322 se = (struct soc_enum *)kc->private_value; 2323 scontrol = se->dobj.private; 2324 break; 2325 case SND_SOC_TPLG_TYPE_BYTES: 2326 sbe = (struct soc_bytes_ext *)kc->private_value; 2327 scontrol = sbe->dobj.private; 2328 break; 2329 default: |
2332 dev_warn(sdev->dev, "unsupported kcontrol_type\n"); | 2330 dev_warn(scomp->dev, "unsupported kcontrol_type\n"); |
2333 goto out; 2334 } 2335 kfree(scontrol->control_data); 2336 list_del(&scontrol->list); 2337 kfree(scontrol); 2338 } 2339 2340out: --- 26 unchanged lines hidden (view full) --- 2367 /* nothing to do for BEs atm */ 2368 if (!pcm) 2369 return 0; 2370 2371 spcm = kzalloc(sizeof(*spcm), GFP_KERNEL); 2372 if (!spcm) 2373 return -ENOMEM; 2374 | 2331 goto out; 2332 } 2333 kfree(scontrol->control_data); 2334 list_del(&scontrol->list); 2335 kfree(scontrol); 2336 } 2337 2338out: --- 26 unchanged lines hidden (view full) --- 2365 /* nothing to do for BEs atm */ 2366 if (!pcm) 2367 return 0; 2368 2369 spcm = kzalloc(sizeof(*spcm), GFP_KERNEL); 2370 if (!spcm) 2371 return -ENOMEM; 2372 |
2375 spcm->sdev = sdev; | 2373 spcm->scomp = scomp; |
2376 spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].comp_id = COMP_ID_UNASSIGNED; 2377 spcm->stream[SNDRV_PCM_STREAM_CAPTURE].comp_id = COMP_ID_UNASSIGNED; 2378 2379 spcm->pcm = *pcm; | 2374 spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].comp_id = COMP_ID_UNASSIGNED; 2375 spcm->stream[SNDRV_PCM_STREAM_CAPTURE].comp_id = COMP_ID_UNASSIGNED; 2376 2377 spcm->pcm = *pcm; |
2380 dev_dbg(sdev->dev, "tplg: load pcm %s\n", pcm->dai_name); | 2378 dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name); |
2381 2382 dai_drv->dobj.private = spcm; 2383 list_add(&spcm->list, &sdev->pcm_list); 2384 2385 ret = sof_parse_tokens(scomp, spcm, stream_tokens, 2386 ARRAY_SIZE(stream_tokens), private->array, 2387 le32_to_cpu(private->size)); 2388 if (ret) { | 2379 2380 dai_drv->dobj.private = spcm; 2381 list_add(&spcm->list, &sdev->pcm_list); 2382 2383 ret = sof_parse_tokens(scomp, spcm, stream_tokens, 2384 ARRAY_SIZE(stream_tokens), private->array, 2385 le32_to_cpu(private->size)); 2386 if (ret) { |
2389 dev_err(sdev->dev, "error: parse stream tokens failed %d\n", | 2387 dev_err(scomp->dev, "error: parse stream tokens failed %d\n", |
2390 le32_to_cpu(private->size)); 2391 return ret; 2392 } 2393 2394 /* do we need to allocate playback PCM DMA pages */ 2395 if (!spcm->pcm.playback) 2396 goto capture; 2397 | 2388 le32_to_cpu(private->size)); 2389 return ret; 2390 } 2391 2392 /* do we need to allocate playback PCM DMA pages */ 2393 if (!spcm->pcm.playback) 2394 goto capture; 2395 |
2398 dev_vdbg(sdev->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n", | 2396 dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n", |
2399 spcm->pcm.pcm_name, spcm->stream[0].d0i3_compatible); 2400 2401 caps = &spcm->pcm.caps[stream]; 2402 2403 /* allocate playback page table buffer */ 2404 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 2405 PAGE_SIZE, &spcm->stream[stream].page_table); 2406 if (ret < 0) { | 2397 spcm->pcm.pcm_name, spcm->stream[0].d0i3_compatible); 2398 2399 caps = &spcm->pcm.caps[stream]; 2400 2401 /* allocate playback page table buffer */ 2402 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 2403 PAGE_SIZE, &spcm->stream[stream].page_table); 2404 if (ret < 0) { |
2407 dev_err(sdev->dev, "error: can't alloc page table for %s %d\n", | 2405 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n", |
2408 caps->name, ret); 2409 2410 return ret; 2411 } 2412 2413 /* bind pcm to host comp */ | 2406 caps->name, ret); 2407 2408 return ret; 2409 } 2410 2411 /* bind pcm to host comp */ |
2414 ret = spcm_bind(sdev, spcm, stream); | 2412 ret = spcm_bind(scomp, spcm, stream); |
2415 if (ret) { | 2413 if (ret) { |
2416 dev_err(sdev->dev, | 2414 dev_err(scomp->dev, |
2417 "error: can't bind pcm to host\n"); 2418 goto free_playback_tables; 2419 } 2420 2421capture: 2422 stream = SNDRV_PCM_STREAM_CAPTURE; 2423 2424 /* do we need to allocate capture PCM DMA pages */ 2425 if (!spcm->pcm.capture) 2426 return ret; 2427 | 2415 "error: can't bind pcm to host\n"); 2416 goto free_playback_tables; 2417 } 2418 2419capture: 2420 stream = SNDRV_PCM_STREAM_CAPTURE; 2421 2422 /* do we need to allocate capture PCM DMA pages */ 2423 if (!spcm->pcm.capture) 2424 return ret; 2425 |
2428 dev_vdbg(sdev->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n", | 2426 dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n", |
2429 spcm->pcm.pcm_name, spcm->stream[1].d0i3_compatible); 2430 2431 caps = &spcm->pcm.caps[stream]; 2432 2433 /* allocate capture page table buffer */ 2434 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 2435 PAGE_SIZE, &spcm->stream[stream].page_table); 2436 if (ret < 0) { | 2427 spcm->pcm.pcm_name, spcm->stream[1].d0i3_compatible); 2428 2429 caps = &spcm->pcm.caps[stream]; 2430 2431 /* allocate capture page table buffer */ 2432 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 2433 PAGE_SIZE, &spcm->stream[stream].page_table); 2434 if (ret < 0) { |
2437 dev_err(sdev->dev, "error: can't alloc page table for %s %d\n", | 2435 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n", |
2438 caps->name, ret); 2439 goto free_playback_tables; 2440 } 2441 2442 /* bind pcm to host comp */ | 2436 caps->name, ret); 2437 goto free_playback_tables; 2438 } 2439 2440 /* bind pcm to host comp */ |
2443 ret = spcm_bind(sdev, spcm, stream); | 2441 ret = spcm_bind(scomp, spcm, stream); |
2444 if (ret) { | 2442 if (ret) { |
2445 dev_err(sdev->dev, | 2443 dev_err(scomp->dev, |
2446 "error: can't bind pcm to host\n"); 2447 snd_dma_free_pages(&spcm->stream[stream].page_table); 2448 goto free_playback_tables; 2449 } 2450 2451 return ret; 2452 2453free_playback_tables: --- 109 unchanged lines hidden (view full) --- 2563 /* init IPC */ 2564 memset(&config->ssp, 0, sizeof(struct sof_ipc_dai_ssp_params)); 2565 config->hdr.size = size; 2566 2567 ret = sof_parse_tokens(scomp, &config->ssp, ssp_tokens, 2568 ARRAY_SIZE(ssp_tokens), private->array, 2569 le32_to_cpu(private->size)); 2570 if (ret != 0) { | 2444 "error: can't bind pcm to host\n"); 2445 snd_dma_free_pages(&spcm->stream[stream].page_table); 2446 goto free_playback_tables; 2447 } 2448 2449 return ret; 2450 2451free_playback_tables: --- 109 unchanged lines hidden (view full) --- 2561 /* init IPC */ 2562 memset(&config->ssp, 0, sizeof(struct sof_ipc_dai_ssp_params)); 2563 config->hdr.size = size; 2564 2565 ret = sof_parse_tokens(scomp, &config->ssp, ssp_tokens, 2566 ARRAY_SIZE(ssp_tokens), private->array, 2567 le32_to_cpu(private->size)); 2568 if (ret != 0) { |
2571 dev_err(sdev->dev, "error: parse ssp tokens failed %d\n", | 2569 dev_err(scomp->dev, "error: parse ssp tokens failed %d\n", |
2572 le32_to_cpu(private->size)); 2573 return ret; 2574 } 2575 2576 config->ssp.mclk_rate = le32_to_cpu(hw_config->mclk_rate); 2577 config->ssp.bclk_rate = le32_to_cpu(hw_config->bclk_rate); 2578 config->ssp.fsync_rate = le32_to_cpu(hw_config->fsync_rate); 2579 config->ssp.tdm_slots = le32_to_cpu(hw_config->tdm_slots); 2580 config->ssp.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); 2581 config->ssp.mclk_direction = hw_config->mclk_direction; 2582 config->ssp.rx_slots = le32_to_cpu(hw_config->rx_slots); 2583 config->ssp.tx_slots = le32_to_cpu(hw_config->tx_slots); 2584 | 2570 le32_to_cpu(private->size)); 2571 return ret; 2572 } 2573 2574 config->ssp.mclk_rate = le32_to_cpu(hw_config->mclk_rate); 2575 config->ssp.bclk_rate = le32_to_cpu(hw_config->bclk_rate); 2576 config->ssp.fsync_rate = le32_to_cpu(hw_config->fsync_rate); 2577 config->ssp.tdm_slots = le32_to_cpu(hw_config->tdm_slots); 2578 config->ssp.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); 2579 config->ssp.mclk_direction = hw_config->mclk_direction; 2580 config->ssp.rx_slots = le32_to_cpu(hw_config->rx_slots); 2581 config->ssp.tx_slots = le32_to_cpu(hw_config->tx_slots); 2582 |
2585 dev_dbg(sdev->dev, "tplg: config SSP%d fmt 0x%x mclk %d bclk %d fclk %d width (%d)%d slots %d mclk id %d quirks %d\n", | 2583 dev_dbg(scomp->dev, "tplg: config SSP%d fmt 0x%x mclk %d bclk %d fclk %d width (%d)%d slots %d mclk id %d quirks %d\n", |
2586 config->dai_index, config->format, 2587 config->ssp.mclk_rate, config->ssp.bclk_rate, 2588 config->ssp.fsync_rate, config->ssp.sample_valid_bits, 2589 config->ssp.tdm_slot_width, config->ssp.tdm_slots, 2590 config->ssp.mclk_id, config->ssp.quirks); 2591 2592 /* validate SSP fsync rate and channel count */ 2593 if (config->ssp.fsync_rate < 8000 || config->ssp.fsync_rate > 192000) { | 2584 config->dai_index, config->format, 2585 config->ssp.mclk_rate, config->ssp.bclk_rate, 2586 config->ssp.fsync_rate, config->ssp.sample_valid_bits, 2587 config->ssp.tdm_slot_width, config->ssp.tdm_slots, 2588 config->ssp.mclk_id, config->ssp.quirks); 2589 2590 /* validate SSP fsync rate and channel count */ 2591 if (config->ssp.fsync_rate < 8000 || config->ssp.fsync_rate > 192000) { |
2594 dev_err(sdev->dev, "error: invalid fsync rate for SSP%d\n", | 2592 dev_err(scomp->dev, "error: invalid fsync rate for SSP%d\n", |
2595 config->dai_index); 2596 return -EINVAL; 2597 } 2598 2599 if (config->ssp.tdm_slots < 1 || config->ssp.tdm_slots > 8) { | 2593 config->dai_index); 2594 return -EINVAL; 2595 } 2596 2597 if (config->ssp.tdm_slots < 1 || config->ssp.tdm_slots > 8) { |
2600 dev_err(sdev->dev, "error: invalid channel count for SSP%d\n", | 2598 dev_err(scomp->dev, "error: invalid channel count for SSP%d\n", |
2601 config->dai_index); 2602 return -EINVAL; 2603 } 2604 2605 /* send message to DSP */ 2606 ret = sof_ipc_tx_message(sdev->ipc, 2607 config->hdr.cmd, config, size, &reply, 2608 sizeof(reply)); 2609 2610 if (ret < 0) { | 2599 config->dai_index); 2600 return -EINVAL; 2601 } 2602 2603 /* send message to DSP */ 2604 ret = sof_ipc_tx_message(sdev->ipc, 2605 config->hdr.cmd, config, size, &reply, 2606 sizeof(reply)); 2607 2608 if (ret < 0) { |
2611 dev_err(sdev->dev, "error: failed to set DAI config for SSP%d\n", | 2609 dev_err(scomp->dev, "error: failed to set DAI config for SSP%d\n", |
2612 config->dai_index); 2613 return ret; 2614 } 2615 2616 /* set config for all DAI's with name matching the link name */ 2617 ret = sof_set_dai_config(sdev, size, link, config); 2618 if (ret < 0) | 2610 config->dai_index); 2611 return ret; 2612 } 2613 2614 /* set config for all DAI's with name matching the link name */ 2615 ret = sof_set_dai_config(sdev, size, link, config); 2616 if (ret < 0) |
2619 dev_err(sdev->dev, "error: failed to save DAI config for SSP%d\n", | 2617 dev_err(scomp->dev, "error: failed to save DAI config for SSP%d\n", |
2620 config->dai_index); 2621 2622 return ret; 2623} 2624 2625static int sof_link_sai_load(struct snd_soc_component *scomp, int index, 2626 struct snd_soc_dai_link *link, 2627 struct snd_soc_tplg_link_config *cfg, --- 22 unchanged lines hidden (view full) --- 2650 /* init IPC */ 2651 memset(&config->esai, 0, sizeof(struct sof_ipc_dai_esai_params)); 2652 config->hdr.size = size; 2653 2654 ret = sof_parse_tokens(scomp, &config->esai, esai_tokens, 2655 ARRAY_SIZE(esai_tokens), private->array, 2656 le32_to_cpu(private->size)); 2657 if (ret != 0) { | 2618 config->dai_index); 2619 2620 return ret; 2621} 2622 2623static int sof_link_sai_load(struct snd_soc_component *scomp, int index, 2624 struct snd_soc_dai_link *link, 2625 struct snd_soc_tplg_link_config *cfg, --- 22 unchanged lines hidden (view full) --- 2648 /* init IPC */ 2649 memset(&config->esai, 0, sizeof(struct sof_ipc_dai_esai_params)); 2650 config->hdr.size = size; 2651 2652 ret = sof_parse_tokens(scomp, &config->esai, esai_tokens, 2653 ARRAY_SIZE(esai_tokens), private->array, 2654 le32_to_cpu(private->size)); 2655 if (ret != 0) { |
2658 dev_err(sdev->dev, "error: parse esai tokens failed %d\n", | 2656 dev_err(scomp->dev, "error: parse esai tokens failed %d\n", |
2659 le32_to_cpu(private->size)); 2660 return ret; 2661 } 2662 2663 config->esai.mclk_rate = le32_to_cpu(hw_config->mclk_rate); 2664 config->esai.bclk_rate = le32_to_cpu(hw_config->bclk_rate); 2665 config->esai.fsync_rate = le32_to_cpu(hw_config->fsync_rate); 2666 config->esai.mclk_direction = hw_config->mclk_direction; 2667 config->esai.tdm_slots = le32_to_cpu(hw_config->tdm_slots); 2668 config->esai.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); 2669 config->esai.rx_slots = le32_to_cpu(hw_config->rx_slots); 2670 config->esai.tx_slots = le32_to_cpu(hw_config->tx_slots); 2671 | 2657 le32_to_cpu(private->size)); 2658 return ret; 2659 } 2660 2661 config->esai.mclk_rate = le32_to_cpu(hw_config->mclk_rate); 2662 config->esai.bclk_rate = le32_to_cpu(hw_config->bclk_rate); 2663 config->esai.fsync_rate = le32_to_cpu(hw_config->fsync_rate); 2664 config->esai.mclk_direction = hw_config->mclk_direction; 2665 config->esai.tdm_slots = le32_to_cpu(hw_config->tdm_slots); 2666 config->esai.tdm_slot_width = le32_to_cpu(hw_config->tdm_slot_width); 2667 config->esai.rx_slots = le32_to_cpu(hw_config->rx_slots); 2668 config->esai.tx_slots = le32_to_cpu(hw_config->tx_slots); 2669 |
2672 dev_info(sdev->dev, | 2670 dev_info(scomp->dev, |
2673 "tplg: config ESAI%d fmt 0x%x mclk %d width %d slots %d mclk id %d\n", 2674 config->dai_index, config->format, 2675 config->esai.mclk_rate, config->esai.tdm_slot_width, 2676 config->esai.tdm_slots, config->esai.mclk_id); 2677 2678 if (config->esai.tdm_slots < 1 || config->esai.tdm_slots > 8) { | 2671 "tplg: config ESAI%d fmt 0x%x mclk %d width %d slots %d mclk id %d\n", 2672 config->dai_index, config->format, 2673 config->esai.mclk_rate, config->esai.tdm_slot_width, 2674 config->esai.tdm_slots, config->esai.mclk_id); 2675 2676 if (config->esai.tdm_slots < 1 || config->esai.tdm_slots > 8) { |
2679 dev_err(sdev->dev, "error: invalid channel count for ESAI%d\n", | 2677 dev_err(scomp->dev, "error: invalid channel count for ESAI%d\n", |
2680 config->dai_index); 2681 return -EINVAL; 2682 } 2683 2684 /* send message to DSP */ 2685 ret = sof_ipc_tx_message(sdev->ipc, 2686 config->hdr.cmd, config, size, &reply, 2687 sizeof(reply)); 2688 if (ret < 0) { | 2678 config->dai_index); 2679 return -EINVAL; 2680 } 2681 2682 /* send message to DSP */ 2683 ret = sof_ipc_tx_message(sdev->ipc, 2684 config->hdr.cmd, config, size, &reply, 2685 sizeof(reply)); 2686 if (ret < 0) { |
2689 dev_err(sdev->dev, "error: failed to set DAI config for ESAI%d\n", | 2687 dev_err(scomp->dev, "error: failed to set DAI config for ESAI%d\n", |
2690 config->dai_index); 2691 return ret; 2692 } 2693 2694 /* set config for all DAI's with name matching the link name */ 2695 ret = sof_set_dai_config(sdev, size, link, config); 2696 if (ret < 0) | 2688 config->dai_index); 2689 return ret; 2690 } 2691 2692 /* set config for all DAI's with name matching the link name */ 2693 ret = sof_set_dai_config(sdev, size, link, config); 2694 if (ret < 0) |
2697 dev_err(sdev->dev, "error: failed to save DAI config for ESAI%d\n", | 2695 dev_err(scomp->dev, "error: failed to save DAI config for ESAI%d\n", |
2698 config->dai_index); 2699 2700 return ret; 2701} 2702 2703static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, 2704 struct snd_soc_dai_link *link, 2705 struct snd_soc_tplg_link_config *cfg, --- 16 unchanged lines hidden (view full) --- 2722 */ 2723 memset(&config->dmic, 0, sizeof(struct sof_ipc_dai_dmic_params)); 2724 2725 /* get DMIC tokens */ 2726 ret = sof_parse_tokens(scomp, &config->dmic, dmic_tokens, 2727 ARRAY_SIZE(dmic_tokens), private->array, 2728 le32_to_cpu(private->size)); 2729 if (ret != 0) { | 2696 config->dai_index); 2697 2698 return ret; 2699} 2700 2701static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, 2702 struct snd_soc_dai_link *link, 2703 struct snd_soc_tplg_link_config *cfg, --- 16 unchanged lines hidden (view full) --- 2720 */ 2721 memset(&config->dmic, 0, sizeof(struct sof_ipc_dai_dmic_params)); 2722 2723 /* get DMIC tokens */ 2724 ret = sof_parse_tokens(scomp, &config->dmic, dmic_tokens, 2725 ARRAY_SIZE(dmic_tokens), private->array, 2726 le32_to_cpu(private->size)); 2727 if (ret != 0) { |
2730 dev_err(sdev->dev, "error: parse dmic tokens failed %d\n", | 2728 dev_err(scomp->dev, "error: parse dmic tokens failed %d\n", |
2731 le32_to_cpu(private->size)); 2732 return ret; 2733 } 2734 2735 /* 2736 * allocate memory for dmic dai config accounting for the 2737 * variable number of active pdm controllers 2738 * This will be the ipc payload for setting dai config --- 18 unchanged lines hidden (view full) --- 2757 return -ENOMEM; 2758 } 2759 2760 /* get DMIC PDM tokens */ 2761 ret = sof_parse_tokens(scomp, &ipc_config->dmic.pdm[0], dmic_pdm_tokens, 2762 ARRAY_SIZE(dmic_pdm_tokens), private->array, 2763 le32_to_cpu(private->size)); 2764 if (ret != 0) { | 2729 le32_to_cpu(private->size)); 2730 return ret; 2731 } 2732 2733 /* 2734 * allocate memory for dmic dai config accounting for the 2735 * variable number of active pdm controllers 2736 * This will be the ipc payload for setting dai config --- 18 unchanged lines hidden (view full) --- 2755 return -ENOMEM; 2756 } 2757 2758 /* get DMIC PDM tokens */ 2759 ret = sof_parse_tokens(scomp, &ipc_config->dmic.pdm[0], dmic_pdm_tokens, 2760 ARRAY_SIZE(dmic_pdm_tokens), private->array, 2761 le32_to_cpu(private->size)); 2762 if (ret != 0) { |
2765 dev_err(sdev->dev, "error: parse dmic pdm tokens failed %d\n", | 2763 dev_err(scomp->dev, "error: parse dmic pdm tokens failed %d\n", |
2766 le32_to_cpu(private->size)); 2767 goto err; 2768 } 2769 2770 /* set IPC header size */ 2771 ipc_config->hdr.size = size; 2772 2773 /* debug messages */ | 2764 le32_to_cpu(private->size)); 2765 goto err; 2766 } 2767 2768 /* set IPC header size */ 2769 ipc_config->hdr.size = size; 2770 2771 /* debug messages */ |
2774 dev_dbg(sdev->dev, "tplg: config DMIC%d driver version %d\n", | 2772 dev_dbg(scomp->dev, "tplg: config DMIC%d driver version %d\n", |
2775 ipc_config->dai_index, ipc_config->dmic.driver_ipc_version); | 2773 ipc_config->dai_index, ipc_config->dmic.driver_ipc_version); |
2776 dev_dbg(sdev->dev, "pdmclk_min %d pdm_clkmax %d duty_min %hd\n", | 2774 dev_dbg(scomp->dev, "pdmclk_min %d pdm_clkmax %d duty_min %hd\n", |
2777 ipc_config->dmic.pdmclk_min, ipc_config->dmic.pdmclk_max, 2778 ipc_config->dmic.duty_min); | 2775 ipc_config->dmic.pdmclk_min, ipc_config->dmic.pdmclk_max, 2776 ipc_config->dmic.duty_min); |
2779 dev_dbg(sdev->dev, "duty_max %hd fifo_fs %d num_pdms active %d\n", | 2777 dev_dbg(scomp->dev, "duty_max %hd fifo_fs %d num_pdms active %d\n", |
2780 ipc_config->dmic.duty_max, ipc_config->dmic.fifo_fs, 2781 ipc_config->dmic.num_pdm_active); | 2778 ipc_config->dmic.duty_max, ipc_config->dmic.fifo_fs, 2779 ipc_config->dmic.num_pdm_active); |
2782 dev_dbg(sdev->dev, "fifo word length %hd\n", | 2780 dev_dbg(scomp->dev, "fifo word length %hd\n", |
2783 ipc_config->dmic.fifo_bits); 2784 2785 for (j = 0; j < ipc_config->dmic.num_pdm_active; j++) { | 2781 ipc_config->dmic.fifo_bits); 2782 2783 for (j = 0; j < ipc_config->dmic.num_pdm_active; j++) { |
2786 dev_dbg(sdev->dev, "pdm %hd mic a %hd mic b %hd\n", | 2784 dev_dbg(scomp->dev, "pdm %hd mic a %hd mic b %hd\n", |
2787 ipc_config->dmic.pdm[j].id, 2788 ipc_config->dmic.pdm[j].enable_mic_a, 2789 ipc_config->dmic.pdm[j].enable_mic_b); | 2785 ipc_config->dmic.pdm[j].id, 2786 ipc_config->dmic.pdm[j].enable_mic_a, 2787 ipc_config->dmic.pdm[j].enable_mic_b); |
2790 dev_dbg(sdev->dev, "pdm %hd polarity a %hd polarity b %hd\n", | 2788 dev_dbg(scomp->dev, "pdm %hd polarity a %hd polarity b %hd\n", |
2791 ipc_config->dmic.pdm[j].id, 2792 ipc_config->dmic.pdm[j].polarity_mic_a, 2793 ipc_config->dmic.pdm[j].polarity_mic_b); | 2789 ipc_config->dmic.pdm[j].id, 2790 ipc_config->dmic.pdm[j].polarity_mic_a, 2791 ipc_config->dmic.pdm[j].polarity_mic_b); |
2794 dev_dbg(sdev->dev, "pdm %hd clk_edge %hd skew %hd\n", | 2792 dev_dbg(scomp->dev, "pdm %hd clk_edge %hd skew %hd\n", |
2795 ipc_config->dmic.pdm[j].id, 2796 ipc_config->dmic.pdm[j].clk_edge, 2797 ipc_config->dmic.pdm[j].skew); 2798 } 2799 2800 if (SOF_ABI_VER(v->major, v->minor, v->micro) < SOF_ABI_VER(3, 0, 1)) { 2801 /* this takes care of backwards compatible handling of fifo_bits_b */ 2802 ipc_config->dmic.reserved_2 = ipc_config->dmic.fifo_bits; 2803 } 2804 2805 /* send message to DSP */ 2806 ret = sof_ipc_tx_message(sdev->ipc, 2807 ipc_config->hdr.cmd, ipc_config, size, &reply, 2808 sizeof(reply)); 2809 2810 if (ret < 0) { | 2793 ipc_config->dmic.pdm[j].id, 2794 ipc_config->dmic.pdm[j].clk_edge, 2795 ipc_config->dmic.pdm[j].skew); 2796 } 2797 2798 if (SOF_ABI_VER(v->major, v->minor, v->micro) < SOF_ABI_VER(3, 0, 1)) { 2799 /* this takes care of backwards compatible handling of fifo_bits_b */ 2800 ipc_config->dmic.reserved_2 = ipc_config->dmic.fifo_bits; 2801 } 2802 2803 /* send message to DSP */ 2804 ret = sof_ipc_tx_message(sdev->ipc, 2805 ipc_config->hdr.cmd, ipc_config, size, &reply, 2806 sizeof(reply)); 2807 2808 if (ret < 0) { |
2811 dev_err(sdev->dev, | 2809 dev_err(scomp->dev, |
2812 "error: failed to set DAI config for DMIC%d\n", 2813 config->dai_index); 2814 goto err; 2815 } 2816 2817 /* set config for all DAI's with name matching the link name */ 2818 ret = sof_set_dai_config(sdev, size, link, ipc_config); 2819 if (ret < 0) | 2810 "error: failed to set DAI config for DMIC%d\n", 2811 config->dai_index); 2812 goto err; 2813 } 2814 2815 /* set config for all DAI's with name matching the link name */ 2816 ret = sof_set_dai_config(sdev, size, link, ipc_config); 2817 if (ret < 0) |
2820 dev_err(sdev->dev, "error: failed to save DAI config for DMIC%d\n", | 2818 dev_err(scomp->dev, "error: failed to save DAI config for DMIC%d\n", |
2821 config->dai_index); 2822 2823err: 2824 kfree(sdev->private); 2825 kfree(ipc_config); 2826 2827 return ret; 2828} --- 74 unchanged lines hidden (view full) --- 2903 memset(&config->hda, 0, sizeof(struct sof_ipc_dai_hda_params)); 2904 config->hdr.size = size; 2905 2906 /* get any bespoke DAI tokens */ 2907 ret = sof_parse_tokens(scomp, config, hda_tokens, 2908 ARRAY_SIZE(hda_tokens), private->array, 2909 le32_to_cpu(private->size)); 2910 if (ret != 0) { | 2819 config->dai_index); 2820 2821err: 2822 kfree(sdev->private); 2823 kfree(ipc_config); 2824 2825 return ret; 2826} --- 74 unchanged lines hidden (view full) --- 2901 memset(&config->hda, 0, sizeof(struct sof_ipc_dai_hda_params)); 2902 config->hdr.size = size; 2903 2904 /* get any bespoke DAI tokens */ 2905 ret = sof_parse_tokens(scomp, config, hda_tokens, 2906 ARRAY_SIZE(hda_tokens), private->array, 2907 le32_to_cpu(private->size)); 2908 if (ret != 0) { |
2911 dev_err(sdev->dev, "error: parse hda tokens failed %d\n", | 2909 dev_err(scomp->dev, "error: parse hda tokens failed %d\n", |
2912 le32_to_cpu(private->size)); 2913 return ret; 2914 } 2915 2916 dai = snd_soc_find_dai(link->cpus); 2917 if (!dai) { | 2910 le32_to_cpu(private->size)); 2911 return ret; 2912 } 2913 2914 dai = snd_soc_find_dai(link->cpus); 2915 if (!dai) { |
2918 dev_err(sdev->dev, "error: failed to find dai %s in %s", | 2916 dev_err(scomp->dev, "error: failed to find dai %s in %s", |
2919 link->cpus->dai_name, __func__); 2920 return -EINVAL; 2921 } 2922 2923 ret = sof_link_hda_process(sdev, link, config); 2924 if (ret < 0) | 2917 link->cpus->dai_name, __func__); 2918 return -EINVAL; 2919 } 2920 2921 ret = sof_link_hda_process(sdev, link, config); 2922 if (ret < 0) |
2925 dev_err(sdev->dev, "error: failed to process hda dai link %s", | 2923 dev_err(scomp->dev, "error: failed to process hda dai link %s", |
2926 link->name); 2927 2928 return ret; 2929} 2930 2931static int sof_link_alh_load(struct snd_soc_component *scomp, int index, 2932 struct snd_soc_dai_link *link, 2933 struct snd_soc_tplg_link_config *cfg, --- 9 unchanged lines hidden (view full) --- 2943 config->hdr.size = size; 2944 2945 /* send message to DSP */ 2946 ret = sof_ipc_tx_message(sdev->ipc, 2947 config->hdr.cmd, config, size, &reply, 2948 sizeof(reply)); 2949 2950 if (ret < 0) { | 2924 link->name); 2925 2926 return ret; 2927} 2928 2929static int sof_link_alh_load(struct snd_soc_component *scomp, int index, 2930 struct snd_soc_dai_link *link, 2931 struct snd_soc_tplg_link_config *cfg, --- 9 unchanged lines hidden (view full) --- 2941 config->hdr.size = size; 2942 2943 /* send message to DSP */ 2944 ret = sof_ipc_tx_message(sdev->ipc, 2945 config->hdr.cmd, config, size, &reply, 2946 sizeof(reply)); 2947 2948 if (ret < 0) { |
2951 dev_err(sdev->dev, "error: failed to set DAI config for ALH %d\n", | 2949 dev_err(scomp->dev, "error: failed to set DAI config for ALH %d\n", |
2952 config->dai_index); 2953 return ret; 2954 } 2955 2956 /* set config for all DAI's with name matching the link name */ 2957 ret = sof_set_dai_config(sdev, size, link, config); 2958 if (ret < 0) | 2950 config->dai_index); 2951 return ret; 2952 } 2953 2954 /* set config for all DAI's with name matching the link name */ 2955 ret = sof_set_dai_config(sdev, size, link, config); 2956 if (ret < 0) |
2959 dev_err(sdev->dev, "error: failed to save DAI config for ALH %d\n", | 2957 dev_err(scomp->dev, "error: failed to save DAI config for ALH %d\n", |
2960 config->dai_index); 2961 2962 return ret; 2963} 2964 2965/* DAI link - used for any driver specific init */ 2966static int sof_link_load(struct snd_soc_component *scomp, int index, 2967 struct snd_soc_dai_link *link, 2968 struct snd_soc_tplg_link_config *cfg) 2969{ | 2958 config->dai_index); 2959 2960 return ret; 2961} 2962 2963/* DAI link - used for any driver specific init */ 2964static int sof_link_load(struct snd_soc_component *scomp, int index, 2965 struct snd_soc_dai_link *link, 2966 struct snd_soc_tplg_link_config *cfg) 2967{ |
2970 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); | |
2971 struct snd_soc_tplg_private *private = &cfg->priv; 2972 struct sof_ipc_dai_config config; 2973 struct snd_soc_tplg_hw_config *hw_config; 2974 int num_hw_configs; 2975 int ret; 2976 int i = 0; 2977 2978 if (!link->platforms) { | 2968 struct snd_soc_tplg_private *private = &cfg->priv; 2969 struct sof_ipc_dai_config config; 2970 struct snd_soc_tplg_hw_config *hw_config; 2971 int num_hw_configs; 2972 int ret; 2973 int i = 0; 2974 2975 if (!link->platforms) { |
2979 dev_err(sdev->dev, "error: no platforms\n"); | 2976 dev_err(scomp->dev, "error: no platforms\n"); |
2980 return -EINVAL; 2981 } | 2977 return -EINVAL; 2978 } |
2982 link->platforms->name = dev_name(sdev->dev); | 2979 link->platforms->name = dev_name(scomp->dev); |
2983 2984 /* 2985 * Set nonatomic property for FE dai links as their trigger action 2986 * involves IPC's. 2987 */ 2988 if (!link->no_pcm) { 2989 link->nonatomic = true; 2990 2991 /* set trigger order */ 2992 link->trigger[0] = SND_SOC_DPCM_TRIGGER_POST; 2993 link->trigger[1] = SND_SOC_DPCM_TRIGGER_POST; 2994 2995 /* nothing more to do for FE dai links */ 2996 return 0; 2997 } 2998 2999 /* check we have some tokens - we need at least DAI type */ 3000 if (le32_to_cpu(private->size) == 0) { | 2980 2981 /* 2982 * Set nonatomic property for FE dai links as their trigger action 2983 * involves IPC's. 2984 */ 2985 if (!link->no_pcm) { 2986 link->nonatomic = true; 2987 2988 /* set trigger order */ 2989 link->trigger[0] = SND_SOC_DPCM_TRIGGER_POST; 2990 link->trigger[1] = SND_SOC_DPCM_TRIGGER_POST; 2991 2992 /* nothing more to do for FE dai links */ 2993 return 0; 2994 } 2995 2996 /* check we have some tokens - we need at least DAI type */ 2997 if (le32_to_cpu(private->size) == 0) { |
3001 dev_err(sdev->dev, "error: expected tokens for DAI, none found\n"); | 2998 dev_err(scomp->dev, "error: expected tokens for DAI, none found\n"); |
3002 return -EINVAL; 3003 } 3004 3005 /* Send BE DAI link configurations to DSP */ 3006 memset(&config, 0, sizeof(config)); 3007 3008 /* get any common DAI tokens */ 3009 ret = sof_parse_tokens(scomp, &config, dai_link_tokens, 3010 ARRAY_SIZE(dai_link_tokens), private->array, 3011 le32_to_cpu(private->size)); 3012 if (ret != 0) { | 2999 return -EINVAL; 3000 } 3001 3002 /* Send BE DAI link configurations to DSP */ 3003 memset(&config, 0, sizeof(config)); 3004 3005 /* get any common DAI tokens */ 3006 ret = sof_parse_tokens(scomp, &config, dai_link_tokens, 3007 ARRAY_SIZE(dai_link_tokens), private->array, 3008 le32_to_cpu(private->size)); 3009 if (ret != 0) { |
3013 dev_err(sdev->dev, "error: parse link tokens failed %d\n", | 3010 dev_err(scomp->dev, "error: parse link tokens failed %d\n", |
3014 le32_to_cpu(private->size)); 3015 return ret; 3016 } 3017 3018 /* 3019 * DAI links are expected to have at least 1 hw_config. 3020 * But some older topologies might have no hw_config for HDA dai links. 3021 */ 3022 num_hw_configs = le32_to_cpu(cfg->num_hw_configs); 3023 if (!num_hw_configs) { 3024 if (config.type != SOF_DAI_INTEL_HDA) { | 3011 le32_to_cpu(private->size)); 3012 return ret; 3013 } 3014 3015 /* 3016 * DAI links are expected to have at least 1 hw_config. 3017 * But some older topologies might have no hw_config for HDA dai links. 3018 */ 3019 num_hw_configs = le32_to_cpu(cfg->num_hw_configs); 3020 if (!num_hw_configs) { 3021 if (config.type != SOF_DAI_INTEL_HDA) { |
3025 dev_err(sdev->dev, "error: unexpected DAI config count %d!\n", | 3022 dev_err(scomp->dev, "error: unexpected DAI config count %d!\n", |
3026 le32_to_cpu(cfg->num_hw_configs)); 3027 return -EINVAL; 3028 } 3029 } else { | 3023 le32_to_cpu(cfg->num_hw_configs)); 3024 return -EINVAL; 3025 } 3026 } else { |
3030 dev_dbg(sdev->dev, "tplg: %d hw_configs found, default id: %d!\n", | 3027 dev_dbg(scomp->dev, "tplg: %d hw_configs found, default id: %d!\n", |
3031 cfg->num_hw_configs, le32_to_cpu(cfg->default_hw_config_id)); 3032 3033 for (i = 0; i < num_hw_configs; i++) { 3034 if (cfg->hw_config[i].id == cfg->default_hw_config_id) 3035 break; 3036 } 3037 3038 if (i == num_hw_configs) { | 3028 cfg->num_hw_configs, le32_to_cpu(cfg->default_hw_config_id)); 3029 3030 for (i = 0; i < num_hw_configs; i++) { 3031 if (cfg->hw_config[i].id == cfg->default_hw_config_id) 3032 break; 3033 } 3034 3035 if (i == num_hw_configs) { |
3039 dev_err(sdev->dev, "error: default hw_config id: %d not found!\n", | 3036 dev_err(scomp->dev, "error: default hw_config id: %d not found!\n", |
3040 le32_to_cpu(cfg->default_hw_config_id)); 3041 return -EINVAL; 3042 } 3043 } 3044 3045 /* configure dai IPC message */ 3046 hw_config = &cfg->hw_config[i]; 3047 --- 22 unchanged lines hidden (view full) --- 3070 ret = sof_link_sai_load(scomp, index, link, cfg, hw_config, 3071 &config); 3072 break; 3073 case SOF_DAI_IMX_ESAI: 3074 ret = sof_link_esai_load(scomp, index, link, cfg, hw_config, 3075 &config); 3076 break; 3077 default: | 3037 le32_to_cpu(cfg->default_hw_config_id)); 3038 return -EINVAL; 3039 } 3040 } 3041 3042 /* configure dai IPC message */ 3043 hw_config = &cfg->hw_config[i]; 3044 --- 22 unchanged lines hidden (view full) --- 3067 ret = sof_link_sai_load(scomp, index, link, cfg, hw_config, 3068 &config); 3069 break; 3070 case SOF_DAI_IMX_ESAI: 3071 ret = sof_link_esai_load(scomp, index, link, cfg, hw_config, 3072 &config); 3073 break; 3074 default: |
3078 dev_err(sdev->dev, "error: invalid DAI type %d\n", config.type); | 3075 dev_err(scomp->dev, "error: invalid DAI type %d\n", 3076 config.type); |
3079 ret = -EINVAL; 3080 break; 3081 } 3082 if (ret < 0) 3083 return ret; 3084 3085 return 0; 3086} --- 31 unchanged lines hidden (view full) --- 3118 list_for_each_entry(sof_dai, &sdev->dai_list, list) { 3119 if (!sof_dai->name) 3120 continue; 3121 3122 if (strcmp(link->name, sof_dai->name) == 0) 3123 goto found; 3124 } 3125 | 3077 ret = -EINVAL; 3078 break; 3079 } 3080 if (ret < 0) 3081 return ret; 3082 3083 return 0; 3084} --- 31 unchanged lines hidden (view full) --- 3116 list_for_each_entry(sof_dai, &sdev->dai_list, list) { 3117 if (!sof_dai->name) 3118 continue; 3119 3120 if (strcmp(link->name, sof_dai->name) == 0) 3121 goto found; 3122 } 3123 |
3126 dev_err(sdev->dev, "error: failed to find dai %s in %s", | 3124 dev_err(scomp->dev, "error: failed to find dai %s in %s", |
3127 link->name, __func__); 3128 return -EINVAL; 3129found: 3130 3131 switch (sof_dai->dai_config->type) { 3132 case SOF_DAI_INTEL_SSP: 3133 case SOF_DAI_INTEL_DMIC: 3134 case SOF_DAI_INTEL_ALH: 3135 /* no resource needs to be released for SSP, DMIC and ALH */ 3136 break; 3137 case SOF_DAI_INTEL_HDA: 3138 ret = sof_link_hda_unload(sdev, link); 3139 break; 3140 default: | 3125 link->name, __func__); 3126 return -EINVAL; 3127found: 3128 3129 switch (sof_dai->dai_config->type) { 3130 case SOF_DAI_INTEL_SSP: 3131 case SOF_DAI_INTEL_DMIC: 3132 case SOF_DAI_INTEL_ALH: 3133 /* no resource needs to be released for SSP, DMIC and ALH */ 3134 break; 3135 case SOF_DAI_INTEL_HDA: 3136 ret = sof_link_hda_unload(sdev, link); 3137 break; 3138 default: |
3141 dev_err(sdev->dev, "error: invalid DAI type %d\n", | 3139 dev_err(scomp->dev, "error: invalid DAI type %d\n", |
3142 sof_dai->dai_config->type); 3143 ret = -EINVAL; 3144 break; 3145 } 3146 3147 return ret; 3148} 3149 --- 9 unchanged lines hidden (view full) --- 3159 struct sof_ipc_reply reply; 3160 int ret = 0; 3161 3162 /* allocate memory for sroute and connect */ 3163 sroute = kzalloc(sizeof(*sroute), GFP_KERNEL); 3164 if (!sroute) 3165 return -ENOMEM; 3166 | 3140 sof_dai->dai_config->type); 3141 ret = -EINVAL; 3142 break; 3143 } 3144 3145 return ret; 3146} 3147 --- 9 unchanged lines hidden (view full) --- 3157 struct sof_ipc_reply reply; 3158 int ret = 0; 3159 3160 /* allocate memory for sroute and connect */ 3161 sroute = kzalloc(sizeof(*sroute), GFP_KERNEL); 3162 if (!sroute) 3163 return -ENOMEM; 3164 |
3167 sroute->sdev = sdev; | 3165 sroute->scomp = scomp; |
3168 3169 connect = kzalloc(sizeof(*connect), GFP_KERNEL); 3170 if (!connect) { 3171 kfree(sroute); 3172 return -ENOMEM; 3173 } 3174 3175 connect->hdr.size = sizeof(*connect); 3176 connect->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_CONNECT; 3177 | 3166 3167 connect = kzalloc(sizeof(*connect), GFP_KERNEL); 3168 if (!connect) { 3169 kfree(sroute); 3170 return -ENOMEM; 3171 } 3172 3173 connect->hdr.size = sizeof(*connect); 3174 connect->hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_CONNECT; 3175 |
3178 dev_dbg(sdev->dev, "sink %s control %s source %s\n", | 3176 dev_dbg(scomp->dev, "sink %s control %s source %s\n", |
3179 route->sink, route->control ? route->control : "none", 3180 route->source); 3181 3182 /* source component */ | 3177 route->sink, route->control ? route->control : "none", 3178 route->source); 3179 3180 /* source component */ |
3183 source_swidget = snd_sof_find_swidget(sdev, (char *)route->source); | 3181 source_swidget = snd_sof_find_swidget(scomp, (char *)route->source); |
3184 if (!source_swidget) { | 3182 if (!source_swidget) { |
3185 dev_err(sdev->dev, "error: source %s not found\n", | 3183 dev_err(scomp->dev, "error: source %s not found\n", |
3186 route->source); 3187 ret = -EINVAL; 3188 goto err; 3189 } 3190 3191 /* 3192 * Virtual widgets of type output/out_drv may be added in topology 3193 * for compatibility. These are not handled by the FW. 3194 * So, don't send routes whose source/sink widget is of such types 3195 * to the DSP. 3196 */ 3197 if (source_swidget->id == snd_soc_dapm_out_drv || 3198 source_swidget->id == snd_soc_dapm_output) 3199 goto err; 3200 3201 connect->source_id = source_swidget->comp_id; 3202 3203 /* sink component */ | 3184 route->source); 3185 ret = -EINVAL; 3186 goto err; 3187 } 3188 3189 /* 3190 * Virtual widgets of type output/out_drv may be added in topology 3191 * for compatibility. These are not handled by the FW. 3192 * So, don't send routes whose source/sink widget is of such types 3193 * to the DSP. 3194 */ 3195 if (source_swidget->id == snd_soc_dapm_out_drv || 3196 source_swidget->id == snd_soc_dapm_output) 3197 goto err; 3198 3199 connect->source_id = source_swidget->comp_id; 3200 3201 /* sink component */ |
3204 sink_swidget = snd_sof_find_swidget(sdev, (char *)route->sink); | 3202 sink_swidget = snd_sof_find_swidget(scomp, (char *)route->sink); |
3205 if (!sink_swidget) { | 3203 if (!sink_swidget) { |
3206 dev_err(sdev->dev, "error: sink %s not found\n", | 3204 dev_err(scomp->dev, "error: sink %s not found\n", |
3207 route->sink); 3208 ret = -EINVAL; 3209 goto err; 3210 } 3211 3212 /* 3213 * Don't send routes whose sink widget is of type 3214 * output or out_drv to the DSP --- 7 unchanged lines hidden (view full) --- 3222 /* 3223 * For virtual routes, both sink and source are not 3224 * buffer. Since only buffer linked to component is supported by 3225 * FW, others are reported as error, add check in route function, 3226 * do not send it to FW when both source and sink are not buffer 3227 */ 3228 if (source_swidget->id != snd_soc_dapm_buffer && 3229 sink_swidget->id != snd_soc_dapm_buffer) { | 3205 route->sink); 3206 ret = -EINVAL; 3207 goto err; 3208 } 3209 3210 /* 3211 * Don't send routes whose sink widget is of type 3212 * output or out_drv to the DSP --- 7 unchanged lines hidden (view full) --- 3220 /* 3221 * For virtual routes, both sink and source are not 3222 * buffer. Since only buffer linked to component is supported by 3223 * FW, others are reported as error, add check in route function, 3224 * do not send it to FW when both source and sink are not buffer 3225 */ 3226 if (source_swidget->id != snd_soc_dapm_buffer && 3227 sink_swidget->id != snd_soc_dapm_buffer) { |
3230 dev_dbg(sdev->dev, "warning: neither Linked source component %s nor sink component %s is of buffer type, ignoring link\n", | 3228 dev_dbg(scomp->dev, "warning: neither Linked source component %s nor sink component %s is of buffer type, ignoring link\n", |
3231 route->source, route->sink); 3232 ret = 0; 3233 goto err; 3234 } else { 3235 ret = sof_ipc_tx_message(sdev->ipc, 3236 connect->hdr.cmd, 3237 connect, sizeof(*connect), 3238 &reply, sizeof(reply)); 3239 3240 /* check IPC return value */ 3241 if (ret < 0) { | 3229 route->source, route->sink); 3230 ret = 0; 3231 goto err; 3232 } else { 3233 ret = sof_ipc_tx_message(sdev->ipc, 3234 connect->hdr.cmd, 3235 connect, sizeof(*connect), 3236 &reply, sizeof(reply)); 3237 3238 /* check IPC return value */ 3239 if (ret < 0) { |
3242 dev_err(sdev->dev, "error: failed to add route sink %s control %s source %s\n", | 3240 dev_err(scomp->dev, "error: failed to add route sink %s control %s source %s\n", |
3243 route->sink, 3244 route->control ? route->control : "none", 3245 route->source); 3246 goto err; 3247 } 3248 3249 /* check IPC reply */ 3250 if (reply.error < 0) { | 3241 route->sink, 3242 route->control ? route->control : "none", 3243 route->source); 3244 goto err; 3245 } 3246 3247 /* check IPC reply */ 3248 if (reply.error < 0) { |
3251 dev_err(sdev->dev, "error: DSP failed to add route sink %s control %s source %s result %d\n", | 3249 dev_err(scomp->dev, "error: DSP failed to add route sink %s control %s source %s result %d\n", |
3252 route->sink, 3253 route->control ? route->control : "none", 3254 route->source, reply.error); 3255 ret = reply.error; 3256 goto err; 3257 } 3258 3259 sroute->route = route; --- 10 unchanged lines hidden (view full) --- 3270 kfree(connect); 3271 kfree(sroute); 3272 return ret; 3273} 3274 3275/* Function to set the initial value of SOF kcontrols. 3276 * The value will be stored in scontrol->control_data 3277 */ | 3250 route->sink, 3251 route->control ? route->control : "none", 3252 route->source, reply.error); 3253 ret = reply.error; 3254 goto err; 3255 } 3256 3257 sroute->route = route; --- 10 unchanged lines hidden (view full) --- 3268 kfree(connect); 3269 kfree(sroute); 3270 return ret; 3271} 3272 3273/* Function to set the initial value of SOF kcontrols. 3274 * The value will be stored in scontrol->control_data 3275 */ |
3278static int snd_sof_cache_kcontrol_val(struct snd_sof_dev *sdev) | 3276static int snd_sof_cache_kcontrol_val(struct snd_soc_component *scomp) |
3279{ | 3277{ |
3278 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); |
|
3280 struct snd_sof_control *scontrol = NULL; 3281 int ipc_cmd, ctrl_type; 3282 int ret = 0; 3283 3284 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 3285 3286 /* notify DSP of kcontrol values */ 3287 switch (scontrol->cmd) { 3288 case SOF_CTRL_CMD_VOLUME: 3289 case SOF_CTRL_CMD_ENUM: 3290 case SOF_CTRL_CMD_SWITCH: 3291 ipc_cmd = SOF_IPC_COMP_GET_VALUE; 3292 ctrl_type = SOF_CTRL_TYPE_VALUE_CHAN_GET; 3293 break; 3294 case SOF_CTRL_CMD_BINARY: 3295 ipc_cmd = SOF_IPC_COMP_GET_DATA; 3296 ctrl_type = SOF_CTRL_TYPE_DATA_GET; 3297 break; 3298 default: | 3279 struct snd_sof_control *scontrol = NULL; 3280 int ipc_cmd, ctrl_type; 3281 int ret = 0; 3282 3283 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 3284 3285 /* notify DSP of kcontrol values */ 3286 switch (scontrol->cmd) { 3287 case SOF_CTRL_CMD_VOLUME: 3288 case SOF_CTRL_CMD_ENUM: 3289 case SOF_CTRL_CMD_SWITCH: 3290 ipc_cmd = SOF_IPC_COMP_GET_VALUE; 3291 ctrl_type = SOF_CTRL_TYPE_VALUE_CHAN_GET; 3292 break; 3293 case SOF_CTRL_CMD_BINARY: 3294 ipc_cmd = SOF_IPC_COMP_GET_DATA; 3295 ctrl_type = SOF_CTRL_TYPE_DATA_GET; 3296 break; 3297 default: |
3299 dev_err(sdev->dev, | 3298 dev_err(scomp->dev, |
3300 "error: Invalid scontrol->cmd: %d\n", 3301 scontrol->cmd); 3302 return -EINVAL; 3303 } | 3299 "error: Invalid scontrol->cmd: %d\n", 3300 scontrol->cmd); 3301 return -EINVAL; 3302 } |
3304 ret = snd_sof_ipc_set_get_comp_data(sdev->ipc, scontrol, | 3303 ret = snd_sof_ipc_set_get_comp_data(scontrol, |
3305 ipc_cmd, ctrl_type, 3306 scontrol->cmd, 3307 false); 3308 if (ret < 0) { | 3304 ipc_cmd, ctrl_type, 3305 scontrol->cmd, 3306 false); 3307 if (ret < 0) { |
3309 dev_warn(sdev->dev, 3310 "error: kcontrol value get for widget: %d\n", 3311 scontrol->comp_id); | 3308 dev_warn(scomp->dev, 3309 "error: kcontrol value get for widget: %d\n", 3310 scontrol->comp_id); |
3312 } 3313 } 3314 3315 return ret; 3316} 3317 | 3311 } 3312 } 3313 3314 return ret; 3315} 3316 |
3318int snd_sof_complete_pipeline(struct snd_sof_dev *sdev, | 3317int snd_sof_complete_pipeline(struct device *dev, |
3319 struct snd_sof_widget *swidget) 3320{ | 3318 struct snd_sof_widget *swidget) 3319{ |
3320 struct snd_sof_dev *sdev = dev_get_drvdata(dev); |
|
3321 struct sof_ipc_pipe_ready ready; 3322 struct sof_ipc_reply reply; 3323 int ret; 3324 | 3321 struct sof_ipc_pipe_ready ready; 3322 struct sof_ipc_reply reply; 3323 int ret; 3324 |
3325 dev_dbg(sdev->dev, "tplg: complete pipeline %s id %d\n", | 3325 dev_dbg(dev, "tplg: complete pipeline %s id %d\n", |
3326 swidget->widget->name, swidget->comp_id); 3327 3328 memset(&ready, 0, sizeof(ready)); 3329 ready.hdr.size = sizeof(ready); 3330 ready.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_COMPLETE; 3331 ready.comp_id = swidget->comp_id; 3332 3333 ret = sof_ipc_tx_message(sdev->ipc, --- 13 unchanged lines hidden (view full) --- 3347 /* some widget types require completion notificattion */ 3348 list_for_each_entry(swidget, &sdev->widget_list, list) { 3349 if (swidget->complete) 3350 continue; 3351 3352 switch (swidget->id) { 3353 case snd_soc_dapm_scheduler: 3354 swidget->complete = | 3326 swidget->widget->name, swidget->comp_id); 3327 3328 memset(&ready, 0, sizeof(ready)); 3329 ready.hdr.size = sizeof(ready); 3330 ready.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_PIPE_COMPLETE; 3331 ready.comp_id = swidget->comp_id; 3332 3333 ret = sof_ipc_tx_message(sdev->ipc, --- 13 unchanged lines hidden (view full) --- 3347 /* some widget types require completion notificattion */ 3348 list_for_each_entry(swidget, &sdev->widget_list, list) { 3349 if (swidget->complete) 3350 continue; 3351 3352 switch (swidget->id) { 3353 case snd_soc_dapm_scheduler: 3354 swidget->complete = |
3355 snd_sof_complete_pipeline(sdev, swidget); | 3355 snd_sof_complete_pipeline(scomp->dev, swidget); |
3356 break; 3357 default: 3358 break; 3359 } 3360 } 3361 /* 3362 * cache initial values of SOF kcontrols by reading DSP value over 3363 * IPC. It may be overwritten by alsa-mixer after booting up 3364 */ | 3356 break; 3357 default: 3358 break; 3359 } 3360 } 3361 /* 3362 * cache initial values of SOF kcontrols by reading DSP value over 3363 * IPC. It may be overwritten by alsa-mixer after booting up 3364 */ |
3365 snd_sof_cache_kcontrol_val(sdev); | 3365 snd_sof_cache_kcontrol_val(scomp); |
3366} 3367 3368/* manifest - optional to inform component of manifest */ 3369static int sof_manifest(struct snd_soc_component *scomp, int index, 3370 struct snd_soc_tplg_manifest *man) 3371{ | 3366} 3367 3368/* manifest - optional to inform component of manifest */ 3369static int sof_manifest(struct snd_soc_component *scomp, int index, 3370 struct snd_soc_tplg_manifest *man) 3371{ |
3372 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); | |
3373 u32 size; 3374 u32 abi_version; 3375 3376 size = le32_to_cpu(man->priv.size); 3377 3378 /* backward compatible with tplg without ABI info */ 3379 if (!size) { | 3372 u32 size; 3373 u32 abi_version; 3374 3375 size = le32_to_cpu(man->priv.size); 3376 3377 /* backward compatible with tplg without ABI info */ 3378 if (!size) { |
3380 dev_dbg(sdev->dev, "No topology ABI info\n"); | 3379 dev_dbg(scomp->dev, "No topology ABI info\n"); |
3381 return 0; 3382 } 3383 3384 if (size != SOF_TPLG_ABI_SIZE) { | 3380 return 0; 3381 } 3382 3383 if (size != SOF_TPLG_ABI_SIZE) { |
3385 dev_err(sdev->dev, "error: invalid topology ABI size\n"); | 3384 dev_err(scomp->dev, "error: invalid topology ABI size\n"); |
3386 return -EINVAL; 3387 } 3388 | 3385 return -EINVAL; 3386 } 3387 |
3389 dev_info(sdev->dev, | 3388 dev_info(scomp->dev, |
3390 "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", 3391 man->priv.data[0], man->priv.data[1], 3392 man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, 3393 SOF_ABI_PATCH); 3394 3395 abi_version = SOF_ABI_VER(man->priv.data[0], 3396 man->priv.data[1], 3397 man->priv.data[2]); 3398 3399 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { | 3389 "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", 3390 man->priv.data[0], man->priv.data[1], 3391 man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, 3392 SOF_ABI_PATCH); 3393 3394 abi_version = SOF_ABI_VER(man->priv.data[0], 3395 man->priv.data[1], 3396 man->priv.data[2]); 3397 3398 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { |
3400 dev_err(sdev->dev, "error: incompatible topology ABI version\n"); | 3399 dev_err(scomp->dev, "error: incompatible topology ABI version\n"); |
3401 return -EINVAL; 3402 } 3403 3404 if (abi_version > SOF_ABI_VERSION) { 3405 if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { | 3400 return -EINVAL; 3401 } 3402 3403 if (abi_version > SOF_ABI_VERSION) { 3404 if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { |
3406 dev_warn(sdev->dev, "warn: topology ABI is more recent than kernel\n"); | 3405 dev_warn(scomp->dev, "warn: topology ABI is more recent than kernel\n"); |
3407 } else { | 3406 } else { |
3408 dev_err(sdev->dev, "error: topology ABI is more recent than kernel\n"); | 3407 dev_err(scomp->dev, "error: topology ABI is more recent than kernel\n"); |
3409 return -EINVAL; 3410 } 3411 } 3412 3413 return 0; 3414} 3415 3416/* vendor specific kcontrol handlers available for binding */ --- 41 unchanged lines hidden (view full) --- 3458 .io_ops = sof_io_ops, 3459 .io_ops_count = ARRAY_SIZE(sof_io_ops), 3460 3461 /* vendor specific bytes ext handlers available for binding */ 3462 .bytes_ext_ops = sof_bytes_ext_ops, 3463 .bytes_ext_ops_count = ARRAY_SIZE(sof_bytes_ext_ops), 3464}; 3465 | 3408 return -EINVAL; 3409 } 3410 } 3411 3412 return 0; 3413} 3414 3415/* vendor specific kcontrol handlers available for binding */ --- 41 unchanged lines hidden (view full) --- 3457 .io_ops = sof_io_ops, 3458 .io_ops_count = ARRAY_SIZE(sof_io_ops), 3459 3460 /* vendor specific bytes ext handlers available for binding */ 3461 .bytes_ext_ops = sof_bytes_ext_ops, 3462 .bytes_ext_ops_count = ARRAY_SIZE(sof_bytes_ext_ops), 3463}; 3464 |
3466int snd_sof_load_topology(struct snd_sof_dev *sdev, const char *file) | 3465int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) |
3467{ 3468 const struct firmware *fw; 3469 int ret; 3470 | 3466{ 3467 const struct firmware *fw; 3468 int ret; 3469 |
3471 dev_dbg(sdev->dev, "loading topology:%s\n", file); | 3470 dev_dbg(scomp->dev, "loading topology:%s\n", file); |
3472 | 3471 |
3473 ret = request_firmware(&fw, file, sdev->dev); | 3472 ret = request_firmware(&fw, file, scomp->dev); |
3474 if (ret < 0) { | 3473 if (ret < 0) { |
3475 dev_err(sdev->dev, "error: tplg request firmware %s failed err: %d\n", | 3474 dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n", |
3476 file, ret); 3477 return ret; 3478 } 3479 | 3475 file, ret); 3476 return ret; 3477 } 3478 |
3480 ret = snd_soc_tplg_component_load(sdev->component, | 3479 ret = snd_soc_tplg_component_load(scomp, |
3481 &sof_tplg_ops, fw, 3482 SND_SOC_TPLG_INDEX_ALL); 3483 if (ret < 0) { | 3480 &sof_tplg_ops, fw, 3481 SND_SOC_TPLG_INDEX_ALL); 3482 if (ret < 0) { |
3484 dev_err(sdev->dev, "error: tplg component load failed %d\n", | 3483 dev_err(scomp->dev, "error: tplg component load failed %d\n", |
3485 ret); 3486 ret = -EINVAL; 3487 } 3488 3489 release_firmware(fw); 3490 return ret; 3491} 3492EXPORT_SYMBOL(snd_sof_load_topology); | 3484 ret); 3485 ret = -EINVAL; 3486 } 3487 3488 release_firmware(fw); 3489 return ret; 3490} 3491EXPORT_SYMBOL(snd_sof_load_topology); |