Lines Matching +full:dev +full:- +full:ctrl
1 // SPDX-License-Identifier: GPL-2.0
20 * ---- S/PDIF Transmitter Controller Register map ----
37 * ---- Control Register (Write-only) ----
43 * ---- Mode Register (Read/Write) ----
91 ((((bytes) - 1) << 28) & SPDIFTX_MR_BPS_MASK)
94 * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----
109 static bool mchp_spdiftx_readable_reg(struct device *dev, unsigned int reg) in mchp_spdiftx_readable_reg() argument
133 static bool mchp_spdiftx_writeable_reg(struct device *dev, unsigned int reg) in mchp_spdiftx_writeable_reg() argument
159 static bool mchp_spdiftx_precious_reg(struct device *dev, unsigned int reg) in mchp_spdiftx_precious_reg() argument
194 struct device *dev; member
202 static inline int mchp_spdiftx_is_running(struct mchp_spdiftx_dev *dev) in mchp_spdiftx_is_running() argument
206 regmap_read(dev->regmap, SPDIFTX_MR, &mr); in mchp_spdiftx_is_running()
210 static void mchp_spdiftx_channel_status_write(struct mchp_spdiftx_dev *dev) in mchp_spdiftx_channel_status_write() argument
212 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_channel_status_write() local
216 for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat) / 4; i++) { in mchp_spdiftx_channel_status_write()
217 val = (ctrl->ch_stat[(i * 4) + 0] << 0) | in mchp_spdiftx_channel_status_write()
218 (ctrl->ch_stat[(i * 4) + 1] << 8) | in mchp_spdiftx_channel_status_write()
219 (ctrl->ch_stat[(i * 4) + 2] << 16) | in mchp_spdiftx_channel_status_write()
220 (ctrl->ch_stat[(i * 4) + 3] << 24); in mchp_spdiftx_channel_status_write()
222 regmap_write(dev->regmap, SPDIFTX_CH1S(i), val); in mchp_spdiftx_channel_status_write()
226 static void mchp_spdiftx_user_data_write(struct mchp_spdiftx_dev *dev) in mchp_spdiftx_user_data_write() argument
228 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_user_data_write() local
232 for (i = 0; i < ARRAY_SIZE(ctrl->user_data) / 4; i++) { in mchp_spdiftx_user_data_write()
233 val = (ctrl->user_data[(i * 4) + 0] << 0) | in mchp_spdiftx_user_data_write()
234 (ctrl->user_data[(i * 4) + 1] << 8) | in mchp_spdiftx_user_data_write()
235 (ctrl->user_data[(i * 4) + 2] << 16) | in mchp_spdiftx_user_data_write()
236 (ctrl->user_data[(i * 4) + 3] << 24); in mchp_spdiftx_user_data_write()
238 regmap_write(dev->regmap, SPDIFTX_CH1UD(i), val); in mchp_spdiftx_user_data_write()
244 struct mchp_spdiftx_dev *dev = dev_id; in mchp_spdiftx_interrupt() local
245 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_interrupt() local
248 regmap_read(dev->regmap, SPDIFTX_ISR, &sr); in mchp_spdiftx_interrupt()
249 regmap_read(dev->regmap, SPDIFTX_IMR, &imr); in mchp_spdiftx_interrupt()
256 dev_warn(dev->dev, "underflow detected\n"); in mchp_spdiftx_interrupt()
261 dev_warn(dev->dev, "overflow detected\n"); in mchp_spdiftx_interrupt()
266 spin_lock(&ctrl->lock); in mchp_spdiftx_interrupt()
267 mchp_spdiftx_user_data_write(dev); in mchp_spdiftx_interrupt()
268 spin_unlock(&ctrl->lock); in mchp_spdiftx_interrupt()
273 spin_lock(&ctrl->lock); in mchp_spdiftx_interrupt()
274 mchp_spdiftx_channel_status_write(dev); in mchp_spdiftx_interrupt()
275 spin_unlock(&ctrl->lock); in mchp_spdiftx_interrupt()
279 regmap_write(dev->regmap, SPDIFTX_IDR, idr); in mchp_spdiftx_interrupt()
287 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_dai_startup() local
290 regmap_write(dev->regmap, SPDIFTX_CR, in mchp_spdiftx_dai_startup()
299 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_dai_shutdown() local
302 regmap_write(dev->regmap, SPDIFTX_IDR, 0xffffffff); in mchp_spdiftx_dai_shutdown()
308 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_trigger() local
309 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_trigger() local
315 spin_lock(&ctrl->lock); in mchp_spdiftx_trigger()
316 regmap_read(dev->regmap, SPDIFTX_MR, &mr); in mchp_spdiftx_trigger()
337 spin_unlock(&ctrl->lock); in mchp_spdiftx_trigger()
338 return -EINVAL; in mchp_spdiftx_trigger()
341 ret = regmap_write(dev->regmap, SPDIFTX_MR, mr); in mchp_spdiftx_trigger()
342 spin_unlock(&ctrl->lock); in mchp_spdiftx_trigger()
344 dev_err(dev->dev, "unable to disable TX: %d\n", ret); in mchp_spdiftx_trigger()
356 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_hw_params() local
357 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_hw_params() local
362 dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n", in mchp_spdiftx_hw_params()
366 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in mchp_spdiftx_hw_params()
367 dev_err(dev->dev, "Capture is not supported\n"); in mchp_spdiftx_hw_params()
368 return -EINVAL; in mchp_spdiftx_hw_params()
371 regmap_read(dev->regmap, SPDIFTX_MR, &mr); in mchp_spdiftx_hw_params()
374 dev_err(dev->dev, "PCM already running\n"); in mchp_spdiftx_hw_params()
375 return -EBUSY; in mchp_spdiftx_hw_params()
380 dev->playback.maxburst = 1; in mchp_spdiftx_hw_params()
388 dev->playback.maxburst = 2; in mchp_spdiftx_hw_params()
391 dev_err(dev->dev, "unsupported number of channels: %d\n", in mchp_spdiftx_hw_params()
393 return -EINVAL; in mchp_spdiftx_hw_params()
395 mr |= SPDIFTX_MR_CHUNK(dev->playback.maxburst); in mchp_spdiftx_hw_params()
438 dev_err(dev->dev, "unsupported PCM format: %d\n", in mchp_spdiftx_hw_params()
440 return -EINVAL; in mchp_spdiftx_hw_params()
445 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_hw_params()
446 ctrl->ch_stat[3] &= ~IEC958_AES3_CON_FS; in mchp_spdiftx_hw_params()
449 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_22050; in mchp_spdiftx_hw_params()
452 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_24000; in mchp_spdiftx_hw_params()
455 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_32000; in mchp_spdiftx_hw_params()
458 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_44100; in mchp_spdiftx_hw_params()
461 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_48000; in mchp_spdiftx_hw_params()
464 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_88200; in mchp_spdiftx_hw_params()
467 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_96000; in mchp_spdiftx_hw_params()
470 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_176400; in mchp_spdiftx_hw_params()
473 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_192000; in mchp_spdiftx_hw_params()
479 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_NOTID; in mchp_spdiftx_hw_params()
482 dev_err(dev->dev, "unsupported sample frequency: %u\n", in mchp_spdiftx_hw_params()
484 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_hw_params()
485 return -EINVAL; in mchp_spdiftx_hw_params()
487 mchp_spdiftx_channel_status_write(dev); in mchp_spdiftx_hw_params()
488 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_hw_params()
490 if (dev->gclk_enabled) { in mchp_spdiftx_hw_params()
491 clk_disable_unprepare(dev->gclk); in mchp_spdiftx_hw_params()
492 dev->gclk_enabled = 0; in mchp_spdiftx_hw_params()
494 ret = clk_set_rate(dev->gclk, params_rate(params) * in mchp_spdiftx_hw_params()
497 dev_err(dev->dev, in mchp_spdiftx_hw_params()
502 ret = clk_prepare_enable(dev->gclk); in mchp_spdiftx_hw_params()
504 dev_err(dev->dev, "unable to enable gclk: %d\n", ret); in mchp_spdiftx_hw_params()
507 dev->gclk_enabled = 1; in mchp_spdiftx_hw_params()
508 dev_dbg(dev->dev, "%s(): GCLK set to %d\n", __func__, in mchp_spdiftx_hw_params()
512 regmap_write(dev->regmap, SPDIFTX_IER, in mchp_spdiftx_hw_params()
515 regmap_write(dev->regmap, SPDIFTX_MR, mr); in mchp_spdiftx_hw_params()
523 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_hw_free() local
525 regmap_write(dev->regmap, SPDIFTX_IDR, in mchp_spdiftx_hw_free()
527 if (dev->gclk_enabled) { in mchp_spdiftx_hw_free()
528 clk_disable_unprepare(dev->gclk); in mchp_spdiftx_hw_free()
529 dev->gclk_enabled = 0; in mchp_spdiftx_hw_free()
532 return regmap_write(dev->regmap, SPDIFTX_CR, in mchp_spdiftx_hw_free()
564 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in mchp_spdiftx_info()
565 uinfo->count = 1; in mchp_spdiftx_info()
575 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_cs_get() local
576 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_cs_get() local
578 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_cs_get()
579 memcpy(uvalue->value.iec958.status, ctrl->ch_stat, in mchp_spdiftx_cs_get()
580 sizeof(ctrl->ch_stat)); in mchp_spdiftx_cs_get()
581 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_cs_get()
591 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_cs_put() local
592 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_cs_put() local
596 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_cs_put()
597 for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat); i++) { in mchp_spdiftx_cs_put()
598 if (ctrl->ch_stat[i] != uvalue->value.iec958.status[i]) in mchp_spdiftx_cs_put()
600 ctrl->ch_stat[i] = uvalue->value.iec958.status[i]; in mchp_spdiftx_cs_put()
605 if (mchp_spdiftx_is_running(dev)) { in mchp_spdiftx_cs_put()
610 regmap_write(dev->regmap, SPDIFTX_IER, in mchp_spdiftx_cs_put()
613 mchp_spdiftx_channel_status_write(dev); in mchp_spdiftx_cs_put()
616 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_cs_put()
624 memset(uvalue->value.iec958.status, 0xff, in mchp_spdiftx_cs_mask()
625 sizeof(uvalue->value.iec958.status)); in mchp_spdiftx_cs_mask()
634 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_subcode_get() local
635 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_subcode_get() local
638 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_subcode_get()
639 memcpy(uvalue->value.iec958.subcode, ctrl->user_data, in mchp_spdiftx_subcode_get()
640 sizeof(ctrl->user_data)); in mchp_spdiftx_subcode_get()
641 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_subcode_get()
651 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_subcode_put() local
652 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_subcode_put() local
656 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_subcode_put()
657 for (i = 0; i < ARRAY_SIZE(ctrl->user_data); i++) { in mchp_spdiftx_subcode_put()
658 if (ctrl->user_data[i] != uvalue->value.iec958.subcode[i]) in mchp_spdiftx_subcode_put()
661 ctrl->user_data[i] = uvalue->value.iec958.subcode[i]; in mchp_spdiftx_subcode_put()
664 if (mchp_spdiftx_is_running(dev)) { in mchp_spdiftx_subcode_put()
669 regmap_write(dev->regmap, SPDIFTX_IER, in mchp_spdiftx_subcode_put()
672 mchp_spdiftx_user_data_write(dev); in mchp_spdiftx_subcode_put()
675 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_subcode_put()
712 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_dai_probe() local
715 snd_soc_dai_init_dma_data(dai, &dev->playback, NULL); in mchp_spdiftx_dai_probe()
717 ret = clk_prepare_enable(dev->pclk); in mchp_spdiftx_dai_probe()
719 dev_err(dev->dev, in mchp_spdiftx_dai_probe()
733 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai); in mchp_spdiftx_dai_remove() local
735 clk_disable_unprepare(dev->pclk); in mchp_spdiftx_dai_remove()
741 .name = "mchp-spdiftx",
755 .name = "mchp-spdiftx",
760 .compatible = "microchip,sama7g5-spdiftx",
768 struct mchp_spdiftx_dev *dev; in mchp_spdiftx_probe() local
772 struct mchp_spdiftx_mixer_control *ctrl; in mchp_spdiftx_probe() local
777 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in mchp_spdiftx_probe()
778 if (!dev) in mchp_spdiftx_probe()
779 return -ENOMEM; in mchp_spdiftx_probe()
786 regmap = devm_regmap_init_mmio(&pdev->dev, base, in mchp_spdiftx_probe()
796 err = devm_request_irq(&pdev->dev, irq, mchp_spdiftx_interrupt, 0, in mchp_spdiftx_probe()
797 dev_name(&pdev->dev), dev); in mchp_spdiftx_probe()
802 dev->pclk = devm_clk_get(&pdev->dev, "pclk"); in mchp_spdiftx_probe()
803 if (IS_ERR(dev->pclk)) { in mchp_spdiftx_probe()
804 err = PTR_ERR(dev->pclk); in mchp_spdiftx_probe()
805 dev_err(&pdev->dev, in mchp_spdiftx_probe()
811 dev->gclk = devm_clk_get(&pdev->dev, "gclk"); in mchp_spdiftx_probe()
812 if (IS_ERR(dev->gclk)) { in mchp_spdiftx_probe()
813 err = PTR_ERR(dev->gclk); in mchp_spdiftx_probe()
814 dev_err(&pdev->dev, in mchp_spdiftx_probe()
819 ctrl = &dev->control; in mchp_spdiftx_probe()
820 spin_lock_init(&ctrl->lock); in mchp_spdiftx_probe()
823 ctrl->ch_stat[0] = IEC958_AES0_CON_NOT_COPYRIGHT | in mchp_spdiftx_probe()
826 dev->dev = &pdev->dev; in mchp_spdiftx_probe()
827 dev->regmap = regmap; in mchp_spdiftx_probe()
828 platform_set_drvdata(pdev, dev); in mchp_spdiftx_probe()
830 dev->playback.addr = (dma_addr_t)mem->start + SPDIFTX_CDR; in mchp_spdiftx_probe()
831 dev->playback.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in mchp_spdiftx_probe()
833 err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in mchp_spdiftx_probe()
835 dev_err(&pdev->dev, "failed to register PMC: %d\n", err); in mchp_spdiftx_probe()
839 err = devm_snd_soc_register_component(&pdev->dev, in mchp_spdiftx_probe()
843 dev_err(&pdev->dev, "failed to register component: %d\n", err); in mchp_spdiftx_probe()