^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) STMicroelectronics SA 2015
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * for STMicroelectronics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "uniperif.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Some hardware-related definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* sys config registers definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define SYS_CFG_AUDIO_GLUE 0xA4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Driver specific types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define UNIPERIF_PLAYER_CLK_ADJ_MIN -999999
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define UNIPERIF_PLAYER_CLK_ADJ_MAX 1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define UNIPERIF_PLAYER_I2S_OUT 1 /* player id connected to I2S/TDM TX bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Note: snd_pcm_hardware is linked to DMA controller but is declared here to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * integrate DAI_CPU capability in term of rate and supported channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static const struct snd_pcm_hardware uni_player_pcm_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) SNDRV_PCM_INFO_MMAP_VALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .rates = SNDRV_PCM_RATE_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .rate_max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .periods_max = 48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .period_bytes_min = 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .period_bytes_max = 64 * PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .buffer_bytes_max = 256 * PAGE_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * uni_player_irq_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * In case of error audio stream is stopped; stop action is protected via PCM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * stream lock to avoid race condition with trigger callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct uniperif *player = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) spin_lock(&player->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (!player->substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) goto irq_spin_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) snd_pcm_stream_lock(player->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (player->state == UNIPERIF_STATE_STOPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) goto stream_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Get interrupt status & clear them immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) status = GET_UNIPERIF_ITS(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) SET_UNIPERIF_ITS_BCLR(player, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* Check for fifo error (underrun) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(player))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) dev_err(player->dev, "FIFO underflow error detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Interrupt is just for information when underflow recovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (player->underflow_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Update state to underflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) player->state = UNIPERIF_STATE_UNDERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Disable interrupt so doesn't continually fire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Stop the player */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Check for dma error (overrun) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (unlikely(status & UNIPERIF_ITS_DMA_ERROR_MASK(player))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dev_err(player->dev, "DMA error detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Disable interrupt so doesn't continually fire */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Stop the player */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Check for underflow recovery done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!player->underflow_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) dev_err(player->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) "unexpected Underflow recovering\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) goto stream_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* Read the underflow recovery duration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dev_dbg(player->dev, "Underflow recovered (%d LR clocks max)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* Clear the underflow recovery duration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Update state to started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) player->state = UNIPERIF_STATE_STARTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Check if underflow recovery failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (unlikely(status &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(player))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) dev_err(player->dev, "Underflow recovery failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* Stop the player */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) stream_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) snd_pcm_stream_unlock(player->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) irq_spin_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) spin_unlock(&player->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int uni_player_clk_set_rate(struct uniperif *player, unsigned long rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int rate_adjusted, rate_achieved, delta, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int adjustment = player->clk_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * F = f + --------- * f = f + d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * 1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * d = --------- * f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * 1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * where:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * f - nominal rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * a - adjustment in ppm (parts per milion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * F - rate to be set in synthesizer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * d - delta (difference) between f and F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (adjustment < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* div64_64 operates on unsigned values... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) delta = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) adjustment = -adjustment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* 500000 ppm is 0.5, which is used to round up values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) delta *= (int)div64_u64((uint64_t)rate *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) (uint64_t)adjustment + 500000, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) rate_adjusted = rate + delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Adjusted rate should never be == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!rate_adjusted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ret = clk_set_rate(player->clk, rate_adjusted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) rate_achieved = clk_get_rate(player->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!rate_achieved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* If value is 0 means that clock or parent not valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * Using ALSA's adjustment control, we can modify the rate to be up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * to twice as much as requested, but no more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) delta = rate_achieved - rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (delta < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* div64_64 operates on unsigned values... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) delta = -delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) adjustment = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) adjustment = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Frequency/2 is added to round up result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) adjustment *= (int)div64_u64((uint64_t)delta * 1000000 + rate / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) player->clk_adj = adjustment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void uni_player_set_channel_status(struct uniperif *player,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * Some AVRs and TVs require the channel status to contain a correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * sampling frequency. If no sample rate is already specified, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * set one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (runtime) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) switch (runtime->rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) IEC958_AES3_CON_FS_22050;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) IEC958_AES3_CON_FS_44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) IEC958_AES3_CON_FS_88200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) IEC958_AES3_CON_FS_176400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case 24000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) IEC958_AES3_CON_FS_24000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) IEC958_AES3_CON_FS_48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) IEC958_AES3_CON_FS_96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) IEC958_AES3_CON_FS_192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) IEC958_AES3_CON_FS_32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* Mark as sampling frequency not indicated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) IEC958_AES3_CON_FS_NOTID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Audio mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Use audio mode status to select PCM or encoded mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (player->stream_settings.iec958.status[0] & IEC958_AES0_NONAUDIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) player->stream_settings.encoding_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) UNIPERIF_IEC958_ENCODING_MODE_ENCODED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) player->stream_settings.encoding_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) UNIPERIF_IEC958_ENCODING_MODE_PCM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (player->stream_settings.encoding_mode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) UNIPERIF_IEC958_ENCODING_MODE_PCM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* Clear user validity bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Set user validity bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* Program the new channel status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) for (n = 0; n < 6; ++n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) player->stream_settings.iec958.status[0 + (n * 4)] & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) status |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) player->stream_settings.iec958.status[1 + (n * 4)] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) status |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) player->stream_settings.iec958.status[2 + (n * 4)] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) status |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) player->stream_settings.iec958.status[3 + (n * 4)] << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* Update the channel status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int uni_player_prepare_iec958(struct uniperif *player,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) int clk_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) clk_div = player->mclk / runtime->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Oversampling must be multiple of 128 as iec958 frame is 32-bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if ((clk_div % 128) || (clk_div <= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dev_err(player->dev, "%s: invalid clk_div %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) __func__, clk_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) switch (runtime->format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* 16/16 memory format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* 16-bits per sub-frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) SET_UNIPERIF_I2S_FMT_NBIT_32(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* Set 16-bit sample precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case SNDRV_PCM_FORMAT_S32_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* 16/0 memory format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* 32-bits per sub-frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) SET_UNIPERIF_I2S_FMT_NBIT_32(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* Set 24-bit sample precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev_err(player->dev, "format not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Set parity to be calculated by the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* Set channel status bits to be inserted by the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Set user data bits to be inserted by the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* Set validity bits to be inserted by the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Set full software control to disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) mutex_lock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Update the channel status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) uni_player_set_channel_status(player, runtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mutex_unlock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Clear the user validity user bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* Disable one-bit audio mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Enable consecutive frames repetition of Z preamble (not for HBRA) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Change to SUF0_SUBF1 and left/right channels swap! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Set data output as MSB first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (player->stream_settings.encoding_mode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) UNIPERIF_IEC958_ENCODING_MODE_ENCODED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* Set rounding to off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* Set clock divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Set the spdif latency to not wait before starting player */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * Ensure iec958 formatting is off. It will be enabled in function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * uni_player_start() at the same time as the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * mode is set to work around a silicon issue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static int uni_player_prepare_pcm(struct uniperif *player,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int output_frame_size, slot_width, clk_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Force slot width to 32 in I2S mode (HW constraint) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if ((player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) SND_SOC_DAIFMT_I2S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) slot_width = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) slot_width = snd_pcm_format_width(runtime->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) output_frame_size = slot_width * runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) clk_div = player->mclk / runtime->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * For 32 bits subframe clk_div must be a multiple of 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * for 16 bits must be a multiple of 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if ((slot_width == 32) && (clk_div % 128)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) dev_err(player->dev, "%s: invalid clk_div\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if ((slot_width == 16) && (clk_div % 64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev_err(player->dev, "%s: invalid clk_div\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Number of bits per subframe (which is one channel sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * on output - Transfer 16 or 32 bits from FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) switch (slot_width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) SET_UNIPERIF_I2S_FMT_NBIT_32(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) SET_UNIPERIF_I2S_FMT_NBIT_16(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dev_err(player->dev, "subframe format not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Configure data memory format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) switch (runtime->format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* One data word contains two samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case SNDRV_PCM_FORMAT_S32_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * on the left than zeros (if less than 32 bytes)"... ;-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dev_err(player->dev, "format not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* Set rounding to off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Set clock divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / (2 * output_frame_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Number of channelsmust be even*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if ((runtime->channels % 2) || (runtime->channels < 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) (runtime->channels > 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) dev_err(player->dev, "%s: invalid nb of channels\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* Set 1-bit audio format to disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* No iec958 formatting as outputting to DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static int uni_player_prepare_tdm(struct uniperif *player,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) int tdm_frame_size; /* unip tdm frame size in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int user_frame_size; /* user tdm frame size in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* default unip TDM_WORD_POS_X_Y */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned int word_pos[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int freq, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) tdm_frame_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) sti_uniperiph_get_unip_tdm_frame_size(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) user_frame_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) sti_uniperiph_get_user_frame_size(runtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* fix 16/0 format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* number of words inserted on the TDM line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) SET_UNIPERIF_I2S_FMT_NUM_CH(player, user_frame_size / 4 / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* Enable the tdm functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* number of 8 bits timeslots avail in unip tdm frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(player, tdm_frame_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* set the timeslot allocation for words in FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) sti_uniperiph_get_tdm_word_pos(player, word_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) SET_UNIPERIF_TDM_WORD_POS(player, 1_2, word_pos[WORD_1_2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) SET_UNIPERIF_TDM_WORD_POS(player, 3_4, word_pos[WORD_3_4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) SET_UNIPERIF_TDM_WORD_POS(player, 5_6, word_pos[WORD_5_6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) SET_UNIPERIF_TDM_WORD_POS(player, 7_8, word_pos[WORD_7_8]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* set unip clk rate (not done vai set_sysclk ops) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) freq = runtime->rate * tdm_frame_size * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) mutex_lock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = uni_player_clk_set_rate(player, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) player->mclk = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) mutex_unlock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * ALSA uniperipheral iec958 controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mutex_lock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ucontrol->value.iec958.status[0] = iec958->status[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ucontrol->value.iec958.status[1] = iec958->status[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ucontrol->value.iec958.status[2] = iec958->status[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ucontrol->value.iec958.status[3] = iec958->status[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) mutex_unlock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) mutex_lock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) iec958->status[0] = ucontrol->value.iec958.status[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) iec958->status[1] = ucontrol->value.iec958.status[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) iec958->status[2] = ucontrol->value.iec958.status[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) iec958->status[3] = ucontrol->value.iec958.status[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) spin_lock_irqsave(&player->irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (player->substream && player->substream->runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) uni_player_set_channel_status(player,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) player->substream->runtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) uni_player_set_channel_status(player, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) spin_unlock_irqrestore(&player->irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) mutex_unlock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static struct snd_kcontrol_new uni_player_iec958_ctl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .info = uni_player_ctl_iec958_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .get = uni_player_ctl_iec958_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .put = uni_player_ctl_iec958_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * uniperif rate adjustement control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) mutex_lock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) ucontrol->value.integer.value[0] = player->clk_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) mutex_unlock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static int snd_sti_clk_adjustment_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if ((ucontrol->value.integer.value[0] < UNIPERIF_PLAYER_CLK_ADJ_MIN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) (ucontrol->value.integer.value[0] > UNIPERIF_PLAYER_CLK_ADJ_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) mutex_lock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) player->clk_adj = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (player->mclk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ret = uni_player_clk_set_rate(player, player->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) mutex_unlock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static struct snd_kcontrol_new uni_player_clk_adj_ctl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) .name = "PCM Playback Oversampling Freq. Adjustment",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) .info = snd_sti_clk_adjustment_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) .get = snd_sti_clk_adjustment_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) .put = snd_sti_clk_adjustment_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) &uni_player_clk_adj_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static struct snd_kcontrol_new *snd_sti_iec_ctl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) &uni_player_iec958_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) &uni_player_clk_adj_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static int uni_player_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) spin_lock_irqsave(&player->irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) player->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) spin_unlock_irqrestore(&player->irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) player->clk_adj = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (!UNIPERIF_TYPE_IS_TDM(player))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* refine hw constraint in tdm mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) ret = snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sti_uniperiph_fix_tdm_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) player, SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return snd_pcm_hw_rule_add(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) sti_uniperiph_fix_tdm_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) player, SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static int uni_player_set_sysclk(struct snd_soc_dai *dai, int clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) unsigned int freq, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (UNIPERIF_TYPE_IS_TDM(player) || (dir == SND_SOC_CLOCK_IN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (clk_id != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) mutex_lock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret = uni_player_clk_set_rate(player, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) player->mclk = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) mutex_unlock(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static int uni_player_prepare(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) int transfer_size, trigger_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* The player should be stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (player->state != UNIPERIF_STATE_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dev_err(player->dev, "%s: invalid player state %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) player->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Calculate transfer size (in fifo cells and bytes) for frame count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (player->type == SND_ST_UNIPERIF_TYPE_TDM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* transfer size = user frame size (in 32 bits FIFO cell) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) transfer_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) sti_uniperiph_get_user_frame_size(runtime) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* Calculate number of empty cells available before asserting DREQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * FDMA_TRIGGER_LIMIT also controls when the state switches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * from OFF or STANDBY to AUDIO DATA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) trigger_limit = transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Trigger limit must be an even number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if ((!trigger_limit % 2) || (trigger_limit != 1 && transfer_size % 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(player))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_err(player->dev, "invalid trigger limit %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) trigger_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* Uniperipheral setup depends on player type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) switch (player->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) case SND_ST_UNIPERIF_TYPE_HDMI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ret = uni_player_prepare_iec958(player, runtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case SND_ST_UNIPERIF_TYPE_PCM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ret = uni_player_prepare_pcm(player, runtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) case SND_ST_UNIPERIF_TYPE_SPDIF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret = uni_player_prepare_iec958(player, runtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) case SND_ST_UNIPERIF_TYPE_TDM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ret = uni_player_prepare_tdm(player, runtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) dev_err(player->dev, "invalid player type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) switch (player->daifmt & SND_SOC_DAIFMT_INV_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case SND_SOC_DAIFMT_NB_NF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) case SND_SOC_DAIFMT_NB_IF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case SND_SOC_DAIFMT_IB_NF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case SND_SOC_DAIFMT_IB_IF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) switch (player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case SND_SOC_DAIFMT_I2S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case SND_SOC_DAIFMT_LEFT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case SND_SOC_DAIFMT_RIGHT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) dev_err(player->dev, "format not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(player, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return sti_uniperiph_reset(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static int uni_player_start(struct uniperif *player)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* The player should be stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (player->state != UNIPERIF_STATE_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dev_err(player->dev, "%s: invalid player state\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ret = clk_prepare_enable(player->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) dev_err(player->dev, "%s: Failed to enable clock\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* Clear any pending interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) SET_UNIPERIF_ITS_BCLR(player, GET_UNIPERIF_ITS(player));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* Set the interrupt mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) SET_UNIPERIF_ITM_BSET_DMA_ERROR(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* Enable underflow recovery interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (player->underflow_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ret = sti_uniperiph_reset(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) clk_disable_unprepare(player->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * Does not use IEC61937 features of the uniperipheral hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * Instead it performs IEC61937 in software and inserts it directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * into the audio data stream. As such, when encoded mode is selected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * linear pcm mode is still used, but with the differences of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * channel status bits set for encoded mode and the validity bits set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * If iec958 formatting is required for hdmi or spdif, then it must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * enabled after the operation mode is set. If set prior to this, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * will not take affect and hang the player.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (UNIPERIF_TYPE_IS_IEC958(player))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* Force channel status update (no update if clk disable) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* Update state to started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) player->state = UNIPERIF_STATE_STARTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) static int uni_player_stop(struct uniperif *player)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) /* The player should not be in stopped state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (player->state == UNIPERIF_STATE_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) dev_err(player->dev, "%s: invalid player state\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* Turn the player off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) SET_UNIPERIF_CTRL_OPERATION_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ret = sti_uniperiph_reset(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /* Disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) SET_UNIPERIF_ITM_BCLR(player, GET_UNIPERIF_ITM(player));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Disable clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) clk_disable_unprepare(player->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /* Update state to stopped and return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) player->state = UNIPERIF_STATE_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) int uni_player_resume(struct uniperif *player)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /* Select the frequency synthesizer clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (player->clk_sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ret = regmap_field_write(player->clk_sel, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dev_err(player->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) "%s: Failed to select freq synth clock\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) EXPORT_SYMBOL_GPL(uni_player_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) static int uni_player_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int cmd, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return uni_player_start(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return uni_player_stop(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return uni_player_resume(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static void uni_player_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct uniperif *player = priv->dai_data.uni;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) spin_lock_irqsave(&player->irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (player->state != UNIPERIF_STATE_STOPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /* Stop the player */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) uni_player_stop(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) player->substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) spin_unlock_irqrestore(&player->irq_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct uniperif *player)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct device_node *node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) struct reg_field regfield[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* PCM_CLK_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) REG_FIELD(SYS_CFG_AUDIO_GLUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 8 + player->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 8 + player->id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) /* PCMP_VALID_SEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) player->clk_sel = regmap_field_alloc(regmap, regfield[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) player->valid_sel = regmap_field_alloc(regmap, regfield[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) static const struct snd_soc_dai_ops uni_player_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .startup = uni_player_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .shutdown = uni_player_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .prepare = uni_player_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .trigger = uni_player_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .hw_params = sti_uniperiph_dai_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .set_fmt = sti_uniperiph_dai_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .set_sysclk = uni_player_set_sysclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .set_tdm_slot = sti_uniperiph_set_tdm_slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) int uni_player_init(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct uniperif *player)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) player->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) player->state = UNIPERIF_STATE_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) player->dai_ops = &uni_player_dai_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) ret = uni_player_parse_dt_audio_glue(pdev, player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) dev_err(player->dev, "Failed to parse DeviceTree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /* Underflow recovery is only supported on later ip revisions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) player->underflow_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (UNIPERIF_TYPE_IS_TDM(player))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) player->hw = &uni_tdm_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) player->hw = &uni_player_pcm_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* Get uniperif resource */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) player->clk = of_clk_get(pdev->dev.of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (IS_ERR(player->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) dev_err(player->dev, "Failed to get clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return PTR_ERR(player->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* Select the frequency synthesizer clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (player->clk_sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) ret = regmap_field_write(player->clk_sel, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) dev_err(player->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) "%s: Failed to select freq synth clock\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /* connect to I2S/TDM TX bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (player->valid_sel &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) (player->id == UNIPERIF_PLAYER_I2S_OUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) ret = regmap_field_write(player->valid_sel, player->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_err(player->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) "%s: unable to connect to tdm bus\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ret = devm_request_irq(&pdev->dev, player->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) uni_player_irq_handler, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dev_name(&pdev->dev), player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dev_err(player->dev, "unable to request IRQ %d\n", player->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) mutex_init(&player->ctrl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) spin_lock_init(&player->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /* Ensure that disabled by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (UNIPERIF_TYPE_IS_IEC958(player)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* Set default iec958 status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* Consumer, PCM, copyright, 2ch, mode 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) player->stream_settings.iec958.status[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /* Broadcast reception category */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) player->stream_settings.iec958.status[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) IEC958_AES1_CON_GENERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* Do not take into account source or channel number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) player->stream_settings.iec958.status[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) IEC958_AES2_CON_SOURCE_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /* Sampling frequency not indicated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) player->stream_settings.iec958.status[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) IEC958_AES3_CON_FS_NOTID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* Max sample word 24-bit, sample word length not indicated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) player->stream_settings.iec958.status[4] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) IEC958_AES4_CON_MAX_WORDLEN_24 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) IEC958_AES4_CON_WORDLEN_24_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) player->snd_ctrls = snd_sti_iec_ctl[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) player->snd_ctrls = snd_sti_pcm_ctl[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) EXPORT_SYMBOL_GPL(uni_player_init);