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