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);