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