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