xref: /openbmc/linux/sound/soc/fsl/imx-pcm-rpmsg.c (revision 9659281c)
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 snd_pcm_runtime *runtime = substream->runtime;
143 	struct rpmsg_msg *msg;
144 	int ret = 0;
145 
146 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
147 		msg = &info->msg[TX_HW_PARAM];
148 		msg->s_msg.header.cmd = TX_HW_PARAM;
149 	} else {
150 		msg = &info->msg[RX_HW_PARAM];
151 		msg->s_msg.header.cmd = RX_HW_PARAM;
152 	}
153 
154 	msg->s_msg.param.rate = params_rate(params);
155 
156 	switch (params_format(params)) {
157 	case SNDRV_PCM_FORMAT_S16_LE:
158 		msg->s_msg.param.format   = RPMSG_S16_LE;
159 		break;
160 	case SNDRV_PCM_FORMAT_S24_LE:
161 		msg->s_msg.param.format   = RPMSG_S24_LE;
162 		break;
163 	case SNDRV_PCM_FORMAT_DSD_U16_LE:
164 		msg->s_msg.param.format   = RPMSG_DSD_U16_LE;
165 		break;
166 	case SNDRV_PCM_FORMAT_DSD_U32_LE:
167 		msg->s_msg.param.format   = RPMSG_DSD_U32_LE;
168 		break;
169 	default:
170 		msg->s_msg.param.format   = RPMSG_S32_LE;
171 		break;
172 	}
173 
174 	switch (params_channels(params)) {
175 	case 1:
176 		msg->s_msg.param.channels = RPMSG_CH_LEFT;
177 		break;
178 	case 2:
179 		msg->s_msg.param.channels = RPMSG_CH_STEREO;
180 		break;
181 	default:
182 		ret = -EINVAL;
183 		break;
184 	}
185 
186 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
187 	runtime->dma_bytes = params_buffer_bytes(params);
188 
189 	info->send_message(msg, info);
190 
191 	return ret;
192 }
193 
194 static int imx_rpmsg_pcm_hw_free(struct snd_soc_component *component,
195 				 struct snd_pcm_substream *substream)
196 {
197 	snd_pcm_set_runtime_buffer(substream, NULL);
198 	return 0;
199 }
200 
201 static snd_pcm_uframes_t imx_rpmsg_pcm_pointer(struct snd_soc_component *component,
202 					       struct snd_pcm_substream *substream)
203 {
204 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
205 	struct rpmsg_msg *msg;
206 	unsigned int pos = 0;
207 	int buffer_tail = 0;
208 
209 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
210 		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
211 	else
212 		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
213 
214 	buffer_tail = msg->r_msg.param.buffer_tail;
215 	pos = buffer_tail * snd_pcm_lib_period_bytes(substream);
216 
217 	return bytes_to_frames(substream->runtime, pos);
218 }
219 
220 static void imx_rpmsg_timer_callback(struct timer_list *t)
221 {
222 	struct stream_timer  *stream_timer =
223 			from_timer(stream_timer, t, timer);
224 	struct snd_pcm_substream *substream = stream_timer->substream;
225 	struct rpmsg_info *info = stream_timer->info;
226 	struct rpmsg_msg *msg;
227 
228 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
229 		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
230 		msg->s_msg.header.cmd = TX_PERIOD_DONE;
231 	} else {
232 		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
233 		msg->s_msg.header.cmd = RX_PERIOD_DONE;
234 	}
235 
236 	imx_rpmsg_insert_workqueue(substream, msg, info);
237 }
238 
239 static int imx_rpmsg_pcm_open(struct snd_soc_component *component,
240 			      struct snd_pcm_substream *substream)
241 {
242 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
243 	struct rpmsg_msg *msg;
244 	int ret = 0;
245 	int cmd;
246 
247 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
248 		msg = &info->msg[TX_OPEN];
249 		msg->s_msg.header.cmd = TX_OPEN;
250 
251 		/* reinitialize buffer counter*/
252 		cmd = TX_PERIOD_DONE + MSG_TYPE_A_NUM;
253 		info->msg[cmd].s_msg.param.buffer_tail = 0;
254 		info->msg[cmd].r_msg.param.buffer_tail = 0;
255 		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;
256 
257 	} else {
258 		msg = &info->msg[RX_OPEN];
259 		msg->s_msg.header.cmd = RX_OPEN;
260 
261 		/* reinitialize buffer counter*/
262 		cmd = RX_PERIOD_DONE + MSG_TYPE_A_NUM;
263 		info->msg[cmd].s_msg.param.buffer_tail = 0;
264 		info->msg[cmd].r_msg.param.buffer_tail = 0;
265 		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
266 	}
267 
268 	info->send_message(msg, info);
269 
270 	imx_rpmsg_pcm_hardware.period_bytes_max =
271 			imx_rpmsg_pcm_hardware.buffer_bytes_max / 2;
272 
273 	snd_soc_set_runtime_hwparams(substream, &imx_rpmsg_pcm_hardware);
274 
275 	ret = snd_pcm_hw_constraint_integer(substream->runtime,
276 					    SNDRV_PCM_HW_PARAM_PERIODS);
277 	if (ret < 0)
278 		return ret;
279 
280 	info->msg_drop_count[substream->stream] = 0;
281 
282 	/* Create timer*/
283 	info->stream_timer[substream->stream].info = info;
284 	info->stream_timer[substream->stream].substream = substream;
285 	timer_setup(&info->stream_timer[substream->stream].timer,
286 		    imx_rpmsg_timer_callback, 0);
287 	return ret;
288 }
289 
290 static int imx_rpmsg_pcm_close(struct snd_soc_component *component,
291 			       struct snd_pcm_substream *substream)
292 {
293 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
294 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
295 	struct rpmsg_msg *msg;
296 	int ret = 0;
297 
298 	/* Flush work in workqueue to make TX_CLOSE is the last message */
299 	flush_workqueue(info->rpmsg_wq);
300 
301 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
302 		msg = &info->msg[TX_CLOSE];
303 		msg->s_msg.header.cmd = TX_CLOSE;
304 	} else {
305 		msg = &info->msg[RX_CLOSE];
306 		msg->s_msg.header.cmd = RX_CLOSE;
307 	}
308 
309 	info->send_message(msg, info);
310 
311 	del_timer(&info->stream_timer[substream->stream].timer);
312 
313 	rtd->dai_link->ignore_suspend = 0;
314 
315 	if (info->msg_drop_count[substream->stream])
316 		dev_warn(rtd->dev, "Msg is dropped!, number is %d\n",
317 			 info->msg_drop_count[substream->stream]);
318 
319 	return ret;
320 }
321 
322 static int imx_rpmsg_pcm_prepare(struct snd_soc_component *component,
323 				 struct snd_pcm_substream *substream)
324 {
325 	struct snd_pcm_runtime *runtime = substream->runtime;
326 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
327 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
328 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
329 
330 	/*
331 	 * NON-MMAP mode, NONBLOCK, Version 2, enable lpa in dts
332 	 * four conditions to determine the lpa is enabled.
333 	 */
334 	if ((runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
335 	     runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) &&
336 	     rpmsg->enable_lpa) {
337 		/*
338 		 * Ignore suspend operation in low power mode
339 		 * M core will continue playback music on A core suspend.
340 		 */
341 		rtd->dai_link->ignore_suspend = 1;
342 		rpmsg->force_lpa = 1;
343 	} else {
344 		rpmsg->force_lpa = 0;
345 	}
346 
347 	return 0;
348 }
349 
350 static int imx_rpmsg_pcm_mmap(struct snd_soc_component *component,
351 			      struct snd_pcm_substream *substream,
352 			      struct vm_area_struct *vma)
353 {
354 	struct snd_pcm_runtime *runtime = substream->runtime;
355 
356 	return dma_mmap_wc(substream->pcm->card->dev, vma,
357 			   runtime->dma_area,
358 			   runtime->dma_addr,
359 			   runtime->dma_bytes);
360 }
361 
362 static void imx_rpmsg_pcm_dma_complete(void *arg)
363 {
364 	struct snd_pcm_substream *substream = arg;
365 
366 	snd_pcm_period_elapsed(substream);
367 }
368 
369 static int imx_rpmsg_prepare_and_submit(struct snd_soc_component *component,
370 					struct snd_pcm_substream *substream)
371 {
372 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
373 	struct rpmsg_msg *msg;
374 
375 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
376 		msg = &info->msg[TX_BUFFER];
377 		msg->s_msg.header.cmd = TX_BUFFER;
378 	} else {
379 		msg = &info->msg[RX_BUFFER];
380 		msg->s_msg.header.cmd = RX_BUFFER;
381 	}
382 
383 	/* Send buffer address and buffer size */
384 	msg->s_msg.param.buffer_addr = substream->runtime->dma_addr;
385 	msg->s_msg.param.buffer_size = snd_pcm_lib_buffer_bytes(substream);
386 	msg->s_msg.param.period_size = snd_pcm_lib_period_bytes(substream);
387 	msg->s_msg.param.buffer_tail = 0;
388 
389 	info->num_period[substream->stream] = msg->s_msg.param.buffer_size /
390 					      msg->s_msg.param.period_size;
391 
392 	info->callback[substream->stream] = imx_rpmsg_pcm_dma_complete;
393 	info->callback_param[substream->stream] = substream;
394 
395 	return imx_rpmsg_insert_workqueue(substream, msg, info);
396 }
397 
398 static int imx_rpmsg_async_issue_pending(struct snd_soc_component *component,
399 					 struct snd_pcm_substream *substream)
400 {
401 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
402 	struct rpmsg_msg *msg;
403 
404 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
405 		msg = &info->msg[TX_START];
406 		msg->s_msg.header.cmd = TX_START;
407 	} else {
408 		msg = &info->msg[RX_START];
409 		msg->s_msg.header.cmd = RX_START;
410 	}
411 
412 	return imx_rpmsg_insert_workqueue(substream, msg, info);
413 }
414 
415 static int imx_rpmsg_restart(struct snd_soc_component *component,
416 			     struct snd_pcm_substream *substream)
417 {
418 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
419 	struct rpmsg_msg *msg;
420 
421 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
422 		msg = &info->msg[TX_RESTART];
423 		msg->s_msg.header.cmd = TX_RESTART;
424 	} else {
425 		msg = &info->msg[RX_RESTART];
426 		msg->s_msg.header.cmd = RX_RESTART;
427 	}
428 
429 	return imx_rpmsg_insert_workqueue(substream, msg, info);
430 }
431 
432 static int imx_rpmsg_pause(struct snd_soc_component *component,
433 			   struct snd_pcm_substream *substream)
434 {
435 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
436 	struct rpmsg_msg *msg;
437 
438 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
439 		msg = &info->msg[TX_PAUSE];
440 		msg->s_msg.header.cmd = TX_PAUSE;
441 	} else {
442 		msg = &info->msg[RX_PAUSE];
443 		msg->s_msg.header.cmd = RX_PAUSE;
444 	}
445 
446 	return imx_rpmsg_insert_workqueue(substream, msg, info);
447 }
448 
449 static int imx_rpmsg_terminate_all(struct snd_soc_component *component,
450 				   struct snd_pcm_substream *substream)
451 {
452 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
453 	struct rpmsg_msg *msg;
454 	int cmd;
455 
456 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
457 		msg = &info->msg[TX_TERMINATE];
458 		msg->s_msg.header.cmd = TX_TERMINATE;
459 		/* Clear buffer count*/
460 		cmd = TX_PERIOD_DONE + MSG_TYPE_A_NUM;
461 		info->msg[cmd].s_msg.param.buffer_tail = 0;
462 		info->msg[cmd].r_msg.param.buffer_tail = 0;
463 		info->msg[TX_POINTER].r_msg.param.buffer_offset = 0;
464 	} else {
465 		msg = &info->msg[RX_TERMINATE];
466 		msg->s_msg.header.cmd = RX_TERMINATE;
467 		/* Clear buffer count*/
468 		cmd = RX_PERIOD_DONE + MSG_TYPE_A_NUM;
469 		info->msg[cmd].s_msg.param.buffer_tail = 0;
470 		info->msg[cmd].r_msg.param.buffer_tail = 0;
471 		info->msg[RX_POINTER].r_msg.param.buffer_offset = 0;
472 	}
473 
474 	del_timer(&info->stream_timer[substream->stream].timer);
475 
476 	return imx_rpmsg_insert_workqueue(substream, msg, info);
477 }
478 
479 static int imx_rpmsg_pcm_trigger(struct snd_soc_component *component,
480 				 struct snd_pcm_substream *substream, int cmd)
481 {
482 	struct snd_pcm_runtime *runtime = substream->runtime;
483 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
484 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
485 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
486 	int ret = 0;
487 
488 	switch (cmd) {
489 	case SNDRV_PCM_TRIGGER_START:
490 		ret = imx_rpmsg_prepare_and_submit(component, substream);
491 		if (ret)
492 			return ret;
493 		ret = imx_rpmsg_async_issue_pending(component, substream);
494 		break;
495 	case SNDRV_PCM_TRIGGER_RESUME:
496 		if (rpmsg->force_lpa)
497 			break;
498 		fallthrough;
499 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
500 		ret = imx_rpmsg_restart(component, substream);
501 		break;
502 	case SNDRV_PCM_TRIGGER_SUSPEND:
503 		if (!rpmsg->force_lpa) {
504 			if (runtime->info & SNDRV_PCM_INFO_PAUSE)
505 				ret = imx_rpmsg_pause(component, substream);
506 			else
507 				ret = imx_rpmsg_terminate_all(component, substream);
508 		}
509 		break;
510 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
511 		ret = imx_rpmsg_pause(component, substream);
512 		break;
513 	case SNDRV_PCM_TRIGGER_STOP:
514 		ret = imx_rpmsg_terminate_all(component, substream);
515 		break;
516 	default:
517 		return -EINVAL;
518 	}
519 
520 	if (ret)
521 		return ret;
522 
523 	return 0;
524 }
525 
526 /*
527  * imx_rpmsg_pcm_ack
528  *
529  * Send the period index to M core through rpmsg, but not send
530  * all the period index to M core, reduce some unnessesary msg
531  * to reduce the pressure of rpmsg bandwidth.
532  */
533 static int imx_rpmsg_pcm_ack(struct snd_soc_component *component,
534 			     struct snd_pcm_substream *substream)
535 {
536 	struct snd_pcm_runtime *runtime = substream->runtime;
537 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
538 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
539 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
540 	struct rpmsg_info *info = dev_get_drvdata(component->dev);
541 	snd_pcm_uframes_t period_size = runtime->period_size;
542 	snd_pcm_sframes_t avail;
543 	struct timer_list *timer;
544 	struct rpmsg_msg *msg;
545 	unsigned long flags;
546 	int buffer_tail = 0;
547 	int written_num;
548 
549 	if (!rpmsg->force_lpa)
550 		return 0;
551 
552 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
553 		msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
554 		msg->s_msg.header.cmd = TX_PERIOD_DONE;
555 	} else {
556 		msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
557 		msg->s_msg.header.cmd = RX_PERIOD_DONE;
558 	}
559 
560 	msg->s_msg.header.type = MSG_TYPE_C;
561 
562 	buffer_tail = (frames_to_bytes(runtime, runtime->control->appl_ptr) %
563 		       snd_pcm_lib_buffer_bytes(substream));
564 	buffer_tail = buffer_tail / snd_pcm_lib_period_bytes(substream);
565 
566 	/* There is update for period index */
567 	if (buffer_tail != msg->s_msg.param.buffer_tail) {
568 		written_num = buffer_tail - msg->s_msg.param.buffer_tail;
569 		if (written_num < 0)
570 			written_num += runtime->periods;
571 
572 		msg->s_msg.param.buffer_tail = buffer_tail;
573 
574 		/* The notification message is updated to latest */
575 		spin_lock_irqsave(&info->lock[substream->stream], flags);
576 		memcpy(&info->notify[substream->stream], msg,
577 		       sizeof(struct rpmsg_s_msg));
578 		info->notify_updated[substream->stream] = true;
579 		spin_unlock_irqrestore(&info->lock[substream->stream], flags);
580 
581 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
582 			avail = snd_pcm_playback_hw_avail(runtime);
583 		else
584 			avail = snd_pcm_capture_hw_avail(runtime);
585 
586 		timer = &info->stream_timer[substream->stream].timer;
587 		/*
588 		 * If the data in the buffer is less than one period before
589 		 * this fill, which means the data may not enough on M
590 		 * core side, we need to send message immediately to let
591 		 * M core know the pointer is updated.
592 		 * if there is more than one period data in the buffer before
593 		 * this fill, which means the data is enough on M core side,
594 		 * we can delay one period (using timer) to send the message
595 		 * for reduce the message number in workqueue, because the
596 		 * pointer may be updated by ack function later, we can
597 		 * send latest pointer to M core side.
598 		 */
599 		if ((avail - written_num * period_size) <= period_size) {
600 			imx_rpmsg_insert_workqueue(substream, msg, info);
601 		} else if (rpmsg->force_lpa && !timer_pending(timer)) {
602 			int time_msec;
603 
604 			time_msec = (int)(runtime->period_size * 1000 / runtime->rate);
605 			mod_timer(timer, jiffies + msecs_to_jiffies(time_msec));
606 		}
607 	}
608 
609 	return 0;
610 }
611 
612 static int imx_rpmsg_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
613 						int stream, int size)
614 {
615 	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
616 	struct snd_dma_buffer *buf = &substream->dma_buffer;
617 
618 	buf->dev.type = SNDRV_DMA_TYPE_DEV;
619 	buf->dev.dev = pcm->card->dev;
620 	buf->private_data = NULL;
621 	buf->area = dma_alloc_wc(pcm->card->dev, size,
622 				 &buf->addr, GFP_KERNEL);
623 	if (!buf->area)
624 		return -ENOMEM;
625 
626 	buf->bytes = size;
627 	return 0;
628 }
629 
630 static void imx_rpmsg_pcm_free_dma_buffers(struct snd_soc_component *component,
631 					   struct snd_pcm *pcm)
632 {
633 	struct snd_pcm_substream *substream;
634 	struct snd_dma_buffer *buf;
635 	int stream;
636 
637 	for (stream = SNDRV_PCM_STREAM_PLAYBACK;
638 	     stream < SNDRV_PCM_STREAM_LAST; stream++) {
639 		substream = pcm->streams[stream].substream;
640 		if (!substream)
641 			continue;
642 
643 		buf = &substream->dma_buffer;
644 		if (!buf->area)
645 			continue;
646 
647 		dma_free_wc(pcm->card->dev, buf->bytes,
648 			    buf->area, buf->addr);
649 		buf->area = NULL;
650 	}
651 }
652 
653 static int imx_rpmsg_pcm_new(struct snd_soc_component *component,
654 			     struct snd_soc_pcm_runtime *rtd)
655 {
656 	struct snd_card *card = rtd->card->snd_card;
657 	struct snd_pcm *pcm = rtd->pcm;
658 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
659 	struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
660 	int ret;
661 
662 	ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
663 	if (ret)
664 		return ret;
665 
666 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
667 		ret = imx_rpmsg_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK,
668 							   rpmsg->buffer_size);
669 		if (ret)
670 			goto out;
671 	}
672 
673 	if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
674 		ret = imx_rpmsg_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE,
675 							   rpmsg->buffer_size);
676 		if (ret)
677 			goto out;
678 	}
679 
680 	imx_rpmsg_pcm_hardware.buffer_bytes_max = rpmsg->buffer_size;
681 out:
682 	/* free preallocated buffers in case of error */
683 	if (ret)
684 		imx_rpmsg_pcm_free_dma_buffers(component, pcm);
685 
686 	return ret;
687 }
688 
689 static const struct snd_soc_component_driver imx_rpmsg_soc_component = {
690 	.name		= IMX_PCM_DRV_NAME,
691 	.pcm_construct	= imx_rpmsg_pcm_new,
692 	.pcm_destruct	= imx_rpmsg_pcm_free_dma_buffers,
693 	.open		= imx_rpmsg_pcm_open,
694 	.close		= imx_rpmsg_pcm_close,
695 	.hw_params	= imx_rpmsg_pcm_hw_params,
696 	.hw_free	= imx_rpmsg_pcm_hw_free,
697 	.trigger	= imx_rpmsg_pcm_trigger,
698 	.pointer	= imx_rpmsg_pcm_pointer,
699 	.mmap		= imx_rpmsg_pcm_mmap,
700 	.ack		= imx_rpmsg_pcm_ack,
701 	.prepare	= imx_rpmsg_pcm_prepare,
702 };
703 
704 static void imx_rpmsg_pcm_work(struct work_struct *work)
705 {
706 	struct work_of_rpmsg *work_of_rpmsg;
707 	bool is_notification = false;
708 	struct rpmsg_info *info;
709 	struct rpmsg_msg msg;
710 	unsigned long flags;
711 
712 	work_of_rpmsg = container_of(work, struct work_of_rpmsg, work);
713 	info = work_of_rpmsg->info;
714 
715 	/*
716 	 * Every work in the work queue, first we check if there
717 	 * is update for period is filled, because there may be not
718 	 * enough data in M core side, need to let M core know
719 	 * data is updated immediately.
720 	 */
721 	spin_lock_irqsave(&info->lock[TX], flags);
722 	if (info->notify_updated[TX]) {
723 		memcpy(&msg, &info->notify[TX], sizeof(struct rpmsg_s_msg));
724 		info->notify_updated[TX] = false;
725 		spin_unlock_irqrestore(&info->lock[TX], flags);
726 		info->send_message(&msg, info);
727 	} else {
728 		spin_unlock_irqrestore(&info->lock[TX], flags);
729 	}
730 
731 	spin_lock_irqsave(&info->lock[RX], flags);
732 	if (info->notify_updated[RX]) {
733 		memcpy(&msg, &info->notify[RX], sizeof(struct rpmsg_s_msg));
734 		info->notify_updated[RX] = false;
735 		spin_unlock_irqrestore(&info->lock[RX], flags);
736 		info->send_message(&msg, info);
737 	} else {
738 		spin_unlock_irqrestore(&info->lock[RX], flags);
739 	}
740 
741 	/* Skip the notification message for it has been processed above */
742 	if (work_of_rpmsg->msg.s_msg.header.type == MSG_TYPE_C &&
743 	    (work_of_rpmsg->msg.s_msg.header.cmd == TX_PERIOD_DONE ||
744 	     work_of_rpmsg->msg.s_msg.header.cmd == RX_PERIOD_DONE))
745 		is_notification = true;
746 
747 	if (!is_notification)
748 		info->send_message(&work_of_rpmsg->msg, info);
749 
750 	/* update read index */
751 	spin_lock_irqsave(&info->wq_lock, flags);
752 	info->work_read_index++;
753 	info->work_read_index %= WORK_MAX_NUM;
754 	spin_unlock_irqrestore(&info->wq_lock, flags);
755 }
756 
757 static int imx_rpmsg_pcm_probe(struct platform_device *pdev)
758 {
759 	struct snd_soc_component *component;
760 	struct rpmsg_info *info;
761 	int ret, i;
762 
763 	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
764 	if (!info)
765 		return -ENOMEM;
766 
767 	platform_set_drvdata(pdev, info);
768 
769 	info->rpdev = container_of(pdev->dev.parent, struct rpmsg_device, dev);
770 	info->dev = &pdev->dev;
771 	/* Setup work queue */
772 	info->rpmsg_wq = alloc_ordered_workqueue("rpmsg_audio",
773 						 WQ_HIGHPRI |
774 						 WQ_UNBOUND |
775 						 WQ_FREEZABLE);
776 	if (!info->rpmsg_wq) {
777 		dev_err(&pdev->dev, "workqueue create failed\n");
778 		return -ENOMEM;
779 	}
780 
781 	/* Write index initialize 1, make it differ with the read index */
782 	info->work_write_index = 1;
783 	info->send_message = imx_rpmsg_pcm_send_message;
784 
785 	for (i = 0; i < WORK_MAX_NUM; i++) {
786 		INIT_WORK(&info->work_list[i].work, imx_rpmsg_pcm_work);
787 		info->work_list[i].info = info;
788 	}
789 
790 	/* Initialize msg */
791 	for (i = 0; i < MSG_MAX_NUM; i++) {
792 		info->msg[i].s_msg.header.cate  = IMX_RPMSG_AUDIO;
793 		info->msg[i].s_msg.header.major = IMX_RMPSG_MAJOR;
794 		info->msg[i].s_msg.header.minor = IMX_RMPSG_MINOR;
795 		info->msg[i].s_msg.header.type  = MSG_TYPE_A;
796 		info->msg[i].s_msg.param.audioindex = 0;
797 	}
798 
799 	init_completion(&info->cmd_complete);
800 	mutex_init(&info->msg_lock);
801 	spin_lock_init(&info->lock[TX]);
802 	spin_lock_init(&info->lock[RX]);
803 	spin_lock_init(&info->wq_lock);
804 
805 	ret = devm_snd_soc_register_component(&pdev->dev,
806 					      &imx_rpmsg_soc_component,
807 					      NULL, 0);
808 	if (ret)
809 		goto fail;
810 
811 	component = snd_soc_lookup_component(&pdev->dev, IMX_PCM_DRV_NAME);
812 	if (!component) {
813 		ret = -EINVAL;
814 		goto fail;
815 	}
816 #ifdef CONFIG_DEBUG_FS
817 	component->debugfs_prefix = "rpmsg";
818 #endif
819 
820 	return 0;
821 
822 fail:
823 	if (info->rpmsg_wq)
824 		destroy_workqueue(info->rpmsg_wq);
825 
826 	return ret;
827 }
828 
829 static int imx_rpmsg_pcm_remove(struct platform_device *pdev)
830 {
831 	struct rpmsg_info *info = platform_get_drvdata(pdev);
832 
833 	if (info->rpmsg_wq)
834 		destroy_workqueue(info->rpmsg_wq);
835 
836 	return 0;
837 }
838 
839 #ifdef CONFIG_PM
840 static int imx_rpmsg_pcm_runtime_resume(struct device *dev)
841 {
842 	struct rpmsg_info *info = dev_get_drvdata(dev);
843 
844 	cpu_latency_qos_add_request(&info->pm_qos_req, 0);
845 
846 	return 0;
847 }
848 
849 static int imx_rpmsg_pcm_runtime_suspend(struct device *dev)
850 {
851 	struct rpmsg_info *info = dev_get_drvdata(dev);
852 
853 	cpu_latency_qos_remove_request(&info->pm_qos_req);
854 
855 	return 0;
856 }
857 #endif
858 
859 #ifdef CONFIG_PM_SLEEP
860 static int imx_rpmsg_pcm_suspend(struct device *dev)
861 {
862 	struct rpmsg_info *info = dev_get_drvdata(dev);
863 	struct rpmsg_msg *rpmsg_tx;
864 	struct rpmsg_msg *rpmsg_rx;
865 
866 	rpmsg_tx = &info->msg[TX_SUSPEND];
867 	rpmsg_rx = &info->msg[RX_SUSPEND];
868 
869 	rpmsg_tx->s_msg.header.cmd = TX_SUSPEND;
870 	info->send_message(rpmsg_tx, info);
871 
872 	rpmsg_rx->s_msg.header.cmd = RX_SUSPEND;
873 	info->send_message(rpmsg_rx, info);
874 
875 	return 0;
876 }
877 
878 static int imx_rpmsg_pcm_resume(struct device *dev)
879 {
880 	struct rpmsg_info *info = dev_get_drvdata(dev);
881 	struct rpmsg_msg *rpmsg_tx;
882 	struct rpmsg_msg *rpmsg_rx;
883 
884 	rpmsg_tx = &info->msg[TX_RESUME];
885 	rpmsg_rx = &info->msg[RX_RESUME];
886 
887 	rpmsg_tx->s_msg.header.cmd = TX_RESUME;
888 	info->send_message(rpmsg_tx, info);
889 
890 	rpmsg_rx->s_msg.header.cmd = RX_RESUME;
891 	info->send_message(rpmsg_rx, info);
892 
893 	return 0;
894 }
895 #endif /* CONFIG_PM_SLEEP */
896 
897 static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = {
898 	SET_RUNTIME_PM_OPS(imx_rpmsg_pcm_runtime_suspend,
899 			   imx_rpmsg_pcm_runtime_resume,
900 			   NULL)
901 	SET_SYSTEM_SLEEP_PM_OPS(imx_rpmsg_pcm_suspend,
902 				imx_rpmsg_pcm_resume)
903 };
904 
905 static struct platform_driver imx_pcm_rpmsg_driver = {
906 	.probe  = imx_rpmsg_pcm_probe,
907 	.remove	= imx_rpmsg_pcm_remove,
908 	.driver = {
909 		.name = IMX_PCM_DRV_NAME,
910 		.pm = &imx_rpmsg_pcm_pm_ops,
911 	},
912 };
913 module_platform_driver(imx_pcm_rpmsg_driver);
914 
915 MODULE_DESCRIPTION("Freescale SoC Audio RPMSG PCM interface");
916 MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
917 MODULE_ALIAS("platform:" IMX_PCM_DRV_NAME);
918 MODULE_LICENSE("GPL v2");
919