linux/sound/soc/xilinx/xlnx_formatter_pcm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Xilinx ASoC audio formatter support
   4 *
   5 * Copyright (C) 2018 Xilinx, Inc.
   6 *
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/dma-mapping.h>
  11#include <linux/io.h>
  12#include <linux/module.h>
  13#include <linux/of_address.h>
  14#include <linux/of_irq.h>
  15#include <linux/platform_device.h>
  16#include <linux/sizes.h>
  17
  18#include <sound/asoundef.h>
  19#include <sound/soc.h>
  20#include <sound/pcm_params.h>
  21
  22#include "xlnx_snd_common.h"
  23
  24#define DRV_NAME "xlnx_formatter_pcm"
  25
  26#define XLNX_S2MM_OFFSET        0
  27#define XLNX_MM2S_OFFSET        0x100
  28
  29#define XLNX_AUD_CORE_CONFIG    0x4
  30#define XLNX_AUD_CTRL           0x10
  31#define XLNX_AUD_STS            0x14
  32
  33#define AUD_CTRL_RESET_MASK     BIT(1)
  34#define AUD_CFG_MM2S_MASK       BIT(15)
  35#define AUD_CFG_S2MM_MASK       BIT(31)
  36
  37#define XLNX_AUD_FS_MULTIPLIER  0x18
  38#define XLNX_AUD_PERIOD_CONFIG  0x1C
  39#define XLNX_AUD_BUFF_ADDR_LSB  0x20
  40#define XLNX_AUD_BUFF_ADDR_MSB  0x24
  41#define XLNX_AUD_XFER_COUNT     0x28
  42#define XLNX_AUD_CH_STS_START   0x2C
  43#define XLNX_BYTES_PER_CH       0x44
  44#define XLNX_AUD_ALIGN_BYTES    64
  45
  46#define AUD_STS_IOC_IRQ_MASK    BIT(31)
  47#define AUD_STS_CH_STS_MASK     BIT(29)
  48#define AUD_CTRL_IOC_IRQ_MASK   BIT(13)
  49#define AUD_CTRL_TOUT_IRQ_MASK  BIT(14)
  50#define AUD_CTRL_DMA_EN_MASK    BIT(0)
  51
  52#define CFG_MM2S_CH_MASK        GENMASK(11, 8)
  53#define CFG_MM2S_CH_SHIFT       8
  54#define CFG_MM2S_XFER_MASK      GENMASK(14, 13)
  55#define CFG_MM2S_XFER_SHIFT     13
  56#define CFG_MM2S_PKG_MASK       BIT(12)
  57
  58#define CFG_S2MM_CH_MASK        GENMASK(27, 24)
  59#define CFG_S2MM_CH_SHIFT       24
  60#define CFG_S2MM_XFER_MASK      GENMASK(30, 29)
  61#define CFG_S2MM_XFER_SHIFT     29
  62#define CFG_S2MM_PKG_MASK       BIT(28)
  63
  64#define AUD_CTRL_DATA_WIDTH_MASK        GENMASK(18, 16)
  65#define AUD_CTRL_DATA_WIDTH_SHIFT       16
  66#define AUD_CTRL_ACTIVE_CH_MASK         GENMASK(22, 19)
  67#define AUD_CTRL_ACTIVE_CH_SHIFT        19
  68#define PERIOD_CFG_PERIODS_SHIFT        16
  69
  70#define PERIODS_MIN             2
  71#define PERIODS_MAX             6
  72#define PERIOD_BYTES_MIN        192
  73#define PERIOD_BYTES_MAX        (50 * 1024)
  74#define XLNX_PARAM_UNKNOWN      0
  75
  76static const struct snd_pcm_hardware xlnx_pcm_hardware = {
  77        .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  78                SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_PAUSE |
  79                SNDRV_PCM_INFO_RESUME,
  80        .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |
  81                   SNDRV_PCM_FMTBIT_S24_LE,
  82        .channels_min = 2,
  83        .channels_max = 2,
  84        .rates = SNDRV_PCM_RATE_8000_192000,
  85        .rate_min = 8000,
  86        .rate_max = 192000,
  87        .buffer_bytes_max = PERIODS_MAX * PERIOD_BYTES_MAX,
  88        .period_bytes_min = PERIOD_BYTES_MIN,
  89        .period_bytes_max = PERIOD_BYTES_MAX,
  90        .periods_min = PERIODS_MIN,
  91        .periods_max = PERIODS_MAX,
  92};
  93
  94struct xlnx_pcm_drv_data {
  95        void __iomem *mmio;
  96        bool s2mm_presence;
  97        bool mm2s_presence;
  98        int s2mm_irq;
  99        int mm2s_irq;
 100        struct snd_pcm_substream *play_stream;
 101        struct snd_pcm_substream *capture_stream;
 102        struct platform_device *pdev;
 103        struct device_node *nodes[XLNX_MAX_PATHS];
 104        struct clk *axi_clk;
 105        struct clk *mm2s_axis_clk;
 106        struct clk *s2mm_axis_clk;
 107        struct clk *aud_mclk;
 108};
 109
 110/*
 111 * struct xlnx_pcm_stream_param - stream configuration
 112 * @mmio: base address offset
 113 * @interleaved: audio channels arrangement in buffer
 114 * @xfer_mode: data formatting mode during transfer
 115 * @ch_limit: Maximum channels supported
 116 * @buffer_size: stream ring buffer size
 117 */
 118struct xlnx_pcm_stream_param {
 119        void __iomem *mmio;
 120        bool interleaved;
 121        u32 xfer_mode;
 122        u32 ch_limit;
 123        u64 buffer_size;
 124};
 125
 126enum bit_depth {
 127        BIT_DEPTH_8,
 128        BIT_DEPTH_16,
 129        BIT_DEPTH_20,
 130        BIT_DEPTH_24,
 131        BIT_DEPTH_32,
 132};
 133
 134enum {
 135        AES_TO_AES,
 136        AES_TO_PCM,
 137        PCM_TO_PCM,
 138        PCM_TO_AES
 139};
 140
 141static void xlnx_parse_aes_params(u32 chsts_reg1_val, u32 chsts_reg2_val,
 142                                  struct device *dev)
 143{
 144        u32 padded, srate, bit_depth, status[2];
 145
 146        if (chsts_reg1_val & IEC958_AES0_PROFESSIONAL) {
 147                status[0] = chsts_reg1_val & 0xff;
 148                status[1] = (chsts_reg1_val >> 16) & 0xff;
 149
 150                switch (status[0] & IEC958_AES0_PRO_FS) {
 151                case IEC958_AES0_PRO_FS_44100:
 152                        srate = 44100;
 153                        break;
 154                case IEC958_AES0_PRO_FS_48000:
 155                        srate = 48000;
 156                        break;
 157                case IEC958_AES0_PRO_FS_32000:
 158                        srate = 32000;
 159                        break;
 160                case IEC958_AES0_PRO_FS_NOTID:
 161                default:
 162                        srate = XLNX_PARAM_UNKNOWN;
 163                        break;
 164                }
 165
 166                switch (status[1] & IEC958_AES2_PRO_SBITS) {
 167                case IEC958_AES2_PRO_WORDLEN_NOTID:
 168                case IEC958_AES2_PRO_SBITS_20:
 169                        padded = 0;
 170                        break;
 171                case IEC958_AES2_PRO_SBITS_24:
 172                        padded = 4;
 173                        break;
 174                default:
 175                        bit_depth = XLNX_PARAM_UNKNOWN;
 176                        goto log_params;
 177                }
 178
 179                switch (status[1] & IEC958_AES2_PRO_WORDLEN) {
 180                case IEC958_AES2_PRO_WORDLEN_20_16:
 181                        bit_depth = 16 + padded;
 182                        break;
 183                case IEC958_AES2_PRO_WORDLEN_22_18:
 184                        bit_depth = 18 + padded;
 185                        break;
 186                case IEC958_AES2_PRO_WORDLEN_23_19:
 187                        bit_depth = 19 + padded;
 188                        break;
 189                case IEC958_AES2_PRO_WORDLEN_24_20:
 190                        bit_depth = 20 + padded;
 191                        break;
 192                case IEC958_AES2_PRO_WORDLEN_NOTID:
 193                default:
 194                        bit_depth = XLNX_PARAM_UNKNOWN;
 195                        break;
 196                }
 197
 198        } else {
 199                status[0] = (chsts_reg1_val >> 24) & 0xff;
 200                status[1] = chsts_reg2_val & 0xff;
 201
 202                switch (status[0] & IEC958_AES3_CON_FS) {
 203                case IEC958_AES3_CON_FS_44100:
 204                        srate = 44100;
 205                        break;
 206                case IEC958_AES3_CON_FS_48000:
 207                        srate = 48000;
 208                        break;
 209                case IEC958_AES3_CON_FS_32000:
 210                        srate = 32000;
 211                        break;
 212                default:
 213                        srate = XLNX_PARAM_UNKNOWN;
 214                        break;
 215                }
 216
 217                if (status[1] & IEC958_AES4_CON_MAX_WORDLEN_24)
 218                        padded = 4;
 219                else
 220                        padded = 0;
 221
 222                switch (status[1] & IEC958_AES4_CON_WORDLEN) {
 223                case IEC958_AES4_CON_WORDLEN_20_16:
 224                        bit_depth = 16 + padded;
 225                        break;
 226                case IEC958_AES4_CON_WORDLEN_22_18:
 227                        bit_depth = 18 + padded;
 228                        break;
 229                case IEC958_AES4_CON_WORDLEN_23_19:
 230                        bit_depth = 19 + padded;
 231                        break;
 232                case IEC958_AES4_CON_WORDLEN_24_20:
 233                        bit_depth = 20 + padded;
 234                        break;
 235                case IEC958_AES4_CON_WORDLEN_21_17:
 236                        bit_depth = 17 + padded;
 237                        break;
 238                case IEC958_AES4_CON_WORDLEN_NOTID:
 239                default:
 240                        bit_depth = XLNX_PARAM_UNKNOWN;
 241                        break;
 242                }
 243        }
 244
 245log_params:
 246        if (srate != XLNX_PARAM_UNKNOWN)
 247                dev_info(dev, "sample rate = %d\n", srate);
 248        else
 249                dev_info(dev, "sample rate = unknown\n");
 250
 251        if (bit_depth != XLNX_PARAM_UNKNOWN)
 252                dev_info(dev, "bit_depth = %d\n", bit_depth);
 253        else
 254                dev_info(dev, "bit_depth = unknown\n");
 255}
 256
 257static int xlnx_formatter_pcm_reset(void __iomem *mmio_base)
 258{
 259        u32 val, retries = 0;
 260
 261        val = ioread32(mmio_base + XLNX_AUD_CTRL);
 262        val |= AUD_CTRL_RESET_MASK;
 263        iowrite32(val, mmio_base + XLNX_AUD_CTRL);
 264
 265        val = ioread32(mmio_base + XLNX_AUD_CTRL);
 266        /* Poll for maximum timeout of approximately 100ms (1 * 100)*/
 267        while ((val & AUD_CTRL_RESET_MASK) && (retries < 100)) {
 268                mdelay(1);
 269                retries++;
 270                val = ioread32(mmio_base + XLNX_AUD_CTRL);
 271        }
 272        if (val & AUD_CTRL_RESET_MASK)
 273                return -ENODEV;
 274
 275        return 0;
 276}
 277
 278static void xlnx_formatter_disable_irqs(void __iomem *mmio_base, int stream)
 279{
 280        u32 val;
 281
 282        val = ioread32(mmio_base + XLNX_AUD_CTRL);
 283        val &= ~AUD_CTRL_IOC_IRQ_MASK;
 284        if (stream == SNDRV_PCM_STREAM_CAPTURE)
 285                val &= ~AUD_CTRL_TOUT_IRQ_MASK;
 286
 287        iowrite32(val, mmio_base + XLNX_AUD_CTRL);
 288}
 289
 290static irqreturn_t xlnx_mm2s_irq_handler(int irq, void *arg)
 291{
 292        u32 val;
 293        void __iomem *reg;
 294        struct device *dev = arg;
 295        struct xlnx_pcm_drv_data *adata = dev_get_drvdata(dev);
 296
 297        reg = adata->mmio + XLNX_MM2S_OFFSET + XLNX_AUD_STS;
 298        val = ioread32(reg);
 299        if (val & AUD_STS_IOC_IRQ_MASK) {
 300                iowrite32(val & AUD_STS_IOC_IRQ_MASK, reg);
 301                if (adata->play_stream)
 302                        snd_pcm_period_elapsed(adata->play_stream);
 303                return IRQ_HANDLED;
 304        }
 305
 306        return IRQ_NONE;
 307}
 308
 309static irqreturn_t xlnx_s2mm_irq_handler(int irq, void *arg)
 310{
 311        u32 val;
 312        void __iomem *reg;
 313        struct device *dev = arg;
 314        struct xlnx_pcm_drv_data *adata = dev_get_drvdata(dev);
 315
 316        reg = adata->mmio + XLNX_S2MM_OFFSET + XLNX_AUD_STS;
 317        val = ioread32(reg);
 318        if (val & AUD_STS_IOC_IRQ_MASK) {
 319                iowrite32(val & AUD_STS_IOC_IRQ_MASK, reg);
 320                if (adata->capture_stream)
 321                        snd_pcm_period_elapsed(adata->capture_stream);
 322                return IRQ_HANDLED;
 323        }
 324
 325        return IRQ_NONE;
 326}
 327
 328static int xlnx_formatter_pcm_open(struct snd_soc_component *component,
 329                               struct snd_pcm_substream *substream)
 330{
 331        int err;
 332        u32 val, data_format_mode;
 333        u32 ch_count_mask, ch_count_shift, data_xfer_mode, data_xfer_shift;
 334        struct xlnx_pcm_stream_param *stream_data;
 335        struct snd_pcm_runtime *runtime = substream->runtime;
 336        struct xlnx_pcm_drv_data *adata;
 337
 338        if (!component)
 339                return -ENODEV;
 340
 341        adata = dev_get_drvdata(component->dev);
 342
 343        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 344            !adata->mm2s_presence)
 345                return -ENODEV;
 346        else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
 347                 !adata->s2mm_presence)
 348                return -ENODEV;
 349
 350        stream_data = kzalloc(sizeof(*stream_data), GFP_KERNEL);
 351        if (!stream_data)
 352                return -ENOMEM;
 353
 354        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 355                ch_count_mask = CFG_MM2S_CH_MASK;
 356                ch_count_shift = CFG_MM2S_CH_SHIFT;
 357                data_xfer_mode = CFG_MM2S_XFER_MASK;
 358                data_xfer_shift = CFG_MM2S_XFER_SHIFT;
 359                data_format_mode = CFG_MM2S_PKG_MASK;
 360                stream_data->mmio = adata->mmio + XLNX_MM2S_OFFSET;
 361                adata->play_stream = substream;
 362
 363        } else {
 364                ch_count_mask = CFG_S2MM_CH_MASK;
 365                ch_count_shift = CFG_S2MM_CH_SHIFT;
 366                data_xfer_mode = CFG_S2MM_XFER_MASK;
 367                data_xfer_shift = CFG_S2MM_XFER_SHIFT;
 368                data_format_mode = CFG_S2MM_PKG_MASK;
 369                stream_data->mmio = adata->mmio + XLNX_S2MM_OFFSET;
 370                adata->capture_stream = substream;
 371        }
 372
 373        val = ioread32(adata->mmio + XLNX_AUD_CORE_CONFIG);
 374
 375        if (!(val & data_format_mode))
 376                stream_data->interleaved = true;
 377        else
 378                stream_data->interleaved = false;
 379
 380        stream_data->xfer_mode = (val & data_xfer_mode) >> data_xfer_shift;
 381        stream_data->ch_limit = (val & ch_count_mask) >> ch_count_shift;
 382        dev_info(component->dev,
 383                 "stream %d : format = %d mode = %d ch_limit = %d\n",
 384                 substream->stream, stream_data->interleaved,
 385                 stream_data->xfer_mode, stream_data->ch_limit);
 386
 387        snd_soc_set_runtime_hwparams(substream, &xlnx_pcm_hardware);
 388        runtime->private_data = stream_data;
 389
 390        /* Resize the period bytes as divisible by 64 */
 391        err = snd_pcm_hw_constraint_step(runtime, 0,
 392                                         SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
 393                                         XLNX_AUD_ALIGN_BYTES);
 394        if (err) {
 395                dev_err(component->dev,
 396                        "Unable to set constraint on period bytes\n");
 397                return err;
 398        }
 399        /* Resize the buffer bytes as divisible by 64 */
 400        err = snd_pcm_hw_constraint_step(runtime, 0,
 401                                         SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
 402                                         XLNX_AUD_ALIGN_BYTES);
 403        if (err) {
 404                dev_err(component->dev,
 405                        "Unable to set constraint on buffer bytes\n");
 406                return err;
 407        }
 408        /* Set periods as integer multiple */
 409        err = snd_pcm_hw_constraint_integer(runtime,
 410                                            SNDRV_PCM_HW_PARAM_PERIODS);
 411        if (err < 0) {
 412                dev_err(component->dev,
 413                        "Unable to set constraint on periods to be integer\n");
 414                return err;
 415        }
 416
 417        /* enable DMA IOC irq */
 418        val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
 419        val |= AUD_CTRL_IOC_IRQ_MASK;
 420        iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
 421
 422        return 0;
 423}
 424
 425static int xlnx_formatter_pcm_close(struct snd_soc_component *component,
 426                               struct snd_pcm_substream *substream)
 427{
 428        int ret;
 429        struct xlnx_pcm_stream_param *stream_data =
 430                        substream->runtime->private_data;
 431
 432        if (!component)
 433                return -ENODEV;
 434
 435        ret = xlnx_formatter_pcm_reset(stream_data->mmio);
 436        if (ret) {
 437                dev_err(component->dev, "audio formatter reset failed\n");
 438                goto err_reset;
 439        }
 440        xlnx_formatter_disable_irqs(stream_data->mmio, substream->stream);
 441
 442err_reset:
 443        kfree(stream_data);
 444        return 0;
 445}
 446
 447static snd_pcm_uframes_t
 448xlnx_formatter_pcm_pointer(struct snd_soc_component *component,
 449                                        struct snd_pcm_substream *substream)
 450{
 451        u32 pos;
 452        struct snd_pcm_runtime *runtime = substream->runtime;
 453        struct xlnx_pcm_stream_param *stream_data = runtime->private_data;
 454
 455        pos = ioread32(stream_data->mmio + XLNX_AUD_XFER_COUNT);
 456
 457        if (pos >= stream_data->buffer_size)
 458                pos = 0;
 459
 460        return bytes_to_frames(runtime, pos);
 461}
 462
 463static int xlnx_formatter_pcm_hw_params(struct snd_soc_component *component,
 464                                        struct snd_pcm_substream *substream,
 465                                        struct snd_pcm_hw_params *params)
 466{
 467        u32 low, high, active_ch, val, bits_per_sample, bytes_per_ch;
 468        u32 aes_reg1_val, aes_reg2_val;
 469        int status;
 470        u64 size;
 471        struct pl_card_data *prv;
 472        struct snd_pcm_runtime *runtime = substream->runtime;
 473        struct xlnx_pcm_stream_param *stream_data = runtime->private_data;
 474        struct xlnx_pcm_drv_data *adata;
 475        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 476
 477        if (!component)
 478                return -ENODEV;
 479
 480        adata = dev_get_drvdata(component->dev);
 481
 482        active_ch = params_channels(params);
 483        if (active_ch > stream_data->ch_limit)
 484                return -EINVAL;
 485
 486        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
 487            stream_data->xfer_mode == AES_TO_PCM &&
 488            ((strstr(adata->nodes[XLNX_CAPTURE]->name, "hdmi")) ||
 489            (strstr(adata->nodes[XLNX_CAPTURE]->name, "sdi")))) {
 490                /*
 491                 * If formatter is in AES_PCM mode for HDMI/SDI capture path,
 492                 * parse AES header
 493                 */
 494                val = ioread32(stream_data->mmio + XLNX_AUD_STS);
 495                if (val & AUD_STS_CH_STS_MASK) {
 496                        aes_reg1_val = ioread32(stream_data->mmio +
 497                                         XLNX_AUD_CH_STS_START);
 498                        aes_reg2_val = ioread32(stream_data->mmio +
 499                                         XLNX_AUD_CH_STS_START + 0x4);
 500
 501                        xlnx_parse_aes_params(aes_reg1_val, aes_reg2_val,
 502                                              component->dev);
 503                }
 504        }
 505
 506        size = params_buffer_bytes(params);
 507        status = snd_pcm_lib_malloc_pages(substream, size);
 508        if (status < 0)
 509                return status;
 510
 511        stream_data->buffer_size = size;
 512
 513        low = lower_32_bits(substream->dma_buffer.addr);
 514        high = upper_32_bits(substream->dma_buffer.addr);
 515        iowrite32(low, stream_data->mmio + XLNX_AUD_BUFF_ADDR_LSB);
 516        iowrite32(high, stream_data->mmio + XLNX_AUD_BUFF_ADDR_MSB);
 517
 518        val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
 519        val &= ~AUD_CTRL_DATA_WIDTH_MASK;
 520        bits_per_sample = params_width(params);
 521        switch (bits_per_sample) {
 522        case 8:
 523                val |= (BIT_DEPTH_8 << AUD_CTRL_DATA_WIDTH_SHIFT);
 524                break;
 525        case 16:
 526                val |= (BIT_DEPTH_16 << AUD_CTRL_DATA_WIDTH_SHIFT);
 527                break;
 528        case 20:
 529                val |= (BIT_DEPTH_20 << AUD_CTRL_DATA_WIDTH_SHIFT);
 530                break;
 531        case 24:
 532                val |= (BIT_DEPTH_24 << AUD_CTRL_DATA_WIDTH_SHIFT);
 533                break;
 534        case 32:
 535                val |= (BIT_DEPTH_32 << AUD_CTRL_DATA_WIDTH_SHIFT);
 536                break;
 537        }
 538
 539        val &= ~AUD_CTRL_ACTIVE_CH_MASK;
 540        val |= active_ch << AUD_CTRL_ACTIVE_CH_SHIFT;
 541        iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
 542
 543        val = (params_periods(params) << PERIOD_CFG_PERIODS_SHIFT)
 544                | params_period_bytes(params);
 545        iowrite32(val, stream_data->mmio + XLNX_AUD_PERIOD_CONFIG);
 546        bytes_per_ch = DIV_ROUND_UP(params_period_bytes(params), active_ch);
 547        iowrite32(bytes_per_ch, stream_data->mmio + XLNX_BYTES_PER_CH);
 548
 549        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 550                prv = snd_soc_card_get_drvdata(rtd->card);
 551                iowrite32(prv->mclk_ratio,
 552                          stream_data->mmio + XLNX_AUD_FS_MULTIPLIER);
 553        }
 554
 555        return 0;
 556}
 557
 558static int xlnx_formatter_pcm_hw_free(struct snd_soc_component *component,
 559                                        struct snd_pcm_substream *substream)
 560{
 561        return snd_pcm_lib_free_pages(substream);
 562}
 563
 564static int xlnx_formatter_pcm_trigger(struct snd_soc_component *component,
 565                                        struct snd_pcm_substream *substream, int cmd)
 566{
 567        u32 val;
 568        struct xlnx_pcm_stream_param *stream_data =
 569                        substream->runtime->private_data;
 570
 571        switch (cmd) {
 572        case SNDRV_PCM_TRIGGER_START:
 573        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 574        case SNDRV_PCM_TRIGGER_RESUME:
 575                val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
 576                val |= AUD_CTRL_DMA_EN_MASK;
 577                iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
 578                break;
 579        case SNDRV_PCM_TRIGGER_STOP:
 580        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 581        case SNDRV_PCM_TRIGGER_SUSPEND:
 582                val = ioread32(stream_data->mmio + XLNX_AUD_CTRL);
 583                val &= ~AUD_CTRL_DMA_EN_MASK;
 584                iowrite32(val, stream_data->mmio + XLNX_AUD_CTRL);
 585                break;
 586        }
 587
 588        return 0;
 589}
 590
 591static int xlnx_formatter_pcm_new(struct snd_soc_component *component,
 592                                        struct snd_soc_pcm_runtime *rtd)
 593{
 594        if (!component)
 595                return -ENODEV;
 596
 597        snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
 598                        SNDRV_DMA_TYPE_DEV, component->dev,
 599                        xlnx_pcm_hardware.buffer_bytes_max,
 600                        xlnx_pcm_hardware.buffer_bytes_max);
 601        return 0;
 602}
 603
 604static struct snd_soc_component_driver xlnx_asoc_component = {
 605        .name = DRV_NAME,
 606        .open = xlnx_formatter_pcm_open,
 607        .close = xlnx_formatter_pcm_close,
 608        .hw_params = xlnx_formatter_pcm_hw_params,
 609        .hw_free = xlnx_formatter_pcm_hw_free,
 610        .trigger = xlnx_formatter_pcm_trigger,
 611        .pointer = xlnx_formatter_pcm_pointer,
 612        .pcm_construct = xlnx_formatter_pcm_new,
 613};
 614
 615static int configure_mm2s(struct xlnx_pcm_drv_data *aud_drv_data,
 616                          struct platform_device *pdev)
 617{
 618        int ret;
 619        struct device *dev = &pdev->dev;
 620
 621        aud_drv_data->mm2s_axis_clk = devm_clk_get(dev, "m_axis_mm2s_aclk");
 622        if (IS_ERR(aud_drv_data->mm2s_axis_clk)) {
 623                ret = PTR_ERR(aud_drv_data->mm2s_axis_clk);
 624                dev_err(dev, "failed to get m_axis_mm2s_aclk(%d)\n", ret);
 625                return ret;
 626        }
 627        ret = clk_prepare_enable(aud_drv_data->mm2s_axis_clk);
 628        if (ret) {
 629                dev_err(dev, "failed to enable m_axis_mm2s_aclk(%d)\n", ret);
 630                return ret;
 631        }
 632
 633        aud_drv_data->aud_mclk = devm_clk_get(dev, "aud_mclk");
 634        if (IS_ERR(aud_drv_data->aud_mclk)) {
 635                ret = PTR_ERR(aud_drv_data->aud_mclk);
 636                dev_err(dev, "failed to get aud_mclk(%d)\n", ret);
 637                goto axis_clk_err;
 638        }
 639        ret = clk_prepare_enable(aud_drv_data->aud_mclk);
 640        if (ret) {
 641                dev_err(dev, "failed to enable aud_mclk(%d)\n", ret);
 642                goto axis_clk_err;
 643        }
 644
 645        aud_drv_data->mm2s_irq = platform_get_irq_byname(pdev,
 646                                                         "irq_mm2s");
 647        if (aud_drv_data->mm2s_irq < 0) {
 648                ret = aud_drv_data->mm2s_irq;
 649                goto mm2s_err;
 650        }
 651        ret = devm_request_irq(dev, aud_drv_data->mm2s_irq,
 652                               xlnx_mm2s_irq_handler, 0,
 653                               "xlnx_formatter_pcm_mm2s_irq",
 654                               dev);
 655        if (ret) {
 656                dev_err(dev, "xlnx audio mm2s irq request failed\n");
 657                goto mm2s_err;
 658        }
 659        ret = xlnx_formatter_pcm_reset(aud_drv_data->mmio +
 660                                       XLNX_MM2S_OFFSET);
 661        if (ret) {
 662                dev_err(dev, "audio formatter reset failed\n");
 663                goto mm2s_err;
 664        }
 665        xlnx_formatter_disable_irqs(aud_drv_data->mmio +
 666                                    XLNX_MM2S_OFFSET,
 667                                    SNDRV_PCM_STREAM_PLAYBACK);
 668
 669        aud_drv_data->nodes[XLNX_PLAYBACK] =
 670                of_parse_phandle(dev->of_node, "xlnx,tx", 0);
 671        if (!aud_drv_data->nodes[XLNX_PLAYBACK])
 672                dev_err(dev, "tx node not found\n");
 673        else
 674                dev_info(dev,
 675                         "sound card device will use DAI link: %s\n",
 676                         (aud_drv_data->nodes[XLNX_PLAYBACK])->name);
 677        of_node_put(aud_drv_data->nodes[XLNX_PLAYBACK]);
 678
 679        aud_drv_data->mm2s_presence = true;
 680        return 0;
 681
 682mm2s_err:
 683        clk_disable_unprepare(aud_drv_data->aud_mclk);
 684axis_clk_err:
 685        clk_disable_unprepare(aud_drv_data->mm2s_axis_clk);
 686
 687        return ret;
 688}
 689
 690static int configure_s2mm(struct xlnx_pcm_drv_data *aud_drv_data,
 691                          struct platform_device *pdev)
 692{
 693        int ret;
 694        struct device *dev = &pdev->dev;
 695
 696        aud_drv_data->s2mm_axis_clk = devm_clk_get(dev, "s_axis_s2mm_aclk");
 697        if (IS_ERR(aud_drv_data->s2mm_axis_clk)) {
 698                ret = PTR_ERR(aud_drv_data->s2mm_axis_clk);
 699                dev_err(dev, "failed to get s_axis_s2mm_aclk(%d)\n", ret);
 700                return ret;
 701        }
 702        ret = clk_prepare_enable(aud_drv_data->s2mm_axis_clk);
 703        if (ret) {
 704                dev_err(dev, "failed to enable s_axis_s2mm_aclk(%d)\n", ret);
 705                return ret;
 706        }
 707
 708        aud_drv_data->s2mm_irq = platform_get_irq_byname(pdev, "irq_s2mm");
 709        if (aud_drv_data->s2mm_irq < 0) {
 710                ret = aud_drv_data->s2mm_irq;
 711                goto s2mm_err;
 712        }
 713        ret = devm_request_irq(dev, aud_drv_data->s2mm_irq,
 714                               xlnx_s2mm_irq_handler, 0,
 715                               "xlnx_formatter_pcm_s2mm_irq",
 716                               dev);
 717        if (ret) {
 718                dev_err(dev, "xlnx audio s2mm irq request failed\n");
 719                goto s2mm_err;
 720        }
 721        ret = xlnx_formatter_pcm_reset(aud_drv_data->mmio +
 722                                       XLNX_S2MM_OFFSET);
 723        if (ret) {
 724                dev_err(dev, "audio formatter reset failed\n");
 725                goto s2mm_err;
 726        }
 727        xlnx_formatter_disable_irqs(aud_drv_data->mmio +
 728                                    XLNX_S2MM_OFFSET,
 729                                    SNDRV_PCM_STREAM_CAPTURE);
 730
 731        aud_drv_data->nodes[XLNX_CAPTURE] =
 732                of_parse_phandle(dev->of_node, "xlnx,rx", 0);
 733        if (!aud_drv_data->nodes[XLNX_CAPTURE])
 734                dev_err(dev, "rx node not found\n");
 735        else
 736                dev_info(dev, "sound card device will use DAI link: %s\n",
 737                         (aud_drv_data->nodes[XLNX_CAPTURE])->name);
 738        of_node_put(aud_drv_data->nodes[XLNX_CAPTURE]);
 739
 740        aud_drv_data->s2mm_presence = true;
 741        return 0;
 742
 743s2mm_err:
 744        clk_disable_unprepare(aud_drv_data->s2mm_axis_clk);
 745        return ret;
 746}
 747
 748static int xlnx_formatter_pcm_probe(struct platform_device *pdev)
 749{
 750        int ret;
 751        u32 val;
 752        size_t pdata_size;
 753        struct xlnx_pcm_drv_data *aud_drv_data;
 754        struct device *dev = &pdev->dev;
 755
 756        aud_drv_data = devm_kzalloc(dev, sizeof(*aud_drv_data), GFP_KERNEL);
 757        if (!aud_drv_data)
 758                return -ENOMEM;
 759
 760        ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
 761        if (ret) {
 762                dev_err(dev, "higher dma address mapping failed %d\n", ret);
 763                return ret;
 764        }
 765
 766        aud_drv_data->axi_clk = devm_clk_get(dev, "s_axi_lite_aclk");
 767        if (IS_ERR(aud_drv_data->axi_clk)) {
 768                ret = PTR_ERR(aud_drv_data->axi_clk);
 769                dev_err(dev, "failed to get s_axi_lite_aclk(%d)\n", ret);
 770                return ret;
 771        }
 772        ret = clk_prepare_enable(aud_drv_data->axi_clk);
 773        if (ret) {
 774                dev_err(dev, "failed to enable s_axi_lite_aclk(%d)\n", ret);
 775                return ret;
 776        }
 777
 778        aud_drv_data->mmio = devm_platform_ioremap_resource(pdev, 0);
 779        if (IS_ERR(aud_drv_data->mmio)) {
 780                dev_err(dev, "audio formatter ioremap failed\n");
 781                ret = PTR_ERR(aud_drv_data->mmio);
 782                goto clk_err;
 783        }
 784
 785        val = ioread32(aud_drv_data->mmio + XLNX_AUD_CORE_CONFIG);
 786        if (val & AUD_CFG_MM2S_MASK) {
 787                ret = configure_mm2s(aud_drv_data, pdev);
 788                if (ret)
 789                        goto clk_err;
 790        }
 791
 792        if (val & AUD_CFG_S2MM_MASK) {
 793                ret = configure_s2mm(aud_drv_data, pdev);
 794                if (ret)
 795                        goto clk_err;
 796        }
 797
 798        dev_set_drvdata(dev, aud_drv_data);
 799
 800        ret = devm_snd_soc_register_component(dev, &xlnx_asoc_component,
 801                                              NULL, 0);
 802        if (ret) {
 803                dev_err(dev, "pcm platform device register failed\n");
 804                goto clk_err;
 805        }
 806
 807        pdata_size = sizeof(aud_drv_data->nodes);
 808        if (aud_drv_data->nodes[XLNX_PLAYBACK] ||
 809            aud_drv_data->nodes[XLNX_CAPTURE])
 810                aud_drv_data->pdev =
 811                        platform_device_register_resndata(dev, "xlnx_snd_card",
 812                                                          PLATFORM_DEVID_AUTO,
 813                                                          NULL, 0,
 814                                                          &aud_drv_data->nodes,
 815                                                          pdata_size);
 816        if (!aud_drv_data->pdev)
 817                dev_err(dev, "sound card device creation failed\n");
 818
 819        dev_info(dev, "pcm platform device registered\n");
 820        return 0;
 821
 822clk_err:
 823        clk_disable_unprepare(aud_drv_data->axi_clk);
 824        return ret;
 825}
 826
 827static int xlnx_formatter_pcm_remove(struct platform_device *pdev)
 828{
 829        int ret = 0;
 830        struct xlnx_pcm_drv_data *adata = dev_get_drvdata(&pdev->dev);
 831
 832        platform_device_unregister(adata->pdev);
 833
 834        if (adata->s2mm_presence)
 835                ret = xlnx_formatter_pcm_reset(adata->mmio + XLNX_S2MM_OFFSET);
 836
 837        /* Try MM2S reset, even if S2MM  reset fails */
 838        if (adata->mm2s_presence)
 839                ret = xlnx_formatter_pcm_reset(adata->mmio + XLNX_MM2S_OFFSET);
 840
 841        if (ret)
 842                dev_err(&pdev->dev, "audio formatter reset failed\n");
 843
 844        clk_disable_unprepare(adata->axi_clk);
 845        return ret;
 846}
 847
 848static const struct of_device_id xlnx_formatter_pcm_of_match[] = {
 849        { .compatible = "xlnx,audio-formatter-1.0"},
 850        {},
 851};
 852MODULE_DEVICE_TABLE(of, xlnx_formatter_pcm_of_match);
 853
 854static struct platform_driver xlnx_formatter_pcm_driver = {
 855        .probe  = xlnx_formatter_pcm_probe,
 856        .remove = xlnx_formatter_pcm_remove,
 857        .driver = {
 858                .name   = DRV_NAME,
 859                .of_match_table = xlnx_formatter_pcm_of_match,
 860        },
 861};
 862
 863module_platform_driver(xlnx_formatter_pcm_driver);
 864MODULE_AUTHOR("Maruthi Srinivas Bayyavarapu");
 865MODULE_LICENSE("GPL v2");
 866