linux/sound/soc/sti/uniperif_reader.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) STMicroelectronics SA 2015
   3 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
   4 *          for STMicroelectronics.
   5 * License terms:  GNU General Public License (GPL), version 2
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/delay.h>
  10#include <linux/io.h>
  11
  12#include <sound/soc.h>
  13
  14#include "uniperif.h"
  15
  16/*
  17 * Note: snd_pcm_hardware is linked to DMA controller but is declared here to
  18 * integrate unireader capability in term of rate and supported channels
  19 */
  20static const struct snd_pcm_hardware uni_reader_pcm_hw = {
  21        .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  22                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
  23                SNDRV_PCM_INFO_MMAP_VALID,
  24        .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,
  25
  26        .rates = SNDRV_PCM_RATE_CONTINUOUS,
  27        .rate_min = 8000,
  28        .rate_max = 96000,
  29
  30        .channels_min = 2,
  31        .channels_max = 8,
  32
  33        .periods_min = 2,
  34        .periods_max = 48,
  35
  36        .period_bytes_min = 128,
  37        .period_bytes_max = 64 * PAGE_SIZE,
  38        .buffer_bytes_max = 256 * PAGE_SIZE
  39};
  40
  41/*
  42 * uni_reader_irq_handler
  43 * In case of error audio stream is stopped; stop action is protected via PCM
  44 * stream lock  to avoid race condition with trigger callback.
  45 */
  46static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id)
  47{
  48        irqreturn_t ret = IRQ_NONE;
  49        struct uniperif *reader = dev_id;
  50        unsigned int status;
  51
  52        if (reader->state == UNIPERIF_STATE_STOPPED) {
  53                /* Unexpected IRQ: do nothing */
  54                dev_warn(reader->dev, "unexpected IRQ ");
  55                return IRQ_HANDLED;
  56        }
  57
  58        /* Get interrupt status & clear them immediately */
  59        status = GET_UNIPERIF_ITS(reader);
  60        SET_UNIPERIF_ITS_BCLR(reader, status);
  61
  62        /* Check for fifo overflow error */
  63        if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) {
  64                dev_err(reader->dev, "FIFO error detected");
  65
  66                snd_pcm_stream_lock(reader->substream);
  67                snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN);
  68                snd_pcm_stream_unlock(reader->substream);
  69
  70                return IRQ_HANDLED;
  71        }
  72
  73        return ret;
  74}
  75
  76static int uni_reader_prepare_pcm(struct snd_pcm_runtime *runtime,
  77                                  struct uniperif *reader)
  78{
  79        int slot_width;
  80
  81        /* Force slot width to 32 in I2S mode */
  82        if ((reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK)
  83                == SND_SOC_DAIFMT_I2S) {
  84                slot_width = 32;
  85        } else {
  86                switch (runtime->format) {
  87                case SNDRV_PCM_FORMAT_S16_LE:
  88                        slot_width = 16;
  89                        break;
  90                default:
  91                        slot_width = 32;
  92                        break;
  93                }
  94        }
  95
  96        /* Number of bits per subframe (i.e one channel sample) on input. */
  97        switch (slot_width) {
  98        case 32:
  99                SET_UNIPERIF_I2S_FMT_NBIT_32(reader);
 100                SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader);
 101                break;
 102        case 16:
 103                SET_UNIPERIF_I2S_FMT_NBIT_16(reader);
 104                SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(reader);
 105                break;
 106        default:
 107                dev_err(reader->dev, "subframe format not supported");
 108                return -EINVAL;
 109        }
 110
 111        /* Configure data memory format */
 112        switch (runtime->format) {
 113        case SNDRV_PCM_FORMAT_S16_LE:
 114                /* One data word contains two samples */
 115                SET_UNIPERIF_CONFIG_MEM_FMT_16_16(reader);
 116                break;
 117
 118        case SNDRV_PCM_FORMAT_S32_LE:
 119                /*
 120                 * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
 121                 * on the MSB then zeros (if less than 32 bytes)"...
 122                 */
 123                SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader);
 124                break;
 125
 126        default:
 127                dev_err(reader->dev, "format not supported");
 128                return -EINVAL;
 129        }
 130
 131        /* Number of channels must be even */
 132        if ((runtime->channels % 2) || (runtime->channels < 2) ||
 133            (runtime->channels > 10)) {
 134                dev_err(reader->dev, "%s: invalid nb of channels", __func__);
 135                return -EINVAL;
 136        }
 137
 138        SET_UNIPERIF_I2S_FMT_NUM_CH(reader, runtime->channels / 2);
 139        SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader);
 140
 141        return 0;
 142}
 143
 144static int uni_reader_prepare_tdm(struct snd_pcm_runtime *runtime,
 145                                  struct uniperif *reader)
 146{
 147        int frame_size; /* user tdm frame size in bytes */
 148        /* default unip TDM_WORD_POS_X_Y */
 149        unsigned int word_pos[4] = {
 150                0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};
 151
 152        frame_size = sti_uniperiph_get_user_frame_size(runtime);
 153
 154        /* fix 16/0 format */
 155        SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader);
 156        SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader);
 157
 158        /* number of words inserted on the TDM line */
 159        SET_UNIPERIF_I2S_FMT_NUM_CH(reader, frame_size / 4 / 2);
 160
 161        SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader);
 162        SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
 163        SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(reader);
 164
 165        /*
 166         * set the timeslots allocation for words in FIFO
 167         *
 168         * HW bug: (LSB word < MSB word) => this config is not possible
 169         *         So if we want (LSB word < MSB) word, then it shall be
 170         *         handled by user
 171         */
 172        sti_uniperiph_get_tdm_word_pos(reader, word_pos);
 173        SET_UNIPERIF_TDM_WORD_POS(reader, 1_2, word_pos[WORD_1_2]);
 174        SET_UNIPERIF_TDM_WORD_POS(reader, 3_4, word_pos[WORD_3_4]);
 175        SET_UNIPERIF_TDM_WORD_POS(reader, 5_6, word_pos[WORD_5_6]);
 176        SET_UNIPERIF_TDM_WORD_POS(reader, 7_8, word_pos[WORD_7_8]);
 177
 178        return 0;
 179}
 180
 181static int uni_reader_prepare(struct snd_pcm_substream *substream,
 182                              struct snd_soc_dai *dai)
 183{
 184        struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
 185        struct uniperif *reader = priv->dai_data.uni;
 186        struct snd_pcm_runtime *runtime = substream->runtime;
 187        int transfer_size, trigger_limit, ret;
 188        int count = 10;
 189
 190        /* The reader should be stopped */
 191        if (reader->state != UNIPERIF_STATE_STOPPED) {
 192                dev_err(reader->dev, "%s: invalid reader state %d", __func__,
 193                        reader->state);
 194                return -EINVAL;
 195        }
 196
 197        /* Calculate transfer size (in fifo cells and bytes) for frame count */
 198        if (reader->info->type == SND_ST_UNIPERIF_TYPE_TDM) {
 199                /* transfer size = unip frame size (in 32 bits FIFO cell) */
 200                transfer_size =
 201                        sti_uniperiph_get_user_frame_size(runtime) / 4;
 202        } else {
 203                transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
 204        }
 205
 206        /* Calculate number of empty cells available before asserting DREQ */
 207        if (reader->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
 208                trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
 209        else
 210                /*
 211                 * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
 212                 * FDMA_TRIGGER_LIMIT also controls when the state switches
 213                 * from OFF or STANDBY to AUDIO DATA.
 214                 */
 215                trigger_limit = transfer_size;
 216
 217        /* Trigger limit must be an even number */
 218        if ((!trigger_limit % 2) ||
 219            (trigger_limit != 1 && transfer_size % 2) ||
 220            (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(reader))) {
 221                dev_err(reader->dev, "invalid trigger limit %d", trigger_limit);
 222                return -EINVAL;
 223        }
 224
 225        SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(reader, trigger_limit);
 226
 227        if (UNIPERIF_TYPE_IS_TDM(reader))
 228                ret = uni_reader_prepare_tdm(runtime, reader);
 229        else
 230                ret = uni_reader_prepare_pcm(runtime, reader);
 231        if (ret)
 232                return ret;
 233
 234        switch (reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 235        case SND_SOC_DAIFMT_I2S:
 236                SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
 237                SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(reader);
 238                break;
 239        case SND_SOC_DAIFMT_LEFT_J:
 240                SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
 241                SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
 242                break;
 243        case SND_SOC_DAIFMT_RIGHT_J:
 244                SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(reader);
 245                SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
 246                break;
 247        default:
 248                dev_err(reader->dev, "format not supported");
 249                return -EINVAL;
 250        }
 251
 252        /* Data clocking (changing) on the rising/falling edge */
 253        switch (reader->daifmt & SND_SOC_DAIFMT_INV_MASK) {
 254        case SND_SOC_DAIFMT_NB_NF:
 255                SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader);
 256                SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader);
 257                break;
 258        case SND_SOC_DAIFMT_NB_IF:
 259                SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader);
 260                SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader);
 261                break;
 262        case SND_SOC_DAIFMT_IB_NF:
 263                SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader);
 264                SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader);
 265                break;
 266        case SND_SOC_DAIFMT_IB_IF:
 267                SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader);
 268                SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader);
 269                break;
 270        }
 271
 272        /* Clear any pending interrupts */
 273        SET_UNIPERIF_ITS_BCLR(reader, GET_UNIPERIF_ITS(reader));
 274
 275        SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(reader, 0);
 276
 277        /* Set the interrupt mask */
 278        SET_UNIPERIF_ITM_BSET_DMA_ERROR(reader);
 279        SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
 280        SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader);
 281
 282        /* Enable underflow recovery interrupts */
 283        if (reader->info->underflow_enabled) {
 284                SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader);
 285                SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader);
 286        }
 287
 288        /* Reset uniperipheral reader */
 289        SET_UNIPERIF_SOFT_RST_SOFT_RST(reader);
 290
 291        while (GET_UNIPERIF_SOFT_RST_SOFT_RST(reader)) {
 292                udelay(5);
 293                count--;
 294        }
 295        if (!count) {
 296                dev_err(reader->dev, "Failed to reset uniperif");
 297                return -EIO;
 298        }
 299
 300        return 0;
 301}
 302
 303static int uni_reader_start(struct uniperif *reader)
 304{
 305        /* The reader should be stopped */
 306        if (reader->state != UNIPERIF_STATE_STOPPED) {
 307                dev_err(reader->dev, "%s: invalid reader state", __func__);
 308                return -EINVAL;
 309        }
 310
 311        /* Enable reader interrupts (and clear possible stalled ones) */
 312        SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(reader);
 313        SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
 314
 315        /* Launch the reader */
 316        SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(reader);
 317
 318        /* Update state to started */
 319        reader->state = UNIPERIF_STATE_STARTED;
 320        return 0;
 321}
 322
 323static int uni_reader_stop(struct uniperif *reader)
 324{
 325        /* The reader should not be in stopped state */
 326        if (reader->state == UNIPERIF_STATE_STOPPED) {
 327                dev_err(reader->dev, "%s: invalid reader state", __func__);
 328                return -EINVAL;
 329        }
 330
 331        /* Turn the reader off */
 332        SET_UNIPERIF_CTRL_OPERATION_OFF(reader);
 333
 334        /* Disable interrupts */
 335        SET_UNIPERIF_ITM_BCLR(reader, GET_UNIPERIF_ITM(reader));
 336
 337        /* Update state to stopped and return */
 338        reader->state = UNIPERIF_STATE_STOPPED;
 339
 340        return 0;
 341}
 342
 343static int  uni_reader_trigger(struct snd_pcm_substream *substream,
 344                               int cmd, struct snd_soc_dai *dai)
 345{
 346        struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
 347        struct uniperif *reader = priv->dai_data.uni;
 348
 349        switch (cmd) {
 350        case SNDRV_PCM_TRIGGER_START:
 351                return  uni_reader_start(reader);
 352        case SNDRV_PCM_TRIGGER_STOP:
 353                return  uni_reader_stop(reader);
 354        default:
 355                return -EINVAL;
 356        }
 357}
 358
 359static int uni_reader_startup(struct snd_pcm_substream *substream,
 360                              struct snd_soc_dai *dai)
 361{
 362        struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
 363        struct uniperif *reader = priv->dai_data.uni;
 364        int ret;
 365
 366        if (!UNIPERIF_TYPE_IS_TDM(reader))
 367                return 0;
 368
 369        /* refine hw constraint in tdm mode */
 370        ret = snd_pcm_hw_rule_add(substream->runtime, 0,
 371                                  SNDRV_PCM_HW_PARAM_CHANNELS,
 372                                  sti_uniperiph_fix_tdm_chan,
 373                                  reader, SNDRV_PCM_HW_PARAM_CHANNELS,
 374                                  -1);
 375        if (ret < 0)
 376                return ret;
 377
 378        return snd_pcm_hw_rule_add(substream->runtime, 0,
 379                                   SNDRV_PCM_HW_PARAM_FORMAT,
 380                                   sti_uniperiph_fix_tdm_format,
 381                                   reader, SNDRV_PCM_HW_PARAM_FORMAT,
 382                                   -1);
 383}
 384
 385static void uni_reader_shutdown(struct snd_pcm_substream *substream,
 386                                struct snd_soc_dai *dai)
 387{
 388        struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
 389        struct uniperif *reader = priv->dai_data.uni;
 390
 391        if (reader->state != UNIPERIF_STATE_STOPPED) {
 392                /* Stop the reader */
 393                uni_reader_stop(reader);
 394        }
 395}
 396
 397static int uni_reader_parse_dt(struct platform_device *pdev,
 398                               struct uniperif *reader)
 399{
 400        struct uniperif_info *info;
 401        struct device_node *node = pdev->dev.of_node;
 402        const char *mode;
 403
 404        /* Allocate memory for the info structure */
 405        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 406        if (!info)
 407                return -ENOMEM;
 408
 409        if (of_property_read_u32(node, "st,version", &reader->ver) ||
 410            reader->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
 411                dev_err(&pdev->dev, "Unknown uniperipheral version ");
 412                return -EINVAL;
 413        }
 414
 415        /* Read the device mode property */
 416        if (of_property_read_string(node, "st,mode", &mode)) {
 417                dev_err(&pdev->dev, "uniperipheral mode not defined");
 418                return -EINVAL;
 419        }
 420
 421        if (strcasecmp(mode, "tdm") == 0)
 422                info->type = SND_ST_UNIPERIF_TYPE_TDM;
 423        else
 424                info->type = SND_ST_UNIPERIF_TYPE_PCM;
 425
 426        /* Save the info structure */
 427        reader->info = info;
 428
 429        return 0;
 430}
 431
 432static const struct snd_soc_dai_ops uni_reader_dai_ops = {
 433                .startup = uni_reader_startup,
 434                .shutdown = uni_reader_shutdown,
 435                .prepare = uni_reader_prepare,
 436                .trigger = uni_reader_trigger,
 437                .hw_params = sti_uniperiph_dai_hw_params,
 438                .set_fmt = sti_uniperiph_dai_set_fmt,
 439                .set_tdm_slot = sti_uniperiph_set_tdm_slot
 440};
 441
 442int uni_reader_init(struct platform_device *pdev,
 443                    struct uniperif *reader)
 444{
 445        int ret = 0;
 446
 447        reader->dev = &pdev->dev;
 448        reader->state = UNIPERIF_STATE_STOPPED;
 449        reader->dai_ops = &uni_reader_dai_ops;
 450
 451        ret = uni_reader_parse_dt(pdev, reader);
 452        if (ret < 0) {
 453                dev_err(reader->dev, "Failed to parse DeviceTree");
 454                return ret;
 455        }
 456
 457        if (UNIPERIF_TYPE_IS_TDM(reader))
 458                reader->hw = &uni_tdm_hw;
 459        else
 460                reader->hw = &uni_reader_pcm_hw;
 461
 462        ret = devm_request_irq(&pdev->dev, reader->irq,
 463                               uni_reader_irq_handler, IRQF_SHARED,
 464                               dev_name(&pdev->dev), reader);
 465        if (ret < 0) {
 466                dev_err(&pdev->dev, "Failed to request IRQ");
 467                return -EBUSY;
 468        }
 469
 470        return 0;
 471}
 472EXPORT_SYMBOL_GPL(uni_reader_init);
 473