View | Details | Raw Unified | Return to bug 219654
Collapse All | Expand All

(-)a/sound/soc/intel/avs/path.c (+130 lines)
Lines 115-120 avs_path_find_variant(struct avs_dev *adev, Link Here
115
	return NULL;
115
	return NULL;
116
}
116
}
117
117
118
/* Every BLOB contains at least gateway attributes. */
119
static struct acpi_nhlt_config *default_blob = (struct acpi_nhlt_config *)&(u32[2]) {4};
120
121
static struct acpi_nhlt_config *
122
avs_nhlt_config_or_default(struct avs_dev *adev, struct avs_tplg_module *t)
123
{
124
        struct acpi_nhlt_format_config *fmtcfg;
125
        struct avs_tplg_modcfg_ext *te;
126
        struct avs_audio_format *fmt;
127
        int link_type, dev_type;
128
        int bus_id, dir;
129
130
        te = t->cfg_ext;
131
132
        switch (te->copier.dma_type) {
133
        case AVS_DMA_I2S_LINK_OUTPUT:
134
                link_type = ACPI_NHLT_LINKTYPE_SSP;
135
                dev_type = ACPI_NHLT_DEVICETYPE_CODEC;
136
                bus_id = te->copier.vindex.i2s.instance;
137
                dir = SNDRV_PCM_STREAM_PLAYBACK;
138
                fmt = te->copier.out_fmt;
139
                break;
140
141
        case AVS_DMA_I2S_LINK_INPUT:
142
                link_type = ACPI_NHLT_LINKTYPE_SSP;
143
                dev_type = ACPI_NHLT_DEVICETYPE_CODEC;
144
                bus_id = te->copier.vindex.i2s.instance;
145
                dir = SNDRV_PCM_STREAM_CAPTURE;
146
                fmt = t->in_fmt;
147
                break;
148
149
        case AVS_DMA_DMIC_LINK_INPUT:
150
                link_type = ACPI_NHLT_LINKTYPE_PDM;
151
                dev_type = -1; /* ignored */
152
                bus_id = 0;
153
                dir = SNDRV_PCM_STREAM_CAPTURE;
154
                fmt = t->in_fmt;
155
                break;
156
157
        default:
158
                return default_blob;
159
        }
160
161
        /* Override format selection if necessary. */
162
        if (te->copier.blob_fmt)
163
                fmt = te->copier.blob_fmt;
164
165
        fmtcfg = acpi_nhlt_find_fmtcfg(link_type, dev_type, dir, bus_id,
166
                                       fmt->num_channels, fmt->sampling_freq, fmt->valid_bit_depth,
167
                                       fmt->bit_depth);
168
        if (!fmtcfg) {
169
                dev_warn(adev->dev, "Endpoint format configuration not found.\n");
170
                return ERR_PTR(-ENOENT);
171
        }
172
173
        if (fmtcfg->config.capabilities_size < default_blob->capabilities_size)
174
                return ERR_PTR(-ETOOSMALL);
175
        /* The firmware expects the payload to be DWORD-aligned. */
176
        if (fmtcfg->config.capabilities_size % sizeof(u32))
177
                return ERR_PTR(-EINVAL);
178
179
        return &fmtcfg->config;
180
}
181
182
int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template *template,
183
			    struct snd_pcm_hw_constraint_list *rate_list,
184
			    struct snd_pcm_hw_constraint_list *channels_list,
185
			    struct snd_pcm_hw_constraint_list *sample_bits_list)
186
{
187
	struct avs_tplg_path *path_template;
188
	unsigned int *rlist, *clist, *slist;
189
	size_t i;
190
191
	i = 0;
192
	list_for_each_entry(path_template, &template->path_list, node)
193
		i++;
194
195
	rlist = kzalloc(sizeof(rlist) * i, GFP_KERNEL);
196
	clist = kzalloc(sizeof(clist) * i, GFP_KERNEL);
197
	slist = kzalloc(sizeof(slist) * i, GFP_KERNEL);
198
199
	i = 0;
200
	list_for_each_entry(path_template, &template->path_list, node) {
201
		struct avs_tplg_pipeline *pipeline_template;
202
		list_for_each_entry(pipeline_template, &path_template->ppl_list, node) {
203
			struct avs_tplg_module *module_template;
204
			list_for_each_entry(module_template, &pipeline_template->mod_list, node) {
205
				const guid_t *type = &module_template->cfg_ext->type;
206
				struct acpi_nhlt_config *blob;
207
208
				if (!guid_equal(type, &AVS_COPIER_MOD_UUID))
209
					continue;
210
211
				if (module_template->cfg_ext->copier.dma_type == INVALID_OBJECT_ID)
212
					continue;
213
214
				if (!(module_template->cfg_ext->copier.dma_type == AVS_DMA_DMIC_LINK_INPUT) &&
215
				    !(module_template->cfg_ext->copier.dma_type == AVS_DMA_I2S_LINK_OUTPUT) &&
216
				    !(module_template->cfg_ext->copier.dma_type == AVS_DMA_I2S_LINK_INPUT))
217
					continue;
218
219
				blob = avs_nhlt_config_or_default(adev, module_template);
220
				if (IS_ERR(blob))
221
					continue;
222
223
				rlist[i] = path_template->fe_fmt->sampling_freq;
224
				clist[i] = path_template->fe_fmt->num_channels;
225
				slist[i] = path_template->fe_fmt->bit_depth;
226
227
				i++;
228
			}
229
		}
230
	}
231
232
	if (i) {
233
		rate_list->count = i;
234
		rate_list->list = rlist;
235
		channels_list->count = i;
236
		channels_list->list = clist;
237
		sample_bits_list->count = i;
238
		sample_bits_list->list = slist;
239
	} else {
240
		kfree(rlist);
241
		kfree(clist);
242
		kfree(slist);
243
	}
244
245
	return i;
246
}
247
118
__maybe_unused
248
__maybe_unused
119
static bool avs_dma_type_is_host(u32 dma_type)
249
static bool avs_dma_type_is_host(u32 dma_type)
120
{
250
{
(-)a/sound/soc/intel/avs/path.h (+5 lines)
Lines 69-72 int avs_path_reset(struct avs_path *path); Link Here
69
int avs_path_pause(struct avs_path *path);
69
int avs_path_pause(struct avs_path *path);
70
int avs_path_run(struct avs_path *path, int trigger);
70
int avs_path_run(struct avs_path *path, int trigger);
71
71
72
int avs_path_set_constraint(struct avs_dev *adev, struct avs_tplg_path_template *template,
73
			    struct snd_pcm_hw_constraint_list *rate_list,
74
			    struct snd_pcm_hw_constraint_list *channels_list,
75
			    struct snd_pcm_hw_constraint_list *sample_bits_list);
76
72
#endif
77
#endif
(-)a/sound/soc/intel/avs/pcm.c (-2 / +50 lines)
Lines 31-36 struct avs_dma_data { Link Here
31
		struct hdac_ext_stream *host_stream;
31
		struct hdac_ext_stream *host_stream;
32
	};
32
	};
33
33
34
	struct snd_pcm_hw_constraint_list rate_list;
35
	struct snd_pcm_hw_constraint_list channels_list;
36
	struct snd_pcm_hw_constraint_list sample_bits_list;
37
34
	struct work_struct period_elapsed_work;
38
	struct work_struct period_elapsed_work;
35
	struct snd_pcm_substream *substream;
39
	struct snd_pcm_substream *substream;
36
};
40
};
Lines 74-79 void avs_period_elapsed(struct snd_pcm_substream *substream) Link Here
74
	schedule_work(&data->period_elapsed_work);
78
	schedule_work(&data->period_elapsed_work);
75
}
79
}
76
80
81
static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
82
static int avs_hw_constraints_init(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
83
{
84
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
85
	struct snd_pcm_runtime *runtime = substream->runtime;
86
	int ret;
87
88
	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
89
	if (ret < 0)
90
		goto out;
91
92
	struct avs_dma_data *data;
93
	struct avs_tplg_path_template *template;
94
	struct snd_pcm_hw_constraint_list *r, *c, *s;
95
96
	data = snd_soc_dai_get_dma_data(dai, substream);
97
	r = &(data->rate_list);
98
	c = &(data->channels_list);
99
	s = &(data->sample_bits_list);
100
101
	template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
102
	ret = avs_path_set_constraint(data->adev, template, r, c, s);
103
	if (ret <= 0)
104
		goto out;
105
106
	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, r);
107
	if (ret < 0)
108
		goto out;
109
110
	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, c);
111
	if (ret < 0)
112
		goto out;
113
114
	ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, s);
115
	if (ret < 0)
116
		goto out;
117
118
out:
119
	return ret;
120
}
121
77
static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
122
static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
78
{
123
{
79
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
124
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
Lines 101-107 static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d Link Here
101
	if (rtd->dai_link->ignore_suspend)
146
	if (rtd->dai_link->ignore_suspend)
102
		adev->num_lp_paths++;
147
		adev->num_lp_paths++;
103
148
104
	return 0;
149
	return avs_hw_constraints_init(substream, dai);
105
}
150
}
106
151
107
static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
152
static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
Lines 114-119 static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc Link Here
114
	if (rtd->dai_link->ignore_suspend)
159
	if (rtd->dai_link->ignore_suspend)
115
		data->adev->num_lp_paths--;
160
		data->adev->num_lp_paths--;
116
161
162
	kfree(data->rate_list.list);
163
	kfree(data->channels_list.list);
164
	kfree(data->sample_bits_list.list);
165
117
	snd_soc_dai_set_dma_data(dai, substream, NULL);
166
	snd_soc_dai_set_dma_data(dai, substream, NULL);
118
	kfree(data);
167
	kfree(data);
119
}
168
}
120
- 

Return to bug 219654