Lines Matching +full:clock +full:- +full:master

1 // SPDX-License-Identifier: GPL-2.0-only
29 * ---- I2S Controller Register map ----
44 * ---- Control Register (Write-only) ----
48 #define ATMEL_I2SC_CR_CKEN BIT(2) /* Clock Enable */
49 #define ATMEL_I2SC_CR_CKDIS BIT(3) /* Clock Disable */
55 * ---- Mode Register (Read/Write) ----
101 /* Audio Clock to I2SC Master Clock ratio */
106 /* Master Clock to fs ratio */
111 /* Master Clock mode */
113 /* 0: No master clock generated (selected clock drives I2SCK pin) */
115 /* 1: master clock generated (internally generated clock drives I2SMCK pin) */
124 * ---- Status Registers ----
143 * ---- Interrupt Enable/Disable/Mask Registers ----
211 regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr); in atmel_i2s_interrupt()
212 regmap_read(dev->regmap, ATMEL_I2SC_IMR, &imr); in atmel_i2s_interrupt()
224 dev_err(dev->dev, in atmel_i2s_interrupt()
228 regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask); in atmel_i2s_interrupt()
238 dev_err(dev->dev, in atmel_i2s_interrupt()
242 regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask); in atmel_i2s_interrupt()
263 dev->fmt = fmt; in atmel_i2s_set_dai_fmt()
271 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); in atmel_i2s_prepare()
275 regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr); in atmel_i2s_prepare()
282 dev_dbg(dev->dev, "RXRDY is set\n"); in atmel_i2s_prepare()
283 regmap_read(dev->regmap, ATMEL_I2SC_RHR, &rhr); in atmel_i2s_prepare()
294 if (!dev->gclk) { in atmel_i2s_get_gck_param()
295 dev_err(dev->dev, "cannot generate the I2S Master Clock\n"); in atmel_i2s_get_gck_param()
296 return -EINVAL; in atmel_i2s_get_gck_param()
300 * Find the best possible settings to generate the I2S Master Clock in atmel_i2s_get_gck_param()
303 dev->gck_param = NULL; in atmel_i2s_get_gck_param()
307 int val = abs(fs - gck_param->fs); in atmel_i2s_get_gck_param()
311 dev->gck_param = gck_param; in atmel_i2s_get_gck_param()
323 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); in atmel_i2s_hw_params()
327 switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in atmel_i2s_hw_params()
333 dev_err(dev->dev, "unsupported bus format\n"); in atmel_i2s_hw_params()
334 return -EINVAL; in atmel_i2s_hw_params()
337 switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { in atmel_i2s_hw_params()
339 /* codec is slave, so cpu is master */ in atmel_i2s_hw_params()
347 /* codec is master, so cpu is slave */ in atmel_i2s_hw_params()
349 dev->gck_param = NULL; in atmel_i2s_hw_params()
353 dev_err(dev->dev, "unsupported master/slave mode\n"); in atmel_i2s_hw_params()
354 return -EINVAL; in atmel_i2s_hw_params()
367 dev_err(dev->dev, "unsupported number of audio channels\n"); in atmel_i2s_hw_params()
368 return -EINVAL; in atmel_i2s_hw_params()
401 dev_err(dev->dev, "unsupported size/endianness for audio samples\n"); in atmel_i2s_hw_params()
402 return -EINVAL; in atmel_i2s_hw_params()
405 return regmap_write(dev->regmap, ATMEL_I2SC_MR, mr); in atmel_i2s_hw_params()
421 /* Disable the I2S Master Clock generator. */ in atmel_i2s_switch_mck_generator()
422 ret = regmap_write(dev->regmap, ATMEL_I2SC_CR, in atmel_i2s_switch_mck_generator()
427 /* Reset the I2S Master Clock generator settings. */ in atmel_i2s_switch_mck_generator()
428 ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, in atmel_i2s_switch_mck_generator()
433 /* Disable/unprepare the PMC generated clock. */ in atmel_i2s_switch_mck_generator()
434 clk_disable_unprepare(dev->gclk); in atmel_i2s_switch_mck_generator()
439 if (!dev->gck_param) in atmel_i2s_switch_mck_generator()
440 return -EINVAL; in atmel_i2s_switch_mck_generator()
442 gclk_rate = dev->gck_param->mck * (dev->gck_param->imckdiv + 1); in atmel_i2s_switch_mck_generator()
444 ret = clk_set_rate(dev->gclk, gclk_rate); in atmel_i2s_switch_mck_generator()
448 ret = clk_prepare_enable(dev->gclk); in atmel_i2s_switch_mck_generator()
452 /* Update the Mode Register to generate the I2S Master Clock. */ in atmel_i2s_switch_mck_generator()
453 mr |= ATMEL_I2SC_MR_IMCKDIV(dev->gck_param->imckdiv); in atmel_i2s_switch_mck_generator()
454 mr |= ATMEL_I2SC_MR_IMCKFS(dev->gck_param->imckfs); in atmel_i2s_switch_mck_generator()
456 ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, mr_mask, mr); in atmel_i2s_switch_mck_generator()
460 /* Finally enable the I2S Master Clock generator. */ in atmel_i2s_switch_mck_generator()
461 return regmap_write(dev->regmap, ATMEL_I2SC_CR, in atmel_i2s_switch_mck_generator()
469 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); in atmel_i2s_trigger()
488 return -EINVAL; in atmel_i2s_trigger()
491 /* Read the Mode Register to retrieve the master/slave state. */ in atmel_i2s_trigger()
492 err = regmap_read(dev->regmap, ATMEL_I2SC_MR, &mr); in atmel_i2s_trigger()
497 /* If master starts, enable the audio clock. */ in atmel_i2s_trigger()
503 err = regmap_write(dev->regmap, ATMEL_I2SC_CR, cr); in atmel_i2s_trigger()
507 /* If master stops, disable the audio clock. */ in atmel_i2s_trigger()
525 snd_soc_dai_init_dma_data(dai, &dev->playback, &dev->capture); in atmel_i2s_dai_probe()
548 .name = "atmel-i2s",
557 if (!dev->gclk) in atmel_i2s_sama5d2_mck_init()
561 muxclk = devm_clk_get(dev->dev, "muxclk"); in atmel_i2s_sama5d2_mck_init()
564 if (err == -EPROBE_DEFER) in atmel_i2s_sama5d2_mck_init()
565 return -EPROBE_DEFER; in atmel_i2s_sama5d2_mck_init()
566 dev_warn(dev->dev, in atmel_i2s_sama5d2_mck_init()
567 "failed to get the I2S clock control: %d\n", err); in atmel_i2s_sama5d2_mck_init()
571 return clk_set_parent(muxclk, dev->gclk); in atmel_i2s_sama5d2_mck_init()
580 .compatible = "atmel,sama5d2-i2s",
591 struct device_node *np = pdev->dev.of_node; in atmel_i2s_probe()
598 int err = -ENXIO; in atmel_i2s_probe()
603 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in atmel_i2s_probe()
605 return -ENOMEM; in atmel_i2s_probe()
610 dev->caps = match->data; in atmel_i2s_probe()
614 base = devm_ioremap_resource(&pdev->dev, mem); in atmel_i2s_probe()
618 regmap = devm_regmap_init_mmio(&pdev->dev, base, in atmel_i2s_probe()
628 err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0, in atmel_i2s_probe()
629 dev_name(&pdev->dev), dev); in atmel_i2s_probe()
633 /* Get the peripheral clock. */ in atmel_i2s_probe()
634 dev->pclk = devm_clk_get(&pdev->dev, "pclk"); in atmel_i2s_probe()
635 if (IS_ERR(dev->pclk)) { in atmel_i2s_probe()
636 err = PTR_ERR(dev->pclk); in atmel_i2s_probe()
637 dev_err(&pdev->dev, in atmel_i2s_probe()
638 "failed to get the peripheral clock: %d\n", err); in atmel_i2s_probe()
642 /* Get audio clock to generate the I2S Master Clock (I2S_MCK) */ in atmel_i2s_probe()
643 dev->gclk = devm_clk_get(&pdev->dev, "gclk"); in atmel_i2s_probe()
644 if (IS_ERR(dev->gclk)) { in atmel_i2s_probe()
645 if (PTR_ERR(dev->gclk) == -EPROBE_DEFER) in atmel_i2s_probe()
646 return -EPROBE_DEFER; in atmel_i2s_probe()
647 /* Master Mode not supported */ in atmel_i2s_probe()
648 dev->gclk = NULL; in atmel_i2s_probe()
650 dev->dev = &pdev->dev; in atmel_i2s_probe()
651 dev->regmap = regmap; in atmel_i2s_probe()
655 if (dev->caps && dev->caps->mck_init) { in atmel_i2s_probe()
656 err = dev->caps->mck_init(dev, np); in atmel_i2s_probe()
661 /* Enable the peripheral clock. */ in atmel_i2s_probe()
662 err = clk_prepare_enable(dev->pclk); in atmel_i2s_probe()
667 regmap_read(dev->regmap, ATMEL_I2SC_VERSION, &version); in atmel_i2s_probe()
668 dev_info(&pdev->dev, "hw version: %#x\n", version); in atmel_i2s_probe()
671 regmap_write(dev->regmap, ATMEL_I2SC_IER, in atmel_i2s_probe()
674 err = devm_snd_soc_register_component(&pdev->dev, in atmel_i2s_probe()
678 dev_err(&pdev->dev, "failed to register DAI: %d\n", err); in atmel_i2s_probe()
679 clk_disable_unprepare(dev->pclk); in atmel_i2s_probe()
684 dev->playback.addr = (dma_addr_t)mem->start + ATMEL_I2SC_THR; in atmel_i2s_probe()
685 dev->playback.maxburst = 1; in atmel_i2s_probe()
686 dev->capture.addr = (dma_addr_t)mem->start + ATMEL_I2SC_RHR; in atmel_i2s_probe()
687 dev->capture.maxburst = 1; in atmel_i2s_probe()
689 if (of_property_match_string(np, "dma-names", "rx-tx") == 0) in atmel_i2s_probe()
691 err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, pcm_flags); in atmel_i2s_probe()
693 dev_err(&pdev->dev, "failed to register PCM: %d\n", err); in atmel_i2s_probe()
694 clk_disable_unprepare(dev->pclk); in atmel_i2s_probe()
705 clk_disable_unprepare(dev->pclk); in atmel_i2s_remove()