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