linux/sound/soc/fsl/imx-pcm-rpmsg.c
<<
>>
Prefs
   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
  19static 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
  35static 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
 107static 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
 137static 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
 194static 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
 201static 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
 220static 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
 239static 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
 290static 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
 322static 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
 350static 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
 362static 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
 369static 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
 398static 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
 415static 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
 432static 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
 449static 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
 479static 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 */
 533static 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
 612static 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
 630static 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
 653static 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;
 681out:
 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
 689static 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
 704static 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
 757static 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
 822fail:
 823        if (info->rpmsg_wq)
 824                destroy_workqueue(info->rpmsg_wq);
 825
 826        return ret;
 827}
 828
 829static 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
 840static 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
 849static 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
 860static 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
 878static 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
 897static 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
 905static 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};
 913module_platform_driver(imx_pcm_rpmsg_driver);
 914
 915MODULE_DESCRIPTION("Freescale SoC Audio RPMSG PCM interface");
 916MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
 917MODULE_ALIAS("platform:" IMX_PCM_DRV_NAME);
 918MODULE_LICENSE("GPL v2");
 919