Lines Matching +full:asrc +full:- +full:format
1 // SPDX-License-Identifier: GPL-2.0
3 // Freescale ASRC ALSA SoC Digital Audio Interface (DAI) driver
11 #include <linux/dma-mapping.h>
14 #include <linux/dma/imx-dma.h>
26 dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
29 dev_dbg(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
32 dev_warn(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
159 * fsl_asrc_sel_proc - Select the pre-processing and post-processing options
162 * @pre_proc: return value for pre-processing option
163 * @post_proc: return value for post-processing option
192 /* Condition for selection of post-processing */ in fsl_asrc_sel_proc()
206 * fsl_asrc_request_pair - Request ASRC pair
210 * It assigns pair by the order of A->C->B because allocation of pair B,
211 * within range [ANCA, ANCA+ANCB-1], depends on the channels of pair A
217 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_request_pair() local
218 struct device *dev = &asrc->pdev->dev; in fsl_asrc_request_pair()
222 spin_lock_irqsave(&asrc->lock, lock_flags); in fsl_asrc_request_pair()
225 if (asrc->pair[i] != NULL) in fsl_asrc_request_pair()
236 ret = -EBUSY; in fsl_asrc_request_pair()
237 } else if (asrc->channel_avail < channels) { in fsl_asrc_request_pair()
239 ret = -EINVAL; in fsl_asrc_request_pair()
241 asrc->channel_avail -= channels; in fsl_asrc_request_pair()
242 asrc->pair[index] = pair; in fsl_asrc_request_pair()
243 pair->channels = channels; in fsl_asrc_request_pair()
244 pair->index = index; in fsl_asrc_request_pair()
247 spin_unlock_irqrestore(&asrc->lock, lock_flags); in fsl_asrc_request_pair()
253 * fsl_asrc_release_pair - Release ASRC pair
256 * It clears the resource from asrc and releases the occupied channels.
260 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_release_pair() local
261 enum asrc_pair_index index = pair->index; in fsl_asrc_release_pair()
265 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_release_pair()
268 spin_lock_irqsave(&asrc->lock, lock_flags); in fsl_asrc_release_pair()
270 asrc->channel_avail += pair->channels; in fsl_asrc_release_pair()
271 asrc->pair[index] = NULL; in fsl_asrc_release_pair()
272 pair->error = 0; in fsl_asrc_release_pair()
274 spin_unlock_irqrestore(&asrc->lock, lock_flags); in fsl_asrc_release_pair()
278 * fsl_asrc_set_watermarks- configure input and output thresholds
285 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_set_watermarks() local
286 enum asrc_pair_index index = pair->index; in fsl_asrc_set_watermarks()
288 regmap_update_bits(asrc->regmap, REG_ASRMCR(index), in fsl_asrc_set_watermarks()
298 * fsl_asrc_cal_asrck_divisor - Calculate the total divisor between asrck clock rate and sample rate
312 return ((div - 1) << ASRCDRi_AxCPi_WIDTH) | ps; in fsl_asrc_cal_asrck_divisor()
316 * fsl_asrc_set_ideal_ratio - Calculate and set the ratio for Ideal Ratio mode only
321 * The ratio is a 32-bit fixed point value with 26 fractional bits.
326 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_set_ideal_ratio() local
327 enum asrc_pair_index index = pair->index; in fsl_asrc_set_ideal_ratio()
333 return -EINVAL; in fsl_asrc_set_ideal_ratio()
348 ratio |= 1 << (IDEAL_RATIO_DECIMAL_DEPTH - i); in fsl_asrc_set_ideal_ratio()
349 inrate -= outrate; in fsl_asrc_set_ideal_ratio()
355 regmap_write(asrc->regmap, REG_ASRIDRL(index), ratio); in fsl_asrc_set_ideal_ratio()
356 regmap_write(asrc->regmap, REG_ASRIDRH(index), ratio >> 24); in fsl_asrc_set_ideal_ratio()
362 * fsl_asrc_config_pair - Configure the assigned ASRC pair
366 * It configures those ASRC registers according to a configuration instance
372 * Using IDEAL_RATIO_RATE gives a faster converting speed but overloads ASRC.
379 struct fsl_asrc_pair_priv *pair_priv = pair->private; in fsl_asrc_config_pair()
380 struct asrc_config *config = pair_priv->config; in fsl_asrc_config_pair()
381 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_config_pair() local
382 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_config_pair()
383 enum asrc_pair_index index = pair->index; in fsl_asrc_config_pair()
396 return -EINVAL; in fsl_asrc_config_pair()
400 if (config->channel_num < 1 || config->channel_num > 10) { in fsl_asrc_config_pair()
401 pair_err("does not support %d channels\n", config->channel_num); in fsl_asrc_config_pair()
402 return -EINVAL; in fsl_asrc_config_pair()
405 switch (snd_pcm_format_width(config->input_format)) { in fsl_asrc_config_pair()
416 pair_err("does not support this input format, %d\n", in fsl_asrc_config_pair()
417 config->input_format); in fsl_asrc_config_pair()
418 return -EINVAL; in fsl_asrc_config_pair()
421 switch (snd_pcm_format_width(config->output_format)) { in fsl_asrc_config_pair()
429 pair_err("does not support this output format, %d\n", in fsl_asrc_config_pair()
430 config->output_format); in fsl_asrc_config_pair()
431 return -EINVAL; in fsl_asrc_config_pair()
434 inrate = config->input_sample_rate; in fsl_asrc_config_pair()
435 outrate = config->output_sample_rate; in fsl_asrc_config_pair()
436 ideal = config->inclk == INCLK_NONE; in fsl_asrc_config_pair()
445 return -EINVAL; in fsl_asrc_config_pair()
454 return -EINVAL; in fsl_asrc_config_pair()
461 return -EINVAL; in fsl_asrc_config_pair()
465 clk_index[IN] = asrc_priv->clk_map[IN][config->inclk]; in fsl_asrc_config_pair()
466 clk_index[OUT] = asrc_priv->clk_map[OUT][config->outclk]; in fsl_asrc_config_pair()
469 clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]]; in fsl_asrc_config_pair()
475 * The divider range is [1, 1024], defined by the hardware. For non- in fsl_asrc_config_pair()
484 return -EINVAL; in fsl_asrc_config_pair()
489 clk = asrc_priv->asrck_clk[clk_index[OUT]]; in fsl_asrc_config_pair()
500 return -EINVAL; in fsl_asrc_config_pair()
506 channels = config->channel_num; in fsl_asrc_config_pair()
508 if (asrc_priv->soc->channel_bits < 4) in fsl_asrc_config_pair()
512 regmap_update_bits(asrc->regmap, REG_ASRCNCR, in fsl_asrc_config_pair()
513 ASRCNCR_ANCi_MASK(index, asrc_priv->soc->channel_bits), in fsl_asrc_config_pair()
514 ASRCNCR_ANCi(index, channels, asrc_priv->soc->channel_bits)); in fsl_asrc_config_pair()
517 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_config_pair()
519 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_config_pair()
524 regmap_update_bits(asrc->regmap, REG_ASRCSR, in fsl_asrc_config_pair()
534 regmap_update_bits(asrc->regmap, REG_ASRCDR(index), in fsl_asrc_config_pair()
540 regmap_update_bits(asrc->regmap, REG_ASRMCR1(index), in fsl_asrc_config_pair()
546 regmap_update_bits(asrc->regmap, REG_ASRMCR(index), in fsl_asrc_config_pair()
558 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_config_pair()
562 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_config_pair()
568 /* Apply configurations for pre- and post-processing */ in fsl_asrc_config_pair()
569 regmap_update_bits(asrc->regmap, REG_ASRCFG, in fsl_asrc_config_pair()
578 * fsl_asrc_start_pair - Start the assigned ASRC pair
585 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_start_pair() local
586 enum asrc_pair_index index = pair->index; in fsl_asrc_start_pair()
590 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_start_pair()
596 regmap_read(asrc->regmap, REG_ASRCFG, ®); in fsl_asrc_start_pair()
598 } while (!reg && --retry); in fsl_asrc_start_pair()
604 /* Make the input fifo to ASRC STALL level */ in fsl_asrc_start_pair()
605 regmap_read(asrc->regmap, REG_ASRCNCR, ®); in fsl_asrc_start_pair()
606 for (i = 0; i < pair->channels * 4; i++) in fsl_asrc_start_pair()
607 regmap_write(asrc->regmap, REG_ASRDI(index), 0); in fsl_asrc_start_pair()
610 regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE); in fsl_asrc_start_pair()
614 * fsl_asrc_stop_pair - Stop the assigned ASRC pair
619 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_stop_pair() local
620 enum asrc_pair_index index = pair->index; in fsl_asrc_stop_pair()
623 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_stop_pair()
628 * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
635 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_get_dma_channel() local
636 enum asrc_pair_index index = pair->index; in fsl_asrc_get_dma_channel()
641 return dma_request_slave_channel(&asrc->pdev->dev, name); in fsl_asrc_get_dma_channel()
647 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai); in fsl_asrc_dai_startup() local
648 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_dai_startup()
650 /* Odd channel number is not valid for older ASRC (channel_bits==3) */ in fsl_asrc_dai_startup()
651 if (asrc_priv->soc->channel_bits == 3) in fsl_asrc_dai_startup()
652 snd_pcm_hw_constraint_step(substream->runtime, 0, in fsl_asrc_dai_startup()
656 return snd_pcm_hw_constraint_list(substream->runtime, 0, in fsl_asrc_dai_startup()
666 struct fsl_asrc_pair_priv *pair_priv = pair->private; in fsl_asrc_select_clk()
667 struct asrc_config *config = pair_priv->config; in fsl_asrc_select_clk()
678 clk_index = asrc_priv->clk_map[j][i]; in fsl_asrc_select_clk()
679 clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]); in fsl_asrc_select_clk()
694 config->inclk = select_clk[IN]; in fsl_asrc_select_clk()
695 config->outclk = select_clk[OUT]; in fsl_asrc_select_clk()
702 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai); in fsl_asrc_dai_hw_params() local
703 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_dai_hw_params()
704 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dai_hw_params()
705 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dai_hw_params()
706 struct fsl_asrc_pair_priv *pair_priv = pair->private; in fsl_asrc_dai_hw_params()
714 dev_err(dai->dev, "fail to request asrc pair\n"); in fsl_asrc_dai_hw_params()
718 pair_priv->config = &config; in fsl_asrc_dai_hw_params()
720 config.pair = pair->index; in fsl_asrc_dai_hw_params()
723 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in fsl_asrc_dai_hw_params()
725 config.output_format = asrc->asrc_format; in fsl_asrc_dai_hw_params()
727 config.output_sample_rate = asrc->asrc_rate; in fsl_asrc_dai_hw_params()
729 config.input_format = asrc->asrc_format; in fsl_asrc_dai_hw_params()
731 config.input_sample_rate = asrc->asrc_rate; in fsl_asrc_dai_hw_params()
741 dev_err(dai->dev, "fail to config asrc pair\n"); in fsl_asrc_dai_hw_params()
751 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dai_hw_free()
752 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dai_hw_free()
763 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dai_trigger()
764 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dai_trigger()
778 return -EINVAL; in fsl_asrc_dai_trigger()
786 struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai); in fsl_asrc_dai_probe() local
788 snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx, in fsl_asrc_dai_probe()
789 &asrc->dma_params_rx); in fsl_asrc_dai_probe()
808 .stream_name = "ASRC-Playback",
818 .stream_name = "ASRC-Capture",
973 * fsl_asrc_init - Initialize ASRC registers with a default configuration
974 * @asrc: ASRC context
976 static int fsl_asrc_init(struct fsl_asrc *asrc) in fsl_asrc_init() argument
980 /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */ in fsl_asrc_init()
981 regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN); in fsl_asrc_init()
984 regmap_write(asrc->regmap, REG_ASRIER, 0x0); in fsl_asrc_init()
987 regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff); in fsl_asrc_init()
988 regmap_write(asrc->regmap, REG_ASRPM2, 0x255555); in fsl_asrc_init()
989 regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280); in fsl_asrc_init()
990 regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280); in fsl_asrc_init()
991 regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280); in fsl_asrc_init()
994 regmap_update_bits(asrc->regmap, REG_ASRTFR1, in fsl_asrc_init()
999 * the ASRC processing clock. in fsl_asrc_init()
1002 ipg_rate = clk_get_rate(asrc->ipg_clk); in fsl_asrc_init()
1003 regmap_write(asrc->regmap, REG_ASR76K, ipg_rate / 76000); in fsl_asrc_init()
1004 return regmap_write(asrc->regmap, REG_ASR56K, ipg_rate / 56000); in fsl_asrc_init()
1008 * fsl_asrc_isr- Interrupt handler for ASRC
1010 * @dev_id: ASRC context
1014 struct fsl_asrc *asrc = (struct fsl_asrc *)dev_id; in fsl_asrc_isr() local
1015 struct device *dev = &asrc->pdev->dev; in fsl_asrc_isr()
1019 regmap_read(asrc->regmap, REG_ASRSTR, &status); in fsl_asrc_isr()
1022 regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE); in fsl_asrc_isr()
1025 * We here use dev_dbg() for all exceptions because ASRC itself does in fsl_asrc_isr()
1030 if (!asrc->pair[index]) in fsl_asrc_isr()
1034 asrc->pair[index]->error |= ASRC_TASK_Q_OVERLOAD; in fsl_asrc_isr()
1035 dev_dbg(dev, "ASRC Task Queue FIFO overload\n"); in fsl_asrc_isr()
1039 asrc->pair[index]->error |= ASRC_OUTPUT_TASK_OVERLOAD; in fsl_asrc_isr()
1044 asrc->pair[index]->error |= ASRC_INPUT_TASK_OVERLOAD; in fsl_asrc_isr()
1049 asrc->pair[index]->error |= ASRC_OUTPUT_BUFFER_OVERFLOW; in fsl_asrc_isr()
1054 asrc->pair[index]->error |= ASRC_INPUT_BUFFER_UNDERRUN; in fsl_asrc_isr()
1070 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_get_output_fifo_size() local
1071 enum asrc_pair_index index = pair->index; in fsl_asrc_get_output_fifo_size()
1074 regmap_read(asrc->regmap, REG_ASRFST(index), &val); in fsl_asrc_get_output_fifo_size()
1083 struct fsl_asrc_pair_priv *pair_priv = pair->private; in fsl_asrc_m2m_prepare()
1084 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_m2m_prepare() local
1085 struct device *dev = &asrc->pdev->dev; in fsl_asrc_m2m_prepare()
1090 config.pair = pair->index; in fsl_asrc_m2m_prepare()
1091 config.channel_num = pair->channels; in fsl_asrc_m2m_prepare()
1092 config.input_sample_rate = pair->rate[IN]; in fsl_asrc_m2m_prepare()
1093 config.output_sample_rate = pair->rate[OUT]; in fsl_asrc_m2m_prepare()
1094 config.input_format = pair->sample_format[IN]; in fsl_asrc_m2m_prepare()
1095 config.output_format = pair->sample_format[OUT]; in fsl_asrc_m2m_prepare()
1099 pair_priv->config = &config; in fsl_asrc_m2m_prepare()
1106 pair->first_convert = 1; in fsl_asrc_m2m_prepare()
1113 if (pair->first_convert) { in fsl_asrc_m2m_start()
1115 pair->first_convert = 0; in fsl_asrc_m2m_start()
1118 * Clear DMA request during the stall state of ASRC: in fsl_asrc_m2m_start()
1135 if (!pair->first_convert) { in fsl_asrc_m2m_stop()
1137 pair->first_convert = 1; in fsl_asrc_m2m_stop()
1147 unsigned int channels = pair->channels; in fsl_asrc_m2m_calc_out_len()
1151 in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8; in fsl_asrc_m2m_calc_out_len()
1152 out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8; in fsl_asrc_m2m_calc_out_len()
1155 out_samples = pair->rate[OUT] * in_samples / pair->rate[IN]; in fsl_asrc_m2m_calc_out_len()
1156 out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * channels; in fsl_asrc_m2m_calc_out_len()
1163 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_m2m_get_maxburst() local
1164 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_m2m_get_maxburst()
1167 if (!asrc_priv->soc->use_edma) in fsl_asrc_m2m_get_maxburst()
1168 return wml * pair->channels; in fsl_asrc_m2m_get_maxburst()
1175 cap->fmt_in = FSL_ASRC_FORMATS; in fsl_asrc_m2m_get_cap()
1176 cap->fmt_out = FSL_ASRC_FORMATS | SNDRV_PCM_FMTBIT_S8; in fsl_asrc_m2m_get_cap()
1178 cap->rate_in = supported_asrc_rate; in fsl_asrc_m2m_get_cap()
1179 cap->rate_in_count = ARRAY_SIZE(supported_asrc_rate); in fsl_asrc_m2m_get_cap()
1180 cap->rate_out = supported_asrc_rate; in fsl_asrc_m2m_get_cap()
1181 cap->rate_out_count = ARRAY_SIZE(supported_asrc_rate); in fsl_asrc_m2m_get_cap()
1182 cap->chan_min = 1; in fsl_asrc_m2m_get_cap()
1183 cap->chan_max = 10; in fsl_asrc_m2m_get_cap()
1190 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_m2m_pair_resume() local
1193 for (i = 0; i < pair->channels * 4; i++) in fsl_asrc_m2m_pair_resume()
1194 regmap_write(asrc->regmap, REG_ASRDI(pair->index), 0); in fsl_asrc_m2m_pair_resume()
1196 pair->first_convert = 1; in fsl_asrc_m2m_pair_resume()
1205 struct device_node *np = pdev->dev.of_node; in fsl_asrc_probe()
1207 struct fsl_asrc *asrc; in fsl_asrc_probe() local
1216 asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL); in fsl_asrc_probe()
1217 if (!asrc) in fsl_asrc_probe()
1218 return -ENOMEM; in fsl_asrc_probe()
1220 asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL); in fsl_asrc_probe()
1222 return -ENOMEM; in fsl_asrc_probe()
1224 asrc->pdev = pdev; in fsl_asrc_probe()
1225 asrc->private = asrc_priv; in fsl_asrc_probe()
1232 asrc->paddr = res->start; in fsl_asrc_probe()
1234 asrc->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_asrc_regmap_config); in fsl_asrc_probe()
1235 if (IS_ERR(asrc->regmap)) { in fsl_asrc_probe()
1236 dev_err(&pdev->dev, "failed to init regmap\n"); in fsl_asrc_probe()
1237 return PTR_ERR(asrc->regmap); in fsl_asrc_probe()
1244 ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, in fsl_asrc_probe()
1245 dev_name(&pdev->dev), asrc); in fsl_asrc_probe()
1247 dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret); in fsl_asrc_probe()
1251 asrc->mem_clk = devm_clk_get(&pdev->dev, "mem"); in fsl_asrc_probe()
1252 if (IS_ERR(asrc->mem_clk)) { in fsl_asrc_probe()
1253 dev_err(&pdev->dev, "failed to get mem clock\n"); in fsl_asrc_probe()
1254 return PTR_ERR(asrc->mem_clk); in fsl_asrc_probe()
1257 asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg"); in fsl_asrc_probe()
1258 if (IS_ERR(asrc->ipg_clk)) { in fsl_asrc_probe()
1259 dev_err(&pdev->dev, "failed to get ipg clock\n"); in fsl_asrc_probe()
1260 return PTR_ERR(asrc->ipg_clk); in fsl_asrc_probe()
1263 asrc->spba_clk = devm_clk_get(&pdev->dev, "spba"); in fsl_asrc_probe()
1264 if (IS_ERR(asrc->spba_clk)) in fsl_asrc_probe()
1265 dev_warn(&pdev->dev, "failed to get spba clock\n"); in fsl_asrc_probe()
1269 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp); in fsl_asrc_probe()
1270 if (IS_ERR(asrc_priv->asrck_clk[i])) { in fsl_asrc_probe()
1271 dev_err(&pdev->dev, "failed to get %s clock\n", tmp); in fsl_asrc_probe()
1272 return PTR_ERR(asrc_priv->asrck_clk[i]); in fsl_asrc_probe()
1276 asrc_priv->soc = of_device_get_match_data(&pdev->dev); in fsl_asrc_probe()
1277 asrc->use_edma = asrc_priv->soc->use_edma; in fsl_asrc_probe()
1278 asrc->get_dma_channel = fsl_asrc_get_dma_channel; in fsl_asrc_probe()
1279 asrc->request_pair = fsl_asrc_request_pair; in fsl_asrc_probe()
1280 asrc->release_pair = fsl_asrc_release_pair; in fsl_asrc_probe()
1281 asrc->get_fifo_addr = fsl_asrc_get_fifo_addr; in fsl_asrc_probe()
1282 asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv); in fsl_asrc_probe()
1284 asrc->m2m_prepare = fsl_asrc_m2m_prepare; in fsl_asrc_probe()
1285 asrc->m2m_start = fsl_asrc_m2m_start; in fsl_asrc_probe()
1286 asrc->m2m_stop = fsl_asrc_m2m_stop; in fsl_asrc_probe()
1287 asrc->get_output_fifo_size = fsl_asrc_get_output_fifo_size; in fsl_asrc_probe()
1288 asrc->m2m_calc_out_len = fsl_asrc_m2m_calc_out_len; in fsl_asrc_probe()
1289 asrc->m2m_get_maxburst = fsl_asrc_m2m_get_maxburst; in fsl_asrc_probe()
1290 asrc->m2m_pair_resume = fsl_asrc_m2m_pair_resume; in fsl_asrc_probe()
1291 asrc->m2m_get_cap = fsl_asrc_m2m_get_cap; in fsl_asrc_probe()
1293 if (of_device_is_compatible(np, "fsl,imx35-asrc")) { in fsl_asrc_probe()
1294 asrc_priv->clk_map[IN] = input_clk_map_imx35; in fsl_asrc_probe()
1295 asrc_priv->clk_map[OUT] = output_clk_map_imx35; in fsl_asrc_probe()
1296 } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) { in fsl_asrc_probe()
1297 asrc_priv->clk_map[IN] = input_clk_map_imx53; in fsl_asrc_probe()
1298 asrc_priv->clk_map[OUT] = output_clk_map_imx53; in fsl_asrc_probe()
1299 } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc") || in fsl_asrc_probe()
1300 of_device_is_compatible(np, "fsl,imx8qxp-asrc")) { in fsl_asrc_probe()
1301 ret = of_property_read_u32(np, "fsl,asrc-clk-map", &map_idx); in fsl_asrc_probe()
1303 dev_err(&pdev->dev, "failed to get clk map index\n"); in fsl_asrc_probe()
1308 dev_err(&pdev->dev, "unsupported clk map index\n"); in fsl_asrc_probe()
1309 return -EINVAL; in fsl_asrc_probe()
1311 if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) { in fsl_asrc_probe()
1312 asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx]; in fsl_asrc_probe()
1313 asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx]; in fsl_asrc_probe()
1315 asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx]; in fsl_asrc_probe()
1316 asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx]; in fsl_asrc_probe()
1320 asrc->channel_avail = 10; in fsl_asrc_probe()
1322 ret = of_property_read_u32(np, "fsl,asrc-rate", in fsl_asrc_probe()
1323 &asrc->asrc_rate); in fsl_asrc_probe()
1325 dev_err(&pdev->dev, "failed to get output rate\n"); in fsl_asrc_probe()
1329 ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt); in fsl_asrc_probe()
1330 asrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt; in fsl_asrc_probe()
1332 ret = of_property_read_u32(np, "fsl,asrc-width", &width); in fsl_asrc_probe()
1334 dev_err(&pdev->dev, "failed to decide output format\n"); in fsl_asrc_probe()
1340 asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE; in fsl_asrc_probe()
1343 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; in fsl_asrc_probe()
1346 dev_warn(&pdev->dev, in fsl_asrc_probe()
1348 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; in fsl_asrc_probe()
1353 if (!(FSL_ASRC_FORMATS & pcm_format_to_bits(asrc->asrc_format))) { in fsl_asrc_probe()
1354 dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n"); in fsl_asrc_probe()
1355 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; in fsl_asrc_probe()
1358 platform_set_drvdata(pdev, asrc); in fsl_asrc_probe()
1359 spin_lock_init(&asrc->lock); in fsl_asrc_probe()
1360 pm_runtime_enable(&pdev->dev); in fsl_asrc_probe()
1361 if (!pm_runtime_enabled(&pdev->dev)) { in fsl_asrc_probe()
1362 ret = fsl_asrc_runtime_resume(&pdev->dev); in fsl_asrc_probe()
1367 ret = pm_runtime_resume_and_get(&pdev->dev); in fsl_asrc_probe()
1371 ret = fsl_asrc_init(asrc); in fsl_asrc_probe()
1373 dev_err(&pdev->dev, "failed to init asrc %d\n", ret); in fsl_asrc_probe()
1377 ret = pm_runtime_put_sync(&pdev->dev); in fsl_asrc_probe()
1378 if (ret < 0 && ret != -ENOSYS) in fsl_asrc_probe()
1381 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component, in fsl_asrc_probe()
1384 dev_err(&pdev->dev, "failed to register ASoC DAI\n"); in fsl_asrc_probe()
1388 ret = fsl_asrc_m2m_init(asrc); in fsl_asrc_probe()
1390 dev_err(&pdev->dev, "failed to init m2m device %d\n", ret); in fsl_asrc_probe()
1397 if (!pm_runtime_status_suspended(&pdev->dev)) in fsl_asrc_probe()
1398 fsl_asrc_runtime_suspend(&pdev->dev); in fsl_asrc_probe()
1400 pm_runtime_disable(&pdev->dev); in fsl_asrc_probe()
1406 struct fsl_asrc *asrc = dev_get_drvdata(&pdev->dev); in fsl_asrc_remove() local
1408 fsl_asrc_m2m_exit(asrc); in fsl_asrc_remove()
1410 pm_runtime_disable(&pdev->dev); in fsl_asrc_remove()
1411 if (!pm_runtime_status_suspended(&pdev->dev)) in fsl_asrc_remove()
1412 fsl_asrc_runtime_suspend(&pdev->dev); in fsl_asrc_remove()
1417 struct fsl_asrc *asrc = dev_get_drvdata(dev); in fsl_asrc_runtime_resume() local
1418 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_runtime_resume()
1423 ret = clk_prepare_enable(asrc->mem_clk); in fsl_asrc_runtime_resume()
1426 ret = clk_prepare_enable(asrc->ipg_clk); in fsl_asrc_runtime_resume()
1429 if (!IS_ERR(asrc->spba_clk)) { in fsl_asrc_runtime_resume()
1430 ret = clk_prepare_enable(asrc->spba_clk); in fsl_asrc_runtime_resume()
1435 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]); in fsl_asrc_runtime_resume()
1441 regmap_read(asrc->regmap, REG_ASRCTR, &asrctr); in fsl_asrc_runtime_resume()
1442 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_runtime_resume()
1446 regcache_cache_only(asrc->regmap, false); in fsl_asrc_runtime_resume()
1447 regcache_mark_dirty(asrc->regmap); in fsl_asrc_runtime_resume()
1448 regcache_sync(asrc->regmap); in fsl_asrc_runtime_resume()
1450 regmap_update_bits(asrc->regmap, REG_ASRCFG, in fsl_asrc_runtime_resume()
1452 ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg); in fsl_asrc_runtime_resume()
1455 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_runtime_resume()
1461 regmap_read(asrc->regmap, REG_ASRCFG, ®); in fsl_asrc_runtime_resume()
1463 } while ((reg != ((asrctr >> ASRCTR_ASRCEi_SHIFT(0)) & 0x7)) && --retry); in fsl_asrc_runtime_resume()
1479 for (i--; i >= 0; i--) in fsl_asrc_runtime_resume()
1480 clk_disable_unprepare(asrc_priv->asrck_clk[i]); in fsl_asrc_runtime_resume()
1481 if (!IS_ERR(asrc->spba_clk)) in fsl_asrc_runtime_resume()
1482 clk_disable_unprepare(asrc->spba_clk); in fsl_asrc_runtime_resume()
1484 clk_disable_unprepare(asrc->ipg_clk); in fsl_asrc_runtime_resume()
1486 clk_disable_unprepare(asrc->mem_clk); in fsl_asrc_runtime_resume()
1492 struct fsl_asrc *asrc = dev_get_drvdata(dev); in fsl_asrc_runtime_suspend() local
1493 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_runtime_suspend()
1496 regmap_read(asrc->regmap, REG_ASRCFG, in fsl_asrc_runtime_suspend()
1497 &asrc_priv->regcache_cfg); in fsl_asrc_runtime_suspend()
1499 regcache_cache_only(asrc->regmap, true); in fsl_asrc_runtime_suspend()
1502 clk_disable_unprepare(asrc_priv->asrck_clk[i]); in fsl_asrc_runtime_suspend()
1503 if (!IS_ERR(asrc->spba_clk)) in fsl_asrc_runtime_suspend()
1504 clk_disable_unprepare(asrc->spba_clk); in fsl_asrc_runtime_suspend()
1505 clk_disable_unprepare(asrc->ipg_clk); in fsl_asrc_runtime_suspend()
1506 clk_disable_unprepare(asrc->mem_clk); in fsl_asrc_runtime_suspend()
1513 struct fsl_asrc *asrc = dev_get_drvdata(dev); in fsl_asrc_suspend() local
1516 fsl_asrc_m2m_suspend(asrc); in fsl_asrc_suspend()
1523 struct fsl_asrc *asrc = dev_get_drvdata(dev); in fsl_asrc_resume() local
1527 fsl_asrc_m2m_resume(asrc); in fsl_asrc_resume()
1557 { .compatible = "fsl,imx35-asrc", .data = &fsl_asrc_imx35_data },
1558 { .compatible = "fsl,imx53-asrc", .data = &fsl_asrc_imx53_data },
1559 { .compatible = "fsl,imx8qm-asrc", .data = &fsl_asrc_imx8qm_data },
1560 { .compatible = "fsl,imx8qxp-asrc", .data = &fsl_asrc_imx8qxp_data },
1569 .name = "fsl-asrc",
1576 MODULE_DESCRIPTION("Freescale ASRC ASoC driver");
1578 MODULE_ALIAS("platform:fsl-asrc");