xref: /linux/sound/soc/fsl/imx-pcm-rpmsg.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright 2017-2021 NXP
3 
4 #include <linux/dma-mapping.h>
5 #include <linux/slab.h>
6 #include <linux/module.h>
7 #include <linux/delay.h>
8 #include <linux/rpmsg.h>
9 #include <sound/core.h>
10 #include <sound/pcm.h>
11 #include <sound/pcm_params.h>
12 #include <sound/dmaengine_pcm.h>
13 #include <sound/soc.h>
14 
15 #include "imx-pcm.h"
16 #include "fsl_rpmsg.h"
17 #include "imx-pcm-rpmsg.h"
18 
19 static const struct snd_pcm_hardware imx_rpmsg_pcm_hardware = {
20 	.info = SNDRV_PCM_INFO_INTERLEAVED |
21 		SNDRV_PCM_INFO_BLOCK_TRANSFER |
22 		SNDRV_PCM_INFO_BATCH |
23 		SNDRV_PCM_INFO_MMAP |
24 		SNDRV_PCM_INFO_MMAP_VALID |
25 		SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
26 		SNDRV_PCM_INFO_PAUSE |
27 		SNDRV_PCM_INFO_RESUME,
28 	.buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
29 	.period_bytes_min = 512,
30 	.period_bytes_max = 65536,
31 	.periods_min = 2,
32 	.periods_max = 6000,
33 	.fifo_size = 0,
34 };
35 
36 static int imx_rpmsg_pcm_send_message(struct rpmsg_msg *msg,
37 				      struct rpmsg_info *info)
38 {
39 	struct rpmsg_device *rpdev = info->rpdev;
40 	int ret = 0;
41 
42 	guard(mutex)(&info->msg_lock);
43 	if (!rpdev) {
44 		dev_err(info->dev, "rpmsg channel not ready\n");
45 		return -EINVAL;
46 	}
47 
48 	dev_dbg(&rpdev->dev, "send cmd %d\n", msg->s_msg.header.cmd);
49 
50 	if (!(msg->s_msg.header.type == MSG_TYPE_C))
51 		reinit_completion(&info->cmd_complete);
52 
53 	ret = rpmsg_send(rpdev->ept, (void *)&msg->s_msg,
54 			 sizeof(struct rpmsg_s_msg));
55 	if (ret) {
56 		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
57 		return ret;
58 	}
59 
60 	/* No receive msg for TYPE_C command */
61 	if (msg->s_msg.header.type == MSG_TYPE_C)
62 		return 0;
63 
64 	/* wait response from rpmsg */
65 	ret = wait_for_completion_timeout(&info->cmd_complete,
66 					  msecs_to_jiffies(RPMSG_TIMEOUT));
67 	if (!ret) {
68 		dev_err(&rpdev->dev, "rpmsg_send cmd %d timeout!\n",
69 			msg->s_msg.header.cmd);
70 		return -ETIMEDOUT;
71 	}
72 
73 	memcpy(&msg->r_msg, &info->r_msg, sizeof(struct rpmsg_r_msg));
74 	memcpy(&info->msg[msg->r_msg.header.cmd].r_msg,
75 	       &msg->r_msg, sizeof(struct rpmsg_r_msg));
76 
77 	/*
78 	 * Reset the buffer pointer to be zero, actully we have
79 	 * set the buffer pointer to be zero in imx_rpmsg_terminate_all
80 	 * But if there is timer task queued in queue, after it is
81 	 * executed the buffer pointer will be changed, so need to
82 	 * reset it again with TERMINATE command.
83 	 */
84 	switch (msg->s_msg.header.cmd) {
85 	case TX_TERMINATE:
86 		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;
87 		break;
88 	case RX_TERMINATE:
89 		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
90 		break;
91 	default:
92 		break;
93 	}
94 
95 	dev_dbg(&rpdev->dev, "cmd:%d, resp %d\n", msg->s_msg.header.cmd,
96 		info->r_msg.param.resp);
97 
98 	return 0;
99 }
100 
101 static int imx_rpmsg_insert_workqueue(struct snd_pcm_substream *substream,
102 				      struct rpmsg_msg *msg,
103 				      struct rpmsg_info *info)
104 {
105 	int ret = 0;
106 
107 	/*
108 	 * Queue the work to workqueue.
109 	 * If the queue is full, drop the message.
110 	 */
111 	guard(spinlock_irqsave)(&info->wq_lock);
112 	if (info->work_write_index != info->work_read_index) {
113 		int index = info->work_write_index;
114 
115 		memcpy(&info->work_list[index].msg, msg,
116 		       sizeof(struct rpmsg_s_msg));
117 
118 		queue_work(info->rpmsg_wq, &info->work_list[index].work);
119 		info->work_write_index++;
120 		info->work_write_index %= WORK_MAX_NUM;
121 	} else {
122 		info->msg_drop_count[substream->stream]++;
123 		ret = -EPIPE;
124 	}
125 
126 	return ret;
127 }
128 
129 static int imx_rpmsg_pcm_hw_params(struct snd_soc_component *component,
130 				   struct snd_pcm_substream *substream,
131 				   struct snd_pcm_hw_params *params)
132 {
133 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
134 	struct rpmsg_msg *msg;
135 
136 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
137 		msg = &info->msg[TX_HW_PARAM];
138 		msg->s_msg.header.cmd = TX_HW_PARAM;
139 	} else {
140 		msg = &info->msg[RX_HW_PARAM];
141 		msg->s_msg.header.cmd = RX_HW_PARAM;
142 	}
143 
144 	msg->s_msg.param.rate = params_rate(params);
145 
146 	switch (params_format(params)) {
147 	case SNDRV_PCM_FORMAT_S16_LE:
148 		msg->s_msg.param.format   = RPMSG_S16_LE;
149 		break;
150 	case SNDRV_PCM_FORMAT_S24_LE:
151 		msg->s_msg.param.format   = RPMSG_S24_LE;
152 		break;
153 	case SNDRV_PCM_FORMAT_DSD_U16_LE:
154 		msg->s_msg.param.format   = RPMSG_DSD_U16_LE;
155 		break;
156 	case SNDRV_PCM_FORMAT_DSD_U32_LE:
157 		msg->s_msg.param.format   = RPMSG_DSD_U32_LE;
158 		break;
159 	default:
160 		msg->s_msg.param.format   = RPMSG_S32_LE;
161 		break;
162 	}
163 
164 	switch (params_channels(params)) {
165 	case 1:
166 		msg->s_msg.param.channels = RPMSG_CH_LEFT;
167 		break;
168 	case 2:
169 		msg->s_msg.param.channels = RPMSG_CH_STEREO;
170 		break;
171 	default:
172 		msg->s_msg.param.channels = params_channels(params);
173 		break;
174 	}
175 
176 	info->send_message(msg, info);
177 
178 	return 0;
179 }
180 
181 static snd_pcm_uframes_t imx_rpmsg_pcm_pointer(struct snd_soc_component *component,
182 					       struct snd_pcm_substream *substream)
183 {
184 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
185 	struct rpmsg_msg *msg;
186 	unsigned int pos = 0;
187 	int buffer_tail = 0;
188 
189 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
190 		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
191 	else
192 		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
193 
194 	buffer_tail = msg->r_msg.param.buffer_tail;
195 	pos = buffer_tail * snd_pcm_lib_period_bytes(substream);
196 
197 	return bytes_to_frames(substream->runtime, pos);
198 }
199 
200 static void imx_rpmsg_timer_callback(struct timer_list *t)
201 {
202 	struct stream_timer  *stream_timer =
203 			timer_container_of(stream_timer, t, timer);
204 	struct snd_pcm_substream *substream = stream_timer->substream;
205 	struct rpmsg_info *info = stream_timer->info;
206 	struct rpmsg_msg *msg;
207 
208 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
209 		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
210 		msg->s_msg.header.cmd = TX_PERIOD_DONE;
211 	} else {
212 		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
213 		msg->s_msg.header.cmd = RX_PERIOD_DONE;
214 	}
215 
216 	imx_rpmsg_insert_workqueue(substream, msg, info);
217 }
218 
219 static int imx_rpmsg_pcm_open(struct snd_soc_component *component,
220 			      struct snd_pcm_substream *substream)
221 {
222 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
223 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
224 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
225 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
226 	struct snd_pcm_hardware pcm_hardware;
227 	struct rpmsg_msg *msg;
228 	int ret = 0;
229 	int cmd;
230 
231 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
232 		msg = &info->msg[TX_OPEN];
233 		msg->s_msg.header.cmd = TX_OPEN;
234 
235 		/* reinitialize buffer counter*/
236 		cmd = TX_PERIOD_DONE + MSG_TYPE_A_NUM;
237 		info->msg[cmd].s_msg.param.buffer_tail = 0;
238 		info->msg[cmd].r_msg.param.buffer_tail = 0;
239 		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;
240 
241 	} else {
242 		msg = &info->msg[RX_OPEN];
243 		msg->s_msg.header.cmd = RX_OPEN;
244 
245 		/* reinitialize buffer counter*/
246 		cmd = RX_PERIOD_DONE + MSG_TYPE_A_NUM;
247 		info->msg[cmd].s_msg.param.buffer_tail = 0;
248 		info->msg[cmd].r_msg.param.buffer_tail = 0;
249 		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
250 	}
251 
252 	info->send_message(msg, info);
253 
254 	pcm_hardware = imx_rpmsg_pcm_hardware;
255 	pcm_hardware.buffer_bytes_max = rpmsg->buffer_size[substream->stream];
256 	pcm_hardware.period_bytes_max = pcm_hardware.buffer_bytes_max / 2;
257 
258 	snd_soc_set_runtime_hwparams(substream, &pcm_hardware);
259 
260 	ret = snd_pcm_hw_constraint_integer(substream->runtime,
261 					    SNDRV_PCM_HW_PARAM_PERIODS);
262 	if (ret < 0)
263 		return ret;
264 
265 	info->msg_drop_count[substream->stream] = 0;
266 
267 	/* Create timer*/
268 	info->stream_timer[substream->stream].info = info;
269 	info->stream_timer[substream->stream].substream = substream;
270 	timer_setup(&info->stream_timer[substream->stream].timer,
271 		    imx_rpmsg_timer_callback, 0);
272 	return ret;
273 }
274 
275 static int imx_rpmsg_pcm_close(struct snd_soc_component *component,
276 			       struct snd_pcm_substream *substream)
277 {
278 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
279 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
280 	struct rpmsg_msg *msg;
281 
282 	/* Flush work in workqueue to make TX_CLOSE is the last message */
283 	flush_workqueue(info->rpmsg_wq);
284 
285 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
286 		msg = &info->msg[TX_CLOSE];
287 		msg->s_msg.header.cmd = TX_CLOSE;
288 	} else {
289 		msg = &info->msg[RX_CLOSE];
290 		msg->s_msg.header.cmd = RX_CLOSE;
291 	}
292 
293 	info->send_message(msg, info);
294 
295 	timer_delete(&info->stream_timer[substream->stream].timer);
296 
297 	rtd->dai_link->ignore_suspend = 0;
298 
299 	if (info->msg_drop_count[substream->stream])
300 		dev_warn(rtd->dev, "Msg is dropped!, number is %d\n",
301 			 info->msg_drop_count[substream->stream]);
302 
303 	return 0;
304 }
305 
306 static int imx_rpmsg_pcm_prepare(struct snd_soc_component *component,
307 				 struct snd_pcm_substream *substream)
308 {
309 	struct snd_pcm_runtime *runtime = substream->runtime;
310 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
311 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
312 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
313 
314 	/*
315 	 * NON-MMAP mode, NONBLOCK, Version 2, enable lpa in dts
316 	 * four conditions to determine the lpa is enabled.
317 	 */
318 	if ((runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
319 	     runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) &&
320 	     rpmsg->enable_lpa) {
321 		/*
322 		 * Ignore suspend operation in low power mode
323 		 * M core will continue playback music on A core suspend.
324 		 */
325 		rtd->dai_link->ignore_suspend = 1;
326 		rpmsg->force_lpa = 1;
327 	} else {
328 		rpmsg->force_lpa = 0;
329 	}
330 
331 	return 0;
332 }
333 
334 static void imx_rpmsg_pcm_dma_complete(void *arg)
335 {
336 	struct snd_pcm_substream *substream = arg;
337 
338 	snd_pcm_period_elapsed(substream);
339 }
340 
341 static int imx_rpmsg_prepare_and_submit(struct snd_soc_component *component,
342 					struct snd_pcm_substream *substream)
343 {
344 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
345 	struct rpmsg_msg *msg;
346 
347 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
348 		msg = &info->msg[TX_BUFFER];
349 		msg->s_msg.header.cmd = TX_BUFFER;
350 	} else {
351 		msg = &info->msg[RX_BUFFER];
352 		msg->s_msg.header.cmd = RX_BUFFER;
353 	}
354 
355 	/* Send buffer address and buffer size */
356 	msg->s_msg.param.buffer_addr = substream->runtime->dma_addr;
357 	msg->s_msg.param.buffer_size = snd_pcm_lib_buffer_bytes(substream);
358 	msg->s_msg.param.period_size = snd_pcm_lib_period_bytes(substream);
359 	msg->s_msg.param.buffer_tail = 0;
360 
361 	info->num_period[substream->stream] = msg->s_msg.param.buffer_size /
362 					      msg->s_msg.param.period_size;
363 
364 	info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
365 	info->callback_param[substream->stream] = substream;
366 
367 	return imx_rpmsg_insert_workqueue(substream, msg, info);
368 }
369 
370 static int imx_rpmsg_async_issue_pending(struct snd_soc_component *component,
371 					 struct snd_pcm_substream *substream)
372 {
373 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
374 	struct rpmsg_msg *msg;
375 
376 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
377 		msg = &info->msg[TX_START];
378 		msg->s_msg.header.cmd = TX_START;
379 	} else {
380 		msg = &info->msg[RX_START];
381 		msg->s_msg.header.cmd = RX_START;
382 	}
383 
384 	return imx_rpmsg_insert_workqueue(substream, msg, info);
385 }
386 
387 static int imx_rpmsg_restart(struct snd_soc_component *component,
388 			     struct snd_pcm_substream *substream)
389 {
390 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
391 	struct rpmsg_msg *msg;
392 
393 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
394 		msg = &info->msg[TX_RESTART];
395 		msg->s_msg.header.cmd = TX_RESTART;
396 	} else {
397 		msg = &info->msg[RX_RESTART];
398 		msg->s_msg.header.cmd = RX_RESTART;
399 	}
400 
401 	return imx_rpmsg_insert_workqueue(substream, msg, info);
402 }
403 
404 static int imx_rpmsg_pause(struct snd_soc_component *component,
405 			   struct snd_pcm_substream *substream)
406 {
407 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
408 	struct rpmsg_msg *msg;
409 
410 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
411 		msg = &info->msg[TX_PAUSE];
412 		msg->s_msg.header.cmd = TX_PAUSE;
413 	} else {
414 		msg = &info->msg[RX_PAUSE];
415 		msg->s_msg.header.cmd = RX_PAUSE;
416 	}
417 
418 	return imx_rpmsg_insert_workqueue(substream, msg, info);
419 }
420 
421 static int imx_rpmsg_terminate_all(struct snd_soc_component *component,
422 				   struct snd_pcm_substream *substream)
423 {
424 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
425 	struct rpmsg_msg *msg;
426 	int cmd;
427 
428 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
429 		msg = &info->msg[TX_TERMINATE];
430 		msg->s_msg.header.cmd = TX_TERMINATE;
431 		/* Clear buffer count*/
432 		cmd = TX_PERIOD_DONE + MSG_TYPE_A_NUM;
433 		info->msg[cmd].s_msg.param.buffer_tail = 0;
434 		info->msg[cmd].r_msg.param.buffer_tail = 0;
435 		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;
436 	} else {
437 		msg = &info->msg[RX_TERMINATE];
438 		msg->s_msg.header.cmd = RX_TERMINATE;
439 		/* Clear buffer count*/
440 		cmd = RX_PERIOD_DONE + MSG_TYPE_A_NUM;
441 		info->msg[cmd].s_msg.param.buffer_tail = 0;
442 		info->msg[cmd].r_msg.param.buffer_tail = 0;
443 		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
444 	}
445 
446 	timer_delete(&info->stream_timer[substream->stream].timer);
447 
448 	return imx_rpmsg_insert_workqueue(substream, msg, info);
449 }
450 
451 static int imx_rpmsg_pcm_trigger(struct snd_soc_component *component,
452 				 struct snd_pcm_substream *substream, int cmd)
453 {
454 	struct snd_pcm_runtime *runtime = substream->runtime;
455 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
456 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
457 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
458 	int ret = 0;
459 
460 	switch (cmd) {
461 	case SNDRV_PCM_TRIGGER_START:
462 		ret = imx_rpmsg_prepare_and_submit(component, substream);
463 		if (ret)
464 			return ret;
465 		ret = imx_rpmsg_async_issue_pending(component, substream);
466 		break;
467 	case SNDRV_PCM_TRIGGER_RESUME:
468 		if (rpmsg->force_lpa)
469 			break;
470 		fallthrough;
471 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
472 		ret = imx_rpmsg_restart(component, substream);
473 		break;
474 	case SNDRV_PCM_TRIGGER_SUSPEND:
475 		if (!rpmsg->force_lpa) {
476 			if (runtime->info & SNDRV_PCM_INFO_PAUSE)
477 				ret = imx_rpmsg_pause(component, substream);
478 			else
479 				ret = imx_rpmsg_terminate_all(component, substream);
480 		}
481 		break;
482 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
483 		ret = imx_rpmsg_pause(component, substream);
484 		break;
485 	case SNDRV_PCM_TRIGGER_STOP:
486 		ret = imx_rpmsg_terminate_all(component, substream);
487 		break;
488 	default:
489 		return -EINVAL;
490 	}
491 
492 	if (ret)
493 		return ret;
494 
495 	return 0;
496 }
497 
498 /*
499  * imx_rpmsg_pcm_ack
500  *
501  * Send the period index to M core through rpmsg, but not send
502  * all the period index to M core, reduce some unnessesary msg
503  * to reduce the pressure of rpmsg bandwidth.
504  */
505 static int imx_rpmsg_pcm_ack(struct snd_soc_component *component,
506 			     struct snd_pcm_substream *substream)
507 {
508 	struct snd_pcm_runtime *runtime = substream->runtime;
509 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
510 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
511 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
512 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
513 	snd_pcm_uframes_t period_size = runtime->period_size;
514 	snd_pcm_sframes_t avail;
515 	struct timer_list *timer;
516 	struct rpmsg_msg *msg;
517 	int buffer_tail = 0;
518 	int written_num;
519 
520 	if (!rpmsg->force_lpa)
521 		return 0;
522 
523 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
524 		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
525 		msg->s_msg.header.cmd = TX_PERIOD_DONE;
526 	} else {
527 		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
528 		msg->s_msg.header.cmd = RX_PERIOD_DONE;
529 	}
530 
531 	msg->s_msg.header.type = MSG_TYPE_C;
532 
533 	buffer_tail = (frames_to_bytes(runtime, runtime->control->appl_ptr) %
534 		       snd_pcm_lib_buffer_bytes(substream));
535 	buffer_tail = buffer_tail / snd_pcm_lib_period_bytes(substream);
536 
537 	/* There is update for period index */
538 	if (buffer_tail != msg->s_msg.param.buffer_tail) {
539 		written_num = buffer_tail - msg->s_msg.param.buffer_tail;
540 		if (written_num < 0)
541 			written_num += runtime->periods;
542 
543 		msg->s_msg.param.buffer_tail = buffer_tail;
544 
545 		/* The notification message is updated to latest */
546 		scoped_guard(spinlock_irqsave, &info->lock[substream->stream]) {
547 			memcpy(&info->notify[substream->stream], msg,
548 			       sizeof(struct rpmsg_s_msg));
549 			info->notify_updated[substream->stream] = true;
550 		}
551 
552 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
553 			avail = snd_pcm_playback_hw_avail(runtime);
554 		else
555 			avail = snd_pcm_capture_hw_avail(runtime);
556 
557 		timer = &info->stream_timer[substream->stream].timer;
558 		/*
559 		 * If the data in the buffer is less than one period before
560 		 * this fill, which means the data may not enough on M
561 		 * core side, we need to send message immediately to let
562 		 * M core know the pointer is updated.
563 		 * if there is more than one period data in the buffer before
564 		 * this fill, which means the data is enough on M core side,
565 		 * we can delay one period (using timer) to send the message
566 		 * for reduce the message number in workqueue, because the
567 		 * pointer may be updated by ack function later, we can
568 		 * send latest pointer to M core side.
569 		 */
570 		if ((avail - written_num * period_size) <= period_size) {
571 			imx_rpmsg_insert_workqueue(substream, msg, info);
572 		} else if (rpmsg->force_lpa && !timer_pending(timer)) {
573 			int time_msec;
574 
575 			time_msec = (int)(runtime->period_size * 1000 / runtime->rate);
576 			mod_timer(timer, jiffies + msecs_to_jiffies(time_msec));
577 		}
578 	}
579 
580 	return 0;
581 }
582 
583 static int imx_rpmsg_pcm_new(struct snd_soc_component *component,
584 			     struct snd_soc_pcm_runtime *rtd)
585 {
586 	struct snd_card *card = rtd->card->snd_card;
587 	struct snd_pcm *pcm = rtd->pcm;
588 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
589 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
590 	struct snd_pcm_substream *substream;
591 	int ret;
592 
593 	ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
594 	if (ret)
595 		return ret;
596 
597 	substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
598 	if (substream) {
599 		ret = snd_pcm_set_fixed_buffer(substream, SNDRV_DMA_TYPE_DEV_WC, pcm->card->dev,
600 					       rpmsg->buffer_size[SNDRV_PCM_STREAM_PLAYBACK]);
601 		if (ret < 0)
602 			return ret;
603 	}
604 	substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
605 	if (substream) {
606 		ret = snd_pcm_set_fixed_buffer(substream, SNDRV_DMA_TYPE_DEV_WC, pcm->card->dev,
607 					       rpmsg->buffer_size[SNDRV_PCM_STREAM_CAPTURE]);
608 		if (ret < 0)
609 			return ret;
610 	}
611 
612 	return ret;
613 }
614 
615 static const struct snd_soc_component_driver imx_rpmsg_soc_component = {
616 	.name		= IMX_PCM_DRV_NAME,
617 	.pcm_new	= imx_rpmsg_pcm_new,
618 	.open		= imx_rpmsg_pcm_open,
619 	.close		= imx_rpmsg_pcm_close,
620 	.hw_params	= imx_rpmsg_pcm_hw_params,
621 	.trigger	= imx_rpmsg_pcm_trigger,
622 	.pointer	= imx_rpmsg_pcm_pointer,
623 	.ack		= imx_rpmsg_pcm_ack,
624 	.prepare	= imx_rpmsg_pcm_prepare,
625 	.debugfs_prefix	= "rpmsg",
626 };
627 
628 static void imx_rpmsg_pcm_work(struct work_struct *work)
629 {
630 	struct work_of_rpmsg *work_of_rpmsg;
631 	bool is_notification = false;
632 	struct rpmsg_info *info;
633 	struct rpmsg_msg msg;
634 	bool updated;
635 
636 	work_of_rpmsg = container_of(work, struct work_of_rpmsg, work);
637 	info = work_of_rpmsg->info;
638 
639 	/*
640 	 * Every work in the work queue, first we check if there
641 	 * is update for period is filled, because there may be not
642 	 * enough data in M core side, need to let M core know
643 	 * data is updated immediately.
644 	 */
645 	scoped_guard(spinlock_irqsave, &info->lock[TX]) {
646 		updated = info->notify_updated[TX];
647 		if (updated) {
648 			memcpy(&msg, &info->notify[TX], sizeof(struct rpmsg_s_msg));
649 			info->notify_updated[TX] = false;
650 		}
651 	}
652 	if (updated)
653 		info->send_message(&msg, info);
654 
655 	scoped_guard(spinlock_irqsave, &info->lock[RX]) {
656 		updated = info->notify_updated[RX];
657 		if (updated) {
658 			memcpy(&msg, &info->notify[RX], sizeof(struct rpmsg_s_msg));
659 			info->notify_updated[RX] = false;
660 		}
661 	}
662 	if (updated)
663 		info->send_message(&msg, info);
664 
665 
666 	/* Skip the notification message for it has been processed above */
667 	if (work_of_rpmsg->msg.s_msg.header.type == MSG_TYPE_C &&
668 	    (work_of_rpmsg->msg.s_msg.header.cmd == TX_PERIOD_DONE ||
669 	     work_of_rpmsg->msg.s_msg.header.cmd == RX_PERIOD_DONE))
670 		is_notification = true;
671 
672 	if (!is_notification)
673 		info->send_message(&work_of_rpmsg->msg, info);
674 
675 	/* update read index */
676 	scoped_guard(spinlock_irqsave, &info->wq_lock) {
677 		info->work_read_index++;
678 		info->work_read_index %= WORK_MAX_NUM;
679 	}
680 }
681 
682 static int imx_rpmsg_pcm_probe(struct platform_device *pdev)
683 {
684 	struct rpmsg_info *info;
685 	int ret, i;
686 
687 	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
688 	if (!info)
689 		return -ENOMEM;
690 
691 	platform_set_drvdata(pdev, info);
692 
693 	info->rpdev = container_of(pdev->dev.parent, struct rpmsg_device, dev);
694 	info->dev = &pdev->dev;
695 	/* Setup work queue */
696 	info->rpmsg_wq = alloc_ordered_workqueue(info->rpdev->id.name,
697 						 WQ_HIGHPRI |
698 						 WQ_UNBOUND |
699 						 WQ_FREEZABLE);
700 	if (!info->rpmsg_wq) {
701 		dev_err(&pdev->dev, "workqueue create failed\n");
702 		return -ENOMEM;
703 	}
704 
705 	/* Write index initialize 1, make it differ with the read index */
706 	info->work_write_index = 1;
707 	info->send_message = imx_rpmsg_pcm_send_message;
708 
709 	for (i = 0; i < WORK_MAX_NUM; i++) {
710 		INIT_WORK(&info->work_list[i].work, imx_rpmsg_pcm_work);
711 		info->work_list[i].info = info;
712 	}
713 
714 	/* Initialize msg */
715 	for (i = 0; i < MSG_MAX_NUM; i++) {
716 		info->msg[i].s_msg.header.cate  = IMX_RPMSG_AUDIO;
717 		info->msg[i].s_msg.header.major = IMX_RMPSG_MAJOR;
718 		info->msg[i].s_msg.header.minor = IMX_RMPSG_MINOR;
719 		info->msg[i].s_msg.header.type  = MSG_TYPE_A;
720 		info->msg[i].s_msg.param.audioindex = 0;
721 	}
722 
723 	init_completion(&info->cmd_complete);
724 	mutex_init(&info->msg_lock);
725 	spin_lock_init(&info->lock[TX]);
726 	spin_lock_init(&info->lock[RX]);
727 	spin_lock_init(&info->wq_lock);
728 
729 	ret = devm_snd_soc_register_component(&pdev->dev,
730 					      &imx_rpmsg_soc_component,
731 					      NULL, 0);
732 	if (ret)
733 		goto fail;
734 
735 	return 0;
736 
737 fail:
738 	if (info->rpmsg_wq)
739 		destroy_workqueue(info->rpmsg_wq);
740 
741 	return ret;
742 }
743 
744 static void imx_rpmsg_pcm_remove(struct platform_device *pdev)
745 {
746 	struct rpmsg_info *info = platform_get_drvdata(pdev);
747 
748 	if (info->rpmsg_wq)
749 		destroy_workqueue(info->rpmsg_wq);
750 }
751 
752 static int imx_rpmsg_pcm_runtime_resume(struct device *dev)
753 {
754 	struct rpmsg_info *info = dev_get_drvdata(dev);
755 
756 	cpu_latency_qos_add_request(&info->pm_qos_req, 0);
757 
758 	return 0;
759 }
760 
761 static int imx_rpmsg_pcm_runtime_suspend(struct device *dev)
762 {
763 	struct rpmsg_info *info = dev_get_drvdata(dev);
764 
765 	cpu_latency_qos_remove_request(&info->pm_qos_req);
766 
767 	return 0;
768 }
769 
770 static int imx_rpmsg_pcm_suspend(struct device *dev)
771 {
772 	struct rpmsg_info *info = dev_get_drvdata(dev);
773 	struct rpmsg_msg *rpmsg_tx;
774 	struct rpmsg_msg *rpmsg_rx;
775 
776 	rpmsg_tx = &info->msg[TX_SUSPEND];
777 	rpmsg_rx = &info->msg[RX_SUSPEND];
778 
779 	rpmsg_tx->s_msg.header.cmd = TX_SUSPEND;
780 	info->send_message(rpmsg_tx, info);
781 
782 	rpmsg_rx->s_msg.header.cmd = RX_SUSPEND;
783 	info->send_message(rpmsg_rx, info);
784 
785 	return 0;
786 }
787 
788 static int imx_rpmsg_pcm_resume(struct device *dev)
789 {
790 	struct rpmsg_info *info = dev_get_drvdata(dev);
791 	struct rpmsg_msg *rpmsg_tx;
792 	struct rpmsg_msg *rpmsg_rx;
793 
794 	rpmsg_tx = &info->msg[TX_RESUME];
795 	rpmsg_rx = &info->msg[RX_RESUME];
796 
797 	rpmsg_tx->s_msg.header.cmd = TX_RESUME;
798 	info->send_message(rpmsg_tx, info);
799 
800 	rpmsg_rx->s_msg.header.cmd = RX_RESUME;
801 	info->send_message(rpmsg_rx, info);
802 
803 	return 0;
804 }
805 
806 static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = {
807 	RUNTIME_PM_OPS(imx_rpmsg_pcm_runtime_suspend,
808 		       imx_rpmsg_pcm_runtime_resume, NULL)
809 	SYSTEM_SLEEP_PM_OPS(imx_rpmsg_pcm_suspend, imx_rpmsg_pcm_resume)
810 };
811 
812 static const struct platform_device_id imx_rpmsg_pcm_id_table[] = {
813 	{ .name = "rpmsg-audio-channel" },
814 	{ .name = "rpmsg-micfil-channel" },
815 	{ }
816 };
817 MODULE_DEVICE_TABLE(platform, imx_rpmsg_pcm_id_table);
818 
819 static struct platform_driver imx_pcm_rpmsg_driver = {
820 	.probe  = imx_rpmsg_pcm_probe,
821 	.remove = imx_rpmsg_pcm_remove,
822 	.id_table = imx_rpmsg_pcm_id_table,
823 	.driver = {
824 		.name = IMX_PCM_DRV_NAME,
825 		.pm = pm_ptr(&imx_rpmsg_pcm_pm_ops),
826 	},
827 };
828 module_platform_driver(imx_pcm_rpmsg_driver);
829 
830 MODULE_DESCRIPTION("Freescale SoC Audio RPMSG PCM interface");
831 MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
832 MODULE_ALIAS("platform:" IMX_PCM_DRV_NAME);
833 MODULE_LICENSE("GPL v2");
834