xref: /linux/sound/soc/intel/catpt/pcm.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2020 Intel Corporation
4 //
5 // Author: Cezary Rojewski <cezary.rojewski@intel.com>
6 //
7 
8 #include <linux/cleanup.h>
9 #include <linux/pm_runtime.h>
10 #include <sound/soc.h>
11 #include <sound/pcm_params.h>
12 #include <uapi/sound/tlv.h>
13 #include "core.h"
14 #include "messages.h"
15 
16 struct catpt_stream_template {
17 	enum catpt_path_id path_id;
18 	enum catpt_stream_type type;
19 	u32 persistent_size;
20 	u8 num_entries;
21 	struct catpt_module_entry entries[];
22 };
23 
24 static struct catpt_stream_template system_pb = {
25 	.path_id = CATPT_PATH_SSP0_OUT,
26 	.type = CATPT_STRM_TYPE_SYSTEM,
27 	.num_entries = 1,
28 	.entries = {{ CATPT_MODID_PCM_SYSTEM, 0 }},
29 };
30 
31 static struct catpt_stream_template system_cp = {
32 	.path_id = CATPT_PATH_SSP0_IN,
33 	.type = CATPT_STRM_TYPE_CAPTURE,
34 	.num_entries = 1,
35 	.entries = {{ CATPT_MODID_PCM_CAPTURE, 0 }},
36 };
37 
38 static struct catpt_stream_template offload_pb = {
39 	.path_id = CATPT_PATH_SSP0_OUT,
40 	.type = CATPT_STRM_TYPE_RENDER,
41 	.num_entries = 1,
42 	.entries = {{ CATPT_MODID_PCM, 0 }},
43 };
44 
45 static struct catpt_stream_template loopback_cp = {
46 	.path_id = CATPT_PATH_SSP0_OUT,
47 	.type = CATPT_STRM_TYPE_LOOPBACK,
48 	.num_entries = 1,
49 	.entries = {{ CATPT_MODID_PCM_REFERENCE, 0 }},
50 };
51 
52 static struct catpt_stream_template bluetooth_pb = {
53 	.path_id = CATPT_PATH_SSP1_OUT,
54 	.type = CATPT_STRM_TYPE_BLUETOOTH_RENDER,
55 	.num_entries = 1,
56 	.entries = {{ CATPT_MODID_BLUETOOTH_RENDER, 0 }},
57 };
58 
59 static struct catpt_stream_template bluetooth_cp = {
60 	.path_id = CATPT_PATH_SSP1_IN,
61 	.type = CATPT_STRM_TYPE_BLUETOOTH_CAPTURE,
62 	.num_entries = 1,
63 	.entries = {{ CATPT_MODID_BLUETOOTH_CAPTURE, 0 }},
64 };
65 
66 static struct catpt_stream_template *catpt_topology[] = {
67 	[CATPT_STRM_TYPE_RENDER]		= &offload_pb,
68 	[CATPT_STRM_TYPE_SYSTEM]		= &system_pb,
69 	[CATPT_STRM_TYPE_CAPTURE]		= &system_cp,
70 	[CATPT_STRM_TYPE_LOOPBACK]		= &loopback_cp,
71 	[CATPT_STRM_TYPE_BLUETOOTH_RENDER]	= &bluetooth_pb,
72 	[CATPT_STRM_TYPE_BLUETOOTH_CAPTURE]	= &bluetooth_cp,
73 };
74 
75 static struct catpt_stream_template *
76 catpt_get_stream_template(struct snd_pcm_substream *substream)
77 {
78 	struct snd_soc_pcm_runtime *rtm = snd_soc_substream_to_rtd(substream);
79 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtm, 0);
80 	enum catpt_stream_type type;
81 
82 	type = cpu_dai->driver->id;
83 
84 	/* account for capture in bidirectional dais */
85 	switch (type) {
86 	case CATPT_STRM_TYPE_SYSTEM:
87 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
88 			type = CATPT_STRM_TYPE_CAPTURE;
89 		break;
90 	case CATPT_STRM_TYPE_BLUETOOTH_RENDER:
91 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
92 			type = CATPT_STRM_TYPE_BLUETOOTH_CAPTURE;
93 		break;
94 	default:
95 		break;
96 	}
97 
98 	return catpt_topology[type];
99 }
100 
101 /* Caller responsible for holding ->stream_mutex. */
102 struct catpt_stream_runtime *
103 catpt_stream_find(struct catpt_dev *cdev, u8 stream_hw_id)
104 {
105 	struct catpt_stream_runtime *pos, *result = NULL;
106 
107 	list_for_each_entry(pos, &cdev->stream_list, node) {
108 		if (pos->info.stream_hw_id == stream_hw_id) {
109 			result = pos;
110 			break;
111 		}
112 	}
113 
114 	return result;
115 }
116 
117 /* Caller responsible for holding ->stream_mutex. */
118 static u8 catpt_stream_hw_id(struct catpt_dev *cdev, enum catpt_pin_id pin_id)
119 {
120 	struct catpt_stream_runtime *stream;
121 
122 	switch (pin_id) {
123 	default:
124 		stream = catpt_stream_find(cdev, pin_id);
125 		if (stream)
126 			return stream->info.stream_hw_id;
127 		break;
128 	case CATPT_PIN_ID_MIXER:
129 		if (!list_empty(&cdev->stream_list))
130 			return cdev->mixer.mixer_hw_id;
131 		break;
132 	}
133 
134 	return CATPT_PIN_ID_INVALID;
135 }
136 
137 /* Caller responsible for holding ->stream_mutex. */
138 static u32 *catpt_stream_volume_regs(struct catpt_dev *cdev, enum catpt_pin_id pin_id)
139 {
140 	struct catpt_stream_runtime *stream;
141 
142 	switch (pin_id) {
143 	case CATPT_PIN_ID_MIXER:
144 		if (!list_empty(&cdev->stream_list))
145 			return &cdev->mixer.volume_regaddr[0];
146 		break;
147 	default:
148 		stream = catpt_stream_find(cdev, pin_id);
149 		if (stream)
150 			return &stream->info.volume_regaddr[0];
151 		break;
152 	}
153 
154 	return NULL;
155 }
156 
157 static void catpt_stream_read_position(struct catpt_dev *cdev,
158 				       struct catpt_stream_runtime *stream, u32 *pos)
159 {
160 	memcpy_fromio(pos, cdev->lpe_ba + stream->info.read_pos_regaddr, sizeof(*pos));
161 }
162 
163 static void catpt_arrange_page_table(struct snd_pcm_substream *substream,
164 				     struct snd_dma_buffer *pgtbl)
165 {
166 	struct snd_pcm_runtime *rtm = substream->runtime;
167 	struct snd_dma_buffer *databuf = snd_pcm_get_dma_buf(substream);
168 	int i, pages;
169 
170 	pages = snd_sgbuf_aligned_pages(rtm->dma_bytes);
171 
172 	for (i = 0; i < pages; i++) {
173 		u32 pfn, offset;
174 		u32 *page_table;
175 
176 		pfn = PFN_DOWN(snd_sgbuf_get_addr(databuf, i * PAGE_SIZE));
177 		/* incrementing by 2 on even and 3 on odd */
178 		offset = ((i << 2) + i) >> 1;
179 		page_table = (u32 *)(pgtbl->area + offset);
180 
181 		if (i & 1)
182 			*page_table |= (pfn << 4);
183 		else
184 			*page_table |= pfn;
185 	}
186 }
187 
188 static u32 catpt_get_channel_map(enum catpt_channel_config config)
189 {
190 	switch (config) {
191 	case CATPT_CHANNEL_CONFIG_MONO:
192 		return GENMASK(31, 4) | CATPT_CHANNEL_CENTER;
193 
194 	case CATPT_CHANNEL_CONFIG_STEREO:
195 		return GENMASK(31, 8) | CATPT_CHANNEL_LEFT
196 				      | (CATPT_CHANNEL_RIGHT << 4);
197 
198 	case CATPT_CHANNEL_CONFIG_2_POINT_1:
199 		return GENMASK(31, 12) | CATPT_CHANNEL_LEFT
200 				       | (CATPT_CHANNEL_RIGHT << 4)
201 				       | (CATPT_CHANNEL_LFE << 8);
202 
203 	case CATPT_CHANNEL_CONFIG_3_POINT_0:
204 		return GENMASK(31, 12) | CATPT_CHANNEL_LEFT
205 				       | (CATPT_CHANNEL_CENTER << 4)
206 				       | (CATPT_CHANNEL_RIGHT << 8);
207 
208 	case CATPT_CHANNEL_CONFIG_3_POINT_1:
209 		return GENMASK(31, 16) | CATPT_CHANNEL_LEFT
210 				       | (CATPT_CHANNEL_CENTER << 4)
211 				       | (CATPT_CHANNEL_RIGHT << 8)
212 				       | (CATPT_CHANNEL_LFE << 12);
213 
214 	case CATPT_CHANNEL_CONFIG_QUATRO:
215 		return GENMASK(31, 16) | CATPT_CHANNEL_LEFT
216 				       | (CATPT_CHANNEL_RIGHT << 4)
217 				       | (CATPT_CHANNEL_LEFT_SURROUND << 8)
218 				       | (CATPT_CHANNEL_RIGHT_SURROUND << 12);
219 
220 	case CATPT_CHANNEL_CONFIG_4_POINT_0:
221 		return GENMASK(31, 16) | CATPT_CHANNEL_LEFT
222 				       | (CATPT_CHANNEL_CENTER << 4)
223 				       | (CATPT_CHANNEL_RIGHT << 8)
224 				       | (CATPT_CHANNEL_CENTER_SURROUND << 12);
225 
226 	case CATPT_CHANNEL_CONFIG_5_POINT_0:
227 		return GENMASK(31, 20) | CATPT_CHANNEL_LEFT
228 				       | (CATPT_CHANNEL_CENTER << 4)
229 				       | (CATPT_CHANNEL_RIGHT << 8)
230 				       | (CATPT_CHANNEL_LEFT_SURROUND << 12)
231 				       | (CATPT_CHANNEL_RIGHT_SURROUND << 16);
232 
233 	case CATPT_CHANNEL_CONFIG_5_POINT_1:
234 		return GENMASK(31, 24) | CATPT_CHANNEL_CENTER
235 				       | (CATPT_CHANNEL_LEFT << 4)
236 				       | (CATPT_CHANNEL_RIGHT << 8)
237 				       | (CATPT_CHANNEL_LEFT_SURROUND << 12)
238 				       | (CATPT_CHANNEL_RIGHT_SURROUND << 16)
239 				       | (CATPT_CHANNEL_LFE << 20);
240 
241 	case CATPT_CHANNEL_CONFIG_DUAL_MONO:
242 		return GENMASK(31, 8) | CATPT_CHANNEL_LEFT
243 				      | (CATPT_CHANNEL_LEFT << 4);
244 
245 	default:
246 		return U32_MAX;
247 	}
248 }
249 
250 static enum catpt_channel_config catpt_get_channel_config(u32 num_channels)
251 {
252 	switch (num_channels) {
253 	case 6:
254 		return CATPT_CHANNEL_CONFIG_5_POINT_1;
255 	case 5:
256 		return CATPT_CHANNEL_CONFIG_5_POINT_0;
257 	case 4:
258 		return CATPT_CHANNEL_CONFIG_QUATRO;
259 	case 3:
260 		return CATPT_CHANNEL_CONFIG_2_POINT_1;
261 	case 1:
262 		return CATPT_CHANNEL_CONFIG_MONO;
263 	case 2:
264 	default:
265 		return CATPT_CHANNEL_CONFIG_STEREO;
266 	}
267 }
268 
269 static int catpt_dai_startup(struct snd_pcm_substream *substream,
270 			     struct snd_soc_dai *dai)
271 {
272 	struct catpt_stream_template *template;
273 	struct catpt_stream_runtime *stream;
274 	struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
275 	struct resource *res;
276 	int ret;
277 
278 	template = catpt_get_stream_template(substream);
279 
280 	stream = kzalloc_obj(*stream);
281 	if (!stream)
282 		return -ENOMEM;
283 
284 	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, cdev->dev, PAGE_SIZE,
285 				  &stream->pgtbl);
286 	if (ret)
287 		goto err_pgtbl;
288 
289 	res = catpt_request_region(&cdev->dram, template->persistent_size);
290 	if (!res) {
291 		ret = -EBUSY;
292 		goto err_request;
293 	}
294 
295 	catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask);
296 
297 	stream->template = template;
298 	stream->persistent = res;
299 	stream->substream = substream;
300 	INIT_LIST_HEAD(&stream->node);
301 	snd_soc_dai_set_dma_data(dai, substream, stream);
302 
303 	return 0;
304 
305 err_request:
306 	snd_dma_free_pages(&stream->pgtbl);
307 err_pgtbl:
308 	kfree(stream);
309 	return ret;
310 }
311 
312 static void catpt_dai_shutdown(struct snd_pcm_substream *substream,
313 			       struct snd_soc_dai *dai)
314 {
315 	struct catpt_stream_runtime *stream;
316 	struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
317 
318 	stream = snd_soc_dai_get_dma_data(dai, substream);
319 
320 	release_resource(stream->persistent);
321 	kfree(stream->persistent);
322 	catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask);
323 
324 	snd_dma_free_pages(&stream->pgtbl);
325 	kfree(stream);
326 	snd_soc_dai_set_dma_data(dai, substream, NULL);
327 }
328 
329 static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol);
330 
331 struct catpt_control_data {
332 	enum catpt_pin_id pin_id;
333 	long volumes[CATPT_CHANNELS_MAX];
334 };
335 
336 static int catpt_apply_volume(struct catpt_dev *cdev, struct snd_soc_card *card, const char *name)
337 {
338 	struct snd_kcontrol *kctl = snd_ctl_find_id_mixer(card->snd_card, name);
339 	struct catpt_control_data *data;
340 
341 	if (!kctl)
342 		return -ENOENT;
343 	data = (struct catpt_control_data *)kctl->private_value;
344 
345 	return catpt_set_dspvol(cdev, data->pin_id, data->volumes);
346 }
347 
348 static int catpt_apply_mute(struct catpt_dev *cdev, struct snd_soc_card *card)
349 {
350 	struct snd_kcontrol *kctl = snd_ctl_find_id_mixer(card->snd_card, "Loopback Mute");
351 	bool mute;
352 	int ret;
353 
354 	if (!kctl)
355 		return -ENOENT;
356 	mute = *(bool *)kctl->private_value;
357 
358 	ret = catpt_ipc_mute_loopback(cdev, CATPT_PIN_ID_REFERENCE, mute);
359 	return CATPT_IPC_RET(ret);
360 }
361 
362 static int catpt_apply_controls(struct catpt_dev *cdev, struct snd_soc_card *card,
363 				struct catpt_stream_runtime *stream)
364 {
365 	int ret;
366 
367 	/* Update the master volume when the first stream is opened. */
368 	if (list_empty(&cdev->stream_list)) {
369 		ret = catpt_apply_volume(cdev, card, "Master Playback Volume");
370 		if (ret)
371 			return ret;
372 	}
373 
374 	/* Only selected streams have individual controls. */
375 	switch (stream->info.stream_hw_id) {
376 	case CATPT_PIN_ID_OFFLOAD1:
377 		return catpt_apply_volume(cdev, card, "Media0 Playback Volume");
378 	case CATPT_PIN_ID_OFFLOAD2:
379 		return catpt_apply_volume(cdev, card, "Media1 Playback Volume");
380 	case CATPT_PIN_ID_CAPTURE1:
381 		return catpt_apply_volume(cdev, card, "Mic Capture Volume");
382 	case CATPT_PIN_ID_REFERENCE:
383 		return catpt_apply_mute(cdev, card);
384 	default:
385 		return 0;
386 	}
387 }
388 
389 static int catpt_dai_hw_params(struct snd_pcm_substream *substream,
390 			       struct snd_pcm_hw_params *params,
391 			       struct snd_soc_dai *dai)
392 {
393 	struct snd_pcm_runtime *rtm = substream->runtime;
394 	struct snd_dma_buffer *dmab;
395 	struct catpt_stream_runtime *stream;
396 	struct catpt_audio_format afmt;
397 	struct catpt_ring_info rinfo;
398 	struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
399 	int ret;
400 
401 	stream = snd_soc_dai_get_dma_data(dai, substream);
402 	if (stream->allocated)
403 		return 0;
404 
405 	memset(&afmt, 0, sizeof(afmt));
406 	afmt.sample_rate = params_rate(params);
407 	afmt.bit_depth = params_physical_width(params);
408 	afmt.valid_bit_depth = params_width(params);
409 	afmt.num_channels = params_channels(params);
410 	afmt.channel_config = catpt_get_channel_config(afmt.num_channels);
411 	afmt.channel_map = catpt_get_channel_map(afmt.channel_config);
412 	afmt.interleaving = CATPT_INTERLEAVING_PER_CHANNEL;
413 
414 	dmab = snd_pcm_get_dma_buf(substream);
415 	catpt_arrange_page_table(substream, &stream->pgtbl);
416 
417 	memset(&rinfo, 0, sizeof(rinfo));
418 	rinfo.page_table_addr = stream->pgtbl.addr;
419 	rinfo.num_pages = DIV_ROUND_UP(rtm->dma_bytes, PAGE_SIZE);
420 	rinfo.size = rtm->dma_bytes;
421 	rinfo.offset = 0;
422 	rinfo.ring_first_page_pfn = PFN_DOWN(snd_sgbuf_get_addr(dmab, 0));
423 
424 	ret = catpt_ipc_alloc_stream(cdev, stream->template->path_id,
425 				     stream->template->type,
426 				     &afmt, &rinfo,
427 				     stream->template->num_entries,
428 				     stream->template->entries,
429 				     stream->persistent,
430 				     cdev->scratch,
431 				     &stream->info);
432 	if (ret)
433 		return CATPT_IPC_RET(ret);
434 
435 	guard(mutex)(&cdev->stream_mutex);
436 
437 	ret = catpt_apply_controls(cdev, dai->component->card, stream);
438 	if (ret) {
439 		catpt_ipc_free_stream(cdev, stream->info.stream_hw_id);
440 		return ret;
441 	}
442 
443 	list_add_tail(&stream->node, &cdev->stream_list);
444 	stream->allocated = true;
445 	return 0;
446 }
447 
448 static int catpt_dai_hw_free(struct snd_pcm_substream *substream,
449 			     struct snd_soc_dai *dai)
450 {
451 	struct catpt_stream_runtime *stream;
452 	struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
453 
454 	stream = snd_soc_dai_get_dma_data(dai, substream);
455 	if (!stream->allocated)
456 		return 0;
457 
458 	mutex_lock(&cdev->stream_mutex);
459 	list_del(&stream->node);
460 	mutex_unlock(&cdev->stream_mutex);
461 
462 	catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id);
463 	catpt_ipc_free_stream(cdev, stream->info.stream_hw_id);
464 
465 	stream->allocated = false;
466 	return 0;
467 }
468 
469 static int catpt_dai_prepare(struct snd_pcm_substream *substream,
470 			     struct snd_soc_dai *dai)
471 {
472 	struct catpt_stream_runtime *stream;
473 	struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
474 	int ret;
475 
476 	stream = snd_soc_dai_get_dma_data(dai, substream);
477 	if (stream->prepared)
478 		return 0;
479 
480 	ret = catpt_ipc_reset_stream(cdev, stream->info.stream_hw_id);
481 	if (ret)
482 		return CATPT_IPC_RET(ret);
483 
484 	ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id);
485 	if (ret)
486 		return CATPT_IPC_RET(ret);
487 
488 	stream->prepared = true;
489 	return 0;
490 }
491 
492 static int catpt_dai_trigger(struct snd_pcm_substream *substream, int cmd,
493 			     struct snd_soc_dai *dai)
494 {
495 	struct snd_pcm_runtime *runtime = substream->runtime;
496 	struct catpt_stream_runtime *stream;
497 	struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
498 	snd_pcm_uframes_t pos;
499 	int ret;
500 
501 	stream = snd_soc_dai_get_dma_data(dai, substream);
502 
503 	switch (cmd) {
504 	case SNDRV_PCM_TRIGGER_START:
505 		/* only offload is set_write_pos driven */
506 		if (stream->template->type != CATPT_STRM_TYPE_RENDER)
507 			goto resume_stream;
508 
509 		pos = frames_to_bytes(runtime, runtime->start_threshold);
510 		/*
511 		 * Dsp operates on buffer halves, thus max 2x set_write_pos
512 		 * (entire buffer filled) prior to stream start.
513 		 */
514 		ret = catpt_ipc_set_write_pos(cdev, stream->info.stream_hw_id,
515 					      pos, false, false);
516 		if (ret)
517 			return CATPT_IPC_RET(ret);
518 		fallthrough;
519 	case SNDRV_PCM_TRIGGER_RESUME:
520 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
521 	resume_stream:
522 		catpt_dsp_update_lpclock(cdev);
523 		ret = catpt_ipc_resume_stream(cdev, stream->info.stream_hw_id);
524 		if (ret)
525 			return CATPT_IPC_RET(ret);
526 		break;
527 
528 	case SNDRV_PCM_TRIGGER_STOP:
529 		stream->prepared = false;
530 		fallthrough;
531 	case SNDRV_PCM_TRIGGER_SUSPEND:
532 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
533 		ret = catpt_ipc_pause_stream(cdev, stream->info.stream_hw_id);
534 		catpt_dsp_update_lpclock(cdev);
535 		if (ret)
536 			return CATPT_IPC_RET(ret);
537 		break;
538 
539 	default:
540 		break;
541 	}
542 
543 	return 0;
544 }
545 
546 void catpt_stream_update_position(struct catpt_dev *cdev,
547 				  struct catpt_stream_runtime *stream,
548 				  struct catpt_notify_position *pos)
549 {
550 	struct snd_pcm_substream *substream = stream->substream;
551 	struct snd_pcm_runtime *r = substream->runtime;
552 	snd_pcm_uframes_t dsppos, newpos;
553 	int ret;
554 
555 	dsppos = bytes_to_frames(r, pos->stream_position);
556 
557 	if (!stream->prepared)
558 		goto exit;
559 	/* only offload is set_write_pos driven */
560 	if (stream->template->type != CATPT_STRM_TYPE_RENDER)
561 		goto exit;
562 
563 	if (dsppos >= r->buffer_size / 2)
564 		newpos = r->buffer_size / 2;
565 	else
566 		newpos = 0;
567 	/*
568 	 * Dsp operates on buffer halves, thus on every notify position
569 	 * (buffer half consumed) update wp to allow stream progression.
570 	 */
571 	ret = catpt_ipc_set_write_pos(cdev, stream->info.stream_hw_id,
572 				      frames_to_bytes(r, newpos),
573 				      false, false);
574 	if (ret) {
575 		dev_err(cdev->dev, "update position for stream %d failed: %d\n",
576 			stream->info.stream_hw_id, ret);
577 		return;
578 	}
579 exit:
580 	snd_pcm_period_elapsed(substream);
581 }
582 
583 /* 200 ms for 2 32-bit channels at 48kHz (native format) */
584 #define CATPT_BUFFER_MAX_SIZE	76800
585 #define CATPT_PCM_PERIODS_MAX	4
586 #define CATPT_PCM_PERIODS_MIN	2
587 
588 static const struct snd_pcm_hardware catpt_pcm_hardware = {
589 	.info			= SNDRV_PCM_INFO_MMAP |
590 				  SNDRV_PCM_INFO_MMAP_VALID |
591 				  SNDRV_PCM_INFO_INTERLEAVED |
592 				  SNDRV_PCM_INFO_PAUSE |
593 				  SNDRV_PCM_INFO_RESUME |
594 				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
595 	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
596 				  SNDRV_PCM_FMTBIT_S32_LE,
597 	.subformats		= SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
598 				  SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
599 	.period_bytes_min	= PAGE_SIZE,
600 	.period_bytes_max	= CATPT_BUFFER_MAX_SIZE / CATPT_PCM_PERIODS_MIN,
601 	.periods_min		= CATPT_PCM_PERIODS_MIN,
602 	.periods_max		= CATPT_PCM_PERIODS_MAX,
603 	.buffer_bytes_max	= CATPT_BUFFER_MAX_SIZE,
604 };
605 
606 static int catpt_component_pcm_new(struct snd_soc_component *component,
607 				   struct snd_soc_pcm_runtime *rtm)
608 {
609 	struct catpt_dev *cdev = dev_get_drvdata(component->dev);
610 
611 	snd_pcm_set_managed_buffer_all(rtm->pcm, SNDRV_DMA_TYPE_DEV_SG,
612 				       cdev->dev,
613 				       catpt_pcm_hardware.buffer_bytes_max,
614 				       catpt_pcm_hardware.buffer_bytes_max);
615 
616 	return 0;
617 }
618 
619 static int catpt_component_open(struct snd_soc_component *component,
620 				struct snd_pcm_substream *substream)
621 {
622 	struct snd_soc_pcm_runtime *rtm = snd_soc_substream_to_rtd(substream);
623 
624 	if (!rtm->dai_link->no_pcm)
625 		snd_soc_set_runtime_hwparams(substream, &catpt_pcm_hardware);
626 	return 0;
627 }
628 
629 static snd_pcm_uframes_t
630 catpt_component_pointer(struct snd_soc_component *component,
631 			struct snd_pcm_substream *substream)
632 {
633 	struct snd_soc_pcm_runtime *rtm = snd_soc_substream_to_rtd(substream);
634 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtm, 0);
635 	struct catpt_stream_runtime *stream;
636 	struct catpt_dev *cdev = dev_get_drvdata(component->dev);
637 	u32 pos;
638 
639 	if (rtm->dai_link->no_pcm)
640 		return 0;
641 
642 	stream = snd_soc_dai_get_dma_data(cpu_dai, substream);
643 	catpt_stream_read_position(cdev, stream, &pos);
644 
645 	return bytes_to_frames(substream->runtime, pos);
646 }
647 
648 static const struct snd_soc_dai_ops catpt_fe_dai_ops = {
649 	.startup = catpt_dai_startup,
650 	.shutdown = catpt_dai_shutdown,
651 	.hw_params = catpt_dai_hw_params,
652 	.hw_free = catpt_dai_hw_free,
653 	.prepare = catpt_dai_prepare,
654 	.trigger = catpt_dai_trigger,
655 };
656 
657 static int catpt_dai_pcm_new(struct snd_soc_pcm_runtime *rtm,
658 			     struct snd_soc_dai *dai)
659 {
660 	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtm, 0);
661 	struct catpt_ssp_device_format devfmt;
662 	struct catpt_dev *cdev = dev_get_drvdata(dai->dev);
663 	int ret;
664 
665 	devfmt.iface = dai->driver->id;
666 	devfmt.channels = codec_dai->driver->capture.channels_max;
667 
668 	switch (devfmt.iface) {
669 	case CATPT_SSP_IFACE_0:
670 		devfmt.mclk = CATPT_MCLK_FREQ_24_MHZ;
671 
672 		switch (devfmt.channels) {
673 		case 4:
674 			devfmt.mode = CATPT_SSP_MODE_TDM_PROVIDER;
675 			devfmt.clock_divider = 4;
676 			break;
677 		case 2:
678 		default:
679 			devfmt.mode = CATPT_SSP_MODE_I2S_PROVIDER;
680 			devfmt.clock_divider = 9;
681 			break;
682 		}
683 		break;
684 
685 	case CATPT_SSP_IFACE_1:
686 		devfmt.mclk = CATPT_MCLK_OFF;
687 		devfmt.mode = CATPT_SSP_MODE_I2S_CONSUMER;
688 		devfmt.clock_divider = 0;
689 		break;
690 	}
691 
692 	/* see if this is a new configuration */
693 	if (!memcmp(&cdev->devfmt[devfmt.iface], &devfmt, sizeof(devfmt)))
694 		return 0;
695 
696 	ret = pm_runtime_resume_and_get(cdev->dev);
697 	if (ret)
698 		return ret;
699 
700 	ret = catpt_ipc_set_device_format(cdev, &devfmt);
701 
702 	pm_runtime_put_autosuspend(cdev->dev);
703 
704 	if (ret)
705 		return CATPT_IPC_RET(ret);
706 
707 	/* store device format set for given SSP */
708 	memcpy(&cdev->devfmt[devfmt.iface], &devfmt, sizeof(devfmt));
709 	return 0;
710 }
711 
712 static const struct snd_soc_dai_ops catpt_dai_ops = {
713 	.pcm_new = catpt_dai_pcm_new,
714 };
715 
716 static struct snd_soc_dai_driver dai_drivers[] = {
717 /* FE DAIs */
718 {
719 	.name = "System Pin",
720 	.id = CATPT_STRM_TYPE_SYSTEM,
721 	.ops = &catpt_fe_dai_ops,
722 	.playback = {
723 		.stream_name = "System Playback",
724 		.channels_min = 2,
725 		.channels_max = 2,
726 		.rates = SNDRV_PCM_RATE_48000,
727 		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
728 		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
729 			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
730 	},
731 	.capture = {
732 		.stream_name = "Analog Capture",
733 		.channels_min = 2,
734 		.channels_max = 4,
735 		.rates = SNDRV_PCM_RATE_48000,
736 		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
737 		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
738 			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
739 	},
740 },
741 {
742 	.name = "Offload0 Pin",
743 	.id = CATPT_STRM_TYPE_RENDER,
744 	.ops = &catpt_fe_dai_ops,
745 	.playback = {
746 		.stream_name = "Offload0 Playback",
747 		.channels_min = 2,
748 		.channels_max = 2,
749 		.rates = SNDRV_PCM_RATE_8000_192000,
750 		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
751 		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
752 			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
753 	},
754 },
755 {
756 	.name = "Offload1 Pin",
757 	.id = CATPT_STRM_TYPE_RENDER,
758 	.ops = &catpt_fe_dai_ops,
759 	.playback = {
760 		.stream_name = "Offload1 Playback",
761 		.channels_min = 2,
762 		.channels_max = 2,
763 		.rates = SNDRV_PCM_RATE_8000_192000,
764 		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
765 		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
766 			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
767 	},
768 },
769 {
770 	.name = "Loopback Pin",
771 	.id = CATPT_STRM_TYPE_LOOPBACK,
772 	.ops = &catpt_fe_dai_ops,
773 	.capture = {
774 		.stream_name = "Loopback Capture",
775 		.channels_min = 2,
776 		.channels_max = 2,
777 		.rates = SNDRV_PCM_RATE_48000,
778 		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
779 		.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
780 			      SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
781 	},
782 },
783 {
784 	.name = "Bluetooth Pin",
785 	.id = CATPT_STRM_TYPE_BLUETOOTH_RENDER,
786 	.ops = &catpt_fe_dai_ops,
787 	.playback = {
788 		.stream_name = "Bluetooth Playback",
789 		.channels_min = 1,
790 		.channels_max = 1,
791 		.rates = SNDRV_PCM_RATE_8000,
792 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
793 	},
794 	.capture = {
795 		.stream_name = "Bluetooth Capture",
796 		.channels_min = 1,
797 		.channels_max = 1,
798 		.rates = SNDRV_PCM_RATE_8000,
799 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
800 	},
801 },
802 /* BE DAIs */
803 {
804 	.name = "ssp0-port",
805 	.id = CATPT_SSP_IFACE_0,
806 	.playback = {
807 		.channels_min = 1,
808 		.channels_max = 8,
809 	},
810 	.capture = {
811 		.channels_min = 1,
812 		.channels_max = 8,
813 	},
814 	.ops = &catpt_dai_ops,
815 },
816 {
817 	.name = "ssp1-port",
818 	.id = CATPT_SSP_IFACE_1,
819 	.playback = {
820 		.channels_min = 1,
821 		.channels_max = 8,
822 	},
823 	.capture = {
824 		.channels_min = 1,
825 		.channels_max = 8,
826 	},
827 	.ops = &catpt_dai_ops,
828 },
829 };
830 
831 #define DSP_VOLUME_MAX		S32_MAX /* 0db */
832 #define DSP_VOLUME_STEP_MAX	30
833 
834 static u32 ctlvol_to_dspvol(u32 value)
835 {
836 	if (value > DSP_VOLUME_STEP_MAX)
837 		value = 0;
838 	return DSP_VOLUME_MAX >> (DSP_VOLUME_STEP_MAX - value);
839 }
840 
841 static u32 dspvol_to_ctlvol(u32 volume)
842 {
843 	if (volume > DSP_VOLUME_MAX)
844 		return DSP_VOLUME_STEP_MAX;
845 	return volume ? __fls(volume) : 0;
846 }
847 
848 static int catpt_set_dspvol(struct catpt_dev *cdev, u8 stream_id, long *ctlvol)
849 {
850 	u32 dspvol;
851 	int ret, i;
852 
853 	for (i = 1; i < CATPT_CHANNELS_MAX; i++)
854 		if (ctlvol[i] != ctlvol[0])
855 			break;
856 
857 	if (i == CATPT_CHANNELS_MAX) {
858 		dspvol = ctlvol_to_dspvol(ctlvol[0]);
859 
860 		ret = catpt_ipc_set_volume(cdev, stream_id,
861 					   CATPT_ALL_CHANNELS_MASK, dspvol,
862 					   0, CATPT_AUDIO_CURVE_NONE);
863 	} else {
864 		for (i = 0; i < CATPT_CHANNELS_MAX; i++) {
865 			dspvol = ctlvol_to_dspvol(ctlvol[i]);
866 
867 			ret = catpt_ipc_set_volume(cdev, stream_id,
868 						   i, dspvol,
869 						   0, CATPT_AUDIO_CURVE_NONE);
870 			if (ret)
871 				break;
872 		}
873 	}
874 
875 	return CATPT_IPC_RET(ret);
876 }
877 
878 static int catpt_volume_info(struct snd_kcontrol *kcontrol,
879 			     struct snd_ctl_elem_info *uinfo)
880 {
881 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
882 	uinfo->count = CATPT_CHANNELS_MAX;
883 	uinfo->value.integer.min = 0;
884 	uinfo->value.integer.max = DSP_VOLUME_STEP_MAX;
885 	return 0;
886 }
887 
888 static int catpt_volume_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
889 {
890 	struct snd_soc_component *component = snd_kcontrol_chip(kctl);
891 	struct catpt_dev *cdev = dev_get_drvdata(component->dev);
892 	struct catpt_control_data *data;
893 	u32 dspvol, *regs;
894 	long *uvolumes;
895 	int i;
896 
897 	data = (struct catpt_control_data *)kctl->private_value;
898 	uvolumes = &uctl->value.integer.value[0];
899 
900 	guard(mutex)(&cdev->stream_mutex);
901 
902 	regs = catpt_stream_volume_regs(cdev, data->pin_id);
903 	if (regs) {
904 		for (i = 0; i < CATPT_CHANNELS_MAX; i++) {
905 			dspvol = readl(cdev->lpe_ba + regs[i]);
906 			data->volumes[i] = dspvol_to_ctlvol(dspvol);
907 		}
908 	}
909 
910 	memcpy(uvolumes, data->volumes, sizeof(data->volumes));
911 	return 0;
912 }
913 
914 static int catpt_volume_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
915 {
916 	struct snd_soc_component *component = snd_kcontrol_chip(kctl);
917 	struct catpt_dev *cdev = dev_get_drvdata(component->dev);
918 	struct catpt_control_data *data;
919 	u8 stream_hw_id;
920 	long *uvolumes;
921 	int ret;
922 
923 	data = (struct catpt_control_data *)kctl->private_value;
924 	uvolumes = &uctl->value.integer.value[0];
925 
926 	if (!memcmp(data->volumes, uvolumes, sizeof(data->volumes)))
927 		return 0;
928 
929 	guard(mutex)(&cdev->stream_mutex);
930 
931 	stream_hw_id = catpt_stream_hw_id(cdev, data->pin_id);
932 	if (stream_hw_id != CATPT_PIN_ID_INVALID) {
933 		ret = catpt_set_dspvol(cdev, stream_hw_id, uvolumes);
934 		if (ret)
935 			return ret;
936 	}
937 
938 	memcpy(data->volumes, uvolumes, sizeof(data->volumes));
939 	return 1;
940 }
941 
942 static int catpt_loopback_mute_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
943 {
944 	uctl->value.integer.value[0] = *(bool *)kctl->private_value;
945 	return 0;
946 }
947 
948 static int catpt_loopback_mute_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl)
949 {
950 	struct snd_soc_component *component = snd_kcontrol_chip(kctl);
951 	struct catpt_dev *cdev = dev_get_drvdata(component->dev);
952 	bool *kmute, cmute;
953 	u8 stream_hw_id;
954 	int ret;
955 
956 	kmute = (bool *)kctl->private_value;
957 	cmute = (bool)uctl->value.integer.value[0];
958 
959 	if (*kmute == cmute)
960 		return 0;
961 
962 	guard(mutex)(&cdev->stream_mutex);
963 
964 	stream_hw_id = catpt_stream_hw_id(cdev, CATPT_PIN_ID_REFERENCE);
965 	if (stream_hw_id != CATPT_PIN_ID_INVALID) {
966 		ret = catpt_ipc_mute_loopback(cdev, stream_hw_id, cmute);
967 		if (ret)
968 			return CATPT_IPC_RET(ret);
969 	}
970 
971 	*kmute = cmute;
972 	return 1;
973 }
974 
975 static int catpt_waves_switch_get(struct snd_kcontrol *kcontrol,
976 				  struct snd_ctl_elem_value *ucontrol)
977 {
978 	return 0;
979 }
980 
981 static int catpt_waves_switch_put(struct snd_kcontrol *kcontrol,
982 				  struct snd_ctl_elem_value *ucontrol)
983 {
984 	return 0;
985 }
986 
987 static int catpt_waves_param_get(struct snd_kcontrol *kcontrol,
988 				 unsigned int __user *bytes,
989 				 unsigned int size)
990 {
991 	return 0;
992 }
993 
994 static int catpt_waves_param_put(struct snd_kcontrol *kcontrol,
995 				 const unsigned int __user *bytes,
996 				 unsigned int size)
997 {
998 	return 0;
999 }
1000 
1001 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(catpt_volume_tlv, -9000, 300, 1);
1002 
1003 #define CATPT_VOLUME_CTL(kname, pname) {		\
1004 	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,		\
1005 	.name	= kname,				\
1006 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |	\
1007 		  SNDRV_CTL_ELEM_ACCESS_TLV_READ,	\
1008 	.info	= catpt_volume_info,			\
1009 	.get	= catpt_volume_get,			\
1010 	.put	= catpt_volume_put,			\
1011 	.tlv.p	= catpt_volume_tlv,			\
1012 	.private_value = (unsigned long)		\
1013 		&(struct catpt_control_data) { CATPT_PIN_ID_##pname } \
1014 }
1015 
1016 static const struct snd_kcontrol_new component_kcontrols[] = {
1017 /* Master volume (mixer stream) */
1018 CATPT_VOLUME_CTL("Master Playback Volume", MIXER),
1019 /* Individual volume controls for offload and capture */
1020 CATPT_VOLUME_CTL("Media0 Playback Volume", OFFLOAD1),
1021 CATPT_VOLUME_CTL("Media1 Playback Volume", OFFLOAD2),
1022 CATPT_VOLUME_CTL("Mic Capture Volume", CAPTURE1),
1023 SOC_SINGLE_BOOL_EXT("Loopback Mute", (unsigned long)&(bool[1]) {0},
1024 		    catpt_loopback_mute_get, catpt_loopback_mute_put),
1025 /* Enable or disable WAVES module */
1026 SOC_SINGLE_BOOL_EXT("Waves Switch", 0,
1027 		    catpt_waves_switch_get, catpt_waves_switch_put),
1028 /* WAVES module parameter control */
1029 SND_SOC_BYTES_TLV("Waves Set Param", 128,
1030 		  catpt_waves_param_get, catpt_waves_param_put),
1031 };
1032 
1033 static const struct snd_soc_dapm_widget component_widgets[] = {
1034 	SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL, 0, SND_SOC_NOPM, 0, 0),
1035 	SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
1036 	SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL, 0, SND_SOC_NOPM, 0, 0),
1037 	SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
1038 
1039 	SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1040 };
1041 
1042 static const struct snd_soc_dapm_route component_routes[] = {
1043 	{"Playback VMixer", NULL, "System Playback"},
1044 	{"Playback VMixer", NULL, "Offload0 Playback"},
1045 	{"Playback VMixer", NULL, "Offload1 Playback"},
1046 
1047 	{"SSP0 CODEC OUT", NULL, "Playback VMixer"},
1048 
1049 	{"Analog Capture", NULL, "SSP0 CODEC IN"},
1050 	{"Loopback Capture", NULL, "SSP0 CODEC IN"},
1051 
1052 	{"SSP1 BT OUT", NULL, "Bluetooth Playback"},
1053 	{"Bluetooth Capture", NULL, "SSP1 BT IN"},
1054 };
1055 
1056 static const struct snd_soc_component_driver catpt_comp_driver = {
1057 	.name = "catpt-platform",
1058 
1059 	.pcm_new = catpt_component_pcm_new,
1060 	.open = catpt_component_open,
1061 	.pointer = catpt_component_pointer,
1062 
1063 	.controls = component_kcontrols,
1064 	.num_controls = ARRAY_SIZE(component_kcontrols),
1065 	.dapm_widgets = component_widgets,
1066 	.num_dapm_widgets = ARRAY_SIZE(component_widgets),
1067 	.dapm_routes = component_routes,
1068 	.num_dapm_routes = ARRAY_SIZE(component_routes),
1069 };
1070 
1071 int catpt_arm_stream_templates(struct catpt_dev *cdev)
1072 {
1073 	struct resource *res;
1074 	u32 scratch_size = 0;
1075 	int i, j;
1076 
1077 	for (i = 0; i < ARRAY_SIZE(catpt_topology); i++) {
1078 		struct catpt_stream_template *template;
1079 		struct catpt_module_entry *entry;
1080 		struct catpt_module_type *type;
1081 
1082 		template = catpt_topology[i];
1083 		template->persistent_size = 0;
1084 
1085 		for (j = 0; j < template->num_entries; j++) {
1086 			entry = &template->entries[j];
1087 			type = &cdev->modules[entry->module_id];
1088 
1089 			if (!type->loaded)
1090 				return -ENOENT;
1091 
1092 			entry->entry_point = type->entry_point;
1093 			template->persistent_size += type->persistent_size;
1094 			if (type->scratch_size > scratch_size)
1095 				scratch_size = type->scratch_size;
1096 		}
1097 	}
1098 
1099 	if (scratch_size) {
1100 		/* allocate single scratch area for all modules */
1101 		res = catpt_request_region(&cdev->dram, scratch_size);
1102 		if (!res)
1103 			return -EBUSY;
1104 		cdev->scratch = res;
1105 	}
1106 
1107 	return 0;
1108 }
1109 
1110 int catpt_register_plat_component(struct catpt_dev *cdev)
1111 {
1112 	struct snd_soc_component *component;
1113 	int ret;
1114 
1115 	component = devm_kzalloc(cdev->dev, sizeof(*component), GFP_KERNEL);
1116 	if (!component)
1117 		return -ENOMEM;
1118 
1119 	ret = snd_soc_component_initialize(component, &catpt_comp_driver,
1120 					   cdev->dev);
1121 	if (ret)
1122 		return ret;
1123 
1124 	component->name = catpt_comp_driver.name;
1125 	return snd_soc_add_component(component, dai_drivers,
1126 				     ARRAY_SIZE(dai_drivers));
1127 }
1128