Lines Matching +full:assigned +full:- +full:clock +full:- +full:rates +full:- +full:u64

1 // SPDX-License-Identifier: GPL-2.0
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__)
130 u64 n; in fsl_asrc_divider_avail()
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()
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
260 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_release_pair()
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()
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()
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
368 * and clock settings.
371 * The ideal ratio configuration can work with a flexible clock rate setting.
373 * For a regular audio playback, the clock rate should not be slower than an
374 * clock rate aligning with the output sample rate; For a use case requiring
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()
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()
388 u64 clk_rate; 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()
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()
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()
438 /* Validate input and output sample rates */ 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()
464 /* Validate input and output clock sources */ 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()
468 /* We only have output clock for ideal ratio mode */ 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()
476 * ideal ratio configuration, clock rate has to be strictly aligned in fsl_asrc_config_pair()
477 * with the sample rate. For ideal ratio configuration, clock rates 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()
522 /* Set the input and output clock sources */ in fsl_asrc_config_pair()
523 regmap_update_bits(asrc->regmap, REG_ASRCSR, in fsl_asrc_config_pair()
528 /* Calculate the input clock divisors */ in fsl_asrc_config_pair()
533 regmap_update_bits(asrc->regmap, REG_ASRCDR(index), in fsl_asrc_config_pair()
539 regmap_update_bits(asrc->regmap, REG_ASRMCR1(index), in fsl_asrc_config_pair()
545 regmap_update_bits(asrc->regmap, REG_ASRMCR(index), in fsl_asrc_config_pair()
557 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_config_pair()
561 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_config_pair()
567 /* Apply configurations for pre- and post-processing */ in fsl_asrc_config_pair()
568 regmap_update_bits(asrc->regmap, REG_ASRCFG, in fsl_asrc_config_pair()
577 * fsl_asrc_start_pair - Start the assigned ASRC pair
580 * It enables the assigned pair and makes it stopped at the stall level.
584 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_start_pair()
585 enum asrc_pair_index index = pair->index; in fsl_asrc_start_pair()
589 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_start_pair()
595 regmap_read(asrc->regmap, REG_ASRCFG, &reg); in fsl_asrc_start_pair()
597 } while (!reg && --retry); in fsl_asrc_start_pair()
604 regmap_read(asrc->regmap, REG_ASRCNCR, &reg); in fsl_asrc_start_pair()
605 for (i = 0; i < pair->channels * 4; i++) in fsl_asrc_start_pair()
606 regmap_write(asrc->regmap, REG_ASRDI(index), 0); in fsl_asrc_start_pair()
609 regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE); in fsl_asrc_start_pair()
613 * fsl_asrc_stop_pair - Stop the assigned ASRC pair
618 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_stop_pair()
619 enum asrc_pair_index index = pair->index; in fsl_asrc_stop_pair()
622 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_stop_pair()
627 * fsl_asrc_get_dma_channel- Get DMA channel according to the pair and direction.
634 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_get_dma_channel()
635 enum asrc_pair_index index = pair->index; in fsl_asrc_get_dma_channel()
640 return dma_request_slave_channel(&asrc->pdev->dev, name); in fsl_asrc_get_dma_channel()
647 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_dai_startup()
650 if (asrc_priv->soc->channel_bits == 3) in fsl_asrc_dai_startup()
651 snd_pcm_hw_constraint_step(substream->runtime, 0, in fsl_asrc_dai_startup()
655 return snd_pcm_hw_constraint_list(substream->runtime, 0, in fsl_asrc_dai_startup()
659 /* Select proper clock source for internal ratio mode */
665 struct fsl_asrc_pair_priv *pair_priv = pair->private; in fsl_asrc_select_clk()
666 struct asrc_config *config = pair_priv->config; in fsl_asrc_select_clk()
674 /* Select proper clock source for internal ratio mode */ in fsl_asrc_select_clk()
677 clk_index = asrc_priv->clk_map[j][i]; in fsl_asrc_select_clk()
678 clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]); in fsl_asrc_select_clk()
679 /* Only match a perfect clock source with no remainder */ in fsl_asrc_select_clk()
687 /* Switch to ideal ratio mode if there is no proper clock source */ in fsl_asrc_select_clk()
693 config->inclk = select_clk[IN]; in fsl_asrc_select_clk()
694 config->outclk = select_clk[OUT]; in fsl_asrc_select_clk()
702 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_dai_hw_params()
703 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dai_hw_params()
704 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dai_hw_params()
705 struct fsl_asrc_pair_priv *pair_priv = pair->private; in fsl_asrc_dai_hw_params()
713 dev_err(dai->dev, "fail to request asrc pair\n"); in fsl_asrc_dai_hw_params()
717 pair_priv->config = &config; in fsl_asrc_dai_hw_params()
719 config.pair = pair->index; in fsl_asrc_dai_hw_params()
722 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in fsl_asrc_dai_hw_params()
724 config.output_format = asrc->asrc_format; in fsl_asrc_dai_hw_params()
726 config.output_sample_rate = asrc->asrc_rate; in fsl_asrc_dai_hw_params()
728 config.input_format = asrc->asrc_format; in fsl_asrc_dai_hw_params()
730 config.input_sample_rate = asrc->asrc_rate; in fsl_asrc_dai_hw_params()
740 dev_err(dai->dev, "fail to config asrc pair\n"); in fsl_asrc_dai_hw_params()
750 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dai_hw_free()
751 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dai_hw_free()
762 struct snd_pcm_runtime *runtime = substream->runtime; in fsl_asrc_dai_trigger()
763 struct fsl_asrc_pair *pair = runtime->private_data; in fsl_asrc_dai_trigger()
777 return -EINVAL; in fsl_asrc_dai_trigger()
787 snd_soc_dai_init_dma_data(dai, &asrc->dma_params_tx, in fsl_asrc_dai_probe()
788 &asrc->dma_params_rx); in fsl_asrc_dai_probe()
807 .stream_name = "ASRC-Playback",
812 .rates = SNDRV_PCM_RATE_KNOT,
817 .stream_name = "ASRC-Capture",
822 .rates = SNDRV_PCM_RATE_KNOT,
972 * fsl_asrc_init - Initialize ASRC registers with a default configuration
980 regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN); in fsl_asrc_init()
983 regmap_write(asrc->regmap, REG_ASRIER, 0x0); in fsl_asrc_init()
986 regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff); in fsl_asrc_init()
987 regmap_write(asrc->regmap, REG_ASRPM2, 0x255555); in fsl_asrc_init()
988 regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280); in fsl_asrc_init()
989 regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280); in fsl_asrc_init()
990 regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280); in fsl_asrc_init()
993 regmap_update_bits(asrc->regmap, REG_ASRTFR1, in fsl_asrc_init()
998 * the ASRC processing clock. in fsl_asrc_init()
1001 ipg_rate = clk_get_rate(asrc->ipg_clk); in fsl_asrc_init()
1002 regmap_write(asrc->regmap, REG_ASR76K, ipg_rate / 76000); in fsl_asrc_init()
1003 return regmap_write(asrc->regmap, REG_ASR56K, ipg_rate / 56000); in fsl_asrc_init()
1007 * fsl_asrc_isr- Interrupt handler for ASRC
1014 struct device *dev = &asrc->pdev->dev; in fsl_asrc_isr()
1018 regmap_read(asrc->regmap, REG_ASRSTR, &status); in fsl_asrc_isr()
1021 regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE); in fsl_asrc_isr()
1029 if (!asrc->pair[index]) in fsl_asrc_isr()
1033 asrc->pair[index]->error |= ASRC_TASK_Q_OVERLOAD; in fsl_asrc_isr()
1038 asrc->pair[index]->error |= ASRC_OUTPUT_TASK_OVERLOAD; in fsl_asrc_isr()
1043 asrc->pair[index]->error |= ASRC_INPUT_TASK_OVERLOAD; in fsl_asrc_isr()
1048 asrc->pair[index]->error |= ASRC_OUTPUT_BUFFER_OVERFLOW; in fsl_asrc_isr()
1053 asrc->pair[index]->error |= ASRC_INPUT_BUFFER_UNDERRUN; in fsl_asrc_isr()
1069 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_get_output_fifo_size()
1070 enum asrc_pair_index index = pair->index; in fsl_asrc_get_output_fifo_size()
1073 regmap_read(asrc->regmap, REG_ASRFST(index), &val); in fsl_asrc_get_output_fifo_size()
1082 struct fsl_asrc_pair_priv *pair_priv = pair->private; in fsl_asrc_m2m_prepare()
1083 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_m2m_prepare()
1084 struct device *dev = &asrc->pdev->dev; in fsl_asrc_m2m_prepare()
1089 config.pair = pair->index; in fsl_asrc_m2m_prepare()
1090 config.channel_num = pair->channels; in fsl_asrc_m2m_prepare()
1091 config.input_sample_rate = pair->rate[IN]; in fsl_asrc_m2m_prepare()
1092 config.output_sample_rate = pair->rate[OUT]; in fsl_asrc_m2m_prepare()
1093 config.input_format = pair->sample_format[IN]; in fsl_asrc_m2m_prepare()
1094 config.output_format = pair->sample_format[OUT]; in fsl_asrc_m2m_prepare()
1098 pair_priv->config = &config; in fsl_asrc_m2m_prepare()
1105 pair->first_convert = 1; in fsl_asrc_m2m_prepare()
1112 if (pair->first_convert) { in fsl_asrc_m2m_start()
1114 pair->first_convert = 0; in fsl_asrc_m2m_start()
1134 if (!pair->first_convert) { in fsl_asrc_m2m_stop()
1136 pair->first_convert = 1; in fsl_asrc_m2m_stop()
1146 unsigned int channels = pair->channels; in fsl_asrc_m2m_calc_out_len()
1150 in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8; in fsl_asrc_m2m_calc_out_len()
1151 out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8; in fsl_asrc_m2m_calc_out_len()
1154 out_samples = pair->rate[OUT] * in_samples / pair->rate[IN]; in fsl_asrc_m2m_calc_out_len()
1155 out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * channels; in fsl_asrc_m2m_calc_out_len()
1162 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_m2m_get_maxburst()
1163 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_m2m_get_maxburst()
1166 if (!asrc_priv->soc->use_edma) in fsl_asrc_m2m_get_maxburst()
1167 return wml * pair->channels; in fsl_asrc_m2m_get_maxburst()
1174 cap->fmt_in = FSL_ASRC_FORMATS; in fsl_asrc_m2m_get_cap()
1175 cap->fmt_out = FSL_ASRC_FORMATS | SNDRV_PCM_FMTBIT_S8; in fsl_asrc_m2m_get_cap()
1177 cap->rate_in = supported_asrc_rate; in fsl_asrc_m2m_get_cap()
1178 cap->rate_in_count = ARRAY_SIZE(supported_asrc_rate); in fsl_asrc_m2m_get_cap()
1179 cap->rate_out = supported_asrc_rate; in fsl_asrc_m2m_get_cap()
1180 cap->rate_out_count = ARRAY_SIZE(supported_asrc_rate); in fsl_asrc_m2m_get_cap()
1181 cap->chan_min = 1; in fsl_asrc_m2m_get_cap()
1182 cap->chan_max = 10; in fsl_asrc_m2m_get_cap()
1189 struct fsl_asrc *asrc = pair->asrc; in fsl_asrc_m2m_pair_resume()
1192 for (i = 0; i < pair->channels * 4; i++) in fsl_asrc_m2m_pair_resume()
1193 regmap_write(asrc->regmap, REG_ASRDI(pair->index), 0); in fsl_asrc_m2m_pair_resume()
1195 pair->first_convert = 1; in fsl_asrc_m2m_pair_resume()
1204 struct device_node *np = pdev->dev.of_node; in fsl_asrc_probe()
1215 asrc = devm_kzalloc(&pdev->dev, sizeof(*asrc), GFP_KERNEL); in fsl_asrc_probe()
1217 return -ENOMEM; in fsl_asrc_probe()
1219 asrc_priv = devm_kzalloc(&pdev->dev, sizeof(*asrc_priv), GFP_KERNEL); in fsl_asrc_probe()
1221 return -ENOMEM; in fsl_asrc_probe()
1223 asrc->pdev = pdev; in fsl_asrc_probe()
1224 asrc->private = asrc_priv; in fsl_asrc_probe()
1231 asrc->paddr = res->start; in fsl_asrc_probe()
1233 asrc->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_asrc_regmap_config); in fsl_asrc_probe()
1234 if (IS_ERR(asrc->regmap)) { in fsl_asrc_probe()
1235 dev_err(&pdev->dev, "failed to init regmap\n"); in fsl_asrc_probe()
1236 return PTR_ERR(asrc->regmap); in fsl_asrc_probe()
1243 ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, in fsl_asrc_probe()
1244 dev_name(&pdev->dev), asrc); in fsl_asrc_probe()
1246 dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret); in fsl_asrc_probe()
1250 asrc->mem_clk = devm_clk_get(&pdev->dev, "mem"); in fsl_asrc_probe()
1251 if (IS_ERR(asrc->mem_clk)) { in fsl_asrc_probe()
1252 dev_err(&pdev->dev, "failed to get mem clock\n"); in fsl_asrc_probe()
1253 return PTR_ERR(asrc->mem_clk); in fsl_asrc_probe()
1256 asrc->ipg_clk = devm_clk_get(&pdev->dev, "ipg"); in fsl_asrc_probe()
1257 if (IS_ERR(asrc->ipg_clk)) { in fsl_asrc_probe()
1258 dev_err(&pdev->dev, "failed to get ipg clock\n"); in fsl_asrc_probe()
1259 return PTR_ERR(asrc->ipg_clk); in fsl_asrc_probe()
1262 asrc->spba_clk = devm_clk_get(&pdev->dev, "spba"); in fsl_asrc_probe()
1263 if (IS_ERR(asrc->spba_clk)) in fsl_asrc_probe()
1264 dev_warn(&pdev->dev, "failed to get spba clock\n"); in fsl_asrc_probe()
1268 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp); in fsl_asrc_probe()
1269 if (IS_ERR(asrc_priv->asrck_clk[i])) { in fsl_asrc_probe()
1270 dev_err(&pdev->dev, "failed to get %s clock\n", tmp); in fsl_asrc_probe()
1271 return PTR_ERR(asrc_priv->asrck_clk[i]); in fsl_asrc_probe()
1275 asrc_priv->soc = of_device_get_match_data(&pdev->dev); in fsl_asrc_probe()
1276 asrc->use_edma = asrc_priv->soc->use_edma; in fsl_asrc_probe()
1277 asrc->get_dma_channel = fsl_asrc_get_dma_channel; in fsl_asrc_probe()
1278 asrc->request_pair = fsl_asrc_request_pair; in fsl_asrc_probe()
1279 asrc->release_pair = fsl_asrc_release_pair; in fsl_asrc_probe()
1280 asrc->get_fifo_addr = fsl_asrc_get_fifo_addr; in fsl_asrc_probe()
1281 asrc->pair_priv_size = sizeof(struct fsl_asrc_pair_priv); in fsl_asrc_probe()
1283 asrc->m2m_prepare = fsl_asrc_m2m_prepare; in fsl_asrc_probe()
1284 asrc->m2m_start = fsl_asrc_m2m_start; in fsl_asrc_probe()
1285 asrc->m2m_stop = fsl_asrc_m2m_stop; in fsl_asrc_probe()
1286 asrc->get_output_fifo_size = fsl_asrc_get_output_fifo_size; in fsl_asrc_probe()
1287 asrc->m2m_calc_out_len = fsl_asrc_m2m_calc_out_len; in fsl_asrc_probe()
1288 asrc->m2m_get_maxburst = fsl_asrc_m2m_get_maxburst; in fsl_asrc_probe()
1289 asrc->m2m_pair_resume = fsl_asrc_m2m_pair_resume; in fsl_asrc_probe()
1290 asrc->m2m_get_cap = fsl_asrc_m2m_get_cap; in fsl_asrc_probe()
1292 if (of_device_is_compatible(np, "fsl,imx35-asrc")) { in fsl_asrc_probe()
1293 asrc_priv->clk_map[IN] = input_clk_map_imx35; in fsl_asrc_probe()
1294 asrc_priv->clk_map[OUT] = output_clk_map_imx35; in fsl_asrc_probe()
1295 } else if (of_device_is_compatible(np, "fsl,imx53-asrc")) { in fsl_asrc_probe()
1296 asrc_priv->clk_map[IN] = input_clk_map_imx53; in fsl_asrc_probe()
1297 asrc_priv->clk_map[OUT] = output_clk_map_imx53; in fsl_asrc_probe()
1298 } else if (of_device_is_compatible(np, "fsl,imx8qm-asrc") || in fsl_asrc_probe()
1299 of_device_is_compatible(np, "fsl,imx8qxp-asrc")) { in fsl_asrc_probe()
1300 ret = of_property_read_u32(np, "fsl,asrc-clk-map", &map_idx); in fsl_asrc_probe()
1302 dev_err(&pdev->dev, "failed to get clk map index\n"); in fsl_asrc_probe()
1307 dev_err(&pdev->dev, "unsupported clk map index\n"); in fsl_asrc_probe()
1308 return -EINVAL; in fsl_asrc_probe()
1310 if (of_device_is_compatible(np, "fsl,imx8qm-asrc")) { in fsl_asrc_probe()
1311 asrc_priv->clk_map[IN] = clk_map_imx8qm[map_idx]; in fsl_asrc_probe()
1312 asrc_priv->clk_map[OUT] = clk_map_imx8qm[map_idx]; in fsl_asrc_probe()
1314 asrc_priv->clk_map[IN] = clk_map_imx8qxp[map_idx]; in fsl_asrc_probe()
1315 asrc_priv->clk_map[OUT] = clk_map_imx8qxp[map_idx]; in fsl_asrc_probe()
1319 asrc->channel_avail = 10; in fsl_asrc_probe()
1321 ret = of_property_read_u32(np, "fsl,asrc-rate", in fsl_asrc_probe()
1322 &asrc->asrc_rate); in fsl_asrc_probe()
1324 dev_err(&pdev->dev, "failed to get output rate\n"); in fsl_asrc_probe()
1328 ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt); in fsl_asrc_probe()
1329 asrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt; in fsl_asrc_probe()
1331 ret = of_property_read_u32(np, "fsl,asrc-width", &width); in fsl_asrc_probe()
1333 dev_err(&pdev->dev, "failed to decide output format\n"); in fsl_asrc_probe()
1339 asrc->asrc_format = SNDRV_PCM_FORMAT_S16_LE; in fsl_asrc_probe()
1342 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; in fsl_asrc_probe()
1345 dev_warn(&pdev->dev, in fsl_asrc_probe()
1347 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; in fsl_asrc_probe()
1352 if (!(FSL_ASRC_FORMATS & pcm_format_to_bits(asrc->asrc_format))) { in fsl_asrc_probe()
1353 dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n"); in fsl_asrc_probe()
1354 asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE; in fsl_asrc_probe()
1358 spin_lock_init(&asrc->lock); in fsl_asrc_probe()
1359 pm_runtime_enable(&pdev->dev); in fsl_asrc_probe()
1360 if (!pm_runtime_enabled(&pdev->dev)) { in fsl_asrc_probe()
1361 ret = fsl_asrc_runtime_resume(&pdev->dev); in fsl_asrc_probe()
1366 ret = pm_runtime_resume_and_get(&pdev->dev); in fsl_asrc_probe()
1372 dev_err(&pdev->dev, "failed to init asrc %d\n", ret); in fsl_asrc_probe()
1376 ret = pm_runtime_put_sync(&pdev->dev); in fsl_asrc_probe()
1377 if (ret < 0 && ret != -ENOSYS) in fsl_asrc_probe()
1380 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component, in fsl_asrc_probe()
1383 dev_err(&pdev->dev, "failed to register ASoC DAI\n"); in fsl_asrc_probe()
1389 dev_err(&pdev->dev, "failed to init m2m device %d\n", ret); in fsl_asrc_probe()
1396 if (!pm_runtime_status_suspended(&pdev->dev)) in fsl_asrc_probe()
1397 fsl_asrc_runtime_suspend(&pdev->dev); in fsl_asrc_probe()
1399 pm_runtime_disable(&pdev->dev); in fsl_asrc_probe()
1405 struct fsl_asrc *asrc = dev_get_drvdata(&pdev->dev); in fsl_asrc_remove()
1409 pm_runtime_disable(&pdev->dev); in fsl_asrc_remove()
1410 if (!pm_runtime_status_suspended(&pdev->dev)) in fsl_asrc_remove()
1411 fsl_asrc_runtime_suspend(&pdev->dev); in fsl_asrc_remove()
1417 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_runtime_resume()
1422 ret = clk_prepare_enable(asrc->mem_clk); in fsl_asrc_runtime_resume()
1425 ret = clk_prepare_enable(asrc->ipg_clk); in fsl_asrc_runtime_resume()
1428 if (!IS_ERR(asrc->spba_clk)) { in fsl_asrc_runtime_resume()
1429 ret = clk_prepare_enable(asrc->spba_clk); in fsl_asrc_runtime_resume()
1434 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]); in fsl_asrc_runtime_resume()
1440 regmap_read(asrc->regmap, REG_ASRCTR, &asrctr); in fsl_asrc_runtime_resume()
1441 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_runtime_resume()
1445 regcache_cache_only(asrc->regmap, false); in fsl_asrc_runtime_resume()
1446 regcache_mark_dirty(asrc->regmap); in fsl_asrc_runtime_resume()
1447 regcache_sync(asrc->regmap); in fsl_asrc_runtime_resume()
1449 regmap_update_bits(asrc->regmap, REG_ASRCFG, in fsl_asrc_runtime_resume()
1451 ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg); in fsl_asrc_runtime_resume()
1454 regmap_update_bits(asrc->regmap, REG_ASRCTR, in fsl_asrc_runtime_resume()
1460 regmap_read(asrc->regmap, REG_ASRCFG, &reg); in fsl_asrc_runtime_resume()
1462 } while ((reg != ((asrctr >> ASRCTR_ASRCEi_SHIFT(0)) & 0x7)) && --retry); in fsl_asrc_runtime_resume()
1478 for (i--; i >= 0; i--) in fsl_asrc_runtime_resume()
1479 clk_disable_unprepare(asrc_priv->asrck_clk[i]); in fsl_asrc_runtime_resume()
1480 if (!IS_ERR(asrc->spba_clk)) in fsl_asrc_runtime_resume()
1481 clk_disable_unprepare(asrc->spba_clk); in fsl_asrc_runtime_resume()
1483 clk_disable_unprepare(asrc->ipg_clk); in fsl_asrc_runtime_resume()
1485 clk_disable_unprepare(asrc->mem_clk); in fsl_asrc_runtime_resume()
1492 struct fsl_asrc_priv *asrc_priv = asrc->private; in fsl_asrc_runtime_suspend()
1495 regmap_read(asrc->regmap, REG_ASRCFG, in fsl_asrc_runtime_suspend()
1496 &asrc_priv->regcache_cfg); in fsl_asrc_runtime_suspend()
1498 regcache_cache_only(asrc->regmap, true); in fsl_asrc_runtime_suspend()
1501 clk_disable_unprepare(asrc_priv->asrck_clk[i]); in fsl_asrc_runtime_suspend()
1502 if (!IS_ERR(asrc->spba_clk)) in fsl_asrc_runtime_suspend()
1503 clk_disable_unprepare(asrc->spba_clk); in fsl_asrc_runtime_suspend()
1504 clk_disable_unprepare(asrc->ipg_clk); in fsl_asrc_runtime_suspend()
1505 clk_disable_unprepare(asrc->mem_clk); in fsl_asrc_runtime_suspend()
1556 { .compatible = "fsl,imx35-asrc", .data = &fsl_asrc_imx35_data },
1557 { .compatible = "fsl,imx53-asrc", .data = &fsl_asrc_imx53_data },
1558 { .compatible = "fsl,imx8qm-asrc", .data = &fsl_asrc_imx8qm_data },
1559 { .compatible = "fsl,imx8qxp-asrc", .data = &fsl_asrc_imx8qxp_data },
1568 .name = "fsl-asrc",
1577 MODULE_ALIAS("platform:fsl-asrc");